UNIVERSIDADE TÉCNICA DE LISBOA INSTITUTO SUPERIOR TÉCNICO CRM SGBD T eMIP T eMIPConnector JCA Apli cação J2EE ERP LDAP EIS Um Conector J2EE para a Plataforma de Gestão Integrada TeMIP Ricardo Jorge Feliciano Lopes Pereira (Licenciado) Dissertação para obtenção do Grau de Mestre em Engenharia Informática e de Computadores Orientador: Doutora Teresa Maria Sá Ferreira Vazão Vasques Júri Presidente: Doutor Arlindo Manuel Limede de Oliveira Vogais: Doutor Paulo de Costa Luís da Fonseca Pinto Doutora Teresa Maria Sá Ferreira Vazão Vasques Setembro 2002 Resumo I Resumo: O crescente tamanho, heterogeneidade e complexidade das redes de comunicação levaram muitas empresas a investir em Plataformas de Gestão Integradas. Estas aplicações concentram todas as tarefas relacionadas com a Gestão de Redes. No entanto, a informação encontrada noutras aplicações empresariais como Enterprise Resource Planning (ERP), Costumer Relationship Management (CRM) e aplicações de workflow pode permitir alcançar uma Gestão a nível de Serviço eficiente. Java 2 Enterprise Edition (J2EE) e a Java Connector Architecture (JCA) fornecem as bases para o desenvolvimento de aplicações que integram informação de várias fontes e actuam sobre essas mesmas fontes. Actualmente já estão disponíveis Conectores JCA para a maioria das aplicações empresariais de primeira linha, enquanto que as Plataformas de Gestão Integradas oferecem um ponto único de acesso aos elementos de rede. Esta dissertação apresenta um Conector JCA para a Plataforma de Gestão Integrada da Compaq Telecommunications Management Information Platform (TeMIP). São ainda apresentadas aplicações que demonstram potenciais usos para este Conector. Palavras-chave: Integração de Sistemas, Gestão de Redes, Java Connector Architecture (JCA), Plataformas de Gestão Integrada, Interfaces Web, Java 2 Enterprise Edition (J2EE) Abstract III Abstract: The increasing size, heterogeneity and complexity of communication networks have prompted many companies to invest in Integrated Network Management Platforms. These applications concentrate all tasks related to network management. But information found in other applications, such as Enterprise Resource Planning (ERP), Costumer Relationship Management (CRM) and workflow applications can be very useful if effective Service Management is to be achieved. Java 2 Enterprise Edition (J2EE) and the Java Connector Architecture (JCA) provided a basis for developing applications that integrate data from several sources and drive these sources. JCA connectors are available for most of the major Enterprise Information Systems (EIS) and Integrated Network Management Platforms provide a single point of access to network elements. This thesis presents a JCA connector for the Compaq Telecommunications Management Information Platform (TeMIP) Integrated Network Management Platform. J2EE applications that demonstrate potential uses of the connector are also presented. Key-Words: System Integration, Network Management, Java Connector Architecture (JCA), Integrated Network Management Platform, Web Interface, Java 2 Enterprise Edition (J2EE) Agradecimentos V Agradecimentos: Queria agradecer à minha orientadora, a Professora Teresa Vazão, por toda a atenção e apoio prestado, assim como pelo seu diligente esforço no sentido de proporcionar as condições de trabalho necessárias. Este trabalho não teria sido possível sem o apoio da Compaq Portugal, que cedeu generosamente hardware e software indispensável à sua realização: uma Workstation Alpha XP1000 com Tru64 Unix e o TeMIP 4.0.0. Gostaria ainda de estender os meus agradecimentos ao Christian Kuesters pela sua disponibilidade para manter e realizar upgrades ao TeMIP. Ao Eng. Ricardo Fortunato agradeço também a sua disponibilidade no esclarecimento de dúvidas sobre o TeMIP. O Eng. José Calhariz também merece uma palavra de apreço pela ajuda prestada na administração da máquina Tru64 e do TeMIP. Estendo ainda os meus agradecimentos ao INESC-ID pelas condições de trabalho proporcionadas. Índice VII Capítulo 1 – Introdução................................................................................................. 1 1.1 – Motivação ........................................................................................................ 2 1.2 – Solução proposta .............................................................................................. 8 1.3 – Estrutura da tese ............................................................................................... 9 Capítulo 2 – Gestão de redes ....................................................................................... 11 2.1 – O modelo de referência do TMForum............................................................. 12 2.1.1 – Modelo de Responsabilidade ................................................................... 12 2.1.2 – Áreas Funcionais ..................................................................................... 14 2.1.3 – O modelo TOM ....................................................................................... 17 2.2 – Ferramentas de Gestão de Rede ...................................................................... 22 2.2.1 – Classificação............................................................................................ 22 2.2.2 – Plataforma de Gestão Integrada de Rede .................................................. 23 2.3 – Integração de sistemas .................................................................................... 26 2.3.1 – Java 2 Enterprise Edition ......................................................................... 26 2.3.2 – CORBA - Common Object Request Broker Architecture......................... 28 2.3.3 – Soluções proprietárias.............................................................................. 28 2.4 – Sumário.......................................................................................................... 31 Capítulo 3 – Tecnologias utilizadas............................................................................. 33 3.1 – TeMIP............................................................................................................ 34 3.1.1 – Capacidades de Integração....................................................................... 35 3.1.2 – TAL - TeMIP Access Library .................................................................. 37 3.2 – J2SE - Java 2 Standard Edition ....................................................................... 39 3.2.1 – JNI - Java Native Interface....................................................................... 44 3.2.2 – RMI - Remote Method Invocation ........................................................... 45 3.3 – J2EE - Java 2 Enterprise Edition..................................................................... 47 3.3.1 – Java Servlets............................................................................................ 49 3.3.1.1 – Ciclo de vida dos servlets................................................................... 51 3.3.1.2 – Persistência dos dados ....................................................................... 52 3.3.1.3 – Beans e sua utilização ........................................................................ 53 3.3.1.4 – Outras funcionalidades ...................................................................... 53 3.3.2 – JavaServer Pages ..................................................................................... 54 3.3.3 – EJB - Enterprise Java Beans..................................................................... 57 3.4 – JCA - Java Connector Architecture................................................................. 60 3.4.1 – Papeis ...................................................................................................... 61 3.4.2 – Gestão de ligações ................................................................................... 63 3.4.3 – Transacções ............................................................................................. 67 3.4.4 – Segurança ................................................................................................ 68 3.4.5 – CCI - Common Client Interface ............................................................... 69 3.4.6 – Exceptions ............................................................................................... 70 3.4.7 – Packaging ................................................................................................ 71 3.4.8 – Vantagens da norma ................................................................................ 71 3.4.9 – Actuais deficiências da norma.................................................................. 72 3.4.10 – Futuras adições à norma......................................................................... 73 Capítulo 4 – Arquitectura da solução........................................................................... 75 4.1 – Objectivos ...................................................................................................... 76 4.2 – Arquitectura geral........................................................................................... 78 4.3 – Biblioteca TalAccess ...................................................................................... 83 4.4 – Servidor RMI ................................................................................................. 85 4.5 – Conector......................................................................................................... 88 Índice VIII Capítulo 5 – Implementação........................................................................................ 91 5.1 – Ferramentas utilizadas .................................................................................... 92 5.1.1 – Java 2 Software Development Kit (SDK)................................................. 92 5.1.2 – Compilador C++ da Compaq ................................................................... 93 5.1.3 – NetBeans/Forte4Java EE.......................................................................... 93 5.1.4 – CVS......................................................................................................... 93 5.1.5 – Ant .......................................................................................................... 94 5.1.6 – Servidores J2EE....................................................................................... 95 5.1.6.1 – J2EE Reference Implementation ........................................................ 95 5.1.6.2 – JBoss ................................................................................................. 96 5.2 – Biblioteca TalAccess ...................................................................................... 97 5.2.1 – API oferecida........................................................................................... 98 5.2.1.1 – Representação das respostas e erros ................................................. 101 5.2.2 – Interacção com o TAL ........................................................................... 104 5.2.2.1 – Criação do objecto TalAccess .......................................................... 105 5.2.2.2 – Notificação de paragem do TeMIP................................................... 107 5.2.2.3 – Fim da utilização da biblioteca TalAccess........................................ 108 5.2.2.4 – Interrogações síncronas.................................................................... 109 5.2.2.5 – Verificação de username/password.................................................. 110 5.2.2.6 – Interrogações assíncronas ................................................................ 110 5.2.2.7 – Cancelamento de interrogações assíncronas ..................................... 114 5.2.3 – Limitações da biblioteca TalAccess ....................................................... 114 5.2.4 – Testes da biblioteca TalAccess - Cliente local........................................ 115 5.3 – Servidor RMI ............................................................................................... 116 5.3.1 – API oferecida......................................................................................... 117 5.3.2 – Funcionamento ...................................................................................... 118 5.3.2.1 – Arranque.......................................................................................... 119 5.3.2.2 – Paragem do servidor ........................................................................ 120 5.3.2.3 – Paragem do TeMIP .......................................................................... 121 5.3.2.4 – Interrogação síncrona....................................................................... 121 5.3.2.5 – Verificação de username/password .................................................. 122 5.3.2.6 – Interrogação assíncrona ................................................................... 122 5.3.2.7 – Cancelamento interrogação assíncrona............................................. 123 5.3.2.8 – Sistema de histórico......................................................................... 124 5.3.3 – Testes ao Servidor RMI - Cliente remoto ............................................... 124 5.4 – Conector....................................................................................................... 127 5.4.1 – API oferecida......................................................................................... 127 5.4.2 – Instalação .............................................................................................. 128 5.4.3 – Funcionamento ...................................................................................... 129 5.4.3.1 – Arranque e paragem......................................................................... 129 5.4.3.2 – Obtenção de uma ligação ................................................................. 130 5.4.3.3 – Invocação de métodos...................................................................... 132 5.4.4 – Testes ao Conector - Cliente J2EE ......................................................... 132 Capítulo 6 – Aplicações ............................................................................................ 135 6.1 – Interface Web............................................................................................... 136 6.1.1 – A rede gerida ......................................................................................... 137 6.1.2 – Funcionalidades disponibilizadas ........................................................... 138 6.1.3 – Arquitectura........................................................................................... 142 6.1.4 – Implementação ...................................................................................... 143 6.2 – Modulo de autenticação JAAS...................................................................... 146 Índice IX Capítulo 7 – Testes de desempenho........................................................................... 147 7.1 – Cenário de testes........................................................................................... 148 7.2 – Desempenho em modo síncrono ................................................................... 150 7.3 – Desempenho em modo assíncrono ................................................................ 155 7.4 – Conclusões ................................................................................................... 158 Capítulo 8 – Conclusões............................................................................................ 159 8.1 – Conclusões ................................................................................................... 160 8.2 – Trabalho futuro no TeMIPConnector............................................................ 162 Referências Bibliográficas Anexo A - Glossário Índice de Figuras XI Figura 1 – O TeMIPConnector permite integrar o TeMIP com outras aplicações........... 8 Figura 2 – Pirâmide de gestão .................................................................................... 14 Figura 3 – TOM, modelo de processos de negócio ..................................................... 19 Figura 4 – Exemplo do fluxo de processos de garantia de serviço ............................... 21 Figura 5 – Classificação de ferramentas de gestão de rede........................................... 22 Figura 6 – Estrutura geral de uma Plataforma de Gestão ............................................. 24 Figura 7 – Visão conceptual do modelo de gestão empregado no TeMIP..................... 34 Figura 8 – Componentes do Java 2 Platform Standard Edition .................................... 41 Figura 9 – Componentes do Java 2 Enterprise Edition ............................................... 47 Figura 10 – Arquitectura de uma solução assente em servlets...................................... 50 Figura 11 – Relação entre classes passíveis de extensão para a criação de um servlet .. 51 Figura 12 – Arquitectura de um servidor HTTP com suporte para JSP ........................ 55 Figura 13 – Arquitectura JCA...................................................................................... 61 Figura 14 – Interfaces constituintes da JCA ................................................................ 64 Figura 15 – Diagrama temporal para estabelecimento de nova ligacao ........................ 65 Figura 16 – Arquitectura global do TeMIPConnector.................................................. 78 Figura 17 – Arquitectura da biblioteca TalAccess ....................................................... 83 Figura 18 – Biblioteca TalAccess................................................................................ 97 Figura 19 – Transformação das respostas do TAL...................................................... 101 Figura 20 – Classes utilizadas nas respostas .............................................................. 103 Figura 21 – Início de utilização da biblioteca TalAccess e paragem do TeMIP .......... 106 Figura 22 – Paragem da biblioteca TalAccess ........................................................... 108 Figura 23 – Realização de uma interrogação síncrona ............................................... 109 Figura 24 – Realização de uma interrogação assíncrona ............................................ 111 Figura 25 – Posicionamento do cliente local.............................................................. 115 Figura 26 – Posicionamento do cliente remoto .......................................................... 125 Figura 27 – Introdução da interrogação ..................................................................... 133 Figura 28 – Apresentação da resposta........................................................................ 133 Figura 29 – Autenticação do utilizador...................................................................... 134 Figura 30 – Página inicial vista num PDA ................................................................. 139 Figura 31 – Página inicial vista num browser ............................................................ 140 Figura 32 – Escolha de OCs a monitorizar ................................................................ 140 Figura 33 – Lista de alarmes de um operation context ............................................... 141 Figura 34 – Pormenores de um alarme ...................................................................... 142 Figura 35 – Arquitectura global da aplicação Web .................................................... 143 Figura 36 – Ritmo de resposta no modo síncrono ...................................................... 151 Figura 37 – Tempo de resposta no modo síncrono..................................................... 152 Figura 38 – Detalhe do tempo de resposta no modo síncrono .................................... 153 Figura 39 – Ritmo de resposta para perguntas assíncronas......................................... 156 Figura 40 – Tempo de resposta para perguntas assíncronas ....................................... 156 Índice de Tabelas XIII Tabela 1 – Ritmo de resposta no modo síncrono (respostas/s) ................................... 150 Tabela 2 – Tempo de resposta no modo síncrono (ms) .............................................. 150 Tabela 3 – Ritmo de respostas em modo assíncrono (respostas/s).............................. 155 Tabela 4 – Tempo de resposta em modo assíncrono (ms) .......................................... 155 Introdução 1 Capítulo 1 – Introdução Este capítulo apresenta o problema identificado e a solução proposta. A primeira secção apresenta a motivação para a realização deste trabalho. Na segunda secção é delineada a solução proposta, que será apresentada em detalhe nos capítulos seguintes. A última secção descreve a estrutura deste texto. Introdução 2 1.1 – Motivação As redes de comunicação ocupam hoje um papel central nas nossas vidas. É difícil imaginar como seria viver sem telefones, telemóveis, computadores e Internet. No entanto, todas estas tecnologias, às quais damos tanto valor, são ainda relativamente recentes, estando em constante evolução. Com o objectivo de tornar a vida do consumidor final cada vez mais simples e de aumentar a aceitação dos produtos, as redes de comunicação que os suportam são cada vez mais complexas. A manutenção e operação destas redes, das quais a nossa dependência aumenta de dia para dia, são também tarefas cada vez mais complexas. A evolução das redes de dados ditou e acompanhou a evolução dos próprios computadores e da forma como os utilizamos. Os primeiros computadores similares aos que conhecemos hoje eram sistemas centralizados, podendo os utilizadores aceder-lhes através de terminais remotos. As redes de acesso que ligavam os terminais aos sistemas centralizados eram de reduzida dimensão e isoladas. Foi por esta altura que começaram a surgir as primeiras redes de computadores, assentes sobre tecnologias proprietárias específicas de cada fabricante. Embora fossem estes computadores os primeiros a fazer parte da Internet, na altura esta era ainda uma experiência de diminutas proporções (década de 70). A década de 80 assistiu à explosão do mercado dos PCs (Personal Computers), cujos baixos preços levaram à colocação de um computador por secretária, em detrimento dos sistemas centralizados. As redes locais, em particular aquelas suportadas em Token-Ring e Ethernet, ligavam estes PCs. A manutenção de um grande número de PCs tornou-se uma tarefa complexa. Na década de 90 a Internet implantouse comercialmente, graças à popularidade da WWW (World Wide Web). As aplicações WWW retomaram o conceito de servidores centrais ao concentrar as aplicações nos servidores HTTP (Hyper Text Transport Protocol), facilitando a sua manutenção e distribuição. No entanto, nos últimos anos, à medida que cada vez mais aplicações adoptam interfaces Web, estas têm sofrido grandes avanços, tornando-se cada vez mais complexas e integrando um número cada vez maior de outros sistemas. Como resultado a sua gestão e manutenção também se tornaram mais complexas. Paralelamente, também as redes de telecomunicações evoluíram. Inicialmente destinadas apenas ao tráfego de voz, as redes de telecomunicações suportam hoje voz e Introdução 3 dados. Enquanto a voz requer uma largura de banda relativamente baixa, a qual tem vindo a diminuir através de técnicas de codificação cada vez mais eficientes, as aplicações de dados requerem cada vez mais largura de banda. O volume de tráfego constituído por dados é cada mais significativo, havendo uma tendência para a criação de redes integradas, destinadas a suportar aplicações multimédia, sendo a voz transportada, por exemplo, sobre IP (Internet Protocol) [1]. Para isso ser possível é necessário introduzir qualidade de serviço na rede inteira. O aumento do número de utilizadores e carga na rede motiva a sua constante evolução e reengenharia. À medida que os operadores de rede adoptam novas tecnologias, estas têm de coexistir com as já presentes nas redes, aumentando assim a sua complexidade. Um operador de telecomunicações tem de gerir não só uma complexa rede de comunicações como um conjunto de aplicações destinadas a prestar os serviços aos clientes. Para complicar ainda mais a situação, frequentemente o operador não é dono da rede inteira, contratando serviços a outros operadores. Assim, um operador, para prestar determinado serviço aos clientes, tem de gerir os seus equipamentos e verificar se os seus próprios fornecedores lhe prestam o serviço contratado [2]. Este cenário, já de si complexo, é agravado pela necessidade de manter os custos baixos e disponibilizar rapidamente novos serviços devido à competição. Os esforços de normalização das redes de comunicações centraram-se no desenvolvimento das tecnologias de comunicação em si, deixando para segundo plano a gestão das redes. Assim, as normas de gestão de rede surgiram mais tarde. Nesta área, os fabricantes foram capazes de impor soluções proprietárias durante mais tempo, demonstrando que a maturação destas tecnologias foi um processo mais demorado. A necessidade de interligação dos operadores de telecomunicações obrigou o mercado a fornecer soluções normalizadas desde cedo. No entanto, sendo a gestão de rede muitas vezes um processo interno a cada organização, foi possível responder às necessidades dos operadores com soluções de gestão proprietárias. Existem várias tecnologias normalizadas, até certo ponto, que coexistem, nem sempre pacificamente, umas com as outras e com soluções proprietárias. Os finais da década de 80, inícios da década de 90, assistiram ao surgimento de esforços de normalização das arquitecturas de gestão. As mais bem sucedidas foram a SNMP (Simple Network Management Protocol) [3], promovido pelo IETF (Internet Engineering Task Force), e a OSI/TMN (Open Systems Introdução 4 Interconnection/Telecommunications Management Network) [4][5], promovida pelo ISO (International Organization for Standardization) e pelo ITU-T (International Telecommunications Union – Telecommunication Standardization Sector). Ambas as arquitecturas se baseiam num modelo cliente/servidor onde os clientes, sobre a forma de aplicações de gestão, comunicam com os servidores (agentes), que correm nos equipamentos geridos. Os agentes são componentes de software que permitem efectuar a gestão remota dos equipamentos. As duas arquitecturas distinguem-se principalmente pelo seu mercado alvo e nível de funcionalidade implementada nos agentes. O SNMP foi criado com o objectivo de gerir equipamentos ligados a redes de dados, nomeadamente à Internet ou a outras redes TCP/IP (Transport Control Protocol/Internet Protocol), tendo sido especificado de uma forma aberta através de RFCs (Request For Comments). O objectivo era a criação de uma arquitectura simples e fácil de implementar. Esse objectivo foi conseguido e o SNMP, devido ao seu baixo custo de implementação, é hoje suportado pela maioria dos equipamentos destinados a redes IP, mesmo quando estes suportam outras arquitecturas mais complexas. Os agentes SNMP apresentam uma funcionalidade muito limitada, sendo o processamento efectuado pela aplicação gestor. Isto implica que o gestor tem de aceder frequentemente aos agentes, resultando assim numa grande ocupação da rede. O transporte da informação de gestão sobre a rede gerida, e a utilização de um protocolo de transporte sem garantia de entrega (UDP – User Datagram Protocol), limitam a utilização do SNMP em ambientes críticos. A simplicidade da arquitectura SNMP também é reflectida no modelo de informação, que não é orientado a objectos, tornando a sua adaptação às necessidades específicas de cada equipamento impossível. A consequência foi a criação de diversas MIBs (Management Information Base) proprietárias onde os fabricantes colocaram a informação específica dos seus produtos, obrigando as aplicações de gestão a conhecer explicitamente cada uma destas MIBs e diminuindo a interoperabilidade dos equipamentos a nível de gestão [6][7]. A arquitectura OSI/TMN foi criada através de um processo mais formal e moroso, fazendo com que tivesse uma implantação mais lenta. Esta arquitectura destina-se ao mercado dos operadores de telecomunicações, tendo maiores requisitos de disponibilidade que o SNMP. A comunicação entre agentes e gestores pode mesmo ser efectuada através de uma rede separada, física ou virtualmente, das redes geridas. Esta arquitectura permite ainda a troca de informação de gestão entre operadores de uma Introdução 5 forma normalizada. A maior complexidade desta arquitectura está patente no modelo de informação e na funcionalidade atribuída aos agentes. A arquitectura usa um modelo de informação baseado em objectos, que para além de ser muito extenso, permite a sua fácil ampliação através do mecanismo de herança. No entanto, os agentes OSI/TMN são muito mais complexos, fazendo com que a sua implementação apenas se justifique em equipamentos mais caros. Estes são capazes de realizar algum processamento, permitindo que a gestão de rede seja realizada de uma forma distribuída, por oposição ao modelo centralizado do SNMP. Hoje a convergência das redes de telecomunicações e dados é cada vez mais uma realidade. Assim os operadores de telecomunicações são forçados a manter redes constituídas por equipamentos que utilizam tanto as arquitecturas de gestão referidas, como outras proprietárias. Muitos dos equipamentos de rede existentes não seguem as normas de gestão, quer porque estas não são suficientemente flexíveis para suportar as necessidades do equipamento, quer porque os fabricantes esperam fidelizar os clientes através do uso de protocolos e aplicações de gestão proprietárias. No entanto, uma gestão de rede eficaz só pode ser atingida através da recolha e análise da informação fornecida por todos os equipamentos constituintes da rede. Numa rede constituída por um grande número de equipamentos de diversas marcas a gestão individual de cada elemento de rede não é viável. Este tipo de gestão requer uma grande quantidade de recursos humanos e não consegue proporcionar uma visão global da rede. Como resposta a este problema, vários fabricantes desenvolveram aplicações capazes de gerir diferentes tipos de elementos de rede graças ao suporte de vários protocolos de gestão. Estas aplicações, denominadas Plataformas Integradas de Gestão de Rede, caracterizam-se ainda por poderem ser facilmente estendidas de forma a permitir a gestão de novos equipamentos [8]. É assim possível usar estas aplicações para efectuar a gestão de redes complexas, quer recorrendo às capacidades nativas da plataforma, quer comprando ou desenvolvendo módulos para comunicação com equipamentos específicos. Os próprios fabricantes dos equipamentos de rede podem vender módulos de acesso para Plataformas Integradas de Gestão de Rede de vários vendedores. A concentração da gestão de todos os elementos de rede numa única aplicação permite passar da gestão individual do elemento de rede para uma gestão ao nível da rede. Os serviços normalmente oferecidos por todas as Plataformas Integradas são: a monitorização de equipamento/rede (estado, desempenho), a indicação de faltas (valores Introdução 6 fora dos limites estabelecidos, alarme, perda de contacto), a gestão de configuração e representação topológica da rede. No entanto, estes serviços podem ser complementados por outros, tais como a correlação de eventos ou a gestão de problemas. As Plataformas Integradas de Gestão de Rede podem proporcionar uma visão geral da rede e possibilitar a gestão ao nível de rede. Apesar disso, não permitem, por si só, atingir níveis mais elevados de abstracção, como os existentes no Modelo de Responsabilidades, recomendado pelo ITU-T [9]. Este é representado sobre a forma de uma pirâmide, onde cada nível assenta sobre o inferior, e proporciona um grau de abstracção superior. Na base encontramos a gestão ao nível de elemento de rede. O nível superior é o nível de rede, que pressupõe a agregação da gestão de todos os elementos de rede, permitindo assim uma visão global do comportamento da rede como um todo. No entanto, a rede apenas existe para suportar os serviços, e é este o nível seguinte da pirâmide. Neste nível são geridos os serviços, abstraindo a rede e os elementos de rede e focando o serviço como o cliente o vê. No topo da pirâmide reside a abstracção de nível de negócio, para o qual é relevante informação financeira, legal, estratégica, económica e métricas de rentabilidade do negócio. Quanto mais acima na pirâmide reside um nível de gestão, mais difícil é implementá-lo. No entanto, a Gestão de Serviço é hoje um objectivo a atingir [10][11][12], o qual só se atinge de uma forma eficaz se a informação de gestão de rede for combinada com outras fontes de informação como ferramentas de workflow, CRM (Costumer Relationship Management) e ERP (Enterprise Resource Planning). A concentração da gestão de rede numa única aplicação torna viável a integração desta informação com outras fontes, existindo muitas vantagens à espera de serem aproveitadas. O acesso à informação de gestão poderá ser utilizado para vários fins, tais como: criação de novos interfaces (WAP – Wireless Application Protocol [13], WWW, PDA – Personal Digital Assistent, 3G – Third Generation of mobile communications technology); criação de interfaces de gestão Web [14][15]; geração automática de relatórios; integração em processos de workflow tais como aprovisionamento de serviços [16]. Informação proveniente de outras aplicações pode também ajudar à gestão de rede: a prioridade de um alarme pode ser alterada de acordo com o nível de serviço (Service Level Agreement – SLA) acordado com o cliente afectado; a informação de contacto do responsável por um determinado equipamento pode ser retirada de um directório LDAP (Lightweight Directory Access Protocol), evitando assim a replicação de informação. Introdução 7 As Plataformas Integrada de Gestão de Rede dão muita ênfase à capacidade de integrar vários tipos de elementos de rede. No entanto, a sua capacidade de integração com outras aplicações é reduzida. Por sua vez, o mercado das aplicações de integração fornece produtos capazes de realizar a integração da maior parte das aplicações acima referidas, excepto as Plataformas Integradas de Gestão de Rede. A integração eficiente de diversas aplicações requer o uso de uma plataforma de middleware que forneça acesso a estas aplicações [17][18]. O Java 2 Enterprise Edition (J2EE) [19] proporciona essa possibilidade ao mesmo tempo que oferece as vantagens associadas à linguagem Java: grande base de programadores; portabilidade de código fonte e compilado para um grande número de sistemas operativos e arquitecturas; suporte para Common Object Request Broker Architecture (CORBA) [20] permitindo o acesso directo a aplicações de gestão suportadas em CORBA. Adicionalmente o J2EE não é um produto mas uma norma suportada pelos grandes nomes da indústria, permitindo que uma aplicação J2EE possa correr em diferentes implementações (J2EE containers ou servidores) de diferentes vendedores. A interacção entre uma aplicação J2EE e Sistemas de Informação Empresariais, tais como Plataformas Integradas de Gestão de Rede, é conseguida através da Java Connector Architecture (JCA), uma das últimas adições ao J2EE [21]. Esta norma define interfaces que um connector e um servidor J2EE devem implementar para que um connector possa funcionar com qualquer servidor J2EE. O conceito de Conector não é novo, e produtos de middleware como o Vitria [22] ou o Tibco [23] há muito que fornecem tecnologias similares, conhecidas como Conectores ou Adaptadores [24]. Embora o JCA só tenha sido introduzido há alguns meses, já é listado como sendo suportado por nove vendedores de servidores J2EE, existindo connectors para os EIS mais utilizados, como por exemplo o SAP [25], para o qual já são conhecidos quinze connectors diferentes [26]. Estes primeiros connectors a surgir no mercado destinam-se a ERPs, aplicações de CRM, SGBDs (Sistemas de Gestão de Bases de Dados) e outros sistemas empresariais. No entanto, não se encontram disponíveis connectors para Plataformas Integradas de Gestão de Redes. Introdução 8 1.2 – Solução proposta Este trabalho apresenta um connector JCA para a Plataforma de Gestão Integrada Telecommunications Management Information Platform (TeMIP) da Compaq [27]. O TeMIPConnector, nome com que o connector foi baptizado, poderá ser utilizado no desenvolvimento de aplicações J2EE que comunicam com o TeMIP. O recurso a outros connectors possibilita o desenvolvimento de aplicações que comunicam com vários sistemas, servindo de hub, conforme ilustrado na Figura 1. É assim possível desenvolver aplicações para automatizar tarefas de gestão ao nível de serviço ou mesmo de negócio. Aplicação ERP Connector para ERP Aplicação de Facturação Connector para Apl. Fact. Aplicação J2EE Connector para CRM Aplicação CRM TeMIP Connector TeMIP Figura 1 – O TeMIPConnector permite integrar o TeMIP com outras aplicações Introdução 9 1.3 – Estrutura da tese A presente tese é constituída por oito capítulos e um anexo. O próximo capítulo apresenta uma perspectiva mais detalhada da problemática da gestão de rede e integração de aplicações. As tecnologias escolhidas para a realização deste trabalho são apresentadas no terceiro capítulo. O quarto capítulo detalha a arquitectura da solução, enquanto que o quinto foca os detalhes de implementação. No sexto capítulo é dado o exemplo de uma aplicação que utiliza o TeMIPConnector, explorando assim um possível cenário de utilização. O sétimo capítulo apresenta os testes de desempenho realizados com vista a avaliar a escalabilidade da solução. Esta dissertação termina com o oitavo capítulo onde são apresentadas as conclusões e caminhos possíveis para o desenvolvimento futuro do trabalho. Após as referências bibliográficas é apresentado, em anexo, um glossário. Gestão de redes 11 Capítulo 2 – Gestão de redes Este capítulo analisa a problemática de gestão de rede, segundo as normas e recomendações internacionais. Na primeira secção são apresentadas as normas e recomendação relevantes desenvolvidas pelos organismos internacionais de normalização ou consórcios industriais. A segunda secção apresenta algumas das funcionalidades fornecidas pelas plataformas de gestão de rede disponíveis, mostrando que estas soluções não são capazes, por si só, de realizar a visão idealizada pelos organismos de normalização. Devido à necessidade de integração das plataformas de gestão com outras aplicações empresariais para atingir uma gestão integrada de rede e serviços, são analisados na terceira secção algumas das soluções de integração utilizadas. Na última secção apresenta é apresentado um resumo deste capítulo. Gestão de redes 12 2.1 – O modelo de referência do TMForum O Telecommunications Management Forum (TMForum) é uma organização internacional sem fins lucrativos, sendo um consórcio de operadores de telecomunicações, prestadores de serviços e fabricantes de equipamentos e software para a indústria de serviços de informação e comunicação. O seu objectivo é concertar fornecedores e compradores de equipamentos e soluções, de modo a criar especificações e recomendações que facilitem a automação dos processos de negócio dos operadores e fornecedores de serviços de telecomunicações de uma forma eficiente em termos de tempo e custo. O TMForum tenta atingir os seus objectivos utilizando normas já existentes e, quando necessário, sugerindo às organizações internacionais de normalização a criação de novas normas. Parte do seu esforço envolve a implementação das suas próprias recomendações, processo que pode resultar na entrega de feed-back às referidas organizações. 2.1.1 – Modelo de Responsabilidade Uma das normas em que o TMForum se apoia é o modelo de gestão OSI/TMN. Este é uma arquitectura de referência para a gestão distribuída de redes de telecomunicações. Um dos seus objectivos é permitir a troca de informação de gestão, de uma forma normalizada, entre operadores de rede ou fornecedores de serviços de telecomunicações. A arquitectura OSI/TMN foi a primeira a ser definida explicitamente através da sua separação em quatro modelos: o modelo de informação, o modelo de organização, o modelo de comunicação e o modelo funcional. O modelo de informação define a abstracção dos objectos geridos, definindo, por exemplo, os tipos de dados disponíveis para representar os objectos geridos e o sistema de nomes utilizado para identificar as instâncias dos objectos [28][29]. A quantidade de informação definida no modelo de informação e o detalhe desta informação restringem a funcionalidade e afectam a complexidade das aplicações de gestão. A arquitectura OSI/TMN recorre à modelação por objectos para representar os objectos geridos. Gestão de redes 13 O modelo de organização define as relações entre gestores e sistemas geridos, devendo ser adaptável às características próprias de cada organização, nomeadamente à sua estrutura departamental ou distribuição de responsabilidades [30][31]. A arquitectura OSI/TMN define dois papéis para um sistema (gestor e agente), podendo cada sistema desempenhar um ou ambos os papéis simultaneamente. Os sistemas geridos podem ser agrupados em domínios hierárquicos com grande flexibilidade, permitindo, por exemplo, mapear nos domínios de gestão a estrutura departamental ou geográfica de uma organização. O modelo funcional especifica as funções genéricas de gestão da arquitectura [32]. É este modelo que serve de base à modelação dos processos de gestão. O modelo funcional OSI/TMN é bastante extenso e em constante evolução, sendo divido em cinco áreas funcionais: gestão de falhas, gestão de configuração, gestão de contabilização, gestão de desempenho e gestão de segurança. Cada uma destas áreas funcionais é constituída por várias funções de gestão de sistemas, cada uma definida no seu próprio documento. Algumas das funções de gestão de sistemas são: gestão de estado [33], reporte de eventos [34], controlo de ficheiros de histórico (logs) [35], reporte de alarmes de segurança [36] e gestão de software [37]. O modelo de comunicação define como se processa a troca de informação de gestão entre os vários componentes do sistema de gestão, incluindo a definição do protocolo de comunicação. O modelo de comunicação OSI/TMN define o CMIP (Common Management Information Protocol) para a troca de informação entre sistemas [38][39]. Existem especificações para a implementação de CMIP sobre vários protocolos de transporte, entre os quais TCP/IP (CMOT – CMIP over TCP) e a pilha de protocolos OSI [40]. Um dos conceitos da arquitectura OSI/TMN mais utilizados é o Modelo de Responsabilidades, representado pela pirâmide de gestão, apresentada na Figura 2 e já mencionada no capítulo anterior. Neste modelo, cada nível assenta sobre o inferior, conferindo um grau de abstracção maior. Na base encontramos os elementos constituintes da rede de telecomunicações. A informação de gestão disponível em cada nível condiciona a funcionalidade do nível superior, ao mesmo tempo que é limitada pela informação disponibilizada pelo nível inferior. A arquitectura OSI/TMN debruça-se Gestão de redes 14 em maior detalhe sobre os dois níveis inferiores da pirâmide, sendo mais lacónica em relação aos níveis superiores. Negócio Serviço Rede Elementos de Rede Figura 2 – Pirâmide de gestão [9] 2.1.2 – Áreas Funcionais Como já foi referido, o modelo funcional da arquitectura de gestão OSI/TMN divide as funções de gestão em cinco áreas funcionais: gestão de falhas, gestão de configuração, gestão de contabilização, gestão de desempenho e gestão de segurança. A palavra “configuração” pode-se referir à descrição do estado e valor dos parâmetros de um equipamento, ou indicar o processo de alteração desses parâmetros. Como processo, configuração pode ser definido como a adaptação dos sistemas ao seu ambiente operacional, incluindo tarefas como, por exemplo, a instalação de novo software, upgrade a software antigo, modificação de parâmetros do sistema, alterações físicas ao hardware e alterações à topologia de uma rede. O processo de configuração pode tomar formas muito distintas. Algumas tarefas podem ser realizadas por software, e eventualmente automatizadas, enquanto que outras requerem uma intervenção física no local. As intervenções de natureza não física podem necessitar de ser realizadas localmente, ou permitir a realização remota. Uma tarefa importante do processo de configuração é a manutenção de documentos técnicos que descrevam as alterações efectuadas e a configuração actual de cada equipamento. Umas das ferramentas cruciais de gestão de configuração são precisamente os sistemas de documentação para o registo das configurações. Outros exemplos são: ferramentas de auto descoberta, que permitem inferir o estado actual de Gestão de redes 15 um sistema ou a topologia de uma rede; ferramentas de distribuição de software e licenças; ferramentas para activação de sistemas de suporte, em caso de falha num sistema. A gestão de faltas tem como objectivo a detecção e correcção de falhas de forma a manter os sistemas ou redes, e serviços que estes proporcionam, em funcionamento a maior parte do tempo possível. Qualquer desvio em relação ao comportamento esperado pode ser considerado uma falha. Estas podem, por exemplo, ser: físicas, como o corte de um cabo, falta de electricidade ou a avaria de um componente; de software, como a paragem inesperada de um programa; ou resultantes de condicionalismos externos, como a sobrecarga de uma rede pelos utilizadores. Uma única falha pode levar a que vários equipamentos ou utilizadores gerem alarmes com sintomas diferentes. Numa rede complexa, constituída por um grande número de elementos de rede heterogéneos, distribuídos geograficamente, e que compreenda várias organizações, pode ser muito difícil determinar a origem do problema. Algumas das tarefas de gestão de falhas incluem: monitorização do estado da rede e sistemas, reacção a alarmes, determinação das causas dos alarmes, fornecimento de assistência aos utilizadores (help desk) e operação de sistemas de gestão de problemas (trouble ticket). Algumas das ferramentas e técnicas que podem contribuir para a gestão de faltas são: ferramentas de teste, de preferência realizáveis remotamente, como ping, traceroute e echos aos vários níveis de rede; manutenção de logs de mensagens e eventos; mecanismos de filtragem de alarmes, para limitar a quantidade de informação a processar por cada operador de rede e permitir a sua especialização; ferramentas de correlação de eventos e de determinação da causa dos vários eventos; a integração dos sistemas de gestão de alarmes com os sistemas de help desk e de trouble ticket. A gestão de contabilização e de utilizadores trata de restringir o acesso dos utilizadores aos serviços e determinar os custos de utilização desses serviços. Nem todos os utilizadores necessitam ou podem ter acesso a todos os recursos de uma rede. Assim sendo, a gestão de utilizadores lida com a definição dos recursos a que cada utilizador ou grupo de utilizadores pode aceder, definindo ainda a forma como lhes pode aceder. A identificação dos utilizadores e manutenção dos seus atributos (nome, morada, etc.) é também uma tarefa importante. A restrição de acesso é uma tarefa comum, mas a Gestão de redes 16 contabilização de custos é essencialmente importante para os prestadores de serviços de comunicação. O acesso aos recursos tem custos, que podem ser imputados aos utilizadores. Este é o caso dos serviços oferecidos pelos prestadores de serviços de comunicação, que dependem dos utilizadores como fonte de rendimentos. O processo de contabilização dos montantes a cobrar a um cliente pode ser tão simples como uma prestação mensal fixa ou tão complexa como o cálculo do custo de uma chamada telefónica que varia com o tarifário escolhido pelo cliente, com a hora do dia, com o dia da semana, com o destino da chamada e com outros factores como promoções em vigor. O desempenho esperado do sistema de contabilização também pode variar entre a realização dos cálculos após a utilização dos serviços, e um sistema quase tempo real, que calcula o custo antes ou durante a utilização do serviço, como é o caso dos serviços de telefone móvel pré-pagos. Quando os serviços são prestados conjuntamente por vários prestadores de serviços, pode haver necessidade de partilha de receitas. A complexidade dos sistemas de contabilização é um factor importante a ter em conta pois estes não devem ser tão dispendiosos a ponto de ter um impacto no custo dos serviços. A utilização de parte significativa da capacidade da rede para transferir informação de contabilização é um exemplo disso. No entanto estes sistemas devem ser suficientemente flexíveis, oferecendo a possibilidade de estabelecer tarifários assentes em critérios muito distintos, senão para garantir uma vantagem competitiva, pelo menos para não limitarem a oferta comercial perante a concorrência. Esta área funcional é aquela com ligações mais claras aos níveis superiores da pirâmide de gestão: o nível de serviço e o de negócio. A gestão de desempenho é similar à gestão de faltas, mas enquanto a última se destina a garantir que a rede funciona, a primeira verifica que a rede ou sistema funciona dentro de determinados parâmetros de desempenho. Estes parâmetros de qualidade de serviço (QoS – Quality of Service) podem ser definidos aquando da criação ou configuração da rede, alterados consoante as necessidades, ou definidos em contrato no caso de serviços contratados a um prestador de serviços de comunicação (SLA). Embora possa ser efectuada ao nível de uma rede Ethernet local, é mais provável que seja primeiro implementada num serviço de comunicações caro, prestado exteriormente à organização. A sua implementação pode ser complicada pelo facto de um canal de Gestão de redes 17 comunicação depender de vários prestadores de serviços de comunicações, por exemplo: no caso de um operador fazer a ligação até determinado ponto e outro operador garantir o resto da ligação; quando operadores diferentes garantem o serviço nos vários níveis, como o aluguer da linha e a conectividade IP. Esta área funcional é de especial importância para os prestadores de serviços de telecomunicações, que tem a obrigação contratual de manter a qualidade do serviço prestado aos seus clientes. Monitorização de parâmetros de qualidade de serviços, analisadores de protocolos, geração de tráfego de teste e ferramentas de simulação e planeamento de capacidade são algumas das técnicas utilizadas na gestão de desempenho. Gestão de segurança é a área funcional responsável pela protecção da rede e sistemas. Qualquer sistema ou rede está sujeito a ameaças, que variam de acções involuntárias, como a má utilização dos sistemas, até ataques propositados como vírus informáticos, roubo ou adulteração de informação, ou ataques de negação de serviço (denial of service). Os recursos dispendidos na protecção dos sistemas são proporcionais ao valor dos sistemas e prejuízos resultantes da sua indisponibilidade. Auditorias de segurança e análises de risco e ameaças são algumas das técnicas utilizadas para determinar as medidas de segurança necessárias. As medidas de segurança podem tomar a forma de políticas de segurança, como exigir um determinado nível de complexidade para as password, ou o uso de ferramentas de segurança como anti vírus, firewalls e Intrusion Detection Systems (IDS). 2.1.3 – O modelo TOM A arquitectura OSI/TMN debruça-se essencialmente sobre os níveis inferiores da pirâmide de gestão. No entanto, o mundo competitivo das telecomunicações, caracterizado por compras, fusões e parcerias, rápida mudança, redução constante de custos e expectativas acrescidas por parte dos clientes, exige a capacidade de integrar os processos de negócio com outros operadores. Mesmo dentro de uma única organização, é importante automatizar os processos de negócio, de forma a reduzir custos e aumentar a satisfação do cliente. A arquitectura OSI/TMN não é suficientemente abrangente para definir uma plataforma comum de processos de negócio, uma única visão partilhada por operadores, prestadores de serviços de telecomunicações e fabricantes de equipamento e Gestão de redes 18 hardware. Assim, o TMForum criou o modelo TOM (Telecom Operations Map) [41][42]. Não pretendendo ser exacto e prescritivo, o TOM é essencialmente o ponto de partida para a automação dos processos de negócio através do desenvolvimento e integração dos sistemas de suporte ao negócio e suporte à operação de sistemas (OSS – Operations Support Systems). A envolvente legal, cultural, tecnológica e social em que opera cada operador ou prestador de serviços de telecomunicações faz com que os seus processos de negócio sejam distintos. O TOM destina-se assim a servir de guia para a identificação de processos, sub-processos e tarefas comuns aos operadores, permitindo identificar funções e dados genéricos a implementar pelos fabricantes de software em cada tipo de produto, proporcionando aos operadores uma maior escolha ao diminuir o esforço de integração entre produtos distintos. Serve ainda como ponto de partida para acções de reengenharia de processos e análise do impacto de fusões e parcerias. O TOM fornece uma visão genérica dos processos de negócio de um operador, centrada no cliente, que abrange toda a organização, parceiros e fornecedores. É um modelo genérico, top-down, de alto nível, independente de tecnologias, organização e serviços, pretendendo poder ser utilizado para descrever processos actuais e futuros. Os processos, fluxos de processos e informação básica trocada entre processos pretendem ser genéricos, mas quando aplicado a situações concretas, a informação detalhada trocada será diferente de caso para caso. O TOM reflecte a forma como os operadores e fornecedores de serviços de telecomunicações operam e desenham os seus negócios, apresentando-se como a norma de facto para a automação dos processos de gestão de operações na indústria de telecomunicações. Apenas a automação e integração de processos permite reduzir o tempo de execução dos fluxos de trabalho necessários, por exemplo, para estabelecer o fornecimento de um novo serviço a um cliente, principalmente quando este fluxo de trabalho atravessa várias organizações. O foco do TOM é nos processos de negócio utilizados pelos operadores e prestadores de serviços de telecomunicações, nas ligações entre esses processos, na identificação das interfaces entre eles e no uso da informação de clientes, serviço, rede e de outras fontes. Um dos seus objectivos é gerar consenso sobre quais os processos e interfaces que mais necessitam de integração e normalização. Gestão de redes 19 A Figura 3, traduzida de [41], apresenta a plataforma de processos de negócio do modelo TOM. No topo temos o cliente, e no fundo a infra-estrutura física da rede, sendo que todos os processos se destinam a ligar estes dois extremos. Pode-se ver que os processos estão agrupados segundo os níveis da pirâmide de gestão: em baixo estão os processos de gestão dos elementos de rede, depois os processos de gestão de rede e sistemas, seguidos dos processos de serviço. O nível de negócio está relacionado com todos os processos e o nível de serviço foi dividido em duas partes: processos de acompanhamento do cliente e processos de desenvolvimento e operação de serviço. Esta divisão justifica-se por os processos de acompanhamento do cliente serem relativos a clientes individuais, enquanto que os de desenvolvimento e operação de serviço dizem respeito ao grupo de clientes de um serviço. A interface com os clientes é extremamente importante, sendo muitas vezes um importante diferenciador entre concorrentes, pelo que é representada separadamente. Esta camada representa todas as interfaces entre o cliente e os processos de acompanhamento do cliente: atendimento em pessoa, interfaces Web, Call Centers, email e IVR (Interactive Voice Response). Cliente Interface do Cliente aos Processo de Gestão Cumprimento de Serviço Vendas Garantia de Serviço Processamento de Pedidos Processamento de Problemas Gestão de QoS de Cliente Billing Facturação Cobrança Processos de Acompanhamento do Cliente Planea/desenv. Serviço Configuração de Serviço Gestão Probl. de Serviço Gestão de QoS Taxação Processos de Desenvolvimento e Operação de Serviço Planea/desenv. de Rede Aprovisionamento de Rede Gestão Invent. de Rede Manutenção e Restauro Processos de Gestão de Rede e de Sistemas Processos de Gestão de Elementos de Rede Infra-estrutura de Rede e de Sistemas Figura 3 – TOM, modelo de processos de negócio [41] Gestão Infor. de Rede Gestão de redes 20 Existe ainda uma outra divisão dos processos de negócio, desta feita vertical, em fluxos de processos. Esta divisão, representada na figura pelas linhas pretas tracejadas, separa os processos em: cumprimento de serviço (service fulfillment), garantia de serviço (service assurance) e facturação (billing). Os processos de Cumprimento de Serviço dizem respeito ao desenvolvimento e à activação dos serviços solicitados pelos clientes. Os processos de Garantia de Serviço e Serviço de Pós-venda destinam-se à manutenção do serviço, incluindo resposta às queixas dos clientes ou problemas identificados pelos processos de gestão de rede. Os processos de Billing têm como objectivo garantir que os serviços são facturados correctamente ao cliente e em tempo útil, e incluem serviços de apoio ao cliente, tais como o esclarecimento de dúvidas nas facturas. Existem processos que são partilhados entre dois fluxos, como o de Gestão de Informação de Rede, onde a informação recolhida dos equipamentos tanto é utilizado na manutenção do serviço como no cálculo da facturação. A forma como toda a informação disponível é reaproveitada pode determinar a vantagem competitiva de uma organização. Processos de acompanhamento do cliente em mercados de massas, personalizados e a baixo custo, exigem uma forte ligação automatizada entre a gestão comercial da oferta de serviços, a gestão dos elementos de rede e outros sistemas empresariais como o CRM, e ERP. Um cliente que é avisado de um eventual problema com o seu serviço, detectado automaticamente através da análise da informação da rede e resolvido prontamente, e reembolsado na factura, é um cliente mais satisfeito do que um que necessita de se queixar para ver o seu problema resolvido. A Figura 4, baseada em [41], apresenta um exemplo de um fluxo de processos da garantia de serviço para a resolução de um problema de rede. Nela são representadas as várias interacções entre os processos de garantia de serviço, desde a descoberta do problema até à sua resolução. Este exemplo em concreto abrange as três áreas de fluxos de processos, existindo troca de informação com processos das outras áreas. Neste fluxo são apresentadas as várias trocas de informação entre os processos para que seja possível detectar a falha através da informação recolhida de rede (1 e 2), requerer a reparação ou reconfiguração (3, 4, 5 e 6), notificar a existência do problema (7) e identificar e contactar o cliente e serviços afectados (8, 9 e 10). Quanto mais automatizadas forem as trocas de informação e os processos em si, mais depressa e por menor custo, se consegue executar todo o fluxo, que envolve várias ferramentas. Num Gestão de redes 21 cenário simplificado, existiria pelo menos um plataforma de gestão de rede, capaz de detectar e identificar o problema, um sistema de workflow para despoletar os processos de reparação, uma base de dados com informação sobre os clientes e parâmetros dos serviços contratados contendo a informação necessária para determinar quais os clientes e serviços afectados, um sistema de Trouble Ticket para acompanhamento do problema e um sistema de CRM para contacto com o cliente. Tratamento de problema Alertar cliente (TT) Reportar 7. Reportar problema (Trouble Ticket) 6. ((Re)Configuração de serviço) (Restituição por violação de SLA) 10. Impacto no serviço 8. Reportar dados do problema Processos de Billing Gestão de QoS do cliente Determinar violações ao SLA Actividades 9. Impacto no SLA Processos Fluxo de Informação Resolução de problema de serviço 8. Reportar dados do problema Inter Forn. de Ser. Decidir reparação Processos de Cumprimento de Serviço Inter Processos Gestão de QoS Monitorizar SLAs Através de processos CS/GS/B 5. Notificar detecção/ resolução de problema Decidir reparação Outros Fornecedores de Serviços 3. ((Re)Configuração da rede) 4. Ordem de trabalho Manutenção e restauro da rede 2. Reportar degradação Gestão de inventário da rede Alocar recursos Gestão de informação da rede Detectar falha 1. Informação de alarme/evento Testar Detectar problemas de trafego/ desempenho Isolar raiz do problema 1. Informação da rede Gestão de elemento de rede / Elementos de rede Figura 4 – Exemplo do fluxo de processos de garantia de serviço [41] Gestão de redes 22 2.2 – Ferramentas de Gestão de Rede Nesta secção são apresentadas ferramentas de gestão de rede, utilizadas para a gestão ao nível de elemento de rede ou ao nível de rede e sistema. Esta área é aquela onde existe maior normalização, nomeadamente através das duas arquitecturas de gestão (incompatíveis) Internet e OSI. Apesar disso, existe pouca interoperabilidade entre as muitas ferramentas disponíveis. Algumas destas ferramentas apenas podem ser utilizadas para realizar sub-processos de gestão segundo o modelo TOM, enquanto que outros realizam um processo por inteiro ou abrangem mesmo vários processos. 2.2.1 – Classificação A Figura 5 apresenta uma divisão das ferramentas de gestão de rede baseada em [43]. Nela estão também incluídas as ferramentas de desenvolvimento, utilizadas na criação de aplicações de gestão. Ferramentas de Gestão Ferramentas isoladas Plataformas de Gestão Aparelhos de teste Ferramentas de Desenvolvimento Ferramentas de Integração Desenvolvimento de agentes Desenvolvimento de interfaces gráficas Sistemas de Gestão Empresarial Analisadores de Protocolos Gestão de Problemas Ferramentas internet Ferramentas de MIB Desenvolvimento de aplicações de gestão Sistemas de Documentação Figura 5 – Classificação de ferramentas de gestão de rede As ferramentas de gestão de rede podem ser divididas em três grupos: ferramentas isoladas, plataformas de gestão e ferramentas de integração. As ferramentas isoladas são aparelhos ou programas autónomos, capazes por si só de cumprir a sua missão. Estes incluem: programas como as ferramentas comuns de diagnóstico Internet (ping, traceroute); analisadores de protocolos, quer na forma de aparelhos dedicados, como uma sonda RMON, quer na forma de software como por exemplo o ethereal [44]; aparelhos de teste para os vários níveis de comunicação, desde um aparelho para testar a condutividade de uma cabo até um gerador de tráfego multicast. Gestão de redes 23 As plataformas de gestão, discutidas na próxima subsecção, servem essencialmente de suporte a aplicações de gestão, factorizando assim um conjunto de serviços básicos. As ferramentas de integração permitem realizar algumas das ligações identificadas no modelo TOM, ao permitir associar várias outras ferramentas de gestão. Estas podem ser ferramentas de carácter genérico, como as ferramentas de integração utilizadas noutros contextos, nomeadamente os sistemas de workflow, CRM e outras ferramentas de integração, que permitem a integração dos vários sistemas de informação empresarial (EIS – Enterprise Information Systems) envolvidos [45]. No entanto, também podem ser ferramentas especializadas de gestão de redes, como por exemplo: sistemas de documentação, utilizados nos processos de gestão de rede (gestão de inventário); ou sistemas de gestão de problemas, utilizados ao longo dos vários grupos de processos definidos no TOM. As ferramentas de auxílio ao desenvolvimento de aplicações de gestão de rede podem tomar várias formas, desde simples bibliotecas até ambientes completos de suporte ao desenvolvimento. Exemplos deste tipo de ferramentas são: bibliotecas para comunicações com elementos de rede, compiladores de MIB e geradores de código para implementação de agentes. As plataformas de gestão podem oferecer várias destas ferramentas para o desenvolvimento de aplicações de gestão de rede a serem executadas na plataforma e para a integração de equipamento de rede com gestão proprietária. 2.2.2 – Plataforma de Gestão Integrada de Rede Uma plataforma de Gestão Integrada junta, numa única ferramenta, capacidades para as diversas vertentes da gestão de rede, sendo capaz de interagir com vários tipos de equipamentos. Para cada área funcional, são oferecidas funções de monitorização e de controlo, que permitem observar o estado e comportamento do sistema gerido, além de modificar parâmetros ou executar acções nesses sistemas. Uma Plataforma de Gestão é uma aplicação que fornece, numa única interface utilizador, diversas funcionalidades de gestão, de uma forma integrada e independente dos fabricantes. Isto significa que tem de possibilitar a transferência de informação entre os elementos que a constituem, possuir uma estrutura de informação única e ser capaz de gerir qualquer tipo de equipamento independentemente do seu fabricante. Este objectivo apenas pode ser atingido graças à normalização imposta pelas arquitecturas de Gestão de redes 24 gestão. Como forma de se adaptar a qualquer uso, uma plataforma de gestão oferece ainda um ambiente de desenvolvimento através do qual se podem desenvolver novas funcionalidades ou acrescentar outras às aplicações já existentes. Na Figura 6, retirada de [46], onde é apresentada a estrutura geral de uma plataforma de gestão, pode-se observar que esta é constituída por três módulos diferentes, que trocam informações através de APIs (Application Program Interface) normalizadas: Módulo Superficial, Módulo de Aplicações e Módulo de Infra-estrutura. Outras ferramentas Programador Utilizador Módulo Superficial API Aplicações de Gestão Ferramentas de Desenvolvimento Gestão de Topologia MIB Browser Aplicações Básicas Gestão de Configuração Gestão de Eventos Monitorização de Desempenho Monitorização de Estado API Infra-estrutura Módulo de Comunicação Núcleo Adm. de Informação Base de Dados Figura 6 – Estrutura geral de uma Plataforma de Gestão [46] O Módulo Superficial, situado no topo, é responsável pela interface com o exterior: operadores de rede, programadores e aplicações não integradas na plataforma. É comum existirem três tipos de interfaces disponíveis: uma gráfica, outra de linha de comando e APIs para programação. Um tipo possível de integração de aplicações de gestão é conferir a todas elas uma interface gráfica comum. Este tipo de integração, embora apenas superficial, permite ao utilizador sentir-se familiarizado com todas as aplicações. A nível intermédio situa-se o Módulo das Aplicações que engloba todas as aplicações existentes na plataforma, quer sejam aplicações de Gestão, aplicações de desenvolvimento ou aplicações básicas de gestão. São sete as aplicações básicas de gestão presentes na maioria das plataformas: monitorização de estado, monitorização de limiares, gestão de eventos, gestão de configuração, gestão de topologia, gestão de desempenho e pesquisadores de MIB (MIB browsers). As aplicações de gestão mais Gestão de redes 25 vulgares incluem: gestão de problemas, help-desk, correlação de eventos, gestão de inventário, gestão de facilidades, contabilidade e taxação, distribuição de software, gestão de segurança, gestão de sistemas e gestão de redes. As ferramentas de desenvolvimento incluem normalmente ferramentas gráficas e linguagens de programação próprias, que não são mais do que extensões a linguagens de programação já existentes. A realização da integração das várias aplicações a este nível reduz o número de operações que tem de ser realizadas pelas várias aplicações, permitindo factorizar funções comuns e partilhar um conjunto de dados. Por exemplo, quando a plataforma recolhe os dados dos vários elementos de rede liberta cada aplicação de realizar a comunicação directamente com cada elemento de rede. Na base encontra-se o Módulo de Infra-estrutura, que contém o núcleo da plataforma, as componentes de comunicação e administração e o repositório de informação. O TeMIP, a plataforma de gestão de rede utilizada neste trabalho, é um exemplo de uma plataforma de gestão que segue uma arquitectura semelhante. Fornece as aplicações básicas de MIB browser, gestão de eventos e monitorização de estado. Fornece várias APIs para o desenvolvimento de aplicações de gestão integradas com a plataforma. Estas aplicações são depois executadas pela plataforma, não sendo autónomas devido a dependerem dos serviços fornecidos pela plataforma. Existem ferramentas de gestão suportadas na plataforma TeMIP, e desenvolvidas por terceiros, que permitem desempenhar outros processos, como por exemplo o TeMIP Clarify Liaison Trouble Ticket da Amdocs [47] ou o Remedy Action Request System for Trouble Ticketing da Peregrine [48] para realizar o processo de Gestão de Problemas, ou o Service Activator for IP-VPN da Orchestream [49] para a Configuração de Serviços, neste caso para a activação de serviços VPNs sobre redes IP [50]. Gestão de redes 26 2.3 – Integração de sistemas Não existe uma ferramenta única capaz de suportar todos os processos necessários à manutenção de uma rede de grande escala. Em redes de reduzida dimensão, é possível que um único produto forneça todas as funcionalidades necessárias. No entanto, para um operador de telecomunicações, todos os níveis de gestão, do elemento de rede até ao negócio necessitam, idealmente, de ser integrados. Existem várias ferramentas e tecnologias disponíveis para realizar a integração de aplicações empresariais. As próprias plataformas integradas de gestão de rede, com as suas ferramentas de desenvolvimento, apresentam a possibilidade de desenvolver novas aplicações, que complementem as suas capacidades. No entanto existe uma distância significativa entre a maior parte das soluções de integração de aplicações empresariais, mais destinadas à integração de aplicações empresariais de suporte ao negócio (exemplo: facturação, CRM, ERP), e o tipo de aplicações passíveis de desenvolver para uma plataforma de gestão, que são aplicações orientadas para a gestão de rede. Para mais, a integração de uma plataforma de gestão com apenas uma ou duas aplicações empresariais não é suficiente. O objectivo é a integração com o maior número possível de aplicações empresariais. A solução que maior recompensa parece oferecer é, assim, a integração da plataforma de gestão com uma solução ou tecnologia de integração. Utilizando essa solução como hub, é possível realizar a integração entre as várias aplicações empresariais já suportadas por essa solução e a plataforma de gestão. 2.3.1 – Java 2 Enterprise Edition A arquitectura J2EE, apresentada pela Sun Microsystems e suportada por grandes nomes da indústria, apresenta um modelo de programação que alivia o programador de tarefas comuns. O programador apenas tem de se concentrar em implementar a lógica de negócio da aplicação, podendo a arquitectura J2EE resolver os problemas de escalabilidade, redundância, gestão de utilizadores, gestão de transacções, gestão de tarefas, partilha de ligações a bases de dados, etc. Em J2EE é utilizado o conceito de container ou servidor aplicacional. Existem containers para EJB (Enterprise Java Beans), Web containers (para servlets e JSP - Gestão de redes 27 Java Server Pages), containers para aplicações cliente, e containers mistos. O programador que desenvolve uma aplicação J2EE, apenas desenvolve componentes que são executados por um container. Para poder prestar todos os serviços referidos anteriormente, a arquitectura J2EE impõe uma série de restrições à implementação dos componentes. Por exemplo, no caso dos EJB, não é possível aceder a ficheiros, criar tarefas, criar sockets ou utilizar JNI (Java Native Interface) para chamar bibliotecas escritas noutras linguagens. Estas limitações restringem o âmbito das aplicações J2EE, dificultando, por exemplo, a comunicação com outros sistemas não baseados em Java ou CORBA. Por forma a ultrapassar esta limitação da arquitectura vários fornecedores de containers oferecem métodos proprietários para estender a funcionalidade dos mesmos, permitindo assim o desenvolvimento de aplicações que não só tomam partido das funcionalidades da arquitectura J2EE mas que também são capazes de comunicar com os sistemas legados existentes nas empresas, tais como ERP, bases de dados que não suportem JDBC (Java Database Connectivity), TP (Transaction Processing) e EIS genéricos. Infelizmente os programas que fazem uso destas funcionalidades não são portáveis. Consciente desta realidade a Sun apresentou uma nova adição à arquitectura J2EE, a JCA, com o objectivo de uniformizar os métodos de acesso a EIS. O JCA permite o desenvolvimento de componentes de software normalizados, utilizados por aplicações J2EE para aceder a sistemas legados, hardware e quaisquer outros sistemas informático anteriormente fora do alcance deste tipo de aplicação. Embora o J2EE não seja especificamente uma solução de integração, mas sim uma norma aberta para plataformas aplicacionais implementadas por vários fabricantes, as capacidades de comunicação inerentes à linguagem Java, acrescidas da disponibilidade de Connectors JCA para um grande número de aplicações empresariais e do serviço de mensagem JMS (Java Message Service), possibilitam o desenvolvimento de aplicações para a integração de processos ou aplicações [51]. Soluções proprietárias de integração, como o Webmethods, começam já a ser suportadas por tecnologia J2EE [52]. A área onde esta tese se insere, a gestão de redes, começa também a ser explorada no Java, existindo já uma norma, Java Management Extensions (JMX), para a gestão de redes e aplicações a partir da plataforma Java [53][54]. Foram também definidos Gestão de redes 28 mapeamentos entre esta arquitectura de gestão e aquelas actualmente em uso, como o SNMP [55]. 2.3.2 – CORBA - Common Object Request Broker Architecture O CORBA, promovido pelo Object Management Group (OMG), é uma arquitectura e infra-estrutura aberta e independente de vendedor, para o desenvolvimento de aplicações distribuídas independentes de linguagem, tecnologia de rede, sistema operativo e arquitectura da máquina utilizada [56]. Inicialmente limitado à invocação de métodos em objectos remotos, o CORBA evoluiu, apresentado hoje um conjunto de serviços normalizado que implementa muitas das tarefas comuns a aplicações distribuídas, tais como serviços de mensagens e serviços de histórico. Tal como o J2EE, o CORBA, nas suas versões mais recentes, suporta o conceito de componentes. Existem vários produtos de integração proprietários que utilizam CORBA na comunicação entre os vários sistemas. No entanto, também é possível utilizar CORBA directamente no desenvolvimento de aplicações que integram vários sistemas, para o que muito contribui a existência de suporte CORBA para várias linguagem de programação. Na área de gestão de redes, o CORBA desempenha um papel importante. Não só é utilizado por muitas plataformas de gestão na comunicação entre os seus componentes, como foi proposta a sua utilização na comunicação entre agentes e gestores, embora o seu sucesso nesta área fosse reduzido devido à inexistência de um modelo de dados [43]. Na versão 3.0, o CORBA passou a suportar uma maior integração com o Java, permitindo a aplicações Java RMI (Remote Method Invocation) aceder directamente a aplicações CORBA e vice-versa. Enquanto tecnologias concorrentes, o Java apresenta a vantagem de permite a portabilidade do código compilado e maior flexibilidade no tipo de dados transmitido. 2.3.3 – Soluções proprietárias O mercado da integração de aplicações empresariais é explorado por um conjunto de firmas que desenvolve os chamados Integration Brokers. Estas aplicações são normalmente suportadas por tecnologias de middleware como CORBA ou J2EE, sendo Gestão de redes 29 por isso também conhecidos por middleware de alto nível. Entre os produtos mais conhecidos encontram-se o Active Enterprise da TIBCO, o BusinessWare da Vitria, o webMethods Integration Platform da webMethods e o WebSphere MQ da IBM (antigo MQSeries Integrator) [57]. Estas aplicações permitem integrar várias aplicações segundo uma arquitectura em estrela, em que cada aplicação comunica com a aplicação de integração e esta com todas as aplicações. Como soluções proprietárias que são, existem diferenças significativas entre cada uma, sendo, no entanto, normalmente baseadas em sistemas de mensagens. São cinco os componentes principais deste tipo de aplicações: interfaces, transformações, distribuição, encaminhamento e gestão. As interfaces, também conhecidos como adaptadores, permitem comunicar com as diferentes aplicações, existindo uma interface para cada aplicação. O conjunto de aplicações suportado directamente pela aplicação de integração, o conjunto de aplicações suportados por adaptadores desenvolvidos por terceiros e a facilidade com que podem ser desenvolvidos novos adaptadores é um dos factores a ter em conta na escolha de uma aplicação de integração. As interfaces são o equivalente aos connectors JCA para a plataforma J2EE. A informação recolhida de uma aplicação não pode ser passada directamente a outra aplicação. Pode ser necessário transformar o formato das mensagens ou agregar dados de várias origens, sendo este o papel desempenhado pelas transformações. Soluções mais avançadas contemplam não só a transformação sintáctica das mensagens mas também a semântica. A distribuição das mensagens pode tomar duas formas, ponto-a-ponto ou difusão. A difusão, embora consuma mais recursos, é particularmente útil quando os mesmos eventos afectam várias aplicações. Uma solução fiável exige que as mensagens não sejam perdidas, mesmo quando as aplicações não estão disponíveis para as receber. O encaminhamento das mensagens entre as aplicações, fluxo de dados, está directamente relacionado com os fluxos de trabalho definidos nos processos de negócios. As aplicações de integração são capazes de determinar quais as aplicações que cada mensagem afecta com base na origem da mensagem e no seu conteúdo. Gestão de redes 30 A gestão das aplicações de integração é particularmente relevante. Estas aplicações tomam um papel central nos sistemas informáticos das organizações, pois todos os processos de negócios dependem delas. É assim importante fornecer ferramentas intuitivas para controlar e monitorizar os fluxos de trabalho. As ferramentas de integração são normalmente fornecidas com interfaces gráficas de desenvolvimento, permitindo acelerar o processo de integração. Estas ferramentas permitem definir graficamente as transformações a aplicar às mensagens e inferir os fluxos de dados a partir dos fluxos de trabalho. Sendo a integração de aplicações um processo complexo, estas ferramentas podem prestar um grande auxílio pois já incorporam os fluxos de trabalho mais comuns, permitindo até servir de base para processos de reengenharia de processos nas empresas. Um estudo da Ovum indica que este tipo de ferramentas permite reduzir os custos de integração em um terço e os de manutenção em dois terços [58]. Gestão de redes 31 2.4 – Sumário A gestão eficiente de uma rede só é possível extraindo informação de gestão de todos os elementos da rede. Esta tarefa é complicada pela existência, na mesma rede, de equipamento de diferentes fabricantes, comprados ao longo do tempo. Além disso, um único problema, como o corte de um cabo, pode fazer com que vários equipamentos sejam afectados, resultando numa série de alarmes distintos. Em cenários complexos, os sistemas periciais prestam uma grande ajuda, ao apontar a causa raiz, poupando aos operadores de rede o trabalho de analisar todos os alarmes. No entanto, todos estes sistemas de gestão de rede limitam-se ao nível de rede, e eventualmente a partes do nível de serviço, não abarcando informação dos níveis superiores da pirâmide de gestão. Uma gestão mais eficiente requer a integração com as aplicações utilizadas para a gestão de negócio, devendo os diversos níveis ser integrados. Mesmo ao nível de rede, existem dificuldades a ultrapassar. Embora existam plataformas de gestão capazes de comunicar com equipamentos de diversos fabricante, estas nem sempre permitem utilizar todas as funcionalidades ou aceder a toda a informação disponibilizada por esses equipamentos. A configuração de opções mais avançadas requer muitas vezes a utilização de software proprietário, fornecido pelo fabricante do equipamento. Também ao nível da gestão de rede é desejável realizar a integração entre as diversas ferramentas de gestão utilizadas. Ferramentas isoladas como ferramentas de gestão de inventário, gestão de nível de serviço, e outras, devem ser integradas com as restantes, de forma a automatizar os fluxos de processos definidos pelo TMForum no TOM. O processo como a integração é realizada e quais as prioridades e necessidades reais de integração são características únicas de cada organização. A própria informação a transportar entre os vários processos depende da natureza de cada organização e das aplicações já em uso. Isto faz com que a integração de aplicações seja uma tarefa complexa, dispendiosa e que requer muitos recursos humanos. Nesta tese é apresentado um connector JCA para a plataforma integrada de gestão de rede TeMIP. A tecnologia J2EE foi escolhida porque é independente de fabricante, flexível e oferece as vantagens da linguagem Java. A existência de connectors JCA para Gestão de redes 32 muitas das aplicações empresariais mais conhecidas, e o elevado ritmo a que surgem connectors para outras aplicações, permite o desenvolvimento de aplicações que integrem a gestão ao nível de rede, efectuada pelo TeMIP, com a gestão ao nível de serviço e de negócio, parte dela já efectuada pelas diversas aplicações empresariais utilizadas pelos operadores de telecomunicações. O desenvolvimento de uma aplicação J2EE para realizar a integração de vários sistemas pode parecer uma operação demasiado complexa à primeira vista. No entanto, é irrealista assumir que cenários complexos de integração podem ser realizadas sem o desenvolvimento de código. Além disso, o suporte J2EE oferecido por muitas das soluções proprietárias de integração de sistemas, permite conjugá-las com este connector. A título de exemplo, refira-se que a passagem da gestão ao nível de rede para o nível de serviço requer o uso de informação sobre clientes (facturação e SLAs). Esta informação não está disponível numa plataforma de gestão de rede como o TeMIP, mas sim em sistemas dedicados como por exemplo um sistema de ERP ou directório LDAP. A conjugação desta informação pode permitir, por exemplo, dados vários clientes com serviços afectados, escolher qual o primeiro cliente a atender segundo o montante facturado a cada cliente, o montante em dívida pelo cliente ou a gravidade da violação de serviço. Como caso de estudo da viabilidade do uso do connector para atingir o nível de serviço através de integração de aplicações, é apresentado no Capítulo 6 uma aplicação que integra a informação de rede fornecida pelo TeMIP com informação sobre os utilizadores recolhida de um directório LDAP. Tecnologias utilizadas 33 Capítulo 3 – Tecnologias utilizadas Este capítulo foca as tecnologias utilizadas. Estas tecnologias já foram apresentadas, embora superficialmente no capítulo anterior. A primeira secção apresenta a Plataforma de Gestão Integrada TeMIP, e a API utilizada para interagir com o TeMIP, a TeMIP Access Library (TAL). A plataforma Java 2, na sua versão Standard Edition, é discutida na secção três. Aí são analisadas em maior detalhe as tecnologias utilizadas especificamente neste projecto. A terceira secção aborda as componentes do Java 2 Enterprise Edition que foram utilizadas. Este capítulo termina com uma secção dedicada à Java Connector Architecture, parte integrante do Java 2 Enterprise Edition 1.3, que merece um destaque especial devido ao papel que desempenha neste trabalho. Tecnologias utilizadas 34 3.1 – TeMIP O Telecommunications Management Information Platform (TeMIP) é uma Plataforma Integrada de Gestão de Rede, desenvolvida e comercializada pela HP. O TeMIP foi originalmente criado pela Digital Equipment Corporation (DEC), a qual foi posteriormente comprada pela Compaq, que por sua vez foi recentemente adquirida pela HP [59]. O mercado do TeMIP é constituído em grande parte por operadores de telecomunicações, sendo particularmente orientado para a gestão de redes de grandes dimensões. É actualmente utilizado por oito dos dez maiores operadores internacionais de telecomunicações [60]. O TeMIP teve a sua génese na arquitectura de gestão OSI, pelo que o seu funcionamento está fortemente baseado em eventos. Esta plataforma de gestão integrada adopta os princípios da arquitectura cliente-servidor e, tendo sido desenvolvido pela DEC, existem apenas versões para UNIX. Foi recentemente apresentada uma versão do software cliente para Microsoft Windows. A nomenclatura utilizada pelo fabricante atribui a uma instância do produto TeMIP o nome de Director TeMIP. A Figura 7 ilustra o modelo de gestão utilizado. Figura 7 – Visão conceptual do modelo de gestão empregado no TeMIP Estruturalmente, um Director TeMIP divide-se em três módulos distintos, Form, Function e Access, que comunicam entre si através de Interfaces de Gestão. O módulo Form é responsável pelas funções de apresentação da informação de gestão ao Tecnologias utilizadas 35 utilizador, designando-se também por módulo de Apresentação (Presentation Module – PM). O módulo Function realiza as funções de gestão, quer sejam as aplicações básicas, quer sejam aplicações mais complexas. Por último, o módulo Access é responsável por fornecer o acesso a entidades TeMIP, suportadas em diferentes tecnologias de rede. O módulo Access fornece o acesso a entidades que suportem as arquitecturas de gestão OSI, SNMP, CORBA e interfaces ASCII, fornecendo ao TeMIP uma grande flexibilidade. No âmbito deste trabalho apenas são apenas utilizadas entidades SNMP, pois este é o protocolo de gestão disponibilizado pelos equipamentos geridos na rede de testes. No entanto, nada no projecto realizado impede a sua utilização na gestão de entidades de outro tipo, desde que devidamente suportadas pelo TeMIP. O módulo Function engloba as aplicações de gestão propriamente ditas. São estas a gestão de eventos e de alarmes, cooperação na resolução de problemas (Trouble Ticketing), testes periódicos de acessibilidade (polling), organização lógica da rede através da construção de domínios de gestão, e outras aplicações incluídas no TeMIP ou disponíveis como módulos opcionais. No módulo Form as aplicações mais relevantes são o Iconic Map, uma interface gráfica que funciona em X-Windows, e o FCL (Framework Command Line), uma interface de linha de comando [61]. Uma entidade TeMIP é constituída pelo agente e pelos objectos geridos, pelos quais o agente é responsável. O agente funciona como intermediário, sinalizando a ocorrência de eventos e respondendo a directivas de gestão sobre os objectos geridos. Em sistemas de pequena e média complexidade existe um único Director TeMIP, com um ou mais clientes a executarem diferentes módulos de acesso ou de apresentação. Porém, em sistemas complexos, pode existir uma arquitectura distribuída, com vários Directores TeMIP a gerirem redes diferentes ou a partilharem a gestão da mesma rede em configurações de distribuição de carga ou alta disponibilidade. 3.1.1 – Capacidades de Integração O TeMIP foi desenhado para ser fácil integrar nele todo o tipo de elementos de rede, mas a flexibilidade para a interligação com outras aplicações é menor. No âmbito deste projecto foi necessário escolher uma forma de interacção com o TeMIP que permitisse Tecnologias utilizadas 36 não só extrair informação deste, mas também emitir ordens que modificassem o estado dos elementos geridos. O método a escolher deveria estar disponível numa instalação típica do TeMIP e não poderia limitar a funcionalidade oferecida. Uma análise à plataforma revelou as seguintes interfaces disponíveis para extrair informação: Interface gráfica X-Windows: Esta interface é o principal meio de interagir com o TeMIP. É uma interface desenhada para humanos, seria muito difícil desenhar software para comunicar com ela. VisualTeMIP: É um conjunto de classes C++ que permitem o desenvolvimento de módulos de software que correm dentro da plataforma TeMIP. Este seria um caminho viável, não fosse o facto de ser uma interface antiga e extremamente complexa, que requer vastos conhecimentos da arquitectura interna da plataforma TeMIP. Embora o nome VisualTeMIP sugira a existência de um ambiente de desenvolvimento gráfico fácil de utilizar, tal não se verifica [62]. Interface gráfica Microsoft Windows: Mais uma vez é uma interface desenhada para humanos, não sendo fácil interagir com ela. No entanto, para construir esta interface a Compaq desenhou um serviço CORBA, no qual esta interface assenta. Os serviços CORBA correm na máquina Alpha onde o TeMIP corre, e a interface gráfica para Microsoft Windows funciona como cliente. Infelizmente a Compaq não dispõe de documentação sobre esta interface CORBA, pelo que a sua utilização não é viável. A Compaq disponibiliza sim um conjunto de DLLs (Dynamic Link Library), a que chama Remote TAL, que permitem o desenvolvimento de aplicações Win32 que utilizam transparentemente o serviço CORBA. Esta interface não foi a escolhida, quer porque restringia a utilização do connector à plataforma Windows, quer ainda pelo facto da funcionalidade proporcionada pelo Remote TAL ser um subconjunto daquela proporcionada pelo Local TAL. TeMIP Access Library: Consiste num conjunto de classes C++ que permite o desenvolvimento de aplicações que comunicam com o TeMIP [63][64]. É um produto posterior às primeiras versões do TeMIP, que não pretende substituir o VisualTeMIP, mas apenas complementá-lo nesta área de aplicações de apresentação. A sua grande vantagem é esconder muitos dos mecanismos internos do TeMIP, possibilitando o desenvolvimento de aplicações de apresentação sem ser necessário conhecimento dos Tecnologias utilizadas 37 detalhes mais ínfimos da arquitectura interna do TeMIP. O TAL foi a ferramenta escolhida para o desenvolvimento do connector, sendo apresentado em maior detalhe na próxima secção. Interface ASCII: Consiste num programa em modo de texto (FCL) que permite uma utilização interactiva ou em batch, recebendo para isso os comandos TeMIP como parâmetros de linha de comando. Embora seja trabalhoso implementar a interacção para todos os comando TeMIP disponíveis, seria viável a implementação do parsing do output desta interface para um subconjunto limitado de comandos. 3.1.2 – TAL - TeMIP Access Library A TAL é uma biblioteca C++ que permite a construção de aplicações de apresentação, destinadas a disponibilizar o acesso ao TeMIP a humanos ou outras aplicações. Estas aplicações interagem com o TeMIP através de uma colecção de classes que representam as entidades manipuláveis pelo TeMIP. O TAL foi inicialmente criado para permitir o desenvolvimento de uma interface gráfica para Microsoft Windows, pois anteriormente a única interface gráfica existente era para X-Windows. Esta API foi construída em cima do Visual TeMIP, uma API mais flexível que permite expandir as funcionalidades do TeMIP, para além de possibilitar o desenvolvimento de aplicações de apresentação. O TAL não exige, no entanto, o conhecimento detalhado dos mecanismos e estruturas internas do TeMIP exigido pelo Visual TeMIP. O TAL existe em duas versões: Local TAL, destinado a ser utilizado por aplicações que correm na mesma máquina Unix que o TeMIP; Remote TAL, que permite o desenvolvimento de aplicações de apresentação em ambientes Microsoft Windows. Nesta tese foi utilizada o Local TAL de forma a não limitar a escolha de Sistema Operativo onde as aplicações podiam correr. A arquitectura desenvolvida, apresentada no Capítulo 4, permite que as aplicações clientes acedam ao TeMIP de qualquer Sistema Operativo que suporte Java. Embora fosse possível atingir os mesmos objectivos recorrendo ao Remote TAL, esta opção implicaria o uso obrigatório de mais uma máquina a correr Windows, sem que daí adviessem quaisquer vantagens. O TAL foi desenvolvido com o objectivo de facilitar a criação de interfaces gráficas, sendo que o Local TAL está pensado para ser utilizado com X-Windows enquanto que o Remote TAL está pensado para ser utilizado com Microsoft Windows. Assim, tal como Tecnologias utilizadas 38 estes ambientes gráficos, o TAL baseia-se num sistema de eventos, destinados a provocar o redesenho das janelas assim que a informação solicitada esteja disponível. É o sistema de eventos do ambiente gráfico que proporciona ao TAL um meio de notificar os clientes que os pedidos efectuados já foram satisfeitos. O uso do TAL num ambiente não gráfico, como é o caso da aplicação a desenvolver, requer a criação de uma tarefa dedicada ao TAL. Essa tarefa chama a função TalMainLoop(), ficando bloqueada nessa função, que fornecerá ao TAL os recursos necessários para notificar o cliente da conclusão do processamento dos pedidos. São dois os modos disponibilizados pelo TAL para a realização de interrogações: modo síncrono e assíncrono. O modo síncrono é normalmente utilizado para consultar o estado de uma entidade ou executar comandos com vista à alteração do estado das mesmas. Como o seu nome indica, este modo caracteriza-se pelo facto da tarefa que efectua um pedido ficar bloqueada na execução desse método. A resposta será retornada pelo método chamado. No modo assíncrono o método chamado para executar o pedido retorna imediatamente, ficando a tarefa livre para realizar outro trabalho. As respostas são posteriormente entregues pela biblioteca TAL através da execução de uma função de callback, definida pela aplicação cliente. Embora possa ser utilizado para os mesmos fim que o modo síncrono, este modo é o único que permite a notificação assíncrona da ocorrência de eventos. Assim, é normalmente utilizado para permitir às aplicações serem notificadas da ocorrência de alarmes ou da modificação do estado de determinada entidade. Os comandos a executar são transmitidos à biblioteca TAL através de uma linguagem proprietária do TeMIP. Esta linguagem não está restrita ao TAL, sendo também utilizada, por exemplo, na interface de linha de comando, a FCL. As respostas produzidas pelo TAL podem ser consultadas de duas formas: utilizando um conjunto de classes que descrevem as entidades ou através de uma representação em texto. Todas as classes que descrevem entidades permitem a transposição da informação que contêm para texto. Tecnologias utilizadas 39 3.2 – J2SE - Java 2 Standard Edition Java é o nome de uma linguagem de programação orientada por objectos apresentada ao público pela Sun Microsystems em 1995 [65]. Mas Java não é apenas uma linguagem, é um sistema operativo virtual, uma plataforma comum de serviços que permite às aplicações escritas em Java correrem um múltiplos sistemas operativos. As aplicações escritas em Java não são compiladas para código nativo de uma determinada plataforma, mas é criada uma representação intermédia, independente de plataforma. Este código intermédio, denominado bytecode, destina-se a correr numa máquina de pilha (stack machine). O código intermédio é normalmente executado por software, denominado máquina virtual Java (Java Virtual Machine - JVM). As primeiras JVM limitavam-se a interpretar o código intermédio, mas as mais recentes são capazes de realizar uma compilação incremental para código nativo da plataforma em que correm. Esta tecnologia, conhecida por Just In Time Compilation (JIT), permitiu aumentar significativamente o desempenho das aplicações Java, anteriormente apontado como uma das maiores limitações da linguagem. Ultimamente são alvo de intensa pesquisa as implementações em hardware de JVM [66]. O Java é hoje aquilo a que se poderia chamar uma evolução de uma revolução. Revolução pois foi o produto principal do trabalho de um grupo de 13 pessoas, denominado “Green Team”, que decidiu quebrar com a tradição e mentalidade instituída na Sun. Descontentes com os produtos e orientação estratégica da empresa, em 1990 este grupo consegui autorização para desenvolver e pesquisar as “tecnologias informáticas do futuro”, saltando por cima de duas gerações de tecnologia: o mundo dos grandes servidores Unix centralizados, personificado pela Sun, e o mundo dos PCs, no qual o domínio da Microsoft era já poderoso demais para ser combatido [67]. Trabalhando em segredo e isolados do resto da Sun, a equipa concentrou o seu trabalho em interfaces homem máquina adaptados aos novos produtos que acreditavam iriam surgir da fusão entre a informática e a electrónica de consumo. Evolução pois a plataforma Java tem sofrido grandes e continuas alterações desde o seu lançamento publico em 1995. Inicialmente lançado como uma linguagem para a criação Tecnologias utilizadas 40 de páginas Web dinâmicas, o Java evoluiu para uma linguagem presente em múltiplos campos, desde os pequenos aparelhos de electrónica de consumo, como os telemóveis, até às grandes aplicações empresariais críticas, a correr em computadores de grande porte. Os produtos comerciais resultantes do esforço do “Green Team” foram a linguagem Java, criada por James Gosling, e o HotJava. HotJava era um Web Browser com a capacidade de correr aplicações Java como objectos de uma página HTML (Hyper Text Markup Language). Foi a primeira aplicação da linguagem, escolhida numa altura em que a World Wide Web se começava a implantar e prometia abarcar todo o futuro da indústria informática [68]. A quase imediata aceitação e integração da tecnologia do HotJava pela Netscape, que na altura dominava o mercado dos Web browsers, auguraram um futuro promissor para o Java como “a linguagem da net”. No entanto, a conquista de quota de mercado pelo Internet Explorer da Microsoft, que vê o Java como uma tecnologia concorrente aos seus próprios produtos, fez com que o Java não obtivesse o protagonismo esperado na World Wide Web. A evolução do Java deu origem a quatro plataformas distintas: Java Card [69], Java 2 Platform Micro Edition (J2ME) [70], Java 2 Platform Standard Edition (J2SE) [71] e Java 2 Platform Enterprise Edition [72]. O Java Card é um conjunto de APIs destinado a ser utilizado em cartões inteligentes, possibilitando a criação de programas que residem e correm em cartões com a dimensão de um vulgar cartão de crédito. A Java 2 Platform Micro Edition especifica o ambiente a fornecer por pequenos aparelhos sendo menos abrangente que as outras duas edições do Java 2 Platform. Esta versão destina-se a electrónica de consumo, tendo neste momento maior projecção no mercado dos telefones móveis e handhelds. Muitos dos mais recentes telefones móveis estão equipados com Java 2 Platform Micro Edition e os operadores móveis apostam nos jogos Java como uma fonte de rendimentos a curto prazo. As diferenças entre esta versão e a Standard Edition reflectem-se não só nas APIs disponibilizadas mas também na própria linguagem Java, que sofreu modificações, como a remoção de números reais, de modo a poder ser executada nos recursos limitados dos aparelhos de electrónica de consumo. Tecnologias utilizadas 41 A Java 2 Platform Standard Edition é a versão destinada a computadores com capacidade de processamento “razoável”. Existem versões para vários sistemas operativos (Windows, Linux, Solaris, Tru64, AS/400, Mac OS X, etc.) e plataformas, desde PCs a mainframe. Esta versão fornece às aplicações Java um ambiente virtual muito completo, compreendendo, entre outras, APIs para o uso de: interfaces de utilizador gráficas, aplicações gráficas em 2D, som, Internet (TCP, UDP, HTTP, FTP – File Transfer Protocol, etc.), CORBA e bases de dados. A versão Java 2 Enterprise Edition é apresentada na próxima secção. Esta é composta por um conjunto de tecnologias destinadas a simplificar o desenvolvimento de aplicações empresariais, ao automatizar e sistematizar um conjunto de tarefas comuns à maior parte das aplicações empresariais. A Figura 8, retirada de [73], apresenta os vários componentes do J2SE, na sua versão 1.3, aquela utilizada neste trabalho. A plataforma divide-se em duas partes: Java Runtime Environment (JRE) e Software Development Kit (SDK). A primeira é basicamente constituída pela máquina virtual Java, capaz de executar as aplicações Java representadas em bytecode, e pela implementação de um conjunto de APIs definidas na especificação. O SDK, que engloba o JRE, é constituído por ferramentas de desenvolvimento, como o compilador (Java Compiler - javac) e a ferramenta de depuração (Java Debugger - jdb). Figura 8 – Componentes do Java 2 Platform Standard Edition [73] De entre as muitas APIs definidas na versão 1.3 do J2SE destacam-se duas utilizadas neste trabalho: o RMI, que permite a invocação de métodos em objectos presentes Tecnologias utilizadas 42 noutras máquinas, através da rede; o JNI, que permite a utilização de código escrito noutras linguagem. Estas duas tecnologias serão apresentadas em separado nesta secção. A Sun tem desenvolvido um grande esforço de marketing para promover a linguagem Java. Como forma de criar novos mercados e obter apoios de outras empresas a Sun abriu mão do controlo total da linguagem ao criar o chamado Java Community Process (JCP) através do qual as várias normas são desenvolvidas por um conjunto de empresas interessadas nas tecnologias. O carácter cada vez mais aberto das normas faz com a linguagem seja adoptada por empresas e programadores que querem evitar soluções proprietárias fechadas. No entanto, o sucesso do Java não teria sido possível sem as características da linguagem em si, que são responsáveis pela ampla aceitação que esta linguagem tem junto dos programadores e arquitectos de software. A linguagem Java é simples, é orientada por objectos, apresenta uma ênfase na Internet, é robusta, é segura, é interpretada, apresenta neutralidade arquitectural, é portável, tem alto desempenho, é multitarefa e é dinâmica [74]. A linguagem Java é simples pois apresenta uma sintaxe semelhante à do C/C++ fazendo com que muitos programadores se sintam rapidamente à vontade com a linguagem. Com o propósito de simplificar a linguagem, não foram adoptadas algumas das funcionalidades do C/C++ consideradas mais complexas e pouco utilizadas, tais como herança múltipla e redefinição de operadores. A ênfase dada às redes de computadores, em particular à Internet, está patente no conjunto de protocolos suportados pelas bibliotecas standard de Java, entre os quais se destacam: TCP, UDP, HTTP e FTP. A robustez da linguagem está presente a vários níveis. Devido a ser uma linguagem fortemente tipificada, o Java permite identificar muitos erros em tempo de compilação, erros estes que podem ser novamente verificados pelo interpretador aquando da ligação (linker) ou execução. O Java evita alguns dos erros de programação mais frequentes ao não permitir: o uso de ponteiros, o acesso fora dos limites de um vector e a libertação explícita de memória. A memória é libertada por um garbage collector que é executado concorrentemente (dependendo da JVM) com a aplicação. O sistema de excepções permite limitar e controlar o impacto de situações de erro. Tecnologias utilizadas 43 Devido ao ambiente distribuído para o qual a linguagem foi idealizada, o Java apresenta uma grande preocupação com a segurança. As aplicações são executadas separadamente, não podendo interferir umas com as outras, nem efectuar operações para as quais não estão autorizadas. O modelo de permissões do Java permite limitar as operações e dados a que cada aplicação tem acesso, permitindo, por exemplo, que seja seguro correr num browser uma aplicação retirada da Internet sem prejuízo para o utilizador. O código Java não é compilado para nenhuma arquitectura em particular, mas sim para uma máquina virtual de pilha. A arquitectura desta é suficientemente simples para que o código compilado possa ser interpretado na maioria das plataformas actuais. Esta neutralidade arquitectural, conjugada com o desenho da linguagem, permite que as aplicações Java sejam portáveis. A linguagem evita dependências arquitecturais, por exemplo, definindo um tamanho fixo para os tipos de dados (um inteiro é sempre 32 bit, representado em complemento para dois e com sinal) ao contrário de outras linguagem, como o C/C++, onde a representação dos tipos de dados depende da arquitectura. Embora as primeiras implementações de JVM se limitassem a interpretar os bytecode, as versões actuais são capazes de realizar uma compilação incremental para código nativo (JIT), apresentando assim um desempenho comparável aos das aplicações escritas em linguagens compiladas e muito superior aos de outras linguagens interpretadas. O suporte para aplicações multitarefa está patente não só no suporte nativo para execução concorrente de tarefas mas também nas primitivas de sincronização disponíveis, parte delas integradas na própria sintaxe da linguagem. O Java apresenta-se como uma linguagem dinâmica devido essencialmente a dois pontos: a reflexão e o modo como as classes são carregadas. O mecanismo de reflexão permite a análise e utilização de classes desconhecidas até à execução do programa. Isto apenas é possível devido ao facto das classes apenas serem ligadas em tempo de execução, quando do seu carregamento. Este apenas acontece imediatamente antes das classes serem necessárias e não quando o programa é iniciado. Outras linguagens executam o processo de ligação aquando da compilação e necessitam de carregar todas as classes ou bibliotecas no início da execução do programa. Tecnologias utilizadas 44 3.2.1 – JNI - Java Native Interface Com o fim de abranger um domínio de utilizações o mais vasto possível, o Java incluiu desde cedo a possibilidade de recorrer a bibliotecas C/C++. Esta facilidade possibilita a programas Java interagir com sistemas legados e recorrer a funcionalidades especificas de determinado sistema operativo, e que por isso não estão incluídas na linguagem devido à sua neutralidade. Esta tecnologia é recomendada pelos criadores da linguagem Java para a realização da ponte entre programas Java e aplicações legadas em sistemas duas e três camadas (tier), tal como acontece nesta tese [75]. O JNI é constituído por uma API, disponível em C e C++ e por um compilador [76]. Uma classe pode declarar métodos nativos, cuja invocação resulta na execução do código nativo. O compilador fornecido (javah) permite, a partir da classe Java, criar os ficheiros de definição (.h) da biblioteca C/C++, fornecendo um ponto de partida para o seu desenvolvimento. É da responsabilidade do programa Java solicitar o carregamento da biblioteca C/C++ ligada dinamicamente onde os métodos nativos estão implementados. A implementação em C/C++ pode recorrer às API disponíveis para proceder ao tratamento e criação de excepções, criar e apagar objectos Java, invocar métodos em objectos Java e realizar conversões entre tipos de dados de C/C++ e Java. O JNI especifica ainda o mapeamento realizado entre os tipos primitivos de Java e C/C++. A utilização de JNI num programa Java inibe a sua portabilidade, ficando a execução desse programa restrita às plataformas onde a biblioteca nativa ligada dinamicamente é suportada. Apesar disso, o sistema de carregamento de bibliotecas é independente de sistema operativo, possibilitando que um programa seja fornecido com várias implementações das bibliotecas nativas, sendo automaticamente escolhida a do sistema operativo onde o programa Java é corrido. O JNI permite a aplicações Java executar código nativo. No entanto, apenas em Microsoft Windows é possível a código nativo tomar a iniciativa de executar código Java, quer através do lançamento de uma JVM ou através da associação a uma já em execução. Tecnologias utilizadas 45 A forma como o JNI foi integrado na linguagem Java não limita o seu uso a código nativo implementado em C/C++. O JNI foi desenhado de forma a poder ser expandido a outras linguagens. No entanto, tal nunca aconteceu, talvez por não haver demanda suficiente para efectuar tal expansão. 3.2.2 – RMI - Remote Method Invocation As redes de computadores e os sistemas distribuídos tiveram grande ênfase na criação da linguagem Java. Assim, esta inclui de raiz suporte para a invocação remota de métodos em objectos. Esta tecnologia destaca-se devido a outra característica da linguagem Java, a portabilidade do código compilado (bytecode). O RMI permite não só a criação de um modelo cliente/servidor onde o cliente pode invocar métodos em objectos residentes no servidor, mas também a passagem de objectos desconhecidos ao cliente ou servidor [76][77]. O RMI tenta manter uma semântica idêntica à da linguagem Java. Os tipos primitivos da linguagem são passados por valor, e os objectos remotos são passados por referência. As referências para os objectos remotos são diferentes das referências normais para um objecto local, sendo constituídas por um objecto (stub) que ao ser utilizado efectua a comunicação com o objecto remoto. A diferença semântica entre a linguagem Java normal e a utilização de RMI prende-se com os objectos locais não primitivos. Normalmente estes seriam passados por referência, no entanto como o cliente e o servidor correm em JVM distintas, são passados por valor, sendo executada uma cópia do objecto. O processo de cópia é realizado transformando o objecto, ou grafo de objectos, numa representação passível de ser transmitida pela rede (serialização) e executando a respectiva reconstrução do outro lado (de-serialização). Também a gestão de memória funciona de forma distribuída, existindo um garbage collector distribuído responsável por libertar objectos que já não são referenciados pelos clientes. Devido à natureza de um sistema distribuído, no qual as partes comunicam através de uma rede de comunicação falível, este garbage collector funciona segundo uma filosofia de melhor esforço, sendo possível que objectos remotos sejam reclamados antes do tempo. Assim as aplicações que trabalham com objectos remotos são obrigadas a oferecer um tratamento para este tipo de situações. Tecnologias utilizadas 46 É possível ao cliente ou ao Servidor RMI passar como parâmetro ou valor de retorno de um método um objecto de uma classe desconhecida pela outra parte. Esta classe deve estar disponível para download de forma a permitir à outra entidade obtê-la. Cada entidade, seja ela o servidor ou cliente, deve indicar a localização dos ficheiros correspondentes às classes desconhecidas da outra entidade. Estes podem ser disponibilizadas por HTTP, FTP ou simplesmente colocadas num sistema de ficheiros a que a outra entidade tenha acesso. Este modelo permite não só passar dados entre sistemas remotos mas também comportamento. Os clientes localizam os servidores através de sistemas de directório. O J2SE inclui um serviço de directório básico (rmiregistry), que pode ser lançado como uma aplicação independente ou como parte de uma aplicação Java. No entanto, podem ser utilizados outros serviços de directório mais sofisticados, tais como o incluído no J2EE. As versões mais recentes do J2SE (1.3 e 1.4) permitem também a utilização de CORBA. Nestas versões o protocolo de transporte proprietário utilizado pelo RMI pode ser substituído pelo protocolo utilizado pelo CORBA: o IIOP (Internet Inter ORB Protocol). Tecnologias utilizadas 47 3.3 – J2EE - Java 2 Enterprise Edition O J2EE é constituído por um conjunto de especificações produzidas pela Sun Microsystems e seus parceiros, pretendendo ser a plataforma de eleição para o desenvolvimento de aplicações empresariais. O J2EE aposta na automatização das tarefas comuns aos vários tipos de aplicações empresariais através de uma arquitectura que apresenta suporte para vários tipos de componentes, nos quais as aplicações devem ser divididas. A especificação, cujos componentes da versão 1.3 (utilizada neste trabalho) são apresentados na Figura 9, inclui tecnologias para o desenvolvimento de interfaces, modelação de dados/comportamento e interacção com outros sistemas. Figura 9 – Componentes do Java 2 Enterprise Edition [78] O J2EE permite o desenvolvimento de interfaces Web através de duas tecnologias para a criação de conteúdos Web dinâmicos: os servlets e os Java Server Pages (JSP). Podem ainda ser criadas interfaces gráficas desenvolvendo aplicações Java standalone ou destinadas a ser executadas num browser (applets). Os muito em voga Web Services podem também ser criados para permitir o acesso remoto às aplicações. No entanto, os componentes que modelam comportamento, os EJB, já permitem o acesso remoto. Os componentes que representam os objectos e a lógica de negócio são implementados sobre a forma de EJB. Estes componentes, apresentados nesta secção, libertam o programador das tarefas comuns às várias aplicações empresariais: gestão de persistência, gestão de transacções, segurança, autenticação, autorização, alta disponibilidade, redundância e pooling e partilha de recursos. Os EJB permitem Tecnologias utilizadas 48 declarar, em ficheiros XML independentes do código Java da implementação, os requisitos desejados para os componentes, ficando a cargo do servidor J2EE implementar estas funcionalidades. Estes requisitos podem variar para o mesmo código Java, permitindo que os mesmos componentes sejam reutilizados em cenários distintos. Características como a segurança e transacções podem ser partilhadas com componentes servlet ou JSP, ou uma base de dados, abrangendo assim toda uma aplicação. Existe ainda um tipo especial de EJB destinado ao processamento de eventos assíncronos, recebidos sobre a forma de mensagens. Estas mensagens são transmitidas através do JMS e o seu processamento também pode ser incluído em transacções. O J2EE inclui ainda meios de acesso directo a outros sistemas. Estes incluem o JCA, descrito neste capítulo, e ainda tecnologias de acesso a email (JavaMail), sistemas CORBA, serviços de directório (Java Naming and Directory Interface - JNDI), XML (Extensible Markup Language) e bases de dados (JDBC). Como prova de conceito a Sun produz a implementação de referência da especificação, denominada J2EE Reference Implementation, que apenas pode ser utilizada para fins não comerciais. Os vários parceiros envolvidos no processo de definição do J2EE concorrem entre si na comercialização das suas próprias implementações das especificações, às quais adicionam funcionalidades próprias tais como características de alta disponibilidade ou melhorias de desempenho. Entre estes encontram-se a IBM, BEA, Oracle, Sun, Sybase, Macromedia e muitos outros produtores de software menos conhecidos. As aplicações que se cingem às funcionalidades J2EE podem ser executadas em qualquer um destes servidores, libertando assim o programador/utilizador da dependência de uma solução específica. O J2EE é uma especificação muito completa, que tenta englobar tecnologias a serem utilizadas em diversos cenários. Não se pretende nesta secção cobrir todo o espectro de tecnologias, mas apenas apresentar as mais relevantes no contexto deste trabalho. A norma Java Connector Architecture, embora seja parte constituinte do J2EE, é apresentada à parte na próxima secção devido à sua especial relevância no âmbito deste trabalho. Nesta secção são apresentadas as duas tecnologias destinadas à criação de conteúdos Web dinâmicos (Java Servlets e Java Server Pages) assim como a destinada à modelação de entidades e sua manipulação (Enterprise Java Beans). Tecnologias utilizadas 49 3.3.1 – Java Servlets Quando foi criada, a World Wide Web pretendia ser apenas um repositório de informação estática. Os primeiros servidores HTTP que surgiram apenas permitiam a entrega de conteúdos estáticos. A WWW que conhecemos hoje é rica em conteúdo dinâmico e as aplicações hoje disponíveis só foram possíveis graças ao aparecimento de arquitecturas que permitem a extensão dos servidores HTTP, umas proprietárias e outras normalizadas. Os Java Server Pages representam a especificação mais recente destas arquitecturas, e pretendem fornecer uma solução normalizada simples mas eficaz para o problema da criação dinâmica de conteúdos [79][80]. Os JSP são baseados em servlets, tecnologia que já tinha dado provas, e já possuia alguma implantação no mercado [81]. A crescente adopção da Internet a nível mundial chamou a atenção a muitas empresas, que estão a tentar transpor para lá os seus processos de negócio. Este tipo de aplicações é muito mais complexo que as simples aplicações que tornaram a WWW popular, tais como jogos ou os primeiros motores de pesquisa. Problemas como a escalabilidade da solução, a portabilidade, a integração com as aplicações já existentes que suportam a lógica do negócio, a gestão do conteúdo e a necessidade de separar claramente a apresentação da lógica da aplicação, tornam muitas das soluções já existentes inadequadas para este tipo de aplicações. Os JSP/servlets estão bem posicionados para dar resposta a estas questões devido à sua integração na plataforma J2EE, que lhe empresta a capacidade de comunicação com vários tipos de aplicações e dados, o paradigma de programação orientado a objectos, o mecanismo de excepções para tratamento de erros, e a portabilidade do código, entre outras vantagens. Acima de tudo, o Java e os JSP/servlets, são arquitecturas abertas, que gozam do suporte de grandes nomes da indústria, como a Sun e a IBM entre muitos outros, assim como a atenção da comunidade open-souce [82], como é o caso da Apache Software Foundation, que é responsável pela implementação de referencia dos JSP/servlets [83]. Actualmente na versão 2.3, os servlets são a solução da Sun e parceiros para a criação de aplicações Web. Fazem parte da especificação J2EE, mas podem ser criadas implementações de servlet containers separadas, sem implementar todo o J2EE, pelo que é de esperar que sejam implementados por muitos vendedores de software. Um servlet não é mais que uma classe Java que estende a interface servlet e é executada dentro do ambiente fornecido por um servlet container (também conhecido por servlet Tecnologias utilizadas 50 engine). A arquitectura típica de um servidor HTTP com suporte para servlets é descrita na Figura 10. Cliente Dados Logica aplicacional JDBC Beans Cliente HTTP Servidor HTTP JavaMail Servlets Servlet engine Documento simples JNDI RMI EJB EJB EJB IIOP Enterprise Java Beans container Base de dados Servidor Email Servico de directorio Aplicação Java Aplicação com suporte CORBA Figura 10 – Arquitectura de uma solução assente em servlets Sendo uma classe Java, os servlets dão acesso à propriedade “escrever uma vez, correr em todo o lado” desta linguagem. Aliada ao facto de já existem servlet engines para todos os grandes servidores HTTP, esta propriedade faz dos servlets a primeira solução verdadeiramente multi-plataforma. Um servlet engine pode existir sozinho, caso em que inclui um servidor HTTP, ou como extensão de um servidor HTTP já existente. Em ambos os casos, o servidor é instruído que certos pedidos devem ser entregues a determinados servlets e não tratados como os ficheiros normais. A técnica de mapeamento mais comum consiste em atribuir a cada servlet o nome de um directório, sendo todos os pedidos a esse directório entregues ao servlet. É ainda possível utilizar técnicas mais sofisticadas, como detecção de padrões dentro do nome do ficheiro pedido, por exemplo todos os ficheiros com determinada extensão, para decidir qual o servlet ao qual o pedido deve ser passado. O uso de servlets confere à aplicação um maior desempenho, quando comparada com, por exemplo, os Common Gateway Interface (CGI) [84]. Esta afirmação pode parecer pouco credível, quando a execução de um programa em Java é normalmente muito mais lenta do que a de um programa escrito em C. No entanto, ao contrário dos CGIs, onde para cada pedido é lançado um novo processo, um servlet apenas é carregado uma vez, sendo cada pedido satisfeito por uma nova thread. Tecnologias utilizadas 51 O uso da linguagem Java e do modelo orientado por objectos confere uma grande modularidade às aplicações, permitindo a separação da lógica da aplicação da sua apresentação. Os servlets devem ser responsáveis apenas por receber os pedidos e passar os dados às classes de suporte, normalmente representadas por Beans e, após receber o resultado das operações efectuadas pelos Beans, criar a apresentação dos dados, normalmente em HTML, a qual será entregue ao utilizador. A linguagem Java confere, como se pode observar pela Figura 10, métodos para o fácil acesso a múltiplas fontes de dados. 3.3.1.1 – Ciclo de vida dos servlets Como já foi referido, um servlet não é mais que uma classe que implementa a interface servlet, ou directamente uma das suas subclasses. A maior parte dos servlets, destinamse a servir pedidos HTTP, e são executadas no ambiente proporcionado pelo servlet engine, pelo que estendem directamente a classe abstracta javax.servlet.http.HttpServlet. A relação entre esta classe e a interface servlet pode ser observada na Figura 11. javax.servlet.Servlet javax.servlet.GenericServlet javax.servlet.http.HttpServlet Figura 11 – Relação entre classes passíveis de extensão para a criação de um servlet Uma das características dos servlets que os tornam tão eficientes, é o facto de permanecerem activos enquanto o servidor estiver activo, podendo assim guardar dados. Quando um servlet é carregado o seu método init() é chamado. Como qualquer outro objecto, um servlet pode ter atributos, onde podem ser guardados dados e recursos a utilizar durante a sua vida. O método init() é assim o local indicado para realizar a inicialização destes dados e recursos. Recursos como ligações a bases de dados podem ser inicializados uma única vez, poupando preciosos recursos. Tecnologias utilizadas 52 Durante a vida de um servlet, por cada novo pedido é criada uma nova tread, que recorre ao método indicado para responder ao pedido. Devem aqui ser utilizados os recursos contidos nos atributos do objecto. Ao escrever um servlet é necessário tomar em atenção o facto dos métodos deverem ser thread-safe, de modo a evitar conflitos por concorrência. Caso isto não seja possível, a classe deve implementar a interface javax.servlet.SingleThreadModel, que garante que nunca existe mais que uma thread a trabalhar com um objecto da classe. Neste caso, o servlet engine é forçado a criar vários objectos da classe, para poder responder a pedidos simultâneos, tendo esta opção penalidade em termos de desempenho. Quando um servlet é terminado, quer por o servidor ser desligado, quer por o servlet ser recarregado em virtude de ter sido alterado, o método destroy() fornece a possibilidade de terminar ordeiramente o uso dos recursos, fechando ficheiros e ligações a bases de dados entre outros. 3.3.1.2 – Persistência dos dados Uma das dificuldades de escrever aplicações Web utilizando CGI é a dificuldade em manter estado entre pedidos de um utilizador. Os servlets incluem suporte para guardar dados sobre uma sessão através da classe session. Um objecto do tipo session fica associado a uma sessão de um utilizador, e nele é possível guardar os dados que se queira através de uma hashtable. Para identificar um utilizador, o servlet engine utiliza cookies, gerando um identificador único para cada utilizador. Caso o utilizador utilize um browser sem suporte para cookies, o servlet engine recorre à técnica de URL-rewriting, que consiste em colocar um sufixo em cada link como um identificador do cliente. Esta técnica incorre num penalização de desempenho pois é necessário modificar todos os links originados quer em páginas dinâmicas quer em estáticas, deixando de funcionar mal o utilizador abandona o site, pelo que não é possível regressar. Adicionalmente, existe suporte para guardar dados com outro alcance: aplicação, dados partilhados por todos os servlets; pedido, dados que ficam associados a um pedido HTTP (um pedido pode ser passado a outro servlet). A partilha de dados entre várias servlets dentro do mesmo servlet engine só é possível por este correr numa única Java Virtual Machine. Tecnologias utilizadas 53 Todos estes dados são guardados pelo servlet engine, sendo normalmente perdidos caso o servidor seja desligado, embora existam alguns servidores capazes de guardar o estado em suporte persistente. Quando os dados são importantes, devem ser guardados num suporte persistente. 3.3.1.3 – Beans e sua utilização Um Bean não é mais que uma instância de uma classe que deve seguir as seguintes restrições: ter um construtor vazio; para cada atributo público, ter um método setX() e um getX(). Uma aplicação que recorra a servlets deve estruturar a sua lógica nestes objectos, pois os servlets fornecem métodos que facilitam a sua utilização. Uma das utilizações destes métodos é o tratamento de formulários. Caso um Bean forneça um método setX() para cada campo de um formulário, é possível instruir o servlet engine a chamar automaticamente cada um dos métodos de modo a passar ao Bean o conteúdo do formulário. 3.3.1.4 – Outras funcionalidades Os servlets são uma plataforma estável, com muitas provas dadas, desenhada para servir no maior número de situações imaginável. Como tal, existe um grande suporte para internacionalização, como já era apanágio da linguagem Java [76]. É normal uma aplicação necessitar de escrever diários (logs), não só para registar eventos e ocorrências mas também situações de erro ou falhas de comunicação, com vista à detecção de falhas e posterior correcção. A API servlet possui métodos para a escrita de mensagens nos logs do servlet engine, poupando o esforço de desenvolvimento de uma solução própria ao mesmo tempo que garante uma uniformidade entre os logs de várias aplicações. Este mecanismo é particularmente útil pois permite a gravação no log dos stack traces das excepções Java lançadas em casos de erros durante a execução da aplicação. Cada aplicação pode ser constituída por vários servlets, cada qual com tarefas distintas. Uma das vantagens dos servlets é permitirem a delegação (forwarding) de pedidos a outro servlet que pode até estar a correr numa máquina diferente. Este mecanismo pode ser utilizado para dedicar uns servlets à recepção e processamento de pedidos e outros Tecnologias utilizadas 54 (normalmente JSPs) à construção da resposta (apresentação) a enviar ao utilizador, colocando os dados para a resposta no pedido que é passado. Este mecanismo pode também encontrar aplicação em mecanismos de balanceamento de carga, onde os pedidos são transferidos para o servidor com menor carga. Uma aplicação Web será normalmente constituída por vários servlets, documentos HTML, imagens, etc. Todos estes documentos ficam agrupados debaixo de um directório, onde também fica o ficheiro web.xml. Este ficheiro, em formato XML, contém informação de configuração não só para o servidor HTTP, mas também para os servlets. Este ficheiro guarda pares chave/valor, facilmente acessíveis pelos servlets, de modo a obter dados de inicialização, tais como endereços de bases de dados. 3.3.2 – JavaServer Pages Embora os servlets sejam extremamente poderosos, o facto de serem escritos em Java e necessitarem de ser compilados antes de serem utilizados, torna a alteração da apresentação da aplicação uma tarefa complicada. Esta é uma operação frequente, não só devido às frequentes actualizações estéticas que caracterizam os sites populares, mas também devido à necessidade de adaptar as interfaces às necessidades de cada utilizador. Adicionalmente, os trabalhos de programação e de desenho gráfico são normalmente realizados por pessoas distintas, pelo que é preferível boa separação entre código e apresentação, o que os servlets não permitem. O output HTML gerado por um servlet é produzido recorrendo aos métodos print e println do objecto que representa a stream de output, pelo que alterar a aparência de uma aplicação implica pesquisar muito código até encontrar o que se pretende. A Sun e seus parceiros decidiram assim criar a especificação JSP, actualmente na versão 1.2, que assenta nos servlets, e não é mais que um mecanismo para facilitar a criação de servlets. Conforme se pode observar pela Figura 12, um servlet engine que suporta JSP, não é mais que um servlet engine com capacidade para compilar JSP. Tecnologias utilizadas Cliente 55 Dados Logica aplicacional JDBC Tradutor JSP Cliente HTTP Beans Servidor HTTP Base de dados JavaMail Servidor Email Servlets Servlet engine Documento simples JNDI RMI EJB EJB EJB Servico de directorio Aplicação Java IIOP Enterprise Java Beans container Aplicação com suporte CORBA Figura 12 – Arquitectura de um servidor HTTP com suporte para JSP Os JSP apresentam um paradigma semelhante ao utilizado em linguagens de scripting como PHP (PHP: Hypertext Preprocessor) [85][86] ou ASP (Active Server Pages) [87]. São ficheiros cujo conteúdo principal é HTML (ou outra linguagem como Wireless Markup Language - WML ou XML), ficando o código Java embebido dentro de tags especiais. A primeira vez que um ficheiro JSP é chamado ou sempre que este é alterado, o servlet engine encarrega-se de o transformar num servlet que estende a classe HttpServlet e de o compilar para Java bytecode. Este é em seguida carregado pelo servlet engine tal como todos os servlets, beneficiando das vantagens destes. Esta clara separação entre a apresentação e a lógica da aplicação possibilita um desenvolvimento mais rápido, pois permite aos designers concentrarem-se na apresentação e aos programadores concentrarem-se no desenvolvimento da lógica da aplicação. Tipicamente um JSP só recorre a código Java, ou alternativamente a algumas das tags fornecidas para o efeito, para passar os dados aos Beans e depois obter os resultados. A utilização de tags, permite a programas que só sabem HTML, interpretar o código como comentários, permitindo assim a edição gráfica da apresentação da aplicação através de ferramentas visuais. Um ficheiro JSP pode conter só código se for necessário, ou apenas HTML (embora isso não faça muito sentido). Tal como num servlet, é possível especificar um método para a inicialização e outro para a terminação do objecto. Também é possível passar os pedidos (forwarding) para outros servlets ou JSPs. Tecnologias utilizadas 56 Os JSP acedem aos dados do pedido e da aplicação através de objecto implícitos, dos quais se destacam: request, dados do pedido actual; response, dados da resposta a enviar; pageContext, permite guardar objectos a partilhar pelas várias tarefas deste JSP; session, permite guardar dados a partilhar pelos vários JSP e servlets que sejam chamados no decurso da sessão do utilizador; application, permite guardar objectos a partilhar por todos os servlets e JSP que correm dentro do mesmo servlet engine; out, objecto que representa o stream a enviar ao cliente, possibilitando, no código Java, a escrita do conteúdo a enviar; config, objecto que dá acesso aos parâmetros de configuração contidos no ficheiro web.xml. Desenvolver conteúdo dinâmico com JSP não implica programar em Java. JSP é uma linguagem embebida em tags e os scriptlets (pequenos segmentos de código Java) são apenas o uso de uma das várias tags disponíveis. Existem tags disponíveis para comentários, declarações, escrita de expressões, execução de scriptlets, inclusão de outros ficheiros, configuração de características da página, despacho (forward) do pedido para outro JSP ou servlet e para a declaração e utilização de Beans. São permitidos dois tipos de comentários: relativos ao JSP e relativos ao conteúdo produzido. Os comentários relativos ao JSP são destinados aqueles que trabalham no seu desenvolvimento ou manutenção, servindo para comentar o programa. Estes comentários são ignorados pelo tradutor JSP enquanto cria o servlet. O outro tipo de comentários é relativo ao código HTML gerado, e é passado ao utilizador da aplicação. Existem tags que permitem escrever no stream de output o resultado da avaliação de expressões, sem necessidade de escrever código. Para que se possa utilizar variáveis nestas expressões, elas precisam de ser previamente declaradas, o que é possível com outro tipo de tags. É possível concentrar em ficheiros separados informação usada repetidamente. Conteúdos como cabeçalhos e rodapés, que são comuns a várias páginas podem ficar num ficheiro à parte, o qual pode ser incluído pelos JSP. Existem dois tipos de inclusão: dinâmica e estática. A inclusão estática junta o conteúdo do ficheiro (que pode incluir código) em tempo de compilação, sendo equivalente à primitiva de pré-processamento “#include” da linguagem C. A inclusão dinâmica inclui o conteúdo do ficheiro no Tecnologias utilizadas 57 output do JSP, sem que este possa conter código, resultando assim num menor desempenho pois é necessário ler o ficheiro cada vez que o JSP serve um pedido. Características como o tipo de conteúdo MIME gerado pelo JSP, as classes Java a importar, a necessidade de suporte de sessões, o JSP ser thread-safe, e outras, são configuradas recorrendo à tag page. Sendo o uso de Beans parte importante da arquitectura de uma aplicação baseada em JSP, existe ainda uma tag específica para a sua declaração, onde é possível especificar o seu âmbito: aplicação, página, sessão ou pedido. 3.3.3 – EJB - Enterprise Java Beans Os EJB apresentam-se no centro da arquitectura das aplicações J2EE [88]. O seu papel é concentrar todas as entidades de negócio e a lógica de negócio, permitindo depois o desenvolvimento de várias interfaces totalmente ignorantes da lógica de negócio. Esta tecnologia tem sofrido uma grande evolução à medida que a especificação tem avançado, incorporando os últimos avanços tecnológicos com o intuito de simplificar cada vez mais a tarefa de desenvolver aplicações J2EE. Neste texto são referidas as capacidades do EJB na versão 2.0, aquela que integra o J2EE 1.3. Os EJB dividem-se em três tipos: os destinados a representar entidades que necessitam de ser guardadas em suporte persistente (Entity Beans); os destinados a modelar a lógica de negócio e a servir de interface para modificar o estado dos Entity Beans (Session Beans); os destinados a processar eventos assíncronos (Message Driven Beans - MDB) [89]. Os Entity Beans representam entidades, que necessitam de ser guardadas em suporte persistente, normalmente uma base de dados. O mapeamento da entidade para o suporte persistente pode ser feito manualmente ou deixado a cargo do servidor J2EE. Quando este processo é realizado manualmente, o EJB toma o nome de Bean Managed Persistency (BMP) EJB, no outro caso é chamado Container Managed Persistency (CMP) EJB. A grande vantagem da modelação de entidades como Entity Beans está no uso de CMP. Nesta situação, o programador apenas tem de definir os campos de cada entidade e as relações existentes entre as entidades. Aquando da instalação da aplicação indica-se a Tecnologias utilizadas 58 base de dados onde as entidades devem ser guardadas. O servidor J2EE é responsável por criar, transparentemente, as tabelas na base de dados, caso ainda não existam, e todo o código SQL (Structured Query Language) para acesso à base de dados. O código criado pelo servidor pode ser muito mais eficaz que o criado por humanos, pois o servidor sabe o estado de cada objecto e pode limitar os acessos à base de dados. O servidor pode ainda tomar partido de características específicas do SGBD utilizado, sem que para isso o código escrito pelo programador tenha de ser alterado. Aquando da instalação do programa é ainda possível indicar ao servidor J2EE quais as condições do acesso à base de dados, permitindo por exemplo, que este mantenha uma cache de dados dessincronizada caso seja a única aplicação a aceder à base de dados. Os Entity Beans criam uma camada de abstracção que permite ao programador aceder às entidades sem se preocupar com a sua representação e persistência. As entidades são acedidas como se fossem simples objectos, ficando a cargo do servidor J2EE efectuar as leituras e escritas no suporte persistente e manter a coerência entre o suporte persistente e a representação em memória das entidades. Os Session Beans servem de ponto de entrada para modificar o estado das aplicações e efectuar operações. A arquitectura J2EE não recomenda o acesso directo a Entity Beans, devendo estes ser manipulados apenas através de Session Beans, que implementam a lógica de negócio. Os Session Beans podem ser acedidos remotamente, fornecendo assim uma interface para o desenvolvimento de aplicações distribuídas e clientes remotos. Existem dois tipos de Session Beans: Stateful Session Beans e Stateless Session Beans. Existe apenas uma diferença entre estes dois tipos de EJB: os primeiros guardam estado relativo ao cliente. Esta pequena diferença tem um grande impacto na forma como o servidor J2EE trata estes dois tipos de objectos, pois significa que um cliente deve comunicar sempre com a mesma instância de um Stateful Session Beans ao longo da sua sessão, enquanto que qualquer instância de um Stateless Session Beans pode processar os seus pedidos. Os Stateless Session Beans podem por isso ser guardados em pools, apresentando melhor desempenho ao ser reutilizados por vários clientes. Além disso um cliente pode ser transferido para outro servidor em caso de falha ou sobrecarga, pois qualquer instância de um Stateless Session Beans pode servir os seus pedidos. Já o estado dos Stateful Session Beans tem de ser replicado entre servidores para que os clientes possam Tecnologias utilizadas 59 ser transferidos transparentemente, limitando assim as suas características de alta disponibilidade. O tipo de EJB mais recente é o MDB. Estes não se destinam a ser acedidos directamente por clientes, mas apenas a reagir a eventos assíncronos. Um MDB é configurado para ficar à escuta de mensagens provenientes de uma fila ou de um serviço publish/subscribe. Estes EJB implementam apenas um método, invocado sempre que chega uma mensagem. Os EJB são registados no serviço de directório incluído num servidor J2EE, de onde os clientes obtêm referências através de JNDI. Todos os EJB podem ainda usufruir dos serviços de segurança e controlo transaccional da plataforma J2EE. Estes serviços podem ser acedidos de forma programática ou declarativa. No primeiro caso o programador é responsável por utilizar, no código Java, as API disponíveis para especificar o comportamento desejado. No segundo caso são utilizados os ficheiros XML de configuração do EJB para definir o comportamento desejado, sendo possível altera-lo sem mexer no código Java. É assim possível, por exemplo, limitar determinados métodos de um componente EJB a determinado tipo de utilizador, ou indicar que a execução de um método exige a criação de uma nova transacção. Tecnologias utilizadas 60 3.4 – JCA - Java Connector Architecture Embora faça parte da especificação J2EE 1.3, a apresentação da especificação JCA numa secção independente é motivada pela relevância desta tecnologia no âmbito deste trabalho, justificando assim uma apresentação mais aprofundada [90]. A especificação JCA é muito recente. A versão actual é a 1.0, lançada na segunda metade de 2002. Quando este trabalho foi iniciado a JCA ainda estava em desenvolvimento, sendo a versão disponível ainda beta. Na altura em que esta dissertação foi concluída tinha acabado de ser lançada a proposta de draft para a versão 1.5, que irá certamente tentar superar algumas das limitações aqui apontadas à versão 1.0. A versão 1.0 foi incorporada no J2EE 1.3, tendo as primeiras implementações beta ficado disponíveis em finais de 2001. A implementação de um connector apresentada nesta dissertação começou a ser desenvolvida na implementação de referência do J2EE, tendo mais tarde esta sido abandonada pela implementação open-source JBoss 3.0.0. A arquitectura J2EE é baseada em componentes. Cada componente consiste num conjunto de classes Java que respeitam determinados contratos, existindo contratos estabelecidos para os diversos tipos de componentes previstos na arquitectura. O cumprimento de um contrato consiste na implementação de determinados métodos definidos em interfaces Java. A implementação de um componente JCA, daqui para a frente referenciado como connector, requer a observância de três contratos: Segurança, Gestão de ligações e Gestão de transacções. Existem ainda um contrato opcional, o CCI (Common Cliente Interface), que especifica a API que um connector expõe aos seus clientes. A Figura 13 apresenta as relações entre os vários componentes. As classes constituintes dum componente são empacotadas (packaged) num único ficheiro para ser lançado (deployed) num servidor aplicacional (container). Este ficheiro, compactado segundo a norma JAR (Java Archive), contém ainda um ficheiro XML com informação necessária à configuração do connector e do container, para além de outros recursos (imagens, bibliotecas nativas, classes Java, ficheiros de configuração, etc.) utilizados pelo connector. A importância de seguir o formato do ficheiro prende-se com o facto dos componentes J2EE correrem dentro de espaço de endereçamento do Tecnologias utilizadas 61 container, isto é, dentro da mesma máquina virtual Java. Apesar de ser apenas mais um componente J2EE a correr dentro do servidor, um connector usufrui de privilégios especiais, negados aos outros componentes. O mais importante destes privilégios é a possibilidade de utilizar JNI, fornecendo assim o acesso a código nativo. Componente (ex: EJB ou JSP) Contrato Container Componente API para cliente Container Connector para EIS A Contrato Container Connector Connector para EIS B EIS A Protocolo especifico ao EIS EIS A EIS B Figura 13 – Arquitectura JCA A especificação JCA consiste assim na definição dos contratos e forma de empacotamento a respeitar por um container e por um connector de forma a garantir a interoperabilidade. Um connector permite ampliar a funcionalidade de um servidor aplicacional de forma a permitir a comunicação com uma ou mais instâncias de um determinado EIS. Cada connector é desenvolvido para um EIS específico e apenas funciona com esse EIS. 3.4.1 – Papeis Tornar a especificação numa realidade exige a colaboração de todos os intervenientes na implementação de uma soluções J2EE. Como tal a especificação JCA define os seguintes papéis: Resource Adapter Provider: Aquele que fornece o connector. É alguém perito na tecnologia de um determinado EIS, muito provavelmente o próprio fabricante do EIS. Tecnologias utilizadas 62 Ex: A IBM fornece um connector que permite a aplicações J2EE comunicar com sistemas transaccionais IBM CICS [91]. Application Server Vendor: Aquele que fornece um servidor aplicacional, no qual componentes J2EE podem ser executados. Este é tipicamente desenvolvido ao nível do sistema onde vai correr. Ex: a BEA Inc. fornece o WebLogic para vários sistemas operativos [92]. Container Provider: Embora a especificação apresente este papel separadamente do anterior, eles são essencialmente o mesmo. Um container suporta um tipo de componente J2EE, existindo containers para servlets, containers para EJB, etc. Normalmente, quem produz servidores aplicacionais desenvolve todos os containers necessários a implementar toda a especificação J2EE, embora existam algumas excepções. Ex: O servidor J2EE open-source JBoss [93] pode utilizar como servlet container o Tomcat do projecto Apache [94]. Application Component Provider: Perito numa determinada área de negócio, que desenvolve componentes de alto nível que utilizam EIS e abstraem essa área de negócio. Não utiliza o connector directamente através da CCI mas sim através de uma API simples desenvolvida automaticamente por ferramentas de desenvolvimento. Ex: um componente capaz de fornecer estatísticas sobre vendas com base em dados retirados de SAP. Enterprise Tools Vendor: Fornece aplicações para simplificar o desenvolvimento de componentes. Estas ferramentas são tipicamente utilizadas pelos Application Component Providers, pois geram automaticamente o código que utiliza um connector. Tipicamente uma ferramenta destas funciona graficamente e permite a análise das funcionalidades e dados oferecidos por um connector e a geração automática de código que interage com o connector, possibilitando ao programador de componentes abstrairse dos detalhes do funcionamento de um EIS. Aplication Assembler: Aquele que desenvolve a aplicação J2EE final, recorrendo a componentes fornecidos por outros. É um perito na área que a aplicação serve. Deployer: Aquele que coloca a aplicação em produção. Tipicamente o seu trabalho consiste em configurar a aplicação e os connectors utilizados, fornecendo dados como Tecnologias utilizadas 63 passwords, endereço IP e porto onde correm os EIS, etc. Trabalha em estreita colaboração com o System Administrator. System Administrator: Responsável pela manutenção do servidor aplicacional e EIS. Este trabalho debruça-se sobre o papel do Resource Adapter Provider, uma vez que um dos seus objectivos é a implementação de um connector. 3.4.2 – Gestão de ligações Imaginemos uma aplicação J2EE que necessita de aceder frequentemente a uma base de dados (BD). O processo de obtenção de uma ligação envolve autenticação perante o servidor de BD, pelo que é um processo demorado e portanto de evitar. No entanto, um objecto não pode guardar a sua ligação à BD por tempo indeterminado pois num ambiente complexo isso poderia levar à exaustão das ligações simultâneas permitidas à BD. Para permitir que um objecto não mantenha uma ligação a uma BD por mais tempo do que o necessário, nem que o repetido estabelecimento de ligações à BD se torne um factor limitativo do desempenho da aplicação, os containers J2EE implementam automaticamente pools de ligações a bases de dados JDBC, que são partilhadas pelos vários objectos ou tarefas da aplicação. Este conceito foi transportado para a especificação JCA. Quando as ligações ao EIS apresentam elevados custos de criação/destruição o conceito de partilha de ligações é fundamental para o desenvolvimento de soluções escaláveis e de alto desempenho. Assim a especificação JCA define o contrato de gestão de ligações entre o container e o connector, permitindo ao primeiro a gestão e partilha de ligações sem ter de conhecer as características e propriedades da ligação a um EIS. A Figura 14, retirada de [21], apresenta as interfaces e contratos existentes entre os vários componentes da JCA. Ao registar um connector num container é fornecido o nome da classe de implementação da interface ManagedConnectionFactory e um nome JNDI onde um cliente poderá obter ligações ao EIS. O container utiliza a implementação de ManagedConnectionFactory para criar uma instância de ConnectionFactory associada à implementação de ConnectionManager do container, registando depois esta instância no espaço de nomes JNDI. O cliente usa um endereço JNDI previamente conhecido Tecnologias utilizadas 64 para obter uma referência para a instância de ConnectionFactory, através da qual pode criar uma ligação ao EIS (Connection). Figura 14 – Interfaces constituintes da JCA [21] Como se pode observar na Figura 15, a responsabilidade pela entrega de uma ligação ao EIS a um cliente é partilhada entre o container e o connector. O componente cliente apenas interage com o ConnectionFactory e com o Connection. Do primeiro obtém o segundo e com este realiza as operações sobre o EIS. O restante processo de obtenção de ligações é escondido do cliente. Quando o cliente requer uma ligação, pode passar ao ConnectionFactory parâmetros adicionais, que embora não sejam compreendidos ou utilizados pelo container serão Tecnologias utilizadas 65 passados ao ManagedConnection. Os parâmetros passados são tipicamente específicos ao EIS. É de salientar que dados essenciais ao estabelecimento de uma ligação, tais como servidor e porto onde corre o EIS não são fornecidos pelo cliente, mas sim pelo deployer da aplicação, num ficheiro XML, sendo conhecidos por ManagedConnectionFactory. Componente aplicacional Servidor Aplicacional Connection Factory Connection Managed Connection Managed Connection Factory Connector getConnection ManagedConnection.allocateConnection Encontra conjunto de possiveis candidatos matchManagedConnections Não encontra nenhuma ligação adquada ao cliente createManagedConnection cria nova instancia Devolve nova instancia de ManagedConnection addConnectionEventListener setLogWriter Configura a nova Managed Connection para o tipo de transacção configurado getConnection cria nova instancia Devolve nova instancia de Connection Devolve nova instancia de connection Devolve nova instancia de Connection Figura 15 – Diagrama temporal para estabelecimento de nova ligacao O ConnectionFactory não cria a nova ligação mas delega essa responsabilidade ao container que consulta a sua pool de ligações e através de critérios proprietários reúne um conjunto de ManagedConnection que acredita poderem servir a este cliente. Como não conhece os detalhes de implementação de um connector, o container não é capaz de decidir qual, se algum, o adequado ao cliente, pelo que invoca o método Tecnologias utilizadas 66 matchManagedConnections de ManagedConnectionFactory, para escolher dentro do conjunto encontrado, a ManagedConnection adequada ao cliente, de acordo com a informação de segurança associada ao cliente e aos parâmetros da ligação pedidos por este. Caso não exista nenhuma adequada dentro do conjunto ou o conjunto seja vazio, o container pede a ManagedConnectionFactory a criação de uma nova ligação com as características pretendidas. Uma ManagedConnection representa uma ligação física ao EIS, que nunca é destruída durante a existência da instância, embora seja possível que o seu utilizador mude, caso o EIS suporte reautenticação. Após obter uma ManagedConnection, quer seja retirada da pool, quer seja nova, esta é configurada, sendo-lhe passado um EventListener e o ficheiro para onde pode escrever mensagens de log. O EventListener é o mecanismo utilizado pela JCA para possibilitar a comunicação entre uma ligação e o container, sendo basicamente um objecto do container, que a ManagedConnection pode utilizar para sinalizar ocorrências de erro, acontecimentos relacionados com transacções e o fecho da ligação por parte do cliente. O cliente não interage com uma ManagedConnection mas apenas com uma Connection, a qual apenas lhe permite comunicar com o EIS e fechar a ligação. Assim, o container pede à ManagedConnection uma nova Connection para passar ao cliente. O método utilizado, getConnection, pode também ser utilizado para alterar a informação de autenticação (username, password, ou outro tipo de credenciais) associados a uma ligação, mas apenas quando o EIS admite reautenticação. Caso o connector o permita podem ser associadas várias Connection a uma única ManagedConnection, sendo assim partilhada uma ligação física ao EIS. Quando o componente cliente fecha a ligação, recorrendo ao método close de Connection, a ManagedConnection associada notifica o container através da EventListener fornecido. O container pode então decidir destruir a ligação evocando o método destroy ou manter a ligação física ao EIS, evocando o método cleanup para a desassociar de utilizador, logs e transacções e depois guardar o objecto ManagedConnection na pool de ligações. Tecnologias utilizadas 67 3.4.3 – Transacções Um dos serviços apresentados por um container EJB é a gestão automática de transacções. O programador de EJB apenas tem de especificar no ficheiro XML de deployment de um EJB qual os requisitos de transacções e quais os métodos do EJB envolvidos. Esta especificação declarativa dos requisitos transaccionais de uma aplicação veio simplificar em muito o processo de desenvolvimento, tendo também contribuído para aumentar a qualidade do software produzido. A JCA impõe um contrato entre o container e o connector apenas para a gestão das transacções, fazendo com que o container possa integrar as transacções do EIS com os restantes componentes de uma aplicação. O ficheiro de deployment do connector especifica o tipo de suporte a transacções suportado por este e pelo EIS associado. Nesta versão da JCA estão previstos três tipos: Sem transacções: O EIS não suporta transacções pelo que todas as operações realizadas são permanentes. O connector não necessita de implementar classes relacionadas com transacções devendo apenas devolver uma excepção caso seja executado algum método de ManagedConnection relacionado com transacções. Transacções locais: O EIS suporta o conceito de transacção mas não é capaz de participar em transacções distribuídas. Este será o caso de muitos servidores de bases de dados. Esta situação requer que o connector seja capaz de executar rollback ou commit para cada transacção e que seja capaz de notificar o container de situações anómalas, tais como um rollback automático. O connector deve implementar a interface LocalTransaction referida na Figura 14, que permite ao container a gestão das transacções. O objecto LocalTransaction associado a uma ligação é fornecido por ManagedConnection, sendo a comunicação entre os dois objectos proprietária à implementação do connector. O container é mantido ao corrente do estado das transacções através do EventListener associado a uma ManagedConnection. Transacções XA: O EIS suporta transacções distribuídas segundo a norma XA – X/Open CAE Specification. Neste caso o connector pode suportar transacções em uma fase ou em duas (1PC - one phase commit, 2PC - two phase commit), sendo sempre obrigado a suportar transacções locais. A implementação do connector deve Tecnologias utilizadas 68 contemplar a interface XAResouce, através da qual o container controla as transacções. Caso suporte 2PC o connector pode participar em votações para determinar o resultado de uma transacção. É importante notar que uma implementação de um connector para um determinado EIS apenas pode suportar transacções caso o EIS as suporte. No caso deste trabalho o connector desenvolvido não suporta transacções pois o conceito não existe no TeMIP. 3.4.4 – Segurança A autorização e autenticação fazem parte dos serviços suportados pela plataforma J2EE. Um cliente (seja ele um cliente Web, uma aplicação cliente J2EE ou um EJB) tem sempre associado um conjunto de credenciais. Esta informação é passada ao connector sempre que é pedida uma nova ligação, através de um objecto do tipo Subject. O connector extrai daí a informação de que necessita para realizar a autenticação do utilizador junto ao EIS. Como o domínio de utilizadores do container onde corre a aplicação pode não corresponder ao do EIS, a JCA prevê os seguintes mecanismos de conversão de credenciais: Mapeamento de utilizadores: O deployer do connector fornece uma classe responsável pelo mapeamento, um-para-um, dos utilizadores da aplicação para os utilizadores do EIS. O utilizador da aplicação “ze” com a password “xpto” pode corresponder ao utilizador do EIS “ze manuel” com a password “qwerty”. Delegação de utilizadores: O deployer fornece uma classe que realiza o mapeamento, muitos-para-um, dos utilizadores da aplicação para os utilizadores do EIS. Um caso particular é a utilização de um só utilizador para aceder a uma base de dados, ou de um utilizador por cada classe de utilizadores da aplicação. Por exemplo: os gestores da aplicação são mapeados num utilizador da base de dados com permissão de escrita e os utilizadores comuns da aplicação são mapeados noutro utilizador apenas com permissão de leitura. Mapeamento de credenciais: Semelhante ao mapeamento de utilizadores mas apenas as credenciais de autenticação são alteradas, sendo a identidade do utilizador Tecnologias utilizadas 69 mantida. No domínio do servidor J2EE o utilizador pode utilizar uma password e no do EIS pode recorrer a credenciais kerberos, ou uma password diferente. Single sign on: Neste caso os domínios de autenticação do servidor J2EE e do EIS são idênticos, e as mesmas credenciais são aceites em ambos. Pode mesmo existir um único domínio de autenticação. O modo como os mecanismos de conversão de utilizadores são implementados e especificados está fora do âmbito da JCA, sendo a sua definição deixada a cargo dos fabricantes de servidores aplicacionais. A autenticação dos utilizadores de uma aplicação que corre num container J2EE é realizada por módulos Java Authentication and Authorization Service (JAAS). Tipicamente, um servidor aplicacional é fornecido com módulos JAAS que permitem armazenar os dados dos utilizadores em ficheiros de texto ou em bases de dados. A especificação JCA também sugere a integração de um módulo JAAS com um connector, sendo a autenticação dos utilizadores feita no EIS, deixando assim de haver necessidade de mecanismos de conversão de utilizadores. Mais uma vez esta parte fulcral da arquitectura é deixada de fora do âmbito da JCA, ficando a cargo dos fornecedores de containers a sua definição, o que fará com que connectors que utilizem esta tecnologia não sejam portáveis entre servidores aplicacionais de vários fornecedores. Para além do mecanismo básico de autenticação por username e password, a JCA prevê ainda a utilização de Kerberos, quando os EIS suportem esta norma, o que não é o caso do TeMIP. 3.4.5 – CCI - Common Client Interface A interacção entre o cliente do connector e este pode ser efectuada através de uma interface proprietária ou através da interface CCI. A implementação da interface CCI é opcional. A interface CCI define um conjunto de métodos e classes que o connector deve implementar. O seu objectivo é definir um método standard de interagir com um EIS, à semelhança do que o JDBC faz para o acesso às bases de dados. No entanto, ao contrário das bases de dados JDBC, que todas aceitam SQL, cada EIS é um caso único, podendo mesmo uma base de dados ser vista como um EIS. Como tal, não é possível o Tecnologias utilizadas 70 desenvolvimento de uma interface simples e universal. A solução da JCA para este problema é considerar que o CCI não é para ser utilizado por programadores mas por ferramentas de integração. Estas ferramentas de integração possuem repositórios internos de informação onde está descrita a forma como cada connector utiliza o CCI. A função destas ferramentas é produzir APIs adaptadas ao connector e ao problema que o programador pretende solucionar. O programador deve então utilizar estas APIs. O grande problema do CCI é que o formato do repositório de informação não está definido na JCA, sendo deixado ao cuidado dos fornecedores de ferramentas de integração. Como tal, não pode ser o connector a definir a informação necessária a poder ser utilizado com uma ferramenta de integração, mas é a ferramenta de integração que deve conhecer a priori o connector, o que coloca o problema da actualização constante deste repositório por forma a funcionar com os connectors disponíveis no mercado. Uma possível evolução do mercado será os grandes fornecedores de connectors desenvolverem as suas próprias ferramentas de integração, que venderão juntamente com os connectors. Actualmente ainda não existe nenhuma ferramenta que realize esta integração, e mesmo que existisse não iria conhecer o connector apresentado nesta dissertação, pelo que o CCI não foi implementado. É possível a uma aplicação utilizar directamente o CCI, mas não foi para isso que este foi desenhado e é muito mais complicado interagir com o CCI do que com uma interface simples, desenhada à medida, e que abstráia as funcionalidades do EIS. 3.4.6 – Exceptions A JCA compreende uma excepção, ResourceException, que deve ser utilizada por um connector para assinalar situações de erro e em reposta a chamadas a métodos não suportados. No caso do connector desenvolvido é levantada uma ResourceException sempre que são invocados os métodos referentes a suporte de transacções, uma vez que o TeMIP não suporta transacções. Estas excepções podem incluir informação sobre a excepção que lhes deu origem, pelo que também são utilizadas para transmitir aos clientes J2EE todo o tipo de excepções que podem ocorrer em resposta a um pedido feito ao TeMIP. Tecnologias utilizadas 71 3.4.7 – Packaging Um connector deve ser empacotado num ficheiro JAR com extensão rar (Resource Archive). Este ficheiro deve conter as classes que implementam o connector e um ficheiro XML com as definições previstas na JCA. O ficheiro XML contem informação sobre quais as classes que implementam os vários tipos de interfaces definidos na JCA, o suporte a transacções apresentado, o tipo de autenticação suportado (password ou kerberos), informação textual sobre o fabricante do connector e sobre o tipo de EIS e a versão da JCA na qual o connector se baseia. Este ficheiro permite ainda a definição de um conjunto de parâmetros a passar ao connector durante a sua instanciação. Estes dados são tipicamente elementos como o nome do servidor onde corre o EIS e o porto IP. No entanto, esta informação só por si não é suficiente para o container lançar o connector. Para que os clientes possam obter uma ligação ao connector é necessário que este esteja registado no serviço JNDI, sendo assim necessário fornecer um nome JNDI onde o connector ficará registado. Também isto fica fora do âmbito da JCA, cabendo a cada fabricante definir o método de configuração do seu container. 3.4.8 – Vantagens da norma A grande vantagem da norma é permitir um método universal para interagir com aplicações legadas de dentro dos servidores aplicacionais J2EE. De notar que muitos dos servidores aplicacionais existentes já apresentavam métodos proprietários de ultrapassar esta limitação da arquitectura J2EE. A norma é suficientemente abrangente para permitir a interacção com todo o tipo de EIS, aparelhos de hardware, ficheiros, etc., não sendo restritiva como o JDBC que apenas permite a comunicação com bases de dados. O servidor J2EE JBoss, por exemplo, privilegia o uso de connectors para aceder a bases de dados em detrimento do JDBC. Embora seja pensada para ser utilizada em containers J2EE, a norma JCA permite que um connector seja utilizado por uma simples aplicação Java, fazendo assim com que todo o espectro de aplicações Java possa beneficiar da tecnologia. Tecnologias utilizadas 72 Para as aplicações que correm em containers a arquitectura JCA fornece uma gestão transparente de transacções, segurança (utilizadores, autenticação, autorizações) e de ligações (partilha de ligações, polling). Isto facilita em muito o desenvolvimento de aplicações complexas, diminuindo o esforço, possibilidade de erro humano e conhecimentos necessários, e aumentando a qualidade e fiabilidade do código desenvolvido. A arquitectura JCA é mais um passo em frente na reutilização de código e no desenvolvimento modular de aplicações, apanágio da arquitectura J2EE. 3.4.9 – Actuais deficiências da norma Uma das grandes falhas da arquitectura JCA é que segue o modelo síncrono do JDBC. O JMS e os MDB são uma das grandes apostas do J2EE 1.3, a mesma versão que trás à luz do dia a JCA 1.0. As aplicações que reagem a acontecimentos assíncronos são muito comuns, especialmente quando se interagem com um EIS. Faz mais sentido um sistema de alertas reagir a um acontecimento assim que ele acontece no EIS, do que estar constantemente a perguntar ao EIS se ele já aconteceu (active polling), o que sujeita o EIS a uma grande carga. Deveria ser possível associar um MDB a um acontecimento num EIS. A norma ainda deixa algumas coisas por definir, fazendo com que sejam necessárias adaptações, pelo menos nos ficheiros XML de deployment, para poder migrar um connector entre servidores J2EE de diferentes fabricantes. Este procedimento é vulgar nas várias normas do J2EE e destina-se a permitir alguma distinção entre as várias implementações existentes no mercado, dando assim espaço para a adição de features proprietárias e alguma segurança aos fabricantes que pensam, erradamente, ficar melhor servidos ao limitar a escolha dos seus clientes [95]. A JCA ainda se encontra na sua versão 1.0. Provavelmente o objectivo dos criadores da especificação é dar tempo ao mercado para criar as suas próprias soluções, sendo de prever que futuras versões da JCA venham a incorporar as melhores práticas entretanto apresentadas. Isto é viável pois a JCA não é definida unicamente pela Sun mas por um conjunto alargado de empresas através do JCP. Tecnologias utilizadas 73 3.4.10 – Futuras adições à norma É de esperar que futuras versões da norma JCA venham resolver algumas das limitações apresentadas. O documento draft da futura versão 1.5 apresenta já mecanismos standard para a recepção de acontecimentos assíncronos do EIS. Possibilita ainda o início da interacção connector/EIS por parte do EIS e não apenas pelo connector como acontece na versão actual. Este draft propõe ainda mecanismos para o connector realizar tarefas até agora negadas a todo o tipo de componentes J2EE, como a criação de sockets como servidor. Outra das lacunas com resolução proposta neste novo draft é a ligação mais estreita do connector ao servidor J2EE, passando o connector a ser notificado de eventos como o arranque e paragem do servidor. No futuro é provável que venha a ser alargado o conjunto de parâmetros especificáveis no ficheiro XML de configuração. À medida que a tecnologia se desenvolve, são descobertos novos meios de diferenciar os servidores J2EE, sendo de esperar que as características diferenciadoras de hoje se tornem comuns no futuro. O documento de definição da JCA 1.0 faz uma vaga alusão ao conceito de gestores de cache, deixando prever que no futuro existirá na norma um contrato que permita a implementação de caches independentes do connector e EIS utilizados. Estes gestores de cache poderão ser implementados por outros fabricantes que não os dos connectors e serão universais. Arquitectura da solução 75 Capítulo 4 – Arquitectura da solução Identificadas as tecnologias adequadas à realização deste projecto, urge desenhar a solução. Este capítulo começa por apresentar os objectivos a atingir por este trabalho. A arquitectura escolhida é apresentada na segunda secção, que apresenta uma visão alargada da solução proposta. As escolhas realizadas são fundamentadas nesta secção, sendo apresentada a forma como contribuem para alcançar os objectivos. O software desenvolvido foi dividido em três componentes: biblioteca Java para acesso ao TeMIP; Servidor RMI para acesso remoto ao TeMIP; implementação dos interfaces JCA. Cada um destes componentes é apresentado na sua própria secção. Neste texto será dado o nome de “TeMIPConnector” ao trabalho desenvolvido. Arquitectura da solução 76 4.1 – Objectivos O Conector foi desenhado com os seguintes objectivos: simplicidade de utilização; facilidade de instalação; não restringir as funcionalidades oferecidas pelo TeMIP; oferta às aplicações J2EE de todas as funcionalidades do TeMIP; compatibilidade com as normas; portabilidade; desempenho; não ser intrusivo; segurança. Foram ainda considerados outros factores como alta disponibilidade e distribuição de carga. Simplicidade de utilização significa que não deve ser exigido ao programador de aplicações que recorrem ao TeMIPConnector a aprendizagem de novas linguagens. A linguagem utilizada para emitir os comandos TeMIP já deve ser do conhecimento de quem está familiarizado com o TeMIP. O TeMIPConnector deve ser fácil de instalar, e principalmente não interferir com o normal funcionamento do TeMIP após estar instalado. Uma instalação simples e não intrusiva encoraja a utilização do produto, que de outra forma seria posto de parte devido ao enorme valor que o TeMIP representa para uma organização. A complexidade do TeMIP, assim como a multiplicidade de cenários onde pode ser aplicado, tornam difícil prever as necessidades específicas de cada utilizador. Assim, o TeMIPConnector não deve limitar as operações possíveis de realizar, procurando oferecer às aplicações J2EE todas as funcionalidades do TeMIP. Deve ser oferecida ao programador a possibilidade de utilizar tanto perguntas síncronas como assíncronas. As interrogações síncronas são normalmente usadas para dar comandos ou consultar o estado de um determinado objecto, enquanto as assíncronas são aplicadas para ter conhecimento dos eventos assim que eles ocorrem. Estes eventos podem, por exemplo, ser alterações no estado de um objecto ou o despoletar de alarmes. O produto desenvolvido deve seguir todas as interfaces obrigatórias da JCA, podendo assim ser instalado em qualquer servidor compatível com J2EE 1.3. A portabilidade é uma das maiores vantagens da linguagem Java, sendo importante que o TeMIPConnector mantenha esta propriedade, para que possa ser utilizado em qualquer ambiente que suporte Java. No entanto, o TeMIPConnector necessita de Arquitectura da solução 77 interagir com o TeMIP, que apenas corre em Tru64 Unix ou Solaris, através da API C++ TAL. O desempenho da solução é um factor muito importante em aplicações de gestão de rede. Informação que chegue desfasada da realidade poderá não ser útil para o operador. Assim, o TeMIPConnector não deve limitar o desempenho oferecido pelo TeMIP, nem impor um atraso significativo no processamento dos pedidos. A segurança é um factor importante neste tipo de produtos. A informação de gestão de rede é muito importante para um operador de rede, que deseja que esta permaneça confidencial. É assim necessário garantir que o TeMIPConnector não é utilizado para efectuar acessos não autorizados ao TeMIP. É também fundamental garantir a confidencialidade e integridade das comunicações com clientes remotos. No TeMIP podem existir mecanismos nativos de alta disponibilidade e de distribuição de carga, os quais não estão disponíveis no ambiente utilizado no âmbito desta tese. Caso existissem, o primeiro representaria a capacidade do TeMIPConnector superar falhas no servidor TeMIP, redireccionando os pedidos para outro servidor TeMIP replicado, o segundo possibilitaria atingir maior desempenho distribuindo os pedidos por vários servidores TeMIP replicados. Arquitectura da solução 78 4.2 – Arquitectura geral A Figura 16 descreve a arquitectura global do TeMIPConnector, onde as várias partes constituintes do TeMIPConnector estão representadas a cinzento e as aplicações com que este interage em diferentes cores: azul para os componentes J2EE, laranja para a máquina virtual Java, verde para o TeMIP e verde azulado para o Sistema Operativo. Bibliotecas Java para acesso remoto aos serviços J2EE (apenas é utilizado JMS) Serviço JMS Queues JMS Servidor RMI R JVM TalAccess Servidor J2EE M I/ T LS Conector (implementação da especificação JCA) TAL TeMIP Security Services JVM Tru64 Unix Sistema Operativo Figura 16 – Arquitectura global do TeMIPConnector O TeMIPConnector foi dividido em três componentes: Conector, a implementação da norma JCA, executado dentro do servidor J2EE, que permite a aplicações J2EE aceder às funcionalidades oferecidas pelo Servidor RMI. O Conector fornece a interface para o TeMIP realizar interrogações síncronas, através de métodos bloqueantes, e interrogações assíncronas, cujas respostas serão posteriormente entregues numa fila de mensagens. O Conector implementa ainda as interfaces JCA, possibilitando ao servidor J2EE a gestão de ligações e passagem de credenciais de segurança. Servidor RMI, o serviço que disponibiliza o acesso remoto. O Servidor RMI permite aceder remotamente aos serviços do TeMIP, possibilitando assim que as aplicações J2EE possam ser executadas noutras máquinas que não o servidor Arquitectura da solução 79 TeMIP. A comunicação entre o Conector e o Servidor RMI é efectuada sobre Transport Layer Security (TLS), e todos os pedidos são acompanhados de credenciais (username e password). TalAccess, a biblioteca que faz a interligação entre a linguagem Java e a linguagem C++, oferecendo uma interface Java para aceder às funcionalidades da biblioteca TAL, escrita em C++. Uma vez que o TalAccess utiliza a biblioteca Local TAL, apenas pode ser executada num servidor TeMIP. Para além de disponibilizar os serviços da biblioteca TAL, o TalAccess possibilita ainda a validação de username/password, recorrendo a chamadas de sistema, especificas de Tru64 Unix. A separação do TeMIPConnector nestes três componentes, com interfaces bem definidas entre eles, não é casual. A estrutura escolhida permite a reutilização destes componentes em outros tipos de aplicações que não J2EE. O TalAccess pode ser utilizado em aplicações Java, a correr na máquina com o TeMIP, para comunicar com o TeMIP. O Servidor RMI pode ser utilizado por aplicações remotas Java, não J2EE, para interagir com o TeMIP. Esta arquitectura dá resposta aos objectivos traçados na secção anterior. A simplicidade de utilização foi alcançada oferecendo ao programador a linguagem usada no TAL, a qual permite dar comandos e realizar interrogações ao TeMIP, através da utilização dum subconjunto da linguagem utilizada na interface de linha de comando: o FCL. Sendo uma linguagem proprietária do TeMIP, o FCL representa para este aquilo que o SQL representa para um SGBD. Embora o seu uso exija um esforço de aprendizagem, incluindo alguns conhecimentos do funcionamento do TeMIP, considerou-se preferível manter esta linguagem em alternativa a criar uma nova API, eventualmente mais simples e intuitiva, mas forçosamente mais limitada. A utilização desta linguagem permite ainda tomar partido da experiência já adquirida por administradores de TeMIP, que recorrem frequentemente ao FCL, principalmente para automatizar tarefas rotineiras. A instalação da aplicação TeMIPConnector num servidor TeMIP consiste apenas em copiar alguns ficheiros e registar a referida aplicação nesse servidor. Esta facilidade de instalação permite vencer a resistência de quem administra estas máquinas. Uma instalação complexa, que exigisse alterações no TeMIP, poderia por em causa a Arquitectura da solução 80 utilização do TeMIPConnector, por receio que este fosse interferir no regular funcionamento da Plataforma de Gestão. Assim, a única operação a efectuar no TeMIP é o registo da aplicação Servidor RMI, para que esta possa aceder aos serviços do TAL. Este registo não modifica a configuração ou funcionamento do TeMIP. A operação do Servidor RMI é ainda simplificada pelo facto de uma única instância deste servidor poder responder a pedidos de vários clientes (Conector) instalados em diferentes máquinas. A utilização da linguagem FCL, conjuntamente com a possibilidade de efectuar interrogações síncronas e assíncronas, significa que o TeMIPConnector pode ser utilizado para criar vários tipos de aplicações, uma vez que não restringe as funcionalidades oferecidas pelo TeMIP para aplicações de apresentação. As interrogações síncronas enquadram-se perfeitamente no modelo de funcionamento de RMI. O Conector realiza a interrogação e recebe a resposta. No entanto, este modelo não funciona para a recepção de eventos assíncronos pois um connector não pode funcionar como Servidor RMI, apenas como cliente. A especificação JCA 1.0 não prevê a recepção de eventos assíncronos, mas existem no J2EE outros mecanismos para o efeito: filas de mensagens. A solução escolhida para circundar as limitações do JCA foi associar a cada interrogação assíncrona uma fila para onde as respostas podem ser enviadas. Os componentes J2EE que utilizam o Conector podem depois retirar as mensagens da fila ou podem mesmo ser utilizados MDB que processam as mensagens à medida que estas chegam. Cada interrogação assíncrona é acompanhada pela indicação de uma queue de destino, para onde as respostas serão enviadas, podendo cada interrogação dar origem a um número arbitrário de mensagens, uma para cada resposta. A compatibilidade com servidores J2EE 1.3 é conseguida pelo facto de se ter procedido à implementação de todas as interfaces obrigatórios do JCA 1.0. No entanto, o CCI, uma interface opcional para o programador, não é implementado por ser considerado demasiado complexo, tendo em conta as funcionalidades oferecidas pelo TeMIPConnector. Sendo o CCI desenhado para abranger vários tipos de EIS, apresenta um nível de complexidade que não se adequa ao objectivo de simplicidade de utilização proposto. Como tal foi escolhido implementar uma API proprietária, apresentada na secção 4.5, que consiste apenas de três métodos: realizar interrogação síncrona, realizar interrogação assíncrona e cancelar interrogação assíncrona. Arquitectura da solução 81 A separação do TeMIPConnector nos componentes acima apresentados permite que o Conector seja implementado 100% em Java. O Conector usa os serviços do Servidor RMI para comunicar com o TeMIP, apresentando portabilidade através de qualquer plataforma (Sistema Operativo e arquitectura) em que possa ser corrido um servidor J2EE 1.3. Esta separação permite que o Conector seja utilizado em máquinas diferentes daquela em que o TeMIP é executado, eventualmente localizadas em locais afastados do servidor que contém o TeMIP. Caso o Conector interagisse directamente com o TalAccess, o que seria possível devido aos privilégios oferecidos pela arquitectura JCA, as aplicações que a ele recorressem teriam de ser instaladas, juntamente com o servidor J2EE na máquina que aloja o TeMIP. Permitir utilizar o Conector em outras máquinas alivia os servidores com o TeMIP de correr as aplicações J2EE, evitando assim prejudicar o desempenho do mesmo. A arquitectura escolhida transfere o máximo possível do esforço computacional para fora dos servidores com o TeMIP, permitindo assim manter o desempenho deste. As máquinas que executam o TeMIP são servidores especializados, dispendiosos, os quais não interessa sobrecarregar com outras aplicações. A arquitectura desenvolvida apresenta um bom desempenho pois embora induza algum atraso ao tempo de processamento de cada resposta, não limita o ritmo de respostas sustentado pelo TeMIP. O Servidor RMI apenas utiliza os serviços do TAL, não sendo intrusivo no regular funcionamento do TeMIP. Apesar disso, por não restringir os serviços do TAL a que os clientes podem aceder, existe sempre o risco de que os comandos emitidos por estes possam modificar o comportamento do TeMIP. É assim necessário garantir que os serviços oferecidos pelo Servidor RMI só são utilizados por quem está efectivamente autorizado a faze-lo. Cada chamada remota ao Servidor RMI é acompanhada por um par username/password, só sendo executada caso este seja aceite. Os utilizadores reconhecidos são os do sistema operativo Tru64, contribuindo assim para a facilidade de instalação e operação do TeMIPConnector. Todas as operações efectuadas pelo Servidor RMI no TeMIP são realizadas em nome de um único utilizador, sendo possível utilizar os serviços de segurança do TeMIP para restringir os privilégios oferecidos. Embora seja seguro admitir que os servidores que correm o TeMIP estão situados em redes privadas, devidamente protegidas, é possível que algumas das aplicações estejam fora, podendo a comunicação ser interceptada ou os interlocutores substituídos. A Arquitectura da solução 82 garantia de segurança levou assim à utilização de TLS na comunicação entre o Servidor RMI e os seus clientes. Desta forma, não só é garantida a confidencialidade das comunicações, como a autenticidade do servidor. A confidencialidade da comunicações é de extrema importância, pois cada pedido é acompanhado de um par username/password. Em ambientes seguros é possível prescindir deste serviço, aumentando o desempenho. A separação entre os componentes que correm na máquina com o TeMIP (TalAccess e Servidor RMI) e o componente que corre nos servidores J2EE (Conector) permite que um Servidor RMI sirva vários Conectores, mas também que cada Conector comunique com vários Servidores RMI. Caso o Conector saiba da existência de vários Servidores RMI, instalados em outros tantos servidores TeMIP replicados, pode distribuir os pedidos pelos vários Servidores RMI, realizando assim uma distribuição de carga. A alta disponibilidade pode ser conseguida em conjunção com a distribuição de carga, retirando da lista de servidores disponíveis aqueles que não respondem. Estes seriam periodicamente verificados, para serem novamente incluídos na lista caso recuperassem da falha apresentada. Num ambiente onde a distribuição de carga não fosse necessária, existiria apenas uma lista de Servidores RMI a serem utilizados caso o Servidor em uso na altura apresentasse uma falha. Neste cenário apenas é utilizado um Servidor RMI de cada vez. Embora a arquitectura tenha sido desenvolvida tendo em consideração os requisitos de distribuição de carga e alta disponibilidade, estes mecanismos não puderam ser implementados em virtude de não estar disponível o acesso a servidores TeMIP replicados. Arquitectura da solução 83 4.3 – Biblioteca TalAccess A interligação entre o TeMIP, através da sua interface TAL, e a linguagem Java é constituída por um componente denominado de TALAccess. Para além de permitir a programas Java acederem a alguns dos métodos do TAL, permite ainda validar pares username/password, recorrendo para isso aos Security Services do Tru64 Unix. A Figura 17 apresenta a estrutura da biblioteca TalAccess, a qual inclui uma parte em Java (TalAccess.java) e outra em C++ (TalAccess.cpp). As aplicações cliente utilizam a classe Java TalAccess, necessitando de implementar uma interface que permite à classe TalAccess executar alguns métodos de callback. Classe java cliente implementa interface TalAccessClient TalAccess.java JVM TalAccess.cpp TAL TeMIP Security Services Tru64 Unix Figura 17 – Arquitectura da biblioteca TalAccess O acesso a bibliotecas nativas em C ou C++ através de Java é possível graças ao JNI. Esta tecnologia permite declarar numa classe Java métodos nativos que são implementados em bibliotecas ligadas dinamicamente. Ao chamar estes métodos Java, a JVM executa o código nativo correspondente. Aplicações que recorrem a esta tecnologia deixam de ser portáveis, não podendo portanto ser executadas em qualquer JVM. No caso concreto da aplicação TalAccess, o uso de JNI não é um contratempo significativo pois o TeMIP só corre em Compaq Tru64 ou Sun Solaris. Arquitectura da solução 84 A biblioteca ligada dinamicamente é gerada a partir do ficheiro TalAccess.cpp, que disponibiliza métodos para: realização de interrogações síncronas e assíncronas; cancelamento de interrogações síncronas; verificação de username/password; reserva e libertação de recursos (chamadas no início e fim de programa); receber notificação de paragem do TeMIP. A classe Java TalAccess pode assim fornecer estes serviços a qualquer aplicação Java. Esta classe implementa ainda métodos de callback, permitindo a TalAccess.cpp entregar as respostas assíncronas e notificar da paragem do TeMIP. As respostas recebidas do TeMIP, em formato texto, são processadas antes de serem entregues ao cliente. A resposta a uma interrogação pode ser um erro, representado por uma excepção, ou um ResultSet, que transporta a resposta dada pelo TeMIP em “forma de tabela”. Foi escolhido representar as respostas através da interface java.sql.ResultSet pois este é um formato já conhecido de muitos programadores, e tem capacidade de se auto descrever. As aplicações cliente são obrigadas a implementar métodos a serem utilizados como callback para a entrega das respostas assíncronas e aviso da paragem do TeMIP. Estes métodos estão definidos na interface Java TalAccessClient. Arquitectura da solução 85 4.4 – Servidor RMI O Servidor RMI assenta sobre a biblioteca TalAccess, tal como representado na Figura 16, recorrendo ainda a outras bibliotecas para o envio de mensagens JMS. Disponibiliza a clientes remotos os seguintes serviços: validação de username/password, realização de interrogações síncronas e assíncronas, cancelamento de interrogações assíncronas e paragem do próprio Servidor RMI. Os pedidos de cancelamento e realização de interrogações são acompanhados de username/password, só sendo aceites aqueles cujas credenciais são válidas. Este servidor foi feito a pensar num cliente em particular, o Conector, que por sua vez oferece alguns destes serviços a aplicações J2EE. No entanto, qualquer aplicação Java que conheça os serviços disponibilizados poderá utilizar o Servidor RMI, fazendo com que este possa ser útil por si só. A utilização de TLS garante a autenticidade do servidor perante os clientes e a confidencialidade das comunicações. O TLS não é utilizado para garantir a autenticidade dos clientes uma vez que só são atendidos pedidos de utilizadores válidos. O servidor recebe apenas um parâmetro, que toma o valor “start” ou “stop”. O valor “start” leva o servidor a disponibilizar os seus serviços. Quando é lançada uma instância do servidor com o valor “stop”, esta tenta contactar outra instância, já em funcionamento, ordenando-lhe que pare. As funcionalidades do Servidor RMI não se limitam à simples delegação de tarefas à biblioteca TalAccess. Este necessita de manter informação sobre as interrogações assíncronas pendentes, de forma a saber para que queue enviar as respostas quando estas chegam. A cada interrogação assíncrona é atribuído um identificador inteiro. Este identificador permite cancelar a interrogação e associa cada mensagem de resposta à interrogação que lhe deu origem. De modo a limitar a interferência entre aplicações que usam o Servidor RMI, uma interrogação assíncrona pendente só pode ser cancelada pelo mesmo utilizador que a criou. Quando uma interrogação assíncrona é cancelada todas as suas mensagens ainda por entregar são apagadas. Quando não é possível enviar mensagens para uma determinada queue, as interrogações assíncronas que a têm como destino são canceladas. Arquitectura da solução 86 Sendo o envio das mensagens JMS um processo moroso, foi decidido separar a recepção das respostas da biblioteca TalAccess do seu envio para a respectiva queue. As mensagens são colocadas em espera, enquanto um conjunto de tarefas dedicadas, as vai enviando para o servidor JMS. Quando é solicitada a paragem do Servidor RMI ou este é notificado da paragem do TeMIP, inicia-se um processo de paragem. O Servidor RMI notifica todos os clientes com interrogações assíncronas pendentes através do envio de uma mensagem especial (contendo uma excepção Java). O Servidor RMI espera até atingir o limite de espera definido para se desligar, rejeitando todos os pedidos recebidos entretanto. Durante esse período de tempo tem a possibilidade de acabar de servir as interrogações síncronas em processamento. O servidor foi escrito de modo a poder ultrapassar erros ocorridos durante o processamento de cada pedido, fazendo com que erros ocorridos ao processar um pedido sejam contidos no âmbito desse pedido. Sempre que a comunicação com o servidor JMS é perdida, são realizadas tentativas de ligação, espaçadas no tempo, até a restabelecer. No entanto, como forma de garantir o seu aperfeiçoamento e registar erros apenas detectáveis em situações extremas, sempre que ocorram excepções inesperadas o servidor regista-as num ficheiro para posterior referência, podendo ainda enviá-las por email suscitando assim uma reacção rápida por parte do administrador. Como já foi referido, os pedidos efectuados ao Servidor RMI são acompanhados de um par username/password. O TeMIP possui um mecanismo completo de autenticação e autorização, no qual é possível restringir as operações que cada utilizador pode efectuar. Os utilizadores reconhecidos pelo TeMIP coincidem com os do sistema operativo, simplificando assim a sua manutenção. No entanto, devido à forma como o TAL está implementado foi necessário realizar alguns compromissos relativamente à segurança. O TAL efectua todas as operações em nome do utilizador que é dono do processo no momento em que o TAL é inicializado, não sendo possível definir em nome de quem se deseja executar determinada operação. Para mais, devido à forma como a API está implementada, o TAL é inicializado assim que o programa que o usa é lançado. Alterações posteriores ao uid do processo não surtem qualquer efeito. A única forma de o Servidor RMI responder a cada pedido executando-o em nome do utilizador que o Arquitectura da solução 87 efectuou seria mudar de uid, lançando de seguida um novo programa, que então efectuaria o pedido do cliente. A simples criação de um novo processo para servir o novo cliente, como é feito por muitos servidores, não surte qualquer efeito, pois o TAL não reconhece a mudança de uid. O lançamento de um novo programa externo, que por sua vez iria inicializar o TAL e efectuar a interrogação seria a única solução, mas implicaria um tempo de resposta mais elevado, sobrecarregando a máquina com o TeMIP. Adicionalmente teríamos ainda de contar com os recursos consumidos em comunicação inter processos para que a resposta pudesse ser transmitida ao Servidor RMI. O impacto seria ainda maior no caso das interrogações assíncronas, em que os programas teriam de ficar a correr durante muito tempo, podendo eventualmente levar ao esgotamento dos recursos do sistema operativo. Face a esta análise, foi decidido realizar algumas concessões no que diz respeito à utilização do sistema de autorização do TeMIP, preferindo não sacrificar o desempenho do sistema. Para garantir a autenticidade dos clientes, o Servidor RMI exige que cada pedido seja acompanhado de credenciais na forma de username/password. Estas são verificadas recorrendo ao TalAccess. As interrogações ao TeMIP são então todas efectuadas em nome de um único utilizador, aquele que lançou o Servidor RMI. Devido ao recurso, por parte do TalAccess, dos Security Services do Tru64 Unix, o Servidor RMI tem forçosamente de ser executado como root. Este utilizador não é normalmente utilizado no TeMIP, nem usufrui de privilégios superiores aos outros utilizadores, ao contrário do que se passa no sistema operativo. É assim possível restringir os privilégios deste utilizador no TeMIP, limitando assim de uma forma segura as operações que o Servidor RMI pode efectuar. O Servidor RMI poderá ser instalado em cenários muito diferentes pelo que todas as suas opções devem ser facilmente configuráveis. Ao arrancar o servidor lê um ficheiro de configuração, onde podem ser definidos: endereço de email para onde enviar alertas de ocorrência de situações inesperadas e respectivo servidor SMTP (Simple Mail Transport Protocol); ficheiro de histórico para registar erros inesperados; portos TCP a utilizar pelo servidor; número de tarefas dedicadas ao envio de mensagens JMS; opção de usar TLS; tempo máximo de espera pela terminação dos pedidos pendentes até parar o servidor. Arquitectura da solução 88 4.5 – Conector A implementação das interfaces JCA dá origem ao Conector, componente que permite a aplicações J2EE aceder ao TeMIP. Um connector é construído de acordo com as capacidades do EIS a que dá acesso. Neste caso não existe suporte para transacções uma vez que o TeMIP não suporta o conceito. A autenticação é realizada recorrendo a username/password. A única informação que o Conector associa a cada ligação são as credenciais do utilizador. Essas credenciais não ficam no entanto associadas a cada ligação física, uma vez que o Servidor RMI não mantém estado, sendo as credenciais enviadas com cada pedido. Desta forma a reautenticação de uma ligação é permitida, consistindo na troca das credencias que o Conector utiliza nas invocações ao Servidor RMI. Como não há manutenção de estado entre chamadas ao Servidor RMI, é possível fornecer o serviço de partilha e associação de ligações. Este permite ao container optimizar o desempenho de uma aplicação, fazendo com que pedidos de criação de uma ligação (classe Connection da Figura 14) por diferentes componentes incluídos na mesma transacção, resultem todos no uso da mesma ligação (classe ManagedConnection). É assim evitada a criação desnecessária de ligações. Foi escolhido implementar uma interface de cliente própria em detrimento do CCI. Para além de ser difícil de utilizar directamente por um programador, o CCI não prevê a recepção de respostas assíncronas. Foi assim desenvolvida uma API muito simples, constituída apenas por três métodos, que permitem a realização de interrogações síncronas e assíncronas, e proceder ao cancelamento destas últimas. Esta interface, embora peque por ser proprietária, consegue ultrapassar, de uma forma simples, a maior limitação da versão 1.0 da JCA: a impossibilidade de receber eventos assíncronos. De reparar que os eventos recebidos foram previamente solicitados, não sendo possível ao EIS iniciar a comunicação com o Conector, tal como proposto no draft da futura versão 1.5 da JCA. As interrogações assíncronas são possíveis de realizar através da indicação de uma queue JMS para onde as respostas devem ser enviadas pelo Servidor RMI. A criação das queues e o posterior processamento a dar às mensagens é da responsabilidade das Arquitectura da solução 89 aplicações que utilizam o TeMIPConnector. A mesma queue pode ser utilizada para o envio de respostas a várias interrogações, sendo que cada mensagem de resposta indica que interrogação lhe deu origem. A identificação de cada interrogação assíncrona é um número inteiro que é devolvido pelo Conector em resposta à criação da referida interrogação. No pedido de interrogação assíncrona o cliente passa directamente um objecto do tipo javax.jms.Queue para indicar onde as respostas devem ser entregues. Uma alternativa teria sido passar, em texto, o nome JNDI da queue que o Servidor RMI utilizaria para obter o objecto. A abordagem utilizada apresenta um melhor desempenho, ao poupar as consultas ao serviço JNDI por parte do Servidor RMI. Apresenta ainda a vantagem de não exigir que todas as queues estejam registadas num único directório JNDI. No entanto, esta técnica pode interferir com os mecanismos de replicação ou distribuição do servidor JMS. Caso se utilize um servidor JMS replicado ou distribuído, onde estes mecanismos sejam implementados no serviço JNDI, estes são ignorado. No entanto o próprio objecto queue pode ser utilizado para implementar a redundância e distribuição de carga, pelo que o impacto dependerá do servidor J2EE utilizado. Implementação 91 Capítulo 5 – Implementação Neste capítulo são apresentadas as decisões tomadas durante a fase de implementação do TeMIPConnector. Para cada componentes do TemipConnector, a biblioteca TalAccess, o Servidor RMI, e o Conector, são apresentados, nas respectivas secções, aplicações cliente desenvolvidas especificamente para os testar. Na primeira secção são apresentadas algumas das ferramentas escolhidas para o desenvolvimento do TeMIPConnector e dos vários programas de teste. Os detalhes de implementação de cada um dos componentes do TeMIPConnector são apresentados em secções separadas. Implementação 92 5.1 – Ferramentas utilizadas O desenvolvimento deste trabalho exigiu o recurso a compiladores e em especial a JVMs. O processo de desenvolvimento foi facilitado com o recurso a Integrated Development Environment (IDE), ferramentas de automação de construção (build tools) e ferramentas de gestão de configurações. Foi ainda necessário utilizar um servidor J2EE onde correr o Conector. Esta secção apresenta as ferramentas utilizadas. Sempre que possível tentou-se recorrer a software livre, de qualidade e fiabilidade comprovada e cuja divulgação não se restrinja exclusivamente a meios académicos, dado que o TeMIPConnector é passível de utilização em ambientes de produção típicos de organizações complexas e de grandes dimensões [96]. 5.1.1 – Java 2 Software Development Kit (SDK) Foram utilizadas JVM compatíveis com a versão 1.3 do Java 2, que era a versão mais recente existente para Tru64 e GNU/Linux aquando do início da implementação. Na máquina Tru64 4.0, onde o TeMIP 4.0.0 corre, recorreu-se à JVM da Compaq, a primeira JVM de 64 bit [97]. A versão utilizada foi o SDK 1.3.1-2. A máquina onde foi realizado o desenvolvimento e corridos alguns dos testes utilizava GNU/Linux. Para GNU/Linux existem outras JVM disponíveis, tendo sido escolhida a implementação da Sun, na versão SDK 1.3.1_03, a mais recente das implementações de Java 2 1.3 aquando do começo deste trabalho [73]. A comunicação entre o Servidor RMI e os seus clientes é realizada sobre TLS. Como tal, foi utilizada a Java Secure Socket Extension (JSSE) [98]. Como esta API ainda não está disponível na versão 1.3 do Java 2, apenas na 1.4, foi necessário instalar em ambas as JVM (Tru64 e GNU/Linux) a versão 1.0.2 da JSSE. Esta implementação é escrita 100% em Java, apresentando um desempenho sub óptimo. Implementações incluídas na própria JVM, como a presente no Java 2 1.4, podem potencialmente apresentar melhor desempenho ao serem implementadas em código nativo da arquitectura, não sendo assim necessário a JVM proceder à sua interpretação. Implementação 93 5.1.2 – Compilador C++ da Compaq O desenvolvimento da biblioteca ligada dinamicamente exigiu a utilização de um compilador C/C++ para a arquitectura Alpha. Foi utilizado o compilador DIGITAL C++ V6.1-029, incluído no Tru64 4.0 [99]. 5.1.3 – NetBeans/Forte4Java EE O recurso a ambientes integrados de desenvolvimento, que disponibilizam alguns wizards para a criação de esqueletos de código, pode acelerar em muito a produtividade. Infelizmente, muitas das tecnologias utilizadas eram demasiado recentes para serem suportados pelos IDE utilizados. Além disso o processo de compilação era demasiado complicado para poder ser realizado pelo IDE, tendo sido necessário recorrer a uma ferramenta externa. Ainda assim o uso de um IDE moderno, com syntax highlighting, auto completion, e outras facilidades, acelera muito o processo de desenvolvimento. Numa primeira fase foi utilizado o IDE NetBeans 3.2, produto de um projecto opensource patrocinado pela Sun [100]. Posteriormente, passou a ser utilizado o Forte For Java Enterprise Edition 4.0 Early Access Program da Sun. Este produto é baseado no NetBeans, mas inclui uma séria de módulos proprietários para o desenvolvimento em J2EE. O Early Access Program proporcionou uma licença temporária para utilizar o IDE enquanto este se encontrava na fase Beta. Este produto acabou por ser rebaptizado Sun One Studio 4 antes do seu lançamento [101]. 5.1.4 – CVS Um sistema de controlo de versões é útil não apenas quando se trabalha em equipa, mas também quando se trabalha sozinho, permitindo manter um repositório central com o histórico de todas as versões de cada ficheiro, incluindo descrições das alterações efectuadas em cada versão. Foi utilizado o Concurrent Versions System (CVS) [102]. O CVS é o sistema de controlo de configurações open-source dominante. O seu método de acesso cliente-servidor possibilita o acesso remoto ao repositório, existindo Implementação 94 ferramentas cliente para a maior parte das plataformas. O CVS é apenas um front-end para o Revision Control System (RCS) da GNU (GNU’s not Unix) [103]. Os IDE utilizados suportam o acesso directo ao repositórios CVS, podendo o controlo de versões ser realizado directamente no IDE. 5.1.5 – Ant O Ant é um dos sub projectos do projecto Jakarta da Apache Software Foundation, sendo assim open-source [104]. Trata-se de uma build tool à semelhança do Make que, no entanto, foi feita a pensar nas particularidades de um projecto escrito em Java, nomeadamente na necessidade da portabilidade do sistema de compilação. Sendo o código Java portável entre diferentes plataformas, a utilização de um sistema dependente da plataforma utilizada, como o Make, não faz sentido. O Ant já alcançou grande reconhecimento, sendo hoje a build tool utilizada na maior parte dos projectos Java open-source de grande dimensão, tais como o Tomcat, o JBoss ou o Netbeans. O Ant é escrito em Java e interpreta build scripts escritos em XML. Baseia-se no conceito de tarefa, podendo ser definidos grafos acíclicos de dependências entre as tarefas. Cada tarefa realiza trabalho recorrendo a comandos externos ou às sub tarefas definidas. O Ant é uma ferramenta muito completa, incluindo sub tarefas para a utilização de todas as ferramentas Java, tais como o compilador (javac), o gerador de documentação (javadoc) e a ferramenta de empacotamento (jar). Possibilita ainda a manipulação de ficheiro, alteração de ficheiros, execução de tarefas específicas de vários produtos utilizados em projectos de desenvolvimento (como o CVS), entre outras tarefas. A força do Ant reside na capacidade de criação de novas tarefas, bastando para isso escrever uma classe Java. Têm assim surgido muitos módulos adicionais para o Ant permitindo-lhe automatizar tarefas muito complexas, difíceis de executar com outras build tool. O XDoclet é uma dessas ferramentas, proporcionando a criação automática de ficheiros de deployment J2EE através de um conjunto de módulos Ant [105]. Para manter a portabilidade, o recurso a comandos externos deve ser evitado. No caso da biblioteca TalAccess é necessário utilizar essa funcionalidade para executar o compilador de C++, fazendo com que a tarefa de compilação da biblioteca TalAccess só possa ser executada em Tru64 Unix. Implementação 95 5.1.6 – Servidores J2EE O desenvolvimento do Conector e respectivas aplicações de demonstração impuseram a necessidade de um servidor J2EE 1.3. Este trabalho foi iniciado quando a norma JCA ainda estava em draft e o J2EE 1.3 por lançar, sendo a documentação existente muito escassa e limitada. Inicialmente, apenas a implementação de referência da Sun estava disponível, primeiro em Beta e só depois em versão final. Apenas alguns meses mais tarde ficou disponível a primeira implementação open-source suficientemente estável para poder ser utilizada, o JBoss 3.0.0. Embora desde então tenham surgido implementações do J2EE 1.3 mais robustas e fáceis de utilizar, estas são muito caras e as licenças para avaliação demasiado restritivas para poderem ser utilizadas. 5.1.6.1 – J2EE Reference Implementation A Sun, no papel de principal promotor da tecnologia J2EE, publica, juntamente com cada versão da especificação J2EE, uma implementação de referência [106]. Esta implementação não pode ser utilizada para fins comerciais, de modo a não oferecer concorrência às ofertas comerciais da Sun e parceiros envolvidos no processo de definição da norma. A implementação de referência da Sun é a primeira a estar disponível, sendo comum o lançamento de versões Beta a acompanhar os Draft da norma. A implementação de referência serve para demonstrar a viabilidade da tecnologia, não tendo como objectivos apresentar um bom desempenho ou apresentar características de alta disponibilidade. Caracteriza-se no entanto por apresentar uma interface intuitiva, sendo fácil de utilizar graças à deploytool, uma ferramenta gráfica para a criação dos ficheiros XML de configuração das aplicações, seu empacotamento e lançamento no servidor. A sua instalação é também extremamente simples, incluindo já um servidor de base de dados. Devido às limitações que propositadamente apresenta, não foi possível desenvolver todo o trabalho utilizando este servidor. Revelou-se muito difícil aceder ao serviço JMS remotamente, condição indispensável ao desenvolvimento do Servidor RMI uma vez que este servidor não está disponível para Tru64. Implementação 96 5.1.6.2 – JBoss O servidor open-source JBoss foi o escolhido, na sua versão 3.0.0, para a conclusão do trabalho [107]. Os seus criadores afirmam que este implementa completamente a norma J2EE 1.3, no entanto não possui certificação da Sun, como todos os servidores J2EE comerciais. A certificação implica custos monetários elevados, fora do alcance de um projecto open-source suportado apenas por trabalho voluntário e pelas receitas provenientes da venda de manuais e realização de sessões de formação. O facto da documentação não ser também livre é o principal defeito deste projecto. No caso particular da versão instalada, o servlet container é implementado recorrendo à versão 4.0.2 do conhecido servlet container open-source Apache Tomcat. Existem no entanto outras versões do JBoss que recorrem a um servlet container diferente. Foi escolhida esta versão pois o Tomcat é a implementação de referencia das normas JavaServer Pages (JSP) e Servlets, ambas parte do J2EE, sendo também utilizado na implementação de referencia do J2EE, da Sun. O Tomcat é mais um dos sub projectos do projecto Jakarta da Apache Software Foundation, tendo tido a sua génese em código doado pela Sun. Este servidor J2EE também inclui um servidor de bases de dados, fazendo com que esteja pronto a utilizar assim que é instalado. O processo de instalação é o mais simples possível, consistindo apenas na descompressão do ficheiro de que se fez download. No entanto este servidor não apresenta a facilidade de utilização da implementação de referência da Sun. Em particular, é sentida a falta de uma ferramenta para a configuração e lançamento das aplicações. No entanto, tem como vantagem a facilidade de lançamento das aplicações, onde basta copiar o ficheiro da aplicação para um determinado directório. A cópia de um novo ficheiro leva à remoção da antiga versão da aplicação e ao lançamento da nova contida no ficheiro, sem ser necessário relançar o servidor, permitindo assim um ciclo de desenvolvimento muito rápido. O servidor é 100% escrito em Java, podendo assim correr em qualquer plataforma que suporte Java 2 1.3, tornando-o perfeito para este projecto de carácter multi-plataforma. Foi possível correr o servidor em Tru64, embora posteriormente tenha sido decidido executá-lo em Linux de forma a não sobrecarregar a máquina com o TeMIP. Tal só foi possível devido à separação das bibliotecas cliente, que foram usadas para permitir ao Servidor RMI contactar o serviço JMS remotamente. Implementação 97 5.2 – Biblioteca TalAccess A biblioteca TalAccess realiza a interface entre a linguagem Java e os componentes não Java utilizados neste trabalho: a API TAL e os Security Services do Tru64. Esta biblioteca permite a aplicações Java aceder a estes serviços como se fossem implementados em Java, ignorando o facto destas serem bibliotecas C++. A Figura 18 oferece uma visão macroscópica do TalAccess, que pode ser dividido em duas partes: uma parte escrita em C++, que interage com o TAL e os Security Services do Tru64; outra escrita em Java, que constitui a interface a utilizar pelas aplicações Java. A utilização de código C++ num programa Java é possível, recorrendo ao JNI. Esta tecnologia permite definir, numa classe Java, métodos que não são implementados em Java mas sim em C ou C++. A classe Java TalAccess define vários destes métodos, denominados métodos nativos, que estão implementados numa biblioteca C++ ligada dinamicamente. A biblioteca C++ é carregada pela classe TalAccess, antes dos métodos nativos serem utilizados. Sempre que um dos métodos nativos do TalAccess é chamado, a JVM delega a execução desse método na biblioteca C++. TalAccess Componente Java JVM TalAccess Componente C++ TAL TeMIP Security Services Figura 18 – Biblioteca TalAccess A utilização de JNI apresenta a vantagem de permitir utilizar directamente as bibliotecas TAL e Security Services. No entanto, a utilização de código C++ compilado para uma determinada arquitectura significa a perda de portabilidade. Como consequência, a biblioteca TalAccess apenas pode ser utilizada num sistema Tru64 com o TeMIP instalado. Foi precisamente para ultrapassar esta limitação que foi desenvolvido o Implementação 98 Servidor RMI, que disponibiliza os serviços do TalAccess a clientes Java remotos. Estes clientes, por não utilizarem directamente o TalAccess, podem ser 100% Java e, como tal, são portáveis. Constituindo a biblioteca TalAccess a base desta tese, as decisões tomadas na sua implementação afectaram e condicionaram a implementação dos outros componentes que sobre ela assentam: Servidor RMI e Conector. Por sua vez, esta biblioteca foi condicionada por as bibliotecas que utiliza: o TAL e os Security Services. Como se poderá verificar ao longo desta secção, o TAL teve um grande impacto do desenho e implementação do TalAccess. 5.2.1 – API oferecida A biblioteca TalAccess foi projectada para dar resposta às necessidades específicas deste trabalho, mais concretamente para servir de base à construção do Servidor RMI. Apesar disso, foi realizado um esforço para que as funcionalidades oferecidas sejam suficientemente genéricas para que possam ser utilizadas por outras aplicações. Desta forma é possível conceber a sua utilização por aplicações Java 2 Standard Edition, que por isso não podem recorrer a um connector J2EE. Utilizando esta biblioteca é possível: verificar pares username/password, efectuar interrogações síncronas e assíncronas, cancelar interrogações assíncronas e receber notificação da paragem do TeMIP. As aplicações interagem com a biblioteca TalAccess através da classe TalAccess. Cada aplicação deve criar uma única instância desta classe, a qual utiliza para interagir com a biblioteca. Adicionalmente a aplicação deve criar um objecto que implementa a interface TalAccessClient, a ser utilizado pela biblioteca para entregar informação assíncrona através de funções de callback. A classe TalAccess oferece os seguintes métodos: • public TalAccess( TalAccessClient cli) throws TeMIPInitializationException – Construtor da classe. Recebe como parâmetro uma referência para o objecto que implementa as funções de callback, permitindo assim à biblioteca entregar as respostas a interrogações assíncronas e notificação do encerramento do TeMIP. Implementação 99 É ainda responsável pela inicialização das bibliotecas utilizadas pelo TalAccess: o TAL e os Security Services. • public void finish() – Método que termina a utilização da biblioteca. Deve ser chamado quando esta não é mais necessária. É responsável por libertar todos os recursos utilizados pela biblioteca, nomeadamente os referentes ao uso do TAL e dos Security Services. • public boolean checkPassword( String username, String password) throws TeMIPException – Este método permite validar um par username/password. Recebe um username e uma password e devolve True se estes estiverem correctos. A password é validada perante o sistema operativo, utilizando os Security Services. • public ResultSet syncQueryTal( String query) throws TeMIPException, SQLException – Permite realizar um interrogação, ou emitir um comando, ao TeMIP. Recebe como parâmetro um comando, definido na linguagem utilizada no FCL. Devolve um objecto do tipo java.sql.ResultSet com o resultado da interrogação ou comando. • public int asyncQueryTAL( String query) throws TeMIPException – Permite interrogar o TeMIP de forma assíncrona. As respostas serão posteriormente entregues à aplicação utilizando os métodos de callback definidos no objecto entregue através do construtor de TalAccess. Este método retorna imediatamente, sendo o processamento da interrogação realizado por outra tarefa. Devolve um inteiro que identifica univocamente a interrogação realizada, permitindo assim associar as respostas recebidas posteriormente à interrogação que lhes deu origem. • public boolean cancelAsyncQuery( int queryId) – Este método permite cancelar interrogações assíncronas pendentes, isto é, para as quais ainda não foi recebida a última resposta. Recebe um inteiro que representa a interrogação assíncrona a cancelar. Devolve True caso consiga cancelar a interrogação, ou False caso isso não seja possível, nomeadamente devido ao facto da interrogação já ter sido completamente processada. Implementação 100 As excepções lançadas por estes métodos serão apresentadas na próxima subsecção. Os métodos disponibilizados por TalAccess são todos thread-safe e reentrantes, podendo a única instância de TalAccess ser partilhada por várias tarefas simultaneamente, sem ser necessário sincronizar explicitamente o seu acesso. Ao tomar a seu cargo a sincronização, a biblioteca TalAccess consegue realizá-la com uma menor granularidade, permitindo um maior desempenho quando existem várias tarefas a utilizar concorrentemente a biblioteca. No entanto, quando existe apenas uma tarefa cliente os mecanismo de sincronização são utilizados na mesma, apesar de não serem necessários, resultando num desempenho inferior. Uma vez que as respostas assíncronas e a notificação de paragem do TeMIP podem chegar a qualquer momento, é necessário um mecanismo para entregar estes dados ao programa que utiliza a biblioteca. Para tal foi definida a interface TalAccessClient, a implementar pela aplicação cliente, que define dois métodos: • public void TeMIPShutdown() – Este método é chamado quando o TeMIP é parado, possibilitando assim à aplicação que utiliza o TalAccess parar ordeiramente quando os serviços oferecidos deixam de estar disponíveis. • public void deliverTalAsyncronousReply( TeMIPReply reply) – Permite a entrega das respostas às interrogações assíncronas à medida que estas ficam disponíveis. Cada resposta contém o identificador da interrogação que lhe deu origem. Este método é utilizado em exclusão mútua, não sendo necessário implementar esses mecanismos. A aplicação não deve realizar um processamento demorado sobre a resposta, correndo o risco de atrasar a entrega das respostas seguintes. Quando é necessário um processamento demorado, este método deve apenas receber as mensagens e transferi-las para outras tarefas, retornando imediatamente e deixando o processamento a cargo dessas tarefas. A interacção com o TalAccess é realizada através da classe TalAccess, da interface TalAccessClient e das classes utilizadas para representar a informação, que são apresentadas na próxima subsecção. A biblioteca TalAccess é assim relativamente simples de utilizar pois as interrogações ao TeMIP são emitidas na linguagem de comandos do próprio TeMIP. Caso tivesse sido escolhido implementar uma interface Implementação 101 que escondesse do programador a linguagem de comandos do TeMIP, a interface seria forçosamente mais complexa e limitaria a funcionalidade oferecida. 5.2.1.1 – Representação das respostas e erros O TAL possui um conjunto de classes destinados a representar as entidades manipuladas pelo TeMIP. A resposta à interrogação efectuada, seja ela síncrona ou assíncrona, é um conjunto de objectos do tipo TReply. Esta classe permite a decomposição da resposta em objectos de diferentes classes consoante o conteúdo da resposta. Transpor para Java todas estas classes e obrigar o utilizador a conhecê-las para poder utilizar o TAL pareceu desnecessário e excessivamente complexo. Uma análise detalhada às respostas devolvidas pelo TAL revelou que estas podem ser representadas em forma de tabela. Um objecto da classe TReply não contém mais do que um conjunto de pares nome/valor, e sempre que uma resposta devolve vários objectos do tipo TReply estes partilham pares com o mesmo nome. Este formato pode assim ser convertido para uma representação em tabela, similar à utilizada pelas Bases de Dados Relacionais, contribuindo cada TReply com uma linha. A Figura 19 ilustra o formato das respostas do TAL e a representação em tabela escolhida. No exemplo dado foi efectuada a interrogação “directory domain *” que devolve o lista de domínios registados no TeMIP. No ambiente de teste utilizado existem mais domínios que os apresentados na figura, sendo estes apresentados apenas a titulo de exemplo. Domain .Andar_5 Directory successful. DomainName = .Andar_5 Domain .BackBone Directory successful. DomainName = .BackBone Domain .Gestao Directory successful. DomainName = .Gestao Object Domain Domain Domain Domain Identifier .Andar_5 .BackBone .Gestao .Inesc DomainName .Andar_5 .BackBone .Gestao .Inesc Domain .Inesc Directory successful. DomainName = .Inesc Figura 19 – Transformação das respostas do TAL Do lado esquerdo observamos a representação em texto obtida através do método ToString() da classe TReply. Cada conjunto de três linhas diz respeito a um objecto Implementação 102 TReply. Os vários objectos TReply que fazem parte da resposta a cada interrogação podem ser obtidos todos de uma vez, no caso das interrogações síncronas, ou entregues um de cada vez, espaçados no tempo, no caso das interrogações assíncronas. Do lado direito da figura observamos a representação em tabela dos dados. Para além dos dados retirados das respostas, coluna “DomainName” no exemplo dado, existe em todas as respostas uma coluna com o nome “Object Identifier” que contém o identificador único de cada objecto. Esta coluna permite reconhecer o mesmo objecto quando este aparece em respostas diferentes. Esta característica é importante pois o TeMIP divide as informações relativas a um objecto em várias partições (identifiers, counters, status e characteristics), não permitindo o TAL que a mesma interrogação abranja mais que uma partição. Assim, é muitas vezes necessário realizar várias interrogações para obter toda a informação sobre uma entidade representada no TeMIP, permitindo a coluna “Object Identifier” relacionar os dados recebidos nas várias respostas. As respostas são transformadas em objectos de uma classe que implementa a interface java.sql.ResultSet, utilizada para aceder a Bases de Dados. Esta escolha deveu-se à popularidade das Bases de Dados Relacionais, o que faz com que existam muitos programadores familiarizados com esta interface. A interface java.sql.ResultSet define ainda métodos para descrever o conteúdo da tabela, através da interface java.sql.ResultSetMetaData, permitindo assim às aplicações processar as respostas mesmo não conhecendo à partida a sua estrutura. A interface ResultSetMetaData permite, entre outros, descobrir o número de colunas e conhecer o nome e o tipo de dados de cada coluna. Para além da classe ResultSet, a biblioteca TalAccess contém ainda outras classes destinadas a representar situações de erro. A Figura 20 apresenta as várias classes utilizadas pelo TalAccess nas respostas aos pedidos dos clientes. Nesta figura a classes são representadas por rectângulos com linha cheia enquanto que as interfaces são representadas por rectângulos com linha tracejada. Da mesma forma a herança é representada com linhas cheias e a implementação de interfaces por uma linha tracejada. A classe ResultSet é utilizada para entregar respostas correctas. No entanto uma interrogação pode também gerar erros. Esses erros são representados por duas Implementação 103 excepções que representam os dois tipos de erros gerados pelo TAL: excepções comuns e excepções especializadas. Estas três classes representam as respostas possíveis a uma interrogação válida, e todas elas implementam a interface TeMIPReply. java.sql. ResultSet java.io. Serializable TeMIPReply ResultSet TeMIP Common Exception TeMIP Specialized Exception java.lang. Exception TeMIP Exception TeMIPQuery Exception TeMIP Initialization Exception TeMIPSecurity Exception Figura 20 – Classes utilizadas nas respostas A interface TeMIPReply, implementada por todas as respostas, define dois métodos sem relevância para as interrogações síncronas, mas essenciais para as assíncronas. Estes métodos permitem saber qual a interrogação que deu origem à resposta e se a resposta é a última ou se ainda são esperadas mais respostas para essa interrogação. Pode também dar-se o caso do pedido não chegar sequer a ser processado, em virtude da interrogação estar mal formulada. Nesse caso é gerada uma excepção do tipo TeMIPQueryException. A excepção TeMIPInitializationException é devolvida pelo construtor da classe TalAccess quando não é possível inicializar os serviços necessários ao processamento dos pedidos. As excepções estendem a classe TeMIPException, possibilitando guardar a excepção que lhe deu origem. Este artifício é muito útil pois permite criar uma nova excepção, sem perder a informação sobre o evento que lhe deu origem, ao mesmo tempo que limita a quantidade de excepções que determinada parte de um programa necessita de estar preparado para receber. Implementação 104 A excepção TeMIPSecurityException é utilizada pelo Servidor RMI, sendo apresentada na respectiva secção. Todas as classes apresentadas implementam a interface java.io.Serializable de forma a poderem ser transportadas por RMI. 5.2.2 – Interacção com o TAL A biblioteca TAL contempla o uso sobre ambientes gráficos (X-Windows e Microsoft Windows), tendo sido desenhada para se integrar nesses ambientes e utilizar os respectivos sistemas de eventos. Quando é utilizada em aplicações não gráficas, com é o caso das aplicações para o qual o TalAccess foi pensado, o TAL toma forçosamente um papel central, não oferecendo grande flexibilidade quanto à forma como é utilizado. Um aspecto que teve especial impacto neste projecto foi a impossibilidade de definir o instante em que se pretende começar a utilizar o TAL. A utilização da biblioteca TAL é conseguida através da inclusão de uma macro, que define o objecto que representa o TAL como uma variável global, sendo este criado assim que o programa é lançado. Não é assim possível a um programa especificar quando deseja começar a utilizar o TAL, sendo os recursos necessários ao seu uso reservados no instante de lançamento do referido programa. O impacto desta particularidade reflectiu-se principalmente na impossibilidade de realizar interrogações em nome de utilizadores diferentes, consoante já referido na secção 4.4. A utilização de JNI para integrar código Java e C++ requer alguns cuidados especiais. Habitualmente a JVM trata sozinha do processo de garbage collection, podendo o programador ignorar o problema da libertação de memória. Quando está a executar código nativo, a JVM não tem qualquer tipo de controlo sobre as operações de memória efectuadas, pelo que é da inteira responsabilidade do programador garantir a inexistência de fugas de memória. O acesso a objectos Java em C++ tem de ser explicitamente declarado através dos métodos C++ existentes na API JNI. Caso não sejam utilizados estes métodos, a JVM não tem conhecimento de que os objectos estão a ser utilizados e pode recolhê-los antes do tempo, ou nunca os recolher, resultando numa fuga de memória. É assim fundamental declarar correctamente quando um objecto começa a ser acedido e quando deixa de o ser, para que o garbage collector possa conhecer o número correcto de referencias a cada objecto. Implementação 105 Em C++ é possível executar métodos de um objecto Java e aceder a tipos básicos de dados (int, char, float, java.lang.String, char[], etc.). Este acesso é feito directamente ao objecto, sendo criada mais uma referência para o objecto. No caso concreto de dados do tipo java.lang.String, é utilizado o método GetStringUTFChars para obter um char * que permite aceder à cadeia de caracteres. Posteriormente, é necessário utilizar o método ReleaseStringUTFChars para libertar a referência criada, permitindo que o garbage collector possa depois apagar o objecto quando este já não for necessário. Caso o método C++ retorne sem libertar essa referência, ela será mantida até ao final do programa, impossibilitando a recuperação da memória ocupada pelo objecto. 5.2.2.1 – Criação do objecto TalAccess As aplicações interagem com a biblioteca TalAccess através de um objecto da classe TalAccess. Ao contrário de todas as outras classes, que se encontram agrupadas em packages, esta é a única classe do projecto que não está contida num package. Não foi possível agrupar esta classe com as outras pois quando esta era integrada num package a JVM não conseguia carregar a biblioteca ligada dinamicamente. Não foi possível ultrapassar este aparente bug da JVM utilizada. Cada aplicação apenas pode criar um objecto desta classe, podendo, no entanto, o seu acesso ser partilhado por várias tarefas simultaneamente, sem necessidade de sincronização. A criação do objecto despoleta o carregamento da classe e respectiva execução do iniciador estático, seguida da execução do construtor utilizado. Quando a JVM carrega a classe TalAccess, o iniciador estático desta classe carrega a biblioteca nativa, gerada com o ficheiro TalAccess.cpp, apresentado na Figura 17. Todos os métodos nativos utilizados pela classe Java TalAccess são implementados em C++ neste ficheiro. Assim que esta biblioteca ligada dinamicamente é carregada, o TAL é inicializado. A Figura 21 apresenta o processo desencadeado pela execução do construtor de TalAccess. Nesta figura estão representados as várias partes intervenientes no processo, sendo estas, da esquerda para a direita: a aplicação Java que utiliza a biblioteca TalAccess, os componentes Java da biblioteca, os componentes C++ da biblioteca e o TAL. O tempo evolui de cima para baixo. Na figura cada coluna representa uma tarefa, sendo que colunas com a mesma cor representam a mesma tarefa, a executar código em Implementação 106 componentes diferentes. Neste caso a tarefa apenas está activa na coluna mais à direita. As setas a cheio representam a chamada a um método ou função e o respectivo retorno da resposta. Quando os métodos ou funções não retornam nenhum valor é utilizada uma seta a tracejado. Aplicação Java TalAccess Java TalAccess C++ TAL Criação de TalAccess Iniciação do TAL TalMainLoop WaitTalShutdown Notificação de paragem do TeMIP TeMIPShutdown (Notificação de paragem do TeMIP) Figura 21 – Início de utilização da biblioteca TalAccess e paragem do TeMIP A aplicação cliente, representada pela tarefa a verde, começa por chamar o construtor de TalAccess, de forma a obter o objecto que lhe permite usar a biblioteca. O construtor de TalAccess chama primeiro o método nativo de inicialização. Este método constrói as estruturas e efectua as operações necessárias ao uso do TAL e dos Security Services, utilizados respectivamente para comunicar com o TeMIP e verificar as passwords. De seguida este construtor lança duas tarefas, destinadas a ficar bloqueadas numa chamada a um método nativo: • A primeira destas tarefas, representada a amarelo, chama um método nativo que invoca a função TalMainLoop() do TAL. Este método, já apresentado na secção 3.1.2, destina-se a fornecer ao TAL um meio de processar a entrega das respostas em ambientes não gráficos. Antes de realizar a chamada ao método TalMainLoop, o código C++ guarda os dados referentes ao contexto da tarefa Java que o invocou. Este contexto será utilizado posteriormente para efectuar a entrega das respostas assíncronas. • A segunda tarefa, apresentada na Figura 21 a azul claro, chama um método nativo, WaitTalShutdown, que fica bloqueado num semáforo. Esse semáforo Implementação 107 será sinalizado quando o TeMIP for desligado. Assim que a chamada ao método nativo retorna, o TalAccess pode chamar a função de callback do cliente, permitindo assim à aplicação que usa o TalAccess terminar ordeiramente. 5.2.2.2 – Notificação de paragem do TeMIP A Figura 21 ilustra também os acontecimentos provocados pela paragem do TeMIP. Aquando da paragem do TeMIP, o TAL executa uma função de callback no componente C++ da biblioteca TalAccess, representada a azul-escuro. Esta função sinaliza o semáforo onde está bloqueada a tarefa criada pelo construtor de TalAccess, a tarefa azul clara, permitindo à função retornar. Após o retorno da chamada ao método nativo, a tarefa Java, chama o método TeMIPShutdown do programa cliente, definido na interface TalAccessClient, permitindo a este terminar a aplicação da forma que desejar. Esta tarefa termina logo a seguir. É de realçar que a função de callback inicialmente chamada pelo TAL, representada a azul-escuro, nunca retorna. Devido à forma como o TAL foi implementado, o retorno dessa função significa o fim do programa cliente, pois o TAL toma a liberdade de findar a execução da aplicação cliente. Desta forma, após assinalar o semáforo que bloqueia a tarefa azul clara, esta função bloqueia-se, para sempre, nesse mesmo semáforo, dando oportunidade à aplicação cliente de levar o tempo que necessitar até terminar. Este procedimento não interfere com a paragem do TeMIP. Quando o TeMIP pára, o TAL deixa de funcionar, não existindo um esquema semelhante ao da paragem para notificar o arranque do TeMIP. Também devido à forma como a interacção com o TAL é iniciada, declaração de uma variável global e não uma chamada explícita a um método, não é possível ir verificando periodicamente se o TeMIP volta a estar disponível. Este modelo foi concebido para as aplicações terminarem ao mesmo tempo que o TeMIP, sendo adequado a aplicações satélite do TeMIP. Caso a aplicação tivesse sido apenas escrita em C++, e uma vez que tem de ser registada no TeMIP antes de ser utilizada, seria possível ao TeMIP voltar a lançar a aplicação quando arrancasse. Desta forma, após a terminação do TeMIP não é possível re-iniciar automaticamente as aplicações clientes do TalAccess, sendo necessário voltar a lançar as aplicações manualmente, ou através de scripts, quando o TeMIP é relançado. Implementação 108 5.2.2.3 – Fim da utilização da biblioteca TalAccess Quando uma aplicação cliente finda a utilização da biblioteca TalAccess deve indicá-lo, de forma a permitir a libertação dos recursos ocupados por esta. O processo de libertação de recursos, descrito de seguida, também pode ser chamado pela própria biblioteca quando o objecto da classe TalAccess é recolhido pelo garbage collector, quer devido à terminação da aplicação, quer devido a uma fuga de memória. A Figura 22 ilustra este processo. Aplicação Java TalAccess Java finish() TalAccess C++ nFinish() TAL Interrogação assíncrona Resposta assíncrona Shutdown() Figura 22 – Paragem da biblioteca TalAccess O processo de paragem da biblioteca TalAccess começa quando a aplicação cliente, representada pela tarefa verde, chama o método finish, que por sua vez chama a função C++ nfinish. Esta é responsável por executar as seguintes tarefas, por esta ordem: • Finalizar o uso da biblioteca Security Services libertando os recursos ocupados por esta. • Parar a biblioteca TAL. Este processo envolve chamar o método Shutdown do TAL, o que apenas pode ser realizado no contexto de uma tarefa iniciada pelo próprio. Assim, é criada uma interrogação assíncrona, o que causará a chamada de uma função de callback, pelo TAL, para entregar a resposta. Após criar a interrogação, já se pode passar ao próximo passo. Quando a função de callback, representada a azul-escuro na figura, é chamada, por ser executada pelo TAL, pode chamar o método Shutdown, dando origem à paragem do TAL. • Assinalar o semáforo onde a tarefa representada a azul claro, que aguarda a paragem do TeMIP está bloqueada, permitindo a esta terminar. Devido ao uso de Implementação 109 uma flag a tarefa sabe que o TeMIP não parou, pelo que ao retornar não vai levar o código Java a assinalar à aplicação cliente a paragem do TeMIP. A tarefa representada a amarelo, responsável pela execução do método TalMainLoop, nunca termina, pois mesmo com a paragem do TAL este método nunca termina. Assim as aplicações necessitam de realizar uma chamada a System.exit() para terminar, caso contrário a JVM ficará eternamente a aguardar o fim da referida tarefa. 5.2.2.4 – Interrogações síncronas As interrogações síncronas são realizadas chamando o método syncQueryTal de TalAccess. O processo desencadeado é ilustrado na Figura 23. O processo envolve a execução de código aos vários níveis da biblioteca, mas sempre pela mesma tarefa, iniciada pela aplicação cliente. Aplicação Java TalAccess Java syncQueryTal (Interrogação síncrona) TalAccess C++ nSyncQueryTal (Interrogação síncrona) Resposta TAL Interrogação síncrona Resposta Resposta Figura 23 – Realização de uma interrogação síncrona O método syncQueryTal delega a interrogação ao método C++ nSyncQueryTAL, o qual é responsável por usar os serviços do TAL para obter as respostas à interrogação. Como o nome indica, este método interage com o TAL de forma a apenas retornar quando possui todas as respostas à interrogação realizada. Quando termina devolve uma sequência de caracteres com a representação em texto da referida resposta, conforme representado na Figura 19. Na realidade o texto devolvido é a concatenação das várias respostas que a interrogação produziu. Durante a sua execução, o método nativo nSyncQueryTAL pode encontrar situações de erro. Nesse caso é lançada directamente pelo código C++ a excepção Java adequada, recorrendo para isso aos métodos C++ que o JNI proporciona. A excepção não é interceptada por os componentes Java de TalAccess, sendo passada directamente à aplicação cliente. Implementação 110 A passagem das respostas do TAL entre o C++ e o Java é efectuada em formato de texto pois é um tipo de dados partilhado entre as duas linguagens (char *, java.lang.String). A classe TReply contém o método ToString() que permite passar a resposta para texto, podendo depois ser processado em Java de forma a construir o objectos de classe ResultSet. O texto obtido é transformado num ResultSet, conforme explicado na secção 5.2.1.1, recorrendo ao método auxiliar TeMIP2ResultSet. 5.2.2.5 – Verificação de username/password A verificação de username/password ocorre de um modo em tudo semelhante ao descrito para as interrogações síncronas, mas neste caso em vez do TAL são utilizados os Security Services, além de que a resposta não implica o processamento anteriormente descrito para as respostas do TAL. O método C++ responsável pela validação das password começa por aceder à informação de segurança do utilizador, para poder submeter a password ao mesmo algoritmo de digest utilizado pelo sistema operativo quando guardou a password gerada para o utilizador. Só então é comparado o digest obtido com o que se encontra guardado no sistema. Embora as situações que podem ocorrer sejam variadas (utilizador não existente, password errada, utilizador temporariamente suspenso da utilização da máquina, etc.), a biblioteca apenas retorna se o par username/password é valido ou não, limitando assim a sua hipotética utilidade para ataques ao sistema. 5.2.2.6 – Interrogações assíncronas Uma interrogação assíncrona dissocia a realização da interrogação da entrega das respostas. Ao realizar uma interrogação assíncrona, a aplicação cliente tem de estar preparada para receber posteriormente as respostas, uma a uma, à medida que estas ficam disponíveis. O TeMIP define, na sua linguagem de comandos, vários tipos de interrogações que apenas podem ser efectuadas de modo assíncrono, principalmente a notificação da ocorrência de determinado evento, como a criação de um alarme, ou alteração do estado de determinada entidade. É possível indicar o número de eventos Implementação 111 que se pretende receber ou o limite de tempo que se deseja esperar pela ocorrência do evento. Todas as interrogações síncronas podem ser efectuadas de modo assíncrono. A Figura 24 apresenta o processo de realização de interrogações assíncronas e recepção das respostas geradas. O processamento associado é bastante mais complexo do que o das interrogações síncronas, podendo-se considerar a existência de três fases: a realização da interrogação em si, a entrega das respostas e o eventual cancelamento da interrogação. Aplicação Java TalAccess Java TalAccess C++ TAL Criação de TalAccess Iniciação do TAL TalMainLoop WaitTalShutdown asyncQueryTal (Interrogação assíncrona) Identificador (0) nAsyncQueryTAL (Interrogação assíncrona) Identificador (0) Interrogação assíncrona Identificador (0) Resposta assíncrona (0) Resposta assíncrona (0) Resposta assíncrona (0) Resposta assíncrona (0) Resposta assíncrona (0) Resposta assíncrona (0) Interrogação assíncrona Identificador (1) Interrogação assíncrona Identificador (1) Interrogação assíncrona Identificador (1) Resposta assíncrona (0) Resposta assíncrona (0) Resposta assíncrona (0) Resposta assíncrona (1) Resposta assíncrona (1) Resposta assíncrona (1) Resposta assíncrona (0) Resposta assíncrona (0) Resposta assíncrona (0) Figura 24 – Realização de uma interrogação assíncrona A Figura 24 começa com a criação do objecto TalAccess, etapa já apresentada na secção 5.2.2.1, mas repetida nesta figura para contextualizar as várias tarefas utilizadas. Quando a aplicação cliente, representada pela tarefa verde, deseja efectuar uma interrogação assíncrona, utiliza o método asyncQueryTAL, que por sua vez delega esta responsabilidade ao método C++ nAsyncQueryTAL. Implementação 112 O método C++ cria o objecto que representa a interrogação e transmite-o ao TAL, juntamente com a indicação de qual a função de callback a utilizar para entregar as respostas. O objecto que representa a interrogação possui um identificador inteiro, único. Esse identificador será utilizado pela biblioteca TalAccess e pelas aplicações cliente para cancelar uma interrogação ou relacionar as respostas com a interrogação que lhe deu origem. Antes de retornar, devolvendo o identificador atribuído à interrogação, o método C++ guarda o objecto que representa a interrogação numa HashTable, usando o identificador como chave. O código Java não guarda os identificadores gerados. A criação da interrogação assíncrona pode não ser possível quando esta está mal formulada. Nesse caso o código C++ lança directamente a excepção Java TeMIPQueryException. Esta excepção não é interceptada pela componente Java do TalAccess, sendo recebida directamente pela aplicação cliente. Quando o TAL está em posse de uma resposta para uma interrogação assíncrona entrega-a utilizando a função de callback definida, cuja execução é representada a azulescuro. Esta função é a mesma para todas a interrogações assíncronas. A função processa cada resposta recebida, determinando a interrogação que lhe deu origem, verificando se ainda vão ser recebidas mais respostas para essa interrogação, extraindo o texto da resposta e definindo o tipo de resposta: correcta, excepção comum ou excepção especializada. Caso a resposta seja a última esperada, já não vai ser necessário cancelar a interrogação que lhe deu origem, pelo que o objecto correspondente é removido da HashTable. Assim que todos os dados referentes à resposta estão disponíveis esta deve ser entregue ao método de callback Java de TalAccess. A passagem das respostas entre o componente C++ e o componente Java deparou com um obstáculo: um método C++ apenas pode executar uma chamada a código Java utilizando o contexto de uma tarefa Java, conhecida pela JVM. Apenas é possível a código nativo solicitar a criação desse contexto em Microsoft Windows, pelo que essa opção esta fora de alcance. Tipicamente código Java é executado por código C++ que por sua vez já foi chamado por código Java, algo que não acontece quando o TAL entrega uma resposta. Implementação 113 A solução foi utilizar o contexto de uma tarefa Java que não estivesse a ser executada pela JVM. O contexto da tarefa Java criada para executar o TalMainLoop(), representada a amarelo, está disponível precisamente para este fim. É utilizando este contexto que as respostas são entregues ao TalAccess pelo código nativo, recorrendo à exclusão mútua pois apenas está disponível o contexto de uma tarefa. Embora a tarefa que executa código Java não tenha sido originalmente criada pela JVM (foi criada pelo TAL), esta consegue executar código Java pois ao usar o contexto Java de uma tarefa criada pela JVM está a fazer-se passar por uma tarefa conhecida da JVM. Esta operação é possível pois o JNI representa o contexto de uma tarefa Java através de um objecto, o qual pode ser guardado e utilizado posteriormente por outra tarefa. Na Figura 24 observamos a tarefa criada pelo TAL para entregar a resposta representada a azul-escuro. Quando executa o código Java essa mesma tarefa desaparece, sendo confundida com a tarefa amarela, já existente e bloqueada a executar código C++. A intenção é realçar que a JVM acredita estar a executar a tarefa amarela, devido à utilização do seu contexto Java, muito embora na realidade esteja a executar outra tarefa, criada pelo TAL. Quando o método de callback Java de TalAccess recebe uma resposta cria o objecto ResultSet correspondente, que é então devolvido ao cliente através do método de callback definido em TalAccessClient. A resposta entregue pelo componente C++ é uma sequência de caracteres, tal com exemplificado na Figura 19. Mas no caso das interrogações assíncronas, apenas é entregue uma resposta de cada vez, e não todas de uma vez só, como nessa figura. Como resultado, todos os objectos ResultSet entregues à aplicação cliente contêm apenas uma linha da tabela. É utilizada uma única tarefa para entregar as respostas entre os componentes C++ e Java. É essa tarefa, representada a amarelo nos componentes Java, que irá executar o método deliverTalAsyncronousReply da aplicação cliente. Caso o processamento efectuado pela aplicação cliente seja muito demorado, é possível conceber que a utilização de uma única tarefa seja insuficiente, limitando o desempenho. Os testes efectuados sobre as aplicações desenvolvidas permitiram concluir que no hardware disponível uma tarefa é suficiente. No entanto, caso venha a ser utilizada em máquinas multi-processador, em que o TeMIP consiga obter ritmos de reposta mais elevados, pode ser vantajoso criar mais tarefas. Esta via não foi seguida, pois como explicado, as Implementação 114 tarefas têm de ser criadas pela JVM logo no início da utilização da biblioteca. A criação é realizada por código Java, e estas têm de ficar bloqueadas a executar código C++, para que o seu contexto esteja disponível ao componente C++. Estas tarefas consumiriam recursos mesmo que nunca chegassem a ser utilizadas. 5.2.2.7 – Cancelamento de interrogações assíncronas Quando um cliente pretende cancelar uma interrogação assíncrona que está pendente, apenas tem de indicar o seu número. Mais uma vez o pedido é delegado ao código C++ sem que haja processamento em Java. O código nativo procura o objecto que representa a interrogação na HashTable e utiliza-o para cancelar a pergunta, removendo depois o objecto. Quando a operação é bem sucedida é devolvido True, sendo False devolvido quando o identificador dado não corresponde a uma interrogação pendente. 5.2.3 – Limitações da biblioteca TalAccess O TeMIP obriga a que as aplicações sejam registadas previamente ao seu uso. A inicialização do TAL indica o nome registado, sendo que o TeMIP só aceita o cliente do TAL caso a aplicação seja reconhecida. O propósito do registo, que apenas pode ser efectuado por utilizadores privilegiados, é garantir que apenas aplicações autorizadas acedem ao TeMIP. O processo de registo inclui a indicação do executável do programa, para que o TeMIP possa, ele próprio, lançar a aplicação. No entanto, o TeMIP só lança aplicações na forma de executáveis sem parâmetros, recusando-se a lançar scripts. Visto que a aplicação é desenvolvida em Java é necessário invocar a JVM com uma série de parâmetros para executar a aplicação. É assim necessário lançar as aplicações que recorrem ao TalAccess manualmente, o que tem como vantagem o facto de poderem todas partilhar o mesmo registo no TeMIP. Todas as interrogações são efectuadas em nome do utilizador dono do processo. Não é possível, pelas razões já apresentadas na secção 4.4, alterar o utilizador em nome do qual as interrogações são processadas. Por outro lado, os programas que recorrem ao TalAccess têm de correr com privilégios de root pois só este utilizador pode aceder aos Security Services do Tru64 Unix. Como consequência, todos os acessos ao TeMIP vão ser efectuados com os privilégios associados a este utilizador. Os privilégios que o TeMIP associa ao utilizador root podem ser definidos, não sendo necessário que este Implementação 115 utilizador disponha do mesmo nível de privilégios de que usufrui a nível de sistema operativo, podendo mesmo ter menos privilégios que os outros utilizadores. 5.2.4 – Testes da biblioteca TalAccess - Cliente local O desenvolvimento do TalAccess foi acompanhado pelo desenvolvimento de uma aplicação de testes. Trata-se de uma interface de linha de comando, que permite realizar interrogações síncronas e assíncronas. Esta aplicação recebe como parâmetros a interrogação a realizar, seguida, opcionalmente, de um “s” ou “a” para indicar se a interrogação deve ser executada em modo síncrono ou assíncrono. Quando o segundo parâmetro não é especificado, a interrogação é realizada em modo síncrono. Esta aplicação, cuja arquitectura é apresentada na Figura 25, é constituída por uma única classe, LocalPromptTalAccess, que utiliza directamente a biblioteca TalAccess, implementando a interface TalAccessClient. Cliente Local LocalPromptTalAccess TalAccess JVM TAL TeMIP Security Services Tru64 Unix Figura 25 – Posicionamento do cliente local A aplicação começa por criar o objecto TalAccess, recorrendo a ele para realizar a interrogação. O resultado é apresentado ao utilizador recorrendo ao método toString() de ResultSet, que devolve o texto do resultado formatado como uma tabela. No caso das interrogações síncronas o programa escreve o resultado e termina. As interrogações assíncronas resultam na entrega de várias respostas, pelo que o programa apenas termina após receber e apresentar a última. Implementação 116 5.3 – Servidor RMI O Servidor RMI foi criado para proporcionar acesso remoto às funcionalidades oferecidas pelo TalAccess. Embora possa ser utilizado por qualquer cliente Java que conheça a API, o Servidor RMI foi especificamente construído para satisfazer as necessidades do Conector. É o Servidor RMI que permite ao Conector, e às aplicações que o utilizam, funcionar em máquinas diferentes das que se utilizam para o TeMIP, evitando assim sobrecarregar estas últimas. O modelo de comunicação fornecido pelo RMI, a invocação remota de métodos, adequa-se bem a todas as funcionalidades oferecidas pela biblioteca TalAccess, excepto a uma: as interrogações assíncronas. Utilizar sobre RMI um mecanismo de callback para entregar as respostas assíncronas, semelhante ao utilizado pelo TalAccess, implicaria que os clientes também teriam de funcionar como servidores RMI. Esta é precisamente uma das limitações impostas aos componentes J2EE, que não podem funcionar como servidores RMI. Ainda que fosse possível entregar as respostas ao Conector, que goza de privilégios especiais oferecidos pela arquitectura JCA, este não teria maneira de as encaminhar para as aplicações cliente. A JCA 1.0 não especifica mecanismos para a entrega assíncrona de informação à aplicação cliente. O J2EE inclui um serviço de mensagens, o JMS, que permite a comunicação assíncrona entre componentes através do modelo Publish/Subscribe ou Point-to-Point. O modelo Point-to-Point foi escolhido para colmatar as deficiências da JCA, ao permitir o envio assíncrono de mensagens contendo as respostas, entre o Servidor RMI e os clientes do Servidor RMI ou do Conector. Como tal, ao executar o Servidor RMI é necessário garantir que este tem acesso às bibliotecas JMS especificas do servidor utilizado, conforme representado na Figura 16. A fim de garantir o melhor desempenho possível para o Servidor RMI, este não guarda estado sobre os utilizadores, sendo cada pedido tratado independentemente. Deste modo o Servidor RMI não necessita de gastar recursos para manter o estado de todos os clientes. Como consequência, a informação de autenticação (username/password) tem de ser transmitida em cada pedido, aumentando o risco de esta poder ser escutada. Foi Implementação 117 portanto necessário garantir a confidencialidade e integridade dos pedidos efectuados. Para tal foi escolhido transportar o RMI sobre TLS recorrendo ao JSSE. É importante realçar, que embora a comunicação seja segura nos dois sentidos, o objectivo principal era proteger as interrogações, que continham o username e password do utilizador. Não se considerou tão relevante a confidencialidade das respostas. Assim, embora as respostas síncronas sejam confidenciais, em virtude do uso de RMI sobre TLS, as respostas assíncronas são confiadas ao serviço JMS em claro. Codificar as mensagens assíncronas antes de as passar ao serviço JMS requereria uma troca de chaves entre o Servidor RMI e cada cliente, obrigando o Servidor a manter estado sobre os clientes. Adicionalmente, obrigava cada cliente a ser capaz de descodificar as mensagens, aumentando a sua complexidade. Caso seja necessário garantir a confidencialidade das mensagens assíncronas, pode ser utilizado um servidor JMS que forneça esse serviço, transparentemente, ficando ao cuidado do administrador de sistemas a sua configuração A utilização de TLS implica o uso de certificados, utilizados na negociação da chave secreta de cada ligação. Só é utilizado um certificado para o Servidor RMI, já que o uso de username/password é suficiente para garantir a autenticidade dos clientes. Durante o desenvolvimento desta tese foi criado um certificado auto-assinado para ser utilizado pelo Servidor RMI. Uma vez que este certificado não era reconhecido pelos clientes, devido a não ser assinado por uma autoridade certificadora reconhecida, foi também necessário instalá-lo nos clientes, adicionando-o à lista de autoridades de topo reconhecidas. Se for utilizado um certificado criado por uma autoridade certificadora reconhecida por a implementação de JSSE utilizada, não será necessário fornecer o certificado aos clientes. 5.3.1 – API oferecida A API disponibilizada permite aceder remotamente aos serviços do TalAccess. No entanto, para evitar acessos não autorizados, todos os pedidos têm de ser acompanhados por um username/password válidos na máquina onde o Servidor RMI corre. Os clientes do Servidor RMI têm à sua disposição uma API constituída por quatro métodos: Implementação • boolean 118 checkPassword( String username, String password) throws RemoteException, TeMIPException: permite realizar a validação de um par username/password contra os utilizadores da máquina Tru64 onde o Servidor RMI foi instalado. Os utilizadores do TeMIP são os do sistema operativo Tru64. • ResultSet synchronousTALQuery( String query, String username, String password) throws RemoteException, TeMIPException: permite executar uma interrogação síncrona. Esta só será efectuada caso o username/password esteja correcto. É devolvido um ResultSet com a resposta. • int asynchronousTALQuery( Queue destQueue, String query, String username, String password) throws RemoteException, TeMIPException: permite executar uma interrogação síncrona. Esta só será efectuada caso o username/password esteja correcto. As respostas serão posteriormente entregues, utilizando mensagens JMS, na fila de mensagens indicada no parâmetro destQueue. É devolvido o identificador atribuído a esta interrogação. • void cancelAsyncTALQuery( int queryId, String username, String password) throws RemoteException, TeMIPException: permite cancelar uma interrogação assíncrona que ainda está em processamento. A interrogação a cancelar é identificada através do inteiro que foi devolvido aquando da sua criação. As interrogações assíncronas apenas podem ser canceladas pelo mesmo utilizador que as criou. Os três últimos métodos podem devolver a excepção SecurityException, apresentada na Figura 20, quando a autenticação do utilizador falha, não executando assim qualquer operação. Todas as outras classes apresentadas na Figura 20 são também utilizadas pelo Servidor RMI, para os mesmos propósitos que o TalAccess lhes destina. 5.3.2 – Funcionamento O Servidor RMI assenta sobre a biblioteca TalAccess, necessitando assim de ser executado pelo utilizador root. O programa é constituído por quatro ficheiros: o ficheiro jar com todas as classes que constituem o programa, incluindo as classes de TalAccess; a biblioteca ligada dinamicamente, que faz parte da biblioteca TalAccess; um shell Implementação 119 script utilizado para lançar o programa; o ficheiro de policy destinado a indicar à JVM as permissões de que o Servidor RMI necessita para trabalhar. Para além dos ficheiros que constituem o Servidor RMI, a JVM necessita ainda de ter acesso às bibliotecas que este utiliza. Assim, é necessário garantir que a JVM tem no seu classpath as bibliotecas para envio de emails e para a utilização do serviço de JMS. 5.3.2.1 – Arranque O Servidor RMI aceita apenas um parâmetro, que indica se se deseja lançar o serviço ou pará-lo. Quando esse parâmetro toma o valor “start” o Servidor RMI lança os seus serviços. O primeiro passo efectuado pelo Servidor RMI ao arrancar é ler o ficheiro de configuração. Do ficheiro de configuração, o servidor retira a informação de que necessita: endereços de origem e destino dos emails de alerta; subject dos emails de alerta; servidor SMTP a utilizar para enviar os emails de alerta; nome do ficheiro de histórico onde serão registados todos os eventos; nome do ficheiro de histórico onde pode, opcionalmente, ser registada informação sobre cada pedido feito ao servidor; número de tarefas a criar para envio das respostas assíncronas; informação necessária para contactar o servidor JMS; portos IP a utilizar pelo servidor e pelo RMIRegistry, o serviço de nomes onde o servidor anuncia os seus serviços; nome sobre o qual o Servidor RMI se regista no RMIRegistry; nome DNS a anunciar pelo servidor; tempo de espera para conclusão das tarefas em curso quando o servidor pára; indicação se o servidor deve utilizar TLS para garantir a segurança da comunicação com os clientes. De seguida o servidor lança o serviço RMI e inicia o serviço de histórico, para que as mensagens relativas ao lançamento do servidor possam ser registadas, assim como eventuais erros que possam impedir o arranque do servidor. Estando o serviço RMI disponível é necessário registá-lo no serviço de nomes, o RMIRegistry, para que os clientes possam obter referências para o objecto remoto que representa o servidor. O RMIRegistry costuma ser lançado como uma aplicação à parte, que vem incluída com as distribuições de máquinas virtuais Java. De forma a simplificar a operação do Servidor RMI, este verifica se o RMIRegistry já está a correr, lançando-o como parte do servidor caso não esteja. A integração do RMIRegistry no Servidor RMI também significa que, quando o servidor pára, o RMIRegistry também é desligado. Implementação 120 O lançamento do serviço RMI, referido no parágrafo anterior, é também constituído por várias fases. O serviço RMI é representado pela classe RemoteTalImpl, que dispõe de dois construtores. Um dos construtores lança o serviço utilizando TLS e o outro recorrendo a TCP simples. Quando é utilizado TLS, as chaves pública e privada a utilizar são lidas do ficheiro com o certificado, estando a chave privada protegida com uma password. De seguida é iniciada a biblioteca TalAccess e são criadas as tarefas responsáveis pela entrega das mensagens JMS. 5.3.2.2 – Paragem do servidor A paragem de uma instância do Servidor RMI é conseguida utilizando outra instância do programa. Quando o Servidor RMI é invocado recebendo como parâmetro “stop”, este irá funcionar não como servidor, mas sim como cliente RMI. A nova instância começa por ler o ficheiro de configuração do servidor, determinando assim o porto e IP a utilizar para contactar a outra instância do Servidor RMI. De seguida, contacta-a, invocando um método para lhe ordenar a paragem. Quando esse método retorna, a instância que funciona como cliente finaliza a sua execução. Para garantir que o Servidor RMI não é parado por outro programa, a interface que define o método de paragem do servidor é distinta da apresentada aos clientes. Adicionalmente, o método que executa a paragem requer como parâmetro uma password. Esta password é uma constante do Servidor RMI, apenas sendo conhecida por este. Como não há necessidade de memorizar a password, esta pode ser tão longa e complexa como desejável. Quando o Servidor RMI está a operar como servidor e recebe uma ordem de paragem, efectua uma série de passos com vista a conseguir uma paragem ordeira que não afecte nem o TeMIP, nem os seus clientes. O primeiro passo consiste em activar uma flag que indica que todos os novos pedidos efectuados pelos clientes devem ser recusados, sendo-lhes devolvida uma excepção. De seguida o servidor apaga o seu registo no serviço de nomes, garantindo assim que novos clientes não conseguem obter uma referencia para o servidor. O passo seguinte consistem em cancelar todas as interrogações assíncronas que o TAL está a processar, garantindo assim que o correcto funcionamento do TeMIP não é perturbado. Após o cancelamento de todas as interrogações assíncronas, o TAL é desligado, libertando recursos do TeMIP. Existem agora uma série de clientes que estão à espera das respostas às suas interrogações Implementação 121 assíncronas, e que o vão continuar a fazer até receberem a última resposta. A todos esses clientes, é enviado uma última resposta assíncrona, sob a forma de excepção comum do TeMIP, indicando que o Servidor RMI foi parado. Como as mensagens assíncronas não são enviadas imediatamente mas sim colocadas em filas para posterior entrega por tarefas dedicadas, o Servidor RMI aguarda um intervalo de tempo, definido no ficheiro de configuração, até findar a sua execução. Esta espera permite ainda que as interrogações síncronas em curso sejam completadas. 5.3.2.3 – Paragem do TeMIP O Servidor RMI também pode findar a sua execução devido à paragem do TeMIP. Quando os serviços do TeMIP deixam de estar disponíveis o Servidor RMI fica impossibilitado de fornecer os seus serviços aos clientes, pelo que não faz sentido que continue a correr. O Servidor efectua assim um procedimento de paragem, avisando os clientes com interrogações assíncronas em execução de que o TeMIP parou. Não é possível ao Servidor RMI continuar a operar, recuperando o normal funcionamento quando o TeMIP for lançado novamente. A forma com o a biblioteca TAL foi desenhada não permite voltar a iniciar a biblioteca, necessitando para isso o programa de ser lançado novamente, tal como foi referido na subsecção 5.2.2.2. Deste modo, faz todo o sentido que o Servidor RMI pare ao mesmo tempo que o TeMIP, ficando os administradores de sistema responsáveis por voltar a correr o Servidor RMI quando fizerem o mesmo ao TeMIP. O processo de paragem do Servidor RMI nesta situação é em tudo semelhante ao descrito na secção anterior, pelo que não será descrito novamente. Apenas o passo em que as interrogações assíncronas são canceladas não é efectuado, pois o TAL já não está disponível. 5.3.2.4 – Interrogação síncrona Quando recebe um pedido de interrogação síncrona o Servidor RMI começa por verificar se pode responder ao pedido ou se está em processo de paragem. Caso não possa é gerada uma excepção, que será enviada ao cliente. Quando pode responder ao pedido passa ao próximo passo: a verificação do username/password fornecido no pedido. Implementação 122 Quando a informação de autenticação não é valida o cliente recebe uma excepção, do tipo TeMIPSecurityException, não sendo o pedido processado. Os pedidos válidos são passados ao TalAccess, sendo devolvida ao cliente a resposta gerada pelo TalAccess, sem mais processamento. 5.3.2.5 – Verificação de username/password A verificação de username/password não é uma funcionalidade utilizada pelo Conector. Destina-se a ser utilizada por módulos de autenticação, como o desenvolvido para o servidor J2EE JBoss, apresentado na secção 6.2. Esta funcionalidade permite que os utilizadores das aplicações sejam validados usando o mesmo sistema de autenticação que o Conector utiliza. Assim, é possível construir aplicações onde as credenciais de autenticação fornecidas pelo utilizador são utilizadas pelo Conector, ou seja é possível efectuar single sign on. Em resposta a estes pedidos, o Servidor RMI delega o seu processamento à biblioteca TalAccess, devolvendo directamente o resultado, sem mais processamento. 5.3.2.6 – Interrogação assíncrona O processamento das interrogações assíncronas é idêntico ao realizado para as interrogações síncronas. No entanto, no final não está disponível uma resposta para devolver, mas sim o identificador gerado para a interrogação. As respostas serão entregues posteriormente, à medida que a biblioteca TalAccess as entrega através do método de callback. Cada resposta será entregue, numa mensagem JMS, na fila de mensagens indicada pelo cliente no pedido. Para tal, o Servidor RMI guarda numa hashtable a fila correspondente a cada interrogação assíncrona. Quando uma resposta é entregue pela biblioteca TalAccess, o identificador da interrogação que lhe deu origem é utilizado para determinar qual a fila de mensagens onde a resposta deve ser entregue. A nova resposta é adicionada à lista de respostas que estão por entregar nessa fila de mensagens. Existe um conjunto de tarefas independentes, dedicadas ao envio das respostas para as filas. Estas tarefas vão lendo as respostas das listas correspondentes a cada fila de mensagens, constroem uma mensagem para transportar a resposta e enviam-na. A existência destas tarefas justifica-se pelo elevado período de tempo necessário para Implementação 123 entregar cada mensagem. A separação da entrega das respostas pela biblioteca TalAccess, da entrega das respectivas mensagens aos clientes, permite atingir um maior desempenho, ao mesmo tempo que não bloqueia o funcionamento da biblioteca TalAccess, que apenas dispõe de uma tarefa para a entrega das respostas. As tarefas responsáveis pela entrega das mensagens são ainda responsáveis por detectar problemas com as filas de mensagens. Sempre que uma fila de mensagens, utilizada para entregar respostas a determinada interrogação assíncrona, deixa de estar disponível, essa interrogação assíncrona é cancelada. Ocasionalmente, devido a falhas de comunicação ou por indisponibilidade temporária do servidor JMS, pode não ser possível entregar as mensagens. O Servidor RMI tenta recuperar desta situação criando uma nova ligação ao servidor JMS. Entre cada tentativa de ligação, é efectuada uma pausa de três segundos. Nesta situação o Servidor RMI não descarta as mensagens que aguardam entrega, continuando a guardar as que entretanto foram recebidas da biblioteca TalAccess. Eventualmente, ou a comunicação com o servidor JMS é restabelecida, ou o Servidor RMI pára porque esgotou a memória. Esta solução foi a escolhida pois não pareceu sensato descartar as mensagens por entregar, fosse qual fosse o critério escolhido. Considera-se assim que qualquer falha no serviço JMS é temporária, e que o Servidor RMI deverá tentar manter-se em funcionamento, sem descartar informação, até esta ser resolvida. As respostas são enviadas em mensagens do tipo ObjectMessage, transportando directamente o objecto com a resposta. Para facilitar o processamento das mensagens, é colocado no seu cabeçalho uma propriedade, de nome queryId, com o identificador da interrogação que lhe deu origem. Esta propriedade pode ser utilizada para definir filtros para separar mensagens, sendo particularmente útil quando se utiliza a mesma fila de mensagens para receber respostas de várias interrogações assíncronas. 5.3.2.7 – Cancelamento interrogação assíncrona O cancelamento de uma interrogação assíncrona apenas é aceite quando o username/password é válido e o username é o mesmo que foi utilizado para criar a referida interrogação. Neste caso, o cancelamento da interrogação é transmitido à biblioteca TalAccess. Implementação 124 Todas as respostas ainda por entregar são apagadas, e uma última mensagem é enviada para a fila de mensagens indicada para esta interrogação assíncrona. Esta última mensagem é uma excepção, que indica que a interrogação foi cancelada. 5.3.2.8 – Sistema de histórico O Servidor RMI é desenhado como uma aplicação capaz de superar falhas, destinada a funcionar ininterruptamente durante longos períodos de tempo. Como durante a execução de um programa podem ocorrer erros inesperados ou situações não previstas, o Servidor RMI tenta superar as situações anómalas que possam eventualmente surgir durante o processamento de um pedido. Nestes casos, o Servidor RMI tenta sempre manter-se em funcionamento, de forma a poder responder a futuros pedidos, sacrificando o processamento do pedido que originou o erro e enviando uma excepção ao cliente. Para permitir a sua contínua melhoria, o Servidor RMI regista todos as excepções ocorridas, esperadas ou inesperadas, utilizando um sistema de histórico, que regista num ficheiro a mensagem de erro, a hora da ocorrência e a descrição detalhada da excepção, incluindo as linhas de código onde aconteceu (stack trace). O sistema de histórico é também utilizado para registar os eventos do ciclo de vida do servidor, tal como o seu arranque e paragem. O Servidor RMI também pode registar, num ficheiro separado, toda a informação sobre as invocações remotas que processa. Estes dados incluem hora, endereço IP do cliente e qual o método chamado. O sistema de histórico fornece um método que além de registar o evento num ficheiro, o reporta ao administrador de sistema, através de emails de alerta. Este método é utilizado quando ocorrem excepções não previstas durante o desenvolvimento do código. 5.3.3 – Testes ao Servidor RMI - Cliente remoto O desenvolvimento do Servidor RMI foi efectuado em simultâneo com o desenvolvimento de uma aplicação cliente, o Cliente remoto. Este apresenta a mesma funcionalidade que o Cliente local, descrito na secção 5.2.4. Recebe os mesmos parâmetros que este último, necessitando ainda do URL que identifica a instância do Servidor RMI a utilizar e de um par username/password. Implementação 125 O URL serve para indicar a instância do Servidor RMI a utilizar, contendo: nome DNS ou endereço IP onde corre o serviço de nomes (RMIRegistry); porto IP utilizado pelo serviço de nomes; o nome sob o qual o Servidor RMI se encontra registado no serviço de nomes. A arquitectura do Cliente remoto é apresentada na Figura 26. Para além de comunicar com o Servidor RMI, o Cliente remoto necessita ainda de aceder aos serviços de um servidor JMS, de modo a conseguir receber as respostas a interrogações assíncronas. O servidor JMS utilizado deve ser o mesmo para o cliente e servidor. Ambos devem partilhar as mesmas bibliotecas para acesso ao servidor JMS. Este foi o cenário utilizado durante o desenvolvimento e testes destes programas, onde apenas estava disponível um servidor JMS, no entanto é possível conceber outros cenários, onde o cliente e servidor comuniquem com servidores JMS diferentes, que cooperem entre si para transmitir as mensagens. Bibliotecas Java para acesso remoto ao Servidor J2EE JMS Serviço JMS Queues Servidor RMI Servidor J2EE TalAccess M R I/S JVM SL TAL TeMIP Security Services Cliente Remoto JVM JVM Tru64 Unix Sistema Operativo Sistema Operativo Figura 26 – Posicionamento do cliente remoto O Cliente remoto funciona em modo de texto, não sendo interactivo. Recebe toda a informação de que necessita como parâmetros de linha de comando e apresenta a resposta, ou respostas no caso de interrogações assíncronas, no écran (stdout), terminando de seguida. No caso de uma interrogação assíncrona, antes de solicitar a sua execução ao Servidor RMI, o Cliente remoto cria uma fila de mensagens temporária no servidor JMS. Esta fila Implementação 126 é apagada assim que é recebida a última resposta. Para receber as mensagens à medida que estas chegam à fila, o cliente implementa a interface MessageListener e regista-se como receptor de todas as mensagens enviadas para essa fila. No caso das interrogações síncronas apenas é solicitada a sua realização ao Servidor RMI e apresentada a resposta. Implementação 127 5.4 – Conector O Conector implementa a especificação JCA 1.0, destinando-se a ser executado por um servidor J2EE, de forma a dar às aplicações J2EE acesso ao TeMIP. O acesso ao TeMIP é realizado através do Servidor RMI, funcionando o Conector como cliente. O Conector fornece às aplicações um subconjunto da API fornecida pelo Servidor RMI. Todas as funcionalidades descritas na especificação JCA 1.0 relativamente ao controlo de ligações foram implementadas, nomeadamente re-autenticação, partilha e associação de ligações. No entanto, não existe suporte para transacções uma vez que este conceito não é suportado pelo TeMIP. O contracto de segurança é implementado através do uso de username/password necessitando o Conector de receber esta informação do servidor J2EE antes de criar uma nova ligação. 5.4.1 – API oferecida As aplicações clientes podem invocar quatro métodos sobre uma ligação ao TeMIP: • public java.sql.ResultSet synchronousTALQuery( String query) throws ResourceException: permite efectuar uma interrogação síncrona. Recebe como parâmetro a interrogação a efectuar. Devolve o ResultSet que representa a resposta. • public int asynchronousTALQuery( Queue destQueue, String query) throws ResourceException: permite efectuar uma interrogação assíncrona. Recebe como parâmetros a fila de mensagens onde as respostas devem ser entregues e a interrogação a realizar. É devolvido o identificador atribuído à interrogação. • public void cancelAsyncTALQuery( int queryId) throws ResourceException: cancela uma interrogação assíncrona em curso. Recebe como parâmetro o identificador da interrogação assíncrona a cancelar, o qual lhe foi atribuído quando a referida interrogação foi criada. • public void close() throws ResourceException: utilizado para fechar a ligação. Ao invocar este método a aplicação indica que já não precisa de usar a ligação. Implementação 128 O Conector pode então fechar a ligação ou guardá-la para futura utilização por esta ou outra aplicação. Estes métodos são similares aos já apresentados para o Servidor RMI, na secção 5.3.1, pois efectivamente serão mapeados nesses. Apenas as excepções devolvidas são diferentes, de modo a utilizar as excepções definidas no JCA 1.0. No entanto, a excepção utilizada, ResourceException, transporta a excepção originalmente devolvida pelo Servidor RMI, podendo esta ser consultada. 5.4.2 – Instalação Após o processo de compilação e construção do projecto, o Conector toma a forma de um ficheiro RAR. Este ficheiro, no formato ZIP, contém todas as classes Java compiladas que constituem o Conector, assim como o ficheiro ra.xml. O Conector é constituído pelas classes que implementam as várias interfaces JCA, assim como pelas classes do Servidor RMI necessárias para agir como seu cliente. O ficheiro ra.xml, também definido na especificação JCA, é utilizado para indicar ao servidor J2EE quais as classes que implementam cada uma das interfaces definidas na especificação JCA. É também neste ficheiro que a entidade criadora de um connector pode fornecer alguns dos seus dados, informação sobre a versão do connector e o seu propósito assim como especificar as capacidades do connector. Neste caso, o ficheiro indica ao servidor J2EE que o Conector não suporta transacções, que suporta reautenticação de ligações e que a autenticação é realizada através de username/password. Este ficheiro é ainda utilizado para indicar o nome, descrição e tipo dos parâmetros que têm de ser fornecidos a um connector. No caso concreto do Conector, existe apenas um parâmetro, do tipo String: o URL que especifica a localização da instância do Servidor RMI a utilizar. O ficheiro rar segue o formato especificado no JCA 1.0, no entanto não contém toda a informação necessária ao servidor J2EE para correr o Conector. É ainda necessário especificar o nome sob o qual o Conector vai ser registado no serviço de nomes (JNDI), o valor dos parâmetros definidos no ficheiro ra.xml e que credenciais de autenticação serão passadas ao Conector juntamente com os pedidos de ligação. A forma como esta informação é passada ao servidor J2EE não é especificada no JCA 1.0, tendo sido deixada ao cuidado dos fabricantes de servidores J2EE. Este procedimento é comum em Implementação 129 muitas das tecnologias J2EE, destinando-se a fornecer aos fabricantes espaço de manobra através da diferenciação e introdução de novas capacidades. Assim cada fabricante fornece um modo proprietário de instalação dos connector. No caso concreto do JBoss é utilizado um ficheiro de configuração num formato proprietário. A utilização do Conector requer ainda a instalação do certificado auto assinado utilizado pelo Servidor RMI no TLS. Este procedimento também é específico do servidor J2EE utilizado, e não seria necessário caso fosse utilizado um certificado emitido por uma autoridade certificadora reconhecida. No JBoss este procedimento consistiu na adição do certificado à lista de entidades certificadoras reconhecidas pela máquina virtual Java utilizada para correr o JBoss. 5.4.3 – Funcionamento A liberdade para a implementação do Conector estava à partida limitada: deveria funcionar como cliente do Servidor RMI e implementar a arquitectura definida no JCA. A maior parte da complexidade da implementação deste connector reside na biblioteca TalAccess e no Servidor RMI. Como tal, para evitar repetir a apresentação da arquitectura JCA, já efectuada na secção 3.4, serão apenas apresentados nesta secção os aspectos mais relevantes do Conector: arranque e paragem, obtenção de uma ligação por parte da aplicação cliente e utilização da ligação pelo cliente (invocação de métodos). 5.4.3.1 – Arranque e paragem O Conector não funciona sozinho, requerendo o ambiente fornecido por um servidor J2EE. Assim, é este servidor que tem a responsabilidade de executar o Conector quando este é instalado. O servidor J2EE começa por criar uma instância de ManagedConnectionFactoryImpl que, como o nome indica, implementa a interface ManagedConnectionFactory. A este objecto são transmitidos os valores determinados para as propriedades definidas no ficheiro ra.xml. É também a este objecto que são transmitidas as referências para os objectos do servidor J2EE que implementam a sua parte do contrato JCA. A instância criada é utilizada para criar objectos do tipo ConnectionFactoryImpl, que podem então ser obtidos pelas aplicações clientes através do serviço de directório JNDI. É através dos objectos do tipo ConnectionFactoryImpl que as aplicações clientes podem criar ligações para utilizar o TeMIP. O registo destes objectos no serviço de directório (JNDI) é da Implementação 130 responsabilidade do servidor J2EE, e a forma de indicar o nome sob o qual o registo é efectuado é específica de cada servidor J2EE, sendo normalmente executada aquando da instalação do Conector. Uma vez que o Servidor RMI foi construído de forma a não manter estado, a remoção do Conector ou paragem do servidor J2EE não têm impacto sobre o seu funcionamento. Assim, não é necessário ao Conector executar quaisquer acções quando é parado. Assume-se que no caso de uma paragem ordeira do servidor J2EE as aplicações que usam o Conector são capazes de cancelar as interrogações assíncronas que têm pendentes. Caso não o façam assume-se que estas não devem ser canceladas, sendo as respostas correspondentes entregues nas filas de mensagens para posterior processamento. Alternativamente o Conector poderia cancelar todas as interrogações assíncronas pendentes quando fosse parado. Esta decisão não foi tomada pois o cancelamento das interrogações assíncronas pendentes poderia perturbar o funcionamento das aplicações clientes. Este factor deve ser levado em consideração pois pode haver aplicações a correr fora do servidor J2EE que não devem ser afectadas pela sua paragem. 5.4.3.2 – Obtenção de uma ligação A resposta aos pedidos de novas ligações por parte das aplicações clientes é uma tarefa partilhada entre o Conector e o servidor J2EE onde corre. Os pedidos de novas ligações, realizados a um objecto do tipo ConnectionFactoryImpl, é delegado ao servidor J2EE, que guarda um conjunto de ligações criadas anteriormente. As ligações libertadas pelos clientes não são imediatamente destruídas, sendo guardadas pelo servidor J2EE numa pool. A responsabilidade da gestão dessa pool é do servidor J2EE, sendo normalmente os parâmetros de gestão da pool configuráveis aquando da instalação de um connector. Parâmetros vulgarmente encontrados são: números máximo e mínimo de ligações, tempo máximo que uma ligação pode ser guardada sem ser utilizada e número máximo de usos de cada ligação. No entanto outros parâmetros podem ser configurados, dependendo da complexidade dos algoritmos utilizados pelo servidor J2EE escolhido. Implementação 131 O servidor J2EE reúne, segundo critérios proprietários, um conjunto de ligações que acha poderem ser utilizados para satisfazer o pedido do cliente. Esse conjunto é então entregue ao Conector, mais concretamente à classe ManagedConnectionFactoryImpl, para que este indique se alguma destas ligações pode ser efectivamente entregue ao cliente. Uma vez que o Servidor RMI não mantém estado sobre as ligações, o Conector considera que qualquer ligação efectuada anteriormente utilizando as mesmas credenciais de autenticação pode ser utilizada. Devido à arquitectura escolhida, o que distingue cada ligação é apenas o username/password presente nas credenciais de autenticação utilizadas na sua criação. Ainda assim as ligações do Conector permitem re-autenticação, pelo que o servidor J2EE pode reciclar as ligações para uso por utilizadores diferentes. Sempre que o Conector não encontra nenhuma ligação compatível, o servidor J2EE solicita a criação de uma nova ligação. É assim criado um novo objecto do tipo ManagedConnectionImpl, que representa uma ligação ao TeMIP, através do Servidor RMI. As únicas propriedades diferentes entre cada objecto desta classe, para uma determinada instalação do Conector, são as credenciais de autenticação. Estas, constituídas por username/password, são retiradas da informação de segurança referente ao utilizador a que o Conector tem acesso. O Conector necessita desta informação para poder utilizar o Servidor RMI, sendo assim necessário que o objecto (Subject) que transporta a informação de segurança da aplicação cliente transporte credenciais desse tipo. A informação que o servidor J2EE coloca no Subject passado ao Conector é configurável. Pode conter sempre as mesmas credenciais ou estas podem ser determinadas em função do utilizador que utiliza a aplicação ou qualquer outro critério. Para possibilitar a utilização de single sign on no servidor J2EE JBoss foi desenvolvido um módulo de autenticação para este servidor. Este módulo, apresentado no próximo capítulo, permite construir aplicações onde o Conector recebe as credenciais de autenticação fornecidas pelo utilizador da aplicação quando se autentica. Embora o pooling das ligações por parte do servidor J2EE se traduza numa economia de recursos, devido à reutilização dos objectos, o real ganho de desempenho obtido é difícil de avaliar. O Conector usa ligações RMI para comunicar com o Servidor RMI. O estabelecimento de tais ligações é um processo moroso, que envolve: pesquisas DNS Implementação 132 para aceder ao serviço de nomes (RMIRegistry); comunicação com o serviço de nomes para obter uma referencia para o Servidor RMI; estabelecimento de uma ligação TCP com o Servidor RMI. Há ainda que contar com o menor desempenho normalmente oferecido por ligações recentes devido ao fenómeno slow start das ligações TCP [108]. No entanto, o próprio sistema RMI reutiliza as ligações TCP efectuando também o seu pooling. Assim os efeitos do pooling realizado pelo servidor J2EE são menos expressivos. 5.4.3.3 – Invocação de métodos O Conector funciona como cliente do Servidor RMI. Quando é invocado qualquer um dos métodos fornecidos pelo Conector para contacto com o TeMIP, o pedido é passado ao Servidor RMI utilizando o username/password fornecidos pelo servidor J2EE quando a criação da ligação foi solicitada. As respostas são passadas directamente à aplicação cliente sem serem processadas. Caso não seja possível comunicar com o Servidor RMI, o sistema RMI devolve uma excepção. Estas e quaisquer outras excepções que o Servidor RMI possa gerar em resposta aos pedidos são guardadas numa nova excepção, do tipo ResourceException, a qual é transmitida às aplicações clientes. 5.4.4 – Testes ao Conector - Cliente J2EE Paralelamente ao desenvolvimento do Conector foi implementado um subconjunto da interface Web apresentada no próximo capítulo. A arquitectura desta aplicação será apresentada na Figura 35. Uma vez que esta aplicação é apresentada em pormenor no próximo capítulo, não será alvo de análise detalhada nesta secção. A aplicação de teste permite utilizar um browser HTML para realizar interrogações síncronas ao TeMIP, à semelhança do que era possível efectuar com o Cliente local e com o Cliente remoto. Devido ao modelo síncrono de funcionamento do HTTP a aplicação não permite realizar interrogações assíncronas. A aplicação de testes é constituída por uma página HTML estática, um JSP e um EJB. A página HTML estática, apresentada na Figura 27, é constituída por um formulário onde o utilizador introduz a interrogação a realizar. A submissão do formulário origina a execução do JSP, que através do stateful session EJB transmite o pedido ao Conector. Implementação 133 Figura 27 – Introdução da interrogação O JSP utiliza a resposta obtida para construir a nova página a oferecer ao utilizador, apresentada na Figura 28. A página criada contém a representação da resposta sobre a forma de uma tabela. O nome das colunas a criar é retirada da meta informação disponível no objecto ResultSetMetaData, que descreve o conteúdo de um objecto ResultSet. Figura 28 – Apresentação da resposta Implementação 134 A aplicação foi configurada de forma a exigir ao utilizador autenticação através de username/password. A autenticação é apresentada na Figura 29. Figura 29 – Autenticação do utilizador A aplicação foi corrida no servidor J2EE JBoss, tendo sido utilizado o módulo de autenticação apresentado na secção 6.2. Os utilizadores são assim autenticados utilizando a base de dados de utilizadores do sistema Tru64 onde o Servidor RMI está a correr. O servidor J2EE foi configurado para passar ao Conector as credenciais de autenticação do utilizador, ou seja single sign on. O Conector pode assim comunicar com o Servidor RMI utilizando o username e password fornecidos pelo utilizador durante o login, e que se sabem ser válidos. Aplicações 135 Capítulo 6 – Aplicações Neste capítulo é apresentada uma aplicação desenvolvida para testar o TeMIPConnector, uma interface Web. A primeira secção apresenta a aplicação e discute as suas funcionalidades, a sua arquitectura e a implementação. A última secção deste capítulo apresenta um componente desenvolvido para facilitar o uso do TeMIPConnector, embora não faça parte deste. Trata-se de um módulo de autenticação para o servidor J2EE JBoss que valida os utilizadores recorrendo ao Servidor RMI. Este módulo permite construir aplicações com Single Sign On em que o Conector se liga ao Servidor RMI utilizando as credenciais com que o utilizador se autenticou. Aplicações 136 6.1 – Interface Web Foi desenvolvida uma aplicação com o intuito de demonstrar a correcção da implementação do TeMIPConnector. Não pretende ser uma aplicação completa mas apenas um protótipo, exemplo dos muitos tipos de aplicações que podem ser desenvolvidas recorrendo ao TeMIPConnector. A aplicação desenvolvida recebeu o nome de TeMIPWeb, pois é uma interface HTML para algumas das funcionalidades do TeMIP. Esta aplicação foi concebida para a gestão da rede do campus do IST no Taguspark, conjugando informação de gestão de rede, recebida do TeMIP, com os dados dos utilizadores da rede, recolhidos do directório LDAP do campus. Desta forma o operador de rede, responsável pela manutenção desta, pode utilizar a aplicação para determinar não apenas quais os elementos de rede que apresentam falhas, mas também quais os utilizadores afectados. Quando confrontado com vários problemas a resolver em simultâneo, pode utilizar informações tais como a localização ou categoria do utilizador afectado para ajudar a escolher a ordem pela qual vai resolver os problemas. Esta aplicação foi desenhada para funcionar em PDAs com acesso wireless à Internet, proporcionando grande mobilidade ao operador de rede, que pode assim dar suporte a vários problemas sem ter de regressar à sua sala. A aplicação foi testada em dois PDA: um PDA com modem GSM (Global System for Mobile Communications), permitindo o acesso dentro e fora do campus, outro com placa 802.11b, que possibilitava o acesso à aplicação através da rede wireless do campus. A interface HTML foi escolhida devido à sua universalidade. O uso de soluções nativas como o desenvolvimento de aplicações para Microsoft Pocket Windows, sistema operativo utilizado pelos PDAs testados (nas versões 2000 e 2002), limitaria o tipo de PDAs utilizáveis. Outra possível solução testada foi o uso de tecnologia Java. Infelizmente a única especificação com implementações disponíveis é o Personal Java 1.2, que remonta ao ano de 2000 e assenta na versão 1.1 do Java Development Kit, não sendo utilizável com nenhuma das tecnologias de comunicação actuais (RMI, CORBA ou SOAP - Simple Object Access Protocol) [109]. A especificação mais recente da linguagem Java para PDAs, o CDC (Connected Device Configuration) ainda não está Aplicações 137 disponível em grande escala [110]. Uma interface HTML, embora seja mais pobre, apresenta-se como a interface mais amplamente suportada pelos PDAs existentes no mercado, quer corram Palm OS, Pocket Windows ou Linux. 6.1.1 – A rede gerida Esta aplicação foi testada utilizando um subconjunto da rede do IST no Tagus Park. Estes elementos de rede dispõem de sondas SNMP, não havendo nenhum equipamento disponível que suportasse gestão OSI. Para melhor compreender o modo como esta rede foi representado no TeMIP, é apresentada a definição de alguns conceitos subjacentes a esta aplicação. Do ponto de vista conceptual, um Domínio de Gestão é um conjunto de entidades que se agrupam, sendo geridas de uma forma autónoma. A forma como o agrupamento das entidades é realizada é deixada à escolha do operador de rede, sendo comum o agrupamento por localização geográfica, tipo de equipamento, estrutura da organização ou partilha de responsabilidades entre operadores. Um domínio pode ser incluído num outro, pois também é uma entidade. Este conceito de sub domínio permite a organização hierárquica de domínios. Os Alarmes representam informação que é enviada para o gestor, assincronamente, quando o agente é notificado da ocorrência de situações de mau funcionamento no sistema gerido. Da mesma forma que um sistema em rede é subdividido em vários Domínios, também é possível definir diferentes visões sobre a actividade dos alarmes, através dos Operation Contexts, que permitem estabelecer o âmbito de intervenção de cada equipa de operadores. Cada Operation Context está associado a um determinado domínio de gestão, recebendo os alarmes das entidades contidas neste. Os alarmes recebidos são armazenados nos Operation Context cujos mecanismos de filtragem e escalonamento não os eliminem. Ao chegar, um novo alarme fica no estado Outstanding. Ao tomar conhecimento do alarme, o operador pode-o passar para o estado Acknowledged. Quando a situação que causou do alarme foi resolvida, o alarme é terminado, passando para o estado Terminated. Os alarmes podem ainda ser passados directamente de Outstanding para Terminated. A rede do IST no Tagus Park foi representada no TeMIP através da divisão dos elementos de rede em quatro categorias: equipamentos dos docentes (computadores e Aplicações 138 impressoras), equipamentos dos administradores da rede, servidores e infra-estrutura (routers, switchs e firewall). A estas quatro categorias correspondem quatro domínios de gestão, respectivamente: tp_docentes; tp_administradores; tp_servidores; tp_infrastrutura. Foram criados quatro operation context, cada um responsável por processar os alarmes gerados pelos elementos de rede de um domínio. Estes receberam os nomes: tp_docentes_oc; tp_administradores_oc; tp_servidores_oc; tp_infrastrutura_oc. O TeMIP permite associar a cada elemento de rede alguma informação, como o nome da pessoa responsável pelo equipamento. Cada um dos elementos de rede foi registado colocando no campo “Responsible Person” o identificador de uma pessoa registada no directório LDAP. No caso de equipamento para uso pessoal (computadores dos docentes e administradores) esta pessoa é o utilizador do equipamento. No caso de equipamento de uso partilhado (impressoras, routers, etc.) foi associado ao equipamento um dos administradores de rede. É assim possível recorrer ao directório LDAP para fornecer informação sempre actualizada sobre os responsáveis do equipamento, sem ser necessário manter procedimentos de replicação de dados. 6.1.2 – Funcionalidades disponibilizadas Não pretendendo ser uma interface exaustiva para as funcionalidades oferecidas pelo TeMIP, este programa visa testar a viabilidade de usar o TeMIPConnector para integrar o TeMIP com outras fontes de dados. Foi assim decidido utilizar o conceito de alarme, provavelmente o tipo de objecto com que um operador de rede mais lida na sua interacção com o TeMIP. A aplicação desenvolvida permite a um operador de rede visualizar e gerir os alarmes pendentes de processamento, aqueles no estado Outstanding ou Acknowledged. A aplicação foi idealizada para ser acedida a partir de um PDA, permitindo ao operador de rede grande mobilidade. No entanto, pode ser acedida utilizando um browser HTML normal. A acesso à aplicação apenas é possível mediante autenticação por username/password, necessitando o utilizador de fornecer as credencias de acesso utilizadas na maquina Tru64 onde o Servidor RMI do Conector corre. Após o processo de autenticação, o utilizador pode visualizar a página de entrada. Aplicações 139 Conforme representada na Figura 30 e na Figura 31, a página de entrada fornece informação sumária sobre o estado da rede, nomeadamente: para cada operation context controlado pelo utilizador, o número de alarmes de cada tipo de severidade; a lista dos alarmes mais recentes respeitantes a todos os operation context controlados, sendo possível configurar o número de alarmes apresentado. No final da página surgem as opções disponíveis: selecção dos operation context a monitorizar; realização de interrogações síncronas. A selecção dos operation context a monitorizar permite ao operador seleccionar quais os operation context a monitorizar pela aplicação, de entre todos aqueles registados no TeMIP, sendo realizada através da página representada na Figura 32. Figura 30 – Página inicial vista num PDA Ainda na página inicial, é possível escolher visualizar a lista completa de alarmes de um operation context, Figura 33, ou os pormenores de um alarme, Figura 34. Aplicações 140 Figura 31 – Página inicial vista num browser Figura 32 – Escolha de OCs a monitorizar A lista de alarmes apresenta todos os alarmes pendentes de um operation context, do mais recente para o mais antigo. Para cada alarme fica-se a conhecer a sua severidade, representada através de uma cor, o nome do elemento de rede afectado, o tipo de Aplicações 141 alarme, a hora da sua ocorrência e o seu estado, assim como as iniciais e afiliação da pessoa responsável pelo elemento de rede afectado, dados lidos do directório LDAP. Figura 33 – Lista de alarmes de um operation context Ao escolher um alarme, quer na página inicial, que na lista de alarmes de um operation context, é apresentada a página de pormenor de um alarme, ilustrada na Figura 34. Os pormenores de um alarme contêm dados de três tipos: informação e fotografia do utilizador/responsável do equipamento, retirada do directório LDAP; informação sobre o elemento de rede afectado, retirada por SNMP do elemento através do TeMIP; informação sobre o alarme, fornecida pelo TeMIP. O TeMIP permite associar a cada alarme um pequeno texto, onde o operador de rede pode guardar algumas notas sobre o problema. A página de pormenor de um alarme permite alterar essas notas. Permite ainda alterar o estado de um alarme, dando-o como reconhecido (Acknowledged) ou terminado (Terminated). A aplicação possibilita também a interacção directa com o TeMIP, através da introdução de comandos síncronos. Esta facilidade, já discutida na secção 5.4.4, permite o acesso “directo” ao TeMIP, podendo o utilizador executar qualquer tipo de comando ou interrogação no TeMIP. O utilizador pode realizar tarefas para as quais a aplicação não apresenta suporte explícito, aumentando assim a sua flexibilidade. Os resultados das interrogações ou a resposta aos comandos são representados sobre a forma de uma tabela. Aplicações 142 Figura 34 – Pormenores de um alarme 6.1.3 – Arquitectura Esta aplicação, cuja arquitectura é apresentada na Figura 35, manipula três fontes de dados: o TeMIP; o directório LDAP, acedido exclusivamente para leitura; uma base de dados. A interface com o utilizador é realizada através de um conjunto de JSPs e servlets, responsáveis por aceitar os pedidos do utilizador e gerar o conteúdo dinâmico. Estes componentes delegam todas as operações num EJB de sessão, responsável por implementar a lógica da aplicação. Aplicações 143 Cliente HTTP HT Bibliotecas Java para acesso remoto ao Servidor J2EE JSPs e Servlets Servidor RMI Session EJB Aplicação Web Directório LDAP Entity EJBs RM TalAccess I/S JVM TP SL BD Conector TAL Servidor J2EE Security Services TeMIP JVM True 64 Unix Sistema Operativo Figura 35 – Arquitectura global da aplicação Web Para cada utilizador da aplicação é criada uma instância do EJB de sessão, a qual será utilizada para realizar todas as operações solicitadas durante a interacção do utilizador com a aplicação, numa implementação do padrão Session Facade [111]. Este EJB interage com o TeMIP através do Conector, com o directório LDAP directamente, e com um conjunto de EJBs de entidade. Os EJB de entidade destinam-se a guardar em suporte persistente, neste caso uma base de dados, quais os operation context que cada utilizador deseja monitorizar. 6.1.4 – Implementação A interface HTML foi construída recorrendo principalmente a JSPs [112]. Existe um servlet, para fornecer as fotografias dos utilizadores/responsáveis pelos elementos de rede, pois não é possível a um JSP fornecer conteúdo binário. Existe apenas um página estática, o formulário para comandos síncronos, sendo o restante conteúdo gerado dinamicamente pelos JSPs. A interface Web segue o modelo model-view-controler, onde os EJBs implementam o modelo, e o controlo e a vista são implementados por JSPs. A lógica de negócio, implementada num EJB de sessão, consiste essencialmente em realizar as interrogações ao TeMIP, ao directório LDAP e à BD e em processar os Aplicações 144 resultados, construindo objectos que possam ser facilmente processados pelos JSP para gerar a apresentação. A biblioteca TAL, utilizada pelo TeMIPConnector, não permite realizar interrogações muito complexas, obrigando, em alguns casos, à realização de várias interrogações para capturar dados que a interface de linha de comando do TeMIP pode retornar em apenas uma interrogação. Um exemplo disto é a lista de alarmes, que exige uma interrogação para saber quais os alarmes disponíveis seguida de duas interrogação por alarme para conhecer os seus dados. Os dados da pessoa responsável por cada equipamento são lidos do directório LDAP através da indicação do identificador único atribuído à pessoa. Esse identificador é guardado no TeMIP aquando do registo dos elementos de rede, através do preenchimento do campo “Responsible Person”. É assim possível através do alarme determinar qual o elemento de rede afectado e a partir desse determinar qual a pessoa responsável. Existe apenas um dado que a aplicação tem de manter entre interacções com um utilizador: quais os operation context seleccionados. Para guardar esta informação foram implementados dois CMP EJB. Um guarda informação sobre um utilizador (nome), o outro sobre um operation context (nome), existindo uma relação de muitos para muitos entre o primeiro e o segundo. A utilização de CMP EJBs significa que não é necessário criar as tabelas na base de dados ou os comandos SQL a efectuar. Tudo isto é efectuado automaticamente pelo servidor aplicacional onde a aplicação é executada. É, no entanto, necessário criar várias centenas de linhas de XML para especificar aquilo que se pretende. Quando o utilizador da aplicação escolhe quais os operation context a monitorizar, sãolhe apresentados apenas os operation context existentes no TeMIP, estando já seleccionados os anteriormente escolhidos. Os operation context entretanto removidos do TeMIP, ainda que guardados na BD são ignorados, sendo removidos da BD quando o utilizador confirmar a sua escolha. Este procedimento permite recuperar facilmente de situações de erro geradas pelo facto de um operation context que o utilizador escolhera ter sido removido do TeMIP. Após a aplicação ter sido desenvolvida, foi necessário configura-la para correr no servidor aplicacional utilizado, o JBoss. A utilização de um connector na versão do Aplicações 145 JBoss utilizada difere da especificação J2EE num ponto: o ficheiro com o connector, o rar, não pode ficar dentro do ficheiro com a aplicação, o ear. Ao invés disso, é necessário juntar o ear e o rar num tipo de ficheiro específico do JBoss, com extensão sar (JBoss Service Archive). Este ficheiro sar inclui ainda um ficheiro de configuração próprio do JBoss, com indicações sobre a configuração do connector. A aplicação Web foi configurada de forma a requerer a autenticação dos utilizadores. Esta autenticação é validada pelo módulo descrito na próxima secção. As credenciais de autenticação recolhidas são utilizadas pelo servidor J2EE para realizar a autenticação perante o Conector, sendo assim conseguido um single sign on. A aplicação conta com dois módulos de autenticação. O primeiro é o que realiza a autenticação dos utilizadores, e é apresentado na secção seguinte. O segundo é utilizado pelo Conector, limitando-se a transmitir ao Conector as credenciais utilizadas pelo utilizador. O Conector necessita de acesso ao username/password fornecidos para poder realizar as perguntas ao Servidor RMI em nome do cliente. Aplicações 146 6.2 – Modulo de autenticação JAAS A utilização dos mecanismos de segurança J2EE implica a existência de um mecanismo de autenticação do cliente. Um servidor aplicacional vem normalmente com alguns módulos de autenticação, capazes de comparar as credenciais submetidas pelo utilizador com as guardadas numa base de dados ou num ficheiro de texto. Neste caso pretendia-se que as credenciais fornecidas pelo utilizador fossem comparadas com as aceites pelo TeMIP, Servidor RMI e Conector, as quais são as do sistema Tru64 onde o TeMIP corre. Foi assim implementado um módulo de autenticação para o servidor J2EE open source JBoss, permitindo às aplicações que usam o TeMIPConnector autenticar transparentemente os utilizadores recorrendo ao Servidor RMI. Este módulo de autenticação delega a tarefa de verificar as credenciais ao Servidor RMI, que oferece este serviço propositadamente para este efeito. Desta forma é possível às aplicações utilizarem este módulo de autenticação para garantir que só acede à aplicação quem também poderia aceder directamente ao TeMIP, não sendo necessário manter várias bases de dados de credenciais/autorizações. Este módulo de autenticação possibilita ainda configurar o servidor aplicacional para que o Conector utilize as credenciais de cada utilizador nos acessos ao Servidor RMI. Doutra forma todos os acessos seriam realizados com as mesmas credenciais, previamente configuradas para o Conector. A norma JCA não define uma relação entre um connector e os mecanismos de autenticação, mas sugere que um utilizador possa ser autenticado utilizando o EIS a que o connector dá acesso, tal como foi feito. Testes de desempenho 147 Capítulo 7 – Testes de desempenho Uma peça de software nunca está completa sem a realização de testes. Para além dos vulgares testes funcionais, os testes de desempenho revelam-se fundamentais num connector como o aqui apresentado. Estes testes permitem identificar pontos fracos, na arquitectura ou implementação, que venham a revelar-se limitadores do desempenho. Esta análise é essencial num connector, que se destina a ser mais uma peça a incluir em aplicações empresariais complexas, em que o desempenho pode ser um factor crítico. Este capítulo começa com a apresentação dos testes realizados, seguindo-se a apresentação e análise dos resultados obtidos para os dois métodos de funcionamento deste connector, síncrono e assíncrono. No fim são apresentadas as conclusões obtidas. Testes de desempenho 148 7.1 – Cenário de testes Estes testes visam medir o desempenho individual de cada componente do Conector. Como se pode observar na Figura 16, o sistema é composto por três grandes blocos: a biblioteca TalAccess, o Servidor RMI e o Conector. A biblioteca TalAccess foi testada recorrendo ao Cliente Local, apresentado na Figura 25. Esta aplicação foi alterada para repetir cada interrogação 100 vezes. Os clientes são simulados correndo uma instância da aplicação por cada cliente. Os resultados deste teste foram obtidos através da própria aplicação de teste, na qual foram incluídas verificações de tempo. Devido à natureza deste teste, os clientes tiveram de ser corridos na mesma máquina que o TeMIP, limitando assim o número de clientes passível de serem lançados. Estes testes foram corridos em modo síncrono e assíncrono de recepção das respostas. O Servidor RMI foi testado recorrendo ao Cliente Remoto apresentado na Figura 26, que também foi alterado de modo a repetir cada interrogação 100 vezes e contar o tempo decorrido. Também estes testes puderam ser realizados em modo síncrono e assíncrono de recepção das respostas. Estes clientes não foram corridos na máquina com o TeMIP. Para o teste de funcionamento em modo assíncrono, foi criada uma nova fila de mensagens JMS por cada pergunta. Os testes foram repetidos recorrendo a TLS e sem TLS na comunicação entre servidor e clientes, de forma a verificar o impacto do uso desta tecnologia no desempenho do Servidor RMI. O desempenho do Conector como um todo foi testado utilizando a aplicação J2EE desenvolvida, o cliente Web. Devido à filosofia das aplicações Web, que são sempre síncronas, não foi possível estender os testes assíncronos até este nível. Este teste não mede o desempenho do Conector isoladamente, mas sim de uma aplicação multi-nível da qual ele faz parte. O cenário deste teste, apresentado na Figura 35, pretende simular o tipo de aplicações no qual o Conector pode ser integrado. Os clientes foram simulados utilizando a ferramenta wget, um cliente HTTP de linha de comando, não interactivo, que serve para fazer download de páginas Web. Foram lançados tantos processos como os clientes que se pretendia simular, e os tempos de execução foram medidos recorrendo Testes de desempenho 149 ao comando time do Unix. Tanto os clientes como o servidor J2EE foram executados noutra máquina que não a do TeMIP. A interface de linha de comando do TeMIP, o FCL, foi utilizado como referência, mas só permite respostas síncronas. Os valores obtidos não podem no entanto ser comparados directamente pois o FCL não assenta sobre o TAL. Teria sido interessante realizar testes que medissem o ganho de desempenho obtido pela reutilização das ligações promovida pela especificação JCA. Embora tenha sido possível, através de instrumentação do código, observar que as ligações eram reutilizadas, evitando assim a criação e remoção de novos objectos, este efeito não é tão significativo como o da reutilização das ligações reais, sockets. A reutilização dos sockets não pôde ser medida pois o serviço RMI efectua transparentemente a reutilização e partilha de ligações. Em todos os testes foi realizada a mesma interrogação ao TeMIP, pedindo os detalhes de todos os alarmes de um determinado operation context. A resposta contava com sessenta alarmes, cada um com doze campos. Os testes foram realizados recorrendo a duas máquinas: um Compaq Alpha XP1000 com 256MB de RAM a correr Compaq Tru64 Unix 4.0 onde foi executado o TeMIP 4.0.0; um AMD Athlon 750MHz com 640MB de RAM a correr Debian GNU/Linux 3.0. No Alpha foi utilizada a JVM 1.3.1-2 de 64 bits da Compaq, e no AMD a 1.3.1_03 da Sun, tendo sido acrescentada a implementação 1.0.2 da Sun do JSSE a ambas. O cliente local foi corrido no Alpha e a aplicação remota foi corrida no AMD. A aplicação J2EE, TeMIPWeb, foi corrida na máquina AMD utilizando a versão JBoss-3.0.0-Tomcat-4.0.3 do servidor open source JBoss, que também funcionou como servidor JMS. As máquinas comunicavam utilizando uma ligação Ethernet de 10Mb/s dedicada. Em nenhum dos testes o desempenho da aplicação foi limitado pela capacidade da ligação de rede ou pela máquina GNU/Linux, onde os clientes eram corridos. Cada teste foi repetido várias vezes, sendo apresentado o valor médio obtido para cada teste. O ritmo de respostas, apresentado em respostas por segundo, diz respeito ao total acumulado de todos os clientes, representando o ritmo mantido pelo TeMIP ou pelo Servidor RMI. O tempo de resposta, apresentado em milissegundos indica o tempo médio que um cliente leva a realizar a pergunta e receber a resposta completa. Testes de desempenho 150 7.2 – Desempenho em modo síncrono O modo síncrono foi testado utilizando o Cliente Local, para além do cliente HTTP e da aplicação Cliente Remoto, ambos com e sem o uso de TLS na ligação com o Servidor RMI. O FCL foi também utilizado como referencia pois funciona de modo síncrono. Os ritmos de resposta obtidos são apresentados na Tabela 1, em número total de respostas por segundo, obtidas pela totalidade dos clientes. C. HTTP / TLS Cliente HTTP C. Remoto / TLS Cliente Remoto Cliente Local FCL 1 1,96 2,65 3,36 3,34 3,60 2,12 Número de clientes simultâneos 2 5 10 20 2,76 3,12 3,36 3,53 3,53 3,51 3,50 3,50 3,47 3,44 3,50 3,50 3,48 3,45 3,61 3,34 3,34 2,13 2,10 2,05 50 3,52 3,42 3,41 Tabela 1 – Ritmo de resposta no modo síncrono (respostas/s) O tempo de resposta, desde que o cliente iniciou o pedido até ter recebido a totalidade da resposta também foi medido e é apresentado na Tabela 2. C. HTTP / TLS Cliente HTTP C. Remoto / TLS Cliente Remoto Cliente Local FCL 1 511 377 298 299 278 471 Número de clientes simultâneos 2 5 10 20 50 725 1601 596 1415 2835 5698 14188 572 1428 2883 5816 14610 571 1428 2873 5789 14673 555 1497 2996 937 2377 4886 Tabela 2 – Tempo de resposta no modo síncrono (ms) A Figura 36 apresenta o ritmo de resposta sob a forma de um gráfico, permitindo uma análise visual dos resultados obtidos. Os valores foram medidos para 1, 2, 5, 10, 20 e 50 clientes, não sendo os valores intermédios rigorosos. Os tempos de atraso são apresentados em gráfico na Figura 37. Na Figura 38 apresenta-se em maior detalhe o tempo de resposta considerando um máximo de 5 clientes em simultâneo. Conforme se pode constatar através da análise das referidas figuras, o FCL revela um pico de 2,13 resposta por segundo com dois clientes a correr em simultâneo. Com mais clientes o seu desempenho começa a baixar devido ao FCL ser corrido na mesma máquina que o TeMIP, limitando assim os recursos disponíveis para o TeMIP. Por este motivo, estes testes não puderam ser efectuados com mais do que 10 clientes. Apesar Testes de desempenho 151 disso, o ritmo de resposta decresce suavemente ao aumentar o número de clientes e o tempo de resposta sobe de forma praticamente linear. 3,6 Respostas por segundo 3,4 3,2 3,0 2,8 2,6 2,4 2,2 2,0 1,8 0 5 10 15 20 25 Clientes sim ultâneos C. HTTP / TLS Cliente HTTP C. Remoto / TLS Cliente Remoto Cliente Local FCL Figura 36 – Ritmo de resposta no modo síncrono O Cliente Local obteve o melhor desempenho, apresentando o menor tempo de atraso para um e dois clientes, assim como o maior ritmo de resposta. Lançar várias instâncias (clientes) da aplicação diminui significativamente o rendimento, pois esta necessita da JVM, uma aplicação pesada. Mais uma vez não se pode perceber se o TeMIP tem uma quebra de rendimento com mais de cinco clientes pois o número de processos lançados perturba o bom funcionamento da máquina. Tanto com o Cliente Local como utilizando o FCL, o ritmo de resposta máximo é atingido com dois clientes e não apenas um. Esta aparente contrariedade é justificada pelo tempo que os clientes levam a processar as respostas, durante o qual o TeMIP não está a trabalhar. Apenas um único cliente não é capaz de ocupar todos os recursos do TeMIP, justificando assim o facto do tempo de atraso não apresentar para dois clientes a subida linear que apresenta para um maior número. Testes de desempenho 152 7 Tempo de resposta (s) 6 5 4 3 2 1 0 0 5 10 15 20 25 Clientes simultâneos C. HTTP / TLS Cliente HTTP C. Remoto / TLS Cliente Remoto Cliente Local FCL Figura 37 – Tempo de resposta no modo síncrono O Cliente Remoto é a primeira aplicação a ser corrida fora da máquina que executa o TeMIP. Apenas o Servidor RMI corre conjuntamente com o TeMIP, pelo que o aumento do número de clientes apenas sobrecarrega as aplicações e não a máquina, permitindo assim verificar o verdadeiro desempenho destas. Já era esperado que o desempenho do Cliente Remoto fosse inferior ao do Cliente Local, devido ao atraso induzido pela rede, que, ao aumentar o tempo de resposta, limita o ritmo imposto por cada cliente. Nesta situação, é ainda mais visível o aumento do ritmo de respostas de um para dois clientes. Outra consequência deste facto é que o pico de desempenho é atingido com um número de clientes entre dois e cinco e não apenas com dois como no Cliente Local. Entre dois e cinco clientes levam o Servidor RMI a esgotar a capacidade de resposta do TeMIP, e com maior número de clientes o ritmo de respostas diminui, embora de forma tão ligeira que o tempo de resposta evolui de forma quase linear. A manutenção do ritmo de resposta e a linearidade do tempo de resposta demonstram que a arquitectura do TAL e do Servidor RMI são escaláveis. Seria de esperar que a utilização de TLS tivesse um impacto mais significativo pois é utilizada uma implementação deste protocolo escrita inteiramente em Java. Na realidade verificou-se que o impacto do uso do TLS é diminuto, apenas ganhando expressão com Testes de desempenho 153 um número elevado de clientes, pois só ai a máquina com o Servidor RMI fica suficientemente carregada para evidenciar o esforço necessário à codificação e descodificação das mensagens. E de realçar que, por cada interrogação recebida, o Servidor RMI realiza uma verificação de username/password antes de recorrer ao TAL. Esta verificação resulta em mais uma transição Java/C, ajudando assim a que o desempenho máximo seja inferior ao do Cliente Local. Os valores apresentados para o Cliente Remoto foram medidos após o estabelecimento das ligações. Uma ligação RMI implica um acesso a um serviço de nomes para encontrar o servidor antes da ligação propriamente dita poder ser estabelecida. No caso do uso de TLS é ainda necessário proceder à troca de chaves criptográficas. A criação do par de chaves criptográficas pública e privada é também uma operação morosa, sendo realizada pelo Servidor RMI ao arrancar e pelos clientes ao estabelecer a ligação. Embora o preço da criação das ligações só tenha impacto no arranque das aplicações, quando estas estabelecem uma ligação pela primeira vez, é importante conhecê-lo. Assim, o tempo médio de criação da ligação e realização da pergunta utilizada nos testes é de 0,62 segundos sem o uso de TLS e 8,32 segundos utilizando TLS. 3 Tempo de resposta (s) 2 2 1 1 0 0 1 2 3 4 5 6 Clientes simultâneos C. HTTP / TLS Cliente HTTP C. Remoto / TLS Cliente Remoto Cliente Local FCL Figura 38 – Detalhe do tempo de resposta no modo síncrono Testes de desempenho 154 O interface Web apresenta o pipeline de processamento mais longo, tal como se pode observar na Figura 35, sendo assim de esperar que o seu desempenho fosse muito inferior ao das outras aplicações. Efectivamente, isso verifica-se com um ou dois clientes, mas a partir de cinco, o seu desempenho é superior ao de todas as outras aplicações! É importante salientar que nestes testes foi utilizado a secção de acesso directo ao TeMIP da interface Web, que não utiliza mecanismos de cache. A quantidade de transformações a que cada resposta dada pelo TeMIP é sujeita até chegar ao cliente HTTP faz com que o tempo de resposta seja sempre elevado, limitando assim o ritmo com um e dois clientes. No entanto, a máquina GNU/Linux onde o servidor J2EE corre está sobre pouca carga, conseguindo acomodar o aumento do número de clientes. Com o aumento do número de clientes o ponto crítico passa a ser o TeMIP, sendo razoável esperar um desempenho tão bom como o do Cliente Remoto. No entanto, o desempenho da aplicação J2EE consegue ser superior! Esta aparente contradição é explicada pelo facto do servidor J2EE utilizado, o JBoss, limitar o número de clientes que são satisfeitos simultaneamente a três. Os pedidos HTTP são colocados numa fila e apenas três são satisfeitos concorrentemente, fazendo com que o Servidor RMI apenas tenha de lidar com esse número de clientes. Os resultados obtidos como Cliente Remoto já tinham demonstrado que o pico de desempenho se situava entre os dois e os cinco clientes. A análise anterior do desempenho da aplicação J2EE era apenas referente ao uso de RMI sem TLS. O uso de TLS mostra um cenário muito diferente. Ao contrário do Cliente Remoto, existe uma quebra expressiva de desempenho ao utilizar TLS, sendo os tempos de resposta significativamente maiores. De facto não foi possível realizar os testes com mais de cinco clientes pois o JBoss lançava várias excepções, possivelmente devido ao maior tempo de execução dos testes. O JBoss é uma aplicação complexa, que inclui uma implementação de JSSE. A aplicação J2EE e o Conector são lançados por um classloader próprio do JBoss e não pelo classloader da JVM. É portanto de admitir que o Conector se ligue ao Servidor RMI utilizando uma implementação de JSSE que não a instalada na JVM, conduzindo assim a estes resultados. Testes de desempenho 155 7.3 – Desempenho em modo assíncrono As interrogações em modo assíncrono distinguem-se das interrogações em modo síncrono pela forma como as respostas são entregues. Em vez de uma resposta são devolvidas várias, uma por cada elemento. No caso concreto da pergunta utilizada nestes testes, que devolve sessenta alarmes, são devolvidas sessenta respostas. O elevado número de respostas devolvido fazia antecipar um desempenho várias ordens de grandeza inferior ao do modo síncrono. Por cada resposta assíncrona recebida a parte em C da biblioteca TalAccess é forçada a realizar uma chamada a um método de callback em Java, um processo demorado. No caso da aplicação remota, as mensagens têm ainda de ser enviadas pela rede para o servidor JMS que depois as envia para o cliente, novamente através de um acesso à rede. O ritmo de respostas obtido é apresentado na Tabela 3 e na Figura 39, sendo o tempo de resposta indicado na Tabela 4 e na Figura 40. C. Remoto / TLS Cliente Remoto Cliente Local Número de clientes simultâneos 1 2 5 10 20 1,30 1,99 2,86 2,95 3,00 1,35 1,93 2,84 2,89 2,97 3,33 3,28 3,11 2,79 Tabela 3 – Ritmo de respostas em modo assíncrono (respostas/s) A primeira constatação é que o desempenho não é tão inferior ao do modo síncrono como o esperado, o que indica que quer o tempo gasto no envio das mensagens (apenas no Cliente Remoto) quer o que se gasta a realizar os callback é pouco significativo quando comparado com o tempo de processamento gasto pelo TeMIP. C. Remoto / TLS Cliente Remoto Cliente Local Número de clientes simultâneos 1 2 5 10 20 767 1004 1748 3394 6658 743 1037 1758 3461 6740 300 610 1606 3588 Tabela 4 – Tempo de resposta em modo assíncrono (ms) O Cliente Local consegue um desempenho quase tão bom em modo assíncrono como em modo síncrono conseguindo um pico de desempenho com um cliente. Mas desta vez o desempenho decresce sempre com o aumento do número de clientes, acusando assim a maior necessidade de CPU deste modo de funcionamento. Testes de desempenho 156 3,5 Respostas por segundo 3,0 2,5 2,0 1,5 1,0 0 5 10 15 20 25 Clientes sim ultâneos C. Remoto / TLS Cliente Remoto Cliente Local Figura 39 – Ritmo de resposta para perguntas assíncronas No caso do Cliente Remoto pode-se verificar que o uso de TLS não provoca qualquer impacto no desempenho, não existindo sequer um padrão que permita afirmar se o seu uso melhora ou piora o desempenho. O tempo de resposta deve-se maioritariamente à entrega das respostas e não à realização das perguntas por RMI. 8 Tempo de resposta (s) 7 6 5 4 3 2 1 0 0 5 10 15 20 25 Clientes simultâneos C. Remoto / TLS Cliente Remoto Cliente Local Figura 40 – Tempo de resposta para perguntas assíncronas Testes de desempenho 157 O elevado tempo de resposta utilizando o Cliente Remoto faz com que o desempenho máximo, em termos de ritmo de respostas, só seja atingido com 20 clientes. Verifica-se também que o tempo de respostas tem uma evolução cada vez menos acentuada com o aumento do número de clientes. Com dez clientes o Servidor RMI é mesmo capaz de ultrapassar o Cliente Local, o que se explica pelo facto do Servidor RMI ser um só processo enquanto que no Cliente Local cada cliente era simulado lançando uma instância do programa. O processo de entrega das mensagens passa por dois estágios desde que estas abandonam o Servidor RMI: primeiro, são enviadas pelo Servidor RMI para a fila de destino existente no servidor J2EE, seguidamente, são enviadas por este para o cliente. Embora não se possa controlar o modo como o servidor J2EE envia as mensagens para os clientes, é possível controlar o Servidor RMI. De forma a acelerar o envio das mensagens, que é uma operação lenta devido a esperas por Input/Output, o Servidor RMI dispõe de várias tarefas para o envio das mensagens (10 tarefas nestes testes). No entanto, de forma a manter a sequência das mensagens, cada tarefa está num determinado momento a enviar mensagens para clientes diferentes. Como tal, o efeito desta dissociação da produção e entrega de mensagens não se faz sentir com apenas um cliente, mas é responsável por o tempo de atraso evoluir mais lentamente até aos cinco clientes. Testes de desempenho 158 7.4 – Conclusões O aumento linear do tempo de resposta e a descida pouco expressiva do ritmo de respostas com o aumento do número de clientes demonstram que a arquitectura escolhida é escalável. A comparação dos valores obtidos para o Cliente Local com os obtidos para a aplicação J2EE revela que o TeMIPConnector não incorre num overhead significativo, sendo assim passível de ser instalado nos servidores com o TeMIP, que representam sistemas críticos para as empresas. Demonstrou-se ainda que se pode utilizar o TeMIPConnector para construir aplicações que oferecem um desempenho razoável quando comparados com os interfaces nativos do TeMIP. Não sendo o TeMIPConnector o bottleneck das aplicações mas sim o TeMIP, um meio de aumentar o desempenho seria recorrer às capacidades de replicação e distribuição de carga do TeMIP, instalando vários Servidor RMI em servidores TeMIP replicados. O Conector poderia distribuir a carga por essas máquinas diminuindo assim o tempo de resposta em situações de grande carga. Certos tipos de aplicações podem beneficiar da implementação de mecanismos de cache. Não foi implementado um mecanismo de cache no TeMIPConnector, tendo sido deixado ao cuidado de cada aplicação fazê-lo, pois as necessidades variam de aplicação para aplicação. Para além dos algoritmos e tempos de refrescamento, o tipo de dados que pode ser reutilizado varia grandemente de aplicação para aplicação. Conclusões 159 Capítulo 8 – Conclusões Este capítulo apresenta as conclusões atingidas após a realização deste trabalho. Na primeira secção são apresentadas as conclusões propriamente ditas, enquanto que no segundo são apresentados possíveis rumos a seguir para o desenvolvimento deste trabalho. Conclusões 160 8.1 – Conclusões Do trabalho desenvolvido nesta tese resultou o TeMIPConnector, uma implementação da norma JCA 1.0 para a plataforma integrada de gestão de rede TeMIP. Esta implementação consiste em três módulos (biblioteca TalAccess, Servidor RMI e Conector), construídos incrementalmente, que permitem o desenvolvimento de diferentes tipo de aplicações integradas com o TeMIP: aplicações stand-alone Java a correrem na máquina do TeMIP; aplicações distríbuidas seguras a correrem remotamente; aplicações J2EE. Adicionalmente foram desenvolvidas três aplicações de teste, para avaliar a correcção e desempenho de cada um dos componentes desenvolvidos. Como prova de conceito foi ainda criada uma aplicação, denominada TeMIPWeb, que integra o TeMIP com outras fontes de dados, neste caso, um directório LDAP com informação sobre os utilizadores/responsáveis dos elementos de rede. O TeMIPWeb permite single sign on utilizando as credenciais de autenticação aceites pelo TeMIP graças à criação de um módulo de autenticação para o servidor J2EE JBoss. Os testes realizados demonstram que o elemento limitador do desempenho foi o próprio TeMIP e não o TeMIPConnector ou as aplicações desenvolvidas. Isto sugere que o desempenho poderia ser aumentado recorrendo às características de alta disponibilidade e redundância do TeMIP. O Conector poderia distribuir os pedidos por vários Servidores RMI, a correrem em diferentes servidores TeMIP replicados. A solução proposta procurou soluções simples para as limitações da actual versão da norma JCA. A utilização de filas de mensagens possibilitou um meio para as aplicações receberem eventos assíncronos do TeMIP. No entanto a recepção dos eventos têm de ser previamente solicitada. Não é possível ao TeMIP solicitar o despoletar de acções no servidor J2EE, apenas entregar eventos previamente solicitados. No entanto, a solução proposta apresenta as suas limitações, as quais foram observadas durante o desenvolvimento da aplicação Web de testes. Enquanto que uma deriva da arquitectura escolhida, podendo ser ultrapassada com recurso a soluções com maior complexidade de utilização e que criariam novos problemas, a outra deriva do TAL, não podendo ser ultrapassada. Conclusões 161 O processamento das respostas do TeMIP como texto ignora que alguns dos campos são compostos, necessitando o utilizador do TeMIPConnector de decompor estes campos. Não seria possível ao TeMIPConnector realizar a tarefa de decomposição pois não tem conhecimento semântico sobre as respostas do TeMIP. Uma alternativa seria a decomposição utilizando as classes do TAL, mas isso limitaria a funcionalidade (caso não suportasse todas as classes) e obrigaria a que o TeMIPConnector tivesse de ser actualizado sempre que o TAL fosse alterado ou fossem instalados novos módulos no TeMIP que aumentassem o número de classes disponíveis. A solução actual, onde o utilizador tem o ónus da decomposição é viável, pois este detém conhecimento da semântica dos dados que utiliza no TeMIP, podendo ter requisitos de decomposição específicos. A outra limitação encontrada foi o facto de ser necessário efectuar várias interrogações para obter dados que normalmente estão disponíveis numa só interrogação quando se utiliza a interface de linha de comando. Este problema está enraizado no TAL que apenas aceita um subconjunto da linguagem aceite pela interface de linha de comando. Para além disso, o TeMIP divide a informação sobre cada entidade em várias partições, não podendo uma interrogação ao TAL abranger ou devolver dados de mais que uma partição. Este connector, juntamente com a disponibilidade de connectors para outras aplicações permite o desenvolvimento de um novo tipo de aplicações de Gestão, capazes de fornecer uma perspectiva de gestão ao nível de Serviço. A maior das vantagens da arquitectura proposta é seguir a norma JCA 1.0, garantindo que pode ser utilizada em qualquer servidor que siga a versão 1.3 da norma J2EE. As aplicações desenvolvidas constituem sistemas protótipos, pelo que são apenas uma pequena amostra daquilo que pode ser feito recorrendo a este connector. A disponibilidade deste tipo de connectors permite pensar em novas aplicações, capazes de integrar a informação de gestão de rede e misturá-la com outros dados, de modo a que a sua utilização não se limite ao departamento responsável pela gestão de rede, mas seja aproveitada noutros domínios, por exemplo, gestão financeira ou estratégica. Conclusões 162 8.2 – Trabalho futuro no TeMIPConnector Existem modificações que podem ser realizadas ao TeMIPConnector de forma a melhorar o seu desempenho. Tal como referido na secção anterior uma dessas modificações é a possibilidade de distribuir a carga por vários servidores TeMIP. Esta solução não pôde ser testada devido a apenas estar disponível um servidor TeMIP. Uma futura colaboração com um Operador de Telecomunicações que utilize o TeMIP, poderia proporcionar os meios para este desenvolvimento. Tal colaboração permitiria o estudo e desenvolvimento de aplicações que efectivamente respondam às necessidades de gestão de uma rede de grandes dimensões. A análise do desempenho destas aplicações permitiria avaliar a necessidade de implementar outros mecanismos para aumentar o desempenho, como por exemplo, sistemas de cache, que podem ser implementados no Servidor RMI, no Conector ou nas próprias aplicações. Apenas uma avaliação experimental do TeMIPConnector num ambiente real de um operador pode validar o caminho a seguir. Isto é mais importante que futuros desenvolvimentos apenas tecnológicos. Outra das vantagens de uma colaboração com um Operador de Telecomunicações seria o acesso a elementos de rede que suportem gestão OSI/TMN. No ambiente de testes onde este trabalho foi desenvolvido, apenas estavam disponíveis elementos de rede com suporte para gestão SNMP. A migração do connector para a versão 1.5 da norma JCA, quando esta estiver disponível, é uma das possibilidades de trabalho futuro mais aliciantes. Esta versão propõe resolver as limitações da versão 1.0 que tiveram de ser ultrapassadas, nomeadamente a recepção de eventos assíncronos. Esta versão irá mesmo propor uma solução para permitir o início da conversação pelo EIS gerido, e não apenas pelas aplicações J2EE, como acontece na versão actual. Um outro caminho a seguir será avançar para o desenvolvimento de APIs de alto nível suportadas pelo TeMIPConnector. Estas APIs distanciam o utilizador dos pormenores do funcionamento do TeMIP. Possíveis normas a implementar seriam as interfaces Operation Support Systems through Java Initiative (OSS/J) ou JMX [113][114][115]. A primeira é o resultado do esforço conjunto de Operadores de Rede e fabricantes de Conclusões 163 plataformas de gestão, tendo resultado num conjunto de APIs para o acesso uniforme a sistemas de suporte à operação de redes. O JMX é uma tecnologia aberta para a gestão e monitorização de equipamentos ou software, permitindo gerir sistemas legados, ou sistemas que suportem JMX nativamente. Referências Bibliográficas Referências Bibliográficas [1] Olivier Daures, White Paper – OSS solutions for IP, The New Challenges (Compaq, 2002) [2] Kathleen Goolsby, White Paper - A guide for Establishing Service Level Specifications for Outsourcing Relationships (Everest Group, 2001) [3] RFC 1157, Simple Network Management Protocol (IETF, 1990) [4] M.3000, Overview of TMN recomendations (ITU-T, 2000) [5] X.700, Management Framework for Open Systems Interconnection (OSI) for CCITT Applications (ITU-T, 1992) [6] RFC 1213, Management Information Base for Network Management of TCP/IPBased Internets: MIB-II (IETF, 1991) [7] RFC 1155, Structure and Identification of Management Information for TCP/IPBased Internets (IETF, 1990) [8] Iosif G. Ghetie, Networks and Systems Management – Platforms, Analysis and Evaluation (Boston: Kluwer Academic Publishers, 1997) [9] M.3010, Principles of Telecommunications Management Network (ITU-T, 1996) [10] Lundy Lewis and Pradeep Ray, On the Migration from Enterprise Management to Integrated Service Level Management, IEEE Network, January/February, 2002, 814 [11] K. Willetts, Service Management – The drive for re-engineering, Proc. NOMS 1994 – IEEE/IFIP, 1994 [12] Qinzheng Kong, Graham Chen and Rubina Hussain Management, A Management Framework for Internet Services, Proc. NOMS 1998 – IEEE/IFIP, 1998, 21-29 [13] Charles Arehart, et al, Professional WAP (Birmingham: Wrox Press Ltd., 2000) [14] Jean-Philippe Martin-Flatin, Push vs. pull in Web-based network management application, Proc. IM 1999 – IEEE/IFIP, 1999, 3-18 [15] Kornel Terplan, Web-Based Systems & Network Management (Boca Raton: CRC Press, 1999) [16] S. Sengul, J. Gish and J. Tremlett, Building a service provisioning system using the Enterprise JavaBean framework, Proc. NOMS 2000 – IEEE/IFIP, 2000, 367380 Referências Bibliográficas [17] Jong-Tae Park, Moon-Sang Jeong and Seong-Beom Kim, A Platform Architecture for the Integration of CORBA Technology within TMN Framework, IEICE Trans. Commun., Vol. E82-B, No.11, 1999, 1770-1779 [18] Jae-Young Kim, et al, Towards TMN-Based Integrated Network Management Using CORBA and Java Technologies, IEICE Trans. Commun., Vol. E82-B, No.11, 1999, 1729-1740 [19] Subrahmanyam Allamaraju, et al, Professional Java Server Programming J2EE 1.3 Edition (Birmingham: Wrox press Ltd., 2001) [20] Ron Zahavi, Enterprise Application Integration with CORBA Component and Web-Based Solutions (New York: OMG Press / John Wiley & Sons Inc., 1999) [21] Rahul Sharma, et al, J2EE ConnectorArchitecture Specification Version 1.0 Final Release (http://java.sun.com /j2ee/connector/index.html) [22] Vitria (http://www.vitria.com/) [23] TIBCO Software Inc. (http://www.tibco.com/) [24] Mike Stonebraker, Too Much Middleware (http://research.microsoft.com/~jamesrh/hpts2001/submissions/MikeStonebraker.doc) [25] SAP (http://www.sap.com) [26] J2EETM Connector Architecture Product Information (http://java.sun.com/j2ee/connector/products.htm) [27] HP OpenView TeMIP home page (http://www.emea.compaq.com/TeMIP/) [28] X.720 (ISO/IEC 10165-1), Management Information Model (ITU-T, 1992) [29] M.3100, Generic Network Information Model (ITU-T, 1995) [30] M.3200, TMN Management Services and Telecommunications Managed Areas: Overview (ITU-T, 1997) [31] X.701 (ISO/IEC 10040), Systems Management Overview (ITU-T, 1992) [32] M.3400, TMN Management Functions (ITU-T, 1997) [33] X.731 (ISO/IEC 10164-2), State Management Function (ITU-T, 1992) [34] X.734 (ISO/IEC 10164-5), Event Report Management Function (ITU-T, 1992) [35] X.735 (ISO/IEC 10164-6), Log Control Function (ITU-T, 1992) [36] X.736 (ISO/IEC 10164-7), Security Alarm Reporting Function (ITU-T, 1992) [37] X.744 (ISO/IEC 10164-18), Software Management Function (ITU-T, 1996) [38] X.710 (ISO/IEC 9595), Common Management Information Service Definition for CCITT Applications (ITU-T, 1991) [39] X.711 (ISO/IEC 9596), Common Management Information Protocol Specification for CCITT Applications (ITU-T, 1991) [40] RFC 1189, The Common Management Information Services and Protocols for the Internet (CMOT and CMIP) (IETF, 1990) [41] Don Batorsky, et al, Telecom Operations Map, Approved Version 2.1 (TMForum, 2000) Referências Bibliográficas [42] Bruce Murrill, Network Management Detailed Operations Map, Evaluation Version 1.0 (TMForum, 1999) [43] Heinz-Gerd Hegering, Sebastian Abeck and Bernhard Neumair, Integrated Management of Networked Systems (San Francisco: Morgan Kaufmann Publishers, 1999) [44] The Ethereal Network Analyzer (http://www.ethereal.com/) [45] Kenneth Laudon and Jane Laudon, Management Information Systems, sixth edition, Organization and Technology in the Networked Enterprise (New Jersey: Prentice–Hall, Inc., 2000) [46] Teresa Vazão, Acetatos e Apontamentos para a cadeira de Gestão de Redes e Sistemas Distribuídos, 2000 [47] Amdocs (http://www.amdocs.com/) [48] Peregrine Systems (http://www.peregrine.com) [49] Orchestream (http://www.orchestream.com/) [50] Compaq Telecom - Solutions - Operational Support Systems (OSS)/TeMIP (http://telecom.compaq.com/solutions/solutioncategory.asp?category=13) [51] Kim Haase, Java Message Service API Tutorial (Palo Alto: Sun Microsystems Inc., 2001) [52] Press Release - WEBMETHODS TO INTEGRATE THE JBOSS J2EE-BASED APPLICATION SERVER WITH THE WEBMETHODS INTEGRATION PLATFORM (http://www.webmethods.com/press_release_detail/1,1075,2687,00.html, 2002) [53] Java Management Extensions (JMX) Home Page (http://java.sun.com/products/JavaManagement/index.html) [54] Sun Microsystems, Java™ Management Extensions Instrumentation and Agent Specification, v1.0 (Palo Alto: Sun Microsystems Inc., 2000) [55] Sun Microsystems, Java™ Management Extensions White Paper - Dynamic Management for the Service Age (Palo Alto: Sun Microsystems Inc., 1999) [56] Object Management Group (http://www.omg.org) [57] Business Integration - Segment Overview - IBM Software (http://www-3.ibm.com/software/integration/) [58] Neil Ward-Dutton, Ovum evaluates: Enterprise Application Integration (Ovum, 2003) [59] TeMIP Introduction (Digital Equipment Corporation, 1998) [60] HP OpenView TeMIP Solutions, solutions brief (http://www.emea.compaq.com/TeMIP/documents/BSC%20Solution%20Brief.pdf) [61] TeMIP Framework Iconic Map and FCL User’s Guide (Digital Equipment Corporation, 1998) [62] Visual TeMIP Development Guide (Digital Equipment Corporation, 1998) [63] TeMIP Access Library for DIGITAL UNIX and Windows NT, Reference Guide (Digital Equipment Corporation, 1998) Referências Bibliográficas [64] TeMIP Access Library for DIGITAL UNIX and Windows NT, Development Guide (Digital Equipment Corporation, 1998) [65] What is Java Technology? (http://java.sun.com/java2/whatis/) [66] Takashi Aoki and Takeshi Eto, “On the Software Virtual Machine for the Real Hardware Stack Machine”, Proc. Java Virtual Machine Research and Technology Symposium, 2001, 221-232 [67] David Bank, The Java Saga (http://www.wired.com/wired/archive/3.12/java.saga.html, 1995) [68] John Cassidy, dot.con The Greatest Story Ever Sold (New York: HarperCollins Publisher Inc., 2002) [69] Java Card Technology (http://java.sun.com/products/javacard/) [70] J2ME - Java 2 Platform, Micro Edition (http://java.sun.com/j2me/) [71] Java 2 Platform, Standard Edition (http://java.sun.com/j2se/) [72] Java 2 Platform, Enterprise Edition (http://java.sun.com/j2ee/) [73] JavaTM 2 Platform, Standard Edition v 1.3 (http://java.sun.com/j2se/1.3/) [74] The Java Language: An Overview (http://java.sun.com/docs/overviews/java/javaoverview-1.html) [75] Ken Arnold and James Gosling, The Java Programming Language Second Edition (Reading, Massachusetts: Addison Wesley Longman, Inc., 1997) [76] Mary Campione, et al, The Java Tutorial Continued: The Rest of the JDK (Reading, Massachusetts: Addison Wesley Longman, Inc., 1998) [77] Gjuru short couse - Fundamentals of RMI (http://developer.java.sun.com/developer/onlineTraining/rmi/) [78] Java 2 Platform, Enterprise Edition OVERVIEW (http://java.sun.com/j2ee/overview3.html) [79] Karl Avedal, et al, Professional JSP (Birmingham: Wrox press Ltd., 2000) [80] JAVASERVER PAGESTM PRODUCT INFORMATION (http://java.sun.com/products/jsp/product.html, 2000) [81] Andrew Harbourne-Thomas, et al, Professional Java Servlets 2.3 (Birmingham: Wrox Press Ltd., 2002) [82] Brian Behlendorf, et al, Open Sources, Voices from the Open Source Revolution (Sebastopol, California: O’Reilly & Associates, Inc., 1999) [83] The Jakarta Site - Apache Tomcat (http://jakarta.apache.org/tomcat) [84] João Garrott and António Ferreira, Programação na World Wide Web com CGIs (Lisboa: FCA – Editora de Informática, Lda, 1999) [85] Chris Lea, et al, Beginning PHP4 (Birmingham: Wrox Press Ltd., 2000) [86] PHP: Hypertext Preprocessor (http://www.php.net/) [87] A. Keyton Weissinger, ASP in a Nutshell, 2nd Edition (Sebastopol, California: O’Reilly & Associates, Inc., 2000) [88] The J2EE Tutorial (http://java.sun.com/j2ee/tutorial/1_3-fcs/) Referências Bibliográficas [89] Paul Perrone and Venkata Chaganti, Building Java Enterprise Systems with J2EE (Indianapolis: SAMS, 2000) [90] Rahul Sharma, et al, J2EE Connector Architecture and Enterprise Application Integration (Reading, Massachusetts: Addison Wesley Professional, 2001) [91] IBM software, CICS – Product Overview (http://www-3.ibm.com/software/htp/cics/) [92] BEA Systems (http://www.bea.com) [93] Marc Fleury, et al, JBoss Administration and Development (Indianapolis: SAMS, 2002) [94] The Apache Software Foundation (http://www.apache.org) [95] Eric S. Raymond, The Cathedral & The Bazaar, Musings on Linux and Open Source by an Accidental Revolutionary (Sebastopol, California: O’Reilly & Associates, Inc., 2001) [96] Sam Williams, Free as in Freedom, Richard Stallman’s crusade for free software (Sebastopol, California: O’Reilly & Associates, Inc., 2002) [97] JavaTM technology on hp Alpha systems for the JavaTM Platform (http://www.compaq.com/java/download/index.html) [98] JavaTM Secure Socket Extension (JSSE) (http://java.sun.com/products/jsse/) [99] DIGITAL C++ for DIGITAL UNIX Systems Version 6.1 Documentation (Compaq, 1998) [100] NetBeans Community (http://www.netbeans.org/) [101] Sun One Studio 4 (http://wwws.sun.com/software/sundev/jde/index.html) [102] Concurrent Versions System - The open standard for version control (http://www.cvshome.org/) [103] RCS - GNU Project - Free Software Foundation (FSF) (http://www.gnu.org/software/rcs/rcs.html) [104] The Apache Ant project (http://jakarta.apache.org/ant/) [105] XDoclet Attribute-Oriented Programming (http://xdoclet.sourceforge.net/) [106] Java 2 Platform, Enterprise Edition (J2EE) Reference Implementation (http://java.sun.com/j2ee/download.html) [107] JBoss :: Professional Open Source (http://www.jboss.org/) [108] James Kurose and Keith Ross, Computer Networking, A Top-Down Approach Featuring the Internet (Reading, Massachusetts: Addison Wesley Longman, Inc., 2001) [109] PersonalJava Application Environment (http://java.sun.com/products/personaljava/index.html) [110] CONNECTED DEVICE CONFIGURATION (CDC) and the CVM Virtual Machine (http://java.sun.com/products/cdc/) [111] Deepak Alur, John Crupi and Dan Malks, Core J2EE Patterns, Best Practices and Design Strategies (New Jersey: Prentice–Hall, Inc., 2001) Referências Bibliográficas [112] David Kerven, Jeff Foust and John Zakour, HTML 3.2 plus HOW-TO, The Definitive HTML 3.2 problem-solver (Corte Madera, California: Waite Group Press, 1997) [113] OSS through Java Initiative (http://java.sun.com/products/oss/) [114] Peter Lambert, OSS THROUGH JAVA™ INITIATIVE, A new breed of OSS solutions - Telecommunications Industry White Paper (OSS/J, 2002) [115] Java Management Extensions (JMX) Home Page (http://java.sun.com/products/JavaManagement/) Anexo A – Glossário Glossário 1PC one phase commit 2PC two phase commit 3G Third Generation of mobile communications technology API Application Program Interface ASP Active Server Pages BD Base de Dados BMP Bean Managed Persistency CCI Common Cliente Interface CDC Connected Device Configuration CGI Common Gateway Interface CICS Customer Information Control System CMIP Common Management Information Protocol CMOT CMIP over TCP CMP Container Managed Persistency CORBA Common Object Request Broker Architecture CRM Costumer Relationship Management CVS Concurrent Versions System DEC Digital Equipment Corporation DLL Dynamic Link Library EIS Enterprise Information Systems EJB Enterprise Java Beans ERP Enterprise Resource Planning FCL Framework Command Line FTP File Transfer Protocol GNU GNU's not Unix Anexo A – Glossário GSM Global System for Mobile Communications HTML Hyper Text Markup Language HTTP Hyper Text Transport Protocol IDE Integrated Development Environment IDS Intrusion Detection Systems IETF Internet Engineering Task Force IIOP Internet Inter ORB Protocol IP Internet Protocol ISO International Organization for Standardization ITU-T International Telecommunications Union – Telecommunication Standardization Sector IVR Interactive Voice Response J2EE Java 2 Enterprise Edition J2ME Java 2 Platform Micro Edition J2SE Java 2 Platform Standard Edition JAAS Java Authentication and Authorization Service JAR Java Archive javac Java Compiler JCA Java Connector Architecture JCP Java Community Process jdb Java Debugger JDBC Java Database Connectivity JIT Just In Time Compilation JMS Java Message Service JMX Java Management Extensions JNDI Java Naming and Directory Interface JNI Java Native Interface JRE Java Runtime Environment JSP Java Server Pages JSSE Java Secure Socket Extension JVM Java Virtual Machine LDAP Lightweight Directory Access Protocol MDB Message Driven Bean MIB Management Information Base Anexo A – Glossário OMG Object Management Group OSI/TMN Open Systems Interconnection/Telecommunications Management Network OSS Operations Support Systems OSS/J Operation Support Systems through Java Initiative PC Personal Computer PDA Personal Digital Assistent PHP PHP: Hypertext Preprocessor PM Presentation Module QoS Quality of Service RAR Resource Archive RCS Revision Control System RFC Request For Comments RMI Remote Method Invocation SAR JBoss Service Archive SDK Software Development Kit SGBD Sistemas de Gestão de Bases de Dados SLA Service Level Agreement SMTP Simple Mail Transport Protocol SNMP Simple Network Management Protocol SOAP Simple Object Access Protocol SQL Structured Query Language TAL TeMIP Access Library TCP/IP Transport Control Protocol/Internet Protocol TeMIP Telecommunications Management Information Platform TLS Transport Layer Security TMForum Telecommunications Management Forum TOM Telecom Operations Map TP Transaction Processing UDP User Datagram Protocol WAP Wireless Application Protocol WML Wireless Markup Language WWW World Wide Web XML Extensible Markup Language