4. 他社OTS製品との相互接続について

他社が提供するOTSシステムとの相互接続方法について説明します。


 
4.1. 概要

分散オブジェクト技術CORBAに対応したアプリケーションサーバが多くのベンダから出荷されています。同時に基幹系の情報システムといった、より高い信頼性が要求されるような業務分野にもそれが利用されるようになると考えられます。
そのため、トランザクションサービスを利用する市場が拡大し、それをマルチベンダ環境で実現することが必須技術の1つになることが予想できます。

Transactionサービスは、CORBAトランザクションサービス1.4に準拠しているので、この仕様に準拠した他社のCORBA OTS製品との接続が可能です。現実に複数社との2フェーズコミットメントを用いた相互接続試験も成功しているという実績があります。

複数OTSを用いたシステムの典型的な1例としては次のような、商品の受注システムが考えられます。

2つのOTS製品を用いたシステムの例

簡単に処理の流れを説明します。

  1. クライアントAPでは、トランザクションを開始(begin)して、AシステムのX社OTSにそれを通知します。その後顧客管理オブジェクトが呼び出されます。ここでは入力された情報をもとにデータベースAを仮更新します。
  2. 顧客管理オブジェクトではその後、Bシステム内の受注管理オブジェクトを呼び出します。ここでは注文した商品の在庫チェック等を実施し、データベースBを仮更新します。このときX社OTSからY社OTSに対してトランザクション情報が引き継がれて1つのグローバルトランザクションとして動作します。
  3. ここまで正常に終了すると、クライアントAPでトランザクションの終了要求(commit)を発行します。失敗した場合はロールバック要求を出して業務を失敗させます。
  4. ここで2フェーズコミット処理が2つのOTSにより実施されます。コミットの延長でデータベースを正式に更新し、トランザクションは完了します。

 
4.2. 接続方法

上記の例の場合、Aシステムでは、Bシステム内の受注管理オブジェクトを呼び出すために、そのリファレンスを入手する必要があります。入手の方法として主なものに、次の2つが考えられます。

  1. CORBA名前サービスに、受注管理オブジェクトのオブジェクトリファレンスを登録し、それをAシステム側で使用する。
  2. 受注管理オブジェクトのオブジェクトリファレンスをobject_to_string等で文字列化してファイルに格納し、それをAシステム側で読み込む。その後string_to_object等で文字列からオブジェクトリファレンスに戻して使用する。

CORBA名前サービスは仕様があいまいな点が多いため、各ORBベンダ毎に独自の実装を行っている場合が多く、相互接続できないケースが頻繁に起こります。OMGではこれを改善するためにこれを進化させた仕様である「インタオペラブル名前サービス(INS)」を提唱しています。これをX社ORBとY社ORBの両方がサポートしていれば、この手段は有効になります。

実際の方法について説明します。

● Bシステム側

リファレンスをファイルに格納する形式
BシステムのサーバAPを起動して受注管理オブジェクトを作成する際に、このオブジェクトリファレンスを文字列化し、ファイルに格納して、それをAシステム側で参照します。サーバAPのプログラミング例の一部を次に示します。エラー処理は省いています。

IDLファイル

 interface test : CosTransacttions::TransactionalObject {
	void mehtod();
 };



メイン処理部分

 #include "iostream.h"
 #include "fstream.h"
 #include "stdio.h"
 #include "orb.h"
 ……

 int main(int argc, char **argv) {
   ……
   // ORB、POA(rootPOA)の初期化等

   ……
   // オブジェクトリファレンスの生成
   test* p = new test();
   CORBA::Object_var o = rootPOA->servant_to_reference(p);
   test_ptr tp = test::_narrow(o);

   // 文字列に変換
   CORBA::String_var str = ORB->object_to_string(tp);
   
 #define DEF_FILE  "ior.dat" 
   // ior.datという名前のファイルに格納
   ofstream strm(DEF_FILE);
   strm &st str << endl;
   strm.close();
   ...

 };


インターオペラブル名前サービスを使用する形式
BシステムのサーバAPで、受注管理オブジェクトのリファレンスをインタオペラブル名前サービスに登録する場合、次のようなプログラミングになります。登録作業自体は、提供しているサンプルプログラムと同様に名前サービスのインタフェースを使用します。

なおここでは、リファレンスを格納するための名前サーバが動作するマシンはBシステム内に存在するケースを考えることにします。


 #include "orb.h"
 ……

 int main(int argc, char **argv) {
   ……
   // ORB、POA(rootPOA)の初期化等

   ……
   // オブジェクトリファレンスの生成
   test* p = new test();
   CORBA::Object_var o = rootPOA->servant_to_reference(p);
   test_ptr tp = test::_narrow(o);

   // インタオペラブル名前サーバに登録
   // 実際は名前サービスへの登録と同じ要領

   // NamingServiceオブジェクトリファレンスの取得
   CORBA::Object_var obj = 
       orb->resolve_initial_references("NameService");
   CosNaming::NamingContext_var nmctx = 
       CosNaming::NamingContext::_narrow(obj);

   CosNaming::Name test;
   test.length(1);
   test.id = (const char*)"test";
   test[0].kind = (const char*)"";
   nmctx->bind(test, tp);
   ...
 };


● Aシステム側

リファレンスをファイルに格納する形式
Aシステム側から、Bシステムのオブジェクト呼び出しを実施するために、そのオブジェクトリファレンスを取得します。Bシステム側で作成した"ior.dat"ファイルからオブジェクトリファレンスを取り出します。プログラミング例の一部を次に示します。


 #include "stdio.h"
 #include "stdlib.h"
 #include "string.h"
 #include "orb.h"
 ……

 int main(int argc, char **argv) {
   ……
   // ORBの初期化等

   ……

 #define DEF_FILE  "ior.dat" 
   // ファイルから文字列を取得
   FILE *fp = fopen(DEF_FILE, "r");

# define BUFFER_SIZE 1024
   char buffer[BUFFER_SIZE], *bp;
   fgets(buffer, BUFFER_SIZE, fp);
   fclose(fp);
   if (bp = strchr(buffer, '\n'))
	*bp = '\0';

   // オブジェクトリファレンスに変換
   CORBA::Object_var o = ORB->string_to_object(buffer);
   test_ptr tp = test::_narrow(o);
   ...
   // tpを用いてBシステムのオブジェクト呼び出しを実施
   ...
 };


インターオペラブル名前サービスを使用する形式
Bシステムのオブジェクトリファレンスを取得します。Aシステム側ではBシステムで動作する名前サーバにアクセスして目的のオブジェクトリファレンスを取り出します。プログラミング例の一部を次に示します。インタオペラブル名前サービスの詳細については、「Object Broker オンラインマニュアル」を参照してください。


 #include "orb.h"
 ……

 int main(int argc, char **argv) {
   ……
   // ORBの初期化等

   ……

   // インタオペラブル名前サーバから目的のリファレンスを取得
   CORBA::Object_var obj = 
       orb->string_to_object(
           "iiopname://Y社名前サービスのホスト名/test");
   test_ptr tp = test::_narrow(o);
   ...
 };