3/27/2010

Desarrollo rápido de aplicaciones de red: Apache Mina I - Primeros pasos

En mi primera entrada voy a empezar por algo sencillo pero que creo que puede servirle a alguien como una primera introducción a este framework ya que no hay demasiado en castellano por Internet sobre el tema. Una parte de mi PFC(Proyecto Fin de Carrera) consiste en el desarrollo de una pasarela que realiza una conversión entre protocolos distintos(ambos sobre TCP/IP), mi primera intención fue elegir C, por ser el lenguaje de programación que mejor conozco y el que utilizamos durante la carrera para las aplicaciones de este tipo. Debido a mi PFC es el objetivo de una beca de prácticas de trabajo en una empresa, por motivos corporativos, de entre las opciones que me ofrecieron me quedé con Java por haber desarrollado con anterioridad alguna aplicación web con el IDE Eclipse y el framework J2EE. Esto que en principio me pareció un pequeño problema resultó ser una ventaja porque aunque se necesite un tiempo de adaptación al nuevo entorno y unas cuantas horas de lectura y repaso de código, al final permite aprovechar las ventajas de la programación orientada a objetos para implementar una aplicación de red multipropósito teniendo solo que definir los protocolos involucrados y el comportamiento específico que se precise para el tipo de aplicación.

Las primeras pruebas que realicé fueron con las clases del framework JAVA.NIO (New Input Output) incluido en J2EE, recomiendo éste texto que introduce al lector al tiempo que se desarrolla una aplicación de chat típica por lo cual resulta bastante entretenido. Buscando un framework para el desarrollo de aplicaciones de red en Java(porque en Java hay frameworks para todo :) ) apareció Apache MINA(Multipurpose Infrastucture Networked Aplications) que es un proyecto de Apache que está aun madurando pero ya existen productos desarrollados con esta tecnología. Entre sus ventajas destaco las siguientes:
- Es multipropósito, como dije antes solo es preciso implementar el codec para los protocolos necesarios y el coportamiento específico de la aplicación(lógica de negocio)..
- Utiliza JAVA.NIO, el nuevo framework de Java con nuevas características y mejoras en rendimiento respecto a JAVA.IO.
- Gestiona eficientemente la respuesta a multiples peticiones simultáneas evitándole al programador la necesidad de gestionar de múltiples threads.
- Funciona sobre TCP o UDP.
- Diseñado especificamente para el fin, por ejemplo, los buffers de envío y recepción se expanden y se contraen solos(si queremos).
- Dirigido por eventos, solo hay que definir las acciones a llevar a cabo en funcion de los eventos(conexión creada, mensaje recibido ...) que se producen.
- Todas las ventajas de los lenguajes de programación orientados a objetos(reutilización, abstracción ... )


Vamos al tema, empezaremos por explicar los pasos necesarios para poner a andar todo esto ya que el framework es un proyecto de Apache Maven y quiero usar Eclipse para desarrollar. El primer paso es instalar el Maven, en mi Debian: apt-get install maven2 . En Windows los instaladores los encontramos con éstas instrucciones de instalación.


El siguiente paso es descargar el framework de MINA, en este caso elijo la versión 2.0.0-RC1 aunque es inestable porque hay bastantes cambios respecto a la 1 en algunas de las clases y en el fururo prodrían aparecer problemas de compatibilidad en la aplicación. A continuación se descomprime y se accede a la carpeta por consola ya que no hay plugins de Maven oficial para eclipse y los que probé no me acabaron de funcionar correctamente. Accedemos hasta la carpeta mina-example por ser los proyectos de ejemplo con los que vamos a realizar las pruebas: cd mina-2.0.0-RC1/src/mina-example/ y le decimos al Maven que cambie el proyecto al formato del Ecplise: mvn eclipse:eclipse





Tarda un rato en actualizar el propio Maven(si es preciso) y descargar las dependencias del proyecto. Cuando termina ya tenemos el proyecto en formato del Eclipse así que lo importamos (File/Import.../Existing Projects into Workspace y le damos a Next), en la siguiente pantalla elegimos la ruta del proyecto mina-examples y marcamos la opcion de copiarlo al espacio de trabajo:





Nos aparecerá el proyecto a la izquierda en el explorardor de proyectos y vemos que hay errores, falta definir la variable M2_REPO con la ruta del repositorio de Maven (donde están las dependencias que descargó antes) en la configuración del Eclipse: (Window/Preferences/Java/Classpath Variables/New...)
(Nota: En Linux la carpeta .m2 está en el home del usuario y en Windows la encontramos en Documents and Setting/Usuario en el XP y en Users/USUARIO en el Vista/7).





Se recomendará una recompilación y comprobamos que ahora sí encuentra las dependencias por lo que ya se puede ejecutar el primer ejemplo. Empezamos por el el ejemplo más sencillo, org.apache.mina.example.gettingstarted.timeserver es un servidor que lo único que hace cuando recibe cualquier petición es devolver la fecha y la hora del sistema. Ejecutamos la clase MinaTimeServer.java:





Para comprobar que funciona nos podemos conectar con telnet al puerto 9123(sale en el código fuente de la clase en la primera línea): telnet localhost 9123, lo que se muestra por consola son los logs de la aplicación, porque !MINA incorpora también la gestión de logs!.





Otro ejemplo con la aplicación reverser: telnet localhost 8080





Listo, ya tenemos MINA funcionando. En una próxima entrada intentaré resumir algunas nociones básicas para saber por donde empezar y no perdernos con tal cantidad de clases cuando todavía no escribimos una sola línea de código, pero eso sí, tenemos una implementación de una aplicación de red multipropósito con distintos ejemplos probados para poder experimentar y no empezar de 0, algunos incluso con sus correspondientes tests del JUnit (en el paquete src/test/java del proyecto). Asegurándonos además de que las clases que los componen, y por lo cual las que usaremos nosotros para nuestra aplicación, están diseñadas y probadas por los desarrolladores de Apache MINA con las ventajas que ello supone.



Jesús Pérez