UDDI
Para a publicação e pesquisa de Web Services
usa-se um servidor de nomes que implementa a norma
UDDI (Universal Description, Discovery and Integration).
Comparando com as outras tecnologias de chamada remota:
no Sun RPC usa-se o rpcbind,
no Java RMI usa-se o rmiregistry,
nos Web Services usa-se o UDDI.
Mais informação:
UDDI
JAX-R
Para comunicar com servidores UDDI,
existe a biblioteca JAX-R (Java API for XML Registries),
que permite publicar, pesquisar e eliminar registos de Web Services.
O esquema de dados do UDDI é consideravelmente mais rico do que o habitual num servidor de nomes,
com diversas entidades e relações,
que permitem guardar informação de negócio sobre a organização e os seus serviços.
Como consequência, o JAX-R é uma biblioteca verbosa,
que obriga a escrever muitas linhas de código para realizar as tarefas mais habituais de registo e de pesquisa.
Mais informação:
JAX-R
UDDI Naming
Para tornar a utilização do UDDI mais simples
foi criada a biblioteca UDDINaming que simplifica o esquema de dados para suportar apenas:
1 organização, 1 serviço e 1 implementação.
Esta biblioteca torna o registo e pesquisa de serviços mais sucinto.
O código fonte está disponível para consulta e modificação.
Mais informação:
UDDINaming JavaDoc
Exemplo
O exemplo seguinte é um Web Service que se regista no UDDI:
Nota:
na aula passada vimos Web Services construídos a partir do contrato WSDL,
mas os serviços podem também ser construídos a partir de código Java já existente, numa abordagem que se designa por implementation-first.
A interface Hello foi anotada com @WebService e
o WSDL é depois gerado automaticamente quando o servidor é lançado.
Seguem-se instruções detalhadas para construir e
executar o exemplo.
jUDDI (Java UDDI)
-
O servidor de nomes a utilizar é o jUDDI
alojado na RNL.
-
Para usar basta configurar a propriedade
uddi.url com o seguinte valor:
http://user:pass@uddi.sd.rnl.tecnico.ulisboa.pt:9090/
-
Os valores de user e pass para acesso ao UDDI devem ser pedidos ao professor no laboratório.
-
Para que a configuração seja feita para todos os exemplos,
pode-se criar um perfil Maven que sobrepõe o valor da propriedade para todos os projetos do utilizador.
Para isso, criar um ficheiro settings.xml na pasta .m2 da home do utilizador.
-
Em alternativa ao jUDDI da RNL, pode-se usar um jUDDI local:
-
O pacote de instalação pode ser encontrado na lista de software que se pediu para instalar.
-
Para lançar o servidor,
basta executar o seguinte comando na pasta juddi-.../bin:
-
startup.sh (Linux e Mac)
-
startup.bat (Windows)
-
juddi-startup / juddi-shutdown (laboratórios das aulas)
UDDINaming
-
Obter o código da biblioteca UDDINaming:
-
Instalar o módulo no repositório Maven local:
-
cd uddi-naming
-
mvn install
-
A biblioteca inclui testes de integração
(IT - Integration Tests)
que verificam o funcionamento correto do jUDDI antes de instalar o módulo.
-
Uma vez instalado o módulo no repositório Maven local,
a biblioteca pode ser usada como dependência em qualquer pom.xml.
Servidor JAX-WS
-
Construir e executar o servidor:
-
cd hello-ws_juddi
-
mvn compile exec:java
O nome da classe a executar e
os argumentos estão definidos no pom.xml
O servidor deve executar sem erros,
disponibilizando o endpoint address e
registando-se no UDDI.
-
Para confirmar que o servidor está a funcionar e à espera de pedidos,
consultar o contrato que é gerado automaticamente:
Cliente JAX-WS
-
Construir o cliente:
-
cd hello-ws-cli_juddi
-
mvn compile
Executa previamente generate-sources onde
o cliente obtém o contrato WSDL a partir do servidor e
usa a ferramenta wsimport para gerar as classes de invocação do serviço
(em target/)
-
Executar o cliente:
-
mvn exec:java
O cliente deve executar sem erros,
consultando o UDDI para descobrir o endereço do servidor,
e fazendo uma invocação remota.
Resumindo:
primeiro foi configurado o servidor de nomes jUDDI da RNL.
Depois foi instalada a biblioteca UDDINaming no repositório Maven local,
que testa também o funcionamento do servidor jUDDI.
Em seguida,
foi construído e iniciado o servidor,
que se regista no jUDDI e
fica à espera de pedidos no endpoint address.
Finalmente,
o cliente obtém o WSDL a partir do servidor e
gera o código de invocação que permite depois fazer invocações remotas.
Visão global do exemplo Hello World
Exercício
Continuação do Projeto
Station
Nesta parte devem surgir múltiplas estações e
aparece também o serviço binas-ws que vai comunicar com elas.
Assim sendo, o UDDI torna-se útil e necessário.
Pretende-se agora modificar station-ws
para se registar no UDDI.
-
Adicionar a dependência para a biblioteca UDDINaming:
...
<!-- UDDI Naming -->
<dependency>
<groupId>pt.ulisboa.tecnico.sdis</groupId>
<artifactId>uddi-naming</artifactId>
<version>1.2</version>
</dependency>
...
-
A StationApp deverá receber o endereço do UDDI e o nome do serviço como argumento.
-
O StationEndpointManager deverá ter um novo construtor que recebe o endereço do UDDI e
o nome do serviço, e
que efetua o registo
(e apaga quando o serviço termina).
-
Feitas as alterações,
o servidor deverá iniciar-se,
registar-se no UDDI e depois ficar à espera de pedidos.
Lançar mais do que uma instância do station-ws.
-
A forma mais simples de permitir múltiplas instâncias da estação é
parametrizar as propriedades de configuração com um número de instância.
-
No pom.xml é possível ver as seguintes definições
(substituir CXX pelo identificador do grupo):
...
<ws.i>1</ws.i>
<ws.host>localhost</ws.host>
<ws.port>808${ws.i}</ws.port>
<ws.url>http://${ws.host}:${ws.port}/station-ws/endpoint</ws.url>
<ws.name>CXX_Station${ws.i}</ws.name>
...
-
Para lançar uma station:
-
mvn compile
-
mvn exec:java
Por omissão, será a instância 1,
que fica à escuta de pedidos no porto 8081 e
que se regista com o nome CXX_Station1.
-
Para lançar outra station:
-
mvn exec:java -Dws.i=2
A instância 2 fica à escuta de pedidos no porto 8082 e
regista-se com o nome CXX_Station2.
Pretende-se agora modificar station-ws-cli
para pesquisar no UDDI.
-
Adicionar a dependência para a biblioteca UDDINaming.
-
O StationClient deverá ter um novo construtor que recebe o endereço do UDDI e
o nome do serviço a contactar, e
que efetua a pesquisa para localizar o servidor.
-
A StationClientApp deverá receber o endereço do UDDI e
o nome do serviço como argumento.
Binas
Antes de continuar é necessário completar o esqueleto do web service Binas que faz parte do ponto de partida para o projeto.
No laboratório da semana passada criamos o esqueleto da estação, vamos aproveitar o mesmo guia.
O objectivo é ter uma implementação do Binas com todos os métodos vazios e um cliente que chame os métodos remotos.
Guia do laboratório anterior.
Vamos agora implementar uma operação simples do servidor binas-ws que contacta as estações através de um PING.
-
O binas-ws vai ser cliente de station-ws.
Em vez de repetir código,
vamos usar o objeto StationClient,
já desenvolvido e testado.
-
Em primeiro lugar, instalar o módulo do cliente da station:
cd station-ws-cli
mvn install
-
Depois,
acrescentar a dependência Maven no binas-ws/pom.xml
(substituir CXX pelo identificador do grupo):
...
<dependency>
<groupId>org.binas.CXX</groupId>
<artifactId>station-ws-cli</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
...
O sistema em funcionamento terá três processos:
-
Concretizar a operação test_ping do binas.
-
Consultar o UDDI para pesquisar stations.
-
Criar um StationClient para cada estação encontrada.
-
Chamar a operação ping de cada um.
-
Juntar as respostas e
devolver como resultado.
Finalmente,
usar o binas-ws-cli para chamar o ping que vai fazer ping ao próprio binas e todos as stations.
-
Abrir consola para a Station 1:
-
cd station-ws
-
mvn compile exec:java
-
Abrir consola para a Station 2:
-
cd station-ws
-
mvn compile exec:java -Dws.i=2
-
Station 3
-
mvn compile exec:java -Dws.i=3
-
Abrir consola para o Binas:
-
cd binas-ws
-
mvn compile exec:java
-
Finalmente, na consola para o cliente do Binas:
-
cd binas-ws-cli
-
mvn compile exec:java
O resultado final do ping deverá ser impresso nesta consola.
O que falta fazer?
-
No binas-ws:
-
Implementar todas as operações de acordo com o enunciado
-
Fazer um bom tratamento de exceções
-
Não esquecer também que o servidor é multi-tarefa (thread) e
que os acessos a dados partilhados devem ser devidamente sincronizados
-
No binas-ws-cli:
-
Fazer testes de integração das operações principais
-
Testar casos mais importantes
-
Não esquecer os casos com entradas incorretas: null, "", valores inesperados, etc
-
Os testes de integração correm com mvn verify
Continuação de bom trabalho!