CORBA
Table of contents
- Introdução
- ORB - Object Request Broker
- Clientes
- Servidores
- IDL
- Repositório de interfaces
- Repositório de implementação
- Dynamic Invocation Interface
- Interoperabilidade
- COSS - Common Object Service Specification
- OA - Object Adapter
- BOA - Basic Object Adapter
- POA Portable Object Adapter
- Instalação do omniORB no Debian
- Iniciar o servidor de nomes
- Exemplo
- Criando o servidor
- Implementação do Servant
- Cliente CORBA
- Makefile
- Todo
- Referências
Introdução
O que é CORBA?
- é o acrônimo para Common Object Request Broker Architecture
- é um framework para construção de sistemas distribuídos orientados a objetos
- é multiplataforma
- é independente de linguagem
- é um padrão aberto e extensível definido pela Object Management Group
- clientes e servidores estão em diferentes máquinas
- programas clientes enviam mensagens para servidores remotos como se este estivesse locais (location transparency)
O que é a OMG?
- www.omg.org
- fundada em 1989
- somente provê especificações
- não provê implementações
- todas as especificações são free
CORBA vs SOAP/XML-RPC
SOAP
eXML-RPC
são protocolos wireCORBA
inclui:- um protocolo wire
GIOP
- object model
IDL
- mapeamento de linguagem
- serviços
- códigos de cliente e servidor portáveis entre implementações CORBA
CORBA é pesado?
- uma arquitetura mínima requer algumas dezenas de kB (segundo CORBA? Isn’ t that Obsolete ?)
ORB - Object Request Broker
- é o núcleo da Object Management Architecture
- integra:
- diferentes linguagens
- diferentes arquiteturas
- diferentes sistemas operacionais
- é responsável por:
- encontrar uma implementação para uma requisição
- preparar implementações para receber requisições
- comunicar dados das requisições
Clientes
- possuem referências para objetos e invocam operações nestes objetos
- conhecem apenas a interface dos objetos do servidor
- não conhecem a implementação dos objetos nem os adaptadores utilizados por estas implementações
- invocam interfaces definidas por uma IDL
- invocam as implementações através de:
- proxies (IDL generated stubs)
- DII (Dynamic Invocation Interface)
Servidores
- se registram no ORB
- se disponibilizam para aceitar requisições
- implementam uma IDL
IDL
- provê interfaces independente de linguagem e sistema operacional
- é puramente declarativa (não provê detalhes de implementação)
- é fortemente tipada
- especificações podem ser escritas e invocadas em qualquer linguagem
IDL Features
- modules
- interfaces
- operations
- attributes
- inheritance
- basic types
- arrays
- sequences
- struct, enum, union
- typedef
- consts
- exceptions
Tipos básicos
- float
- double
- long
- short
- unsigned long
- unsigned short
- char
- boolean
- octet
- any
Direções dos parâmetros
in
- do cliente para o servidorout
- do servidor para o clienteinout
- do cliente para o servidor e de volta para o cliente
Exceções
CORBA define dois tipos de exceções:
-
system exceptions: exceções padrões definidas pelo CORBA
-
user defined exceptions: exceções definidas pelo usuário através da IDL
-
Implicitamente, todas as operações definidas na IDL podem lançar qualquer uma das exceções padrão do sistema CORBA
-
Nenhuma referência para exceções padrão devem aparecer na especificação da IDL
-
para especificar que uma operação pode lançar uma exceção definida pelo usuário você deve:
- primeiro definir a estrutura da exceção
- incluir
raises
à definição da operação
-
uma exceção da IDL pode conter membros
Interface Bank {
exception Reject {
string reason; // membro da exceção
};
exception TooMany {}; // exceção sem membros
Account newAccount( in string name ) raises (Reject, TooMany);
};
Operações oneway
Interface Account {
oneway void notice( in string notice );
};
- não bloqueantes
- não aceitam parâmetros
out
ouinout
- não lançam exceções (não aceitam
raise
)
The OMG CORBA specification defines the following exceptions:
BAD_CONTEXT
- if a request does not contain a correct context this exception is raised.BAD_INV_ORDER
- this exception indicates that operations has been invoked operations in the wrong order, which would cause, for example, a dead-lock.BAD_OPERATION
- raised if the target object exists, but that the invoked operation is not supported.BAD_PARAM
- is thrown if, for example, a parameter is out of range or otherwise considered illegal.BAD_TYPECODE
- if illegal type code is passed, for example, encapsulated in an any data type the ‘BAD_TYPECODE’ exception will be raised.BAD_QOS
- raised whenever an object cannot support the required quality of service.CODESET_INCOMPATIBLE
- raised if two ORB’s cannot communicate due to different representation of, for example, char and/or wchar.COMM_FAILURE
- raised if an ORB is unable to setup communication or it is lost while an operation is in progress.DATA_CONVERSION
- raised if an ORB cannot convert data received to the native representation. See also the ‘CODESET_INCOMPATIBLE’ exception.FREE_MEM
- the ORB failed to free dynamic memory and failed.IMP_LIMIT
- an implementation limit was exceeded in the ORB at run time. A object factory may, for example, limit the number of object clients are allowed to create.INTERNAL
- an internal failure occurred in an ORB, which is unrecognized. You may consider contacting the ORB providers support.INTF_REPOS
- the ORB was not able to reach the interface repository, or some other failure relating to the interface repository is detected.INITIALIZE
- the ORB initialization failed due to, for example, network or configuration error.INVALID_TRANSACTION
- is raised if the request carried an invalid transaction context.INV_FLAG
- an invalid flag was passed to an operation, which caused, for example, a connection to be closed.INV_IDENT
- this exception indicates that an IDL identifier is incorrect.INV_OBJREF
- this exception is raised if an objet reference is malformed or a nil reference (see also corba:create_nil_objref/0).INV_POLICY
- the invocation cannot be made due to an incompatibility between policy overrides that apply to the particular invocation.MARSHAL
- this exception may be raised by the client- or server-side when either ORB is unable to marshal/unmarshal requests or replies.NO_IMPLEMENT
- if the operation exists but no implementation exists, this exception is raised.NO_MEMORY
- the ORB has run out of memory.NO_PERMISSION
- the caller has insufficient privileges, such as, for example, bad SSL certificate.NO_RESOURCES
- a general platform resource limit exceeded.NO_RESPONSE
- no response available of a deferred synchronous request.OBJ_ADAPTER
- indicates administrative mismatch; the object adapter is not able to associate an object with the implementation repository.OBJECT_NOT_EXIST
- the object have been disposed or terminated; clients should remove all copies of the object reference and initiate desired recovery process.PERSIST_STORE
- the ORB was not able to establish a connection to its persistent storage or data contained in the the storage is corrupted.REBIND
- a request resulted in, for example, a ‘LOCATION_FORWARD’ message; if the policies are incompatible this exception is raised.TIMEOUT
- raised if a request fail to complete within the given time-limit.TRANSACTION_MODE
- a transaction policy mismatch detected.TRANSACTION_REQUIRED
- a transaction is required for the invoked operation but the request contained no transaction context.TRANSACTION_ROLLEDBACK
- the transaction associated with the request has already been rolled back or will be.TRANSACTION_UNAVAILABLE
- no transaction context can be supplied since the ORB is unable to contact the Transaction Service.TRANSIENT
- the ORB could not determine the current status of an object since it could not be reached. The error may be temporary.UNKNOWN
- is thrown if an implementation throws a non-CORBA, or unrecognized, exception.
Estruturas
struct PersonalDetails {
string name;
short age;
};
interface Bank {
PersonalDetails getPerDet(in string name);
};
Arrays
- podem ser multidimensionais
- precisam ter tamanho fixo (conhecido em tempo de definição)
Account bankAccounts[100];
short matrix[10][20]; // 2D array
Constantes
Interface Bank {
const long MaxAccounts = 10000;
};
Contantes dos tipos long
, float
e string
podem ser declarada.
Typedef
typedef short size;
size i;
typedef Account Accounts[100]; // acho que está invertido aqui
Accounts bankAccounts;
Módulos
Module Finance {
interface Bank { ... };
interface Account { ... };
};
- são usados para agrupar interfaces em unidades lógicas
- utilize nomes completos (p.e.
Finance::Account *a;
)
Preprocessador
- baseado no preprocessador do C++
- substituição de macro
- compilação condicional
- inclusão de IDL
#include
#define
#if
#ifdef
#defined
Mapeamento para linguagem
- linguagens OO e non-OO acessam de modos diferentes
- tipos específicos da linguagem
- estrutura do stub cliente (somente para non-OO)
- interface de invocação dinâmica
- esqueleto de implementação
- adaptadores de objeto
- interface direta ao ORB
Mapeamento de identificadores
- usa o mesmo nome
- se for uma palavra reservada do C++ receberá um
_
como prefixo (p.e._new
)
Mapeamento de interface
- são mapeadas para classes
- uma IDL mapeada para uma classe C++ não pode ser instanciada
Interface Account { ... }
será mapeado para:
class Account : public virtual CORBA::Object { ... }
Mapeamento de escopo
Interface para classe
Interface Bank {
struct Details { ... };
};
será mapeado para:
class Bank {
public:
struct Details { ... };
};
Module para namespace
Module M {
Interface A { ... };
Interface B { ... };
};
será mapeado para:
namespace M {
class A { ... };
class B { ... };
};
Acessíveis via M::A
e M::B
.
Mapeamento do módulo padrão do CORBA
Será mapeado para:
namespace CORBA { ... }
Utilize os membros como:
CORBA::ORB_init( ... );
Mapeamento de tipos
IDL | C++ | Tamanho e faixa |
---|---|---|
short | CORBA::Short | 16 bit: |
long | CORBA::Long | 32 bit: |
long long | CORBA::LongLong | 64 bit: |
unsigned short | CORBA::UShort | 16 bit: |
unsigned long | CORBA::ULong | 32 bit: |
unsigned long long | CORBA::ULongLong | 64 bit: |
float | CORBA::Float | 32 bit IEEE single precision floating point number |
double | CORBA::Double | 64 bit IEEE double precision floating point number |
long double | CORBA::LongDouble | – |
char | CORBA::Char | 8 bit |
wchar | CORBA::WChar | – (Wide Char) |
string | CORBA::char * | – |
wstring | CORBA::WChar * | – |
boolean | CORBA::Boolean | true/false |
octet | CORBA::Octet | (unsigned char) 8 bit raw. Sem conversão |
any | CORBA::Any | Arbitrary |
Repositório de interfaces
- provê armazenamento para informações da IDL
- um programa pode referenciar objetos cuja interface será conhecida em tempo de execução
- estas informações podem ser usadas pelo ORB para realizar requisições
- pode armazenar outras informações sobre interfaces:
- debugging
- info
- browser routines
Repositório de implementação
- informações que o ORB utiliza para localizar e ativar implementações de um servidor de objetos
- armazena informações de ativação:
- máquina onde um servidor pode ser iniciado a partir de uma requisição do cliente
Dynamic Invocation Interface
- Em vez de chamar um stub específico de uma operação, é possível especificar um objeto, operação e parâmetros para através de uma chamada ou sequência de chamadas
- o cliente precisa fornecer os tipos dos parâmetros passados
Interoperabilidade
- suporta rede de objetos distribuídos em múltiplos ORBs (heterogêneos)
- InterORBability
GIOP
: (General Inter-ORB Protocol) sintaxe padrão de transferência e conjunto de formato de mensagens- ESIOP: (Environment Specific Inter-ORB Protocol) protocolo especializado
IIOP
: mapeamentoTCP/IP
paraGIOP
COSS - Common Object Service Specification
- naming
- events
- life cycle
- time
- transactions
- concurrency
- persistence
- query
- security
- licensing
- relationships
- properties
- externalization
- collection
OA - Object Adapter
- Conectam implementações de objetos ao ORB
- Ativam os múltiplos objetos implementados por um servidor
- Encaminhamento de requisições de serviço
- Geram object references
- Para ter o status de CORBA Object o objeto deve ser registrado com o adaptador
BOA - Basic Object Adapter
- Presente na especificação CORBA até a revisão 2.1
- CORBA 2.2 substituiu o BOA pelo POA
- ORB com BOA significa que os servidores não são portáveis
POA Portable Object Adapter
- O POA (Portable Object Adapter) auxilia o ORB (Object Request Broker) na passagem das requisições do clientes para a implementação do servidor (servant).
- O POA interpreta a requisição, empacota a passagem de parâmetros e então localiza o servant e os tratadores de recuperação erros e de segurança.
- Isto habilita portabilidade, independência de fabricantes e extensibilidade compatível com a especificação da OMG (Object Management Group)
- POA também habilita a persistência de objetos bem como dá suporte a ciclo de vida do serviço
- Identificadores de objetos automaticamente gerados ou especificados pelo usuário
- Ativação explícita ou por demanda
- Relação: um servant <-> um ou mais objetos CORBA
- Aplicação tem total controle sobre o comportamento e sobre a existência dos objetos CORBA
- Servants podem usar esqueletos estáticos ou dinâmicos
Identificador de Objeto
- Valor usado para identificar um objeto no contexto de um POA
- Não é um identificador globalmente único!
- Pode ser determinado pela aplicação ou gerado pelo POA
typedef sequence<octet> ObjectID;
- O POA coloca esse valor no campo object id da IOR
O Campo Object Id da IOR
Instalação do omniORB no Debian
apt install libomniorb4-dev omniidl omniorb omniorb-doc omniorb-nameserver omniidl-python python-omniorb
Iniciar o servidor de nomes
OmniORB
Incluir no arquivo /etc/omniORB.cfg
a seguinte linha:
InitRef = OmniNameService=corbaname::localhost
O nome OmniNameService deve ser conhecido pelo servidor e pelo cliente.
Para iniciar o servidor de nomes do OmniORB use:
omniNames -start
Exemplo de saída do comando acima:
omniNames: (0) 2019-12-30 15:36:29.516974: Data file: '/var/lib/omniorb/omninames-erebo.dat'.
omniNames: (0) 2019-12-30 15:36:29.517058: Starting omniNames for the first time.
omniNames: (0) 2019-12-30 15:36:29.517348: Wrote initial data file '/var/lib/omniorb/omninames-erebo.dat'.
omniNames: (0) 2019-12-30 15:36:29.517444: Read data file '/var/lib/omniorb/omninames-erebo.dat' successfully.
omniNames: (0) 2019-12-30 15:36:29.517529: Root context is IOR:010000002b00000049444c3a6f6d672e6f72672f436f734e616d696e672f4e616d696e67436f6e746578744578743a312e300000010000000000000070000000010102000d0000003139322e3136382e302e31330000f90a0b0000004e616d6553657276696365000300000000000000080000000100000000545441010000001c000000010000000100010001000000010001050901010001000000090101000354544108000000ad430a5e010075e0
omniNames: (0) 2019-12-30 15:36:29.517600: Checkpointing Phase 1: Prepare.
omniNames: (0) 2019-12-30 15:36:29.517703: Checkpointing Phase 2: Commit.
omniNames: (0) 2019-12-30 15:36:29.517802: Checkpointing completed.
A porta padrão é a 2809
.
Os arquivos de controle serão criados por padrão no diretório /var/lib/omniorb/
:
/var/lib/omniorb/omninames-nome-da-maquina.dat
/var/lib/omniorb/omninames-nome-da-maquina.bak
Para especificar um diretório diferente use a opção -logdir
:
omniNames -logdir /tmp -start
MICO
Para iniciar o servidor de nomes do MICO use:
nsd -ORBIIOPAddr inet:localhost:2809
Veja exemplo em Connecting 3 ORBs.
Exemplo
Criando a IDL
Arquivo de interface Data.idl
:
#ifndef __DATADIST_IDL__
#define __DATADIST_IDL__
module Data
{
interface ServiceA {
boolean CallServiceRoutineA (
in long num1,
inout long num2,
out long retNum );
boolean CallServiceRoutineB (
inout long num1,
inout long num2);
};
};
#endif
Gerando backend a partir da IDL
Use a opção -b
para escolher o backend
a ser gerado.
omniidl -bcxx Data.idl
omniidl -bpython Data.idl
omniidl -bdump Data.idl
Gerando Python
omniidl -bpython Data.idl
Os arquivos abaixo são criados:
Data_idl.py
Data__POA/__init__.py
Data/__init__.py
Descrever os arquivos gerados em python
.
lorem ipsum
lorem ipsum
lorem ipsum
lorem ipsum
Gerando C++
Ao executar o seguinte comando:
omniidl -bcxx Data.idl
os arquivos abaixo são criados:
Data.hh
- cabeçalho que será usado pelo cliente e pelo servidorDataSK.cc
- deve ser compilado e lincado com o programa que proverá a infraestrutura de comunicação
Contendo os seguintes items:
- classe
ServiceA
contendo funções estáticas e definições de tipos ServiceA_ptr
- um ponteiro para o tipo do objeto de referênciaServiceA_var
- um helper para gerenciamento de memória usado porServiceA_ptr
- classe
POA_Service!
- a classe esqueleto para o servidor
Data.hh
// interface ServiceA
class ServiceA {
public:
// Declarations for this interface type.
typedef ServiceA_ptr _ptr_type;
typedef ServiceA_var _var_type;
static _ptr_type _duplicate(_ptr_type);
static _ptr_type _narrow(::CORBA::Object_ptr);
static _ptr_type _unchecked_narrow(::CORBA::Object_ptr);
static _ptr_type _nil();
DataSK.cc
// This file is generated by omniidl (C++ backend)- omniORB_4_2. Do not edit.
#include "Data.hh"
#include <omniORB4/IOP_S.h>
#include <omniORB4/IOP_C.h>
#include <omniORB4/callDescriptor.h>
#include <omniORB4/callHandle.h>
#include <omniORB4/objTracker.h>
OMNI_USING_NAMESPACE(omni)
...
Criando o servidor
Server.cc
Código do servidor:
- Iniciar o ORB
- Obter a referência para o POA raiz para registra-se
- Vincular com o serviço de nomes
- Iniciar o servidor de objetos
// Server.cc
#include <assert.h>
#include <iostream>
#include <signal.h>
#include <stdlib.h>
#include <string>
#include <unistd.h>
#include "CServiceA_i.hh"
#include "Data.hh"
using namespace std;
int main( int argc, char **argv )
{
try {
// (1) Iniciar o ORB
CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
// (2) Obter a referência para o POA raiz para registra-se para ficar disponível para os clientes
CORBA::Object_var obj = orb->resolve_initial_references( "RootPOA" );
PortableServer::POA_var _poa = PortableServer::POA::_narrow( obj.in() );
// As operações definidas na interface são invocadas pelo objeto de referência.
// Um instância de CRequestSocketStream_i é iniciada
PortableServer::Servant_var<CServiceA_i> myRequestServiceA = new CServiceA_i();
// o servidor e objetos é ativado no RootPOA
PortableServer::ObjectId_var myRequestServiceA_oid = _poa->activate_object( myRequestServiceA );
// Obtêm o objeto de referência do servidor e registra no servidor de nome
CORBA::Object_var SA_obj = myRequestServiceA->_this();
// Obtêm uma referência para o objeto e imprime seu IOR como string
CORBA::String_var sior( orb->object_to_string( SA_obj.in() ) );
cerr << "'" << (char *)sior << "'" << endl;
Aqui você deve utilizar o mesmo nome do servidor de nomes definido no arquivo /etc/omniORB.cfg
.
// (3) Vincular com o serviço de nomes
// o serviço é definido pela diretiva InitRef e pelo identificador
// "OmniNameService" no arquivo omniORB.cfg
CORBA::Object_var obj1 = orb->resolve_initial_references( "OmniNameService" );
assert( !CORBA::is_nil( obj1.in() ) );
CosNaming::NamingContext_var nc = CosNaming::NamingContext::_narrow( obj1.in() );
assert( !CORBA::is_nil( nc.in() ) );
CosNaming::Name name;
name.length( 1 );
name[0].id = CORBA::string_dup( "DataServiceName1" );
nc->rebind( name, SA_obj.in() );
//========================================================================
myRequestServiceA->_remove_ref();
//
PortableServer::POAManager_var pmgr = _poa->the_POAManager();
pmgr->activate();
// (4) Iniciar o servidor de objetos para aceitar requisições dos clientes
orb->run();
//
// Se o ORB deixar o loop de tratamento de eventos
// Atualmente está configurado para nunca dar timeout
orb->destroy();
//
free( name[0].id ); // str_dup realiza um malloc internamente
}
Tratar as exceções:
catch( CORBA::TRANSIENT & ) {
cerr << "Caught system exception TRANSIENT -- unable to contact the server." << endl;
}
catch( CORBA::OBJECT_NOT_EXIST & ) {
cerr << "Caught system exception OBJECT_NOT_EXIST" << endl;
}
catch( CORBA::SystemException & ) {
cerr << "Caught CORBA::SystemException." << endl;
}
catch( CORBA::Exception & ) {
cerr << "Caught CORBA::Exception." << endl;
}
catch( omniORB::fatalException &fe ) {
cerr << "Caught omniORB::fatalException:" << endl;
cerr << " file: " << fe.file() << endl;
cerr << " line: " << fe.line() << endl;
cerr << " mesg: " << fe.errmsg() << endl;
}
catch( ... ) {
cerr << "Caught unknown exception." << endl;
}
return 0;
}
Implementação do Servant
São denotados pelo sufixo _i
.
CServiceA_i.hh
// CServiceA_i.hh
#include "Data.hh"
class CServiceA_i : public POA_Data::ServiceA, public PortableServer::RefCountServantBase {
public:
CServiceA_i();
virtual ~CServiceA_i();
virtual CORBA::Boolean CallServiceARoutineA(
/*in*/ CORBA::Long num1,
/*inout*/ CORBA::Long &num2,
/*out*/ CORBA::Long &retNum );
virtual CORBA::Boolean CallServiceARoutineB(
/*inout*/ CORBA::Long &num1,
/*inout*/ CORBA::Long &num2 );
};
CServiceA_i.cc
// CServiceA.cc
#include <fstream>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <sys/types.h>
#include <unistd.h>
#include <vector>
#include "CServiceA_i.hh"
using namespace Data;
#include <sys/wait.h>
CServiceA_i::CServiceA_i() { }
CServiceA_i::~CServiceA_i( void ) { }
CORBA::Boolean CallServiceARoutineA(
/*in*/ CORBA::Long num1,
/*inout*/ CORBA::Long &num2,
/*out*/ CORBA::Long &retNum )
{
num2 = num2 + num1;
retNum = 10;
return true;
}
CORBA::Boolean CallServiceARoutineB(
/*inout*/ CORBA::Long &num1,
/*inout*/ CORBA::Long &num2 )
{
num1++;
num2++;
return true;
}
Cliente CORBA
Client.cc
// Client.cc
#include "CRequestServiceA.hh"
int main( int argc, char **argv )
{
// O construtor estabelece o link como o servidor CORBA.
CRequestServiceA requestServiceA;
if( requestServiceA.RequestServiceARoutineA() ) {
cout << "ServiceA RoutineA: True" << endl;
}
if( requestServiceA.RequestServiceARoutineB() ) {
cout << "ServiceA RoutineB: True" << endl;
}
return 0;
}
CRrquestServiceA.hh
// CRrquestServiceA.hh
#include "Data.hh"
#include <cassert>
#include <fstream>
#include <iostream>
using namespace std;
class CRequestServiceA {
public:
CRequestServiceA();
~CRequestServiceA();
bool RequestServiceARoutineA();
bool RequestServiceARoutineB();
CosNaming::Name m_corbaCosName;
// CORBA ORB
CORBA::ORB_var m_orb;
CORBA::Object_var m_obj; // ORB Object
CORBA::Object_var m_obj1; // Resolved id to object reference
// Resolved and narrowed CORBA object for proxy calls
Data::ServiceA_var m_Data;
};
class DS_ServerConnectionException {
public:
DS_ServerConnectionException()
{
cerr << "CORBA COMM_FAILURE" << endl;
};
};
class DS_SystemException {
public:
DS_SystemException()
{
cerr << "CORBA Exception" << endl;
};
};
class DS_FatalException {
public:
DS_FatalException()
{
cerr << "CORBA Fatal Exception" << endl;
};
};
class DS_Exception {
public:
DS_Exception()
{
cerr << "Exception" << endl;
};
};
CRequestServiceA.cc
// CRequestServiceA.cc
#include "CRequestServiceA.hh"
using namespace Data;
CRequestServiceA::CRequestServiceA()
{
try {
// Inicia o objeto ORB
int argc = 0; // Variáveis dummy.
char ** argv = 0;
CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
// Vincula o objeto ORB ao servidor de nome
// Deve ser o mesmo nome definido em /etc/omniORB.cfg
CORBA::Object_var obj = orb->resolve_initial_references( "OmniNameService" );
assert( !CORBA::is_nil( obj.in() ) );
CosNaming::NamingContext_var nc = CosNaming::NamingContext::_narrow( obj.in() );
assert( !CORBA::is_nil( nc.in() ) );
CosNaming::Name _corbaCosName;
_corbaCosName.length( 1 );
_corbaCosName[0].id = CORBA::string_dup( "DataServiceName1" );
CORBA::Object_var obj1 = nc->resolve( _corbaCosName );
assert( !CORBA::is_nil( obj1.in() ) );
m_Data = ServiceA::_narrow( obj1.in() );
if( CORBA::is_nil( m_Data.in() ) ) {
cerr << "IOR is not an SA object reference." << endl;
}
}
catch( CORBA::COMM_FAILURE &ex ) {
cerr << "Caught system exception COMM_FAILURE -- unable to contact the "
<< "object." << endl;
throw DS_ServerConnectionException();
return;
}
catch( CORBA::SystemException & ) {
cerr << "Caught a CORBA::SystemException." << endl;
throw DS_SystemException();
return;
}
catch( CORBA::Exception & ) {
cerr << "Caught CORBA::Exception." << endl;
throw DS_Exception();
return;
}
catch( omniORB::fatalException &fe ) {
cerr << "Caught omniORB::fatalException:" << endl;
cerr << " file: " << fe.file() << endl;
cerr << " line: " << fe.line() << endl;
cerr << " mesg: " << fe.errmsg() << endl;
throw DS_FatalException();
return;
}
catch( ... ) {
cerr << "Caught unknown exception." << endl;
throw DS_Exception();
return;
}
return;
}
CRequestServiceA::~CRequestServiceA()
{
// ...
}
bool CRequestServiceA::RequestServiceARoutineA()
{
CORBA::Long num1 = 4;
CORBA::Long num2 = 5;
CORBA::Long retNum;
cout << "Valores de entrada para a rotina A do serviço A: " << num1 << " " << num2 << " " << retNum << endl;
// Esta chamada CORBA será executada remotamente
if( m_Data->CallServiceRoutineA( num1, num2, retNum ) ) {
cout << "Valores retornados pelo serviço A: " << num1 << " " << num2 << " " << retNum << endl;
return true;
}
return false;
}
bool CRequestServiceA::RequestServiceARoutineB()
{
CORBA::Long num1 = 0;
CORBA::Long num2 = 50;
cout << "Valores de entrada para a rotina B do serviço A: " << num1 << " " << num2 << endl;
// Esta chamada CORBA será executada remotamente
if( m_Data->CallServiceRoutineB( num1, num2 ) ) {
cout << "Valores retornados pelo serviço B: " << num1 << " " << num2 << endl;
return true;
}
return false;
}
Makefile
# Makefile
LDFLAGS+=-lomniORB4 -lomnithread -lomniDynamic4
CXXFLAGS+=-Wall
all: server client
server: DataSK.o CServiceA_i.o Server.o
$(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)
client: DataSK.o Client.o CRequestServiceA.o
$(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)
clean:
rm -f *.o
rm -f server
rm -f client
This is the value of CORBA. This is why we use CORBA. Look at how simple the program looks. The constructor establishes the link with the CORBA server. The subsequent calls to Routine A and B are processed remotely on the CORBA server but called like any other local function call.
Todo
- https://www.grisby.org/presentations/py10tut.pdf
- https://www.grisby.org/presentations/CORBAControls2002.pdf
- https://xennis.org/wiki/CORBA <- tutorial que parece muito interessante
- http://www.mario-konrad.ch/blog/programming/connect_orbs.html
- https://docs.oracle.com/cd/E13203_01/tuxedo/tux100/pdf/naming.pdf
Referências
- Introduction to Distributed Computing using CORBA
- CORBA, C++ and Linux
- O Adaptador de Objetos e Interoperabilidade CORBA
- CORBA Tutorial: Connecting 3 ORBs
- CORBA? Isn’ t that Obsolete ?
- (local) [The omniORB IDL Compiler](file:///usr/share/doc/omniorb-doc/omniidl.html)
- (local) [The omniNames CORBA Naming Service](file:///usr/share/doc/omniorb-doc/omniNames.html)
- (local) [The OMNI Thread Abstraction](file:///usr/share/doc/omniorb-doc/omnithread.html)
- (local) [The omniORB utilities](file:///usr/share/doc/omniorb-doc/utilities.html)
- (local) [The omniORB version 4.2 Users’ Guide](file:///usr/share/doc/omniorb-doc/omniORB/index.html)
- Mapping of OMG IDL Statements to C++
- Raising Exceptions in IDL Operations
- O Portable Object Adapter
- CORBA System and User Defined Exceptions