CORBA通知サービスの使用

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

Oracleシンプル・イベントAPIの使い方

この章では、Oracleシンプル・イベント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に関する技術的なサポートまたはドキュメントは提供していません。

 


開発プロセス

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

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

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

 


イベントの設計

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

 


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

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

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

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

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

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

この開発ステップは、リスト3-1で示されています。リスト3-1は、Oracleシンプル・イベントAPIを使用するNotification Serviceサンプル・アプリケーションに基づいています。

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

リスト3-1 イベント・チャネルの取得(C++)
// Get the Simple Events channel factory object reference.
CORBA::Object_var channel_factory_oref =
  bootstrap.resolve_initial_references(
                     "Tobj_SimpleEventsService");
Tobj_SimpleEvents::ChannelFactory_var channel_factory =
  Tobj_SimpleEvents::ChannelFactory::_narrow(
                     channel_factory_oref.in());
// Use the channel factory to get the default channel.
Tobj_SimpleEvents::Channel_var channel =
  channel_factory->find_channel(
                     Tobj_SimpleEvents::DEFAULT_CHANNEL);

イベントの作成とポスト

イベントをポストするには、まずイベントを作成しなければなりません。以下のリストは、Notification Serviceサンプル・アプリケーションに基づいています。

リスト3-2は、C++での実装を示しています。イベント・チャネルにニュースを報告するために、このアプリケーションでは次の手順が実行されます。

  1. イベントを作成し、ドメイン名と型名を設定します。コード・サンプルでは、ドメイン名は「News」、イベント型は「Sports」に設定されます。
  2. ニュース記事を格納するフィールドをイベントのフィルタ処理可能データに追加して、その追加フィールドの名前を「Story」に設定し、値を記事の文字列に設定します。
  3. push_structured_eventオペレーションを使用して、イベントを通知サービスにポストします。
  4. リスト3-2 イベントの作成とポスト(C++)
    // 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
    channel->push_structured_event(notification);

 


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

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

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

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

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

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

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

リスト3-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
リスト3-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.
                           event_type.type_name.in()
    << endl
    << "Story : "
    << story
    << endl;
...
}

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

このステップは、イベント・ポスト元とイベント・サブスクライバの両方で同じです。このステップの説明については、「CosNotifyComm::StructuredPushConsumerインタフェースの実装」を参照してください。

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

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

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

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

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

"BEAWrapper"に注意

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

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

リスト3-5 一時的なオブジェクト参照でコールバック・オブジェクトを作成するサンプル・コード(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;
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()
      );

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

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

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

次の手順を実行する必要があります。

  1. サブスクリプションのサービス品質(QoS)を一時的または永続的のいずれかに設定します。
  2. subscription_name (オプション)、domain_nametype_name、およびdata_filter (オプション)を指定します。
  3. サブスクリプションを作成します。サブスクリプションは、domain_nametype_namedata_filter (オプション)、およびサービスの品質(QoS)を設定し、サブスクライバのコールバック・オブジェクトのオブジェクト参照を通知サービスに提供します。
  4. リスト3-6 一時的なサブスクリプションの作成(C++)
    // Set the quality of service to TRANSIENT.
    CosNotification::QoSProperties qos;
    qos.length(1);
    qos[0].name =
       CORBA::string_dup(Tobj_SimpleEvents::SUBSCRIPTION_TYPE);
    qos[0].value <<=
       Tobj_SimpleEvents::TRANSIENT_SUBSCRIPTION;
    // Set the type to the news category.
    const char* type = “Sports”;
    // Create the subscription. Set the domain to "News" and
    // the data filter to age greater than 30.
    Tobj_SimpleEvents::SubscriptionID subscription_id =
      channel->subscribe(
        subscription_name,
        "News", // domain
       “Sports”, // type
        "Age > 30", // Data filter.
        qos,
        news_consumer.in()
      );
注: データのフィルタリングを使用する場合は、いくつかの構成タスクも実行する必要があります。データのフィルタリングの構成要件の詳細は、「データ・フィルタの構成」を参照してください。

C++のAdvancedサンプル・アプリケーションのコードであるリスト3-7は、通知サービスの永続的なサブスクリプションを作成するコード記述手順を示しています。永続的なサブスクリプションを作成する手順は、前述の一時的なサブスクリプションを作成する手順と同じです。

