Tuxedo CORBA 要求レベルのインターセプタ

     前  次    新しいウィンドウで目次を開く     
ここから内容の開始

CORBA 要求レベルのインターセプタの開発

CORBA 要求レベルのインターセプタの開発を行うには通常、次の手順に従います。

上記の手順は通常、繰り返し行います。たとえば、最初にインターセプタをビルドしてテストするときは、そのインターセプタが実行中であることを確認するだけの最も基本的なコードのみとします。その後のビルドとテストで、インターセプタの全機能を徐々に実装していきます。

以降の節では、Oracle Tuxedo ソフトウェアに同梱されたサンプルのインターセプタを例として、各手順を詳しく説明します。

注意 : 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 に関する技術的なサポートやマニュアルは提供していません。

 


ステップ 1: CORBA アプリケーションのインタフェースの識別

所定のマシンにインターセプタをデプロイすると、そのインターセプタはマシン上のアプリケーションが要求を発行 (クライアントサイド インターセプタの場合) または受信 (ターゲットサイド インターセプタの場合) するたびに呼び出されるため、著しいオーバーヘッドが生じます。したがって、作成したインターセプタはすべて、これらのアプリケーションによく適合している必要があります。

たとえば、セキュリティ インターセプタは通常、問題となっている要求の種類、および要求で処理されているデータの種類を認識する必要があります。

特定の要求を扱うインターセプタはすべて、要求からインタフェース リポジトリ ID を抽出できる必要があります。インタフェースについてこのような情報があれば、インターセプタは要求に含まれるデータの種類を知り、そのデータを要求固有のやり方で処理できます。

さらに、対象外の要求が送信された場合、インターセプタはその要求を迅速かつ効率的に渡すことができなければなりません。

PersonQuery サンプル アプリケーション」で説明されている PersonQuery の例では、PersonQuery クライアント アプリケーションのユーザがアドレスを受信できるかどうかを決定するインターセプタを使用します。ユーザの識別情報が特定の基準に一致する場合には、インターセプタは完全なアドレス番号をクライアントに返すことを許可します。一致しなかった場合、インターセプタはアドレスの代わりに x 文字からなる文字列のみをログ ファイルに返します。

 


ステップ 2: インターセプタ実装コードの記述

インターセプタを実装する場合、次の事項に留意します。

以下のトピックでは、多くのインターセプタについて一般的な実装上の検討事項について説明します。「InterceptorData サンプル インターセプタ」で説明する InterceptorData インターセプタから例を取ります。

実装ファイルの起動

付録 A に示すコードの抜粋を、インターセプタの実装を開始する際に使用できます。付録 A のコードを使用しても、Oracle の Web サイト上の WebLogic Enterprise ディベロッパ センタで入手できるスタータ ファイルをコピーしてもかまいません。

ファイル名
説明
intercep.h
インターセプタ ヘッダのスタータ ファイルです。このファイルの内容と、使用方法の説明は、「ステップ 3: インターセプタ ヘッダ ファイルの作成」に示しています。
intercep.cpp
インターセプタ実装のスタータ ファイルです。

WebLogic Enterprise ディベロッパ センタからこれらのスタータ ファイルを取得する方法については、『リリース ノート』を参照してください。

付録 A に示すサンプル インターセプタのコードを使用して、インターセプタの実装を開始できます。コード中で、YourInterceptor は実装しているインターセプタの名前を表します。ORB は常に ServiceContextList および CORBA::DataOutputStream の各パラメータについて、ニル リファレンスを渡します。これらのパラメータは、使用も参照もできません。またこの制限事項は将来のバージョンで変更される可能性があるため、nil についてのこれらのパラメータのテストはしないでください。

実行時のインターセプタの初期化

ORB の初期化時に、すべてのインターセプタがインスタンス化されます。それ以外では、要求レベルのインターセプタはインスタンス化されません。初期化の一環として、インターセプタの初期化ルーチンにより、インターセプタのサポート対象に応じて、クライアント インターセプタとターゲット インターセプタの一方または両方の実装のインスタンスをインスタンス化する必要があります。前述のように、単一の共有可能なイメージで、クライアントサイド インターセプタとターゲットサイド インターセプタの双方をサポートできます。その後、任意のインスタンス化されたインターセプタのインスタンスが、初期化ルーチンから返され、ORB 実行時に登録されます。

次のコードの抜粋部分は、InterceptorData インターセプタからのものです。クライアントサイド ORB の初期化時に、ORB によって呼び出された初期化オペレーションの宣言を示します。

void InterceptorDataClientInit(
CORBA::ORB_ptr TheORB,
RequestLevelInterceptor::ClientRequestInterceptor ** ClientPtr,
RequestLevelInterceptor::TargetRequestInterceptor ** TargetPtr,
CORBA::Boolean * RetStatus)

次のコードの抜粋部分は、InterceptorData クライアント インターセプタ クラスをインスタンス化するための文を示します。この抜粋部分は、受信される各クライアント要求の追跡を行い、ターゲット オブジェクトから返される応答に一致させるための、tracker というクラスを使用します。tracker クラスは、「要求内のオペレーションの識別」で説明します。

