Labs SD >

Web Services Contract-First

Objetivos

Projeto:

Web Services

Um serviço é uma funcionalidade de um sistema de informação que pode ser invocada remotamente através da rede.
Um Web Service é um serviço que usa os protocolos de comunicação da World Wide Web - HTTP sobre TCP sobre IP - e protocolos adicionais para descrever mensagens e dados - SOAP sobre XML.
Para permitir uma definição rigorosa das operações e dos tipos de dados dos Web Services são usadas as linguagens WSDL (Web Services Description Language) e XSD (XML Schema Definition), respetivamente.

Web Service contract

Os Web Services também têm uma linguagem própria para descrever o seu contrato com os clientes.
A WSDL permite especificar a interface funcional (port type) - operações com entradas, saídas e erros - e também a vinculação (binding) com tecnologias concretas - habitualmente SOAP sobre HTTP.
A WSDL é baseada em XML de forma a ser independente da plataforma e usa XSD para definir o detalhe dos tipos de dados de entrada e saída (e erros) em cada operação.

Exemplo:

Mais informação:

Java API for XML Web Services

As bibliotecas JAX (Java API for XML) são a família de bibliotecas da plataforma Java que lidam com tecnologias baseadas em XML, como é o caso dos Web Services.
A JAX-WS (Java API for XML Web Services) é uma biblioteca para Java que permite implementar Web Services, usando as normas:
HTTP/TCP/IP para mensagens, SOAP/XML para mensagens, WSDL e XSD para descrição.

É possível implementar Web Services partindo de um contrato WSDL (e XSD) já existente.
Esta abordagem ao desenvolvimento de serviços é chamada contract-first.

Exemplo Ping Web Service:

Nota: As pastas que contêm o código não devem ter espaços nem caracteres acentuados no seu caminho.

Mais informação: JAX-WS

JUnit Integration Tests

Para garantir a qualidade do código do Web Service, é necessário produzir testes de integração (IT) que verificam o comportamento de todo o sistema através de invocações remotas.

No contexto dos Web Services, os testes de integração são um programa cliente (ws-cli) que faz invocações remotas a um programa servidor (ws), verificando o contrato das operações remotas definidas no WSDL.
Assume-se que todos os Web Services já foram previamente lançados antes de correr os testes de integração.

Mais informação: JUnit Integration Tests

 


Exercício

Início da primeira parte do projeto (P1)

O objectivo é construir um dos Web Services da primeira parte do projeto, seguindo a abordagem contract-first.

O ponto de partida é o projeto base. Este código inclui o servidor incompleto (station-ws) e o cliente incompleto (station-ws-cli).
Antes de começar, e para prevenir conflitos de módulos Maven, alterar os pom.xml substituindo as referências CXX pelo identificador do grupo.

Vamos começar pelo servidor station-ws:

  1. A estrutura do servidor está representada neste diagrama de classes UML.
    • O pacote à esquerda contém as classes que são geradas a partir do contrato WSDL.
    • O pacote à direita contém as classes do servidor:
      • a App onde a aplicação arranca,
      • o EndpointManager que disponibiliza o endereço do serviço,
      • o PortImpl que concretiza as operações definidas no WSDL, e
      • as classes de domínio que representam a informação armazenada pelo serviço.
  2. As classes de domínio da aplicação já estão implementadas no ponto de partida.
    1. Consulte o pacote domain.
    2. Identifique o Domain Root e as restantes entidades representadas nas classes.
    3. Veja os mecanismos de sincronização que são utilizados para garantir que as classes podem ser chamadas corretamente por múltiplas tarefas (threads).
  3. De seguida, consultar o contrato WSDL do serviço a implementar:
  4. Vamos gerar código Java a partir do WSDL. O Maven está configurado para chamar a ferramenta wsimport.
    1. Copie o ficheiro WSDL do serviço a implementar para a pasta src/main/resources do servidor
    2. cd station-ws
    3. mvn generate-sources
      Caso o WSDL esteja bem formado e válido, a ferramenta wsimport gera vários ficheiros que suportam o web service. Entre eles, estarão as classes para os tipos complexos usados como parâmetros e a interface Java que define o Web Service.
    4. Faça refresh (right-click, Maven, Update Project..., Force Update of Snapshots/Releases, OK) no Eclipse e consulte as classes geradas na pasta: target/generated-sources/wsimport.
      Em especial, consulte a classe ...Service, e descubra a interface Java ...PortType que foi gerada a partir do WSDL.
  5. Vamos agora concretizar o serviço.
    1. Consulte a classe de implementação do serviço ...PortImpl, que deverá implementar a interface Java gerada.
    2. Deverá associar a classe PortImpl ao WSDL através da anotação @WebService com os seguintes atributos: endpoint interface (nome do tipo Java do PortType), wsdlLocation (nome do ficheiro WSDL), name (definido no WSDL), portName (WSDL), targetNamespace (WSDL) e serviceName (WSDL).
    3. Além da anotação, todos os métodos listados na interface PortType devem ser implementados na classe do serviço. Algumas partes estão comentadas e podem ser descomentadas. Cada método é uma operação do Web Service, com entradas, saídas e excepções.
      Para cada operação, confira se está corretamente implementada.
      Adicione a anotação @Override antes de cada método de operação, para que o compilador confirme que está a implementar corretamente o método definido na interface.
      Note que as operações getInfo, getBina e returnBina não estão implementadas. Para já vamos compilar e executar o servidor sem estas operações estarem concluídas.
  6. Executar o servidor:
    1. 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.
    2. Confirmar que o servidor está à espera de pedidos no endereço:

Vamos agora usar o cliente station-ws-cli para testar o servidor.

  1. A estrutura do cliente está representada neste diagrama de classes UML.
    • O pacote à direita contém as classes que são geradas a partir do contrato WSDL.
    • O pacote à esquerda contém as classes do servidor:
      • a ClientApp onde a aplicação arranca, e
      • o Client que usa o stub gerado para fazer invocações remotas.
    Existem também os testes de integração, em que cada classe de testes se destina a testar uma operação remota.
  2. Vamos gerar o código Java para invocação do serviço.
    1. Consultar o pom.xml do cliente para:
      • confirmar que o WSDL está a ser corretamente referenciado (propriedades wsdl.directory e wsdl.filename
      • confirmar que a fase de wsimport está configurada.
    2. cd station-ws-cli
    3. mvn generate-sources
      As classes são geradas na pasta: target/generated-sources/wsimport.
  3. Vamos fazer uma chamada simples, correndo a aplicação cliente.
  4. Depois do teste pontual, vamos correr os testes de integração já existentes.

O que falta fazer antes da aula?

Bom trabalho!

Entrega da solução

Fénix, Avaliação, Projetos, mini Exercício 3 - Web Services

A solução completa deverá ser submetida no Fénix antes do fim da sua aula de laboratório. Trabalhos submetidos depois da hora de fim da aula não serão considerados.

Ter atenção ao seguinte:


© Docentes de Sistemas Distribuídos, Dep. Eng. Informática, Técnico Lisboa