ヘッダーをスキップ
Oracle® Fusion Middleware Oracle User Messaging Serviceによるアプリケーションの開発
リリース12c (12.1.2)
E47999-02
  目次へ移動
目次

前
 
次
 

3 ユーザー・メッセージング・サービスJava APIを使用したメッセージの送受信

この章では、ユーザー・メッセージング・サービス(UMS)クライアントAPIを使用してアプリケーションを開発する方法について説明します。このAPIは、Fusion Middlewareアプリケーション開発者がメッセージ機能をエンタープライズ・アプリケーション内に組み込む際のプログラム上のエントリ・ポイントとして機能します。

クラスとインタフェースの詳細は、ユーザー・メッセージング・サービスJava APIリファレンスを参照してください。

この章の内容は次のとおりです。

このAPIには、Plain Old Java (POJO/POJI)プログラミング・モデルが用意されており、アプリケーション開発者は、UMS機能にアクセスするためにアプリケーションで様々なJava EEモジュール(EJBモジュールなど)をパッケージ化して実装する必要がありません。開発者はモジュールの追加パッケージ化を実行したり、パッケージ・タスクを実行するための特別なツールを取得せずに、Java EEコンテナで実行するアプリケーションを作成できるため、開発時間が削減されます。

UMS Java APIのコンシューマは、環境エントリや他のJava EEデプロイメント・ディスクリプタ・アーティファクトなどのJava EEメカニズムを使用する必要がありません。Java EEディスクリプタの管理に関するオーバーヘッドの他に、多くのクライアント・アプリケーションには、Java EEディスクリプタに依存しない構成フレームワークがあります。


注意:

Oracle User Messaging Serviceのコード・サンプルに関する詳細を参照したり、サンプルを自分で実行するには、次の場所にあるサンプルを参照してください。

http://www.oracle.com/technetwork/indexes/samplecode/sample-ums-1454424.html


3.1 UMS Java APIの概要

UMS Java APIは、POJO/POJI APIとして公開されています。このAPIのコンシューマは、ファクトリ・メソッドを使用してMessagingClientオブジェクトのインスタンスを取得できます。コンシューマは、EJBや他のJava EEモジュールをそれぞれのアプリケーションにデプロイする必要はありませんが、アプリケーションのランタイム・クラスパスでUMSライブラリが使用可能であることを確認する必要があります。デプロイメントは、共有ライブラリ「oracle.sdp.client」としてです。

UMS Java APIは、次のようにグループ化されたパッケージで構成されています。

ソース・コードを含むサンプルは、Oracle Technology Network (OTN)から入手できます。

3.2 UMSクライアント・インスタンスの作成とランタイム・パラメータの指定

この項では、UMSクライアントを作成するための要件を説明します。MessagingClientインスタンスは、MessagingClientFactoryクラスのコードを使用して作成できます。具体的には、このインスタンスの作成にはMessagingClientFactory.createMessagingClient()メソッドを使用します。

クライアント・アプリケーションでは、クライアント・オブジェクトのインスタンス化の実行時に一連のパラメータを指定できます。たとえば、MessagingClientインスタンスを構成するには、複数のパラメータをキーと値のペアのマップとしてjava.util.Map<String, Object>に指定します。特に、これらの構成パラメータは、クライアント・アプリケーションの識別、UMSサーバーの指定およびセキュリティ資格証明の確立に役立ちます。クライアント・アプリケーションでは、使用可能なメカニズムを使用して構成パラメータを保存およびロードする必要があります。

表3-1に、Java APIに設定可能な構成パラメータの一部を示します。通常のユースケースでは、ほとんどのパラメータは指定する必要がなく、APIの実装では適切なデフォルト値が使用されます。

表3-1 実行時に指定する構成パラメータ

パラメータ ノート

APPLICATION_NAME

オプション。デフォルトでは、クライアントはそのデプロイメント名で識別されます。この識別子は、ApplicationInfo.APPLICATION_NAMEキーに値を指定することでオーバーライドできます。

APPLICATION_INSTANCE_NAME

オプション。指定が必要なのは、クラスタ化された特定のユースケースの場合か、セッションベースのルーティングを利用する場合のみです。

SDPM_SECURITY_PRINCIPAL

