1.12 Organização do Documento
5.2.4 Implementação do Módulo de Descoberta de Serviços
A implementação do módulo de descoberta de serviços foi feita usando a linguagem Java e está representada por um diagrama de pacotes contendo as classes que operacionalizam o módulo de descoberta, conforme mostra a Figura 52.
No diagrama, o pacote bootstrap contém a classe RunDiscoveryService que é responsável pela criação e implantação do serviço de descoberta, deixando-o disponível para que outro módulo (funcionalidade) da arquitetura possa consumi-lo. O pacote interface abriga a interface DiscoveryService, que define o comportamento para o crawling e para o algoritmo de descoberta dinâmica. O pacote discoveryImplementation armazena o código que implementa a descoberta de serviços. Nele há duas classes. A classe Crawler responsável pela implementação da descoberta de serviços em tempo de projeto de aplicações e a classe DynamicDiscovery dedicada a descobrir um serviço mais adequado no momento em que a aplicação estiver em execução. O pacote model contém um conjunto de classes que representam estruturas de classes de informação utilizadas pelas classes
Crawler e DynamicDiscovery. A classe QoSInformation contém a estrutura conceitual que permite a manipulação das características de QoS obtidas a partir da ontologia de QoS. A classe Expression representa o conjunto de informações presentes na expressão da descoberta, usada para a descoberta de serviços. A classe DiscoveryResult representa a lista de serviços retornados pelo mecanismo de descoberta e a classe DiscoveredService contém a estrutura responsável por armazenar informações inerentes a um serviço.
Figura 52 - Implementação do módulo de descoberta descrito através de pacotes de classes.
O algoritmo básico usado na implementação do crawler é apresentado na Figura 53. O algoritmo usa como entrada o serviço desejado (definido a partir da ontologia UBL, descrita na Seção 4.2.3.3.1) e um conjunto de características de QoS (definido a partir da ontologia de QoS, descrita na Seção 4.2.3.3.1).
Para cada UDDI presente na federação, o algoritmo cria e lança threads (Figura 53, linhas 1-4). Elas verificam cada serviço comparando capacidades funcionais (i.e se o nome do serviço desejado pertence à ontologia UBL) e checam valores de QoS com os valores desejados. Se um serviço satisfizer a expressão da descoberta, o mesmo é incluído em uma lista de serviços candidatos (Figura 53, linha 12). Esta lista é retornada pelo crawling quando todas as threads finalizam suas pesquisas.
Figura 53 - Algoritmo básico do crawling.
O uso de threads na implementação dos algoritmos de descoberta (tanto no crawling como no algoritmo de DDS, este último descrito nos próximos parágrafos) se justifica em razão de dois pontos chave. O primeiro ponto está relacionado ao cenário de distribuição considerado para os repositórios de serviços (em computadores remotos). Assim, para cada UDDI, disponível na federação, foi criada uma thread para executar a descoberta. Isto facilitou a análise isolada dos resultados das descobertas efetuadas e a identificação de erros de conectividade entre o mecanismo de descoberta e uma determinada UDDI.
O segundo ponto se refere ao compartilhamento de recursos. Como a descoberta em uma UDDI é independente das demais, optou-se por criar threads para favorecer o compartilhamento de recursos, já que enquanto uma thread atua na descoberta propriamente dita (fazendo acesso e pesquisa em uma UDDI), outra pode estar usando o processador para outra atividade.
A Figura 54 mostra um exemplo de resultado produzido pelo crawling. Nela, a primeira coluna informa a relação dos nomes dos serviços descobertos (tais como: AuthorizePayment e Notify of Payment), a classificação da atividade dentro da ontologia UBL
(.../accountingCustomer/authorizePayment) é apresentada na segunda coluna, a quantidade de características de QoS desejados para uma dada atividade é mostrada na terceira coluna, identificada por QoS Constraints. Nessa coluna, tem-se o total de características de QoS requeridas na descoberta (neste caso apenas uma (1) característica foi informada). Ainda na Figura 54, na quarta coluna, a expressão identificada por Matching Services revela o total de serviços descobertos que satisfazem à expressão da descoberta.
Figura 54 - Exemplo de serviços retornados pelo crawling.
Como o crawling foi implementado através de um serviço web, sua invocação requer o conhecimento da sua definição, a qual é expressa através de um arquivo no formato WSDL, disponível em: http://localhost:8070/services/DiscoveryService/DiscoveryService.wsdl. De posse da definição do serviço, um módulo que deseja usar o crawling deve proceder da seguinte forma:
Instanciar um objeto da classe Crawler. Junto a este objeto, três parâmetros devem ser informados. O primeiro é a lista de UDDIs presentes e disponíveis na federação. O segundo parâmetro é a funcionalidade desejada para implementar a atividade (obtida a partir da ontologia UBL). O terceiro parâmetro é o conjunto de características de QoS requeridas (obtido a partir da ontologia de QoS);
Criar um objeto pertencente à classe DiscoveryResult para receber a lista de serviços candidatos retornada pelo crawling.
É importante salientar que, caso um usuário projetista de aplicações informe o uso da reputação do provedor, a lista de serviços candidatos retornada pelo crawling é classificada e apresentada de forma decrescente em relação à reputação do provedor.
O algoritmo de DDS (o submódulo que faz a descoberta em tempo de execução de aplicações) parte da lista de UDDIs disponíveis
na federação e da lista de serviços candidatos associada à atividade em execução.
Figura 55 - Algoritmo usado pelo ambiente de execução para descobrir dinamicamente serviços.
O algoritmo, nas linhas 1 a 7 (ver Figura 55) varre a lista de serviços candidatos da atividade corrente, averiguando a disponibilidade de cada serviço alocado previamente. Caso o serviço esteja disponível e acessível, a descoberta é finalizada (linha 7 da Figura 55), sendo que o serviço é imediatamente vinculado à atividade e a aplicação continua sua execução. Não havendo serviço candidato que possa ser usado na execução da aplicação (da atividade corrente), ocorre a descoberta dinâmica (linhas 8 a 24 da Figura 55). Threads são criadas e disparadas para cada uma das UDDIs disponíveis e ativas na Federação (linhas 8 a 11 da Figura 55). A partir deste ponto, o processo de descoberta acontece de maneira semelhante ao algoritmo de crawling. Todos os serviços são analisados, entretanto o primeiro a atender os valores contidos na expressão da descoberta é escolhido e imediatamente vinculado à aplicação. A DDS termina no momento que encontrar o
primeiro serviço que atenda aos critérios funcionais, de QoS desejados e esteja disponível e acessível (linha 20 da Figura 55).
Fundamentalmente, o algoritmo de DDS difere do algoritmo do crawling em dois aspectos. Antes de fazer uma busca efetiva, o algoritmo de DDS varre a lista de serviços candidatos até encontrar um primeiro serviço disponível e acessível. O segundo aspecto é referente ao término da descoberta. A descoberta dinâmica é finalizada quando encontra um (o primeiro) serviço que satisfaz a expressão da descoberta. O algoritmo da descoberta dinâmica também foi implementado através de um serviço web. A sua invocação requer o conhecimento do arquivo que contém a sua definição (WSDL), disponível em http://localhost:8069/services/DiscoveryService/DynamicDiscoveryServ ice.wsdl. O mecanismo de execução WS-BPEL é o responsável pela invocação do serviço de descoberta dinâmica, fazendo isto através das primitivas <invoke> e <receive> da linguagem WS-BPEL.
De forma similar à descoberta via crawling, na execução da descoberta dinâmica também ocorre a geração do contrato de uso do serviço (SLA) entre as partes envolvidas. Como forma de ilustrar a geração do SLA, um arquivo no formato XML foi criado usando como base a estrutura proposta por (CANCIAN; RABELO; VON WANGENHEIM, 2009). A Figura 56 mostra um fragmento do SLA gerado para um serviço hipotético. O elemento XML <AcordoGeral> informa as bases do contrato. O elemento XML <Objetivo> lista e descreve os objetivos do contrato. O elemento XML <Responsáveis> apresenta as partes envolvidas no contrato.
Figura 56 - Fragmento XML do SLA gerado para documentar o uso serviços. 5.2.5 Implementação do Módulo do Ambiente de Execução de
Aplicações
O ambiente de execução de aplicações é o local onde as aplicações prontas (no formato WS-BPEL) são armazenadas e executadas. Nele, conforme comentado no Capítulo 4, há um repositório de aplicações WS-BPEL, ou seja, uma pasta onde as aplicações WS- BPEL ficam armazenadas para serem executadas por um motor. O motor de execução de aplicações usado foi o Apache ODE (APACHE, 2010b). Em razão da necessidade de visualizar o estado das aplicações em execução, funcionalidade não oferecida pelo Apache ODE, houve a necessidade de usar a suíte BPMS Intalio v. 6.0.3.050, que já incorpora o Apache ODE. Com isso, bastou armazenar as aplicações prontas na pasta de aplicações do Intalio para que o mesmo, através de uma interface gráfica, permitisse o início da execução de aplicações (usando
o Apache ODE) e a visualização do estado das mesmas. Um exemplo da interface gráfica disponibilizada pelo Intalio para gerenciamento de aplicações pode ser visualizado em detalhes na Seção 5.3, apresenta um exemplo do funcionamento do protótipo computacional.