quarta-feira, 4 de maio de 2011

Composição de Serviços - Parte I: Coordenação

Uma das principais características de um Serviço, que deve ser perseguida desde o momento da especificação, é a sua capacidade de se compor com outros Serviços para a elaboração de um novo de mais alto nível de abstração. A figura abaixo ilustra esta capacidade.


Os próximos posts têm como objetivo apresentar algumas das opções de implementações para a Composição de Serviços.

Usualmente, a tecnologia de orquestração (geralmente associada a BPM) é a primeira a ser lembrada. Contudo, dependendo dos requerimentos, outras opções devem ser consideradas:
  • Coordenação ("Coordination")
  • Orquestração ("Orchestration", como mencionado acima) e Coreografia ("Choreography". Não, ela não é sinônimo de Orquestração como frequentemente é encontrado em diversos materiais).
Neste post descrevo de forma introdutória o primeiro item. O segundo fica para a parte II.

Coordenação
Este modelo, primeiramente, define a figura do Coordenador. O Serviço é o responsável pela execução dos Serviços Compostos, também chamados de Participantes. Usualmente, é ele que é exposto aos Serviços Consumidores, abstraindo para estes a existência dos seus Serviços Compostos. Como podemos imaginar, os Serviços Compostos tipicamente são independentes entre si, promovendo mais uma vez o conceito de baixo acoplamento.

A figura abaixo ilusta a situação. Um exemplo clássico para uma composição de serviços é aquele sobre um Agente de Viagens. O Agente cumpria o papel de Serviço Coordenador, enquanto uma Companhia Aérea, um Hotel e uma Locadora de Carros forneceriam os Serviços Participantes.


Há alguns padrões para Web Services que definem frameworks para Coordenação de Serviços. Dentre eles destaco:
Segundo o WS-Transactions, todos os Serviços pertencentes à composição dependem de um runtime ou framework específico chamado de Coordinator (não confundir com o Serviço Coordenador descrito acima). O Coordinator expõe dois serviços: Activation Service e Registration Service. A figura abaixo ilustra os Serviços da Coordenação e o Coordinator. O Coordinator é tipicamente implementado por engenhos como um Servidor de Aplicação.

O fluxo entre os Serviços da Coordenação e o Coordinator seria mais ou menos assim:
  1. O Serviço Coordenador (no nosso exemplo, a Agência de Viagens) faz uma requisição ao Activation Service do Coordinator.
  2. O Coordinator inicia uma nova coordenação e responde ao Serviço Coordenador com um contexto. O contexto possui informações diversas. Dentre as mais importantes, a identificação da coordenação e o endereço do próprio Coordinator.
  3. O Serviço Coordenador faz uma chamada ao Registration Service do Coordinator indicando que irá conduzir a coordenação.
  4. O Serviço Coordenador invoca o primeiro Serviço Participante (por exemplo, a Companhia Aérea) passando as informações de contexto recebidas do Coordinator. Tais informações são inseridas no cabeçalho SOAP da mensagem
  5. O Serviço Participante faz uma chamada ao Registration Service para registrar-se como integrante da coordenação.
    • Os passos 4 e 5 são realizados para os demais Serviços Participantes (no nosso exemplo, o Hotel e a Locadora de Carros).
  6. Os Serviços Participantes finalizam o seu processamento e informam o Coordinator. Note que os Serviços Participantes são totalmente independentes entre si e, portanto, não há uma ordem definida para o término e consequente resposta ao Coordinator.
  7. O Coordinator informa ao Serviço Coordenador sobre o finalização dos Serviços Participantes.
  8. O Serviço Coordenador envia ao Coordinator uma requisição para finalizar a coordenação.
  9. O Coordinator envia uma mensagem para finalização de coordenação para cada Serviço Participante.
Todo o processo fica mais interessantes em situações de exceção: suponha que o cliente da Agência de Viagens (representado pelo Serviço Consumidor) não fique satisfeito com as reservas realizadas. Neste caso o Serviço Coordenador envia uma requisição de compensação ao Coordinator. Este, por sua vez, requisita que o Serviço Participante relativo desfaça a reserva feita.

Os passos descritos acima são chamados, dentro da família WS-Transactions, de Business Activity, definido pelo padrão WS-BusinessActivity (WS-BA). O WS-Transactions define também o padrão WS-AtomicTransaction (WS-AT). A diferença é clara: por um lado o WS-AT define o conceito de Transação Atômica em um cenário de "tudo-ou-nada" entre os Serviços Participantes. Por outro, o WS-BA define o que chamamos de Long-Running Transactions. Eu fiz uma discussão sobre este tema em um post anterior. O exemplo foi dado justamente porque acredito que tenha mais aderência em uma Arquitetura Orientada a Serviços.

A figura ilustra uma situação onde temos somente um Coordinator interagindo com todos os Serviços. Isso quase sempre não é factível: em um ambiente absolutamente distribuído usualmente temos a presença de diversos Coordinators, um em cada ambiente onde os Serviços estão rodando. Deste modo, os Coordinators trocam mensagens a respeito das atividades realizadas pelos Serviços em relação à coordenação (por exemplo, os registros realizados pelos Serviços Participantes). O primeiro Coordinator (responsável pela interação com o Serviço Coordenador) é chamado de root, enquanto os demais são chamados de proxy.

Há inúmeras referências a respeito de Composicão de Serviços, mais precisamente, Coordenação (e Transações). Gostaria de destacar:

Nenhum comentário:

Postar um comentário