Rainbow Engine

IT技術を分かりやすく簡潔にまとめることによる学習の効率化、また日常の気付きを記録に残すことを目指します。

C++

CORBA通信のPOA(Portable Object Adapter)とは?

投稿日:2021年11月18日 更新日:

 

<目次>

(1) CORBA通信のPOA(Portable Object Adapter)とは?
 (1-1) 概要と特徴
 (1-2) 一般的なPOAの処理構成
 (1-3) POAのサンプルプログラム例
 (1-4) 参考文献

(1) CORBA通信のPOA(Portable Object Adapter)とは?

本記事ではCORBA通信のPOA(Portable Object Adapter)について解説します。
CORBA通信の概要記事でご紹介している全体図の中で言うと、以下の⑤の部分について深掘りする記事です。
(図100)

(1-1) 概要と特徴

OAは一般的には、クライアント側のリクエストとサーバ側のメソッドを紐付けを「オブジェクト参照」により実現する機能です(⇒CORBAとは?)。言い換えると、クライアントの要求する処理を、サーバ側にディスパッチ(振り分け)する役割を果たしています。
 
特にCORBAの場合は、CORBA通信の仕様に即した「POA(Portable Object Adapter)」という形で存在しています。「Portable」という名前の通り、POAにおけるサーバント(クライアント要求を実装したクラス)は異なるORB実装の間でも運搬可能(通信可能)です。
 
(POAの特徴)
・異なるORB製品間でも受け渡し可能なオブジェクトの実装を可能にします
・オブジェクトを透過的に(利用者が意識せずとも)有効化する。
・サーバント(※注1)が複数のオブジェクトを同時に定義する事が可能です。
 
(※注1)クライアントからの要求内容を実装したサーバ側のクラス

(1-2) 一般的なPOAの処理構成

CORBAでPOAを用いてサーバ側アプリを実装する際は、サーバ側アプリにてPOAのインスタンスを生成する必要があります。
 
一般的にPOAのライフサイクルにおいては、以下のステップを踏みます。【◎必須】と【△任意】の表記はCORBA通信の最低限(HelloWorld)において必要かどうか?という観点で記載してみました。
 
STEP1:【◎必須】「ルートPOA」の取得
STEP2:【△任意】「POA」のポリシー定義
STEP3:【△任意】「POA」の生成
STEP4:【◎必須】「POAManager」の起動
STEP5:【△任意】サーバントのアクティブ化
STEP6:【◎必須】POAからオブジェクト参照の生成
 

●STEP1:【◎必須】「ルートPOA」の取得

 
「ルートPOA」はPOAの中でも、ORBの初期化インターフェイス(resolve_initial_references)を通じて「常に利用可能」なPOAです。サーバ側のアプリを実装する際には、まず最初にこの「ルートPOA」のインスタンスを生成します。ルートPOAのインスタンスを使って、①直接オブジェクトを操作するか、②新しいPOAオブジェクトを作成するか?をします。
 
(例)
//# ORBインスタンスの生成&初期化
ORB orb = ORB.init( args, null );
//# POAインスタンスの生成&初期化
POA rootPOA = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
 
この時、narrowメソッドはオブジェクト名を指定して、POAのインスタンスを返却します。
↓メソッドシグニチャ
public static POA narrow(Object obj)
 

●STEP2:【△任意】「POA」のポリシー定義

POAでは、オブジェクトの振る舞いや特性(IDの一意性、保持期間、ライフサイクルなど)を実装者が自由に設定できるような仕組みがあり、これを「ポリシー」と呼んでいます。具体的な設定値の例をご紹介します。
 
(表)

スレッド (概要)
生成されたPOAに適用するスレッド処理方式を指定。

(選択肢)
・ORB_CTRL_MODEL ⇒デフォルト値。ORB側でPOAへの要求をスレッドに割当て
・SINGLE_THREAD_MODEL ⇒単一スレッドのPOAの並列処理。

ライフスパン (概要)
POAで実装されたオブジェクトのライフスパンの設定

(選択肢)
・TRANSIENT ⇒最初に生成されたPOAインスタンスの外では利用不可
・PERSISTENT ⇒最初に生成されたPOAインスタンスの外では利用可能

 
ポリシーは配列に設定を格納し、POAの生成時にその配列を引数に指定して使います。
(例)
Policy[] tpolicy = new Policy[4];
tpolicy[0] = rootPOA.create_thread_policy(ThreadPolicyValue.ORB_CTRL_MODEL)
tpolicy[1] = rootPOA.create_lifespan_policy(LifespanPolicyValue.TRANSIENT );
tpolicy[2] = rootPOA.create_request_processing_policy(RequestProcessingPolicyValue.USE_ACTIVE_OBJECT_MAP_ONLY );
tpolicy[3] = rootPOA.create_servant_retention_policy(ServantRetentionPolicyValue.RETAIN);

●STEP3:【△任意】「POA」の生成

新規のPOAは既存のPOAの子供として、「create_POA」メソッドで生成されます。
 
↓メソッド概要
create_POA(String ①アダプタ名, POAManager ②紐付けるPOAマネージャー, Policy[] ③ポリシー定義)
 

●STEP4:【◎必須】「POAManager」の起動

