UNIVERSIDADE FEDERAL DE SANTA CATARINA - UFSC CURSO DE CIÊNCIAS DA COMPUTAÇÃO DOUGLAS SCHROEDER FERNANDO MARÇAL SENRA Uma Proposta de Integração entre Centros de Saúde e Hospitais Públicos Baseada em Web Services (Rascunho) FLORIANÓPOLIS, NOVE DE FEVEREIRO DE 2007. 2 DOUGLAS SCHROEDER FERNANDO MARÇAL SENRA Titulo Uma Proposta de Integração entre Centros de Saúde e Hospitais Públicos Baseada em Web Services Trabalho de Conclusão de Curso, a ser apresentado para obtenção do grau de bacharel no curso de Ciências da Computação da Universidade Federal de Santa Catarina, UFSC. Orientador: Dr. João Bosco Mangueira Sobral 3 4 Dedicatória. (É permitido que cada um escreva uma dedicatória ou tem que ser única???) AGRADECIMENTOS Espaço reservado para agradecimentos àqueles que tornaram possível à realização deste trabalho. () 5 “Nossa vida é desperdiçada em detalhes... Simplifique, simplifique”. Henry ThoureauRESUMO O trabalho tem como objetivo propor e implementar uma arquitetura confiável para a execução de web services, que simulem o acesso a um sistema hospitalar com o propósito de fornecer serviços tais como a marcação de consultas, sendo acessado a partir de terminais remotos localizados nos postos de saúde. Nosso propósito aqui é, não apenas implementar os web services necessários para tal tarefa, como também integrar todo o software necessário para que o sistema possa executar de uma maneira estável. Também é objetivo aplicar técnicas normalmente aceitas de engenharia de software, nas etapas do projeto, desde sua concepção até a sua fase de testes. A motivação nasce da idéia de que serviços semelhantes disponibilizados por hospitais da rede pública de saúde, poderão trazer maior qualidade de vida para os usuários do sistema público, evitando que os mesmos passem horas em filas desnecessárias, muitas vezes em condição enferma. Palavras-chave: WEB SERVICES, AXIS, SOAP. LISTA DE ILUSTRAÇÕES figura 1 – A plataforma Java™ em sua versão J2SE 5.0 ..........................................17 figura 2 – Arquitetura do Hibernate em alto nível ......................................................26 6 figura 3 – Mecanismo do Axis Executando Como Servidor ......................................29 figura 4 – Mecanismo do Axis Executando Como Cliente.........................................30 figura 5 – Subsistemas do Axis .................................................................................31 figura 6 - Arquitetura básica dos Web Services.........................................................35 figura 7 – Web Service sendo utilizado para integrar aplicações...............................38 figura 8 – Web service utilizado para expor funções de Negócio..............................39 figura 9 – Como interagem WSDL, UDDI e SOAP................................................... 44 figura 10 – Modelo do Banco de Dados Hospital......................................................47 figura 11 –Estrutura interna do diretório do Tomcat no Windows XP....................... 48 figura 12 – Página de Configuração do Apache Tomcat 5.0.28................................49 figura 13 – Estrutura de diretório do Axis..................................................................49 figura 14 – Estrutura de diretório do Tomcat após a integração do Axis................. 50 figura 15 – Página com informações do Apache Axis..............................................50 figura 16 - Correspondência entre essas duas diferentes arquiteturas....................52 figura 17 – Abstração da arquitetura de um sistema real.........................................54 figura 18 – Diagrama de classes do pacote tcc.pojo................................................56 figura 19 - Trecho do arquivo WSDL com a definição de um tipo complexo............ 58 LISTA DE TABELAS Tabela 1 – Principais novidades do CORBA..............................................................32 Tabela 2 – Requisitos Funcionais do Sistema...........................................................44 Tabela 3 – Requisitos Não Funcionais do Sistema....................................................44 Tabela 4 –Tipos serializáveis por padrão pela engine SOAP do AXIS......................54 7 LISTA DE ABREVIATURAS E SIGLAS W3C – World Wide Web Consortium URL – Uniform Resource Locator HTTP – Hyper Text Transfer Protocol HTML – Hyper Text Markup Language XML – Extensible Markup Language SOAP – Service Oriented architectural Pattern RPC – Remote Procedure Call RMI – Remote Method Invocation WS-I – Web Services Interoperability Organization FTP – File Transfer Protocol SMTP – Simple Mail Transfer Protocol 8 DOM – Document Object Model CORBA – Common Object Request Broker Architecture OMG – Object Management Group API – Application Programming Interface OASIS – Organization for the Advancement of Structured Information Standards UFSC – Universidade Federal de Santa Catarina INE – Departamento de Informática e Estatística SGBD – Sistema Gerenciador de Banco de Dados UDDI – Universal Description, Discovery and Integration Service XML DSIG – XML Digital Signature JVM – Java Virtual Machine JCP – Java Community Process JSR – Java Specification Request HQL – Hibernate Query Language HBM – Hibernate-Mapping DAO – Data Access Object DTD – Document Type Definition PSH – Protótipo de Sistema Hospitalar HSQLDB – HSQL Database Engine JCE – Java Cryptography Extensions SSL – Secure Socket Layer TLS – Transport Secure Layer AWT – Alternative Window Toolkit TCP – Transmission Control Protocol IP – Internet Protocol WSDD – Web Service Deployment Descriptor WSDL – Web Service Description Language JDBC – Java Database Connectivity XSL – Extendible Stylesheet Language XSLT – XSL Transformation EDI – Eletronic Data Interchange RAM – Random Acces Memory 9 SUMÁRIO 1 APRESENTAÇÃO ................................................................................................. 11 1.1 Entidade ............................................................................................................. 11 1.2 Titulo................................................................................................................... 11 1.3 Autores ............................................................................................................... 11 1.4 Orientador .......................................................................................................... 11 1.5 Banca Avaliadora .............................................................................................. 11 2 INTRODUÇÃO ....................................................................................................... 12 2.1 Descrição do Problema..................................................................................... 12 12 2.2 Objetivos ............................................................................................................ 12 2.2.1 Objetivos Gerais ............................................................................................. 12 Aqui se entende por aplicação Web, uma aplicação que execute código HTML dentro de um navegador de Internet. .................................................................... 13 2.2.2 Objetivos Específicos .................................................................................... 13 3 Tecnologias Escolhidas....................................................................................... 13 3.1 Apache Tomcat .................................................................................................. 14 3.2 A tecnologia Java™ .......................................................................................... 15 3.2.1 A Linguagem Java .......................................................................................... 16 3.3 SGDB .................................................................................................................. 18 Fazendo a opção por messaging de documentos consegue-se que cada componente exponha e acesse interfaces simples, reduzindo, assim, as invocações remotas e facilitando a combinação dinâmica de componentes. Resumindo, tem-se baixo acoplamento. ............................................................... 35 4.1.5 Web Services .................................................................................................. 35 4.2 Visão do W3C sobre Web Services ................................................................. 36 4.3 SOAP (Simple Object Access Protocol) .......................................................... 38 4.4 WSDL (Web Service Description Language) ................................................... 39 REFERÊNCIAS ......................................................................................................... 48 1 APRESENTAÇÃO 111 2 1.1 Entidade Universidade Federal de Santa Catarina Curso de Ciências da Computação 1.2 Titulo Uma Proposta de Integração entre Centros de Saúde e Hospitais Públicos Baseada em Web Services. 1.3 Autores Douglas Schroeder. Fernando Marçal Senra. 1.4 Orientador Prof° João Bosco Mangueira Sobral, Doutor. 1.5 Banca Avaliadora Prof° Fernando Augusto da Silva Cruz, Doutorando. Profª Patrícia Vilain, Doutora. 2 INTRODUÇÃO 121 2 2.1 Descrição do Problema Os hospitais da rede pública de saúde possuem sistemas computacionais gerenciando seus vários processos, como a marcação de consultas, exames, cirurgias, atendimentos emergenciais, sistemas de controle financeiro, controle de lavanderia, sistemas de administração hospitalar, gerenciamento de protocolos, entre outros. A marcação de consultas invariavelmente se dá de uma mesma forma. A pessoa se dirige até o hospital, onde normalmente, em caso de emergência, vai buscar um atendimento imediato para seu problema, o que pode levar minutos ou horas, dependendo da gravidade de seu problema e do tamanho da fila no setor de emergências do hospital. Em outra situação, a pessoa pode não estar procurando o serviço de emergência. Deseja um atendimento preventivo com um clínico geral, ou foi encaminhada por um clínico geral ao hospital com a finalidade de agendar consulta com um médico especialista. Esta consulta pré-agendada poderá ocorrer em questão de horas, dias, ou mesmo meses, principalmente quando há necessidade de um médico especialista e exames sofisticados. Essas pessoas encaminhadas ao hospital, normalmente receberam atendimento médico prévio em um posto ou centro de saúde, em sua localidade, no qual são realizadas consultas com clínicos gerais, que encaminham o paciente a um hospital quando o mesmo necessita de atendimento especializado. 2.2 Objetivos A seguir uma breve descrição dos objetivos a serem atingidos por este trabalho. 2.2.1 Objetivos Gerais O objetivo central deste trabalho é implantar uma arquitetura estável, para execução de web services, além da implementação de um web service que permita a simulação da marcação de consultas, o cadastramento de pacientes, alteração dos dados cadastrais de pacientes, além de pesquisar as consultas já agendadas. O web service ira acessar um hospital fictício, pois não foi possível o acesso a um sistema hospitalar real. Durante o texto, este sistema hospitalar será referenciado como PSH (Protótipo de Sistema Hospitalar). 131 2 O serviço ficará acessível em um URL, onde o mesmo poderá ser acessado através de uma aplicação cliente, a qual pode ser Standalone ou Web1. A idéia é de que este serviço, estando disponível em um sistema real, forneça o serviço de marcação de consultas a partir de qualquer centro de saúde, desde que o mesmo possua um computador conectado a Internet, evitando dessa maneira, que o usuário deste centro de saúde se dirija a uma fila de hospital após ser encaminhado pelo centro com a finalidade única de agendar sua consulta. 2.2.2 Objetivos Específicos Os objetivos específicos deste trabalho são: Definir a estrutura e implementar o PSH. Definir a interface do Web Service. Implementar o Web Service com base em sua interface. Implantar um servidor de aplicações que disponibilize o web service utilizando tecnologia open source. Utilizar um SGBD (Sistema Gerenciador de Banco de Dados) open source para a base de dados do PSH. 1 Aqui se entende por aplicação Web, uma aplicação que execute código HTML dentro de um navegador de Internet. 3 Tecnologias Escolhidas 141 2 O objetivo deste capitulo é descrever as tecnologias escolhidas para a implantação do projeto, isso será feito de forma individual para cada tecnologia. 3.1 Apache Tomcat O Tomcat é um servidor de aplicações Java para web distribuído como software livre e desenvolvido com código fonte aberto. Até sua versão 5.5 foi desenvolvido dentro do conceituado projeto Apache Jacarta, sendo atualmente um projeto independente dentro da fundação Apache. É oficialmente endossado pela Sun Microsystems como a RI (Implementação de Referência) para as tecnologias Java™ Servlet, o qual suporta na versão 2.4 e JavaServer Pages, o qual suporta a versão 2.0. As Atuais versões destas tecnologias Java™ Servlet 2.5 e JavaServer Pages 2.1 possuem o servidor de aplicações JEE 5 Glassfish como implementação de referencia. Muitos são os lugares onde o Tomcat é descrito como sendo apenas um container para execução de Servlet e JSP, apesar deste conceito estar errado. Ele implementa grande parte da especificação da plataforma JEE, abrangendo as tecnologias de Servlet e JSP, incluindo tecnologias de apoio relacionadas como Realms e segurança, JNDI Resources e JDBC (Java DataBase Connectivity) Datasources. O Tomcat tem a capacidade de atuar como servidor web utilizando o protocolo HTTP sozinho, ou pode funcionar integrado a um servidor web dedicado como o Apache HTTP Server, Apache Geronimo, JBoss ou mesmo o Microsoft IIS. A escolha do Tomcat deve-se ao fato da mesma ser a implementação de referência da tecnologia JSP e servlet, o que comprova sua maturidade, possuir ótima documentação, ser de fácil integração com servidores HTTP, e ser de fácil integração com o Apache Axis, que será apresentado adiante no texto. O Tomcat além disso, pode facilmente ser implantado em um ambiente de Cluster, juntamente com o servidor Apache HTTP Server. Isso seria de grande valia para a implantação de um sistema real. O fato é que, um servidor web pode falhar, por diversas razões, e um container JSP pode falhar com muito maior probabilidade. Então a idéia de implementar essa arquitetura de cluster no servidor de uma aplicação web parece excelente, principalmente quando o sistema exige alta disponibilidade do serviço. Como o objetivo deste trabalho é apenas criar um 151 2 protótipo, esta tarefa não será realizada, já que o Tomcat é perfeitamente capaz de ser utilizado em ambientes de produção. 3.2 A tecnologia Java™ O objetivo deste tópico é falar um pouco a respeito da tecnologia a ser utilizada para a implementação dos sistemas integrantes deste projeto, seja o web service e seu cliente, seja o PSH. A escolha parece natural já que outras tecnologias a serem utilizadas nesse projeto são implementadas em Java, como o Axis, o Tomcat e o HSQLDB. Mas como será exposto posteriormente, web services permitem a interoperabilidade entre sistemas, logo a opção para implementação do presente trabalho poderia ter sido C++, por exemplo. A plataforma tecnológica Java™ foi à escolhida para a implementação do projeto por diversos motivo, dentre eles: Por ser uma tecnologia amplamente difundida, já estando presente hoje em mais de 3 bilhões de dispositivos segundo números da Sun. Por ser uma linguagem utilizada em várias disciplinas do curso de Ciências da Computação na UFSC. Por ser uma linguagem em constante evolução. Pelo gigantesco esforço da Sun Microsystems™ em popularizar e facilitar a cultura de web services desde a especificação do servidor de aplicações J2EE 1.4, e agora mais claramente, integrando ao novo JSE 6.0, APIs para facilitar o desenvolvimento de web services. Por ter sido liberado recentemente pela Sun, sob a licença GPL o que a torna definitivamente uma tecnologia open source. Pela enorme disponibilidade de projetos open source que utilizam a tecnologia e disponibilizam ferramentas e APIs que reduzem drasticamente o esforço de desenvolvimento. Pelas constantes melhorias de desempenho, possibilitando que as modernas JVMs (Java Virtual Machines) com seus JIT (Just in Time Compiler) possam apresentar desempenho ótimo, muitas vezes superior ao de compiladores estáticos, como por exemplo, o GCC (GNU Compiler Collection), o qual gera código dependente de 161 2 máquina para diversas linguagens, inclusive Java. Por ser altamente comprometida com a interoperabilidade de sistemas, podendo executar o mesmo código fonte em diversas plataformas. A plataforma Java™ não é a linguagem de programação Java, mas sim o conjunto de especificações, que definem entre outras coisas a linguagem de programação, o formato do arquivo .java, o formato do arquivo .class, o sistema de IO (Input Output), apenas para citar algumas. Essas Especificações nascem de um processo altamente democrático onde qualquer desenvolvedor pode participar com idéias, sugestões, ou mesmo apresentando uma JSR (Java Specification Requests) para o JCP (Java Community Process) , que é a entidade, independente da Sun apesar de que esta participa do processo, responsável por definir os novos rumos da tecnologia. Uma lista completa das JSRs pode ser encontrada em http://www.jcp.org/en/jsr/all . figura 1 – A plataforma Java™ em sua versão JSE 5.0 fonte: http://java.sun.com/j2se/1.5.0/docs/ A figura acima mostra a plataforma Java em sua versão JSE 5.0, a versão atual desta plataforma é a 6.0, mas como esta foi liberada apenas no inicio do ano corrente, a versão 5.0 foi escolhida para o trabalho. 171 2 3.2.1 A Linguagem Java Algumas características da linguagem Java: POO - É uma linguagem de programação orientada a objetos (POO), existem criticas sobre a visão de POO de Java, principalmente sobre seu modelo de herança, mas o JCP busca sempre a melhoria e novas especificações virão. Garbage Collector – Exime o programador de destruir os objetos que criou, os mesmos são automaticamente removidos da memória assim que o coletor de lixo percebe que o mesmo não é mais referenciado por nenhum outro objeto. Threads - Java possui suporte nativo ao mecanismo de threads, o que significa que durante a execução de um programa, a JVM pode escalar outros programas para execução. Por outro lado, um único programa pode rodar vários threads paralelamente, ficando a cargo do programador implementar a alternância de threads dentro de seu programa. Exceptions - o tratamento de erros no Java é realizado através do lançamento de exceções. Exceptions são objetos disparados sempre que um programa executa algo inesperado, como por exemplo, uma divisão por zero, o que na maioria das linguagens tradicionais como C, encerraria a execução com um erro fatal. Em Java o programador pode, através do conhecimento da exceção disparada, tratar o erro corretamente. Controlled Resources – O Controle de Recursos demonstra o grande esforço, desde o início, em tornar Java uma referencia em implementação segura. Para tanto, o acesso a recursos, como arquivos e rede, é enormemente controlado. Isso faz-se necessário, principalmente pelas diversas formas que uma pessoa pode invocar um programa Java, sem ter nem mesmo o conhecimento de que aquilo é um programa. Java API - seguindo o paradigma da orientação a objetos de se reaproveitar tudo ao máximo, uma API (Application Programming Interface) do Java é bastante extensa e abrangente. Não perca seu 181 2 tempo reinventando a roda, use as classes da API! Write once, run everywhere - O principio de que um programa Java, depois de compilado para a linguagem que a JVM interpreta, linguagem esta chamada Java bytecodes, os quais ficam guardados em arquivos de extensão .class (que possuem sua própria especificação, como tudo em Java), deverão executar sem problemas em qualquer implementação de JVM (desde que essa implementação seja aceita pela Sun) sobre qualquer sistema. E este é o segredo da portabilidade de programas Java: a única parte que necessita ser portada é a JVM, e não o seu programa. 3.3 SGDB No decorrer dos últimos anos, a maioria dos grandes SGBDs do mercado, dentre os quais podemos citar Oracle 10g, Microsoft SQL Server 2005 e IBM-Informix, dentre outros, passaram a distribuir versões de uso gratuito de seus SGBDs para bases de dados de até 4GB. Estes SGBDs possuem diversas restrições como a ausência do código fonte, limitações do número de processadores permitidos no servidor, quantidade de memória permitida no servidor, além de limites no número de conexões simultâneas. Portanto, estes foram logo descartados. Dentre os SGBDs de uso comercial distribuídos junto com o código fonte, e com licenças que permitem o uso, a cópia, a modificação e a distribuição das alterações, desde que seja mantida uma cópia da licença original, analisamos o Mysql AB, o Apache Derby e o HSQLDB. O Apache Derby e o HSQLDB se destacaram neste grupo por duas razões. A primeira é que ambos são SGBDs puro Java, o que em alguns casos pode trazer vantagens, como será visto. O segundo motivo é que benchmarks criados pelo projeto PolePosition (polepos.org) colocaram o HSQLDB à frente do Apache Derby em desempenho, este por sua vez esteve à frente do Mysql. O site afirma ainda que a maioria dos bancos proprietários testados teve desempenho inferior ao Mysql, portanto inferior aos bancos puro Java. Infelizmente questões de licenciamento impedem que o projeto divulgue os resultados para estes bancos. Uma vez que estes dois SGBDs analisados possuem características muito 191 2 parecidas, como será visto adiante, temos que realizar uma opção baseada em detalhes a fim de decidir a favor de um ou de outro. Em virtude da maior maturidade do HSQLDB, acabou-se optando por utilizá-lo como SGBD da aplicação. 3.3.1 Derby Apache Derby é um banco de dados relacional escrito inteiramente em Java, e como tal, roda em qualquer JVM certificada, sendo assim, é independente de plataforma. Além disso, é um banco compacto que suporta a maior parte das instruções SQL. Principais Características: Possui driver JDBC para conexão com aplicações Java™; Pode ser utilizado embutido em aplicações Java, rodando na mesma JVM da aplicação; Suporta o modo cliente/servidor, com várias conexões simultâneas; Está a pouco tempo no mercado, se comparado ao HSQLDB; A documentação é um tanto quanto escassa; 3.3.2 HSQLDB O HSQLDB é um banco de dados relacional inteiramente escrito em Java, podendo operar como um servidor de rede independente ou embutido em uma aplicação. Possui grande suporte ao dialeto SQL, incluindo triggers, procedures, integridade referencial, outer joins, visões, transações, campos tipo BLOB, schemas, roles, consultas correlatas e stored procedures. Tudo isso pode estar em um pacote jar com menos de 200 Kb, se for compilado sem as ferramentas gráficas de administração, e sem o servidor web embutido. Por esse motivo ele é ideal para o uso em aplicações embarcadas, ou seja, aplicações em que o SGBD executa na mesma JVM da aplicação. Mas como será visto, ele pode ser utilizado como servidor de banco de dados independente apresentando um ótimo desempenho. (Lozano, 2006, p.18). A sua maturidade pode ser comprovada através de alguns projetos que o utilizam, dentre os quais podemos citar o popular servidor de aplicação J2EE open source Jboss que o inclui como padrão na distribuição. A suíte de escritórios OpenOffice.org, que o inclui como servidor de banco de dados embutido na sua aplicação OOo Base, apesar da suíte OpenOffice.org não ser escrita em Java. Já foi inclusive utilizado como parte do sistema de apuração de votos durante as 201 2 eleições brasileiras, em um sistema que disponibilizava os dados da apuração em tempo real, o que sem dúvida, atesta a sua credibilidade. Alguns fatores que contribuíram para a escolha do HSQLDB: É um SGBD com código aberto, escrito totalmente na linguagem Java™; Pode ser agregado ao pacote da aplicação. Ou seja, não necessita ser instalado e configurado separadamente no Sistema Operacional para entrar em funcionamento; É multiplataforma, ou seja, independe do Sistema Operacional; Possui driver JDBC para conexão com aplicações Java; Permite a manipulação de banco de dados em uma arquitetura clienteservidor, ou em arquitetura standalone. Segundo o manual, apenas 170 KB de memória são necessários para rodar a engine do banco; Está consolidado no mercado, estando embutido em aplicações importantes como o JBoss; Possui documentação vasta e detalhada, inclusive em português; Possui um arquivo .properities padrão do Java, onde podem ser facilmente armazenadas informações sobre um banco de dados. 3.3.2.1 Arquitetura do HSQLDB O HSQLDB foi planejado para ser leve, com pouca demanda de hardware. O coração do HSQLDB é um engine SQL que opera em memória, sem realizar swap com o disco. Isto permite que o engine execute a partir de um cd, ou em ambientes com memória flash, geralmente ambientes com pouquíssima memória. Isso impõem uma limitação: Os registros e índices retornados após uma consulta devem ser mantidos em memória. Apesar do banco poder lidar com bases de dados de 8GB, utilizando um tipo especial de tabela que será apresentado adiante chamado tabela cached, ele não será capaz de retornar todo o conteúdo do banco em uma única consulta. Este problema pode ser contornado através da cláusula LIMIT do comando SELECT da linguagem SQL. O engine do HSQLDB roda como um único thread, de modo que só pode realizar um comando SQL por vez. Isso pode parecer uma grave limitação, mas é o que permite que o engine possa realizar locks e transações utilizando 170Kb de memória RAM de acordo com a documentação. Isso claro, sem contar a 211 2 memória utilizada pelos ResulSets JDBC abertos que alocam memória na própria JVM. Este fato não impede que o servidor aceite várias conexões com o banco ao mesmo tempo, sendo que cada conexão é servida por seu próprio thread. Ao mesmo tempo, isso não impede que cada conexão percorra, de maneira independente o seu objeto ResultSet, pois cada thread possui apenas a referencia aos seus dados retornados. Por outro lado, se o número de conexões crescer muito, é possível que o tempo de resposta das consultas seja comprometido, principalmente quando a consulta dispara stored procedures do banco, já que esta tem prioridade e executam até o fim antes que um novo thread possa assumir a execução na JVM. Como vantagem, este esquema multi-thread permite que as atividades de acesso à rede como envio de comando SQL e o retorno desses comandos executem de maneira paralela. Este mecanismo de thread também permite que uma aplicação utilize vários bancos HSQLDB, e como cada um possui seu próprio thread de engine, os usuários de um banco não competem com os usuários de outro banco, isso é muito útil quando o banco em questão é utilizado apenas para consulta, sem receber alteração de seus dados, como por exemplo, em sistemas de Data Warehouse. 3.3.2.2 Modos de operação Há quatro modos de operação do banco de dados, a fim de dar maior liberdade ao desenvolvedor, que passa a poder escolher o modo mais adequado ao seu sistema. Estes modos de operação determinam como as aplicações clientes irão se comunicar com o engine SQL. Em três dos modos de operação, modo Server, Web Server e Servlet são permitidos o uso de conexões seguras SSL/TLS através da utilização da API JCE (Java Cryptography Extensions). Modo Standalone: O HSQLDB roda na mesma JVM que a aplicação. Um container Web ou EJB pode usar o modo Standalone, visando maior segurança, uma vez que não é necessário abrir nenhuma porta TCP. Neste modo de operação pode haver diversas conexões simultâneas, desde que todas partam de outras threads dentro da mesma JVM. O engine SQL em si, roda em sua própria thread, como já foi exposto anteriormente, e será finalizado no caso do encerramento da JVM, através do comando 221 2 System.exit(), ou através do comando shutdown. Modo Server: É o modo preferencial para desenvolvimento. Neste caso são aceitas conexões por uma porta TCP, a qual pode ser configurada (9001 por padrão). A conexão é realizada através de um protocolo próprio do HSQLDB. Executando neste modo, o HSQLDB garante que clientes que executam em JVMs diferentes podem acessar o mesmo banco de dados simultaneamente. Neste modo de operação, o servidor só é encerrado através do comando shutdown, que só é permitido ser invocado por usuários com privilégio de administrador do banco e pode ser invocado por qualquer cliente que envie comandos SQL ao banco, como por exemplo o DbVisualizer, ou mesmo com clientes de gerenciamento Swing e AWT que acompanham a distribuição do HSQLDB. Caso o banco seja encerrado de maneira diferente da descrita a cima, um arquivo com extensão .lck não é apagado e deverá ser removido manualmente do diretório do banco encerrado subitamente. Modo Web Server: Empregado quando se deseja utilizar uma conexão remota com o banco de dados, mas existe um firewall no caminho. Desta forma é permitido realizar conexões do tipo TCP/IP através da porta 8080, o que normalmente permite que pacotes passem por um firewall sem a necessidade de configurações adicionais por parte do administrador da rede. Os comandos SQL são encapsulados em pacotes TCP/IP, sendo que os resultados são retornados pela mesma conexão. Diferente de conexões HTTP padrão, o HSQLDB no modo Server mantém a conexão aberta para receber múltiplas consultas. Um bom cenário para a utilização do modo Web Server é o uso de applets Java, ou aplicações do tipo Java Web Start. Em ambos os casos, as configurações de sandbox, o ambiente restrito onde uma JVM executa código que veio de uma conexão de rede, ao invés de um arquivo local, pode impedir que sejam criadas conexões TCP/IP a outro servidor que não seja o servidor de origem da aplicação. De esta forma rodar o próprio HSQLDB como servidor web contorna estes problemas. Modo Servlet: Visa atender a usuários que utilizam serviços de hospedagem compartilhada em sites web. Neste caso o servlet recebe comandos SQL como parte dos parâmetros da requisição HTTP, e devolve os resultados como resposta à requisição. Estes servidores geralmente disponibilizam apenas o MySQL, mas com algum esforço de configuração, é possível 231 2 para o usuário do serviço instalar o HSQLDB neste tipo de servidor. 3.3.2.3 Tipos de Tabelas Quanto ao tipo de tabela utilizada por um banco, o HSQLDB pode trabalhar com 3 tipos: Em memória : É o tipo padrão para a criação de tabelas. Com ele, todos os registros da tabela são mantidos em memória para acesso rápido. Este tipo de tabela deve ser utilizado quando o se pretende ter um acesso rápido aos dados independente do preço a se pagar pelo consumo de memória, Entretanto, os dados são preservados permanentemente em disco na finalização do banco de dados, e também no arquivo de log das transações, evitando a perda de dados em caso de falha no software ou hardware do servidor. várias aplicações se beneficiam de ter seus dados inteiramente em memória, e este mecanismo é mais simples e confiável que utilizar o mecanismo de cache com um banco de dados tradicional, pois o cache, como tradicionalmente é realizado por SGBDs mais robustos, pode facilmente ficar desatualizado. Em cache: Estes tipos de tabela mantêm os registros recentemente acessados em memória, mas gravam todos os dados em disco de forma imediata. O tamanho do cache é configurado pelo administrador para o servidor de banco de dados como um todo, não por tabela ou por banco de dados. Tipo Texto: Uma tabela tipo texto utiliza um arquivo texto comum para armazenar de forma permanente os seus registros, e a mesma área de memória para cache de registros que é utilizada para as tabelas cached. Tabelas de texto simplificam a troca de dados com fontes externas de dados, ao custo de uma pequena perda de performance. 3.3.2.4 Componentes do HSQLDB Apesar de ser uma ferramenta pequena, o HSQLDB engloba algumas funcionalidades interessantes, que serão brevemente descritas abaixo: Database Manager: Ferramenta gráfica para gerenciamento de banco de dados. Com ela é possível visualizar o esquema do banco de dados, conjunto de tabelas e submeter instruções SQL. Infelizmente esta ferramenta é 241 2 baseada em AWT, o que permite sua execução apenas em JVMs que impletem os recursos previstos no Personal Java™, logo possui código que não conta com a interoperabilidade entre sistemas, freqüentemente disponível na plataforma Java™, a fim de solucionar este problema existe o DataBaseManagerSwing, baseado na API Swing; Transfer Tool: Ferramenta que possibilita a transferência de esquemas SQL ou dados de uma fonte JDBC para outra. Muito útil quando se deseja migrar de um banco de dados para outro; Query Tool: provê ao desenvolvedor uma interface para interação com o SGBD através de instruções SQL; SQL Tool: outra ferramenta que permite a construção e submissão de instruções SQL; 3.4 Hibernate O Hibernate é um framework de mapeamento objeto/relacional para aplicações Java. Seu objetivo é facilitar o desenvolvimento de aplicações que dependem de bancos de dados relacionais. Aplicações que pouco utilizam o SGBD não tirarão o melhor proveito do seu uso. O Hibernate assume a responsabilidade pelo mapeamento das tabelas do modelo relacional para classes persistentes definidas em linguagem Java. Deste modo, o desenvolvedor pode se ater mais à parte do código referente ao modelo de negócio, aumentando sua produtividade. O modo como o Hibernate se integra com a aplicação pode ser visto na figura abaixo: 251 2 Figura 2 – Arquitetura do Hibernate em alto nível . A conexão do framework com a base de dados se dá basicamente via um driver JDBC apropriado e um arquivo de configuração (hibernate.cfg.xml) que deve ser previamente configurado antes da sua utilização. Os principais elementos que devem ser configurados são: hibernate.dialect: é a implementação do dialeto SQL específico do banco de dados a ser utilizado. hibernate.connection.driver_class: é o nome da classe do driver JDBC do banco de dados que está sendo utilizado. hibernate.connection.url: é a URL de conexão específica do banco que está sendo utilizado. hibernate.connection.username: é o nome de usuário com o qual o Hibernate deve se conectar ao banco. hibernate.connection.password: é a senha do usuário com o qual o Hibernate deve se conectar ao banco. Além desse arquivo, existem outros, onde são configurados os 261 2 mapeamentos das classes da aplicação para as tabelas do banco. Estes arquivos têm a extensão hbm.xml. O arquivo de mapeamento é um arquivo XML que define as propriedades e os relacionamentos de uma classe para o Hibernate, sendo que este arquivo pode conter classes, classes componentes e queries em HQL ou em SQL. 3.4.1 Mapeando Heranças No Hibernate existem diversas formas de se fazer o mapeamento de uma relação de herança. Usando uma tabela para cada classe filha, neste caso a classe pai não teria tabela, as propriedades comuns se repetiriam nas tabelas filhas. Usando uma tabela para todas as classes utilizando discriminadores que definiriam quando é uma classe ou outra. Usando uma tabela para cada uma das classes, assim haverá um arquivo de mapeamento para a classe pai e um outro arquivo para cada a classe filha. Usando uma mistura de todas essas possibilidades, o que esta disponível apenas na versão 3 do Hibernate. 3.4.2 Mapeando associações Para mapear associações entre tabelas não é necessário o uso de instruções SQL. Para tal, usa-se um “set” ou “conjunto” que representa uma coleção de objetos não repetidos, que podem ou não estar ordenados, dependendo da implementação da interface java.util.Set escolhida. Quando você adiciona um nó deste tipo em um arquivo de mapeamento, você está indicando ao Hibernate que o seu objeto tem um relacionamento 1:N ou N:N com outro objeto. 3.4.3 Mecanismo de Persistência do Hibernate Para o Hibernate, existem três tipos de objetos, “transient” (transientes), “detached” (desligados) e “persistent” (persistentes). Objetos “transient” são aqueles que ainda não tem uma representação no banco de dados, ou que foram excluídos, eles ainda não estão sobre o controle do framework e podem não ser mais referenciáveis a qualquer 271 2 momento, como qualquer objeto normal em Java. Objetos “detached” têm uma representação no banco de dados, mas não faz mais parte de uma sessão do Hibernate, o que significa que o seu estado pode não estar mais sincronizado com o banco de dados. Objetos “persistent” são os objetos que tem uma representação no banco de dados e que ainda fazem parte de uma transação do Hibernate, garantindo assim que o seu estado esteja sincronizado com o banco de dados. Isso nem sempre ocorre, claro. (LINHARES, 2006). A maioria dos SGBDs relacionais da atualidade possui suporte por parte desta ferramenta, entre eles podemos citar: Oracle 8i, 9i, 10g DB2 7.1, 7.2, 8.1 Microsoft SQL Server 2000 Sybase 12.5 (JConnect 5.5) MySQL 3.23, 4.0, 4.1, 5.0 PostgreSQL 7.1.2, 7.2, 7.3, 7.4, 8.0, 8.1 HSQLDB 1.61, 1.7.0, 1.7.2, 1.7.3, 1.8 InterSystems Cache' 2007.1 Apache Derby Firebird 1.5 FrontBase Informix Ingres Interbase 6.0.1 Pointbase Embedded 4.3 Progress 9 Isso é realmente interessante, pois caso se deseje migrar o banco para outro SGBD após o sistema estar em estagio avançado de desenvolvimento, basta alterar as configurações do arquivo hibernate.cfg.xml, além é claro, de trocar o driver JDBC da aplicação para o driver do novo SGBD escolhido. 3.4 Apache Axis 281 2 Desenvolvida pela Apache, a plataforma Axis é um projeto open source que implementa o Protocolo SOAP, sendo que este implementa o servidor e o cliente SOAP. Basicamente, o Axis trabalha com processamento de mensagens. É muito comum esta plataforma ser considerada um SOAP engine – um framework para a construção de processadores de mensagens SOAP. Atualmente encontra-se implementado na linguagem Java e linguagem C++ [11]. A plataforma Axis consiste basicamente de vários subsistemas funcionando conjuntamente e pretendemos a seguir dar uma visão geral de como isto funciona. Visto de uma forma simples, Axis consiste basicamente do processamento de mensagens. Quando o processamento central do Axis inicia, uma séria de manipuladores de mensagens são invocados em ordem. A ordem em que são chamados depende de 2 fatores – a configuração em que são desenvolvidos e distribuídos e se a configuração funciona como um cliente ou servidor.(FURTADO;BOTELHO, 2005, p.30) 3.4.1 Manipuladores (Handlers) e Corrente de Mensagens (Chains) no Axis Existem dois caminhos básicos que o axis invoca para transportar mensagens: 1. Como um servidor, um “transport listener”, que irá criar um “MessageContext” e irá chamar o framework do Axis sempre que for solicitado; 2) Como um Cliente, neste caso uma aplicação que irá gerar um “MessageContext” e irá chamar o framework do Axis sempre que for solicitado; A figura abaixo mostra como o Axis funciona no lado do servidor, sendo que os cilindros menores representam manipuladores de mensagens, e o cilindro maior representa uma corrente de manipuladores de mensagens ordenados (Chains). 291 2 Figura 3 – Mecanismo do Axis Executando Como Servidor Fonte: Axis Architecture Guide: http://ws.apache.org/axis/java/architectureguide.html#HandlersAndTheMessagePathInAxis Como está cadeia de manipuladores é instanciada e percorrida foge do escopo deste texto, o link acima fornece uma descrição completa deste processo em inglês. O caminho da mensagem do lado cliente é similar ao lado servidor, exceto pelo fato de a ordem de envio e recebimento de mensagens, fluírem em sentido oposto. Figura 4 – Mecanismo do Axis Executando Como Cliente Fonte: Axis Architecture Guide: http://ws.apache.org/axis/java/architectureguide.html#HandlersAndTheMessagePathInAxis 301 2 O Axis é divido em vários subsistemas, com o objetivo de dividir as responsabilidades e tornar a plataforma modular. Isto permite que apenas alguns subsistemas sejam utilizados na execução de uma tarefa, sendo desnecessário invocar alguns de seus módulos. Figura 5 – Subsistemas do Axis Fonte: Axis Architecture Guide: http://ws.apache.org/axis/java/architectureguide.html#HandlersAndTheMessagePathInAxis A figura acima mostra as camadas do Axis. As camadas mais baixas são independentes das camadas superiores. As caixas empilhadas são mutuamente independentes, embora não sejam mutuamente exclusivas. Esta figura mostra a divisão do Axis em subsistemas lógicos, na verdade a implementação difere desta. De acordo com o guia da arquitetura da plataforma Axis, os subsistemas apresentados acima podem estar divididos em pacotes com outros subsistemas. As peculiaridades do Axis, como por exemplo, seu fluxo de mensagens , contexto de mensagens, entre outras, fogem ao escopo deste trabalho e podem ser mais bem estudados no site do Axis (http://ws.apache.org/axis/java/architectureguide.html). 3.4.2 Expondo Web Services com Axis O Axis disponibiliza dois modos para disponibilizar os métodos de uma classe através de web services. O modo mais simples utiliza os arquivos JWS (Java Web Service) do Axis para gerar um arquivo WSDL (Web Service Description Language) o qual permite o acesso a web services mesmo sem estes estarem registrados no servidor do Axis. Isso é possível porque o WSDL contém a definição da interface 311 2 de um web service, descrevendo seus métodos e parâmetros de entrada. O outro método utiliza um arquivo WSDD (Web Service Deployment Descriptor), que descreve com detalhes como serão criados os web services a partir dos recursos existentes, que nada mas são do que classes Java comuns. Os dois arquivos citados acima podem ser gerados de maneira automática através do Axis. 4 Web Services 4.1 A Longa estrada até dos Web Services Ao contrário do que muitos imaginam, a tecnologia de Web Services não surgiu a partir de necessidades muito recentes. Sua origem está na evolução de diversas gerações de tecnologias anteriores. Nos anos 70, a programação de redes de computadores exigia o uso de APIs de camada de transporte, como por exemplo os BSD Sockets para TCP/IP. Atualmente, podemos fazer isso com classes do pacote java.net, como Socket e ServerSocket. Com essas APIs, podemos abrir conexões com processos que executam em outras máquinas, e enviar e receber blocos de bytes. Tal modelo de programação ainda é viável para aplicação muito simples, ou para casos que têm uma demanda extrema por eficiência, mas é um modelo muito rudimentar e difícil de trabalhar. 4.1.1 RPC A primeira tentativa real de subir o nível de programação de rede em direção às linguagens de programação foi a RPC (remote procedure call). A RPC permite invocar procedimentos através da rede, e introduz um conceito importante: as linguagens de definição de interface. Um compilador de interface irá ler o script escrito nesta linguagem e gerar um código stub que intercepta as invocações no cliente e as converte em mensagens de rede; e um skeleton no servidor, que recebe estas mensagens e executa a invocação ao procedimento real da operação no servidor. Caso a operação do servidor gere algum resultado, ela será enviada ao skeleton que a devolve ao cliente. As linguagens de definição de interface são independentes de arquitetura 321 2 ou compilador. Isso resolve um dos problemas da programação em rede, a heterogeneidade. Segundo Doederlein (2006, p.28), sistemas distribuídos são como as caixas de chocolate de Forrest Gump: você nunca sabe o que haverá no outro lado do cabo de rede. Isso tudo é muito bom, porém a RPC, como o próprio nome sugere, pertence à geração das linguagens estruturadas, muito boas para os tempos do C, mas não para linguagens OO. 4.1.2 Objetos Distribuídos: CORBA A chegada da POO, no final dos anos 80, exigiu uma tecnologia de programação distribuída adequada. A partir daí surgem os middlewares de Objetos Distribuídos (OD). O principal representante desta tecnologia é o CORBA,um padrão da OMG. Um programa CORBA também precisa de uma definição de interface, agora na sintaxe OMG IDL (Interface Definition Language). Esta interface já suporta herança, métodos, atributos, objetos, etc. Novamente um compilador de IDL gera códigos de stub e skeleton, que os clientes e servidores usam para acessar objetos remotos de forma transparente. Além do suporte a POO, o CORBA acrescenta dois conceitos importantes na evolução sobre a Sun RPC: ORB - Object Request Broker É um componente de runtime incorporado a cada aplicação que executa várias tarefas de gerenciamento como administrar portas de rede, criar threads nos servidores para responder a invocações concorrentes, além de executar um algoritmo de garbage collection. BUS – barramento O papel de cliente ou servidor de uma aplicação não é mais estático. A maioria das aplicações poderá desempenhar papeis de clientes ou de servidores conforme a situação; em especial, surgem interações do B2B (business-to-business) onde o servidor de uma aplicação, como um sistema de vendas, pode fazer o papel de cliente 331 2 de outra aplicação, como o sistema de controle de um inventário. Tabela 1 – Principais novidades do CORBA Além dos Object Services, o CORBA também construiu uma camada ortogonal de padrões para necessidades mas verticais, as chamadas “Domain Facilities”. Existem facilities para controle de tráfego aéreo, análise biomolecular, CAD, genômica. O conjunto de todos estes elementos – ORB, Object Services e Domain dacilities foi reunido sob título OMA (Object Management Architeture). 4.1.3 Entram os web services A partir do ano 2000 surge um novo middleware. Para muita gente foi uma surpresa o repentino interesse pelos Web Services. Com alternativas maduras e poderosas como CORBA e EJB. Qual a vantagem de substituir um protocolo binário eficiente , como o IIOP, por SOAP, tornando qualquer mensagem várias vezes maior e mais lenta -não seria apenas uma estratégia da Microsoft e da IBM, que lançaram a nova tecnologia?(DOEDERLEIN, 2006, p. 30). A Figura 6 representa a arquitetura básica dos Web Services. Nota-se algumas semelhanças com os middlewares distribuídos: A comunicação por rede utiliza um protocolo de mais alto nível que o TCP/IP. No caso, SOAP (Simple Object Acces Protocol), que é basicamente XML sobre HTTP. Mas o http já é um protocolo de alto nível implementado sobre o TCP/IP, temos duas camadas adicionais de protocolos. As aplicações podem utilizar código gerado por ferramentas (stubs e skeletons) para automatizar tarefas de comunicação. Por exemplo, APIs como a JAX-RPC fazem um mapeamento de invocações de métodos para mensagens SOAP. As aplicações também utilizam um runtime que implementa a comunicação do SOAP (como a API SAAJ do Java). Também podemos ter serviços padronizados , implementando operações úteis para as aplicações. O mais importante é o UDDI, um diretório que permite publicar e localizar informações sobre os serviços disponíveis. Estas informações são organizadas como documentos WSDL. 341 2 figura 6 - Arquitetura básica dos Web Services. 4.1.4 Acoplamento A principal desvantagem da “geração OD” era o alto acoplamento entre as aplicações. Para distribuir uma aplicação era necessário criar uma camada e interfaces remotas para expor todas as funcionalidades da aplicação que precisam ser mais acessíveis externamente. No total, esta ‘interface remota”poderia ter muitas páginas, expondo várias estruturas de dados, interfaces, e dezenas de métodos. Isto torna a aplicação completamente aberta para a rede, permitindo um alto grau de integração. Porém, os clientes desta IDL tendem a ficar muito dependente desta interface detalhada da aplicação. Esta dependência, caracteriza o que se conhece como alto acoplamento: uma forte dependência entre um componente de software e outros componentes. O problema surge quando seu servidor precisa ser acessado por aplicações completamente distintas. Neste caso, uma interface remota com granularidade muito fina, de baixo nível e que simplesmente expõe parte do seu modelo de classes de rede começa a não parecer uma boa idéia. Mas, o pior ainda está por vir. Todas estas invocações à interface remota 351 2 estarão sendo feitas pela rede, e não localmente. Invocações remotas (mesmo numa rede local) são muito mais lentas e menos confiáveis. Muitos tutoriais de Web Service o apresentam como outra forma de fazer RPC. Apesar de isso ser perfeitamente possível utilizando o protocolo SOAP, tal procedimento não traz muitas vantagens sobre a geração anterior, talvez, a facilidade de atravessar firewalls, mas está perdendo muito, tanto em velocidade, como em outras limitações. 4.1.4.1 Baixo acoplamento O avanço mais importante dos Web Service é estabelecer um modelo de comunicação com baixo acoplamento , ou seja, reduzindo ao mínimo a quantidade de informações que uma aplicação precisa ter sobre as demais. (DOEDERLEIN, 2006) Este baixo acoplamento é conseguido de várias maneiras: Messaging : O protocolo SOAP é assíncrono. Assim como JMS (e ao contrário de Sun RPC/CORBA/EJB), a regra é despachar uma mensagem e ir fazer outra coisa, enquanto a mensagem é entregue e processada por outras aplicações. Invocações síncronas, em que o invocador fica bloqueado enquanto aguarda uma mensagem de resposta, são possíveis, mas são as exceções à regra. Documentos: Ao invés de fazer invocações a procedimentos ou métodos no “modo documento” , enviamos documentos XML que descrevem transações de negócio. Por exemplo, uma lista de passos para uma aplicação de vendas pela Internet. Temos documentos que descrevem uma transação de negócio fim-a-fim como a compra de um produto. Os documentos trafegam entre as diversas aplicações envolvidas na execução da transação, e cada aplicação recebe um documento como conteúdo de mensagem. Fazendo a opção por messaging de documentos consegue-se que cada componente exponha e acesse interfaces simples, reduzindo, assim, as invocações remotas e facilitando a combinação dinâmica de componentes. Resumindo, tem-se baixo acoplamento. Outra vantagem dos middelewares de messaging é que as mensagens podem ser enviadas para destinatários indisponíveis. Estas mensagens ficarão 361 2 numa fila e serão entregues quando o destinatário reaparecer na rede. 4.1.5 Web Services Finalmente, qual é a vantagem especifica dos web services sobre outras opções de messaging, do serviço de eventos do CORBA a JMS? Mais uma vez, baixo acoplamento. Num mundo ideal, todos utilizariam o mesmo middleware, com os mesmo protocolos e formatos de dados. Na prática, nem todos usam CORBA, EJB, ou mesmo algum middleware orientado a mensagens (MOM) compatível com JMS. A vantagem dos web services é ser o mais forte candidato a middleware universal que todos suportam: o universo Java e o universo Windows, OMG, OASIS e W3C; IBM, BEA, Sun, Microsoft, Oracle, e grupos de software livre. O protocolo SOAP possui duas vantagens principais: Facilidade de tráfego na rede. Suas mensagens trafegam através de requisições HTTP, com cabeçalhos adicionais e conteúdos especiais. Pode parecer bobagem, mas a dificuldade de difusão pela Internet foi um grande problema para tecnologias como o CORBA. Uso de XML para as mensagens. Esta é sem dúvida a vantagem principal. O XML é um formato de dados de baixo acoplamento por excelência, por duas razões: é autodescrito e transformável. Num cenário de integração entre aplicações de tecnologias heterogêneas não é necessário que todas utilizem exatamente o mesmo esquema XML. Porém, é preciso que todos os participantes reconheçam as mesmas entidades, num nível abstrato. As pequenas diferenças entre os XMLs podem ser tratadas de forma automática por XSLT. Isso elimina boa parte do trabalho de integração entre aplicações distribuídas distintas, tradicionalmente exigia a programação de “pontes” entre cada par de interfaces incompatíveis. Com os web services, se todos falarem XML, o numero de conversões que não se consegue fazer via XSLT (XSL Transformations) costuma ser muito pequeno, e o transtorno de implementar as conversões remanescentes com código amarrado às aplicações participantes não será suficiente para justificar uma solução de EDI (Eletronic Data Interchange). Isso quer dizer que o SOAP torna estes cenários de integração bem mais baratos. 4.2 Visão do W3C sobre Web Services 371 2 De acordo com o W3C [1]: “There are many things that might be called "Web services" in the world at large. However, for the purpose of this Working Group and this architecture, and without prejudice toward other definitions, we will use the following definition: A Web service is a software system designed to support interoperable machine-tomachine interaction over a network. It has an interface described in a machineprocessable format (specifically WSDL). Other systems interact with the Web service in a manner prescribed by its description using SOAP-messages, typically conveyed using HTTP with an XML serialization in conjunction with other Webrelated standards.” 2 Existem outras definições, mais simples, mas acreditamos que essa é a mais completa e aceita, tendo em vista que o W3C (Word Wide Web Consortium) é o responsável pela especificação de diversas tecnologias incluindo as tecnologias relacionadas ao desenvolvimento de web services baseados em XML, SOAP e WSDL . A grande função de um web service é integrar sistemas escritos em diferentes linguagens, executando sobre diferentes plataformas de uma maneira padronizada e independente de fornecedores. figura 7 – Web Service sendo utilizado para integrar aplicações 2 A tradução será omitida a fim de não distorcer a idéia original expressa no glossário do W3C. O mesmo pode também ser utilizado para expor funções de negócio 381 2 especificas, de uma maneira eficiente, principalmente no quesito de independência de plataforma para implementação da aplicação cliente que ira acessar o web service. Este modelo fica demonstrado na figura 8. figura 8 – Web service utilizado para expor funções de Negócio. Houve muita badalação há alguns anos sobre o XML (Extensible Markup Language) apontada por alguns entusiastas como solução final para todos os problemas de integração. Hoje este entusiasmo recai sobre a tecnologia de web services. Também há aqueles que não enxergam nada de novo no modelo proposto para web services. Segundo Gomes (2004, p.66) em seu pequeno artigo, “Integração de Sistemas? Há mais que Web Services.”, apresentado na revista Java Magazine: “Ainda não me convenceram de que seja possível que aplicações web services automaticamente localizem novos serviços na rede e reconheçam mensagens e seus formatos, integrando-se facilmente e, como num passe de mágica, concebendo uma nova aplicação”. O pequeno artigo citado expunha em uma página, uma solução baseada em URI/HTTP/XML, a qual, segundo ele poderia retirar boa parte da complexidade da tecnologia de web services com pouco investimento em servidores e treinamento aos desenvolvedores além de infra-estrutura. A realidade observada hoje, após 391 2 curto período de tempo é que o mercado acreditou sim, na possibilidade de simplificar o trabalho daqueles que desejem, expor de maneira segura, alguns serviços já prestados por suas aplicações, na rede mundial de computadores. Nomes fortes da computação, como IBM, Oracle, Microsoft, Adobe, Xerox, SAP, Canon, BEA Systems, Sun Microsystems, entre outras, trabalham junto ao W3C em um forte empenho na definição de padrões e tecnologias para que a integração entre sistemas independentes deixe de ser uma experiência muitas vezes traumática nas diversas equipes de TI incumbidas de tal tarefa. 4.2.1 Uma visão de futuro para os Web Services A grande vantagem da web está em seu fácil acesso, e é de se esperar que em um determinado momento, os sistemas disponíveis nas redes internas das organizações, sejam estas pequenas, médias ou grandes, sejam disponibilizados na Internet. Com o advento da computação móvel, os serviços poderão estar disponíveis em qualquer lugar. Desde de distribuidores deixando seus produtos a venda em forma de web services e mecanismos de busca, com enorme poder de busca, encontrando estes serviços e reunindo-os de forma fácil em termos de usabilidade para o usuário final, em uma gigantesca loja virtual, onde os consumidores poderiam encontrar qualquer item que desejarem com a vantagem de poder comparar o produto de diversos fornecedores em tempo real, serviços específicos de acesso restrito aos parceiros e colaboradores, como a compra de produtos por uma loja que mantém a política de não possuir estoque, serviços públicos como emissão de documentos ou declaração de impostos, ou mesmo fornecer informação ao usuário final, como um simples horário de ônibus na tela de seu celular. 4.3 Padrões para implantação de Web Services Muitas tecnologias e padrões estão disponíveis para implementação e implantação de web services, mas aquelas que margeiam o desenvolvimento de web services baseados em XML tem levado vantagem dentre os principais fornecedores de tecnologia de web services. Veremos a seguir um resumo sobre estes padrões, perceba que não é objetivo deste trabalho detalhar os mesmos, sendo que estas informações poderão ser encontradas nas referencias para web sobre os padrões citados. 401 2 4.3.1 SOAP (Simple Object Access Protocol) O SOAP é a especificação de um protocolo de transmissão de dados codificados em XML. Define formas de simplificar a chamada remota de funções na Internet, permitindo que dois programas se comuniquem de forma muito semelhante à invocação de páginas Web. Foi submetido em 2003 pela IBM, Microsoft, Userland e DevelopMentor ao W3C que aceitou continuar o trabalho como mantenedor da especificação que hoje se encontra na versão 1.2. A atual versão é especificada em um documento produzido pelo XML Protocol Working Group que é também o responsável por futuras versões. Segundo a definição do W3C: “SOAP Version 1.2 (SOAP) is a lightweight protocol intended for exchanging structured information in a decentralized, distributed environment. It uses XML technologies to define an extensible messaging framework providing a message construct that can be exchanged over a variety of underlying protocols. The framework has been designed to be independent of any particular programming model and other implementation specific semantics.” Os dois principais objetivos do projeto para o SOAP, segundo o W3C3 são simplicidade e extensibilidade [XMLP]. O projeto SOAP procura atingir esses objetivos e omitir, do framework de mensagens, características que sejam encontradas com freqüência em sistemas distribuídos. Tais características incluem, mas não se limitam a “confiabilidade”, “segurança”, “correlação” e “distribuição”, além das SOAP Messages Exchange Patterns (MEPs) , ou em português “Padrão para troca de mensagens SOAP”. Sendo este último o principal foco do documento de especificação do protocolo SOAP. Outras características são deixadas para ser definida como extensões por outras especificações. É uma das tecnologias tidas como base para o desenvolvimento de web services baseados em XML. 3 http://www.w3.org/TR/soap12-part1/#intro 4.3.2 WSDL (Web Service Description Language) 411 2 A WSDL conforme já informado no texto, é um formato publico de XML para a descrição de Web Services atualmente desenvolvida e mantida pelo W3C. É fruto de uma submissão de diversas empresas ao W3C (Ariba, IBM e Microsoft), as quais possuem os direitos sobre a versão corrente, o WSDL versão 1.1. [9] No entanto, já existe um release para uma versão 2.0 de maio de 2005 que se tornará uma recomendação do W3C assim que for formalmente aprovada [10]. A WSDL (pronuncia-se wiz-dell) descreve uma interface publica para um web service. É um documento baseado em XML que descreve o serviço e a forma como o mesmo se comunica. Ou seja, descreve o protocolo de ligação e os formatos de mensagens requeridos para a interação com os web services listados em um diretório de services. As operações suportadas e as mensagens são descritas de maneira abstrata. A WSDL é freqüentemente combinada com o protocolo SOAP e com UDDI para prover web services na Internet. Dessa Maneira um programa cliente se conecta a um web service e pode ler seus arquivos WSDL a fim de determinar quais funções estão disponíveis no servidor. Alguns tipos especiais de dados são embarcados no arquivo WSDL na forma de um arquivo XML, o cliente pode então usar o protocolo SOAP para chamar uma dessas funções listadas no documento WSDL. 4.3.3 UDDI (Universal Description, Discovery and Integration Service) O UDDI é uma plataforma independente baseada em XML, e tem como função registrar serviços na Internet, ou em outras palavras. “Fornece um mecanismo para a descoberta dinâmica de serviços na web. Utilizando-se a interface do UDDI, negócios podem se conectar dinamicamente a outros serviços fornecidos por parceiros externos. Um registro UDDI é similar a um registro CORBA, ou pode ser imaginado com um serviço DNS para uma aplicação de negócios”. [CM2005] Um registro UDDI possui dois tipos de clientes: negócios que querem publicar um serviço, como no caso da loja virtual que procura por serviços de vários fornecedores a fim de exibir os preços, e clientes que querem obter serviços de 421 2 certo tipo, como quando uma empresa disponibiliza certas funções de seu sistema, como acesso através de web services, dado a certos colaboradores e parceiros, a serviços que estão disponíveis em seus sistemas. O UDDI é uma iniciativa aberta da industria, patrocinada pela OASIS (http://www.oasis-open.org/home/index.php) desenvolvido sobre o protocolo SOAP e assume que as requisições e respostas são objetos UDDI enviados como mensagens SOAP. Um registro de serviço UDDI é formado pro três componentes: Páginas Brancas – Fornecem o nome, endereço, telefone e outras informações de contato de um determinado negócio. São responsáveis pela publicação, ou seja, é como um fornecedor de serviço registra suas informações. Contêm a Informação do negócio, a qual é armazenada em um objeto BusinessEntity, o qual contêm informações sobre os serviços, categorias, contatos, URL e outros dados necessários para interagir com a empresa. Páginas Amarelas – Contêm informações que determinam a categoria do negócio. É responsável pela descoberta e mostra como uma aplicação descobre um serviço web em particular através dessas informações e fornece a informação do serviço, ou seja, descreve um grupo de serviços web. Estes estão contidos em um objeto BusinessService. Páginas Verdes – Contêm as informações técnicas sobre um serviço Web. É responsável pela conexão e mostra como uma aplicação se conecta e interage com um serviço web após sua descoberta. As informações de conexão provem os detalhes técnicos necessários para invocar um serviço web. Isto inclui URLS, informações sobre os nomes dos métodos, tipos de argumentos e assim por diante. Estes dados são representados no objeto BindingTemplate. O UDDI é, normalmente, um dos padrões do núcleo core da tecnologia de implementação de Web services. Ele foi projetado para ser acessado através de mensagens SOAP e providenciar acesso aos documentos WSDL que descrevem o protocolo de ligação e os formatos das mensagens que são necessários para a interação com os serviços web listados em um diretório. Figura 9 – Como interagem WSDL, UDDI e SOAP Fonte: H. Voormann distribuída de maneira legal sobre a licença GNU. A figura 9 demonstra como estas três tecnologias interagem para fornecer, disponibilizar e acessar web services. 431 2 441 2 5 Análise, Projeto e Implementação Este capítulo ira expor o trabalho realizado, desde a concepção da análise até a implementação e implantação do sistema desenvolvido. 5.1 Análise A visão geral do sistema proposto, irá nesta etapa ser transformada em requisitos funcionais e requisitos não funcionais. Aqui se entende por cliente qualquer tipo de aplicação que interaja com o web service e como sistema as aplicações PSH, web service e cliente. 5.1.1 Requisitos funcionais Cadastramento de Pacientes Alteração de dados cadastrais do Paciente Marcação de Consultas Visualizar Agenda Ao cliente deverá ser permitido através do web service cadastrar um paciente no PSH. Ao cliente deverá ser permitido através do web service alterar os dados cadastrais de um paciente do PSH. Ex: Endereço. Ao cliente deverá ser permitido através do web service agendar uma consulta com data, hora, médico, paciente, tipo de consulta e tipo de exame no PSH. Ao cliente deverá ser permitido através do web service, retornar agendas para um determinado médico ou um determinado paciente a partir da base de dados do PSH. Tabela 2 – Requisitos Funcionais do Sistema 5.1.2 Requisitos não funcionais Tecnologia de Implementação Banco de dados O sistema será desenvolvido em Java e compilado utilizando o compilador da plataforma J2SE 5. O banco de dados será instalado em um SGBD HSQLDB e executará em um servidor diferente do servidor de aplicação. 451 2 Servidor de Aplicação Persistência dos dados Será utilizada uma combinação Tomcat + Axis no servidor de aplicação a fim de disponibilizar o web service para acesso. A persistência dos dados devera ser realizada de maneira transparente a lógica do negócio, utilizando para está tarefa, o framework de persistência objeto/relacional Hibernate. Tabela 3 – Requisitos Não Funcionais do Sistema Uma visão mais detalhada dos requisitos e dos casos de uso correspondentes poderá ser encontrada no cd. 5.2 Implantação da Infra-estrutura A fim de executar os objetivos específicos do projeto é necessário se criar uma infra-estrutura para execução do PSH e do web service, está infra-estrutura precisou ser arquitetada e implantada, para que fosse possível atingir os objetivos gerais do trabalho, que é o de disponibilizar o web service para acesso através de requisições HTTP get ou mensagens SOAP em um URL especifico. 5.2.1 Armazenamento dos Dados Como já foi exposto no trabalho, não houve a possibilidade de se trabalhar com um sistema hospitalar real, portanto, para tornar possível à execução do projeto foi-se implementado o PSH. Para este, se tornou necessário criar uma base de dados fictícia, a qual representa uma pequena parte de um sistema hospitalar real. Um sistema real de gerenciamento hospitalar, facilmente possuiria mais que uma centena de tabelas, com informações relativas a todos os domínios de negócio necessários. Para a implementação do web service, no entanto, mesmo que se tenha acesso a uma base de dados de um sistema real, não haveria necessidade de se interagir com todo o banco, apenas as tabelas relativas ao cadastramento de pacientes e marcação de consultas seriam utilizadas. Dessa forma, criou-se um modelo relacional para o banco de dados capaz de suprir as necessidades do PSH, o qual pode ser observado na figura 10. 461 2 Figura 10 – Modelo do Banco de Dados Hospital Este modelo foi implantado em um SGBD HSQLDB 1.8.0.7 rodando em uma maquina isolada, configurado para o modo Server a fim de aceitar conexões via JDBC pela rede na porta 9001. O tipo de tabela utilizando no banco foi o tipoTexto. A instalação e a configuração do HSQLDB é extremamente simples, basta seguir a documentação do HSQLDB no site http://hsqldb.org/web/hsqlDocsFrame.html. Este banco de dados foi intensamente povoado através de um programa desenvolvido apenas para esta finalidade, que gerou um conjunto de dados baseado em alguns arquivos texto de maneira aleatória, e persistiu os mesmos no SGBD. 5.2.2 Servidor de Aplicações Apache Tomcat + Apache Axis Com a finalidade de prover um servidor de aplicações que atinja o objetivo especifico do projeto de implantar um servidor de aplicações para disponibilizar o web service utilizando tecnologia open source, criou-se uma estrutura utilizando o Apache Tomcat integrado com o Apache Axis, o que forma um servidor de aplicações amplamente utilizado para a exposição publica de web services. 5.2.2.1 Instalação e Configuração do Apache Tomcat 471 2 A instalação do Tomcat é bastante simples, foi utilizada a sua versão 5.0.28, que pode ser baixada gratuitamente através do site do Tomcat dentro do projeto Apache. Para instalar o Tomcat conforme descrito a seguir é necessário que a variável de ambiente JAVA_HOME esteja configurada para determinar o caminho base para o Java JDK ou JRE, isto foge ao escopo deste trabalho, mas pode ser facilmente encontrado informações na web sobre como fazê-lo em seu sistema operacional. Após baixar o arquivo para o seu computador, será necessário utilizar um programa descompactador, como por exemplo o WinRAR a fim de descompactar o conteúdo do arquivo baixado em um diretório qualquer de seu sistema de arquivos. Agora é necessário configurar a variável de ambiente CATALINA_HOME para apontar para o caminho do diretório de instalação do tomcat no sistema de arquivos. figura 11 –Estrutura interna do diretório do Tomcat no Windows XP A estrutura interna de diretórios do tomcat deve ficar semelhante à da figura acima, sendo que nesta imagem o Tomcat está instalado dentro do diretório C:\java. Depois de feito isso, basta entrar no diretório bin dentro do diretório do 481 2 Tomcat e executar o arquivo startup.bat no Windows, ou statup.sh no linux para iniciar o Tomcat ou shutdown.bat e shutdown.sh para finalizar a sua execução no Windows ou linux respectivamente. Para testar se a instalação do Tomcat teve sucesso, deve-se abrir um navegador web e digitar o seguinte URL, http://localhost:8080 , e caso a instalação esteja correta a seguinte tela deverá ser exibida. figura 12 – Página de Configuração do Apache Tomcat 5.0.28 5.2.2.2 Instalação e Configuração do Apache Axis A instalação do Apache Axis é um pouco mais complexa, mas os passos são bastante parecidos. Será utilizada a versão 1.4 do Axis implementada em Java, disponível para download no site http://www.apache.org/dyn/closer.cgi/ws/axis/1_4. Após o download deste arquivo é necessário descompactá-lo em um diretório conhecido. A estrutura de diretório do Axis descompactado deverá ficar semelhante ao da figura 13. figura 13 – Estrutura de diretório do Axis. Feito isso, basta copiar a pasta axis dentro da sub-pasta webapps 491 2 mostrada na figura 12 para dentro da pasta webapps do Tomcat. figura 14 – Estrutura de diretório do Tomcat após a integração do Axis. O Objetivo deste passo é integrar o Apache Axis ao Tomcat, tendo como resultado uma estrutura de diretórios semelhante à estrutura da figura 13. Feito isso, basta reiniciar o Tomcat e acessar o endereço http://localhost:8080/axis para confirmar a instalação. figura 15 – Página com informações do Apache Axis. Caso a página da figura 15 seja mostrada no navegador, a instalação 501 2 obteve sucesso. O site do Axis possui em sua documentação uma lista de soluções para os erros mais comuns que podem ocorrer neste momento. Se a página foi exibida corretamente, o servidor de aplicações está devidamente configurado para executar serviços, pois este passo já é suficiente para que o Axis possa executar web services integrado ao Tomcat. Se o desejo for preparar o ambiente para o desenvolvimento de web services com o Axis, é necessário adicionar as bibliotecas que estão na pasta lib, abaixo da pasta Axis1.4 como pode ser visto na figura 10, a variável de ambiente CLASSPATH de seu sistema operacional. As bibliotecas presentes nesta pasta são: axis.jar axis-ant.jar commons-discovery-0.2.jar commons-logging-1.0.4.jar jaxrpc.jar log4j-1.2.8.jar saaj.jar wsdl4j-1.5.1.jar Com o fim desta etapa, o ambiente está pronto para desenvolvimento e execução de web services utilizando o Apache Axis. 5.3 Arquitetura do PSH Para o projeto de implementação da aplicação PSH, optou-se por uma arquitetura dividida em três camadas, camada de apresentação, camada de negócios e camada de persistência. A seguir segue uma breve descrição das funções de cada uma delas de acordo com (ALUR; CRUPI; MALKS,2004): Camada de Apresentação Encapsula a lógica de apresentação exigida para servir os clientes que 511 2 acessam o sistema. Essa camada intercepta as solicitações dos clientes, fornece um único inicio de sessão, conduz o gerenciamento de sessão, controla o acesso a serviços de negócio, constrói e entrega respostas aos clientes. As tecnologias relacionadas com essa camada são Servlet e JSP. Camada de Negócios Fornece os serviços de negócios necessários aos clientes das aplicações. Contêm os dados e a lógica de negócios. Centraliza a maior parte do processamento de negócios para a aplicação. Camada de Persistência Camada de dados que é responsável por fazer a persistência e a gerência dos dados da aplicação, sendo que esta executa na máquina do servidor do banco de dados. Esta divisão em três camadas é recomendada para a maioria dos projetos JEE, sendo importante destacar que a mesma não é equivalente à arquitetura MVC (Model View-Controller), que tem se tornado padrão para aplicações web em Java. figura 16 - Correspondência entre essas duas diferentes arquiteturas. 5.3.1 Padrões de Projeto Utilizados no PSH 521 2 Com o objetivo de implementar a divisão de camadas proposta acima, alguns padrões de projeto foram utilizados: Padrões de Projeto da Camada de Negócio Para esta camada optou-se por adotar o padrão Business Object. Este padrão visa separar os dados e a lógica de negócios usando um modelo de objeto, o modelo escolhido foi o Composite Entity, que implementa um Business Object usando BEANs de entidades e POJOs locais. Com isso criou-se um domain model, ou seja, um conjunto de objetos de negócio para o sistema. Esses objetos devem ter o mínimo acoplamento com as classes de infra-estrutura do sistema, neste caso, a camada de persistência. Padrões de Projeto da Camada de persistência Nesta camada optou-se por utilizar o padrão de projeto DAO (J2EE Data Access Object), que tem por objetivo manter a lógica de acesso a bancos de dados dentro de objetos especializados, que transformam as queries e ResultSets retornados pela API JDBC em objetos que façam sentido para a aplicação que está fazendo uso dos DAOs. Aos DAOs, no entanto, o uso de JDBC é transparente, já que os objetos DAOs fazem uso do framework de persistência Hibernate para o retorno de seus dados. Padrões de Projeto da Camada de Apresentação A camada de apresentação para o PSH não foi implementada. Optou-se por isto já que esta não é um requisito para implantação do sistema, podendo assim ser reservado um maior tempo às outras atividades do projeto. 5.4 Arquitetura do Web Service Para o projeto de implementação do web service, optou-se pela criação de um subsistema com acesso ao banco de dados do hospital, capaz de realizar apenas as funções necessárias ao serviço. Este modelo de desenvolvimento permitiu a reusabilidade de classes implementadas no desenvolvimento do PSH e simplificou de maneira significativa o desenvolvimento do serviço. Neste caso, uma arquitetura em duas camadas aproveitando classes da camada de negócio e persistência do PSH utilizadas para gerar uma biblioteca de funções empacotada em um arquivo .jar, a qual pode ser incluída na pasta lib pertencente ao Axis dentro da pasta webapps do tomcat, com isso eliminou-se a 531 2 necessidade de implementar métodos que utilizassem RPC , ou em Java, RMI para acesso a aplicação PSH. Em uma situação real esta solução de reuso poderia ser utilizada nos hospitais que possuam o sistema implementado em Java, sendo que, nos sistemas não Java, a criação de um subsistema implementado em linguagem Java e empacotado em um arquivo .jar também seria uma solução válida. Por outro lado, poderia se criar um web service com acesso direto ao banco de dados via JDBC, ou ainda, utilizar a partir do serviço invocações remotas de procedimentos (RPC) já existentes no sistema alvo do serviço. Desta forma, o subsistema criado para o web service, herda os padrões de projetos adotados no PSH e o serviço implementa uma arquitetura baseada na figura 8. 5.41 Problemas de Arquitetura Estas soluções de arquitetura foram possíveis graças ao alto grau de abstração que envolve um protótipo, já que em um sistema real, contando com n hospitais a serem integrados, teríamos a seguinte situação. figura 17 – Abstração da arquitetura de um sistema real Na figura 17 podemos perceber que uma solução real envolveria web 541 2 services intermediários, os quais se comunicariam com o web service principal, exposto ao cliente através do servidor de aplicações. 5.5 Implementação O processo de implementação envolveu a utilização de algumas ferramentas, como por exemplo o IDE Eclipse3.2 para edição e compilação do código escrito em linguagem Java, apesar de que isso poderia ser realizado em qualquer editor de textos simples. 5.5.1 Implementação da camada de persistência Junto ao eclipse foi utilizado o plugin Hibernate Tools, que pode ser encontrado no site do Hibernate, o qual pode ser utilizado sem a IDE Eclipse através de comandos executados no prompt de comandos do Windows ou Shell em sistemas Unix. Após as configurações necessárias, este gerou o código dos JavaBeans, dos DAOs e os arquivos de mapeamento para o Hibernate através de engenharia reversa a partir do banco de dados “hospital”. O código gerado, como a maioria dos códigos conseguidos a partir de ferramentas, possui uma enorme quantidade de erros, os quais foram todos corrigidos através de técnicas de refatoração de código. Após a refatoração, o código gerado ainda apresenta um grave problema, os objetos retornados pelos DAOs são mapeados pelo Hibernate para objetos Java Beans, sendo que todas as atividades do Hibernate envolvidas para tal, eram administradas de maneira única por cada DAO gerado. A utilização do Hibernate envolve quatro atividades principais: Criação de um objeto SessionFactory. Obtenção e liberação de conexões ao banco de dados. Criação e fechamento de um objeto Session. Demarcação de Inicio e fim de um objeto Transaction no banco de dados. A criação de um SessionFactory é um processo extremamente caro em termos de processamento, sendo que o mesmo SessionFactory pode e deve ser utilizado por todos os threads da aplicação. Para isso foi criado um objeto denominado HibernateUtility que segue o 551 2 padrão de projeto singleton, fornecendo assim um ponto único para a criação do SessionFactory o que ocorre apenas uma única vez a cada sessão do cliente, além de gerenciar a obtenção e liberação de conexões com o banco e criação de objetos Session e Transaction. Desta forma, os DAOs passam a contar com um modelo otimizado para a utilização dos recursos do Hibernate. O objeto Transaction, apesar de ser criado pelo HibernateUtility no momento propício, deverá ser finalizado por quem iniciou a transação. Isso permite as classes de negócio realizar algumas transações durante o contexto de um objeto Session. Como o HibernateUtility é um singleton, o seu método commityTransaction () que finaliza o objeto Transaction, pode ser facilmente invocado a partir de qualquer ponto do sistema. Desta forma otimizou-se a utilização do framework Hibernate, o que recompensou a curva de aprendizado exigida pelo framework, já que no inicio o custo em processamento exigido pela constante iniciação de objetos SessionFactory tornava proibitivo a sua adoção. 5.5.1 Implementação da camada de negócio Na camada de negócio, a utilização do padrão Composite Entity pode aproveitar as classes Beans geradas e refatoradas, o que deixou todo o trabalho desta camada focado na implementação dos POJOS. A primeira tarefa então, foi definir os métodos a serem implementados por estes objetos, e a forma como os mesmos se relacionam com os JavaBeans e os DAOs. Desta tarefa surgiu o diagrama de classes apresentado na figura 18. 561 2 figura 18 – Diagrama de classes do pacote tcc.pojo Neste diagrama, que pode ser mais bem visualizado através da imagem disponível no cd, que também contem o arquivo original do software freeware Jude Community utilizado para gerar o diagrama, observa-se que a camada de negócio possui um baixo acoplamento com a camada de persistência. O ideal seria não possuir acoplamento com a camada de persistência, uma solução simples para isso, é a utilização de classes que implementem o padrão de projeto Java DTO (Java Data Transfer Object) e que seriam utilizadas para “transferir” os dados de uma camada a outra. Isso é importante em sistemas de grande porte, para que mesmo alterações robustas na camada de negócio, não interfiram na camada de persistência e vice-versa. No entanto o uso desta prática não é recomendado para aplicações de pequeno porte, e é o caso, pela alta carga de trabalho adicional a ser realizada pela equipe de desenvolvimento. A partir do diagrama de classes da figura 18, resta então a tarefa de 571 2 implementar as classes definidas, tarefa na qual o Jude auxilia gerando “esqueletos” de classe, contendo as estruturas de classe e de métodos, restando apenas a tarefa de implementar o corpo dos métodos. 5.6 Implementação do Web Service Inicialmente foi definida uma SID (Interface de Definição de Serviço) a partir do modelo de negócio da aplicação. Esta Interface contem todos os métodos que serão acessíveis através do serviço web. A partir desta interface é gerado um arquivo XML que descreve o serviço. Este arquivo, de extensão .wsdl é gerado a partir de uma ferramenta inclusa no pacote da ferramenta AXIS que utiliza a SID como base para a geração. Neste arquivo, além do que já foi visto anteriormente, devem ser especificados tipos complexos de objetos utilizados na aplicação, ou seja, objetos que não são serializáveis por default pela engine SOAP e se encontram na tabela 4. Java SOAP Serializer Deserializer String xsd:string Built-in* StringDeserializer* Boolean xsd:boolean Built-in* BooleanObjectDeserializer* boolean xsd:boolean Built-in* BooleanDeserializer* Double xsd:double Built-in* DoubleObjectDeserializer* double xsd:double Built-in* DoubleDeserializer* Long xsd:long Built-in* LongObjectDeserializer* long xsd:long Built-in* LongDeserializer* Float xsd:float Built-in* FloatObjectDeserializer* float xsd:float Built-in* FloatDeserializer* Integer xsd:int Built-in* IntObjectDeserializer* int xsd:int Built-in* IntDeserializer* Short xsd:short Built-in* ShortObjectDeserializer* short xsd:short Built-in* ShortDeserializer* Byte xsd:byte Built-in* ByteObjectDeserializer* byte xsd:byte Built-in* ByteDeserializer* BigDeci xsd:decimal mal Built-in DecimalDeserializer Tabela 4 - Tipos serializáveis por padrão pela engine SOAP do AXIS Tais objetos normalmente são Beans e para cada Bean que se deseja 581 2 utilizar durante o processo de troca de mensagens é necessário inserir uma entrada no arquivo WSDL como a entrada da figura 17. Isto é necessário pois a engine SOAP não pode simplesmente serializar qualquer objeto. Para objetos complexos é necessário definir os atributos dos mesmos. figura 19 - Trecho do arquivo WSDL com a definição de um tipo complexo Uma vez de posse do arquivo descritor do serviço, é possível gerar as classes que farão a comunicação entre o cliente e o servidor. No pacote de ferramentas do AXIS há ferramentas que possibilitam a geração do esqueleto de tais classes. Este processo será abordado com mais detalhes a seguir. A ferramenta WSDL2Java consiste em uma classe Java que é disponibilizada junto com o pacote da plataforma AXIS. Ela recebe como entrada um arquivo WSDL que descreve um serviço web. A partir deste arquivo são geradas chamadas de métodos em Java correspondentes à invocação das operações disponibilizadas pelo serviço. Na geração do código para o lado cliente, toda vez que for definido um tipo, ou seja, para cada entrada “type” do documento WSDL, serão gerados uma classe Java que implementa a classe descrita por “type” e um objeto holder4 caso este tipo for usado como parâmetro dos métodos implementados. Ainda, para cada elemento “portType” do documento, será gerada uma interface Java. Para cada elemento binding, uma classe Stub e para cada elemento service serão gerados uma interface de serviço e uma implementação do serviço (o localizador ou locator). Objetos holder podem ser usados como parâmetros de entrada e saída. Apesar da linguagem Java não implementar o conceito desse tipo de parâmetro, obtém-se este comportamento utilizando uma API do AXIS chamada Java JAX-RPC que especifica o uso dessas classes. 4 Uma classe holder é simplesmente uma classe que contém uma instância de seu próprio tipo. No processo de geração de código, obtêm-se uma classe Stub, que nada 591 2 mais é do que a implementação da SDI. Esta classe é responsável por converter as chamadas de métodos em mensagens SOAP. Para isso utiliza objetos Service e Call fornecidos pela própria plataforma AXIS. Ela funciona fazendo o meio de campo entre o serviço local e o remoto, permitindo ao mesmo ser chamado como se fosse um objeto local. Em outras palavras, não é necessário lidar com endpoints, URLs, namespaces, etc. No geral, um cliente não instancia uma classe Stub diretamente. Ao invés disso ele irá instanciar uma classe do tipo ServiceLocator, para depois chamar um método get dessa classe, este, por sua vez, retorna um objeto Stub. Da mesma forma como uma classe Stub representa o lado cliente do serviço, uma classe do tipo skeleton representa o lado servidor. Assim como os stubs, os skeletons podem ser gerados pela ferramenta do AXIS. Classes do tipo skeleton fazem o meio de campo entre a aplicação em si, que executará os métodos, e a engine SOAP. Ou seja, serializando e deserializando as mensagens. Além das classes mencionadas anteriormente, também se pode gerar um arquivo deploy.wsdd, o que indicará que a aplicação será instalada diretamente no servidor, sem o intermédio da classe skeleton. Este arquivo descreve o comportamento da classe e suas dependências. No anexo I pode ser encontrado o código da SID do web service. REFERÊNCIAS 601 2 ALUR, D.; CRUPI, J.; MALKS, D. Core J2EE Patterns. 2a. Ed. New York: Campus, 2004. FURTADO, Carlos Alberto; BOTELHO, Maurício. Avaliação de Plataformas para o Desenvolvimento de Web Services. 2005. 200 p. Tese (Bacharelado em Sistemas de Informação) – Curso de Bacharelado em Sistemas de Informação, Universidade Federal de Santa Catarina, Florianópolis, 2005. APACHE SOFTWARE FOUNDATION. Apache Derby Tutorial. Disponível em: <http://db.apache.org/derby/papers/DerbyTut/index.html>. Acesso em: 27 de Março de 2005. LOZANO, Fernando. O Novo HSQLDB. Java Magazine, Grajaú-RJ, n. 30, p. 18-22, 24-28, nov. 2005. LOZANO, Fernando; GALVÃO, Leonardo. Seção Cafeína, News e Bits. Java Magazine, Grajaú-RJ, n. 29, p. 6, out. 2005. CERAMI, Ethan – Web Services Essentials. Distributed Applications with XML-RPC, UDDI & WSDL. O´Reilly. Janeiro 2002. [1] WIKIPEDIA. Servidor Apache. Disponível em: <http://pt.wikipedia.org/wiki/Servidor_Apache>. Acesso em: 19 de Março de 2006. [2] < http://www.apache.org/>. Acesso em: 11 de Março de 2006. [3] Network Research Group. Hypertext Transfer Protocol -- HTTP/1.1. Disponível em: <http://www.w3.org/Protocols/rfc2616/rfc2616.html>. Acesso em: 13 de Março de 2006. [4] < http://httpd.apache.org/>. Acesso em: 22 de Janeiro de 2006. [5] W3C. SOAP Version 1.2 Part 1: Messaging Framework. Disponível em: <http://www.w3.org/TR/soap12-part1/#msgexchngmdl>. Acesso em: 19 de Fevereiro de 2006. [6] W3C. 3. SOAP Extensibility Model. Disponível em: <http://www.w3.org/TR/soap12-part1/#extensibility>. Acesso em: 11 de Março de 2006. [7] W3C. 4. SOAP Protocol Binding Framework. Disponível em: <http://www.w3.org/TR/soap12-part1/#transpbindframew >. Acesso em: 17 de Fevereiro de 2006. 611 2 [8] W3C. 5. SOAP Message Construct. Disponível em: < http://www.w3.org/TR/soap12-part1/#soapenv >. Acesso em: 17 de Fevereiro de 2006. [9] W3C. Web Services Description Language (WSDL) 1.1. Disponível em: < http://www.w3.org/TR/wsdl >. Acesso em: 17 de Fevereiro de 2006. [10] MILLER, John; VERMA, Kunal; RAJASEKARAN, Preeda.WSDL-S: A Proposal to W3C WSDL 2.0 Committee. Disponível em: <http://lsdis.cs.uga.edu/projects/wsdls/WSDL-S.pdf >. Acesso em: 18 de Fevereiro de 2006. [11] GIRALDI, Reubem Alexandre D’Almeida. FRAMEWORK PARA COORDENAÇÃO E MEDIAÇÃO DE WEB SERVICES MODELADOS COMO LEARNING OBJECTS PARA AMBIENTES DE APRENDIZADO NA WEB. 2004. 213 p. Dissertação (Obtenção do Grau de Mestrado) - Programa de Pós-graduação em Informática do Departamento de Informática do Centro Técnico e Científico. Rio de Janeiro, 2004. Glue user guide. Disponível em: <http://www1.webmethods.com/docs/glue/guide/index.html>. Acesso em: 18 de Fevereiro de 2005. LINHARES, Maurício. Introdução ao Hibernate 3. [online] Disponível em. http://www.guj.com.br/java.tutorial.artigo.174.1.guj. Acessado em 11 de Dezembro de 2006. LINHARES, Maurício. Hibernate 3 avançado, boas práticas, padrões e caching. [online] Disponível em. http://www.guj.com.br/java.tutorial.artigo.181.1.guj. Acessado em 10 de Dezembro de 2006. DOEDERLEIN, Osvaldo Pinali. Entendendo Web Services. Java Magazine, GrajaúRJ, n. 34, p. 26 – 39, Março/2006 Anexo I – Interface de Descrição do Serviço import java.rmi.RemoteException; import tcc.beans.AgendamentoBean; import tcc.beans.EnderecoBean; import tcc.beans.EscolaridadeBean; import tcc.beans.EspecialidadeBean; import tcc.beans.EstadoCivilBean; import tcc.beans.MedicoBean; import tcc.beans.PacienteBean; import tcc.beans.SetorBean; import tcc.beans.TipoConsultaBean; import tcc.beans.TipoExameBean; public interface WebServiceInterface { /** * Este método retorna uma lista contendo todos os pacientes que iniciam o nome com a string recebida. * @param nome * @return PacienteBean[] */ public abstract PacienteBean[] getPacientesComNome(String nome); /** * Este método retorna o paciente especifico pelo seu nome, caso o paciente * não esteja cadastrado lançara uma RemoteException. * @param nome * @return PacienteBean * @throws RemoteException */ public abstract PacienteBean getPacienteNome(String nome) throws RemoteException; /** * Este método retorna um paciente de acordo com o seu identificador no banco de dados. * Caso o paciente não exista é lançado uma RemoteException. * @param id * @return PacienteBean * @throws RemoteException */ public abstract PacienteBean getPacientePorIdentificador(Integer id) throws RemoteException; /** * Este método recebe uma instância de pacienteBean e tenta salvar a mesma no banco. * Este processo pode falhar por diversos motivos, retornando true caso obtenha sucesso * e false em caso de falha. * @param PacienteBean * @return boolean */ public abstract boolean cadastraNovoPaciente(PacienteBean pac); /** * Este método recebe uma nova instância de paciente e uma nova instância de endereço. * O método ira tentar salvar o novo paciente juntamente com seu endereço no banco. * Este processo pode falhar por diversos motivos, retornando true caso obtenha sucesso * e false em caso de falha. * @param PacienteBean, EnderecoBean * @return boolean */ public abstract boolean cadastraNovoPaciente(PacienteBean pac, EnderecoBean end); 621 2 /** * Este método altera o endereço de um paciente que já tenha sido retornado na sessão. * Feito isso, há uma tentativa salvar a alteração no banco. * Este processo pode falhar por diversos motivos, retornando true caso obtenha sucesso * e false em caso de falha. * @param EnderecoBean * @return boolean */ public abstract boolean alteraEnderecoPaciente(EnderecoBean endereco); /** * Este método altera o endereço do paciente recebido como argumento. * Este processo pode falhar por diversos motivos, retornando true caso obtenha sucesso * e false em caso de falha. * @param PacienteBean, EnderecoBean * @return boolean */ public abstract boolean alteraEnderecoPaciente(PacienteBean pac, EnderecoBean endereco); /** * Este método cadastra um endereço na sessão do hibernate, mas não o persiste pois o mesmo deve * ser associado a algum paciente para ser persistido. O objetivo é fornecer um meio para o cliente * cadastrar os dados relativos ao endereço de um paciente na session antes de cadastrar o paciente * propriamente dito. * Este processo pode falhar por diversos motivos, e em caso de falha, dispara uma RemoteException. * @param EnderecoBean * @return EnderecoBean * @throws RemoteException */ public abstract EnderecoBean cadastraEndereco(EnderecoBean end) throws RemoteException; /** * Este método retorna um array contendo todos os tipos de consulta cadastrados no sistema. * @return TipoConsultaBean[] */ public abstract TipoConsultaBean[] getTipoConsulta(); /** * Este método retorna uma instância de TipoConsultaBean contendo o tipo de consulta cadastrado no * sistema com a descrição fornecida, se a descrição fornecida for inválida, dispara uma RemoteException. * @param String * @return TipoConsultaBean * @throws RemoteException */ public abstract TipoConsultaBean getTipoConsultaDescricao(String descricao) throws RemoteException; /** * Este método retorna um array contendo todos os tipos de exame cadastrados no sistema. * @return TipoExame[] */ public abstract TipoExameBean[] getTipoExame(); /** * Este método retorna uma instância de TipoExameBean contendo o tipo de exame cadastrado no * sistema com a descrição fornecida, se a descrição fornecida for inválida, dispara uma RemoteException. * @param String * @return TipoExameBean * @throws RemoteException */ public abstract TipoExameBean getTipoExameDescricao(String descricao) throws RemoteException; 631 2 /** * Este método retorna um array contendo todos os tipos escolaridade cadastrados no sistema. * @return EscolaridadeBean[] */ public abstract EscolaridadeBean[] getEscolaridades(); /** * Este método retorna uma instância de escolaridade cadastrada no sistema de acordo com a sua descrição. * Se a descrição fornecida for inválida, dispara uma RemoteException. * @param String * @return EscolaridadeBean * @throws RemoteException */ public abstract EscolaridadeBean getEscolaridadeByID(String descricao) throws RemoteException; /** * Este método retorna um array contendo todos os tipos de estado civil cadastrados no sistema. * @return EstadoCivilBean[] */ public abstract EstadoCivilBean[] getEstadoCivil(); /** * Este método retorna uma instância de EstadoCivilBean contendo o estado civil cadastrado no sistema de * acordo com a descrioção recebida. * Se a descrição fornecida for inválida, dispara uma RemoteException * @return EstadoCivilBean * @throws RemoteException */ public abstract EstadoCivilBean getEstadoCivilByID(String descricao) throws RemoteException; /** * Este método retorna um array contendo todos os médicos que iniciam o nome * com a string recebida. * @param nome * @return MedicoBean[] */ public abstract MedicoBean[] getMedicosComNome(String nome); /** * Este método retorna um array contendo todos os médicos que possuem a especialidade * recebida. * @param EspecialidadeBean * @return MedicoBean[] */ public abstract MedicoBean[] getMedicosPorEspecialidade(EspecialidadeBean especialidade); /** * Este método retorna um médico especifico pelo seu nome, caso o médico * não esteja cadastrado lançara uma RemoteException. * @param nome * @return MedicoBean * @throws RemoteException */ public abstract MedicoBean getMedicoNome(String nome) throws RemoteException; /** * Este método retorna um médico de acordo com o seu identificador no banco de dados. * Caso o médico não esteja cadastrado lançara uma RemoteException. * @param id * @return MedicoBean * @throws RemoteException 641 2 */ public abstract MedicoBean getMedicoPorIdentificador(Integer id) throws RemoteException; /** * Este método retorna um array contendo todos os agendamentos cadastrados até o momento. * @return AgendamentoBean[] */ public abstract AgendamentoBean[] getAgendamentos(); /** * Este método retorna uma instância contendo o agendamento de acordo com a id passada. * Caso a id seja invalida, ira lançar uma RemoteException. * @param Integer * @return AgendamentoBean * @throws RemoteException */ public abstract AgendamentoBean getAgendamentoBean(Integer id) throws RemoteException; /** * Este método retorna um array contendo todos os agendamentos cadastrados até o momento para * um determinado médico. * @param MedicoBean * @return AgendamentoBean[] */ public abstract AgendamentoBean[] getAgendamentoByMedico(MedicoBean med); /** * Este método retorna uma lista contendo todos os agendamentos cadastrados até o momento para * um determinado paciente. * @return AgendamentoBean[] */ public abstract AgendamentoBean[] getAgendamentoByPaciente(PacienteBean pac); /** * Este método tenta cadastrar um novo agendamento recebido como argumento. * Este processo pode falhar por diversos motivos, retornando true caso obtenha sucesso * e false em caso de falha. * @param AgendamentoBean * @return boolean */ public abstract boolean cadastraNovoAgendamento(AgendamentoBean ag); /** * Este método tenta alterar o paciente de um agendamento já presente na sessão para o paciente * recebido no argumento. Este processo pode falhar por diversos motivos, retornando true caso * obtenha sucesso e false em caso de falha. * @param PacienteBean * @return boolean */ public abstract boolean alteraPacienteAgendamento(PacienteBean pac); /** * Este método tenta alterar o medico de um agendamento já presente na sessão para o medico * recebido no argumento. Este processo pode falhar por diversos motivos, retornando true caso * obtenha sucesso e false em caso de falha. * @param MedicoBean * @return boolean */ public abstract boolean alteraMedicoAgendamento(MedicoBean med); /** 651 2 * Este método tenta alterar o tipo de consulta de um agendamento já presente na sessão para tipo * de consulta recebido no argumento. Este processo pode falhar por diversos motivos, retornando * true caso obtenha sucesso e false em caso de falha. * @param TipoConsultaBean * @return boolean */ public abstract boolean alteraTipoConsultaAgendamento(TipoConsultaBean tc); 661 2 /** * Este método tenta alterar o tipo de exame de um agendamento já presente na sessão com o dado * recebido no argumento. Este processo pode falhar por diversos motivos, retornando true caso * obtenha sucesso e false em caso de falha. * @param TipoExameBean * @return boolean */ public abstract boolean alteraTipoExameAgendamento(TipoExameBean tipoExame); /** * Este método tenta alterar o setor de um agendamento já presente na sessão com o dado recebido o argumento. * Este processo pode falhar por diversos motivos, retornandotrue caso obtenha sucesso e false em caso de falha. * @param SetorBean * @return boolean */ public abstract boolean alteraSetorAgendamento(SetorBean setor); }//fim de classe