CORBAリクエスト・レベルのインターセプタの使用

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

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;
}

//
// This is the interface we are expecting. Now identify the operation
// being invoked, so we can parse the request parameters.
//

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> //for security

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; //for security
Security::AttributeTypeList * m_attributes_to_get; //for security
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リクエスト・レベルのインターセプタのデプロイ」を参照してください。


  先頭に戻る       前  次