この章では、ユーザー・メッセージング・サービス(UMS)クライアントAPIを使用してアプリケーションを開発する方法について説明します。このAPIは、Fusion Middlewareアプリケーション開発者がメッセージ機能をエンタープライズ・アプリケーション内に組み込む際のプログラム上のエントリ・ポイントとして機能します。
クラスとインタフェースの詳細は、ユーザー・メッセージング・サービスJava APIリファレンスを参照してください。
この章の内容は次のとおりです。
|
注意: Oracle User Messaging Serviceのコード・サンプルに関する詳細を参照したり、サンプルを自分で実行するには、次の場所にあるサンプルを参照してください。
|
UMS APIには、Plain Old Java (POJO/POJI)プログラミング・モデルが用意されており、アプリケーション開発者は、UMS機能にアクセスするためにアプリケーションで様々なJava EEモジュール(EJBモジュールなど)をパッケージ化して実装する必要がありません。開発者はモジュールの追加パッケージ化を実行したり、パッケージ・タスクを実行するための特別なツールを取得せずに、Java EEコンテナで実行するアプリケーションを作成できるため、開発時間が削減されます。
コンシューマは、EJBや他のJava EEモジュールをそれぞれのアプリケーションにデプロイする必要はありませんが、アプリケーションのランタイム・クラスパスでUMSライブラリが使用可能であることを確認する必要があります。デプロイメントは、共有ライブラリoracle.sdp.clientとしてです。
ソース・コードを含むサンプルは、Oracle Technology Network (OTN)から入手できます。
MessagingClientオブジェクトは、UMS Java APIユーザーに対して必須です。このオブジェクトは、たとえば、メッセージの送信、送信されたメッセージのステータス情報の取得およびメッセージの同期的な受信に使用されます。MessagingClientオブジェクトは、MessagingClientFactory.createMessagingClient()メソッドを使用して作成されます。
クライアント・アプリケーションでは、MessagingClientオブジェクトのインスタンス化の実行時に一連のパラメータを指定できます。たとえば、MessagingClientインスタンスを構成するには、複数のパラメータをキーと値のペアとしてjava.util.Map<String, Object>に指定します。特に、これらの構成パラメータは、クライアント・アプリケーションの識別、UMSサーバーの指定およびセキュリティ資格証明の確立に役立ちます。クライアント・アプリケーションでは、使用可能なメカニズムを使用して構成パラメータを保存およびロードする必要があります。
表2-1に、Java APIに設定可能な構成パラメータの一部を示します。通常のユースケースでは、ほとんどのパラメータは指定する必要がなく、APIの実装では適切なデフォルト値が使用されます。
表2-1 実行時に指定する構成パラメータ
| パラメータ | ノート |
|---|---|
|
|
オプション。デフォルトでは、クライアントはそのデプロイメント名で識別されます。この識別子は、 |
|
|
オプション。指定が必要なのは、クラスタ化された特定のユースケースの場合か、セッションベースのルーティングを利用する場合のみです。 |
|
|
オプション。デフォルトでは、クライアントのリソースは、同じアプリケーション名のすべてのアプリケーションおよびすべてのセキュリティ・プリンシパルで使用できます。この動作は、 |
|
|
オプション。メッセージまたはステータスの非同期受信にリスナーを使用する場合、リスナー・ワーカー・スレッドの数は、 |
|
|
オプション。メッセージの受信時、トランザクションでのリスナーの使用を、このパラメータの値を指定することで制御できます。 |
MessagingClientインスタンスで使用するリソースが不要となったときに解放するには、MessagingClientFactory.remove(client)をコールします。このメソッドをコールしない場合は、ワーカー・スレッドやJMSリスナーなど一部のリソースがアクティブのまま残る場合があります。
例2-1に、MessagingClientインスタンスを作成するサンプル・コードを示します。
例2-1 MessagingClientインスタンスの作成
Map<String, Object> params = new HashMap<String, Object>(); // params.put(key, value); // if optional parameters need to be specified. MessagingClient messagingClient = MessagingClientFactory.createMessagingClient(params);
インスタンス化された後のMessagingClientは、再構成できません。かわりに、任意の構成を使用してMessagingClientクラスの新しいインスタンスを作成する必要があります。
MessagingClientFactoryクラスのAPIリファレンスには、Javadocからアクセスできます。
MessagingFactoryクラスを使用して、クライアント・アプリケーション用のUMSメッセージ・オブジェクトを作成します。MessagingFactoryクラスは、Addresses、AccessPoints、MessageFiltersおよびMessageQueriesの作成にも使用されます。これらのメソッドの詳細は、ユーザー・メッセージング・サービスJava APIリファレンスを参照してください。
クライアント・アプリケーションがメッセージを送信すると、UMS APIは、メッセージの配信ステータスを取得するために後でクライアント・アプリケーションで使用できる文字列識別子を戻します。戻されたステータスは、UMSの内部処理と外部ゲートウェイから受信した配信通知に基づいた最新のステータスです。
作成可能なメッセージのタイプには、プレーン・テキスト・メッセージ、テキスト/プレーンおよびテキスト/htmlパートで構成可能なマルチパート・メッセージ、および添付が含まれます。ただし、ドライバによって実装されているプロトコルにより、ドライバを使用して送信できるメッセージの種類が制限される場合があります。この問題に対処するために、単一メッセージでドライバ・チャネル(配信タイプ)に固有のペイロードを作成することができます(第2.3.1.3項「異なる配信タイプを使用した、複数受信者用の単一メッセージへの配信チャネル固有のペイロード作成」を参照)。
この項の内容は次のとおりです。
この項では、作成できる様々なタイプのメッセージについて説明します。
例2-2に、UMS Java APIを使用してプレーン・テキスト・メッセージを作成する方法を示します。
例2-3に、UMS Java APIを使用してマルチパート・メッセージまたは代替メッセージを作成する方法を示します。
例2-3 UMS Java APIを使用したマルチパート・メッセージまたは代替メッセージの作成
Message message = MessagingFactory.createMessage();
MimeMultipart mp = new MimeMultipart("alternative");
MimeBodyPart mp_partPlain = new MimeBodyPart();
mp_partPlain.setContent("This is a Plain Text part.", "text/plain;charset=utf-8");
mp.addBodyPart(mp_partPlain);
MimeBodyPart mp_partRich = new MimeBodyPart();
mp_partRich
.setContent(
"<html><head></head><body><b><i>This is an HTML part.</i></b></body></html>",
"text/html");
mp.addBodyPart(mp_partRich);
message.setContent(mp, "multipart/alternative");
メッセージを複数の受信者、または実行時にユーザー・プリファレンスによって解決されるUSERアドレスに送信する場合、複数のチャネルが関わることがあります。Oracle UMSアプリケーション開発者は、各チャネルに対して正しいマルチパート書式を指定する必要があります。
例2-4に、異なる配信タイプを使用して、複数受信者用の単一メッセージに、配信チャネル(DeliveryType)固有のペイロードを作成する方法を示します。
複数ペイロードのマルチパート/代替メッセージの各最上位パートには、このヘッダーの値が1つ以上含まれている必要があります。このヘッダーの値は、有効な配信タイプの名前である必要があります。DeliveryTypeの使用可能な値は、列挙DeliveryTypeを参照してください。
例2-4 異なる配信タイプを使用した、複数受信者用の単一メッセージへの配信チャネル固有のペイロード作成
Message message = MessagingFactory.createMessage();
// create a top-level multipart/alternative MimeMultipart object.
MimeMultipart mp = new MimeMultipart("alternative");
// create first part for SMS payload content.
MimeBodyPart part1 = new MimeBodyPart();
part1.setContent("Text content for SMS.", "text/plain");
part1.setHeader(Message.HEADER_NS_PAYLOAD_PART_DELIVERY_TYPE, "SMS");
// add first part
mp.addBodyPart(part1);
// create second part for EMAIL and IM payload content.
MimeBodyPart part2 = new MimeBodyPart();
MimeMultipart part2_mp = new MimeMultipart("alternative");
MimeBodyPart part2_mp_partPlain = new MimeBodyPart();
part2_mp_partPlain.setContent("Text content for EMAIL/IM.", "text/plain");
part2_mp.addBodyPart(part2_mp_partPlain);
MimeBodyPart part2_mp_partRich = new MimeBodyPart();
part2_mp_partRich.setContent("<html><head></head><body><b><i>" + "HTML content for EMAIL/IM." +
"</i></b></body></html>", "text/html");
part2_mp.addBodyPart(part2_mp_partRich);
part2.setContent(part2_mp, "multipart/alternative");
part2.addHeader(Message.HEADER_NS_PAYLOAD_PART_DELIVERY_TYPE, "EMAIL");
part2.addHeader(Message.HEADER_NS_PAYLOAD_PART_DELIVERY_TYPE, "IM");
// add second part
mp.addBodyPart(part2);
// set the content of the message
message.setContent(mp, "multipart/alternative");
// set the MultiplePayload flag to true
message.setMultiplePayload(true);
クラスMessagingFactory、インタフェースMessageおよび列挙DeliveryTypeのAPIリファレンスには、ユーザー・メッセージング・サービスJava APIリファレンスからアクセスできます。
例2-5に、添付を含むメッセージを作成する方法を示します。
例2-5 メッセージの添付の作成
Message message = MessagingFactory.createMessage();
message.setSubject("Testing attachments");
MimeMultipart mp = new MimeMultipart("mixed");
MimeBodyPart part1 = new MimeBodyPart();
part1.setText("A sample pdf.");
MimeBodyPart part2 = new MimeBodyPart();
part2.attachFile("/tmp/sample-content.pdf");
mp.addBodyPart(part1);
mp.addBodyPart(part2);
message.setContent(mp, MimeType.MULTIPART_MIXED.toString());
この項では、使用可能な様々なタイプのUMSアドレスおよびアドレス・オブジェクトの作成方法を説明します。
この項では、UMSで使用可能な様々なタイプのアドレスについて説明します。
デバイス・アドレス: デバイス・アドレスには、電子メール・アドレス、インスタント・メッセージ・アドレス、電話番号など、様々なタイプがあります。「アドレス・オブジェクトの作成」を参照してください。
フェイルオーバー・アドレス: メッセージが当初のアドレスに送信できなかった場合に使用されるバックアップまたはフェイルオーバー・アドレス。「フェイルオーバー・アドレスを使用した受信者の作成」を参照してください。
ユーザー・アドレス: ユーザー・アドレスは、メッセージの送信中にデバイス・アドレスに解決されるユーザー・リポジトリ内のユーザーIDです。「ユーザー・プリファレンス・ベースのメッセージング」を参照してください。
グループ・アドレス: グループ・アドレスは、メッセージの送信中にユーザーまたはデバイス(あるいはその両方)のアドレスに解決されるLDAPグループ(またはエンタープライズ・ロール)です。「グループ・メッセージの送信」を参照してください。
アプリケーション・ロール・アドレス: アプリケーション・ロール・アドレスは、メッセージの送信中に、グループ、ユーザーまたはデバイス(あるいはそのすべて)のアドレスに解決されます。「アプリケーション・ロールへのメッセージの送信」を参照してください。
Addressオブジェクトは、MessagingFactoryクラスを使用してメッセージの送信者と受信者のアドレスを指定することで作成できます。
例2-9に、フェイルオーバー・アドレスを使用して受信者を作成するサンプル・コードを示します。
例2-9 フェイルオーバーを使用した単一のAddressオブジェクトの作成
String recipientWithFailoverStr = "EMAIL:john@example.com, SMS:123456"; Address recipient = MessagingFactory.createAddress(recipientWithFailoverStr);
または、
Address recipient = MessagingFactory.createAddress("EMAIL:john@example.com");
Address failoverAddr = MessagingFactory.createAddress("SMS:123456");
recipient.setFailoverAddress(failoverAddr);
UMS Java APIでは、電子メール・ドライバで使用されるTo/Cc/Bcc受信者を使用したメッセージの送受信をサポートしています。
メッセージの送信でCc/Bcc受信者を指定するには、oracle.sdp.messaging.MessagingFactory.buildAddressメソッドを使用してoracle.sdp.messaging.Addressオブジェクトを作成します。引数はアドレス値(たとえばuser@domain.com)、配信タイプ(たとえばDeliveryType.EMAIL)および電子メール・モード(たとえば「Cc」や「Bcc」)です。
(たとえば受信したメッセージ内にある)既存のアドレス・オブジェクトの受信者タイプを特定するには、oracle.sdp.messaging.MessagingFactory.getRecipientTypeメソッドを使用してAddressオブジェクトを渡します。それに対して受信者タイプを示す文字列が戻されます。
クラスMessagingFactoryのAPIリファレンスには、ユーザー・メッセージング・サービスJava APIリファレンスからアクセスできます。
ユーザー受信者にメッセージを送信(してユーザーのメッセージング・プリファレンスを活用)する際、メッセージで様々なビジネス条件の現在の値をメタデータとして渡すことができます。UMSサーバーでは、メッセージで指定されたファクトを、ユーザーのメッセージング・フィルタで指定されているビジネス条件の条件と照合し、このメッセージのユーザー・プリファレンスに一致するデバイス・アドレスにメッセージを送信します。
ユーザー・プリファレンスの詳細は、ユーザー通信プリファレンスの管理を参照してください。
|
注意: すべてのファクトはメタデータとして |
図2-10は、ユーザー受信者を指定し、メッセージのユーザー・プリファレンスでビジネス条件のファクトを指定する方法を示します。サポートされているビジネス条件の完全なリストは、ユーザー通信プリファレンスの管理を参照してください。
例2-10 ユーザー・プリファレンス・ベースのメッセージング
Message message = MessagingFactory.createMessage();
// create and add a user recipient
Address userRecipient1 = MessagingFactory.createAddress("USER:sampleuser1");
message.addRecipient(userRecipient1);
// specify business term facts
message.setMetaData(Message.NAMESPACE_NOTIFICATION_PREFERENCES, "Customer
Name", "ACME");
// where "Customer Name" is the Business Term name, and "ACME" is the
Business Term value (i.e, fact).
メッセージをユーザー・グループに送信するには、グループURIに送信するか、LDAPグループ(またはエンタープライズ・ロール)およびアプリケーション・ロールに送信します。
メッセージをLDAPグループまたはエンタープライズ・ロールに送信できます。
メッセージをグループに送信するには、例2-11で示されているように、MessagingFactoryクラスを使用して、GROUPタイプの受信者アドレスを作成し、メッセージを送信します。
例2-11 メッセージの作成とグループへのアドレス指定
Address groupAddr = MessagingFactory.createAddress("GROUP:MyGroup");
Message message = MessagingFactory.createTextMessage("Sending message to a group");
message.addRecipient(groupAddr);
message.setSubject("Testing groups");
String id = messagingClient.send(message);
グループ・アドレスgroupAddrは、最終的にはユーザー・アドレスで置換され、例2-12で示されているような結果になります。
例2-12 ユーザー・アドレスで置換されたグループ・アドレス
Address groupMember1 = MessagingFactory.createAddress("USER:MyGroupMember1");
Address groupMember2 = MessagingFactory.createAddress("USER:MyGroupMember2");
Address groupMember3 = MessagingFactory.createAddress("USER:MyGroupMember3");
Message message = MessagingFactory.createTextMessage("Sending message to a group");
message.addRecipient(groupMember1);
message.addRecipient(groupMember2);
message.addRecipient(groupMember3);
message.setSubject("Testing groups");
String id = messagingClient.send(message);
各ユーザーのユーザー・プリファレンスによって、メッセージが最終的に到達する場所が決定されます。詳細は、ユーザー通信プリファレンスの管理を参照します。
グループ・メッセージの送信前に送信チャネルを指定できます。グループ・メッセージの送信チャネルを指定するには、例2-13で示されているように、グループ・アドレス(groupAddr)のDeliveryTypeプロパティを設定する必要があります。
例2-13 メッセージの作成とチャネル経由でのグループへのアドレス指定
Address groupAddr = MessagingFactory.createAddress("GROUP:MyGroup");
groupAddr.setDeliveryType(DeliveryType.EMAIL);
Message message = MessagingFactory.createTextMessage("Sending message to a group");
message.addRecipient(groupAddr);
message.setSubject("Testing groups through email");
String id = messagingClient.send(message);
グループはユーザーに解決され、次に各ユーザーの電子メール・アドレスがフェッチされます。この場合のユーザーの電子メール・アドレスは、ユーザー・プリファレンスに使用されるものと同じです。電子メール・アドレスがユーザーに存在しない場合、そのユーザーはスキップされます。
アプリケーション・ロールは、ユーザー、グループおよびその他のアプリケーション・ロールの集まりであり、階層構造にできます。アプリケーション・ロールはアプリケーション・ポリシーによって定義されます。JavaEEコンテナに認識されるとは限りません。アプリケーション・ロールの詳細は、『Oracle Platform Security Servicesによるアプリケーションの保護』を参照してください。
|
注意: アプリケーション・ロールは、次のロールなど、他のアプリケーション・ロールにマップできます。
|
メッセージをアプリケーション・ロールに送信するには、MessagingFactoryクラスを使用することにより、アプリケーション・ロール・タイプの受信者アドレスを作成する必要があります。アプリケーション・ロールはアプリケーションID (アプリケーション名またはアプリケーション・ストライプとも呼ばれます)に属します。したがって、例2-14で示されているように、これら両方のパラメータが受信者アドレス内に指定されている必要があります。
例2-14 メッセージの作成とアプリケーション・ロールへのアドレス指定
Address appRoleAddr =
MessagingFactory.createAppRoleAddress("myAppRole", "theAppId");
Message message = MessagingFactory.createTextMessage("Message to an application role");
message.addRecipient(appRoleAddr);
message.setSubject("Testing application roles");
String id = messagingClient.send(message);
アプリケーション・ロールmyAppRoleは、最終的にユーザー・アドレスで置換されます。
アプリケーションIDがコール元アプリケーションのIDである場合は、受信者アドレスの作成時に、アプリケーションIDを指定する必要はありません。UMSは、JpsFilter(web.xml)またはJpsInterceptor(ejb-jar.xml)のapplication.nameパラメータで指定されているアプリケーションIDを自動的にフェッチします。フィルタおよびインターセプタ・パラメータの詳細は、『Oracle Platform Security Servicesによるアプリケーションの保護』を参照してください。
ユーザーは、グループにメッセージを送信する場合のチャネル指定と同じようにして、送信メッセージ用チャネルを指定できます。アプリケーション・ロール・アドレスで配信タイプを設定する必要があります。
電子メールを配信チャネルとして指定するアプリケーション・ロールにメッセージを送信する例を次に示します。
例2-15 メッセージの作成とチャネル経由でのアプリケーションへのアドレス指定
Address appRoleAddr =
MessagingFactory.createAppRoleAddress("myAppRole", "theAppId");
appRoleAddr.setDeliveryType(DeliveryType.EMAIL);
Message message = MessagingFactory.createTextMessage("Message to an application role");
message.addRecipient(appRoleAddr);
message.setSubject("Testing application roles");
String id = messagingClient.send(message);
メッセージを送信した後は、Oracle UMSを使用して、メッセージ・ステータスを同期または非同期で取得します。1人の受信者ごとに、ステータス情報を含むステータス・オブジェクトが1つあり、これにより、メッセージが保留中か、メッセージの送信が成功したか、メッセージの送信が失敗したか、フェイルオーバー・アドレスの有無、およびメッセージが自動的に再送信されるかを把握できます。
現行ステータスの同期取得を実行するには、MessagingClient APIから次のフローを使用します。
String messageId = messagingClient.send(message); Status[] statuses = messagingClient.getStatus(messageId);
または、
Status[] statuses = messagingClient.getStatus(messageId, address[]) --- where address[] is an array of one or more of the recipients set in the message.
ステータスを非同期で受信する場合は、クライアント・アプリケーションは、MessagingClientを使用して、Listenerオブジェクトとオプションの相関機能オブジェクトを指定します。受信ステータスが着信すると、リスナーのonStatusコールバックが起動されます。当初指定の相関機能オブジェクトもコールバック・メソッドに渡されます。
リスナーは純粋なプログラムです。リスナーは、oracle.sdp.messaging.Listenerインタフェースを実装して作成します。このインタフェースは、具体クラス(既存クラスの1つ、新規クラス、あるいは無名クラスか内部クラス)として実装できます。
次のコード例は、ステータス・リスナーの実装方法を示しています。
import oracle.sdp.messaging.Listener;
public class StatusListener implements Listener {
@Override
public void onMessage(Message message, Serializable correlator) {
}
@Override
public void onStatus(Status status, Serializable correlator) {
System.out.println("Received Status: " + status + " with optional correlator: " +
correlator);
}
}
Listenerオブジェクトへの参照は、「デフォルトのステータス・リスナー」および「メッセージごとのステータス・リスナー」の説明に従って、setStatusListenerまたはsendメソッドに渡します。メッセージのステータスが着信すると、UMSインフラストラクチャでは、リスナーのonStatusメソッドが必要に応じて起動されます。
クライアント・アプリケーションでは通常、デフォルトのステータス・リスナー(例2-16)が設定されます。クライアント・アプリケーションでメッセージが送信されると、そのメッセージの配信ステータス・コールバックによって、デフォルト・リスナーのonStatusメソッドが起動されます。
この方法では、クライアント・アプリケーションによってメッセージが送信され、リスナー・オブジェクトとオプションの相関機能オブジェクトが指定されます(例2-17)。該当するメッセージに対して配信ステータス・コールバックが使用できる場合は、指定したリスナーのonStatusメソッドが起動されます。当初指定の相関機能オブジェクトもコールバック・メソッドに渡されます。
|
注意: Oracle UMSでは、 |
着信メッセージを受信するアプリケーションでは、メッセージの受信者アドレスを表すアクセス・ポイントを1つ以上登録する必要があります。サーバーでは、着信メッセージの受信者アドレスと一連の登録済アクセス・ポイントを照合し、一致したアクセス・ポイントを登録したアプリケーションのキュー内に、その着信メッセージをルーティングします。アプリケーション側から見ると、そのキュー内からメッセージを受信するモードには、同期および非同期があります。
AccessPointは、着信メッセージを受信するための1つ以上のデバイス・アドレスを表します。
MessagingFactory.createAccessPointを使用してアクセス・ポイントを作成し、そのアクセス・ポイントをMessagingClient.registerAccessPointを使用してメッセージ受信用に登録します。
電子メールのアクセス・ポイントを登録するには、次のように指定します。
Address apAddress = MessagingFactory.createAddress("EMAIL:user1@example.com");
AccessPoint ap = MessagingFactory.createAccessPoint(apAddress);
MessagingClient.registerAccessPoint(ap);
番号9000のSMSアクセス・ポイントを登録するには、次のように指定します。
AccessPoint accessPointSingleAddress = MessagingFactory.createAccessPoint(AccessPoint.AccessPointType.SINGLE_ADDRESS, DeliveryType.SMS, "9000"); messagingClient.registerAccessPoint(accessPointSingleAddress);
番号が9000から9999の範囲内のSMSアクセス・ポイントを登録するには、次のように指定します。
AccessPoint accessPointRangeAddress = MessagingFactory.createAccessPoint(AccessPoint.AccessPointType.NUMBER_RANGE, DeliveryType.SMS,"9000,9999"); messagingClient.registerAccessPoint(accessPointRangeAddress);
MessagingClient.receiveメソッドを使用して、UMSがアプリケーションで使用可能にしたメッセージを同期受信します。このメソッドは、メッセージの非同期受信による構成オーバーヘッドを望まない軽量なクライアント向けの便利なポーリング・メソッドです。アクセス・ポイントの指定なしでメッセージを受信した場合、アプリケーションでは、登録したすべてのアクセス・ポイントのメッセージを受信します。そうでない場合、アプリケーションでは、そのアクセス・ポイントに送信されたメッセージを受信します。
受信は非ブロック操作です。アプリケーションやアクセス・ポイントに関して保留中のメッセージがない場合、該当するコールでは、nullが即時に戻されます。受信によって、すべての使用可能なメッセージが戻される保証はありませんが、効率上の理由から使用可能なメッセージのサブセットのみを戻すことはできます。
|
注意: 1回の起動で、使用可能なメッセージがすべて取得される保証はありません。 |
メッセージを非同期で受信する場合は、クライアント・アプリケーションによってアクセス・ポイントが登録され、Listenerオブジェクトとオプションの相関機能オブジェクトが指定されます。受信メッセージが指定のアクセス・ポイント・アドレスに着信すると、リスナーのonMessageコールバックが起動されます。当初指定の相関機能オブジェクトもコールバック・メソッドに渡されます。
リスナーは、oracle.sdp.messaging.Listenerインタフェースを実装して作成します。このインタフェースは、具体クラス(既存クラスの1つ、新規クラス、あるいは無名クラスか内部クラス)として実装できます。
次のコード例は、メッセージ・リスナーの実装方法を示しています。
import oracle.sdp.messaging.Listener;
public class MyListener implements Listener {
@Override
public void onMessage(Message message, Serializable correlator) {
System.out.println("Received Message: " + message + " with optional correlator: " +
correlator);
}
@Override
public void onStatus(Status status, Serializable correlator) {
System.out.println("Received Status: " + status + " with optional correlator: " +
correlator);
}
}
リスナー・オブジェクトへの参照は、「デフォルトのメッセージ・リスナー」および「アクセス・ポイントごとのメッセージ・リスナー」の説明に従って、setMessageListenerまたはregisterAccessPointメソッドに渡します。アプリケーションのメッセージが着信すると、UMSインフラストラクチャでは、リスナーのonMessageメソッドが起動されます。
クライアント・アプリケーションでは通常、デフォルトのメッセージ・リスナー(例2-18)が設定されます。Oracle UMSでは、このクライアント・アプリケーションによって登録されたアクセス・ポイント宛てのメッセージを受信すると、受信したメッセージに対応するアクセス・ポイントに登録されている特定のリスナーがない限り、そのクライアント・アプリケーションのデフォルトのリスナーに対してonMessageコールバックが起動されます。
デフォルトのリスナーを削除するには、nullの引数を指定してこのメソッドをコールします。
非同期受信の詳細な手順については、サンプル・アプリケーションusermessagingsample-echoを参照してください。
また、クライアント・アプリケーションでは、アクセス・ポイントを登録し、Listenerオブジェクトとオプションのcorrelatorオブジェクトを指定できます(例2-19)。受信メッセージが指定のアクセス・ポイント・アドレスに着信すると、指定したリスナーのonMessageメソッドが起動されます。当初指定のcorrelatorオブジェクトもコールバック・メッソッドに渡されます。
|
注意: Oracle UMSでは、 |
アプリケーションでMessageFilterを使用すると、配信されるメッセージをより強力に制御できます。MessageFilterには、一致基準とアクションが含まれています。アプリケーションでは、一連のメッセージ・フィルタを登録できます。登録されたメッセージ・フィルタは、着信(受信)メッセージに順に適用され、メッセージが基準と一致するとアクションが実行されます。たとえば、アプリケーションでMessageFiltersを使用して必要なブラックリストを実装すると、指定した送信者アドレスからのすべてのメッセージを拒否できます。メッセージに一致するフィルタがなかった場合、デフォルトのアクションとして、メッセージを受け入れてアプリケーションに配信します。
MessagingFactory.createMessageFilterを使用してメッセージ・フィルタを作成し、MessagingClient.registerMessageFilterを使用してそのメッセージ・フィルタを登録します。フィルタは、アプリケーションの現行フィルタ・チェーンの最後に追加されます。たとえば、件名が"spam"のメッセージを拒否するには、次のようにします。
MessageFilter subjectFilter = MessagingFactory.createMessageFilter("spam",
MessageFilter.FieldType.SUBJECT, null, MessageFilter.Action.REJECT);
messagingClient.registerMessageFilter(subjectFilter);
電子メール・アドレスspammer@foo.comからのメッセージを拒否するには、次のように指定します。
MessageFilter senderFilter =
MessagingFactory.createBlacklistFilter("spammer@foo.com");
messagingClient.registerMessageFilter(senderFilter);
APIでは、クラスタ環境にクライアント・アプリケーションとUMSサーバーがデプロイされている環境をサポートしています。クラスタ化されたデプロイメントが期待どおりに機能するためには、クライアント・アプリケーションを正しく構成する必要があります。次のルールが適用されます。
UMSメッセージング・クライアントの作成時に2つのクライアント・アプリケーションで同じApplicationName構成パラメータが使用されている場合、それらは同じアプリケーションのインスタンスであるとみなされます。明示的に設定されていない場合、UMSでは、クライアント・アプリケーションのデプロイメント名がApplicationNameとして使用されます。
同じアプリケーションのインスタンスでは、それらの構成のほとんどが共有され、1つのインスタンスによって登録されたAccessポイントやメッセージ・フィルタなどのアーティファクトは、すべてのインスタンスによって共有されます。
ApplicationInstanceName構成パラメータを使用すると、各インスタンスを区別できます。通常、このパラメータはAPI実装によって統合されているため、アプリケーション開発者による移入は不要です。この値を移入する必要がある場合については、Javadocを参照してください。
アプリケーション・セッションは、インスタンス固有です。メッセージにセッション・フラグを設定すると、メッセージを送信したインスタンスが受信した返信を確認できます。
リスナー相関機能は、インスタンス固有です。1つのアプリケーションの2つの異なるインスタンスで複数のリスナーが登録され、異なる相関機能が提供されている場合は、インスタンスAのリスナーが起動されると相関機能Aが提供され、インスタンスBのリスナーが起動されると相関機能Bが提供されます。
UMSは、アウトバウンド・メッセージとインバウンド・メッセージのXA対応トランザクションに対するサポートを提供します。業界標準であるX/Open XAプロトコルは、Business Process Management (BPM)など、他のOracle製品でも幅広くサポートされています。
|
注意: XAサポート機能は、UMSサーバーおよびUMSクライアントに含まれているので、インストールする必要はありません。また、XAサポートは、WebサービスAPIではなく、POJO APIでのみ可能です。 |
Java Messaging Service (JMS)は、エンタープライズ・メッセージングの概念と機能の共通セットを定義します。これは、User Messaging Service (UMS)でのメッセージング、キューイング、ソートおよびルーティング用に使用されます。Java Transaction API (JTA)は、トランザクション・マネージャと分散トランザクション・システム(アプリケーション、リソース・マネージャおよびアプリケーション・サーバー)に関わるパーティ間のローカルJavaインタフェースを指定します。JTAパッケージは、次の3つのコンポーネントで構成されます。
トランザクション・アプリケーションがトランザクションの境界を設定できるようにする上位アプリケーション・インタフェース。
トランザクション・リソース・マネージャが、外部トランザクション・マネージャによって制御されるグローバル・トランザクションに参加できるようにする業界標準X/Open XAプロトコルのJavaマッピング。
アプリケーション・サーバーが、アプリケーション・サーバーによって管理されるアプリケーションのトランザクション境界設定を制御できるようにする上位トランザクション・マネージャ・インタフェース。
JTAは、XAトランザクション(分散トランザクションとも呼ばれます)をサポートするためJava Messaging Service (JMS)プロバイダによって使用されます。XAリソース・インタフェースをサポートするJMSプロバイダは、2フェーズ・コミット・トランザクション・プロトコルを使用する分散トランザクション処理システムに、リソース・マネージャとして参加できます。
XAサポートにより、UMSは、トランザクションがコミットされるときにのみトランザクション境界内からメッセージを送信できます。トランザクションがロールバックされると、メッセージの送信は失敗します。コミットはトランザクションの成功につながりますが、ロールバックではメッセージは変更されないままになります。UMSは、アウトバウンド・メッセージとインバウンド・メッセージ両方に対するXAトランザクション・サポートを提供します。
XAを使用したアウトバウンド・メッセージング
UMSクライアント・アプリケーションからUMSサーバー経由で受信者に送信されるメッセージは、アウトバウンド・メッセージと呼ばれます。XAトランザクションがUMSクライアント上で有効な場合、アウトバウンド・メッセージは、トランザクションがコミットされた場合のみ、UMSサーバーに送信されます。トランザクションが成功すると、メッセージは安全に格納され、受信者への配信準備が整った状態になります。クライアント・トランザクションがコミットに失敗し、ロールバックが発生すると、メッセージは配信に向けてUMSサーバーに送信されません。
次のコードの抜粋では、XAを使用したアウトバウンド・メッセージの送信方法を示しています。
transaction.begin(); // Some business logic // ... String messageID = mClient.send(message); // Some business logic // ... transaction.commit();
XAを使用したインバウンド・メッセージング
UMSドライバにより受信され、UMSサーバー・エンジンによって処理され、UMSクライアントにルーティングされるメッセージは、インバウンド・メッセージと呼ばれます。XAトランザクションがUMSクライアント上で有効な場合、インバウンド・メッセージは、トランザクションがコミットされた場合のみ、UMSサーバーから取得され、UMSサーバー・ストアから削除されます。トランザクション・ロールバックが発生した場合、メッセージは後で再配信できるようにUMSサーバー上で変更されないまま維持されます。
次のコードの抜粋では、XAを使用したインバウンド・メッセージの受信方法を示しています。
transaction.begin();
messages = mClient.receive();
for (Message receivedMessage : messages) {
// process individual messages here.
}
transaction.commit();
サーバー・クラッシュによりコミットに失敗したメッセージを受信するには、サーバーとクライアントを再起動するか、特定のサーバー移行手順を実行する必要があります。詳細は、『Oracle Fusion Middleware Oracle WebLogic Server JMSの構成と管理』の「拡張JMSシステム・リソースの構成」を参照してください。
XAトランザクション用リスナーの使用
メッセージの受信中にトランザクション内でリスナーを使用することもできます。これは、定数MessagingConstants.LISTENER_TRANSACTED_MODEを指定することによって行います。MessagingClientインスタンスの作成時に、この定数の値をTRUEまたはFALSEに設定します。次の例を参照してください。
|
注意: リスナーを使用する場合、メッセージング定数 トランザクションのロールバックを行う場合、例外を適切に設定してください。 |
例2-20 リスナーを使用したXA対応メッセージの受信
Map<String, Object> params = new HashMap<String, Object>();
params.put(MessagingConstants.LISTENER_TRANSACTED_MODE, Boolean.TRUE);
MessagingClient mClient = MessagingClientFactory.createMessagingClient(params);
mListener = new MyListener();
mClient.registerAccessPoint(MessagingFactory.createAccessPoint(receiverAddr), mListener, null);
private class MyListener implements Listener {
@Override
public void onMessage(Message message,
Serializable correlator) throws ListenerException {
}}
メッセージ定数の詳細は、ユーザー・メッセージング・サービスJava APIリファレンスを参照してください。
XAトランザクション用EJBコールの使用
EJBコールを使用してXA対応メッセージを送信できます。トランザクションをロールバックするには、setRollbackOnly()メソッドを指定します。このメソッドの詳細は、http://docs.oracle.com/javaee/7/api/javax/ejb/EJBContext.html#setRollbackOnly()を参照してください。
また、トランザクション属性(NotSupported、RequiresNew、Neverなど)を指定して、トランザクション範囲を制御することもできます。次の場所にあるJava EEチュートリアルを参照してください。
http://docs.oracle.com/javaee/6/tutorial/doc/bncij.html
例2-21 EJBコールを使用したXA対応メッセージングの送信
Map<String, Object> params = new HashMap<String, Object>();
MessagingClient mClient =
MessagingClientFactory.createMessagingClient(params);
MimeMultipart mp = new MimeMultipart("alternative");
MimeBodyPart part1 = new MimeBodyPart();
Message message = MessagingFactory.createMessage();
...
...
mClient.sendMessage();
if(failure)
setRollbackOnly()
メッセージの送信が完全に失敗であると分類された場合、つまり、フェイルオーバー・チェーンがすべて使用済である場合、そのメッセージのUMSサーバーによる再送信が自動的にスケジュールされます。これは、そのメッセージの送信が成功するまで、または構成した再送信回数に達するまで繰り返されます。ただし、UMS Java APIを使用すると、次の例に示すようにsetMaxResendメソッドをコールして1メッセージ当たりの再送信の回数をオーバーライドできます。
MessageInfo msgInfo = message.getMessageInfo(); msgInfo.setMaxResend(1); String mid = messagingClient.send(message);
第2.4項「メッセージ・ステータスの取得」で説明したように、送信されたメッセージのステータスを調査する際、StatusオブジェクトでgetTotalFailovers()/getFailoverOrder()およびgetMaxResend()/getCurrentResend()をコールして、フェイルオーバー・チェーンおよび再送信の両方に関する情報を取得します。フェイルオーバーの順序がフェイルオーバー総数と同じになると、APIユーザーには、フェイルオーバー・チェーンがすべて使用済であることがわかります。ただし、再送信機能は、フェイルオーバー・チェーンのループとして動作します。maxResendがcurrentResendと同じになり、フェイルオーバーの順序がフェイルオーバー総数と同じになると、再送信およびフェイルオーバー・チェーンがすべて使用済となります。
setMaxResend、getTotalFailovers、getFailoverOrderなどのメソッドの詳細は、ユーザー・メッセージング・サービスJava APIリファレンスを参照してください。
同じタイプの複数のドライバが使用されていない限り、UMSサーバー・エンジンでは、クライアント・アプリケーションによって送信されるUMSメッセージで定義される配信タイプに基づいてドライバが選択されます。たとえば、メッセージの受信者アドレスがEMAIL:john@example.comの場合、電子メール・ドライバが選択され、受信者アドレスがSMS:1234の場合、SMSドライバが選択されます。
DeliveryType列挙では、メッセージの配信チャネルが定義されます。詳細は、ユーザー・メッセージング・サービスJava APIリファレンスを参照してください。
ただし、システム・トポロジで、複数のドライバ・インスタンスが必要な場合(たとえば、異なる電子メール・サーバーで構成されている2つの電子メール・ドライバなど)、特定のドライバがUMSサーバー・エンジンで選択されて送信UMSメッセージを作成できます。このためには、クライアント・アプリケーション内のメッセージの次のプロパティがUMSドライバ構成設定にマップされていることを確認する必要があります。
| UMSメッセージ・プロパティ | UMSドライバ構成パラメータ |
|---|---|
|
|
受信者アドレスの配信タイプは |
|
|
UMSメッセージ内の |
|
送信者アドレス |
ドライバ構成内の |
|
|
UMSメッセージ内の |
|
|
UMSメッセージ内の |
|
注意: ドライバによって前述の条件が渡されない場合、失敗ステータスがアプリケーションに戻され、警告ログも生成されます。 複数のドライバによって前述の条件が渡された場合、そのいずれかがUMSエンジンによって選択されます。 1つのドライバによってのみ前述の条件が渡された場合、そのドライバが選択されます。 |
ドライバ構成パラメータの詳細は、『Oracle User Messaging Serviceの管理』のユーザー・メッセージング・サービス・ドライバの構成に関する項を参照してください。
高負荷など特定の状況では、メッセージの送信時にUMSメッセージ優先度を指定することが有効です。メッセージの優先度は、内部JMSキューで使用されます。また、ドライバによって実装されているプロトコルが優先度をサポートしている場合、UMSメッセージ優先度は対応するプロトコルの優先度に変換されます。次の例に示すように、優先度を指定します。
例2-22 メッセージの高優先度の設定
MessageInfo msgInfo = message.getMessageInfo(); msgInfo.setPriority(MessagePriorityType.HIGH); String mid = messagingClient.send(message);
すべての使用可能な優先度タイプの詳細は、ユーザー・メッセージング・サービスJava APIリファレンスのMessagePriorityType定義を参照してください。
ユーザー通信プリファレンスは、USER接頭辞(例: USER:john.doe)を含む受信者アドレスに対して起動されます。プリファレンスは、2つのプロファイルにパーティション化できます。メッセージの送信時のプロファイルの指定方法の例を次に示します。
例2-23 アプリケーション・パーティショニング・プロファイルIDの指定
Address recipient = MessagingFactory.createAddress("USER:john.doe");
message.addRecipient(recipient);
MessageInfo msgInfo = message.getMessageInfo();
msgInfo.setProfileId(”myProfileId”);
String mid = messagingClient.send(message);
ユーザー通信プリファレンスおよびプロファイルの詳細は、ユーザー通信プリファレンスの管理を参照してください。
クライアント・アプリケーションには、セキュアなリスナーを確立するために、1つ以上の追加構成パラメータの指定が必要な場合があります(表2-1を参照)。
通常、UMS Java APIを使用するクライアント・アプリケーションはマルチスレッド化されています。通常のシナリオにはEJBインスタンスのプールが含まれ、各シナリオではMessagingClientインスタンスと、Webコンテナの複数のスレッドによって提供されるサーブレット・インスタンスが使用されます。UMS Java APIは、次のスレッド・モデルをサポートしています。
MessagingClientFactory.createMessagingClientの各コールでは、新しいMessagingClientインスタンスが戻されます。
MessagingClientFactory.createMessagingClientと等しいパラメータ・マップを渡して作成した2つのMessagingClientインスタンスは、同じクライアントのインスタンスです。異なるパラメータ・マップを渡して作成したインスタンスは、個別のクライアントのインスタンスです。
MessagingClientのインスタンスは、MessagingClientFactory.createMessagingClientを使用して取得した場合、スレッド・セーフではありません。クライアント・アプリケーションでは、所定のインスタンスが一度に1つのスレッドのみで使用されていることを確認する必要があります。この確認は、一度に1つのインスタンスのみが1つのスレッドに対して表示されていることを確認するか、MessagingClientインスタンスに対するアクセスを同期化することで実行できます。
同じクライアントの2つのインスタンス(同じパラメータ・マップを使用して作成)は、いくつかのリソースを共有します。特に、これらのインスタンスが、メッセージとステータスのリスナーを共有し、ワーカー・スレッドの共通プールを使用して非同期メッセージング操作を実行することに注意してください。たとえば、インスタンスAがsetMessageListener()をコールし、次にインスタンスBがsetMessageListener()をコールした場合は、Bのリスナーがアクティブなデフォルトのメッセージ・リスナーとなります。
次に、典型的なユースケースを示します。
EJB(メッセージドリブンBeanまたはセッションBeanのいずれか)アプリケーションからUMS Java APIを使用するための推奨方法は、MessagingClientインスタンスをBeanのejbCreate(または同等の@PostConstruct)メソッドに作成し、そのMessagingClientインスタンスをBeanクラスのインスタンス変数に保存することです。EJBコンテナでは、一度に1つのスレッドのみが所定のEJBインスタンスを使用していることが確認され、これによって一度に1つのスレッドのみがBeanのMessagingClientインスタンスにアクセスしていることが確認されます。
サーブレットからUMS Java APIを使用するには、いくつかの方法があります。通常、Webコンテナでは、サーブレット・クラスの単一のインスタンスが作成されます。このインスタンスには複数のスレッドが同時にアクセスできます。作成した単一のMessagingClientインスタンスがサーブレット・インスタンス変数に保存されている場合、そのインスタンスへのアクセスは同期している必要があります。
他の方法は、複数のサーブレット・スレッド間で共有するMessagingClientインスタンスのプールを作成することです。
最終的には、個別のMessagingClientインスタンスを個別のHTTPセッションに関連付けることができます。この方法を使用すると、すべてのサーブレット・リクエストに対して単一のMessagingClientを指定するよりも同時性が向上します。ただし、同時クライアント・リクエストが原因で複数のスレッドが1つのHTTPセッションに同時にアクセスする可能性があります。この場合は、同期がさらに必要になります。
第2.4.2項「メッセージ・ステータスの非同期取得」と第2.5.3項「非同期受信」で説明されている非同期受信については、UMSはデフォルトで、受信メッセージ用に1つのスレッド、受信ステータス通知用に1つのスレッドを使用します(それぞれ、少なくとも1つのメッセージ・リスナーまたはステータス・リスナーが登録されているものとします)。クライアント・アプリケーションでは、追加のワーカー・スレッドを構成して非同期処理の同時性を向上させることができます。これを実行するには、MessagingConstants.MESSAGE_LISTENER_THREADSキーとMessagingConstants.STATUS_LISTENER_THREADSキーに整数値を指定し、これらの値をMessagingClientインスタンスの作成時に使用した構成パラメータで、必要なワーカー・スレッドの数に設定します。この場合、アプリケーションのリスナーは、マルチスレッドの実行を処理するために書き込まれる必要があります。