CORBA通知サービスの使用

     前  次    新規ウィンドウで目次を開く  新規ウィンドウで索引を開く  PDFとして表示 - 新規ウィンドウ  Adobe Readerを取得 - 新規ウィンドウ
コンテンツはここから始まります

CosNotificationサービスAPIの使い方

この章では、CosNotificationサービスAPIとC++プログラミング言語を使用して通知サービス・アプリケーションを作成するための開発手順を説明します。

ここでは、以下の内容について説明します。

注意: Oracle Tuxedo CORBA JavaクライアントとOracle Tuxedo CORBA JavaクライアントORBはTuxedo 8.1で非推奨になり、サポートされなくなりました。すべてのOracle Tuxedo CORBA JavaクライアントおよびOracle Tuxedo CORBA JavaクライアントORBのテキスト・リファレンスとコード・サンプルは、サード・パーティのJava ORBライブラリを実装または実行する際の参考や、プログラマの参照用としてのみ使用してください。
注意: サード・パーティのCORBA Java ORBのテクニカル・サポートは、各ベンダーによって提供されます。Oracle Tuxedoでは、サード・パーティのCORBA Java ORBに関する技術的なサポートやドキュメントは提供していません。

 


開発プロセス

表4-1は、通知サービス・アプリケーションの開発プロセスの概略です。

表4-1 開発プロセス
手順
説明
1
イベントの設計
2
イベントをポストするアプリケーションの記述
3
イベントをサブスクライブするアプリケーションの記述
4
通知サービス・アプリケーションのコンパイル

これらの手順については、以降の項で説明します。

 


イベントの設計

イベントの設計は、あらゆる通知サービスの基本です。この設計は、一致するサブスクリプションに配信される情報の量だけでなく、通知サービスの効率とパフォーマンスにも影響します。したがって、計画を慎重に行って、通知サービスが現在のニーズだけでなく将来の規模拡大にも対応できるようにする必要があります。イベント設計の説明については、「イベントの設計」を参照してください。

 


ステップ1:イベントをポストするアプリケーションの記述

次のタイプのCORBAアプリケーションは、イベントをポストできます。

イベントをポストするために、アプリケーションでは最低でも次の機能を実装する必要があります。

以降の項では、これらの各機能について説明します。

イベント・チャネルの取得

最初にイベント・チャネルを取得しないと、クライアント・アプリケーションではイベントをポストできません。

この開発ステップは、リスト 4-1で示されています。リスト 4-1は、CosNotificationサービスAPIを使用するIntroductoryサンプル・アプリケーションのReporter.cppファイルのコードです。

イベント・チャネル・ファクトリのオブジェクト参照を取得するために、"NotificationService"環境オブジェクトを使用してBootstrapオブジェクトのresolve_initial_referencesメソッドが呼び出されます。取得したオブジェクト参照は、チャネル・ファクトリを取得するために使用します。チャネル・ファクトリは、イベント・チャネルを取得するために使用します。コード・リスト 4-1は、C++のサンプル・コードを示しています。

リスト4-1 イベント・チャネルの取得(Reporter.cpp)
// Get the CosNotification channel factory object reference.
CORBA::Object_var channel_factory_oref =
       bootstrap.resolve_initial_references(
        "NotificationService" );
CosNotifyChannelAdmin::EventChannelFactory_var
   channel_factory =
       CosNotifyChannelAdmin::EventChannelFactory::_narrow(
          channel_factory_oref.in() );
// use the channel factory to get the default channel
CosNotifyChannelAdmin::EventChannel_var channel =
   channel_factory->get_event_channel(
       Tobj_Notification::DEFAULT_CHANNEL );

イベントの作成とポスト

イベントをポストするには、SupplierAdminオブジェクトを取得し、そのオブジェクトを使用してプロキシを作成し、イベントを作成して、そのイベントをプロキシにポストする必要があります。

リスト 4-2は、C++での実装を示しています。

リスト4-2 イベントの作成とポスト(Reporter.cpp)
// Since we are a supplier (that is, we post events),
// get the SupplierAdmin object
CosNotifyChannelAdmin::SupplierAdmin_var supplier_admin =
       channel->default_supplier_admin();