「POAManager」は複数のPOAの状態管理をするオブジェクトで、POAを起動・停止するためのインターフェイス(activateメソッド)も提供します。基本的には各POAに対して対応するPOAManagerが存在しています。POAManagerを起動する事で、次の「オブジェクト参照」(≒ORBでオブジェクトを特定する為のデータ)の取得が可能となります。
 
(例)
POA rootpoa = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
rootpoa.the_POAManager().activate();

●STEP5:【△任意】サーバントのアクティブ化

(※注)この手順は、POAのポリシーで「RETAIN」を設定している場合に必要となります。
もし「RETAIN」ポリシーを設定している場合、サーバントとそれに紐付くオブジェクトIDの情報を、対応するPOAのオブジェクトマップに格納します(これを以てサーバントのアクティブ化処理としています)。以下のようなメソッドが使われていたら、この処理に該当します。

・activate_object (サーバーアプリ内で使用)
・activate_object_with_id (サーバーアプリ内で使用)
・set_servant_manager (POA内で使用)

●STEP6:【◎必須】POAからオブジェクト参照の生成

最後に、サーバ側でオブジェクト参照(≒ORBでオブジェクトを特定する為のデータ)を生成します。一度オブジェクト参照を生成すると、以降はクライアントと連携する事ができます。内部的にはオブジェクトの識別子となる情報(IDとか)を保持したり、オブジェクトに紐付くサーバアプリやPOAを特定する為の情報を保持します。
 
(例)サーバントを明示的にアクティブ化し、オブジェクト参照を紐付けを行った例
 
//# サーバント(helloImple)からオブジェクト参照を取得
org.omg.CORBA.Object ref = rootpoa.servant_to_reference(helloImpl);
Hello href = HelloHelper.narrow(ref);

//# ルートネーミングコンテキストの取得
org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);

//# オブジェクト参照とネーミングをバインド(紐付け)
String name = "Hello";
NameComponent path[] = ncRef.to_name( name );
ncRef.rebind(path, href);
 

(1-3) POAのサンプルプログラム例

参考文献②のPOAのHelloWorld用プログラムに対して、上記のSTEP1、STEP4、STEP6(【◎必須】の工程)をマッピングしたものです。
 
(図131)

import SampleApp.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.CORBA.*;
import org.omg.PortableServer.*;
import org.omg.PortableServer.POA;

import java.util.Properties;

//# サーバントのクラス(クライアントから要求される処理の実装クラス)
class HelloImpl extends HelloPOA {
  private ORB orb;

  public void setORB(ORB orb_val) {
    orb = orb_val;
  }

  public String sayHello() {
    return "\nHello world !!\n";
  }

  public void shutdown() {
    orb.shutdown(false);
  }
}

public class HelloServer {

  public static void main(String args[]) {
    try{
      // #### STEP1:【◎必須】「ルートPOA」の取得
      ORB orb = ORB.init(args, null);

      // #### STEP4:【◎必須】「POAManager」の起動
      POA rootpoa = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
      rootpoa.the_POAManager().activate();

      // #### STEP6:【◎必須】POAからオブジェクト参照の生成
      HelloImpl helloImpl = new HelloImpl();
      helloImpl.setORB(orb);

      org.omg.CORBA.Object ref = rootpoa.servant_to_reference(helloImpl);
      Hello href = HelloHelper.narrow(ref);

      org.omg.CORBA.Object objRef =
          orb.resolve_initial_references("NameService");
      NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);

      String name = "Hello";
      NameComponent path[] = ncRef.to_name( name );
      ncRef.rebind(path, href);

      System.out.println("HelloServer ready and waiting ...");

      orb.run();
    }

      catch (Exception e) {
        System.err.println("ERROR: " + e);
        e.printStackTrace(System.out);
      }

      System.out.println("HelloServer Exiting ...");

  }
}
 

(1-4) 参考文献

・①ポータブルオブジェクトアダプタ (POA) とは
 
・②Java IDL入門:Hello Worldサーバーの開発
 

Adsense審査用広告コード


Adsense審査用広告コード


-C++

執筆者:


comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

関連記事

Valgrindの使い方や見方について(基礎編)

  <目次> (1) Valgrindの使い方や見方について(基礎編)  (1-1) メモリリークのチェックのやり方  (1-2) 「valgrind」コマンドの基本的な使い方  (1-3) …

C++における「>>」の意味について

  <目次> (1) C++における「>>」の意味について  (1-1) 概要  (1-2) サンプルプログラム  (1-3) どんな時に使われる?⇒データ圧縮  (1-4) 備 …

C++のlocaltime関数がスレッドアンセーフである理由と使用上の注意点

  <目次> (1) C++のlocaltime関数がスレッドアンセーフである理由と使用上の注意点  (1-1) localtime関数がスレッドアンセーフである理由  (1-2) loca …

ポインタと参照の違いについてサンプルPGを使ってご紹介

  <目次> (1) ポインタと参照の違いについてサンプルPGを使ってご紹介  (1-1) ポインタと参照の概要  (1-2) 両者の違い①:宣言/初期化  (1-3) 両者の違い②:再代入 …

ValgrindのPossibly Lostの意味や実際のサンプルをご紹介

  <目次> (1) ValgrindのPossibly Lostの意味や実際のサンプルをご紹介  (1-1) Valgrindの「Possibly Lost」はどんな状況?  (1-2) …

  • English (United States)
  • 日本語
Top