CORBA

Common Object Request Broker Architecture

Corba por Luiz Schelesky e Dyonatam Terluk

Atualizado em 10/07/2023

Introdução ao CORBA

CORBA é uma sigla que quer dizer Common Object Request Broker Architecture. É uma solução aberta para o desenvolvimento de aplicações em ambientes heterogêneos. Esse conceito foi uma solução aberta criada pela OMG (Object Management Group) que define um framework para o desenvolvimento de sistemas de software distribuídos baseados na tecnologia de objetos. Esse tipo de arquitetura foi desenvolvida para que qualquer tipo de dispositivo, linguagem ou sistema possam se comunicar, assim eles colaboram para que o sistema funcione de forma transparente, permitindo a integração dos sistemas com base em objetos.


Quem é a OMG(Object Management Group)

O Object Management Group (OMG) é uma organização sem fins lucrativos que se dedica à padronização de tecnologias de software baseadas em objetos. Fundada em 1989, sua missão é facilitar a interoperabilidade e a portabilidade de sistemas distribuídos, através do desenvolvimento de especificações e padrões para diversas áreas e setores da indústria. O OMG reúne uma variedade de membros, incluindo empresas, instituições acadêmicas, governos e profissionais individuais. Esses membros trabalham em conjunto para definir e aprimorar os padrões que são adotados pela indústria de software. Um dos padrões mais conhecidos desenvolvidos pelo OMG é a Linguagem de Modelagem Unificada (UML), que é amplamente utilizada para visualizar, especificar e construir sistemas de software. Além da UML, o OMG também criou outros padrões importantes, como o Modelo de Componente do Object Request Broker (CORBA), que possibilita a comunicação entre objetos distribuídos em diferentes plataformas e linguagens de programação. A organização também está envolvida em áreas como Computação em Nuvem, Internet das Coisas (IoT), Modelagem de Processos de Negócio (BPM) e Arquitetura Orientada a Serviços (SOA). Os padrões estabelecidos pelo OMG desempenham um papel fundamental na indústria de software, influenciando o desenvolvimento de sistemas distribuídos e garantindo a interoperabilidade entre diferentes aplicações e sistemas. Através de suas especificações, o OMG promove a colaboração e a inovação na área de tecnologia da informação, permitindo que os sistemas trabalhem juntos de forma eficiente e harmoniosa.


Object Request Broker(ORB)

O primeiro conceito que iremos abordar é o Object Request Broker(ORB) que por definição é um elemento estrutural dessa arquitetura. Ele atua como elemento intermediário entre o Servidor CORBA e o Cliente CORBA dentro da troca de mensagens. Cabe destacar que o ORB esconde do programador a complexidade inerentes das primitivas de comunicação em redes. Nessa situação, um cliente é uma entidade que deseja executar uma operação, cujo código e dados implementam a funcionalidade desejada. Mais especificamente, uma invocação de objeto remoto envolve a especificação do objeto destino, da operação a ser invocada e dos parâmetros que serão enviados (in) - input - e retornados (out) - output - desse. O ORB é responsável por todos os mecanismos necessários para a localização da implementação do objeto invocado, garantindo que a implementação do objeto possa receber a requisição e transferir os dados que foram gerados por essa de volta ao cliente. Cabe destacar que o cliente pode efetuar uma requisição tanto por meio do uso da interface de invocação dinâmica quanto por meio de um stub gerado em IDL (Interface Definition Language). Dessa maneira, uma implementação de objeto recebe uma requisição seja via um skeleton gerado em IDL ou através de um skeleton dinâmico. Um cliente CORBA processa requisições por meio de uma referência para o objeto remoto, de modo que este inicia uma requisição via chamadas a rotinas do stub local ou inicia uma requisição pela construção dinâmica da chamada de método. A partir desse passo, o ORB localiza a operação do objeto referenciado, transmite os parâmetros e transfere o controle para a implementação desse objeto por meio do skeleton baseado em IDL ou por meio da chamada remota de método que foi construída de forma dinâmica. Quando a requisição está completa, tanto o controle quanto o resultado obtido é retornado para o cliente. Cabe acrescentar que invocações remotas via stub (interface de invocação estática) são geralmente síncronas (a não ser que uma operação seja declarada oneway na IDL que a descreve) enquanto que invocações remotas via interface dinâmica podem ser tanto síncronas quanto assíncronas. O ORB permite a criação de objetos cujas operações possam ser invocadas por programas clientes localizados em qualquer lugar. Além disso, a interoperabilidade entre ORBs localizados remotamente é garantido pelo uso do protocolo Internet Inter-Orb (IIOP), baseado no TCP/IP (mais especificamente, no TCP). Resumidamente o ORB é um módulo intermediário entre cliente e objeto, sendo responsável em aceitar a requisição do cliente, enviá-la para o objeto competente e, assim que disponível a resposta, entregar ao cliente. E o IDL é uma linguagem de programação de programação que é baseada em C++, não possui variáveis e nem algoritmos, fica subentendido que é uma linguagem auto declarativa, e portanto, é independente da linguagem de programação utilizada para acessá-la. A criadora do CORBA definiu padrões para as seguintes linguagens de programação: Ada, C, C++, C#, COBOL, IDL script, Lisp, Java, Python, Smalltalk e TTCN. E é dessa forma que possibilita a interoperabilidade entre os diversos sistemas, visto a separação que é definida entre interface e execução.