// Use the supplier admin to create a proxy. Events are posted
// to the proxy (unlike the simple events interface where events
// are posted to the channel).
CosNotifyChannelAdmin::ProxyID proxy_id;
CosNotifyChannelAdmin::ProxyConsumer_var generic_proxy_consumer =
     supplier_admin->obtain_notification_push_consumer(
       CosNotifyChannelAdmin::STRUCTURED_EVENT, proxy_id );
CosNotifyChannelAdmin::StructuredProxyPushConsumer_var
   proxy_push_consumer =
     CosNotifyChannelAdmin::StructuredProxyPushConsumer::_narrow(
       generic_proxy_consumer );
// Connect to the proxy so that we can post events.
proxy_push_consumer->connect_structured_push_supplier(
     CosNotifyComm::StructuredPushSupplier::_nil() );
...
// create an event
  CosNotification::StructuredEvent notification;
// set the domain to "News"
notification.header.fixed_header.event_type.domain_name =
    CORBA::string_dup("News");
// set the type to the news category
notification.header.fixed_header.event_type.type_name =
    CORBA::string_dup(“Sports”);
// add one field, which will contain the story, to the
// event's filterable data. set the field's name to
// "Story" and value to a string containing the story
notification.filterable_data.length(1);
notification.filterable_data[0].name =
           CORBA::string_dup("Story");
notification.filterable_data[0].value <<= “John Smith wins again”;
// post the event
// Subscribers who subscribed to events whose domain is
// "News" and whose type matches the news category will
// receive this event
proxy_push_consumer->push_structured_event(notification);
...
// Disconnect.
proxy_push_consumer->disconnect_structured_push_consumer();

 


ステップ2:イベントをサブスクライブするアプリケーションの記述

次のタイプのCORBAアプリケーションは、イベントをサブスクライブできます。

イベントをサブスクライブするために、アプリケーションでは最低でも次の機能をサポートする必要があります。

CosNotifyComm::StructuredPushConsumerインタフェースの実装

コールバック・サーバーント・オブジェクトでイベントを受信するためには、push_structured_eventオペレーションをサポートするCosNotifyComm::StructuredPushConsumerインタフェースを実装する必要があります。一致するサブスクリプションがあるイベントが発生すると、通知サービスではサブスクライバ・アプリケーションのサーバーント・コールバック・オブジェクトのこのオペレーションを呼び出してイベントをサブスクライバ・アプリケーションに配信します。

CosNotifyComm::StructuredPushConsumerインタフェースでは、offer_changeおよびdisconnect_structured_push_consumerというオペレーションも定義されます。これらのオペレーションは通知サービスで呼び出されないので、CORBA::NO_IMPLEMENTをスローするスタブ・アウト・バージョンを実装する必要があります。

リスト 4-3リスト 4-4は、このインタフェースがC++でどのように実装されるのかを示しています。

リスト4-3 CosNotifyComm::StructuredPushConsumerインタフェースのサンプル実装(NewsConsumer_i.h)
#ifndef _news_consumer_i_h
#define _news_consumer_i_h
#include "CosNotifyComm_s.h"
// For the servant class to receive news events,
// it must implement the CosNotifyComm::StructuredPushConsumer
// idl interface
class NewsConsumer_i : public POA_CosNotifyComm::StructuredPushConsumer
{
  public:
    // this method will be called when a news event occurs
    virtual void push_structured_event(
      const CosNotification::StructuredEvent& notification
    );
    // OMG's CosNotifyComm::StructuredPushConsumer idl
    // interface defines the methods "offer_change" and
    // "disconnect_structured_push_consumer". Since the
    // Notification Service never invokes these methods, just
    // have them throw a CORBA::NO_IMPLEMENT exception
    virtual void offer_change(
      const CosNotification::EventTypeSeq& added,
      const CosNotification::EventTypeSeq& removed )
    {
      throw CORBA::NO_IMPLEMENT();
    }
    virtual void disconnect_structured_push_consumer()
    {
      throw CORBA::NO_IMPLEMENT();
    }
};
#endif
リスト4-4 CosNotifyComm::StructuredPushConsumerインタフェースのサンプル実装(NewsConsumer_i.cpp)
#include "NewsConsumer_i.h"
#include <iostream.h>
//-----------------------------------------------------------
// Subscriber.cpp creates a simple events subscription to "News"
// events and has the events delivered to a NewsConsumer_i
// object. When a news event occurs (this happens when a user
// runs the Reporter application and reports a news story), this
// method will be invoked:
void NewsConsumer_i::push_structured_event(
  const CosNotification::StructuredEvent& notification )
  {
// extract the story from the first field in the event's
// filterable data
char* story;
notification.filterable_data[0].value >>= story;
// for coding simplicity, assume "story" is not "null"
// print out the event
cout
    << "-----------------------------------------------------"
    << endl
    << "Category : "
    << notification.header.fixed_header.
              v            event_type.type_name.in()
    << endl
    << "Story : "
    << story
    << endl;
...
}

