Entender como funciona um ESB não é dificil. Todo ESB precisa dar suporte a três operações básicas: Receber mensagens de diversos canais de transporte (InBound), processar a mensagem recebida realizando uma ou mais operações de transformações e enriquecimentos (Internal Processing) e rotear a mensagem recebida e processada para diverentes tipos de canais de transporte (OutBound). Essa seria a síntese de qualquer implementação de ESB do mercado, e o que mudaria, seria como um dado ESB faria estes três passos.
Veremos neste post, como podemos trabalhar a parte de roteamento de mensagens para um banco de dadas SQL, ou seja, a realização de uma operação de OutBound da mensagem do barramento para um servidor de banco de dados compatível com ANSI/SQL. Para isso, iremos utilizar uma implementação customizada que criei para o JBoss ESB, que oferece recursos mais avançados do que as atuais estratégias do JBoss ESB, a saber, o NotifySQLTable da action Notifier, e os cartuchos de SQL do Smooks.
Qual os problemas das implementações atuais?
As implementações atuais do JBoss ESB para OutBound de mensagens para bancos SQL sofrem de algumas limitações de utilização e usabilidade. O NotifySQLTable por exemplo, possui diversas limitações técnicas como o fato de oferecer somente a operação de INSERT para o usuário, e o fato de oferecer somente a conexão via JDBC (DriverManager) e não a possibilidade de conexão via pools de conexão JDBC o que implica diretamente em diversas considerações de escalabilidade e robustez das soluções. Além disso, todas as informações que o componente manda para o banco de dados são estaticamente definidos no XML do JBoss ESB, tornando o seu uso pouco viável, uma vez que as informações que deverão ser enviadas para o banco de dados constarão no pipeline do serviço em tempo de execução.
O cartucho de SQL do Smooks em contra-partida resolve algumas das limitações do NotifySQLTable, como a de oferecer a possibilidade de conexão ao banco de dados via um pool de conexões JDBC. Porém ele ainda sim deixa a desejar em diversos pontos, como o de obrigar aos integradores de soluções a terem que escrever sentenças SQL baseadas em atributos dos beans transformados via Smooks, o que torna o desenvolvimento das soluções muito mais propenso a erros. Além disso, você deverá considerar que todos os dados que serão enviados ao banco de dados estarão no contexto do Smooks, ou seja, a sessão do Smooks para uma dada ação de transformação. Na maioria dos casos, os integradores de soluções desejam compor dados oriundos de enriquecimentos que se encontram dentro do pipeline da mensagem, fazendo com que o uso do cartucho do Smooks tenha como pré-condição o redesenho das mensagens que serão enviadas para o ESB. Não menos importante, existe a questão moral de se utilizar uma transformação Smooks só para ter o comportamento de OutBound para um banco SQL. Além de ferir o design da solução, isso torna seu uso muito mais complicado do que o simples e puro, uso de uma action do ESB.
SQLRouter: Solução "Simples Assim" para roteamento de mensagens
Um dos recursos mais poderosos e ao mesmo tempo simples do JBoss ESB são seus routers. Além dos routers de endereçamento (ContentBasedRouter, MessageFilter, MessagePersister) existem os routers que encaminham as mensagens do pipeline para algum canal de transporte específico, como o JMSRouter, o EmailRouter e o HTTPRouter. Trabalhando com o JBoss ESB por longos anos, sempre senti falta de um router que pegasse uma mensagem do ESB (ou fragmentos dela) e enviasse a um a tabela de um banco de dados SQL. Na maioria das vezes, tive que escrever uma action que fizesse isso para um cenário particular com pouco ou nenhum reuso da lógica de roteamento da mensagem.
Casos que justifiquem um router para SQL não faltam: De repente você precisa que o ESB sinalize uma aplicação via seu banco de dados, e esta sinalização pode ser a simples inserção de um registro, a atualização de um registro existente ou mesmo a remoção de um registro da tabela. Outro caso interessante é a de persistência de dados. Uma mensagem do ESB pode conter parte dos dados que precisa ser enviado a um Web Service .NET, outra parte precisa ser enviada a um endpoint FTP e outra parte precisa atualizar uma tabela de banco de dados, porém os três casos forma uma única operação atômica de persistência (uma transação) que precisa ser coordenada pelo pipeline de um serviço.
Para estes casos, eu criei um SQLRouter, que além de acomodar os cenários descritos acima, resolve, de forma bem simples e didática, as limitações das implementações atuais de OutBound SQL do JBoss ESB. Atualmente não tenho esta implementação em nenhum projeto open-source, mas assim que estiver eu posto aqui o link para download gratuito. Neste meio tempo, se você precisar deste roteador, mande uma mensagem para jricardoferreira (at) gmail.com que disponibilizo para você ;-)
Um primeiro exemplo usando o SQLRouter
Considere uma tabela de banco de dados para armazenamento de informações sobre clientes. A tabela deverá ter a seguinte estrutura:
Para fins de testes, crie esta tabela num banco de dados MySQL, PostgreSQL ou Firebird, Para inserir um registro nesta tabela através do JBoss ESB, você poderia simplesmente declarar a seguinte action no seu pipeline:
Repare que a action estabelece uma conexão com o banco de dados via JDBC, e com base nas informações declaradas na propriedade "columns", cria uma senteça SQL do tipo INSERT, conforme definido na propriedade "operation-type". Agora imagine que você precisa fazer a mesma operação, só que não quer conectar no banco de dados via JDBC puro, e sim, quer conectar usando um pool de conexões previamente configurado que deve ser acessado através do nome JNDI "java:/sqlRouterDemoDS". Você poderia configurar o SQLRouter da seguinte forma:
Outro recurso interessante deste SQLRouter é que o roteamento não deve ser somente uma operação de INSERT. Caso seja necessário, você pode criar as operações de UPDATE e DELETE apenas mudando a propriedade "operation-type". Opcionalmente também, você pode visualizar no log do JBoss ESB a instrução SQL gerada, habilitado a propriedade "show-sql" para "true".
Outro ponto importante do SQLRouter é que ele possibilidade que você escreva valores em colunas das tabelas oriundas da mensagem do pipeline. Nos exemplos anteriores, repare que sempre definimos estaticamente os valores a serem escritos nas colunas no arquivo de configuração do módulo ESB. Se quiséssemos recuperar estes valores da mensagem do pipeline, poderíamos fazê-lo da seguinte forma:
Repare que as colunas "PRIMEIRO_NOME" e "ULTIMO_NOME" terão seus valores escritos a partir dos objetos que estiverem na mensagem com os ID's "primeiroNomeParam" e "ultimoNomeParam" respectivamente. Para estabelecer estes valores, você pode gravar na mensagem usando a API de actions do JBoss ESB da seguinte forma:
Dependendo do tipo de valor que você configura na propriedade "operation-type" os valores das tags "column" serão usados de formas diferentes. Se você habilita por exemplo uma operação de INSERT, tudo que for declarado nas tags "column" serão usados para inserir valores nos campos de uma tabela. Por exemplo, usando a operação de INSERT, a seguinte instrução SQL será gerada:
Caso você precisa gerar um UPDATE numa tabela de banco de dados, altere a propriedade "operation-type" para "UPDATE" e para os campos que você deseja atualizar, habilite o atributo "update" nas colunas desejadas. As demais colunas que não forem sofrer atualização irão compor a cláusula WHERE da instrução SQL gerada. Caso nenhuma coluna "não update" seja definida, nenhuma cláusula WHERE será gerada. Eis um exemplo:
Para gerar um DELETE na tabela de banco de dados é mais simples ainda: Basta alterar a propriedade "operation-type" para "DELETE" e pronto. Caso você deseje filtrar a remoção gerando uma cláusula WHERE insira uma ou mais propriedades do tipo "column". Cada entrada de "column" se tornará uma condição da cláusula WHERE. Outro recurso interessante do SQLRouter para quando você deseja fazer um UPDATE ou DELETE, é que você pode estipular condições para a cláusula WHERE usando operadores SQL. O exemplo abaixo ativa todos os clientes que se chamarem "Ricardo" e que tenham CPF maior que zero:
Um exemplo do inicio ao fim usando SQLRouter
Agora que exploramos alguns dos detalhes por trás do SQLRouter, vamos ver como utilizá-lo num exemplo concreto. Para este exemplo, considere os seguintes componentes de software:
- MySQL Server 5.1
- JBoss ESB 4.7
- MySQL JDBC Driver
- Eclipse + JBoss Tools 3.1
- JDK 1.6+
A descrição completa do arquivo de configuração do módulo ESB encontra-se textualmente aqui. Já o arquivo de configuração do Smooks que transforma de XML para Java pode ser adquirido aqui. Para testar o exemplo, crie um arquivo XML no diretório especificado no arquivo de configuração como mostrado abaixo:
Você deverá também configurar um pool de conexões no JBoss ESB para que ele aponte para seu banco de dados de testes. Se você é um usuário de JBoss, isso não será um problema. Qualquer banco de dados pode ser usado para testes, uma vez que o SQLRouter fala com o banco de dados via JDBC puro.
Boas Integrações ;-)





