9 EDQでのJava Messaging Service (JMS)の使用
このドキュメントでは、Oracle Enterprise Data Quality (EDQ)でJava Messaging Service (JMS)テクノロジを使用して開始する方法について説明します。このドキュメントの対象読者は、EDQアプリケーションのインストールおよび管理を担当するシステム管理者です。
この章の内容は次のとおりです。
9.1 メッセージ・キュー・アーキテクチャの理解
JMSは、EDQを様々な異なるメッセージング・システムおよびテクノロジ(WebLogic Server Messaging、WebSphere MQ、Oracle Advanced Queueing (OAQ)など)と統合できる柔軟なテクノロジです。
EDQサーバーは、メッセージ・キューの「クライアント」として機能します。サーバー・コンポーネントは、EDQと同じ物理サーバーにインストールできますが、一般的には、1つ以上のサーバーがリモートになります。EDQには、ActiveMQまたはArtemisメッセージ・キュー・プロバイダへの接続に必要なクライアントjarが同梱されています。EDQがWebLogic Serverにデプロイされている場合、WebLogic JMSにネイティブに接続することもできます。それ以外の場合、たとえば、EDQがWebSphere MQなどの代替メッセージ・キュー(MQ)システムのクライアントとして機能する必要がある場合、追加のクライアントjarをインストールする必要があります。この場合、MQシステムの管理者に相談して、EDQなどのJavaアプリケーションがクライアントとして機能するために必要なファイルを決定する必要があります。
9.2 EDQでのJMSの使用
次に示すように、EDQでのJMSの使用方法には、主に2通りあります。ここでは、EDQでのJMSの最初の使用方法について説明します。
- メッセージの消費および提供: JMSキューからメッセージを読み込み、メッセージを書き込むようにEDQを構成できます。これは、複数のEDQサーバーが1つのメッセージ・ストリームから読み取る必要があり、メッセージが永続的で失われないようにする必要がある場合に役立ちます。このモードでは、各EDQサーバーは、キューからのメッセージを消費して、各メッセージの処理が終了した場合にのみコミットします。EDQが特定のメッセージに対して呼出し側アプリケーションにレスポンスを返す必要がない場合に、JMSは非同期通信に最適です。
- トリガーでのJMSの使用: EDQでは他のシステムにJMSメッセージを送信したり、JMSメッセージを使用してトリガーを開始したりできます(たとえば、JMSキューを使用して複数のEDQサーバーにバッチ・ジョブを配布します)。詳細は、「トリガーでのJMSの使用」を参照してください。
9.3 JMSメッセージの読取りおよび書込みを行うためのEDQの構成
EDQとのJMSインタフェースは、次のものを定義するXMLインタフェース・ファイルを使用して構成します。
- メッセージ・キューへのパス
- 特定のJMSテクノロジの使用方法を定義するプロパティ
- メッセージ・ペイロードをEDQプロセスで認識される形式にデコードする方法(メッセージ・プロバイダの場合、EDQがキューからメッセージを読み取る)、またはメッセージを外部プロセスで予測される形式に変換する方法(メッセージ・コンシューマの場合、EDQがメッセージをキューに書き込む)。
XMLファイルは、次のパスのEDQローカル・ホーム・ディレクトリ(以前の構成ディレクトリ)にあります。
- buckets/realtime/providers (EDQに入力するインタフェース)
- buckets/realtime/consumers (EDQから出力するインタフェース)
XMLファイルが構成されると、メッセージ・プロバイダ・インタフェースがEDQのリーダー・プロセッサで使用可能になり、データ・インタフェースをプロセスへの「入力」としてマップできます。また、メッセージ・コンシューマ・インタフェースはライター・プロセッサで使用可能になり、次の図1および2に示すように、データ・インタフェースからプロセスの「出力」としてマップできます。
9.4 インタフェース・ファイルの定義
EDQのインタフェース・ファイルには、次の3つのセクションがあります。
<attributes>
セクション: EDQで認識できるインタフェースの形状を定義します<messengerconfig>
セクション: JMSキューまたはJMSトピックに接続する方法を定義します<messagebody>
セクション: (たとえば、XMLから)メッセージのコンテンツをEDQが読み込める属性データに抽出する方法(インバウンド・インタフェースの場合)、またはEDQからメッセージ・データ(たとえば、XMLに)に属性データを変換する方法を定義します。
9.4.1 <attributes>セクションの理解
< attribute >セクションでは、インタフェースの形状を定義します。これは、リーダーまたはライターを構成するときにEDQで使用できる属性から構成されます。たとえば、インタフェース・ファイルの最初の部分の抜粋では、EDQで使用できる3つの文字列属性とその名前は次のように構成されます。
<?xml version="1.0" encoding="UTF-8"?>
<realtimedata messenger="jms">
<attributes>
<attribute type="string" name="messageID"/>
<attribute type="string" name="name"/>
<attribute type="string" name="AccountNumber"/>
</attributes>
[file continues]...
EDQでは、次のすべての標準属性タイプがサポートされます。
- 文字列
- 数値
- 日付
- stringarray
- numberarray
- datearray
9.4.2 <messengerconfig>セクションの理解
インタフェース・ファイルの<messengerconfig>
セクションでは、特定のタイプのJMSテクノロジ上で指定されたJMSキューまたはトピックに接続するために必要な設定を構成します。<messengerconfig>
内のテキストは、Javaプロパティ・ファイルとして解析され、EDQ構成パス内のrealtime.properties
ファイルの一連のプロパティとマージされます。<messengerconfig>
セクションの設定はrealtime.properties
内の一致設定をオーバーライドします。したがって、realtime.properties
ファイルにより、すべてのJMSインタフェース・ファイルに指定する必要のない様々なグローバル・プロパティを構成できます。
ノート:
- EDQローカル・ホーム・ディレクトリに格納されるすべてのプロパティ・ファイルと同様、変更する必要のないプロパティもEDQホーム・ディレクトリで一連の基本のプロパティにマージされます。ローカル・ホーム・ディレクトのファイルに指定される任意のプロパティは、EDQホーム・ディレクトリの任意のプロパティに優先的に使用されます。たとえば、EDQローカル・ホーム・ディレクトリの
realtime.properties
ファイルは、EDQホーム・ディレクトリ内で同じ名前のファイルとマージされ、使用されるプロパティの最終セットが形成されます。 realtime.properties
値は、EDQのWebサービスのプロパティの設定にも使用できます。そのため、jms.の接頭辞が使用され(このファイルのみ、JMSインタフェース・ファイルの<messengerconfig>
セクションではない)、JMSのプロパティが設定されます(Webサービスにはws.が使用されます)。
メッセンジャ構成プロパティは、JMSインタフェース・ファイルの<messengerconfig>
セクションで指定されるか、realtime.properties
から継承されますが、次の目的で使用されます。
- キューを参照するためのJNDI名ストアの構成
- キュー/トピックおよび接続ファクトリの名前の指定
- 必要な場合、MQサーバーに認証情報を提供
java.naming.factory.initial
- JNDIネーミングのブートストラップに使用される、JNDI初期コンテキスト・ファクトリのクラス名を示しますjava.naming.provider.url
- JNDIサーバーまたはローカル・ストアへの接続に使用するJNDI URL
JNDIサービスへの接続に認証が必要な場合があります。この場合、次のプロパティを追加する必要があります。
java.naming.security.principal
- JNDIユーザー名java.naming.security.credentials
- JNDIパスワード
これらのJNDIプロパティは標準的なJava機能で、詳細はJNDIのドキュメントを参照してください。
その他のプロパティは、次のとおりです。
connectionfactory
- JMS接続ファクトリのJNDI名デフォルト(プロパティが設定されていない場合)は、複数のMQサーバーに適切な'ConnectionFactory'です。destination
- JMSキューまたはトピックのJNDI名これにはデフォルトはなく、常に必須です。
接続時にMQサーバーで認証が必要な場合は、次のプロパティを追加します。
username: connection user name
password: connection password
ノート:
これらのプロパティは、MQサーバーに対する認証に使用され、JNDIへの接続に使用されます。まれに、両方が必要になる場合もあります。- ActiveMQ -
ActiveMQサーバーに接続するには、次に示すプロパティ設定を使用します:
これは、単一インタフェースに適用する場合、
<messengerconfig>
セクションで設定できます。または、すべてのインタフェースのデフォルトを設定する場合、realtime.properties
(接頭辞がjms.)で設定することもできます。java.naming.provider.url=tcp://host:port
ActiveMQサーバーは通常、接続認証を必要とするため、ユーザー名とパスワードのプロパティが必要です。
WebLogicにインストールされたEDQサーバーでActiveMQを使用するには、前述のプロパティ設定をEDQローカル・ホーム・ディレクトリのrealtime.propertiesに入力する必要があります。(設定は存在しますが、ホーム・ディレクトリのファイルにコメント・アウトされています。これは、通常、EDQがWebLogicにインストールされている場合にWebLogic JMSを使用することを前提としているためです。)
- WebLogic JMS -
WebLogic、Glassfish、WebSphereなどの完全なJavaEEアプリケーション・サーバーで実行する場合、ローカルJMSのJNDI設定は自動的に構成され、JNDIファクトリおよびURL情報をEDQ構成ファイルで指定する必要はありません。
このような場合、アプリケーション・サーバー内でJMS構成を定義し、次にJNDI接続ファクトリ名および宛先名を
<messengerconfig>
で指定することをお薦めします。WebLogicでは、「外部」JMSサーバーの概念がサポートされています。この場合、WebLogicコンソールで接続情報を定義し、ネイティブWebLogic JNDIストア内で宛先および接続ファクトリを名前として公開します。これは、Oracle Advanced Queueing (AQ)で効果的に機能します。AQスキーマを指している「外部JMSサーバー」の構成スニペットについては、次を参照してください。
このようにJMSが構成されている場合、一般的な<messengerconfig>
セクションは次のとおりです。<messengerconfig> connectionfactory = jms/cf1 destination = jms/queue1 </messengerconfig>
ここで、
jms/cf1and jms/queue1
はWebLogicで定義されているJNDI名です。
9.4.3 <messagebody>セクションの理解
このセクションでは、JavaScriptを使用して、EDQがインバウンド・インタフェースに使用できる属性にメッセージ・ペイロードを解析し、アウトバウンド・インタフェースのために逆操作(EDQ属性データをメッセージ・ペイロード・データに変換)を実行します。‘extract’という名前の関数は、XMLからインバウンド・インタフェースの属性データへのデータの抽出に使用され、‘build’という名前の関数は、属性データからXMLデータを構築するために使用されます。
詳細は、例を使用してスクリプトをわかりやすく説明している図を参照してください。
9.5 図
例1 – 簡単なプロバイダ・ファイル
次のXMLは、プロバイダ・インタフェース・ファイルの簡単な例で、パス‘dynamicQueues/InputQueue’
内のキューからメッセージを読み取ります。
<?xml version="1.0" encoding="UTF-8"?>
<realtimedata messenger="jms">
<attributes>
<attribute type="string" name="messageID"/>
<attribute type="string" name="name"/>
<attribute type="string" name="AccountNumber"/>
<attribute type="string" name="AccountName"/>
<attribute type="string" name="Country"/>
</attributes>
<messengerconfig> destination = dynamicQueues/InputQueue </messengerconfig>
<incoming>
<messagebody>
<script>
<![CDATA[ function extract(str) { var screeningRequest = new XML(str); var rec = new Record(); rec.messageID = screeningRequest.individual.messageID; rec.name = screeningRequest.individual.name; rec.AccountNumber = screeningRequest.individual.AccountNumber; rec.AccountName = screeningRequest.individual.AccountName; rec.Country = screeningRequest.individual.Country; return [rec]; } ]]>
</script>
</messagebody>
<eof>
<messageheader name="JMSType" value="t1eof"/>
</eof>
</incoming>
</realtimedata>
例2 – 簡単なコンシューマ・ファイル
次のXMLは、前述のプロバイダ・ファイルと類似したデータを表すコンシューマ・ファイルの簡単な例で、EDQプロセスで追加できる属性が追加されています。
<?xml version="1.0" encoding="UTF-8"?>
<realtimedata messenger="jms">
<attributes>
<attribute type="string" name="messageID"/>
<attribute type="string" name="AccountNumber"/>
<attribute type="string" name="AccountName"/>
<attribute type="string" name="Country"/>
<attribute type="string" name="AccountType"/>
</attributes>
<messengerconfig> destination = dynamicQueues/OutputQueue </messengerconfig>
<outgoing>
<messagebody>
<script>
<![CDATA[ function build(recs) { var rec = recs[0]; var xml = <Request> <individual> <messageID>{checkNull(rec.messageID)}</messageID> <AccountNumber>{checkNull(rec.AccountNumber)}</AccountNumber> <AccountName>{checkNull(rec.AccountName)}</AccountName> <Country>{checkNull(rec.Country)}</Country> <AccountType>{checkNull(rec.AccountType)}</AccountType> </individual> </Request>; return xml.toXMLString(); } function checkNull(value) { return value != null ? value : ""; } ]]>
</script>
</messagebody>
</outgoing>
</realtimedata>
例3 – 日付の解析と書式設定
次のファイルの例では、DATE属性の型を定義する方法と、メッセージ・ペイロードをデコードする際に日付解析および書式設定を含める方法を示します。
<?xml version="1.0" encoding="UTF-8"?>
<realtimedata messenger="jms">
<attributes>
<attribute type="date" name="processingDate"/>
</attributes>
<messengerconfig> destination = dynamicQueues/HoldQueue </messengerconfig>
<incoming>
<messagebody>
<script>
<![CDATA[ var df = Formatter.newDateFormatter("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); function extract(str) { var screeningRequest = new XML(str); var rec = new Record();rec.processingDate = date(screeningRequest.processingDate; return [rec]; } function date(x) { var s = x.text().toString(); return s == "" ? null : df.parse(s); } ]]>
</script>
</messagebody>
<eof>
<messageheader name="JMSType" value="t1eof"/>
</eof>
</incoming>
</realtimedata>