|
この章では、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 は、ノーティフィケーション サービス アプリケーションの開発プロセスの概略です。
イベントの設計は、あらゆるノーティフィケーション サービスの基本です。イベントの設計は、一致するサブスクリプションに配信される情報の量だけでなく、ノーティフィケーション サービスの効率と性能にも影響します。したがって、計画を慎重に行って、ノーティフィケーション サービスが現在のニーズだけでなく将来の規模拡大にも対応できるようにする必要があります。イベント設計の説明については、「イベントの設計」を参照してください。
次のタイプの CORBA アプリケーションは、イベントをポストできます。
イベントをポストするために、アプリケーションでは最低でも次の機能を実装する必要があります。
最初にイベント チャネルを取得しないと、クライアント アプリケーションではイベントをポストできません。
この開発ステップは、コード リスト 4-1 で示されています。コード リスト 4-1 は、CosNotification サービス API を使用する Introductory サンプル アプリケーションの Reporter.cpp
ファイルのコードです。
イベント チャネル ファクトリのオブジェクト参照を取得するために、"NotificationService"
環境オブジェクトを使用して Bootstrap オブジェクトの resolve_initial_references
メソッドが呼び出されます。取得したオブジェクト参照は、チャネル ファクトリを取得するために使用します。チャネル ファクトリは、イベント チャネルを取得するために使用します。コード リスト 4-1 は、C++ のサンプル コードを示しています。
// CosNotification チャネル ファクトリのオブジェクト参照を取得
CORBA::Object_var channel_factory_oref =
bootstrap.resolve_initial_references(
"NotificationService" );
CosNotifyChannelAdmin::EventChannelFactory_var
channel_factory =
CosNotifyChannelAdmin::EventChannelFactory::_narrow(
channel_factory_oref.in() );
// チャネル ファクトリを使用してデフォルト チャネルを取得
CosNotifyChannelAdmin::EventChannel_var channel =
channel_factory->get_event_channel(
Tobj_Notification::DEFAULT_CHANNEL );
イベントをポストするには、SupplierAdmin オブジェクトを取得し、そのオブジェクトを使用してプロキシを作成し、イベントを作成して、そのイベントをプロキシにポストする必要があります。
コード リスト 4-2 は、C++ での実装を示しています。
// イベントをポストする側なので、
// SupplierAdmin オブジェクトを取得する
CosNotifyChannelAdmin::SupplierAdmin_var supplier_admin =
channel->default_supplier_admin();
// サプライヤ管理を使用してプロキシを作成する。イベントはそのプロキシ
// にポストされる (シンプル イベント インタフェースの場合、イベント
// はチャネルにポストされる)
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 );
// イベントをポストできるようにプロキシに接続
proxy_push_consumer->connect_structured_push_supplier(
CosNotifyComm::StructuredPushSupplier::_nil() );
...
// イベントを作成
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」で、型がニュース カテゴリと一致する
// イベントをサブスクライブしたサブスクライバがこのイベント
// を受信する
proxy_push_consumer->push_structured_event(notification);
...
// 接続を解除
proxy_push_consumer->disconnect_structured_push_consumer();
次のタイプの CORBA アプリケーションは、イベントをサブスクライブできます。
イベントをサブスクライブするために、アプリケーションでは最低でも次の機能をサポートする必要があります。
コールバック サーバント オブジェクトでイベントを受信するためには、push_structured_event
オペレーションをサポートする CosNotifyComm::StructuredPushConsumer インタフェースを実装する必要があります。一致するサブスクリプションがあるイベントが発生すると、ノーティフィケーション サービスではサブスクライバ アプリケーションのサーバント コールバック オブジェクトのこのオペレーションを呼び出してイベントをサブスクライバ アプリケーションに配信します。
CosNotifyComm::StructuredPushConsumer インタフェースでは、offer_change
および disconnect_structured_push_consumer
というオペレーションも定義されます。これらのオペレーションはノーティフィケーション サービスで呼び出されないので、CORBA::NO_IMPLEMENT
を送出するスタブ アウト バージョンを実装する必要があります。
コード リスト 4-3 とコード リスト 4-4 は、このインタフェースが C++ でどのように実装されるのかを示しています。
#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
#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;
...
}
最初にイベント チャネル、ConsumerAdmin オブジェクト、およびフィルタ ファクトリ オブジェクトを取得しないと、アプリケーションではサブスクリプションを作成できません。コード リスト 4-5 は、C++ での実装を示しています。
イベント チャネル ファクトリのオブジェクト参照を取得するために、"NotificationService"
環境オブジェクトを使用して Bootstrap オブジェクトの resolve_initial_references
メソッドが呼び出されます。取得したオブジェクト参照は、チャネル ファクトリを取得するために使用します。チャネル ファクトリは、イベント チャネルを取得するために使用します。最後に、イベント チャネルは ConsumerAdmin オブジェクトと FilterFactory オブジェクトを取得するために使用します。
// CosNotification チャネル ファクトリのオブジェクト参照を取得
CORBA::Object_var
channel_factory_oref =
bootstrap.resolve_initial_references(
"NotificationService" );
CosNotifyChannelAdmin::EventChannelFactory_var
channel_factory =
CosNotifyChannelAdmin::EventChannelFactory::_narrow(
channel_factory_oref.in() );
// チャネル ファクトリを使用してデフォルト チャネルを取得
CosNotifyChannelAdmin::EventChannel_var channel =
channel_factory->get_event_channel(
Tobj_Notification::DEFAULT_CHANNEL );
// チャネルを使用してコンシューマ管理とフィルタ ファクトリを取得
CosNotifyChannelAdmin::ConsumerAdmin_var consumer_admin =
channel->default_consumer_admin();
CosNotifyFilter::FilterFactory_var filter_factory =
channel->default_filter_factory();
イベントを受信するためには、アプリケーションはサーバであることも必要です。つまり、アプリケーションでは、サブスクライバのサブスクリプションと一致するイベントが発生したときに呼び出すことができるコールバック オブジェクトを実装しなければなりません。
注意 : | この手順は、共同クライアント/サーバでの手順です。Oracle Tuxedo CORBA サーバでもイベントをサブスクライブできます。 |
BEAWrapper コールバック オブジェクトとそのメソッドの詳細については、『Tuxedo CORBA プログラミング リファレンス』の「共同クライアント/サーバ」を参照してください。
注意 : | BEAWrapper コールバック オブジェクトを使用してコールバック オブジェクトを作成する方法は、以下に説明します。POA を使用してコールバック オブジェクトを実装する方法については、『Oracle Tuxedo CORBA サーバ間通信』を参照してください。 |
コード リスト 4-6 は、C++ で、BEAWrapper コールバック オブジェクトを使用してコールバック オブジェクトを作成する方法を示しています。サンプル コードでは、NewsConsumber_i servant
が作成され、start_transient
メソッドを使用して一時的なオブジェクト参照が作成されます。
// このクライアントではコールバックをサポートする必要があるので
// コールバック ラッパー オブジェクトを作成する
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 サンプル アプリケーションのコードであるコード リスト 4-7 は、C++ で一時的なサブスクリプションを作成する方法を示しています。
// 新しいサブスクリプションを作成 (この時点ではまだ完全ではない)
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();
// サービスの品質を設定する。これでサブスクリプション名
// とサブスクリプションのタイプ (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);
// フィルタを作成 (ドメイン、型、およびデータ フィルタの指定に使用)
CosNotifyFilter::Filter_var filter =
filter_factory->create_filter(
Tobj_Notification::CONSTRAINT_GRAMMAR );
s_filter = filter.in();
// フィルタ処理パラメータを設定
// (ドメイン = "News"、型 = “Sports”、およびデータ フィルタなし)
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(""); // データ フィルタなし
CosNotifyFilter::ConstraintInfoSeq_var
add_constraints_results = // この戻り値は無視
filter->add_constraints(constraints);
// フィルタをサブスクリプションに追加
CosNotifyFilter::FilterID filter_id =
subscription->add_filter(filter.in());
// サブスクリプションの名前、タイプ、およびフィルタ処理の各パラメータ
// が設定されたので、イベントを配信するコールバック オブジェクトの
// オブジェクト参照を渡してサブスクリプションを完成する
subscription->connect_structured_push_consumer(
news_consumer.in() );
ノーティフィケーション サービス アプリケーション開発の最後のステップでは、アプリケーションをコンパイル、ビルド、および実行します。そのためには、次の手順を実行する必要があります。
クライアント スタブ ファイルとスケルトン ファイルを生成するには、アプリケーションで使用されるノーティフィケーション IDL ファイルごとに idl
コマンドを実行する必要があります。表 4-2 は、各タイプのサブスクライバで使用する idl
コマンドを示しています。
>idl -IC:\tuxdir\include C:\tuxdir\include\CosEventComm.idl
表 4-3 は、各タイプのノーティフィケーション サービス アプリケーションで必要な IDL ファイルを示しています。
コンパイルとリンクの手続きは、ノーティフィケーション サービス アプリケーションのタイプによって異なります。表 4-4 は、各タイプのアプリケーションをコンパイルするために使用するコマンドとファイルの概要を示しています。
コード リスト 4-8 は、Microsoft Windows システム上の C++ Reporter アプリケーション (Reporter.cpp
) で使用するコマンドを示しています。C++ の実行可能ファイルを作成するために、idl
コマンドが必要な IDL ファイルで実行され、buildobjclient
コマンドによって C++ クライアント アプリケーション ファイルと IDL スタブがコンパイルされます。
# idl コマンドを実行
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
# buildobjclient コマンドを実行
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 ”
# アプリケーションを実行
is_reporter
コード リスト 4-9 とコード リスト 4-10 は、それぞれ Microsoft Windows および UNIX 上の C++ Subscriber アプリケーション (Subscriber.cpp
) で使用するコマンドを示しています。C++ の実行可能ファイルを作成するために、-P
オプションを設定した buildobjclient
コマンドによって、共同クライアント/サーバ アプリケーション ファイル (Subscriber.cpp
と NewsConsumer_i.cpp
)、IDL スタブ、および IDL スケルトン (CosNotifyComm_s.cpp
用) がコンパイルされます。
# idl コマンドを実行
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
# buildobjclient コマンドを実行
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 \
"
# アプリケーションを実行
is_subscriber
# idl コマンドを実行
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
# buildobjclient コマンドを実行
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 \
"
# アプリケーションを実行
is_subscriber