イベント・チャネル、ConsumerAdminオブジェクト、およびフィルタ・ファクトリ・オブジェクトの取得

最初にイベント・チャネル、ConsumerAdminオブジェクト、およびフィルタ・ファクトリ・オブジェクトを取得しないと、アプリケーションではサブスクリプションを作成できません。リスト 4-5は、C++での実装を示しています。

イベント・チャネル・ファクトリのオブジェクト参照を取得するために、"NotificationService"環境オブジェクトを使用してBootstrapオブジェクトのresolve_initial_referencesメソッドが呼び出されます。取得したオブジェクト参照は、チャネル・ファクトリを取得するために使用します。チャネル・ファクトリは、イベント・チャネルを取得するために使用します。最後に、イベント・チャネルはConsumerAdminオブジェクトとFilterFactoryオブジェクトを取得するために使用します。

リスト4-5 イベント・チャネル、ConsumerAdminオブジェクト、およびフィルタ・ファクトリ・オブジェクトの取得(Subscriber.cpp)
// Get the CosNotification channel factory object reference.
CORBA::Object_var
  channel_factory_oref =
     bootstrap.resolve_initial_references(
          "NotificationService" );
   channel_factory =
      CosNotifyChannelAdmin::EventChannelFactory::_narrow(
          channel_factory_oref.in() );
// Use the channel factory to get the default channel.
CosNotifyChannelAdmin::EventChannel_var channel =
   channel_factory->get_event_channel(
      Tobj_Notification::DEFAULT_CHANNEL );
// Use the channel to get the consumer admin and the filter factory.
CosNotifyChannelAdmin::ConsumerAdmin_var consumer_admin =
   channel->default_consumer_admin();
CosNotifyFilter::FilterFactory_var filter_factory =
   channel->default_filter_factory();

コールバック・オブジェクトの作成

イベントを受信するためには、アプリケーションはサーバーであることも必要です。つまり、アプリケーションでは、サブスクライバのサブスクリプションと一致するイベントが発生したときに呼び出すことができるコールバック・オブジェクトを実装しなければなりません。

コールバック・オブジェクトを作成する手順は次のとおりです。

注意: この手順は、共同クライアント/サーバーでの手順です。Oracle Tuxedo CORBAサーバーでもイベントをサブスクライブできます。
  1. コールバック・ラッパー・オブジェクトを作成します。コールバック・ラッパー・オブジェクトは、BEAWrapperコールバック・オブジェクトまたはCORBAポータブル・オブジェクト・アダプタ(POA)を使用して実装できます。
  2. サーバーントを作成します。
  3. コールバック・サーバーントのオブジェクト参照を作成します。

BEAWrapperコールバック・オブジェクトとそのメソッドの詳細は、『CORBAプログラミング・リファレンス』の「共同クライアント/サーバー」を参照してください。

注意: BEAWrapperコールバック・オブジェクトを使用してコールバック・オブジェクトを作成する方法は、以下に説明します。POAを使用してコールバック・オブジェクトを実装する方法については、『CORBAサーバー間通信の使用』を参照してください。

リスト 4-6は、C++で、BEAWrapperコールバック・オブジェクトを使用してコールバック・オブジェクトを作成する方法を示しています。サンプル・コードでは、NewsConsumber_i servantが作成され、start_transientメソッドを使用して一時的なオブジェクト参照が作成されます。