オプション。デフォルトでは、クライアントのリソースは、同じアプリケーション名のすべてのアプリケーションおよびすべてのセキュリティ・プリンシパルで使用できます。この動作は、ApplicationInfo.SDPM_SECURITY_PRINCIPALキーに値を指定することでオーバーライドできます。セキュリティ・プリンシパルが指定されている場合、アプリケーションのリソース(メッセージ、アクセス・ポイントなど)に関連する後続のすべてのリクエストは、同じセキュリティ・プリンシパルを使用して実行する必要があります。

MESSAGE_LISTENER_THREADS
STATUS_LISTENER_THREADS

オプション。メッセージまたはステータスの非同期受信にリスナーを使用する場合、リスナー・ワーカー・スレッドの数は、MessagingConstants.MESSAGE_LISTENER_THREADSおよびMessagingConstants.STATUS_LISTENER_THREADSの各キーに値を指定することで制御できます。

RECEIVE_ACKNOWLEDGEMENT_MODE
LISTENER_ACKNOWLEDGEMENT_MODE

オプション。メッセージの受信時には、次のものに値を指定して、信頼性モードを制御できます: MessagingConstants.RECEIVE_ACKNOWLEDGEMENT_MODE(同期受信)およびMessagingConstants.
LISTENER_ACKNOWLEDGEMENT_MODE(非同期受信)のキー。


MessagingClientインスタンスで使用するリソースが不要となったときに解放するには、MessagingClientFactory.remove(client)をコールします。このメソッドをコールしない場合は、ワーカー・スレッドやJMSリスナーなど一部のリソースがアクティブのまま残る場合があります。

例3-1に、プログラミングによってMessagingClientインスタンスを作成する場合のコードを示します。

例3-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からアクセスできます。

3.3 メッセージの送信

クライアント・アプリケーションでは、次に示すもののMessagingFactoryクラスを使用してメッセージ・オブジェクトを作成できます: oracle.sdp.messaging.MessagingFactory。このクラスの他のメソッドを使用して、AddressesAccessPointsMessageFiltersおよびMessageQueriesを作成できます。これらのメソッドの詳細は、ユーザー・メッセージング・サービスJava APIリファレンスを参照してください。

これで、クライアント・アプリケーションではメッセージを送信できます。APIは、メッセージの配信ステータスを取得するために後でクライアント・アプリケーションで使用できる文字列識別子を戻します。戻されたステータスは、UMSの内部処理と外部ゲートウェイから受信した配信通知に基づいた最新のステータスです。

作成できるメッセージのタイプには、プレーン・テキスト・メッセージ、text/plainパートとtext/htmlパートで構成できるマルチパート・メッセージ、および異なる配信タイプを使用して、複数受信者用の単一メッセージに配信チャネル(DeliveryType)固有のペイロードを作成するメッセージがあります。

この項の内容は次のとおりです。

3.3.1 メッセージの作成

この項では、作成できる様々なタイプのメッセージについて説明します。

3.3.1.1 プレーン・テキスト・メッセージの作成

例3-2に、UMS Java APIを使用してプレーン・テキスト・メッセージを作成する方法を示します。

例3-2 UMS Java APIを使用したプレーン・テキスト・メッセージの作成

Message message = MessagingFactory.createTextMessage("This is a Plain Text message.");

または、

Message message = MessagingFactory.createMessage();
message.setContent("This is a Plain Text message.", "text/plain");

3.3.1.2 Text/PlainパートとText/HTMLパートを持つマルチパート/代替メッセージの作成

例3-3に、UMS Java APIを使用してマルチパート・メッセージまたは代替メッセージを作成する方法を示します。

例3-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");
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");

3.3.1.3 異なる配信タイプを使用した、複数受信者用の単一メッセージへの配信チャネル固有のペイロード作成

メッセージを宛先アドレスに送信する際は、複数のチャネルが関連する場合があります。Oracle UMSアプリケーション開発者は、各チャネルに対して正しいマルチパート書式を指定する必要があります。

例3-4に、異なる配信タイプを使用して、複数受信者用の単一メッセージに、配信チャネル(DeliveryType)固有のペイロードを作成する方法を示します。