Object Management Architecture(OMA)

figura 1

Cliente CORBA: Tem a função de requisitar serviços aos objetos localizados no servidor. É importante ressaltar que o cliente e o servidor podem estar executando sobre ambientes computacionais heterogêneos;

Stub: É a interface de invocação estática gerada a partir da compilação de uma IDL. Esta interface é utilizada pelas aplicações clientes para a realização de chamadas a objetos servidores remotos;

DII: A interface de invocação dinâmica permite que o cliente chame um método no servidor sem que tenha conhecimento de sua interface em tempo de compilação;

Repositório de Interfaces: Banco de dados onde residem todas as interfaces dos serviços conhecidos pelo ORB. Este repositório é utilizado por clientes que usam a DII para chamar os métodos de objetos cujas interfaces são desconhecidas em tempo de compilação;

Servidor CORBA: Tem por finalidade receber solicitações das aplicações clientes, processá-las e enviar uma mensagem contendo a resposta requisitada;

Skeletons: É a interface estática do servidor. Esta interface recebe requisições do cliente e encaminha ao objeto servidor;

DSI: É a interface de skeletons dinâmica. É uma forma de entregar chamadas de métodos a uma implementação de objetos cujas interfaces não são conhecidas em tempo de execução.

Repositório de Implementação: O repositório de implementações contém os dados necessários para que a ORB possa localizar e ativar implementações dos objetos;

Adaptador de Objetos: É um componente da arquitetura CORBA que existe apenas no lado do servidor. É responsável pela criação de referências para objetos CORBA, pela ativação dos objetos e pelo direcionamento das requisições;

Núcleo ORB: Tem a função de intermediar a comunicação entre o cliente e o servidor.



Implementação

Parte 1

Nós temos a interface, temos que transformar em alguma coisa que a linguagem de programação Java entenda, quem vai executar isso para gente é o idlj.exe que fica dentro do jdk. OBS: Se você estiver usando a versão Java SE 20 não vai rodar já que o suporte para as idls foi retirado na versão 11 do Java, assim que você fizer arrumar essa parte pode proseguir, caso contrário a prompt não irá reconhecer esse comando. Use esse comando na prompt idlj -fall Calculadora.idl -f all gerará todos os arquivos do lado do cliente e do lado servidor, e será gerada uma pasta contendo um conjunto de classes criadas automaticamente. Que são CalculadoraHelper, CalculadoraHolder,CalculadoraPOA, CalculadoraOperations, CalculadoraStub.

