miércoles, 8 de junio de 2011

¿Un Tomcat Transaccional?

Vamos a explicar como incorporar en Tomcat la capacidad de coordinar transacciones entre diferentes bases de datos, usando el API estándar JTA (Java Transaction API), que permite englobar en una misma transacción acciones con distintas bases de datos, coordinadas por un Transaction Manager que corre dentro de Tomcat. Para que una base de datos pueda participar en una transacción distribuida de este tipo, debe tener un driver JDBC capaz de soportar este tipo de tareas, y el manejador como tal también debe ser compatible con "XA Transactions".

Tomcat por defecto es un contenedor de servlets, no un servidor de aplicaciones completo JEE, por eso no cubre esta funcionalidad de un coordinador de transacciones. Un servidor de aplicaciones JEE si incorpora esta facilidad y muchas más que en general no son necesarias para desarrollar aplicaciones web eficientes. Nosotros preferimos partir de un servidor liviano y rápido como Tomcat y luego añadirle lo que realmente necesitamos del estándar JEE. Así lo hicimos con el caso de las transacciones JTA, integramos un producto muy fácil de usar, JOTM - Java Open Transaction Manager.

La integración es muy sencilla, pero nosotros la simplificamos aun más, consolidando en un solo JAR todo el subsistema de JOTM. Lo pueden descargar desde nuestro website, deben añadirlo a la carpeta "tomcat6/lib". En el context.xml de la aplicación donde se definen los pools de conexiones es donde vienen los cambios clave:

<Context>

<Resource name="jdbc/dinamica" auth="Container" type="javax.sql.DataSource"
factory="org.objectweb.jotm.datasource.DataSourceFactory"
initialSize="5" maxActive="20" maxIdle="5" maxWait="3000"
username="postgres" password="basica"
driverClassName="org.postgresql.Driver" url="jdbc:postgresql://localhost/demodb" />

<Transaction factory="org.objectweb.jotm.UserTransactionFactory" jotm.timeout="60"/>

</Context>

Como pueden ver lo único nuevo es el la incorporación del elemento "Transaction" y también el factory que se utiliza para el pool de conexiones, que es especial para el manejador de transacciones.

En el caso de Dinámica el uso del coordinador de transacciones es transparente, ya que se implementó como un filtro, por la vía de los "filter-mapping" se le indica que Actions debe englobar, y el Action o proceso server-side de Dinámica procederá a ejecutar su lógica de negocios sin preocuparse por el manejo de la transacción, incluso si se ejecuta la lógica contra varias bases de datos. El filtro coordina, garantiza un COMMIT si no hay error o un ROLLBACK que mantendrá la consistencia en todas las BD involucradas si hay error.


De esta manera, usando un producto compacto open source de fácil integración con Tomcat, y las bondades de una especificación de servlets tan bien pensada, se le añaden a Tomcat características empresariales sin complicarlo ni ponerlo más pesado.

Un abrazo,
El Team Dinámica

sábado, 4 de junio de 2011

Integrando JMS y Dinámica

Cuando estuve en Lima en julio del año pasado, durante una presentación en la SUNAT (el organismo recaudador de impuestos), alguien me preguntó como se hacía para interactuar con un servidor de colas de mensajería, yo le explique que bastaba con extender una clase base del framework para lógica de negocios y añadir el código para hacer las llamadas al API de mensajería estándar de Java JMS. No he tenido necesidad de usar JMS en ningún proyecto, pero se que en algunas telefónicas en Venezuela usaban fuertemente un producto de IBM para tal fin.

Luego en febrero de este año, durante un curso de Dinámica Deluxe en Caracas, me vuelven a hacer la misma pregunta... así que me pareció una señal: hay que integrar esto en Dinámica, aunque no lo usemos, de manera transparente al programador, siguiendo los principios del framework, para que se pueda usar de forma declarativa sin escribir ni una línea de código.

Los servicios de mensajería que ataca JMS se refieren específicamente a comunicación entre aplicaciones o componentes, y de forma asíncrona, no es como enviar email. Estos servicios están pensados para intercambiar data entre procesos, pero de forma desacoplada, a través de una cola de mensajes, donde uno envía y el otro recibe, sin estar conectados entre sí.

Para mayor información sobre JMS leer este tutorial.

De manera que procedimos a bajar el servidor de mensajería más simple que conseguimos: OpenJMS, nos gustó mucho para las pruebas por lo fácil que fue ponerlo a andar sin saber nada del tema, aunque el producto lamentablemente está descontinuado, pero disponible en open source sin embargo.

Extendimos el framework con una clase genérica, que al heredar de GenericTableManager puede ejecutar todo tipo de tareas de lógica de negocios contra una base de datos SQL sin necesidad de programar, pero además con una simple configuración adicional también puede enviar un mensaje a una cola en un servidor JMS:


El nuevo módulo o plugin quedó integrado de manera natural dentro de la arquitectura MVC de Dinámica, permitiendo su uso de forma declarativa:


Todos los parámetros de entrada que recibe un proceso server-side, una vez validados pueden ser inyectados automáticamente en la plantilla de texto del mensaje y luego enviado a la cola, justo después de haber ejecutado la lógica de negocios contra el servidor SQL.