複数ペイロードのマルチパート/代替メッセージの各最上位パートには、このヘッダーの値が1つ以上含まれている必要があります。このヘッダーの値は、有効な配信タイプの名前である必要があります。DeliveryTypeの使用可能な値は、列挙DeliveryTypeを参照してください。

例3-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リファレンスからアクセスできます。

3.3.2 メッセージのアドレス指定

この項では、アドレスのタイプおよびAddressオブジェクトの作成方法について説明します。

3.3.2.1 アドレスのタイプ

アドレスには、デバイス・アドレスユーザー・アドレスの2種類があります。デバイス・アドレスには、電子メール・アドレス、インスタント・メッセージ・アドレス、電話番号など、様々なタイプがあります。ユーザー・アドレスは、ユーザー・リポジトリにあるユーザーIDです。

3.3.2.2 Addressオブジェクトの作成

Addressインタフェースで定義するAddressオブジェクトは、MessagingFactoryクラスを使用してメッセージの送信者と受信者のアドレスを指定することで作成できます。

3.3.2.2.1 単一のAddressオブジェクトの作成

例3-5に、単一のAddressオブジェクトを作成するコードを示します。

例3-5 単一のAddressオブジェクトの作成

Address recipient = MessagingFactory.createAddress("Email:john@example.com");
3.3.2.2.2 1つのバッチ内での複数のAddressオブジェクトの作成

例3-6に、1つのバッチ内に複数のAddressオブジェクトを作成するコードを示します。

例3-6 1つのバッチ内での複数のAddressオブジェクトの作成

String[] recipientsStr = {"Email:john@example.com", "SMS:123456"};
Address[] recipients = MessagingFactory.createAddress(recipientsStr);
3.3.2.2.3 メッセージへの送信者または受信者のアドレスの追加

例3-7に、送信者または受信者のアドレスをメッセージに追加するコードを示します。

例3-7 メッセージへの送信者または受信者のアドレスの追加

Address sender = MessagingFactory.createAddress("Email:john@example.com");
Address recipient = MessagingFactory.createAddress("Email:jane@example.com");
message.addSender(sender);
message.addRecipient(recipient);

3.3.2.3 フェイルオーバー・アドレスを使用した受信者の作成

例3-8に、フェイルオーバー・アドレスを使用して受信者を作成するコードを示します。

例3-8 フェイルオーバーを使用した単一のAddressオブジェクトの作成

String recipientWithFailoverStr = "Email:john@example.com, SMS:123456";
Address recipient = MessagingFactory.createAddress(recipientWithFailoverStr);

3.3.2.4 MessagingFactoryクラスのAPIリファレンス

クラスMessagingFactoryのAPIリファレンスには、ユーザー・メッセージング・サービスJava APIリファレンスからアクセスできます。

3.3.2.5 AddressインタフェースのAPIリファレンス

インタフェースAddressのAPIリファレンスには、ユーザー・メッセージング・サービスJava APIリファレンスからアクセスできます。

3.3.3 グループ・メッセージの送信

メッセージをユーザー・グループに送信するには、グループURIに送信するか、LDAPグループ(またはエンタープライズ・ロール)およびアプリケーション・ロールに送信します。

3.3.3.1 グループへのメッセージ送信

メッセージをLDAPグループまたはエンタープライズ・ロールに送信できます。メッセージは、各ユーザーの電子メール・アドレスをフェッチすることにより、ユーザーに解決されます。グループ内で指定されている特定ユーザーの電子メール・アドレスが存在しない場合、そのユーザーはスキップされます。

メッセージをグループに送信するには、例3-9で示されているように、MessagingFactoryプロパティを使用して、GROUPタイプの受信者アドレスを作成し、メッセージを送信します。

例3-9 メッセージの作成とグループへのアドレス指定

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は、最終的にはユーザー・アドレスで置換され、例3-10で示されているような結果になります。

例3-10 ユーザー・アドレスで置換されたグループ・アドレス

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);

3.3.3.2 特定チャネル経由でのメッセージのグループへの送信

グループ・メッセージの送信前に送信チャネルを指定できます。グループ・メッセージの送信チャネルを指定するには、例3-11で示されているように、グループ・アドレス(groupAddr)のDeliveryTypeプロパティを設定する必要があります。

例3-11 メッセージの作成とチャネル経由でのグループへのアドレス指定

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);