O código da primeira parte está em IDL e descreve as definições de uma interface(IDL) que está dentro do módulo “CalculadoraApp”. Está interface por sua vez está definindo um conjunto de operações, como estamos falando de uma calculadora, ela tem 4 operações matemáticas: adição, subtração, multiplicação e divisão. Cada método da interface tem uma assinatura, que inclui o tipo de retorno e os parâmetros necessários. Os métodos definidos na interface são os seguintes: long adicao(in long x, in long y);: Este método realiza uma operação de adição entre dois números inteiros. Ele recebe dois parâmetros, "x" e "y", ambos do tipo long, e retorna um resultado do mesmo tipo. long subtracao(in long x, in long y);

Este método realiza uma operação de subtração entre dois números inteiros. Ele também recebe dois parâmetros do tipo long e retorna um resultado do mesmo tipo. long multiplicacao(in long x, in long y);

Este método também realiza uma operação de multiplicação entre dois números inteiros. Assim como os métodos anteriores, ele recebe dois parâmetros do tipo long e retorna um resultado do mesmo tipo. double divisao(in long x, in long y);: Este método realiza uma operação de divisão entre dois números inteiros, mas retorna um resultado do tipo double, que é um tipo de ponto flutuante para representar números decimais. Assim como os outros métodos, ele recebe dois parâmetros do tipo long. Essa definição de interface em IDL serve como um contrato que pode ser usado para gerar o código-fonte de uma implementação concreta da interface em uma linguagem de programação específica como Java que estamos usando agora.

Figura 2


Parte 2

Este código chamado CalculadoraOperations é uma interface em Java gerada a partir do nosso arquivo IDL e descreve a interface "CalculadoraOperations". Essa interface é compartilhada entre os stubs (clientes) e os skeletons (servidores). Stubs são objetos que atuam como proxies para invocar os métodos remotos em um objeto remoto, enquanto os skeletons são objetos responsáveis por receber as chamadas remotas e encaminhá-las para a implementação real dos métodos.

Nessa interface, são declarados os mesmos métodos que foram definidos na IDL: adição, subtração, multiplicação e divisão. Cada método recebe dois parâmetros do tipo int e retorna um valor correspondente ao tipo de retorno especificado. O objetivo dessa interface é fornecer um contrato para a comunicação entre o cliente e o servidor. O cliente pode utilizar essa interface para chamar os métodos remotos fornecidos pelo servidor, que por sua vez implementa esses métodos para realizar as operações matemáticas desejadas. Essa implementação em Java é gerada automaticamente a partir da IDL utilizando um compilador IDL-to-Java.

Ela serve como uma base para desenvolver o código real do cliente e do servidor, onde os métodos serão implementados com a lógica específica das operações matemáticas definidas na interface.




Parte 3

Essa classe estende a classe org.omg.PortableServer.Servant e implementa duas interfaces: CalculadoraApp.CalculadoraOperations e org.omg.CORBA.portable.InvokeHandler. Essas interfaces fornecem os métodos necessários para a implementação da interface definida na IDL. A classe CalculadoraPOA define um método chamado _invoke que é responsável por lidar com as chamadas remotas feitas pelos clientes. Esse método recebe o nome do método chamado, um objeto InputStream para ler os parâmetros da chamada e um objeto ResponseHandler para retornar a resposta ao cliente.

Dentro do método _invoke, é verificado qual método foi chamado através do parâmetro $method, e a execução é direcionada para o método correspondente na implementação real da interface CalculadoraOperations. Cada método é implementado individualmente, lendo os parâmetros do objeto InputStream, invocando o método correspondente na classe CalculadoraPOA e retornando o resultado ao cliente usando o objeto OutputStream. Além disso, a classe possui métodos para manipulação de objetos CORBA, como _this() e _all_interfaces(), que são utilizados para obter referências ao objeto de calculadora em um ambiente CORBA. Essa implementação da classe CalculadoraPOA é uma base que pode ser estendida e personalizada para fornecer a lógica real dos métodos da interface definida na IDL.




Parte 4