ClientInterceptorData * client = new ClientInterceptorData(TheORB, tracker);
if (!client)
{
tmpfile << "InterceptorDataClientInit: Client alloc failed"
<< endl << endl;
*RetStatus = CORBA_FALSE;
delete tracker;
return;
}

次のコード抜粋部分は、インターセプタ クラスを ORB に返すための文を示します。

*ClientPtr = client;
*TargetPtr = 0;
*RetStatus = CORBA_TRUE;
return;

要求からのインターセプタ名の取得

特定のインタフェースや要求で機能するインターセプタの場合は、要求に関連付けられたインタフェース ID を抽出する方法が必要です。それにより、インターセプタは要求を識別し、その中のデータをどのように処理すればよいかを理解できます。たとえば、InterceptorData インターセプタは PersonQuery アプリケーションからの要求で送信された要求パラメータを操作します。要求パラメータを操作するには、インターセプタはどの要求が送信されているのかを認識する必要があります。

次の InterceptorData サンプルからのコード抜粋部分は、RequestContext 構造体から抽出されたインタフェース ID を示します。

if (strcmp(request_context.interface_id.in(), 
PersonQuery::_get_interface_name()) != 0)
return ret_status;

要求内のオペレーションの識別

抽出されたインタフェース ID を使用して、InterceptorData サンプルは単純な switch 文でクライアント要求内のオペレーションを識別します。これにより、インターセプタは要求に含まれる要求パラメータの扱い方を認識します。

次のコード抜粋部分は、Exit オペレーション、またはデータベースに対しある人物を名前で指定した問合せを行うためのオペレーションがあるかどうか確認する、switch 文を示します。parser オブジェクトが使用されていることに注意してください。このオブジェクトは tracker オブジェクトより受信した要求からオペレーションを抽出します。