注: サンプル・コードではnews_consumerコールバック・オブジェクトのオブジェクト参照が永続的であると想定されていますが、一時的なコールバック・オブジェクト参照で永続的なサブスクリプションを作成することもできます。一時的と永続的を対比させたコールバック・オブジェクト参照の説明については、表2-3を参照してください。
リスト3-7 永続的なサブスクリプションの作成(AdvancedのSubscriber.cpp)
CosNotification::QoSProperties qos;
qos.length(1);
qos[0].name =
  CORBA::string_dup(Tobj_SimpleEvents::SUBSCRIPTION_TYPE);
qos[0].value <<= Tobj_SimpleEvents::PERSISTENT_SUBSCRIPTION;
CosNotifyComm::StructuredPushConsumer_var
  news_consumer =
    CosNotifyComm::StructuredPushConsumer::_narrow(
        news_consumer_oref.in()
      );
Tobj_SimpleEvents::SubscriptionID sub_id =
channel->subscribe(
    subscription_info.subscription_name(),
    "News", // domain
    “Sports”, // type
    “”, // No data filter.
    qos,
    news_consumer.in()
  )
);

C++共同クライアント/サーバー・アプリケーションのスレッドに関する留意事項

共同クライアント/サーバー・アプリケーションは、まずクライアント・アプリケーションとして機能し、その後にサーバー・アプリケーションにスイッチすることができます。そのために、共同クライアント/サーバー・アプリケーションでは次の呼出しを行って、スレッドの制御を完全にオブジェクト・リクエスト・ブローカ(ORB)に移します。

orb -> run();

共同クライアント/サーバー・アプリケーションのサーバー部分のメソッドがORB::shutdown()を呼び出すと、サーバーのアクティビティはすべて停止し、共同クライアント/サーバー・アプリケーションのサーバー部分でORB::run()が呼び出されると、制御はステートメントに返されます。制御が共同クライアント/サーバー・アプリケーションのクライアント機能に返されるのは、この条件においてのみです。

クライアント・アプリケーションにはスレッドが1つしかないため、共同クライアント/サーバー・アプリケーションのクライアント機能とサーバー機能で、中央演算処理装置(CPU)を共有する必要があります。この共有は、ORBをときどき確認して、共同クライアント/サーバー・アプリケーションに、実行すべきサーバー・アプリケーション作業があるかどうかを調べることによって行われます。ORBの確認を実行するには、次のコードを使用します。

if ( orb->work_pending() ) orb->perform_work();

ORBはサーバー・アプリケーションの作業を完了すると、共同クライアント/サーバー・アプリケーションに戻ります。共同クライアント/サーバー・アプリケーションはその後、クライアント・アプリケーション機能を実行します。共同クライアント/サーバー・アプリケーションでは、ORBの不定期な確認を、確実に行う必要があります。行われない場合、共同クライアント/サーバー・アプリケーションは呼出しをまったく処理しません。

共同クライアント/サーバー・アプリケーションがリクエストでブロックされている間は、ORBでコールバックを提供できないことに注意してください。共同クライアント/サーバー・アプリケーションが別のOracle Tuxedo CORBAサーバー・アプリケーションのオブジェクトを呼び出した場合、そのレスポンスを待つ間ORBはブロックされます。ブロック中のORBはコールバックを扱うことができないため、リクエストが完了するまでコールバックはキューに入れられます。

 


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

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

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

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

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

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

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

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

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

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

アプリケーションのビルドと実行

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

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

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

リスト3-8 C++ Reporterアプリケーションのビルドと実行のコマンド(Microsoft Windows)
# Run the idl command.
idl -IC:\tuxdir\include C:\tuxdir\include\CosEventComm.idl \
C:\tuxdir\include\CosNotification.idl \
C:\tuxdir\include\CosNotifyComm.idl \
C:\tuxdir\include\Tobj_Events.idl \
C:\tuxdir\include\Tobj_SimpleEvents.idl
# Run the buildobjclient command.
buildobjclient -v -o subscriber.exe -f " \
    -DWIN32 \
    Reporter.cpp \
    CosEventComm_c.cpp \
    CosNotification_c.cpp \
    CosNotifyComm_c.cpp \
    Tobj_Events_c.cpp \
    Tobj_SimpleEvents_c.cpp \
    "
# Run the application.
is_reporter

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

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

  先頭に戻る       前  次