O código apresentado acima é uma parte do código gerado a partir da IDL. A interface Calculadora estende a interface CalculadoraOperations, que contém a definição dos métodos especificados na IDL. Além disso, a interface Calculadora também estende outras interfaces padrões do CORBA, que são org.omg.CORBA.Object e org.omg.CORBA.portable.IDLEntity.

A interface org.omg.CORBA.Object fornece funcionalidades básicas para objetos CORBA, como métodos para obtenção de referência ao objeto e para lidar com operações relacionadas ao ciclo de vida do objeto. A interface org.omg.CORBA.portable.IDLEntity é uma marcação que indica que a interface é uma entidade IDL. Essa marcação é necessária para fins de serialização e deserialização de objetos CORBA. Portanto, a interface Calculadora representa a versão Java da interface definida na IDL.

Ela herda as funcionalidades padrões dos objetos CORBA, além de fornecer os métodos especificados na IDL através da extensão da interface CalculadoraOperations. Essa interface pode ser utilizada como base para a implementação concreta da calculadora em Java, onde os métodos serão implementados com a lógica específica das operações matemáticas.




Parte 5

Este código também é gerado a partir da interface definida na linguagem IDL no arquivo "Calculadora.idl". Nesse caso, é a implementação da classe _CalculadoraStub em Java. Essa classe é uma implementação do stub, que é uma representação do cliente para invocar métodos em um objeto remoto. A classe _CalculadoraStub estende a classe org.omg.CORBA.portable.ObjectImpl e implementa a interface Calculadora definida na IDL.

Cada método definido na interface Calculadora é implementado no _CalculadoraStub para lidar com a chamada remota. Cada método do stub segue uma estrutura semelhante, onde é feita a preparação dos parâmetros, a invocação do método remoto, a leitura da resposta e o retorno do resultado ao cliente. Dentro de cada método, é criado um objeto OutputStream para preparar a chamada remota. Os parâmetros do método são escritos no objeto OutputStream, que é então passado para o método _invoke para ser enviado ao objeto remoto. Em seguida, é feita a leitura do objeto InputStream que contém a resposta do método remoto. O resultado é extraído do InputStream e retornado ao cliente.

A classe também possui métodos para manipulação de objetos CORBA, como _ids(), readObject() e writeObject(), que são utilizados para obter informações sobre a identificação da interface e para a serialização e desserialização do objeto CORBA. Essa implementação do stub _CalculadoraStub é uma base que pode ser estendida e personalizada para fornecer a lógica real dos métodos de chamada remota. É utilizada pelo cliente para se comunicar com o servidor e realizar as operações matemáticas definidas na interface Calculadora.




Parte 6

A classe CalculadoraHelper fornece métodos utilitários para manipular objetos da interface Calculadora definida na IDL. O método insert recebe um objeto Any do CORBA é uma instância da interface Calculadora, e insere o valor da instância no objeto Any. Primeiro, é criado um objeto OutputStream a partir do Any, em seguida é definido o tipo do Any para corresponder à interface Calculadora e o valor é escrito no OutputStream. Por fim, o valor é lido do OutputStream e inserido no Any.

O método extract recebe um objeto Any do CORBA e extrai o valor da instância da interface Calculadora contido no Any. É criado um objeto InputStream a partir do Any e o valor é lido do InputStream e retornado. O método type retorna o tipo do objeto Calculadora como um TypeCode, que é uma estrutura que define a estrutura do tipo no CORBA. Esse método utiliza o ORB (Object Request Broker) para obter o TypeCode correspondente à interface Calculadora. O método id retorna a identificação da interface Calculadora.

Os métodos read, write, narrow e unchecked_narrow são responsáveis por ler, escrever e converter objetos CORBA para instâncias da interface Calculadora. Esses métodos utilizam as classes _CalculadoraStub e org.omg.CORBA.portable.ObjectImpl para realizar a leitura, escrita e conversão dos objetos. Essa classe CalculadoraHelper é utilizada para facilitar a manipulação de objetos da interface Calculadora no contexto do CORBA.




