Interstage Application Server アプリケーション作成ガイド (CORBAサービス編)
|
目次
索引

|
5.3.7.4 Servant Locator使用例 (ユーザインスタンス管理方式)
(1)IDL定義
module ODsample{
interface intf{
readonly attribute long value;
void add( in long a );
void sub( in long b );
};
interface Factory{
intf create( in string userid );
void destroy( in intf obj );
};
};
(2)ネーミングサービスの登録
OD_or_adm -c IDL:ODsample/Factory:1.0 -a Imple_POAsample4 -n ODsample::POAsample4
(3)アプリケーション構成概要図

(4)クライアントアプリケーション
#include <iostream>
#include <stdlib.h>
#include "orb_cplus.h"
#include "CosNaming_cplus.h"
#include "simple.h"
using std::cout;
using std::endl;
static CORBA::Object_var obj;
static CORBA::Environment env;
static CORBA::ORB_var orb;
static CosNaming::NamingContext_var cos_naming;
static CosNaming::Name name;
int main( int argc, char* argv[] )
{
try {
// ORBの生成と初期化
orb = CORBA::ORB_init( argc, argv, FJ_OM_ORBid, env );
// ネーミングサービスのオブジェクトリファレンスの取得
obj = orb->resolve_initial_references(
CORBA_ORB_ObjectId_NameService, env );
cos_naming = CosNaming::NamingContext::_narrow( obj );
// ネーミングサービスのresolveメソッドを発行し、
// サーバアプリケーションのオブジェクトリファレンスの獲得
name.length( 1 );
name[0]->id = ( const CORBA::Char* )"ODsample::POAsample4";
name[0]->kind = ( const CORBA::Char* )"";
obj = cos_naming->resolve( name, env );
// サーバアプリケーションのインタフェースクラスの獲得
ODsample::Factory* target = ODsample::Factory::_narrow( obj );
char userid[1024];
printf( "USERID -> " );
userid[0] = 0;
scanf( "%s", userid );
if( strlen( userid ) < 1 ){
return 255;
}
// FactoryでインタフェースアプリのIORを作成する
ODsample::intf* obj2 = target->create( userid, env );
CORBA::Long a = 10;
CORBA::Long b = 5;
// サーバアプリケーションのメソッド呼出し
CORBA::Long ret = obj2->value( env );
printf( "value = %d\n", ret );
obj2->add( a, env );
printf( "add( %d )\n", a );
ret = obj2->value( env );
printf( "value = %d\n", ret );
obj2->sub( b, env );
printf( "sub( %d )\n", b );
ret = obj2->value( env );
printf( "value = %d\n", ret );
target->destroy( obj2, env );
CORBA::release( target );
CORBA::release( obj2 );
} catch( CORBA::SystemException& se ) {
cout << "exception-id: " << se.id() << endl;
exit(1);
} catch( CORBA::Exception& e ) {
cout << "exception-id: " << e.id() << endl;
exit(1);
}
return 0;
}
(5)サーバアプリケーション
#include <iostream>
#include <stdlib.h>
#include "orb_cplus.h"
#include "poa.h"
#include "CosNaming_cplus.h"
#include "simple.h"
using std::cout;
using std::endl;
static CORBA::ORB_var orb;
static CORBA::Object_var obj;
static CORBA::Environment env;
static PortableServer::POA_var rootPOA;
static PortableServer::POA_var factory_poa;
static PortableServer::POA_var childPOA;
static CORBA::PolicyList policies( 4 );
static CORBA::PolicyList inf_policies( 4 );
static PortableServer::POAManager_var poa_manager;
static CORBA::Long val = 10;
// ユーザアプリケーション:メイン処理クラス
int main( int argc, char*argv[] )
{
int current_argc = argc;
try{
// ORBの生成と初期化
orb = CORBA::ORB_init( current_argc, argv, FJ_OM_ORBid, env );
// RootPOAのオブジェクトリファレンスの取得
obj = orb->resolve_initial_references( "RootPOA", env );
// RootPOAのPOAオブジェクト獲得
rootPOA = PortableServer::POA::_narrow( obj );
// Factoryインタフェース用のPOA作成
// ポリシリスト作成
policies.length( 4 );
policies[0] = rootPOA->create_servant_retention_policy(
PortableServer::NON_RETAIN, env );
policies[1] = rootPOA->create_request_processing_policy(
PortableServer::USE_DEFAULT_SERVANT, env );
policies[2] = rootPOA->create_id_assignment_policy(
PortableServer::SYSTEM_ID, env );
policies[3] = rootPOA->create_id_uniqueness_policy(
PortableServer::MULTIPLE_ID, env );
factory_poa = rootPOA->create_POA( "IDL:ODsample/Factory:1.0",
PortableServer::POAManager::_nil(), policies ,env);
// インタフェース用のPOA作成
// ポリシリスト作成
inf_policies.length( 4 );
inf_policies[0] = rootPOA->create_servant_retention_policy(
PortableServer::NON_RETAIN, env );
inf_policies[1] = rootPOA->create_request_processing_policy(
PortableServer::USE_SERVANT_MANAGER, env );
inf_policies[2] = rootPOA->create_id_assignment_policy(
PortableServer::USER_ID, env );
inf_policies[3] = rootPOA->create_id_uniqueness_policy(
PortableServer::UNIQUE_ID, env );
childPOA = rootPOA->create_POA( "childPOA",
PortableServer::POAManager::_nil(), inf_policies ,env);
// FactoryServantの生成
ODsample_Factory_impl* svt = new ODsample_Factory_impl();
// Factoryインタフェース用POAのDefault Servantに設定
factory_poa->set_servant( svt, env );
// ServantLocatorの生成
PortableServer::ServantLocator* svtloc = new UserServantLocator();
// インタフェース用POAにServantManagerとして登録
childPOA->set_servant_manager( svtloc, env );
// POAマネージャの獲得
poa_manager = rootPOA->the_POAManager( env );
// POAマネージャのactivate
poa_manager->activate( env );
orb->run( env );
} catch( CORBA::Exception& e ) {
cout << "exception-id: " << e.id() << endl;
exit(1);
}
return 0;
}
// 管理テーブル
class ServantList
{
public:
ServantList() {
_next = NULL;
_svr = NULL;
_oid = NULL;
};
~ServantList() {
if( _svr != NULL ) {
_svr->servant_delete();
}
if( _oid != NULL ) {
delete _oid;
}
};
PortableServer::ObjectId* getObjectId() {
return _oid;
};
ServantList* getNext() {
return _next;
};
// 管理テーブルから検索
PortableServer::ServantBase* getServant( const PortableServer::ObjectId* oid ) {
if( _svr == NULL ) {
if( _next == NULL ) {
return NULL;
}
return _next->getServant( oid );
}
if( equal( oid ) ) {
return _svr;
}
if( _next ) {
return _next->getServant( oid );
}
return NULL;
};
long equal( const PortableServer::ObjectId* oid ) {
if( _oid == NULL ) {
return 0;
}
if( oid->length() == oid->length() ) {
long len = oid->length();
long i;
for( i = 0 ; i < len ; i++ ) {
if( oid->operator[](i) != _oid->operator[](i) ) {
return 0;
}
}
return 1;
}
return 0;
};
// 管理テーブルから削除
void remove( PortableServer::ObjectId* oid ) {
if( _next != NULL ) {
if( _next->equal( oid ) ) {
ServantList* del = _next;
_next = _next->getNext();
delete del;
}
}
};
// 管理テーブルへ追加
void put( const PortableServer::ObjectId* oid, PortableServer::ServantBase* svr ) {
if( _next != NULL ) {
_next->put( oid, svr );
} else {
_next = new ServantList();
_next->_svr = svr;
_next->_oid = new PortableServer::ObjectId( *oid );
}
};
private :
PortableServer::ObjectId* _oid;
PortableServer::ServantBase* _svr;
ServantList* _next;
};
// 管理テーブルのインスタンス
ServantList servant_list;
// ODsample_Factory_impl::create:メソッドの実装
ODsample::intf_ptr ODsample_Factory_impl::create(
const CORBA::Char* str,
CORBA::Environment& env)
throw( CORBA::Exception ){
try{
long len = strlen( str );
CORBA::Octet* buf = PortableServer::ObjectId::allocbuf( len );
memcpy( buf, str, len );
PortableServer::ObjectId_var userid = new PortableServer::ObjectId(
len, len, buf, CORBA_TRUE );
// オブジェクトリファレンスの生成
CORBA::Object_var _tmpObj = childPOA->create_reference_with_id( *userid,
"IDL:ODsample/intf:1.0",env );
ODsample::intf_ptr ior = ODsample::intf::_narrow( _tmpObj );
return ior;
} catch(CORBA::Exception& e ) {
cout << "exception-id: " << e.id() << endl;
throw e;
}
};
// ODsample_Factory_impl::destroy:メソッドの実装
void ODsample_Factory_impl::destroy(
ODsample::intf_ptr obj,
CORBA::Environment& env)
throw( CORBA::Exception ){
try{
// オブジェクトリファレンスからオブジェクトIDを求める
PortableServer::ObjectId_var oid = childPOA->reference_to_id( obj, env );
// Servantを管理テーブルから削除
servant_list.remove( oid );
} catch( CORBA::Exception& e ) {
cout << "exception-id: " << e.id() << endl;
throw e;
}
};
// ServantLocator:Servant生成クラス(ServantLocatorを継承)
class UserServantLocator: public PortableServer::ServantLocator
{
public:
UserServantLocator() {};
~UserServantLocator() {};
PortableServer::Servant preinvoke(
const PortableServer::ObjectId& oid,
PortableServer::POA_ptr adapter,
const CORBA::Identifier operation,
PortableServer::ServantLocator::Cookie& cookie,
CORBA::Environment& = CORBA::Environment() )
throw( CORBA::Exception )
{
// Servantを検索する。みつからなければnewで生成する。
PortableServer::Servant svt = servant_list.getServant( &oid );
if( svt == NULL ) {
svt = new ODsample_intf_impl();
servant_list.put( &oid, svt );
}
// Cookieの作成
cookie = ( CORBA::ULong )svt;
return svt;
};
void postinvoke(
const PortableServer::ObjectId& oid,
PortableServer::POA_ptr adapter,
const CORBA::Identifier operation,
PortableServer::ServantLocator::Cookie cookie,
PortableServer::Servant the_servant,
CORBA::Environment& = CORBA::Environment() )
throw( CORBA::Exception )
{
};
};
// ODsample_intf_implクラスのメソッド実装
void ODsample_intf_impl::add(
CORBA::Long a,
CORBA::Environment& env )
throw( CORBA::Exception )
{
cout << "ODsample::intf::add()" << endl;
cout << " value : " << val << endl;
cout << " a : " << a << endl;
val = val + a;
cout << " result: " << val << endl;
};
void ODsample_intf_impl::sub(
CORBA::Long b,
CORBA::Environment& env )
throw( CORBA::Exception )
{
cout << "ODsample::intf::sub()" << endl;
cout << " value : " << val << endl;
cout << " b : " << b << endl;
val = val - b;
cout << " result: " << val << endl;
};
CORBA::Long ODsample_intf_impl::value(
CORBA::Environment& env )
throw( CORBA::Exception )
{
return val;
};
(6)例外情報の獲得
サーバアプリケーションで例外を獲得する方法の詳細については、“サーバアプリケーションの例外処理”を参照してください。
All Rights Reserved, Copyright(C) 富士通株式会社 2006