リスト4-6 一時的なオブジェクト参照でコールバック・オブジェクトを作成するサンプル・コード(Introductoryサンプル・アプリケーションのSubscriber.cpp)
// Create a callback wrapper object since this client needs to
// support callbacks
BEAWrapper::Callbacks wrapper(orb.in());
NewsConsumer_i* news_consumer_impl = new NewsConsumer_i;
// Create a transient object reference to this servant.
CORBA::Object_var news_consumer_oref =
       wrapper.start_transient(
         news_consumer_impl,
         CosNotifyComm::_tc_StructuredPushConsumer->id()
          );
CosNotifyComm::StructuredPushConsumer_var
    news_consumer =
       CosNotifyComm::StructuredPushConsumer::_narrow(
           news_consumer_oref.in() );

サブスクリプションの作成

サブスクライバでイベントを受信するためには、通知サービスをサブスクライブする必要があります。一時的なサブスクリプションまたは永続的なサブスクリプションのいずれかを作成できます。

サブスクリプションを作成するには、次の手順を実行する必要があります。

  1. 通知プロキシ・プッシュ・サプライヤを作成し、それを利用してStructuredProxySupplierオブジェクトを作成します。
  2. サブスクリプションのサービスの品質(QoS)を設定します。QoSは、一時的または永続的に設定できます。
  3. フィルタ・オブジェクトを作成し、domain_nametype_name、およびdata_filter (オプション)を割り当てます。
  4. フィルタをプロキシに追加します。
  5. サブスクリプションのコールバック・オブジェクト参照を渡してプロキシに接続します。

Introductoryサンプル・アプリケーションのコードであるリスト 4-7は、C++で一時的なサブスクリプションを作成する方法を示しています。

リスト4-7 一時的なサブスクリプションの作成
// Create a new subscription (at this point, it is not complete).
CosNotifyChannelAdmin::ProxyID subscription_id;
CosNotifyChannelAdmin::ProxySupplier_var generic_subscription =
      consumer_admin->obtain_notification_push_supplier(
          CosNotifyChannelAdmin::STRUCTURED_EVENT,
          subscription_id );
CosNotifyChannelAdmin::StructuredProxyPushSupplier_var
     subscription =
       CosNotifyChannelAdmin::StructuredProxyPushSupplier::_narrow(
            generic_subscription );
      s_subscription = subscription.in();
  // Set the quality of service. This sets the subscription name
  // and subscription type (=TRANSIENT).
  CosNotification::QoSProperties qos;
  qos.length(2);
  qos[0].name =
     CORBA::string_dup(Tobj_Notification::SUBSCRIPTION_NAME);
  qos[0].value <<= subscription_name;
  qos[1].name =
     CORBA::string_dup(Tobj_Notification::SUBSCRIPTION_TYPE);
  qos[1].value <<=
     Tobj_Notification::TRANSIENT_SUBSCRIPTION;
  subscription->set_qos(qos);
  // Create a filter (used to specify domain, type and data filter).
  CosNotifyFilter::Filter_var filter =
           filter_factory->create_filter(
            Tobj_Notification::CONSTRAINT_GRAMMAR );
  s_filter = filter.in();
    // Set the filtering parameters.
    // (domain = "News", type = “Sports”, and no data filter)
    CosNotifyFilter::ConstraintExpSeq constraints;
    constraints.length(1);
    constraints[0].event_types.length(1);
    constraints[0].event_types[0].domain_name =
CORBA::string_dup("News");
    constraints[0].event_types[0].type_name =
CORBA::string_dup(“Sports”);
    constraints[0].constraint_expr =
CORBA::string_dup(""); // No data filter.
    CosNotifyFilter::ConstraintInfoSeq_var
        add_constraints_results = // ignore this returned value
            filter->add_constraints(constraints);
    // Add the filter to the subscription.
    CosNotifyFilter::FilterID filter_id =
       subscription->add_filter(filter.in());
    // Now that we have set the subscription name, type and filtering
    // parameters, complete the subscription by passing in the
    // reference of the callback object to deliver the events to.
    subscription->connect_structured_push_consumer(
         news_consumer.in() );

 


