SDK Openbus Tecgraf PUC-Rio Setembro de 2013 OpenBus • O OpenBus oferece: • Barramento de Integração • Controle de Acesso (autenticação e identificação) • Serviços de Apoio à Integração • SDK • • • • Biblioteca de Acesso Demos Documentação Utilitários Visão de uma Integração Visão de uma Integração Visão de uma Integração Visão de uma Integração Visão de uma Integração Visão da Arquitetura Controle de Acesso • Ponto de entrada no barramento • sua localização (referência) é conhecida por todos • Autentica os componentes que querem fazer parte do barramento • Emite uma credencial • possui uma validade • suporte a autorização LDAP Controle de Acesso Autenticação com usuário / senha credencial Cliente Controle de Acesso - Autenticação • A autenticação no barramento pode ser feita por: • usuário e senha • certificado digital • compartilhamento de autenticação Autenticação por usuário e senha • Requer a configuração de um servidor LDAP. • Normalmente, aplicações cliente (standalone) se autenticam no barramento usando usuário e senha Autenticação por certificado • Baseia-se em um par de chaves: pública e privada • Um certificado digital normalmente é usado para ligar uma entidade a uma chave pública • Assinado digitalmente • Emitido e assinado por uma Autoridade Certificadora • O padrão mais adotado é o X.509 • A validação de certificados digitais é feita usando um modelo desafio-resposta Autenticação por certificado • O Openbus possui instalado os certificados públicos de todas as entidades que precisam se conectar a ele • Apenas a entidade que se conecta ao barramento guarda a chave-privada que é par da chave pública do certificado • Para a autenticação, um desafio é gerado pelo barramento utilizando a chave pública da entidade • A entidade decifra o desafio utilizando a sua chave privada • A chave pública do barramento é usada para gerar a resposta a partir do desafio fornecido Controle de Acesso - Credenciais • Autenticação e Identificação • Login • Identificador único • Nome da entidade proprietária • Cadeia de chamadas • Barramento responsável • Lease • Indica por quanto tempo uma credencial é válida • Deve ser renovado de tempos em tempos • Cadeia de chamadas Controle de Acesso – Cadeia de chamadas • Uma ou mais chamadas aninhadas feitas através do barramento que originaram uma chamada recebida • Contém as informações de login dos processos que originaram cada uma das chamadas aninhadas Registro de Ofertas • Permite a oferta e a descoberta de serviços • Observação de ofertas e registros de ofertas • Sua referência é obtida através do barramento • O mecanismo de govenança é usado para garantir que apenas entidades autorizadas possam publicar serviços no barramento Registro de Ofertas • Descrição de oferta de serviço • Referência para a faceta IComponent do serviço • Lista de propriedades descritivas • Especificadas no ato do registro • Automáticas • Referência para a oferta de serviço propriamente dita • Objeto CORBA que permite a alteração da oferta pela entidade que a registrou ou usuários administradores Registro de Ofertas • Propriedades automáticas • Descritas na IDL do registro de ofertas /** * openbus.offer.id: Ident. único da oferta. * openbus.offer.login: Ident. do login com que a oferta foi registrada. * openbus.offer.entity: Ident. da entidade que registrou a oferta. * openbus.offer.timestamp: Número indicando o momento do registro da oferta. * openbus.offer.year: Ano em que a oferta foi registrada. * openbus.offer.month: Número do mês em que a oferta foi registrada. * openbus.offer.day: Dia do mês que a oferta foi registrada. * openbus.offer.hour: Hora do dia em que a oferta foi registrada. * openbus.offer.minute: Minuto do dia em que a oferta foi registrada. * openbus.offer.second: Segundo do dia em que a oferta foi registrada. * openbus.component.name: Nome do componente SCS que implementa o serviço. * openbus.component.version.major: Versão maior do componente SCS que implementa o serviço. * openbus.component.version.minor: Versão menor do componente SCS que implementa o serviço. * openbus.component.version.patch: Versão de correção do componente SCS que implementa o serviço. * openbus.component.facet: Nome de faceta oferecida pelo component SCS que implementa o serviço. * openbus.component.interface: RepID de interface implementada por faceta do component SCS que implementa o serviço. */ Registro de Ofertas Registro de Ofertas Serviços Adicionais • Atuais • Serviço de Colaboração • Serviço de Dados • Não são parte do núcleo do barramento • Ou seja, não é obrigatória a presença desses serviços em uma instância de barramento • Acrescentam funcionalidades para auxiliar a integração entre serviços e aplicações Serviço de Colaboração • Permite criar e compartilhar uma sessão de colaboração entre serviços • Fornece mecanismo de notificação para adição e exclusão de membros • Oferece um canal de comunicação para o envio de eventos SDK Openbus • Implementa o protocolo de acesso • Exporta interfaces de programação • API • Assistente • Possui: • classes de apoio usadas no cliente e no servidor • classes geradas a partir das idls do barramento • tanto para a versão corrente como para a versão anterior do barramento, para que seja possível a integração com clientes legados API • Os principais conceitos são representados da seguinte forma: • • • • ORBInitializer Connection CallerChain OpenBusContext API - ORBInitializer • Inicializador de ORBs para acesso a barramentos OpenBus • Inicializa ORB de uso exclusivo para chamadas através do barramento • Chamadas fora do barramento devem ser feitas em outro ORB • Abstrai a operação CORBA::ORB_init • Cada ORB inicializado através dessa classe possui um OpenBusContext associado API - ORBInitializer • Exemplo: // inicialização e configuração do ORB ORB orb = ORBInitializer.initORB(); // obtenção do gerente de contexto de chamadas associado a esse // ORB OpenBusContext context = (OpenBusContext) orb.resolve_initial_references(“OpenBusContext”); API - Connection • Representa um ponto de acesso ao barramento, que é usado tanto para realizar como para receber chamadas através do barramento API - Connection • Exemplo: // criação de conexão (não realiza nenhuma chamada remota) Connection connection = context.createConnection(host,port); API - Connection • Utilizada para realizar acessos identificados ao barramento • Definimos acesso identificado como Login • Atualmente três formas de autenticação são possíveis: • Por senha: loginByPassword • Por certificado digital: loginByCertificate • Por autenticação compartilhada: loginBySharedAuth API - Connection • Exemplo: // autenticação try { // por login e senha connection.loginByPassword(entity, password.getBytes()); // por certificado connection.loginByCertificate(entity, privateKey); // logout connection.logout(); } catch(…) { … } API - Connection • O resultado da autenticação é um login com tempo de validade (Lease) • Cada conexão possui uma thread de renovação automática da validade do login • Caso o login seja invalidado, é necessário reconectar e, no caso de serviços, reofertar suas ofertas no barramento • Para isso, deve-se fornecer uma callback API - Connection • Exemplo: // callback de renovação de login e ofertas Connection.onInvalidLoginCallback( new InvalidLoginCallback() { public void invalidLogin(Connection conn, LoginInfo login){ //1. autenticar no barramento //2. republicar ofertas se necessário //é necessário o tratamento de concorrência } } ); API - Connection • Multiplexação • Possibilidade de assumir múltiplas identidades através de múltiplas conexões • Utiliza-se o OpenBusContext para criar e definir as conexões que serão utilizadas pelo ORB API - CallerChain • Representa a identificação de todos os acessos ao barramento que originaram uma chamada recebida • Úteis para aplicações implementarem regras próprias de permissionamento • São obtidas através do OpenBusContext API - CallerChain • Exemplo: // obtenção da cadeia da requisição public void myServantMethod() { CallerChain callerChain = context.getCallerChain(); LoginInfo caller = callerChain.caller(); System.out.println(caller + “ called me.”); // unindo-se a uma cadeia de chamadas context.joinChain(chain); someService.someMethod(); context.exitChain(); } API - OpenBusContext • Permite controlar o contexto de chamadas de um ORB para acessar informações que as identificam • O contexto representa a linha de execução atual do programa em relação a um ORB, o que pode ser a thread em execução ou mais comumente o CORBA::PICurrent do padrão CORBA API - OpenBusContext • Que informações identificam as chamadas? • Conexão • Cadeia de chamadas • O contexto: • Cria conexões • Manipula informações de contexto • Qual conexão realiza a chamada • Qual cadeia está associada à chamada • Qual conexão recebe (atende) uma chamada API - OpenBusContext • Exemplo: // configuração da conexão padrão context.setDefaultConnection(connection); // recuperação da conexão padrão Connection conn = context.getDefaultConnection(); API - OpenBusContext • O contexto também fornece a referência para serviços-núcleo: • Registro de ofertas OfferRegistry offerRegistry = context.getOfferRegistry(); API - Publicação de Ofertas try { // registro de um serviço no barramento ServiceProperty[] properties = new ServiceProperty[] { new ServiceProperty(“my property”, “my property value”)}; context.getOfferRegistry().registerService(iComponent, properties); } catch (…) { … } API - Busca e Utilização de Ofertas ServiceOfferDesc[] offers; try { // busca por serviço ServiceProperty[] properties = new ServiceProperty[1]; properties[0] = new ServiceProperty(“my property”, “my property value”)}; offers = context.getOfferRegistry().findServices(properties); } catch (…) { … } API - Busca e Utilização de Ofertas // análise das ofertas encontradas for(ServiceOfferDesc offerDesc : offers) { try { org.omg.CORBA.Object serviceObj = offerDesc.service_ref.getFacet(ServiceHelper.id()); if (serviceObj == null) { continue; } Service service = ServiceHelper.narrow(serviceObj); service.someMethod(); } catch (…) { … } } Assistente • Abstração sobre a biblioteca de acesso cujo objetivo é atuar como um utilitário que atende a cenários de uso mais comuns • Auxilia na autenticação com o barramento • Auxilia no registro e busca de ofertas • Permite a configuração de número de tentativas • Permite configurar callbacks de falhas • Limitação de um assistente por ORB Assistente • Cenários recomendados: • Comunicação com um único barramento • Necessidade de apenas uma autenticação • Cenários não recomendados: • Comunicação com mais de um barramento • Necessidade de múltiplas autenticações, com um ou mais barramentos Assistente • Principais vantagens: • Auxílio na autenticação com o barramento • Implementa a callback onInvalidLogin para o usuário • Ofertas de serviços são mantidas automaticamente caso a autenticação seja refeita Assistente - Login • Exemplo: // Criação de um assistente – tentará realizar o login em uma // nova thread, até conseguir // por login e senha Assistant assistant = Assistant.createWithPassword(host, port, entity, password.getBytes()); // por certificado Assistant assistant = Assistant.createWithPrivateKey(host, port, entity, privateKey); Assistente – Publicação de Oferta • Exemplo: // registro de um serviço no barramento - tentará realizar o // registro em uma nova thread, até conseguir ServiceProperty[] properties = new ServiceProperty[]{ new ServiceProperty(“my property”, “my property value”)}; assistant.registerService(iComponent, properties); Assistente – Busca por Oferta • Exemplo: // busca por serviço ServiceProperty[] properties = new ServiceProperty[1]; properties[0] = new ServiceProperty(“my property”, “my property value”)}; ServiceOfferDesc[] offers; try { // O segundo parâmetro define o número de tentativas. // -1 significa tentar indefinidamente até conseguir. // Pode-se configurar o tempo entre as tentativas. offers = assistant.findServices(properties, -1); } catch (…) { … } Boas Práticas • Ambiente distribuído • Sempre pode haver falhas de acesso a objetos remotos • Exceções sempre devem ser tratadas para garantir a robustez Tratamento de Exceções • OpenBus • CORBA::NoPermission • NoLogin – caso alguma operação que dependa de login seja feita e não haja um login no momento • InvalidChain – cadeia inválida enviada • UnknownBus – barramento não conhecido pelo serviço que se está tentando utilizar • UnverifiedLogin – o serviço que se está tentanto utilizar não conseguiu verificar seu login no barramento • InvalidRemote – protocolos de versão incompatíveis • ServiceFailure – falha interna em um serviço Tratamento de Exceções • CORBA • CORBA::TRANSIENT • Ocorreu um erro na comunicação, mas pode ser possível tentar novamente (ex: não foi possível contactar o servidor) • CORBA::COMM_FAILURE • Erro de comunicação durante o atendimento de uma chamada (ex: falta de recursos no servidor) • CORBA::OBJECT_NOT_EXISTS • O objeto requisitado no servidor não existe Tratamento de Exceções • CORBA • CORBA::TRANSIENT • Ocorreu um erro na comunicação, mas pode ser possível tentar novamente (ex: não foi possível contactar o servidor) • CORBA::COMM_FAILURE • Erro de comunicação durante o atendimento de uma chamada (ex: falta de recursos no servidor) • CORBA::OBJECT_NOT_EXISTS • O objeto requisitado no servidor não existe Detalhes e Outras Funcionalidades • Veremos agora: • Comunicação detalhada • Multiplexação • Compartilhamento de autenticação Comunicação Detalhada Comunicação Detalhada Multiplexação • OpenBusContext • Representa dois contextos diferentes • Contexto de Requisição (realização de chamadas) • Contexto de Despacho (recebimento de chamadas) • Define conexão padrão • A ser utilizada tanto em Requisição como em Despacho, caso não sejam especificadas Multiplexação – Contexto de Request • Exemplo: // configuração da conexão padrão context.setDefaultConnection(connection); Multiplexação • OpenBusContext • Como Contexto de Requisição • Define conexão corrente • Permite configurar a cadeia de chamadas associada à requisição • Métodos joinChain, exitChain, getJoinedChain Multiplexação – Contexto de Request • Exemplo: // configuração da conexão de requisição (requester) context.setCurrentConnection(connection); Multiplexação • OpenBusContext • Como Contexto de Despacho • Define conexão de despacho • E callback onCallDispatch para a escolha dessa conexão • Permite consultar a cadeia de chamadas associada à chamada recebida • Método getCallerChain Multiplexação – Contexto de Dispatch • Exemplo: // configuração da conexão de despacho (dispatcher) context.onCallDispatch( new CallDispatchCallback() { @Override public Connection Dispatch(OpenBusContext context, String busid, String loginId, byte[] object_id, String operation){ // cabe ao código da aplicação definir a conexão return connection; } } ); Multiplexação • OpenBusContext • Método context.getCurrentConnection() • Contexto de Requisição: • Obtém a conexão corrente do contexto ou a padrão • Contexto de Despacho • Obtém a conexão que atende à requisição Compartilhamento de Autenticação • Exemplo: try { OctetSeqHolder secret = new OctetSeqHolder(); // compartilhamento de autenticação LoginProcess login = connection.startSharedAuth(secret); // compartilhamento da autenticação com uma nova conexão Connection connection2 = context.createConnection(host,port); connection2.loginBySharedAuth(login, secret.value); } catch (…) { … } Compartilhamento de Autenticação • Exemplo com o Assistente: Assistant assistant = new Assistant(host, port) { @Override public AuthArgs onLoginAuthentication() { try { // recupera o processo de login por compartilhamento de // autenticação OctetSeqHolder secret; LoginProcess login = connection.startSharedAuth(secret); return new AuthArgs(login, secret.value); } catch (…) { … } return null; } };