web 2.0

jueves, 28 de julio de 2011

Desarrollando un agente de chat que informe el clima

En este tutorial desarrollaremos con App Engine un pequeño agente de chat que nos informe sobre el estado del tiempo actual de la ciudad que le indiquemos y lo hará utilizando la red XMPP tal como lo hace GTalk. Si no sabes que es App Engine o no has desarrollado anteriormente, es recomendable que leas este pequeño tutorial

Para obtener la información del estado del tiempo podemos utilizar cualquier servicio público como el de Yahoo, Msn, etc., en mi caso utilizaré Google Weather API.


Antes de iniciar...
Antes de iniciar, dejemos en claro el sencillo ejemplo que deseamos hacer. Si tienes algún servicio compatible con el protocolo XMPP como por ejemplo Gtalk (chat de Google), Pidgin, iChat, etc., agrega la siguiente cuenta a tus contactos,

clima-byte@appspot.com

Una vez agregada la cuenta, abre una ventana de chat con este contacto y escribe el nombre de la ciudad de la cual deseas obtener la información actual del estado del tiempo,



Como lo puedes ver en la imagen anterior, del otro lado hay un pequeño agente que te responde inmediatamente con el estado del tiempo actual de la ciudad que le especificas... Lo anterior es una sencilla aplicación que hace uso de un Servlet y del protocolo XMPP desde App Engine.

XMPP

El Extensible Messaging and Presence Protocol es un protocolo open source basado en XML para la transmisión/recepción de mensajes y es mejor conocido como XMPP (anteriormente llamado Jabber). La ventaja de utilizar el protocolo XMPP es que no se requiere de un servidor central, cada uno de nosotros puede ser un servidor y/o el cliente. Cada usuario de la red XMPP, tiene un identificar único conocido como JID (Jabber ID), dicho identificador es del tipo:


usuario@dominio.com


donde el @dominio es el nombre del dominio del servidor que proporciona este servicio. Google App Engine ofrece soporte para XMPP por lo que al momento de registrarnos para obtener una cuenta y crear una aplicación en App Engine, nuestro JID será:


id-aplicacion@appspot.com


El id-aplicación será aquel que indiquemos al momento de crear una aplicación en App Engine.


Para más información sobre el protocolo XMPP puedes consultar la wikipedia en español o ingles.


Google Weather API.

Se trata de un sencillo servicio que basta con invocar la siguiente URL y nos regresará la información del estado del tiempo en formato XML.


http://www.google.com/ig/api?weather=DF

Peguen la url anterior en un navegador y obtendrán un xml con la información actual y un pronostico del tiempo de los próximos días.


Dado que la información es regresada en formato XML, vamos a necesitar un pequeño y sencillo parser xml que haremos nosotros utilizando SAX.

Desarrollando el agente...

  • Creamos un Google Web Application Project (recuerda leer este tutorial en caso de no haber desarrollado antes con App Engine). Le podemos llamar AgenteTiempo.
  • Al crear el proyecto, se creará un Servlet y aquí será donde obtendremos un servicio XMPP para comunicarnos con algún JID, pero antes de ellos, vamos a desarrollar el pequeño parser.
  • Creamos una clase llamada EstadoTiempo con los siguientes atributos y sus respectivos setters y getters,
    • private String condition;
    • private String humidity;
    • private String temp_c;
    • private String temp_f;
    • private String wind_condition;
  • Creamos una clase llamada SaxEstadoTiempoHandler que extienda de la clase DefaultHandler. Puedes ver el código aquí. Podemos ver que sobre-escribimos el método startElement(...) y mediante el parámetro localName verificamos si se trata del elemento deseado. Como podemos ver en la siguiente imagen, nos interesan los elementos señalados en la región amarilla, condition, temp_f, temp_c, humidity y wind_condition, por lo cual en el código Java preguntamos por dichos elementos y obtenemos el valor de su atributo "data" desde el método resolveAttrib.

  • Ahora en el Servlet que se generó al crear el proyecto vamos a parsear el XML utilizando el handler creado anteriormente. Como podemos ver en la siguiente imagen, hemos creado un método privado y utilizado un objeto de la clase XMLReader pasandole como handler la clase SaxEstadoTiempoHandler. En el método parse de XMLReader le pasamos un objeto InputStreamReader que contiene un stream de bytes que representa el XML devuelto por la url del API de Google Weather.

  • Es importante indicar una codificación ISO ya que al pasarle a la url el atributo "hl=es" nos devolvera los resultados con acentos y nuestro programa podría arrojar una excepción. Una vez invocado el método parse del objeto XMLReader, construimos en un StringBuilder la respuesta que le devolveremos al usuario.
  • El cuerpo del mensaje que el contacto de chat envie a nuestro agente se realiza mediante un POST, por lo cual debemos utilizar el método doPost. Ver código fuente completo del Servlet.
  • Ya para finalizar, debemos agregar en el appengine-web.xml las siguientes etiquetas, tal y como lo describe la documentación de Google sobre el protocolo XMPP 

  • Además de esto, en el archivo web.xml debemos modificar el url-pattern de nuestro servlet y cambiarlo por:

