![]() |
![]() |
|
|
BEA シンプル・イベント API の使い方
この章では、BEA シンプル・イベント API と C++ および Java プログラミング言語を使用してノーティフィケーション・サービス・アプリケーションを作成するための開発手順を説明します。
ここでは、次の内容について説明します。
開発プロセス
表 3-1 は、ノーティフィケーション・サービス・アプリケーションの開発プロセスの概略です。
手順 |
説明 |
---|---|
1 |
イベントの設計 |
2 |
イベントをポストするアプリケーションの記述 |
3 |
イベントをサブスクライブするアプリケーションの記述 |
4 |
ノーティフィケーション・サービス・アプリケーションのコンパイル |
これらのステップは、以降の節で詳しく説明されています。
イベントの設計
イベントの設計は、あらゆるノーティフィケーション・サービスの基本です。イベントの設計は、一致するサブスクリプションに配信される情報の量だけでなく、ノーティフィケーション・サービスの効率と性能にも影響します。したがって、計画を慎重に行って、ノーティフィケーション・サービスが現在のニーズだけでなく将来の規模拡大にも対応できるようにする必要があります。イベント設計の説明については、イベントの設計を参照してください。
ステップ 1: イベントをポストするアプリケーションの記述
次のタイプの CORBA アプリケーションは、イベントをポストできます。
注記 BEA Tuxedo 8.0 では、Java のクライアントと共同クライアント/サーバがサポートされていますが、Java サーバはサポートされていません。Java サーバは BEA WebLogic Enterprise 製品のバージョン 5.0 と 5.1 ではサポートされていましたが、BEA WebLogic Enterprise がリリース 8.0 で BEA Tuxedo と結合された時点でそのサポートは除外されました。
イベントをポストするために、アプリケーションでは最低でも次の機能をインプリメントする必要があります。
以降の節では、これらの各機能について説明します。
イベント・チャネルの取得
最初にイベント・チャネルを取得しないと、クライアント・アプリケーションではイベントをポストできません。
この開発ステップは、リスト 3-1 で示されています。リスト 3-1 は、BEA シンプル・イベント API を使用する Notification Service サンプル・アプリケーションに基づいています。
イベント・チャネル・ファクトリのオブジェクト・リファレンスを取得するために、"Tobj_SimpleEventsService"
環境オブジェクトを使用して Bootstrap オブジェクトの resolve_initial_references
メソッドが呼び出されます。取得したオブジェクト・リファレンスは、チャネル・ファクトリを取得するために使用します。チャネル・ファクトリは、イベント・チャネルを取得するために使用します。リスト 3-1 と リスト 3-2 は、C++ および Java のコード例を示しています。
リスト 3-1 イベント・チャネルの取得 (C++)
// シンプル・イベント・チャネル・ファクトリのオブジェクト・リファレンスを取得
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());
// チャネル・ファクトリを使用してデフォルト・チャネルを取得
Tobj_SimpleEvents::Channel_var channel =
channel_factory->find_channel(
Tobj_SimpleEvents::DEFAULT_CHANNEL);
リスト 3-2 イベント・チャネルの取得 (Java)
// シンプル・イベント・チャネル・ファクトリのオブジェクト・リファレンスを取得
org.omg.CORBA.Object channel_factory_oref =
bootstrap.resolve_initial_references(
"Tobj_SimpleEventsService");
// チャネル・ファクトリを使用してデフォルト・チャネルを取得
ChannelFactory channel_factory =
ChannelFactoryHelper.narrow(channel_factory_oref);
Channel channel =
channel_factory.find_channel(DEFAULT_CHANNEL.value);
イベントの作成とポスト
イベントをポストするには、まずイベントを作成しなければなりません。以下のリストは、Notification Service サンプル・アプリケーションに基づいています。
リスト 3-3 と リスト 3-4 は、それぞれ C++ と Java でのインプリメンテーションを示しています。イベント・チャネルにニュースを報告するために、このアプリケーションでは次の手順が実行されます。
push_structured_event
オペレーションを使用して、イベントをノーティ
フィケーション・サービスにポストします。
リスト 3-3 イベントの作成とポスト (C++)
// イベントを作成
CosNotification::StructuredEvent notification;
// ドメインを「News」に設定
notification.header.fixed_header.event_type.domain_name =
CORBA::string_dup("News");
// 型をニュース・カテゴリに設定
notification.header.fixed_header.event_type.type_name =
CORBA::string_dup("Sports");
// 記事を格納するフィールドを 1 つイベントのフィルタ
// 処理可能データに追加。フィールドの名前は「Story」、
// 値は記事の文字列に設定
notification.filterable_data.length(1);
notification.filterable_data[0].name =
CORBA::string_dup("Story");
notification.filterable_data[0].value <<= "John Smith wins again";
// イベントをポスト
// ドメインが「News」で、型がニュース・カテゴリと一致する
// イベントをサブスクライブしたサブスクライバがこのイベント
// を受信する
channel->push_structured_event(notification);
リスト 3-4 イベントの作成とポスト (Java)
// イベントを作成
StructuredEvent notification = new StructuredEvent();
// ヘッダの下位構造を作成
notification.header = new EventHeader();
notification.header.fixed_header = new FixedEventHeader();
notification.header.fixed_header.event_type = new EventType();
// ドメインを「News」に設定
notification.header.fixed_header.event_type.domain_name = "News";
// 型をニュース・カテゴリに設定
notification.header.fixed_header.event_type.type_name = "Sports";
// このサンプルでは使用しないので、イベント名は空の
// 文字列に設定する
notification.header.fixed_header.event_name = "";
// このサンプルでは使用しないので、Variable ヘッダは空にする
notification.header.variable_header = new Property[0];
// 記事を格納するフィールドを 1 つイベントのフィルタ
// 処理可能データに追加。フィールドの名前は「Story」、
// 値は記事の文字列に設定
notification.filterable_data = new Property[1];
notification.filterable_data[0] = new Property();
notification.filterable_data[0].name = "Story";
notification.filterable_data[0].value = orb.create_any();
notification.filterable_data[0].value.insert_string(John Smith wins again");
// このサンプルでは使用しないので、残りの本文は
// 新しい (空の) Any に設定する
notification.remainder_of_body = orb.create_any();
// イベントをポスト
channel.push_structured_event(notification);
ステップ 2: イベントをサブスクライブするアプリケーションの記述
次のタイプの CORBA アプリケーションは、イベントをサブスクライブできます。
注記 BEA Tuxedo 8.0 では、Java のクライアントと共同クライアント/サーバがサポートされていますが、Java サーバはサポートされていません。Java サーバは BEA WebLogic Enterprise 製品のバージョン 5.0 と 5.1 ではサポートされていましたが、BEA WebLogic Enterprise がリリース 8.0 で BEA Tuxedo と結合された時点でそのサポートは除外されました。
イベントをサブスクライブするために、アプリケーションでは最低でも次の機能をインプリメントする必要があります。
push_structured_event
オペレーションをサポートする CosNotifyComm OMG IDL インターフェイスをインプリメントします。CosNotifyComm::StructuredPushConsumer インターフェイスのインプリメント
コールバック・オブジェクトでイベントを受信するためには、push_structured_event
オペレーションをサポートする CosNotifyComm::StructuredPushConsumer インターフェイスをインプリメントする必要があります。一致するサブスクリプションがあるイベントが発生すると、ノーティフィケーション・サービスではコールバック・オブジェクトのこのオペレーションを呼び出してイベントをサブスクライバ・アプリケーションにプッシュします。
CosNotifyComm::StructuredPushConsumer インターフェイスでは、offer_change
および disconnect_structured_push_consumer
というオペレーションも定義されます。これらのオペレーションはノーティフィケーション・サービスで呼び出されないので、CORBA::NO_IMPLEMENT
をスローするスタブ・アウト・バージョンをインプリメントする必要があります。
リスト 3-5 と リスト 3-6 は、このインターフェイスが C++ でどのようにインプリメントされるのかを示しています。
リスト 3-5 CosNotifyComm::StructuredPushConsumer インターフェイスのサンプル・インプリメンテーション (NewsConsumer_i.h)
#ifndef _news_consumer_i_h
#define _news_consumer_i_h
#include "CosNotifyComm_s.h"
// サーバント・クラスでニュース・イベントを受信するためには、
// CosNotifyComm::StructuredPushConsumer idl インターフェイス
// をインプリメントする必要がある
class NewsConsumer_i : public
POA_CosNotifyComm::StructuredPushConsumer
{
public:
// このメソッドはニュース・イベントの発生時に呼び出される
virtual void push_structured_event(
const CosNotification::StructuredEvent& notification
);
// OMG の CosNotifyComm::StructuredPushConsumer idl インターフェイス
// では、offer_change メソッドと disconnect_structured_push_consumer
// メソッドが定義される。ノーティフィケーション・サービスからそれらの
// メソッドが呼び出されることはないので、ただ単に CORBA::NO_IMPLEMENT
// 例外をスローさせる
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-6 CosNotifyComm::StructuredPushConsumer インターフェイスのサンプル・インプリメンテーション (NewsConsumer_i.cpp)
#include "NewsConsumer_i.h"
#include <iostream.h>
//-----------------------------------------------------------
// Subscriber.cpp は「News」イベントのシンプル・イベント・
// サブスクリプションを作成し、イベントが NewsConsumer_i オブジェクト
// に配信されるようにする。ニュース・イベントが発生すると (ユーザが
// Reporter アプリケーションを実行してニュース記事を報告すると発生する)、
// 次のメソッドが呼び出される
void NewsConsumer_i::push_structured_event(
const CosNotification::StructuredEvent& notification )
{
// イベントのフィルタ処理可能データの最初のフィールドから
// 記事を抽出する
char* story;
notification.filterable_data[0].value >>= story;
// コードを単純化するために、「story」は「null」ではないと想定
// イベントを出力
cout
<< "-----------------------------------------------------"
<< endl
<< "Category : "
<< notification.header.fixed_header.
event_type.type_name.in()
<< endl
<< "Story : "
<< story
<< endl;
...
}
イベント・チャネルの取得
このステップは、イベント・ポスト元とイベント・サブスクライバの両方で同じです。このステップの説明については、CosNotifyComm::StructuredPushConsumer インターフェイスのインプリメントを参照してください。
コールバック・オブジェクトの作成
イベントを受信するためには、アプリケーションはサーバであることも必要です。つまり、アプリケーションでは、サブスクライバのサブスクリプションと一致するイベントが発生したときに呼び出すことができるコールバック・オブジェクトをインプリメントしなければなりません。
コールバック・オブジェクトを作成する手順は次のとおりです。
注記 この手順は、BEA Tuxedo CORBA 共同クライアント/サーバでの手順です。BEA Tuxedo CORBA サーバでもイベントをサブスクライブできます。
BEAWrapper コールバック・オブジェクトとそのメソッドの詳細については、『BEA Tuxedo CORBA プログラミング・リファレンス』の「共同クライアント/サーバ」を参照してください。
注記 BEAWrapper コールバック・オブジェクトを使用してコールバック・オブジェクトを作成する方法は、以下に説明します。POA を使用してコールバック・オブジェクトをインプリメントする方法については、『BEA Tuxedo CORBA サーバ間通信』を参照してください。
リスト 3-7 と リスト 3-9 は、それぞれ C++ および Java で、BEAWrapper コールバック・オブジェクトを使用してコールバック・オブジェクトを作成する方法を示しています。コード例では、NewsConsumber_i servant
が作成され、start_transient
メソッドを使用して一時的なオブジェクト・リファレンスが作成されます。
リスト 3-7 一時的なオブジェクト・リファレンスでコールバック・オブジェクトを作成するサンプル・コード (Introductory サンプル・アプリケーションの Subscriber.cpp)
// このクライアントではコールバックをサポートする必要があるので
// コールバック・ラッパー・オブジェクトを作成する
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-8 と リスト 3-11 は、それぞれ C++ および Java で一時的なサブスクリプションを作成する方法を示しています。
次の手順を実行する必要があります。
subscription_name
(オプション)、domain_name
、type_name
、および
data_filter
(オプション) を指定します。
domain_name
、
type_name
、data_filter
(オプション)、およびサービスの品質 (QoS) を設
定し、サブスクライバのコールバック・オブジェクトのオブジェクト・リ
ファレンスをノーティフィケーション・サービスに提供します。
リスト 3-8 一時的なサブスクリプションの作成 (C++)
// サービスの品質を TRANSIENT に設定
CosNotification::QoSProperties qos;
qos.length(1);
qos[0].name =
CORBA::string_dup(Tobj_SimpleEvents::SUBSCRIPTION_TYPE);
qos[0].value <<=
Tobj_SimpleEvents::TRANSIENT_SUBSCRIPTION;
// 型をニュース・カテゴリに設定
const char* type = "Sports";
// サブスクリプションを作成する。ドメインを「News」に設定し、
// データ・フィルタを 30 を超える年齢に設定する
Tobj_SimpleEvents::SubscriptionID subscription_id =
channel->subscribe(
subscription_name,
"News", // ドメイン
"Sports", // 型
"Age > 30", // データ・フィルタ
qos,
news_consumer.in()
);
注記 データのフィルタ処理を利用する場合は、コンフィギュレーション・タスクも行う必要があります。データ・フィルタ処理のコンフィギュレーション要件については、データ・フィルタのコンフィギュレーションを参照してください。
C++ および Java の Advanced サンプル・アプリケーションのコードである リスト 3-9 と リスト 3-13 は、ノーティフィケーション・サービスの永続的なサブスクリプションを作成するコード記述手順を示しています。永続的なサブスクリプションを作成する手順は、前述の一時的なサブスクリプションを作成する手順と同じです。
注記 コード例では news_consumer
コールバック・オブジェクトのオブジェクト・リファレンスが永続的であると想定されていますが、一時的なコールバック・オブジェクト・リファレンスで永続的なサブスクリプションを作成することもできます。一時的と永続的を対比させたコールバック・オブジェクト・リファレンスの説明については、表 2-3 を参照してください。
リスト 3-9 永続的なサブスクリプションの作成 (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", // ドメイン
"Sports", // 型
"", // データ・フィルタなし
qos,
news_consumer.in()
)
);
C++ 共同クライアント/サーバ・アプリケーションのスレッドに関する考慮事項
共同クライアント/サーバ・アプリケーションは、まずクライアント・アプリケーションとして機能し、その後にサーバ・アプリケーションにスイッチすることができます。そのために、共同クライアント/サーバ・アプリケーションでは次の呼び出しを行って、スレッドの制御を完全にオブジェクト・リクエスト・ブローカ (ORB) に移します。
orb -> run();
共同クライアント/サーバ・アプリケーションのサーバ部分のメソッドで ORB::shutdown()
が呼び出されると、共同クライアント/サーバ・アプリケーションのサーバ部分で ORB::run()
が呼び出された後にすべてのサーバ・アクティビティが停止し、制御が文に戻ります。この状況でのみ、制御は共同クライアント/サーバ・アプリケーションのクライアント部分に戻ります。
クライアント・アプリケーションのスレッドは 1 つだけなので、共同クライアント/サーバ・アプリケーションのクライアント部分では共同クライアント/サーバ・アプリケーションのサーバ部分と CPU を共有する必要があります。この共有は、共同クライアント/サーバ・アプリケーションに実行すべきサーバ・アプリケーション作業があるかどうかを ORB でときどき確認することで実現します。その確認を実行するには、次のコードを使用します。
if ( orb->work_pending() ) orb->perform_work();
サーバ・アプリケーションの作業が完了すると、ORB は共同クライアント/サーバ・アプリケーションに戻り、クライアント・アプリケーションの機能が実行されます。共同クライアント/サーバ・アプリケーションでは、ORB での確認をときどき必ず行わなければなりません。確認を行わないと、共同クライアント/サーバ・アプリケーションでは呼び出しが処理されません。
共同クライアント/サーバ・アプリケーションが要求でブロックされている間は、ORB でコールバックを提供できないことに注意してください。共同クライアント/サーバ・アプリケーションが別の BEA Tuxedo CORBA サーバ・アプリケーションのオブジェクトを呼び出した場合、その応答を待つ間 ORB はブロックされます。ブロックされている間は ORB ではコールバックを提供できないので、コールバックは要求が完了するまでキューに入れられます。
ステップ 3: ノーティフィケーション・サービス・アプリケーションのコンパイルと実行
ノーティフィケーション・サービス・アプリケーション開発の最後のステップでは、アプリケーションをコンパイル、ビルド、および実行します。そのためには、次の手順を実行する必要があります。
クライアント・スタブ・ファイルとスケルトン・ファイルの生成
クライアント・スタブ・ファイルとスケルトン・ファイルを生成するには、アプリケーションで使用されるノーティフィケーション IDL ファイルごとに idl
コマンドを実行する必要があります。表 3-2 は、各タイプのサブスクライバで使用する idl
コマンドを示しています。
言語 |
BEA Tuxedo CORBA 共同クライアント/サーバ |
BEA Tuxedo CORBA サーバ |
---|---|---|
C++ |
|
|
Java |
idltojava |
BEA Tuxedo 8.0 以降ではサポートされていない |
次に、idl
コマンドの例を示します。
>idl -IC:\tuxdir\include C:\tuxdir\include\CosEventComm.idl
表 3-3 は、BEA シンプル・イベント・インターフェイスを使用する各タイプのノーティフィケーション・サービス・アプリケーションで必要な IDL ファイルを示しています。
アプリケーションのビルドと実行
ビルドの手続きは、ノーティフィケーション・サービス・アプリケーションのタイプによって異なります。表 3-4 は、各タイプのノーティフィケーション・サービス・アプリケーションをビルドするために使用するファイルのコマンドと種類を示しています。
リスト 3-10 は、Microsoft Windows システム上の C++ ポスト元アプリケーション (Reporter.cpp
) で使用するコマンドを示しています。C++ の実行可能ファイルを作成するために、idl
コマンドが必要な IDL ファイルで実行され、buildobjclient
コマンドによって C++ クライアント・アプリケーション・ファイルと IDL スタブがコンパイルされます。
リスト 3-10 C++ Reporter アプリケーションのビルドと実行のコマンド (Microsoft Windows)
# idl コマンドを実行
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
# buildobjclient コマンドを実行
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 \
"
# アプリケーションを実行
is_reporter
リスト 3-11 と リスト 3-12 は、それぞれ Microsoft Windows および UNIX 上の C++ サブスクライバ・アプリケーション (Subscriber.cpp
) で使用するコマンドを示しています。C++ の実行可能ファイルを作成するために、-P
オプションを設定した buildobjclient
コマンドによって、共同クライアント/サーバ・アプリケーション・ファイル (Subscriber.cpp
と NewsConsumer_i.cpp
)、IDL スタブ、および IDL スケルトン (CosNotifyComm_s.cpp
) がコンパイルされます。
リスト 3-11 C++ Subscriber アプリケーションのビルドと実行のコマンド (Microsoft Windows)
# idl コマンドを実行
idl -P -IC:\tuxdir\include C:\tuxdir\include\CosEventComm.idl \
C:\tuxdir\include\CosNotification.idl \
C:\tuxdir\include\CosNotifyComm.idl \
C:\tuxdir\include\TobjvEvents.idl \
C:\tuxdir\include\Tobj_SimpleEvents.idl
# buildobjclient コマンドを実行
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 \
"
# アプリケーションを実行
is_subscriber
リスト 3-12 C++ Subscriber アプリケーションのビルドと実行のコマンド (UNIX)
# idl コマンドを実行
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
# buildobjclient コマンドを実行
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 \
"
# アプリケーションを実行
is_subscriber
リスト 3-13 は、リモートの Java ポスト元アプリケーションをリンク、ビルド、および実行するために使用するコマンドの例を示しています。
リスト 3-13 Java Reporter アプリケーションのリンク、ビルド、および実行のコマンド
# idltojava コマンドを実行
idltojava -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
# Java ファイルをコンパイル
javac -classpath C:\tuxdir\udataobj\java\jdk\m3envobj.jar Reporter.java
# Java .class ファイルを Java アーカイブ (JAR) ファイルに結合
jar cf reporter.jar Reporter.class org\omg\CosEventComm \
org\omg\CosNotification org\omg\CosNotifyComm \
com\beasys\Tobj_Events com\beasys\Tobj_SimpleEvents
# Reporter アプリケーションを実行
java -DTOBJADDR=//BEANIE:2359 -classpath \
reporter.jar;C:\tuxdir\udataobj\java\jdk\m3envobj.jar Reporter
![]() |
![]() |
![]() |
|
Copyright © 2001, BEA Systems, Inc. All rights reserved.
|