ステップ3:通知サービス・アプリケーションのコンパイルと実行

通知サービス・アプリケーション開発の最後のステップでは、アプリケーションをコンパイル、ビルド、および実行します。そのためには、次の手順を実行する必要があります。

  1. 通知サービスとイベント・ポスト元アプリケーションおよびイベント・サブスクライバ・アプリケーションの間のインタフェースを定義するために必要なクライアント・スタブ・ファイルとスケルトン・ファイルを生成します。イベント・ポスト元アプリケーションとしては、クライアント、共同クライアント/サーバー、またはサーバーが考えられます。イベント・サブスクライバ・アプリケーションとしては、共同クライアント/サーバーまたはサーバーが考えられます。
  2. アプリケーション・コードをコンパイルし、スケルトン・ファイルおよびクライアント・スタブ・ファイルに対してリンクします。
  3. アプリケーションをビルドします。
  4. アプリケーションを実行します。

クライアント・スタブ・ファイルとスケルトン・ファイルの生成

クライアント・スタブ・ファイルとスケルトン・ファイルを生成するには、アプリケーションで使用される通知IDLファイルごとにidlコマンドを実行する必要があります。表4-2は、各タイプのサブスクライバで使用するidlコマンドを示しています。

表4-2 idlコマンドの要件
言語
Oracle Tuxedo CORBA共同クライアント/サーバー
Oracle Tuxedo CORBAサーバー
C++
idl -P
idl

次に、idlコマンドの例を示します。

>idl -IC:\tuxdir\include C:\tuxdir\include\CosEventComm.idl

表4-3は、各タイプの通知サービス・アプリケーションで必要なIDLファイルを示しています。

表4-3 通知サービス・アプリケーションで必要なIDLファイル
アプリケーション・タイプ
必要なOMG IDLファイル
イベント・ポスト元(クライアント、共同クライアント/サーバー、またはサーバー)
CosEventChannelAdmin.idl CosEventComm.idl CosNotification.idl CosNotifyChannelAdmin
CosNotifyComm.idl CosNotifyFilter Tobj_Events.idl Tobj_Notification.idl
サブスクライバ(共同クライアント/サーバーまたはサーバー)
CosEventChannelAdmin.idl CosEventComm.idl CosNotification.idl CosNotifyChannelAdmin CosNotifyComm.idl CosNotifyFilter Tobj_Events.idl Tobj_Notification.idl

アプリケーション・コードのコンパイルとリンク

コンパイルとリンクの手続きは、通知サービス・アプリケーションのタイプによって異なります。表4-4は、各タイプのアプリケーションをコンパイルするために使用するコマンドとファイルの概要を示しています。

表4-4 アプリケーションのビルド要件
アプリケーション・タイプ
クライアント
共同クライアント/サーバー
サーバー
C++のイベント・ポスト元
buildobjclientコマンドを使用して、アプリケーション・ファイルとIDLスタブをコンパイルします。
-Pオプションを設定したbuildobjclientコマンドを使用して、アプリケーション・ファイルとIDLスタブをコンパイルします。
buildobjserverコマンドを使用して、アプリケーション・ファイルとIDLクライアント・スタブをコンパイルします。
C++のイベント・サブスクライバ
適用されません。
-Pオプションを設定したbuildobjclientコマンドを使用して、アプリケーション・ファイル、IDLスタブ、およびIDLスケルトンをコンパイルします。
buildobjserverコマンドを使用して、アプリケーション・ファイル、IDLスタブ、およびIDLスケルトンをコンパイルします。

リスト 4-8は、Microsoft Windowsシステム上のC++ Reporterアプリケーション(Reporter.cpp)で使用するコマンドを示しています。C++の実行可能ファイルを作成するために、idlコマンドが必要なIDLファイルで実行され、buildobjclientコマンドによってC++クライアント・アプリケーション・ファイルとIDLスタブがコンパイルされます。

