sexta-feira, 25 de janeiro de 2008

Java Gateway no Ensemble e alternativas via Web Services

Já mencionei num post anterior sobre Criptografia em Caché/Ensemble, que precisei usar criptografia. Como a API do Caché/Ensemble não contemplava nem de longe o que eu precisava (e mesmo a versão mais nova - que eu não uso - contempla, apesar de ter melhorado), fui em busca de outras soluções.

Como já havia trabalhado com Java, e sabia que tinha uma boa e vasta API, pensei porque não usá-la? Vasculhando na documentação, achei o recurso do Java Gateway, do Ensemble, que nas próprias palavras da Intersystems é:

"... um jeito fácil do Ensemble interoperar com componentes Java. O Java Gateway pode instanciar objetos java externos e manipulá-los como se fossem objetos nativos do Ensemble."

Como isso acontece? Bem, o Ensemble gera alguns "proxies" para as classes Java que você quer manipular. Estes proxies são classes dentro do Ensemble, em Caché Object Script (COS), que fazem chamadas ao Java Gateway. O Java Gateway nada mais é que um conjunto de classes/objetos que fazem a comunicação entre uma JVM (máquina virtual Java) e as classes do Ensemble. Dê uma olhada na figura abaixo, que mostra como é a arquitetura dessa solução:



Se você já estudou Sistemas Distribuídos, ou tem uma noção de como EJBs trabalham, deve reconhecer o design desta solução. O que o Java Gateway faz é nada menos que um pequeno "framework" (Middleware, na realidade) de chamadas remotas. Neste caso, o cliente é dentro do Ensemble e o objeto remoto, dentro da JVM. Simplificadamente, o processo é o seguinte:

- No Ensemble, você efetua uma chamada a um método da classe proxy.
- A classe proxy serializa/transforma os parâmetros para serem enviados via TCP/IP para a instância do Java Gateway que deve estar rodando em uma JVM (não necessariamente na mesma máquina).
- As classes do Java Gateway dentro da JVM recebem uma conexão TCP/IP, identificam que é uma chamada de um método, e reconstroem os parâmetros para serem reconhecidos em Java.
- Através de reflection, fazem a chamada ao objeto Java.
- O objeto Java retorna do método, possivelmente com algum valor.
- Esse valor passa pelo processo de serialização/transformação, e é enviado via TCP/IP para o Ensemble.
- A classe proxy recebe o valor pela conexão TCP/IP, transforma o(s) valor(es) para o formato usado no Caché e retorna para quem efetuou a chamada.

Nota: o processo de formatar/transformar/serializar os dados para serem enviados via rede, e o seu inverso, na literatura de Sistemas Distribuídos é geralmente chamado de marshaling/unmarshaling.

Pois bem, a descrição de todo o processo é muito legal, muito bonita, mas a implementação de qualquer middleware não é trivial, mesmo num ambiente restrito, como é o Java Gateway (só um tipo de cliente, um tipo de objeto servidor, e outros). Por isso, a ocorrência de bugs não é de todo inesperada.

E é exatamente isso o que aconteceu: bugs, bugs e mais bugs. Utilizando o Java Gateway na mesma máquina que rodava o Ensemble (não testei com uma JVM remota), a maioria das vezes, travava tudo. Depois de uma ou duas chamadas, a máquina parava de responder. Algumas vezes, só o Ensemble, mas em outras, congelava todo o computador, de maneira que só reiniciando no dedão.

Conclusão: desisti de usar o Java Gateway. Depois de dois dias investigando sem sucesso, e sem pista do que poderia estar acontecendo, desisti (note que a classe em Java era bem simples, servindo de proxy para umas funções de criptografia, e funcionava perfeitamente bem numa JVM stand-alone). No meu caso particular, achei melhor implementar o algoritmo de criptografia nativamente em Caché Object Script.

Mas nem sempre isso é possível, ou mesmo vantajoso. Imagine implementar em COS tudo o que já foi implementado em Java ou PHP, por exemplo, em termos de bibliotecas. Impraticável.

Eis que uns tempos atrás, na lista de discussão de Caché, o Rob Tweed compartilhou uma idéia que ele teve, e que está na thread Extending Cache using PHP.

O que ele fez? Simplesmente montou uma página em PHP simples, que retornava algo do tipo:

retorno=valor

Usando a classe %Net.HttpRequest, ele estabeleceu uma conexão para a página PHP, obteve o retorno, e simplesmente fez um parsing simples de "retorno=valor" usando a função $PIECE. Um esquema bem simples.

Se você anda por dentro das últimas notícias, deve ter notado que esse esquema é bem parecido (na verdade, praticamente uma simplificação) de arquiteturas Web Services utilizando chamadas estilo REST. Implementando-se um padrão para a troca de valores (em vez de uma String customizada, um XML ou JSON), você estaria construindo a sua primeira arquitetura Web Service REST =P.

Veja que esta abordagem não se limita a utilizar PHP, podendo implementar a página web com qualquer linguagem/plataforma, passando por Java e Ruby.

E apesar de haver algumas implicações não mostradas, por exemplo, falhas na conexão, re-tentativas de acesso, segurança, etc., pelo menos você tem liberdade para cobrir quais casos se aplicam ao seu ambiente. Por exemplo, se o servidor que roda o PHP estiver na mesma máquina que o Caché/Ensemble, não precisará lidar com falhas de conexão. No caso de uso do Java Gateway, você provavelmente também lidará com essas implicações, a diferença é o nível de controle que você terá, bem menor. E claro, estará sujeito a bugs que você provavelmente não terá como de lidar/corrigir.

Ainda no espírito de Web Services, o Caché provê algum suporte ao que se convencionou chamar de estilo ou stack WS-*, que utiliza padrões mais robustos, e consequentemente mais complexos (WSDL, UDDI, WS-Security, entre outros). Para problemas simples, talvez seja pedir demais, mas a idéia permanece a mesma: extender as capacidades do Caché/Ensemble usando invocações de provedores externos.

Conclusão: para extender as capacidades do Ensemble, prefira outras alternativas, como a utilização de Web Services, do que o uso do Java Gateway. Como o Java Gateway também cria um processo separado para a execução da JVM, não existem ganhos significativos em relação ao uso de um outro servidor leve, como por exemplo, um Tomcat. Em suma, talvez o Java Gateway tenha servido há algum tempo atrás, mas hoje em dia, deve ser usado somente em caso de código legado que faça uso deste.

Em tempo: a versão nova do Ensemble parece não ter novidades em relação ao Java Gateway, pelo menos não encontrei nada olhando a documentação da nova versão.

4 comentários:

Aceito Pix disse...

Após esse post meu cérebro entrou em curto e só cerveja vai curar ehehehehe.

Aceito Pix disse...

Tipo assim, eu fui chamada de burra e ainda disse que eu não sou bem vinda aqui? Agora eu vou me embebedar!!! hehehehehe.

Eu entendi, digo o que vc quis dizer... porém o post... não.

hehehe.

Anônimo disse...

cacilds, esse post é mto complexo pra mim!

o-menino-de-ouro disse...

É cara, agora entendi porque você critica tanto o caché/ensemble.