3.3.3.3 メッセージのアプリケーション・ロールへの送信

アプリケーション・ロールは、ユーザー、グループおよびその他のアプリケーション・ロールの集まりであり、階層構造にできます。アプリケーション・ロールはアプリケーション・ポリシーによって定義されます。JavaEEコンテナに認識されるとは限りません。アプリケーション・ロールの詳細は、『Oracle Fusion Middlewareアプリケーション・セキュリティ・ガイド』を参照してください。


注意:

アプリケーション・ロールは、次のロールなど、他のアプリケーション・ロールにマップできます。

  • 認証ロール: 認証に成功したユーザー。受信者が多くなる場合があります。

  • 匿名ロール: このロールの受信者はいません。


メッセージをアプリケーション・ロールに送信するには、MessagingFactoryプロパティを使用することにより、APPROLEタイプの受信者アドレスを作成する必要があります。その後、メッセージを送信する必要があります。アプリケーション・ロールはアプリケーションID (アプリケーション名またはアプリケーション・ストライプとも呼ばれます)に属します。したがって、例3-12で示されているように、これら両方のパラメータが受信者アドレス内に指定されている必要があります。

例3-12 メッセージの作成とアプリケーション・ロールへのアドレス指定

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);

アプリケーション・ロールAPPROLEは、最終的にユーザー・アドレスで置換されます。ただし、アプリケーションIDがコール元アプリケーションのIDである場合は、受信者アドレスの作成時に、アプリケーションIDを指定する必要はありません。UMSは、JpsFilter(web.xml)またはJpsInterceptor(ejb-jar.xml)のapplication.nameパラメータで指定されているアプリケーションIDを自動的にフェッチします。詳細は、『Oracle Fusion Middlewareアプリケーション・セキュリティ・ガイド』を参照してください。

3.3.3.4 特定チャネル経由でのメッセージのアプリケーション・ロールへの送信

ユーザーは、グループにメッセージを送信する場合のチャネル指定と同じようにして、送信メッセージ用チャネルを指定できます。アプリケーション・ロール・アドレスで配信タイプを設定する必要があります。

電子メールを配信チャネルとして指定するアプリケーション・ロールにメッセージを送信する例を次に示します。

例3-13 メッセージの作成とチャネル経由でのアプリケーションへのアドレス指定

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);

3.3.4 ユーザー・プリファレンス・ベースのメッセージング

ユーザー受信者にメッセージを送信(してユーザーのメッセージング・プリファレンスを活用)する際、メッセージで様々なビジネス条件の現在の値をメタデータとして渡すことができます。UMSサーバーでは、メッセージで指定されたファクトを、ユーザーのメッセージング・フィルタで指定されているビジネス条件の条件と照合します。


注意:

すべてのファクトはメタデータとしてMessage.NAMESPACE_NOTIFICATION_PREFERENCES名前空間に追加する必要があります。他の名前空間のメタデータは(ユーザー通信プリファレンスの解決においては)無視されます。


図3-14は、ユーザー受信者を指定し、メッセージのユーザー・プリファレンスでビジネス条件のファクトを指定する方法を示します。サポートされているビジネス条件の完全なリストは、第6章「ユーザー通信プリファレンス」を参照してください。

例3-14 ユーザー・プリファレンス・ベースのメッセージング

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).

3.4 メッセージ・ステータスの取得

メッセージを送信した後は、Oracle UMSを使用して、メッセージ・ステータスを同期または非同期で取得できます。

3.4.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.

3.4.2 メッセージ・ステータスの非同期取得

ステータスを非同期で受信する場合は、クライアント・アプリケーションによってListenerオブジェクトとオプションの相関機能オブジェクトが指定されます。受信ステータスが着信すると、リスナーのonStatusコールバックが起動されます。当初指定の相関機能オブジェクトもコールバック・メソッドに渡されます。

3.4.2.1 プログラムによるリスナーの作成

リスナーは純粋なプログラムです。リスナーは、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メソッドが必要に応じて起動されます。

3.4.2.2 デフォルトのステータス・リスナー

クライアント・アプリケーションでは通常、デフォルトのステータス・リスナー(例3-15)が設定されます。クライアント・アプリケーションでメッセージが送信されると、そのメッセージの配信ステータス・コールバックによって、デフォルト・リスナーのonStatusメソッドが起動されます。