リスト4-8 C++ Reporterアプリケーションのビルドと実行のコマンド
# Run the idl command.
idl -IC:\tuxdir\include C:\tuxdir\include\CosEventComm.idl \
C:\tuxdir\include\CosEventChannelAdmin \
C:\tuxdir\include\CosNotification.idl \
C:\tuxdir\include\CosNotifyComm.idl \
C:\tuxdir\include\CosNotifyFilter.idl \
C:\tuxdir\include\Tobj_Notification.idl
# Run the buildobjclient command.
buildobjclient -v -o is_reporter.exe -f ”\
    -DWIN32 \
    Reporter.cpp \
    CosEventComm_c.cpp \
    CosEventChannelAdmin_c.cpp \
    CosNotification_c.cpp \
    CosNotifyComm_c.cpp \
    CosNotifyFilter_c.cpp \
    CosNotifyChannelAdmin_c.cpp \
    Tobj_Events_c.cpp \
    Tobj_Notification_c.cpp ”
# Run the application.
is_reporter

リスト 4-9リスト 4-10は、それぞれMicrosoft WindowsおよびUNIX上のC++ Subscriberアプリケーション(Subscriber.cpp)で使用するコマンドを示しています。C++の実行可能ファイルを作成するために、-Pオプションを設定したbuildobjclientコマンドによって、共同クライアント/サーバー・アプリケーション・ファイル(Subscriber.cppNewsConsumer_i.cpp)、IDLスタブ、およびIDLスケルトン(CosNotifyComm_s.cpp用)がコンパイルされます。

リスト4-9 C++ Subscriberアプリケーションのビルドと実行のコマンド(Microsoft Windows)
# Run the idl command.
idl -P -IC:\tuxdir\include C:\tuxdir\include\CosEventComm.idl \
C:\tuxdir\include\CosEventChannelAdmin \
C:\tuxdir\include\CosNotification.idl \
C:\tuxdir\include\CosNotifyComm.idl \
C:\tuxdir\include\CosNotifyFilter.idl \
C:\tuxdir\include\CosNotifyChannelAdmin \ \C:\tuxdir\include\Tobj_Events.idl \
\C:\tuxdir\include\Tobj_Notification
# Run the buildobjclient command.
buildobjclient -v -P -o is_subscriber.exe -f " \
   -DWIN32 \
    Subscriber.cpp \
    NewsConsumer_i.cpp \
    CosEventComm_c.cpp \
    CosEventChannelAdmin_c.cpp \
    CosNotification_c.cpp \
    CosNotifyComm_c.cpp \
    CosNotifyComm_s.cpp \
    CosNotifyFilter_c.cpp \
    CosNotifyChannelAdmin_c.cpp \
    Tobj_Events_c.cpp \
    Tobj_Notification_c.cpp \
    C:\tuxdir\lib\libbeawrapper.lib \
    "
# Run the application.
is_subscriber
リスト4-10 C++ Subscriberアプリケーションのビルドと実行のコマンド(UNIX)
# Run the idl command.
idl -P -I/usr/local/tuxdir/include /usr/local/tuxdir/include/CosEventChannelAdmin \
/usr/local/tuxdir/include/CosEventComm.idl \
/usr/local/tuxdir/include/CosNotification.idl \
/usr/local/tuxdir/include/CosNotifyComm.idl \
/usr/local/tuxdir/include/CosNotifyFilter.idl \
/usr/local/tuxdir/include/CosNotifyChannelAdmin \
/usr/local/tuxdir/include/Tobj_Events.idl \
/usr/local/tuxdir/include/Tobj_SimpleEvents.idl
# Run the buildobjclient command.
buildobjclient -v -P -o subscriber -f " \
  Subscriber.cpp \
  NewsConsumer_i.cpp \
  CosEventComm_c.cpp \
  CosEventChannelAdmin_c.cpp \
  CosNotification_c.cpp \
  CosNotifyComm_c.cpp \
  CosNotifyComm_s.cpp \
  CosNotifyFilter_c.cpp \
  CosNotifyChannelAdmin_c.cpp \
  Tobj_Events_c.cpp \
  Tobj_SimpleEvents_c.cpp \
  -lbeawrapper \
"
# Run the application.
is_subscriber

  先頭に戻る       前  次