/_ah/xmpp/message/chat/

Y listo!!!! Finalmente estamos listos para publicar nuestro proyecto en la nube de App Engine! Como lo mencione al inicio de este tutorial, puedes ver el resultado, agregando al contacto clima-byte@appspot a tus contactos de GTalk o de algún otro servicio que utilice la red XMPP como jabber.org o desde Pidgin.


Se te puede quedar como ejercicio que el agente también proporcione el pronóstico de los próximos días! O incluso hacer algo diferente! Por ejemplo un ejercicio que se conecte al DataStore de Google usando JDO donde se encuentren almacenadas las calificaciones de alumnos y el agente le muestre las calificaciones de todas las materias actuales al alumno, claro esta, mediante alguna clave para evitar que algún curioso vea información que no le corresponde.

Saludos!!

martes, 26 de julio de 2011

Leyendo archivos de texto desde Groovy

Hoy en el trabajo necesitaba obtener aquellos tiempos altos en funciones de Oracle que se llaman desde una aplicación web en Java. Dicha aplicación utiliza log4j y graba en el log el tiempo que tarda en ejecutar una función.

Por ejemplo, en dicho log podemos encontrar lineas como esta, siendo la marcada en amarillo la de especial interés,


De esta forma, requería estar leyendo muchos logs de más de 10000 lineas en busca de funciones cuyo tiempo sobrepasara los 2000 milisegundos.

La verdad es que no había utilizado antes Groovy y de momento se me ocurrió investigar en como podría hacer lo anterior, llegando a lo siguiente.

Como seguramente saben, Groovy es un lenguaje dinámico que corre sobre la JVM, por lo que es posible hacer uso de las mismas clases de Java.

Para leer un archivo basta con crear un objeto de la clase file e invocar al método eachLine que recibe un closure,

new File(name).eachLine( aqui closure )

Un closure es algo como un "método anonimo" y en Groovy se identifica por que esta encerrado entre signos de llaves {.......}