例3-15 デフォルトのステータス・リスナー

messagingClient.setStatusListener(new MyStatusListener());
messagingClient.send(message);

3.4.2.3 メッセージごとのステータス・リスナー

この方法では、クライアント・アプリケーションによってメッセージが送信され、リスナー・オブジェクトとオプションの相関機能オブジェクトが指定されます(例3-16)。該当するメッセージに対して配信ステータス・コールバックが使用できる場合は、指定したリスナーのonStatusメソッドが起動されます。当初指定の相関機能オブジェクトもコールバック・メソッドに渡されます。

例3-16 メッセージごとのステータス・リスナー

messagingClient.send(message, new MyStatusListener(), null);

3.5 メッセージの受信

この項では、アプリケーションでメッセージを受信する方法について説明します。メッセージを受信するには、最初にアクセス・ポイントを登録する必要があります。

着信メッセージを受信するアプリケーションでは、メッセージの受信者アドレスを表すアクセス・ポイントを1つ以上登録する必要があります。サーバーでは、着信メッセージの受信者アドレスと一連の登録済アクセス・ポイントを照合し、一致したアクセス・ポイントを登録したアプリケーションに、その着信メッセージをルーティングします。アプリケーション側から見ると、メッセージを受信するモードには同期と非同期があります。

3.5.1 アクセス・ポイントの登録

クライアント・アプリケーションではアクセス・ポイントを作成して登録し、特定のアドレスに送信された着信メッセージを受信するように指定できます。クライアント・アプリケーションにはメッセージ・リスナーが指定されていないため、受信したすべてのメッセージはUMSに保持されます。この場合、クライアント・アプリケーションでは、受信メソッドを起動して保留中のメッセージをフェッチできます。アクセス・ポイントの指定なしでメッセージを受信した場合、アプリケーションでは、登録したすべてのアクセス・ポイントのメッセージを受信します。そうでない場合、アプリケーションでは、そのアクセス・ポイントに送信されたメッセージを受信します。

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);

3.5.2 同期受信

受信は非ブロック操作です。アプリケーションやアクセス・ポイントに関して保留中のメッセージがない場合、該当するコールでは、NULLが即時に戻されます。受信によって、すべての使用可能なメッセージが戻される保証はありませんが、効率上の理由から使用可能なメッセージのサブセットのみを戻すことはできます。

メソッドMessagingClient.receiveを使用して、UMSがアプリケーションで使用可能にしたメッセージを同期受信できます。このメソッドは、メッセージの非同期受信による構成オーバーヘッドを望まない軽量なクライアント向けの便利なポーリング・メソッドです。このメソッドは、アプリケーションのインバウンド・キューですぐに使用できるメッセージの配列を戻します。


注意:

1回の起動で、使用可能なメッセージがすべて取得される保証はありません。ポーリングして、使用可能なすべてのメッセージを受信したことを確認する必要があります。


3.5.3 非同期受信

メッセージを非同期で受信する場合は、クライアント・アプリケーションによってアクセス・ポイントが登録され、Listenerオブジェクトとオプションの相関機能オブジェクトが指定されます。受信メッセージが指定のアクセス・ポイント・アドレスに着信すると、リスナーのonMessageコールバックが起動されます。当初指定の相関機能オブジェクトもコールバック・メソッドに渡されます。

3.5.3.1 プログラムによるリスナーの作成

リスナーは純粋なプログラムです。リスナーは、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メソッドが起動されます。

3.5.3.2 デフォルトのメッセージ・リスナー

クライアント・アプリケーションでは通常、デフォルトのメッセージ・リスナー(例3-17)が設定されます。このリスナーは、このクライアント・アプリケーションによって送信されたメッセージの中で、関連するリスナーがないメッセージの配信ステータスに対して起動されます。Oracle UMSでは、このクライアント・アプリケーションによって登録されたアクセス・ポイント宛てのメッセージを受信すると、そのクライアント・アプリケーションのデフォルトのリスナーに対してonMessageコールバックが起動されます。

デフォルトのリスナーを削除するには、nullの引数を指定してこのメソッドをコールします。

例3-17 デフォルトのメッセージ・リスナー

messagingClient.setMessageListener(new MyListener());