Todo el asunto fue incorporado como un aporte para los suscriptores de Dinámica Deluxe, incluyendo un documento que registra de forma estructurada el conocimiento adquirido:


Bueno, con esto finalizamos nuestra aventura con las colas, por ahora. Sirvió también para demostrar la extensibilidad de Dinámica para incorporar APIs específicos dentro de la lógica de negocios, y si se le pone un poquito de inteligencia, puede ser un plugin genérico, configurable y reutilizable sin programar.

Saludos,
El Team Dinámica

jueves, 2 de junio de 2011

Un Tomcat diferente

El framework Dinámica incluye un Tomcat light, reempaquetado por nosotros para que sea fácil de usar en desarrollo y producción con Dinámica, y sea sobre todo rápido y seguro.

Para eso le sacamos todo el exceso de equipaje que suele incorporar, todas las aplicaciones de administración y los ejemplos, lo dejamos vacío, y también le desactivamos en el web.xml global lo que no vamos a utilizar: JSP entre otras cosas. También limpiamos el server.xml y le desactivamos lo que no necesitamos, básicamente solo dejamos el conector HTTP 1.1 con la compresión GZIP para las salidas de texto y la válvula de log HTTP, la cual es de uso opcional si lo quieren hacer aún más liviano. Le ponemos suficientes Threads de fábrica y la parte de SSL comentada pero lista para usar.

En Windows le dejamos la auto-recarga activada para facilitar el desarrollo, pero en la distro de Linux se la quitamos, porque esta generalmente se usa para producción, y se recomienda hacer lo mismo con la de Windows si la van a usar para producción. Para cubrir la falta de la auto-recarga proveemos un utility seguro que corre local al proceso Tomcat y permite recargar una webapp aunque la facilidad esté desactivada.

Luego vienen los complementos. Una vez que el Tomcat está liviano y seguro, hay que añadirle capacidades empresariales de uso muy frecuente: soporte para publicar web services usando el API estándar JAX-WS y JavaMail, además de los drivers JDBC open source para PostgreSQL 9 y SQLServer/Sybase. Todo en sus últimas versiones estables:

- Tomcat 7.0.53
- JAX-WS 2.2.8
- JavaMail 1.5.1
- postgresql-9.3-1100.jdbc4.jar
- jtds-1.3.1.jar

En resumen: tiene lo necesario para aplicaciones modernas de negocios web, incluyendo web services de alta velocidad, sin sobrecargar al servidor ni hacerlo complicado en su instalación o administración. No hay que olvidar que las webapps hechas con Dinámica incluyen una serie de facilidades para monitore y diagnóstico, así que no hay que añadirle nada de esto a Tomcat, basta con su instrumentación JMX en modo local (no hace falta activarla para acceso remoto, así es más seguro).

Todo esto va distribuido entre las carpetas "lib" y "endorsed" de Tomcat 7. Para correr este Tomcat se puede usar Java 6, Java 7 o Java 8 (recomendado).

Esta idea se parece al concepto de "Web Profile" de la última especificación Java EE, que define containers que no tienes que incluir todo el peso de JEE, en el caso Web permite incorporar solo algunas funcionalidades empresariales, aun así nos parece sobre cargada y deja por fuera JavaMail, que es muy necesario. Para mayor información sobre los profiles JEE:

Java EE: The web profile

Si le quieren añadir otras cosas, como un cliente JMS o soporte para transacciones distribuidas JTA, solo necesitan incorporar los JARs en la carpeta "lib" de Dinámica. Para el caso de transacciones JTA, quizá lo más fácil de integrar con Tomcat 7 es JOTM. Para pruebas con JMS lo más sencillo es OpenJMS. Los JARs que conforman la capa cliente de OpenJMS se pueden consolidar fácilmente en un solo JAR y añadir a Tomcat 7. En Dinámica existe soporte declarativo para enviar mensajes a una cola de forma transparente al programador, se ha probado con OpenJMS y ActiveMQ de Apache, solo requiere que Tomcat tenga los JARs cliente de JMS en su carpeta "lib".

En el caso de Linux, nuestra distro Tomcat es muy fácil de instalar, se descomprime un TGZ y se corre un script install.sh que deja Tomcat como servicio en Ubuntu.

Aunque la documentación de Dinámica que concierne a nuestra distro Tomcat y otras facilidades del framework está solo disponible para nuestros suscriptores, las distros como tal pueden ser descargadas del website del framework.

Nuestro objetivo ha sido proveer un servidor de aplicaciones web que cubra el 100% de nuestros requerimientos, y que sea rápido y confiable tanto en su estabilidad como en su seguridad. Nos gustó Tomcat desde la versión 6 porque se hizo más sencillo en su empaquetamiento y configuración, y adquirió madurez en su Core, suficiente como para competir con productos establecidos como Resin o WebLogic, que se han vuelto en contraste cada vez más complicados, y sigue siendo más simple de usar que las alternativas open source  como Glassfish o JBoss.

Saludos,
El Team Dinámica