new File(name).eachLine(){line ->
            def i = line.indexOf("Time(spring)")

En el código anterior, abrimos el archivo de texto y ejecutamos el método eachLine para iterar por cada línea que contenga el archivo. El método eachLine al obtener una línea del archivo la "depositara" en la variable "line" que será de tipo String y entonces será como podremos posteriormente utilizar el método indexOf.

Para mejores ejemplos sobre un closure, consultar aqui

El código completo es el siguiente:


Una vez medio entendiendo los closures el código de arriba es fácil de digerir, aunque realmente como tal es casi mi primer pinino en Groovy pues la verdad no me he metido con él!

Saludos!!

sábado, 23 de julio de 2011

Introducción al Google App Engine

Con la tecnología de Google App Engine

Google App Engine es un servicio de alojamiento gratuito (1 GB de almacenamiento) de aplicaciones web escritas en Java, Phyton o el propio lenguaje de google llamado "Go". Mediante Google App Engine, google proporciona a los desarrolladores una infraestructura para instalar aplicaciones web en los lenguajes antes descritos.

En el caso de una aplicación web desarrollada en Java, es posible mediante el App Engine desplegarla en la infraestructura que google proporciona y acceder a ella mediante un dominio gratuito del tipo http://name.appspot.com

Google App Engine proporciona un soporte para el desarrollo de aplicaciones Java en sus versiones 5 o 6 y de API's y Frameworks tales como:


  • JavaServlet API 2.4
  • Java Server Pages
  • Java Server Faces 1.1-2.0
  • JPA y JDO
  • JavaMail
  • Groovy
  • BlazeDS
  • Spring MVC
  • Spring ORM
  • Struts 1.0 - 2.0
  • Tapestry
  • WebORB
  • etc...... más información
Para comenzar a utilizar App Engine, debemos crear una cuenta gratuita entrando al siguiente link , se nos pedira un número de celular a donde se nos enviara un código de confirmación, mismo que deberemos introducir. En el caso de México, el número de celular debe ser de la compañía Movistar (telcel, iusacell, etc., no funcionan), antes del número debemos introducir el código del país, por ejemplo, si fueras de México debes introducir algo como:

+52 xxxxxxxxxx

donde +52 es el código del país México.

Una vez creada la cuenta, mediante el Plugin de Google para Eclipse, podemos crear aplicaciones Java utilizando el SDK de App Engine, además de poder desarrollar aplicaciones utilizando el conocido GWT. Al instalar el plugin para eclipse, podemos también instalar el SDK de App Engine, por lo que no será necesario descargar el SDK y el Plugin por separado.




Ya instalado el plugin, podemos inmediatamente crear una aplicación utilizando App Engine y publicarla muy fácilmente. Para crear un proyecto, basta con seleccionar la opción indicada en la imagen.



En la Guia de Introducción a App Engine que ofrece Google en español, se desarrolla en primera instancia parte del siguiente código en un Servlet.





Al crear el servlet con eclipse y escribir el código anterior, es muy fácil probar la aplicación localmente. El SDK de App Engine, incluye un servidor local que simula todos los servicios que ofrece la infraestructura de App Engine, por lo cual podremos simular nuestra aplicación web localmente antes de instalarla en el servidor de Google.

Para ejecutar la aplicación anterior, basta con ir al menú Run > Debug As > Web Application , y entonces en el navegador teclear:

http://localhost:8080 ó http://localhost:8888

dependiendo del puerto que se inicialice.


Como página principal se muestran los Servlets disponibles, al dar click sobre "Guestbook" se ejecutará el código anterior, el cual presentará una pantalla que pedirá un correo como cuenta de Google para poder autenticar, dado que estamos en el ambiente local, se mostrará una pantalla como la siguiente, pero en caso de que la aplicación ya este publicada en nuestro dominio de App Engine, entonces se mostrará la pantalla de Google donde se pide nuestra cuenta:

Pantalla en servidor Local


Pantalla al instalar la aplicación en dominio de App Engine

Una vez que nos hemos autenticado, entonces se mostrará el mensaje que pusimos en el Servlet, que en este caso será algo como:


Hello, molder.itp
Para publicar la aplicación, primero debemos dirigirnos al archivo appengine-web.xml y en las etiquetas  escribir el id de la aplicación que es el mismo que escribimos al crear nuestra cuenta de App Engine, en mi caso fue "mundo-byte" tal como lo podemos ver en nuestra cuenta,



También debemos indicar el número de versión. Finalmente el archivo de configuración quedará similar al siguiente:



Hecho lo anterior, ya podemos publicar nuestra pequeña aplicación desde Eclipse dando click al ícono mostrado en la siguiente imagen:


Y listo!! el resultado lo podremos visualizar con la url de nuestro dominio, que en mi caso es la siguiente:


http://mundo-byte.appspot.com/guestbook
Hemos visto lo fácil que resulta publicar una aplicación web Java utilizando el AppEngine, sin duda una buena opción para varios desarrollos! Espero más adelante compartir más cosas acerca del App Engine de Google.


Saludos!!