非同期受信の詳細な手順については、サンプル・アプリケーションusermessagingsample-echoを参照してください。

3.5.3.3 アクセス・ポイントごとのメッセージ・リスナー

クライアント・アプリケーションでは、アクセス・ポイントを登録し、Listenerオブジェクトとオプションの相関機能オブジェクトを指定できます(例3-18)。受信メッセージが指定のアクセス・ポイント・アドレスに着信すると、指定したリスナーのonMessageメソッドが起動されます。当初指定の相関機能オブジェクトもコールバック・メソッドに渡されます。

例3-18 アクセス・ポイントごとのメッセージ・リスナー

messagingClient.registerAccessPoint(accessPoint, new MyListener(), null);

3.5.4 メッセージ・フィルタ

アプリケーションで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);

3.6 クラスタ環境の構成

APIでは、クラスタ環境にクライアント・アプリケーションとUMSサーバーがデプロイされている環境をサポートしています。クラスタ化されたデプロイメントが期待どおりに機能するためには、クライアント・アプリケーションを正しく構成する必要があります。次のルールが適用されます。

3.7 XAトランザクションに対するUMSクライアントAPIの使用

UMSは、アウトバウンド・メッセージとインバウンド・メッセージのXA対応トランザクションに対するサポートを提供します。業界標準であるX/Open XAプロトコルは、Business Process Management (BPM)など、他のOracle製品でも幅広くサポートされています。


注意:

XAサポート機能は、UMSサーバーおよびUMSクライアントに含まれているので、インストールする必要はありません。また、XAサポートは、WebサービスAPIではなく、POJO APIでのみ可能です。


3.7.1 XAトランザクションについて

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フェーズ・コミット・トランザクション・プロトコルを使用する分散トランザクション処理システムに、リソース・マネージャとして参加できます。

3.7.2 XA対応メッセージの送受信

XAサポートにより、UMSは、トランザクションがコミットされるときにのみトランザクション境界内からメッセージを送信できます。トランザクションがロールバックされると、メッセージの送信は失敗します。コミットはトランザクションの成功につながりますが、ロールバックではメッセージは変更されないままになります。UMSは、アウトバウンド・メッセージとインバウンド・メッセージ両方に対するXAトランザクション・サポートを提供します。

XAを使用したアウトバウンド・メッセージング

UMSクライアント・アプリケーションからUMSサーバー経由で受信者に送信されるメッセージは、アウトバウンド・メッセージと呼ばれます。XAトランザクションがUMSクライアント上で有効な場合、アウトバウンド・メッセージは、トランザクションがコミットされた場合のみ、UMSサーバーに送信されます。トランザクションが成功すると、メッセージは安全に格納され、受信者への配信準備が整った状態になります。クライアント・トランザクションがコミットに失敗し、ロールバックが発生すると、メッセージは配信に向けてUMSサーバーに送信されません。

次のコードの抜粋では、XAを使用したアウトバウンド・メッセージの送信方法を示しています。

transaction.begin();
String messageID = mClient.send(message);
transaction.commit();

XAを使用したインバウンド・メッセージング

次のコードの抜粋では、XAを使用したインバウンド・メッセージの受信方法を示しています。

UMSサーバーからUMSドライバにより受信され、その後UMSクライアントにルーティングされるメッセージは、インバウンド・メッセージと呼ばれます。XAトランザクションがUMSクライアント上で有効な場合、インバウンド・メッセージは、トランザクションがコミットされた場合のみ、UMSサーバーから取得され、UMSサーバー・ストアから削除されます。トランザクション・ロールバックが発生した場合、メッセージは後で再配信できるようにUMSサーバー上で変更されないまま維持されます。

transaction.begin();
messages = mClient.receive();
 
        for (Message receivedMessage : messages) {
                        // process individual messages here.
}
transaction.commit();

外部XAトランザクションがクライアントによってコミットされると、UMSドライバによって受信されたメッセージは、UMSサーバーから完全に削除されます。トランザクションがコミットに失敗し、ロールバックが発生すると、メッセージは、トランザクションのタイムアウト後に受信されます。このメッセージは、trueを返すgetJMSRedeliveredメソッドにより再配信されます。このメソッドの詳細は、ユーザー・メッセージング・サービスJava APIリファレンスを参照してください。