m_outfile << “   Operation:      “ << request_context.operation << endl;
PQ parser;
PQ::op_key key = parser.MapOperation(request_context.operation.in());
switch (key)
{
default:
m_outfile << “ ERROR: operation is not member of “
<< request_context.interface_id.in() << endl;
excep_val = new CORBA::BAD_OPERATION();
return Interceptors::REPLY_EXCEPTION;

case PQ::Exit:
m_outfile << endl;
return ret_status;

case PQ::ByPerson:
{
PersonQuery::Person per;
parser.GetByPerson(request_arg_stream, &per);
m_outfile << “ Parameters:” << endl;
m_outfile << per << endl;
}
break;

インターセプタの応答オペレーションの実装

クライアント要求からインタフェース ID を抽出するのは、かなり単純な作業です。しかし、ターゲット応答で同じ処理を行う場合はそれほど単純ではありません。ORB から受信する応答に関連付けられたインタフェースおよびオペレーションを知る必要がある場合、インターセプタは要求を追跡するための特別なロジックを必要とします。クライアントから受信した要求の追跡は、インターセプタの役割です。

InterceptorData サンプルは、Tracker と呼ばれる言語オブジェクトを実装します。これはターゲットに送られる要求の記録を取り、インターセプタにターゲット応答が返ると、それらの要求に応答を適合させるオブジェクトです。

InterceptorData サンプルの client_response および target_response オペレーションは、ターゲットから応答が返ると、Tracker オブジェクトからインタフェースおよびオペレーションの情報を抽出します。

次の InterceptorData コードの抜粋部分は、応答に関連付けられた要求を抽出するものです。

RequestInfo * req_info = m_tracker->CompleteRequest(reply_context);
if (!req_info)
{
m_outfile << “ unable to find request for this reply (must not be one
we care about)” << endl << endl;
return Interceptors::RESPONSE_NO_EXCEPTION;
}

//
// 必要なインタフェース。ここで、要求パラメータを
// 解析できるように、呼び出されているオペレーションを識別する
//

m_outfile << “ ReplyStatus: “;
OutputReplyStatus(m_outfile, reply_context.reply_status);
m_outfile << endl;
m_outfile << “ Interface: “ << req_info->intf() << endl;
m_outfile << “ Operation: “ << req_info->op() << endl;
PQ parser;
PQ::op_key key = parser.MapOperation(req_info->op());

これでインターセプタは応答に関連付けられた要求を取得したので、応答内のデータを適切に処理できます。

データ入力ストリームからのパラメータの読み出し

次のコードの抜粋部分は、InterceptorData のサンプルがどのようにして、データ ストリームからの要求パラメータを構造体に入れるのかの例を示します。次のコード抜粋部分のパラメータ S は、インターセプタの実装により PersonQuery オペレーションの応答パラメータ値を取得するのに使用可能な DataInputStream 構造体へのポインタを表します。このコード抜粋部分において、中かっこで囲まれたコードは、DataInputStream 構造体からの応答のパラメータを抽出するものです。DataInputStream 構造体の詳細については、「要求レベルのインターセプタの API」を参照してください。

void PQ::get_addr(CORBA::DataInputStream_ptr S, 
PersonQuery::Address *addr)
{
addr->number = S->read_short();
addr->street = S->read_string();
addr->town = S->read_string();
addr->state = S->read_string();
addr->country = S->read_string();
}

例外

excep_val パラメータ経由で返されたインターセプタからの例外は、CORBA::SystemException 基本クラスから派生したタイプのみです (これ以外で、インターセプタの実装が ORB に返す例外のタイプはすべて、ORB によって CORBA::UNKNOWN 例外に変換され、excep_val パラメータを介して渡されます)。例外は CORBA::SystemException クラスまたはその派生クラスの 1 つにマップする必要があります。

 


ステップ 3: インターセプタ ヘッダ ファイルの作成

インターセプタの実装ファイル内に何らかの実装コードを作成した後は、必要に応じてインターセプタ ヘッダ ファイルにデータまたはオペレーションを加える必要があります。

次のサンプル コードは、クライアントサイド インターセプタとターゲットサイド インターセプタの双方を実装する、インターセプタ実装ファイル用のヘッダ ファイルで必要な基本情報を示します。

また、この例では次のものも示されます。

このサンプル コードでは、YourInterceptor は作成しているインターセプタの名前を表します。

#include <CORBA.h>
#include <RequestLevelInterceptor.h>
#include <security_c.h> // セキュリティ用

class YourInterceptorClient : public virtual RequestLevelInterceptor::ClientRequestInterceptor
{
private:
YourInterceptorClient() {}
CORBA::ORB_ptr m_orb;
public:
YourInterceptorClient(CORBA::ORB_ptr TheOrb);
~YourInterceptorClient() {}
Interceptors::ShutdownReturnStatus shutdown(
Interceptors::ShutdownReason reason,
CORBA::Exception_ptr & excep_val);
CORBA::String id();
void exception_occurred (
const RequestLevelInterceptor::ReplyContext & reply_context,
CORBA::Exception_ptr excep_val);
Interceptors::InvokeReturnStatus client_invoke (
const RequestLevelInterceptor::RequestContext & request_context,
RequestLevelInterceptor::ServiceContextList_ptr service_context,
CORBA::DataInputStream_ptr request_arg_stream,
CORBA::DataOutputStream_ptr reply_arg_stream,
CORBA::Exception_ptr & excep_val);
Interceptors::ResponseReturnStatus client_response (
const RequestLevelInterceptor::ReplyContext & reply_context,
RequestLevelInterceptor::ServiceContextList_ptr service_context,
CORBA::DataInputStream_ptr arg_stream,
CORBA::Exception_ptr & excep_val);

};

class YourInterceptorTarget : public virtual RequestLevelInterceptor::TargetRequestInterceptor
{
private:
YourInterceptorTarget() {}
CORBA::ORB_ptr m_orb;
SecurityLevel1::Current_ptr m_security_current; // セキュリティ用
Security::AttributeTypeList * m_attributes_to_get; // セキュリティ用
public:
YourInterceptorTarget(CORBA::ORB_ptr TheOrb);
~YourInterceptorTarget();
Interceptors::ShutdownReturnStatus shutdown(
Interceptors::ShutdownReason reason,
CORBA::Exception_ptr & excep_val);
CORBA::String id();
void exception_occurred (
const RequestLevelInterceptor::ReplyContext & reply_context,
CORBA::Exception_ptr excep_val);
Interceptors::InvokeReturnStatus target_invoke (
const RequestLevelInterceptor::RequestContext & request_context,
RequestLevelInterceptor::ServiceContextList_ptr service_context,
CORBA::DataInputStream_ptr request_arg_stream,
CORBA::DataOutputStream_ptr reply_arg_stream,
CORBA::Exception_ptr & excep_val);
Interceptors::ResponseReturnStatus target_response (
const RequestLevelInterceptor::ReplyContext & reply_context,
RequestLevelInterceptor::ServiceContextList_ptr service_context,
CORBA::DataInputStream_ptr arg_stream,
CORBA::Exception_ptr & excep_val);

};

 


ステップ 4: インターセプタのビルド

インターセプタは、共有可能ライブラリに組み込まれます。したがって、インターセプタをビルドする手順は、プラットフォーム固有です。任意の特定プラットフォーム上でインターセプタをビルドするのに使用される特定のコマンドおよびオプションの詳細を知るには、Oracle Tuxedo ソフトウェア付属のインターセプタのサンプル アプリケーションをビルドする makefile を実行し、ビルドによって生じるログ ファイルで、ビルド結果を参照します。

サンプルのインターセプタをビルドするコマンドは、次のとおりです。

Windows 2003

> nmake -f makefile.nt

UNIX

> make -f makefile.mk

Oracle Tuxedo ソフトウェアに付属するサンプルのインターセプタのビルドおよび実行の詳細については、「PersonQuery サンプル アプリケーション」を参照してください。

 


ステップ 5: インターセプタのテスト

インターセプタをテストするには、次のタスクを実行する必要があります。

インターセプタの登録については、「CORBA 要求レベルのインターセプタのデプロイ」を参照してください。


  ページの先頭       前  次