Parte 7

A classe CalculadoraHolder é usada para armazenar uma referência a um objeto da interface Calculadora. Ela implementa a interface Streamable do CORBA, que permite que o objeto seja transmitido através de streams de entrada e saída.

A classe possui um atributo value do tipo CalculadoraApp.Calculadora, que é a referência ao objeto da interface Calculadora. Esse atributo é inicializado como null no construtor padrão. O construtor com parâmetro permite que um objeto Calculadora seja passado para a classe CalculadoraHolder durante a sua criação. Dessa forma, o atributo value é inicializado com o valor passado no parâmetro initialValue.

O método _read é responsável por ler os dados do objeto InputStream do CORBA e atribuir o valor lido ao atributo value da classe CalculadoraHolder. Esse método utiliza o método CalculadoraApp.CalculadoraHelper.read para realizar a leitura do valor do InputStream. O método _write é responsável por escrever os dados do atributo value no objeto OutputStream do CORBA. Ele utiliza o método CalculadoraApp.CalculadoraHelper.write para escrever o valor do atributo value no OutputStream. O método _type retorna o TypeCode correspondente ao tipo da interface Calculadora utilizando o método CalculadoraApp.CalculadoraHelper.type.

Essa classe CalculadoraHolder é utilizada para facilitar a manipulação de objetos da interface Calculadora no contexto do CORBA e permitir que eles sejam transmitidos através de streams de entrada e saída.




Parte 8

O código apresentado é um exemplo de implementação de um servidor CORBA (Common Object Request Broker Architecture) que oferece um serviço de calculadora remota. Vamos analisar as principais partes do código: Classe CalculadoraImpl: Essa classe implementa a interface CalculadoraPOA que foi gerada a partir do arquivo IDL. Ela possui os métodos de operações da calculadora, como adicao, subtracao, multiplicacao e divisao. A classe tem uma referência ao objeto ORB (Object Request Broker) para permitir a comunicação com o cliente. Classe ServidorCORBA: Essa classe contém o método main, que é o ponto de entrada para o servidor CORBA. O código dentro do bloco try inicializa o ORB e obtém uma referência ao POA (Portable Object Adapter) para ativar o gerenciador POA.

Em seguida, cria uma instância da classe CalculadoraImpl e configura o ORB para essa instância através do método setORB. A instância do CalculadoraImpl é convertida em uma referência de objeto do CORBA através do POA. O serviço é registrado no ORB e uma referência é obtida para esse serviço, que será usada para vinculá-la a um nome no serviço de nomes. A referência para o serviço de nomes é obtida usando orb.resolve_initial_references("NameService"). Em seguida, a referência do objeto é vinculada a um nome específico (Calc) usando o serviço de nomes.

O servidor fica aguardando invocações de clientes usando orb.run(). Em caso de exceção, o bloco catch exibe uma mensagem de erro. No geral, o código configura um servidor CORBA para fornecer um serviço de calculadora remota. O servidor inicia o ORB, registra o serviço no ORB e no serviço de nomes e fica aguardando invocações de clientes. O serviço de calculadora pode ser acessado por clientes CORBA para realizar operações matemáticas remotamente.




Parte 9

O código apresentado é um exemplo de implementação de um cliente CORBA que se conecta a um servidor CORBA para acessar o serviço de calculadora remota. Vamos analisar as principais partes do código: Classe ClienteCORBA: Essa classe contém o método main, que é o ponto de entrada para o cliente CORBA. O código dentro do bloco try inicializa o ORB e obtém uma referência para o serviço de nomes usando orb.resolve_initial_references("NameService").

Em seguida, a referência do serviço de nomes é estreitada para o tipo NamingContextExt usando NamingContextExtHelper.narrow(objRef). O próximo passo é obter uma referência para o objeto do servidor utilizando o serviço de nomes. Isso é feito fornecendo o nome do objeto ("Calc") para o método ncRef.resolve_str(), que retorna a referência do objeto. A referência do objeto é estreitada para o tipo Calculadora usando CalculadoraHelper.narrow(). Em seguida, os métodos da calculadora remota podem ser chamados normalmente. No exemplo, é chamado o método adicao(1, 2) para realizar uma adição. Em caso de exceção, o bloco catch exibe uma mensagem de erro.