トランザクションのタイムアウトは、setTransactionTimeoutのコールにより変更できます。サーバー・クラッシュによりコミットに失敗したメッセージを受信するには、サーバーとクライアントを再起動するか、特定のサーバー移行手順を実行する必要があります。詳細は、『Oracle Fusion Middleware Oracle WebLogic Server JMSの構成と管理』の「拡張JMSシステム・リソースの構成」を参照してください。

XAトランザクション用リスナーの使用

メッセージの受信中にトランザクション内でリスナーを使用することもできます。これは、定数MessagingConstants.LISTENER_TRANSACTED_MODEを指定することによって行います。MessagingClientインスタンスの作成時に、この定数の値をTRUEまたはFALSEに設定します。次の例を参照してください。


注意:

リスナーを使用する場合、メッセージング定数LISTENER_TRANSACTED_MODEがTRUEに設定されていると、例外が発生しないときに、トランザクションがコミットされます。LISTENER_TRANSACTED_MODEがFALSEに設定されている場合、トランザクションは例外とは関係なくコミットされます。

トランザクションのロールバックを行う場合、例外を適切に設定してください。ListenerExceptionの詳細は、ユーザー・メッセージング・サービスJava APIリファレンスを参照してください。


例3-19 リスナーを使用したXA対応メッセージの受信

Map<String, Object> params = new HashMap<String, Object>();
params.put(MessagingConstants.LISTENER_TRANSACTED_MODE, Boolean.TRUE);
MessagingClient mClient = MessagingClientFactory.createMessagingClient(params);

mClient.registerAccessPoint(MessagingFactory.createAccessPoint(receiverAddr),
new MyListener(), 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

例3-20 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()

3.8 UMS Java APIを使用したメッセージ再送信の指定

UMSでは、メッセージ送信が失敗した場合のメッセージ再送信をスケジュールできます。次の例に示されているように、setMaxResendメソッドをコールすることにより、メッセージ再送信の最大回数を指定できます。

MessageInfo msgInfo = message.getMessageInfo();
msgInfo.setMaxResend(1);
String mid = messagingClient.send(message);

フェイルオーバー・アドレスのステータスは、getTotalFailovers()およびgetFailoverOrder()のコールにより受信できます。フェイルオーバーの順序がフェイルオーバー総数と同じになると、APIユーザーには、フェイルオーバー・チェーンがすべて使用済であることがわかります。ただし、再送信機能は、フェイルオーバー・チェーンのループとして動作します。getMaxResend()getCurrentResend()をコールして、再送信とフェイルオーバー・チェーンがすべて使用済となるタイミングを知ることができます。

setMaxResendgetTotalFailoversgetFailoverOrderなどのメソッドの詳細は、ユーザー・メッセージング・サービスJava APIリファレンスを参照してください。

3.9 セキュリティの構成

クライアント・アプリケーションには、セキュアなリスナーを確立するために、1つ以上の追加構成パラメータの指定が必要な場合があります(表3-1を参照)。

3.10 スレッド・モデル

通常、UMS Java APIを使用するクライアント・アプリケーションはマルチスレッド化されています。通常のシナリオにはEJBインスタンスのプールが含まれ、各シナリオではMessagingClientインスタンスと、Webコンテナの複数のスレッドによって提供されるサーブレット・インスタンスが使用されます。UMS Java APIは、次のスレッド・モデルをサポートしています。

次に、典型的なユースケースを示します。

3.10.1 リスナー・スレッド

第3.4.2項「メッセージ・ステータスの非同期取得」第3.5.3項「非同期受信」で説明されている非同期受信については、UMSはデフォルトで、受信メッセージ用に1つのスレッド、受信ステータス通知用に1つのスレッドを使用します(それぞれ、少なくとも1つのメッセージ・リスナーまたはステータス・リスナーが登録されているものとします)。クライアント・アプリケーションでは、追加のワーカー・スレッドを構成して非同期処理の同時性を向上させることができます。これを実行するには、MessagingConstants.MESSAGE_LISTENER_THREADSキーとMessagingConstants.STATUS_LISTENER_THREADSキーに整数値を指定し、これらの値をMessagingClientインスタンスの作成時に使用した構成パラメータで、必要なワーカー・スレッドの数に設定します。