No geral, o código configura um cliente CORBA que se conecta a um servidor CORBA para acessar um serviço de calculadora remota. O cliente inicia o ORB, obtém a referência para o serviço de nomes, obtém a referência do objeto do servidor usando o serviço de nomes e, em seguida, pode chamar os métodos da calculadora remota normalmente.




Execução

1. Compilando os arquivos do servidor:
No diretório em que os arquivos do servidor estão localizados, execute o comando javac *.java CalculadoraApp/*.java. Esse comando irá compilar todos os arquivos .java necessários para o servidor CORBA, incluindo a interface gerada a partir do arquivo IDL. Certifique-se de ter o JDK instalado corretamente em seu sistema e que o comando javac esteja configurado corretamente no seu PATH.

2. Executando o serviço de nomes:
O comando orbd -ORBInitialPort 1050 é usado para executar o daemon do serviço de nomes CORBA. O serviço de nomes é necessário para registrar e localizar os objetos CORBA. Certifique-se de ter o Java Development Kit (JDK) instalado corretamente em seu sistema e que o comando orbd esteja configurado corretamente no seu PATH. O parâmetro -ORBInitialPort 1050 define a porta inicial do ORB (Object Request Broker) como 1050. Isso indica que o ORB será iniciado na porta 1050.

3. Executando o servidor:
O comando java ServidorCORBA -ORBInitialPort 1050 -ORBInitialHost localhost é usado para executar o servidor CORBA. Certifique-se de ter compilado corretamente os arquivos do servidor antes de executá-lo. O parâmetro -ORBInitialPort 1050 define a porta inicial do ORB como 1050, para que o servidor possa se comunicar com o serviço de nomes. O parâmetro -ORBInitialHost localhost especifica o endereço IP ou nome do host onde o serviço de nomes está sendo executado. Nesse caso, está sendo utilizado o localhost.

4. Compilando os arquivos do cliente:
No diretório em que os arquivos do cliente estão localizados, execute o comando javac *.java. Isso irá compilar todos os arquivos .java necessários para o cliente CORBA. Certifique-se de ter o JDK instalado corretamente em seu sistema e que o comando javac esteja configurado corretamente no seu PATH.

5. Executando o cliente:
O comando java ClienteCORBA -ORBInitialPort 1050 -ORBInitialHost localhost é usado para executar o cliente CORBA. Certifique-se de ter compilado corretamente os arquivos do cliente antes de executá-lo. O parâmetro -ORBInitialPort 1050 define a porta inicial do ORB como 1050, para que o cliente possa se comunicar com o serviço de nomes. O parâmetro -ORBInitialHost localhost especifica o endereço IP ou nome do host onde o serviço de nomes está sendo executado. Nesse caso, está sendo utilizado o localhost. Certifique-se de que todas as dependências necessárias, como as bibliotecas CORBA, estejam configuradas corretamente no classpath durante a compilação e execução do servidor e do cliente CORBA.

Essas etapas permitem que você compile e execute o servidor e o cliente CORBA para a calculadora. O servidor irá registrar a calculadora no serviço de nomes e o cliente irá se conectar ao serviço de nomes para localizar e usar a calculadora remota.

Se estiver com dificuldade para executar os códigos você pode ler o terceiro link das referências para te ajudar!



Este Site foi Escrito por:

Luiz Gustavo de Souza Schelesky e Dyonatam Terluk

Com intuito de apresentar um conteúdo

de aluno para aluno, ajudando-os

a compreender o conceito de CORBA,

está página, que foi desenvolvida para disciplina de Sistemas

Operacionais(UEPG).

Professor: Dierone Foltran

Refências:







Menu Principal