viernes, 22 de febrero de 2013

Devolver xml, json o html con RESTEasy

RESTEasy
En esta serie de artículos sobre los servicios web REST hemos visto hasta el momento como hacer un programa sencillo Hola Mundo con RESTEasy y como crear un cliente Java y Javascript de ese servicio web para consumirlo desde javascript en una aplicación web y desde un programa java usando la librería RESTEasy. En un servicio web REST podemos devolver datos en varios formatos, ya sea texto plano, html, json o xml, en esta entrada veremos como devolver datos en los dos últimos y que anotaciones usar para que las cabeceras devueltas en la petición sean las correctas, que ventajas nos puede aporta y que problemas nos puede resolver.

Antes unos pequeños apuntes de porque nos puede interesar devolver json o xml. Unos de los motivos es que a medida que las aplicaciones web están ganando en complejidad estas están tendiendo a delegar en el cliente la parte de visualización en vez de ser el servidor el que devuelva html formateado directamente. Además de evitar cierta carga de proceso en el servidor y delegarla en los clientes ofreciendo una interfaz REST de la apliccación permitimos que terceros desarrollen sus propias aplicaciones y se integren consumiendo los servicios que ofrecemos.

Una vez explicadas algunas ventajas, veamos el ejemplo de como devolver json o xml en el servicio REST, en el siguiente código el servicio HelloWorldResource devolverá los datos de un objeto a través de los métodos getMensajeJSON y getMensajeXML. Los métodos del servicio puede anotarse con @Produces indicando el formato de los datos que se devuelve, en la clase MediaType hay constantes para muchos formatos. Si el formato en el que devolvemos los datos no está definido en la clase MediaType podemos definir uno específico con @Produces("text/html"):

La anotación @Produces es muy importante en el servicio REST ya que los métodos getMensajeJSON y getMensajeXML tienen especificada la misma ruta de petición en la etiqueta @Path, ¿como sabe entonces el servicio REST en que formato se han devolver los datos si la URL solicitada es la misma para ambos casos? La respuesta es empleando la información enviada en las cabeceras del protocolo http, más concretamente empleando la cabecera Accept que en este protocolo indica en que formato quiere el cliente los datos. En muchas aplicaciones es habitual encontrarse en que se realizan peticiones al servidor especificando como Accept text/html y resulta que el servidor devuelve los datos en formato json, xml u otro, la aplicación funcionará bien pero lo hace empleando el protocolo http de forma incorrecta, esto no ocurre con los servicios REST que en función de lo que se solicita en la petición así es el formato de los datos devueltos. En la siguiente imagen pude verse la cabecera Accept de la petición enviada por el cliente javascript.


En el ejemplo se devuelve una clase POJO con varios atributos que usa las anotaciones @XmlRootElement, @XmlElement, @XmlAttribute para indicar los datos y la forma de los datos a generar como resultado:

Para el cliente java desde el punto de vista del que lo usa la comunicación con el servidor y el formato en el que se transmiten los mensajes es transparente.


En el cliente javascript si usamos el formato json nos será más cómodo tratarlo en el navegador: En las siguientes imágenes las peticiones que se realizan desde el navegador con el cliente javascript, en la columna type se puede ver el tipo de datos devuelto en las peticiones:


Para que el ejemplo funcione deberemos incluir las dependencias org.jboss.resteasy:resteasy-jaxb-provider:2.3.5.Final y org.jboss.resteasy:resteasy-jettison-provider:2.3.5.Final.

Para finalizar, comentar que la combinación de ofrecer en la aplicación una API REST junto con librerías como Backbone.js que proporcionan un Modelo-Vista-Controlador (MVC) en el navegador accediendo al servidor para consumir el servicio puede dar lugar a aplicaciones más flexibles y fáciles de desarrollar entre otras cosas. Y esa es la tendencia hacia la que están evolucionado las aplicaciones web a medida que el propio lenguaje javascript y los navegadores aumentan sus capacidades.

En el siguiente enlace puedes encontrar el código fuente completo de este ejemplo y probarlo tu mismo en un servidor de aplicaciones como Tomcat. La siguiente entrada será como integrar RESTEasy con un framework de desarrollo web como Apache Tapestry.

Referencia:
http://www.jboss.org/resteasy
http://backbonejs.org
Código fuente completo del ejemplo Hola Mundo con RESTEasy

sábado, 16 de febrero de 2013

Cliente javascript y java de servicio web REST con RESTEasy

RESTEasy
Una vez que hemos desarrollado un servicio web REST tendremos que obtener un cliente para consumirlo ya sea con javascript, Java u otro lenguaje. En cualquier caso los clientes son mucho más sencillos de obtener en RESTeasy que en los servicios web basados en mensajes SOAP y XML haciendo uso de otras librerías a partir de la definición contenida en el WSDL como vamos a ver. Además, de poder ser consumidos desde un navegador a través de javascript.

Para el cliente Java deberemos tener la interfaz de ese web service con los métodos ofrecidos en el servicio, con las anotaciones adecuadas y que deberemos implementar en una clase. La interfaz del ejemplo Ejemplo sencillo de web service con RESTEasy sería:

Y la implementación:

Una vez tengamos la interfaz del web service REST y su implementación podemos hacer un programa java que lo use como cliente:

Apartir de esa interfaz podemos obtener el cliente y un programa que lo invoca con el siguiente código. La parte importante está en el uso de las clases RegisterBuiltin y ProxyFactory:

Y eso es lo mínimo necesario para consumir los web services desde java ¿te pareció sencillo?, pues para consumirlos desde un navegador con javascript es aún más sencillo, veamos como. RESTEasy proporciona un servlet que genera un archivo js con los clientes javascript de nuestros servicios web REST, lo único que deberemos hacer es incluir ese servlet en el web.xml de nuestra aplicación web y usarlo en la página html en la que queramos hacer uso de él.

El servlet que generará el javscript, resteasy-jsapi, debe ser cargado después del servlet de RESTeasy por eso los valores de los load-on-startup en las etiquetas servlet, si no lo hiciéramos así obtendríamos la siguiente excepción de error:

En el archivo helloworld-resteasy.jsp está como es la llamada al web service desde el navegador, básicamente consiste en generar un html que incluya la etiqueta script haciendo referencia al javascript a obtener en el navegador, contendrá los clientes javascript de todos nuestros web services REST. Aunque en el uso de los clientes las peticiones que se producen a través de la red estas operaciones son totalmente transparentes para nosotros, en cada correspondiente cliente javascript tendremos disponibles unos métodos que se encargarán de realizar y de la forma adecuada las peticiones teniendo entre otras cosas en cuenta como enviar los parámetros de los métodos. Una cosa a tener en cuenta es que en la interfaz del web service REST no debemos usar sobrecarga, mismo nombre de método con diferentes parámetros, ya que de otra manera el cliente javascript no sabe distinguir a que método del Servicio web llamar.


Recursos que pide el cliente Javascript
El último paso que tendremos que aprender es como devolver otros tipos de datos más complejos como json, xml, html u otros.

Referencia:
REST
Ejemplo sencillo de servicio web con RESTEasy
Código fuente completo del ejemplo Hola Mundo con RESTEasy

sábado, 9 de febrero de 2013

Ejemplo sencillo de servicio web con RESTEasy

RESTEasy
Las arquitecturas orientadas a servicios (SOA) no son nuevas y existen desde hace ya bastante tiempo. Surgen por la necesidad de las aplicaciones de comunicarse entre ellas para intercambiar información y colaborar. Dada la heterogeneidad de las mismas aplicaciones en el lenguaje de programación o de representación de datos requieren un lenguaje común con el que intercambiar información, para ello se puede emplear un lenguaje de marcas como XML y para el intercambio de mensajes SOAP (Simple Object Access Protocol) sobre el protocolo HTTP. Otras opciones como CORBA los mensajes se transmitían de forma binaria. Pero los servicios web basados en XML y SOAP no están exentos de problemas, los mensajes SOAP son bastante complejos y para algunas necesidades no son fáciles de construir o cómodas de usar, por ejemplo desde un navegador o un dispositivo móvil empleando javascript.

Dado el auge u omnipresencia que están tomando los servicios basados en internet, la web, los navegadores y javasctipt muchos de los sitios más importantes están evolucionando hacia servicios REST por su simplicidad de ser consumidos y fácil acceso, muchos sitios ofrecen una API basada en REST para que terceros puedan integrase con ellos, este es el principio para poder construir mashups. Algunas de sus características son que emplean el protocolo HTTP y sus diferentes métodos (GET, POST, DELETE y PUT, etc.) asignando a cada uno de ellos una operación de las denominadas CRUD (create -> PUT/POST, retrieve -> GET, update -> PUT/POST, delete -> DELETE). Pueden devolver datos en cualquier formato pero normalmente se emplea JSON o XML. En el siguiente enlace, muy recomendable, sobre algunos conceptos sobre las APIs REST está muy bien explicado las ideas sobre las que se basan estos servicios.

Para hacer sevicios web basados en REST con Java disponemos de varios frameworks entre ellos Restlet o Jersey, sin embargo, me ha convencido el ofrecido por la comunidad de JBoss, RESTEasy, tiene una muy buena documentación que está bien explicada y con la que es muy fácil iniciarse. Por lo tanto a continuación voy a poner lo necesario para implementar el ejemplo Hola Mundo con RESTEasy en una aplicación web java que puede ser hospedada en cualquier servidor de aplicaciones como Tomcat o JBoss.

Con RESTEasy los servicios web son POJO (Plain Old Java Object) a los que se les añade la fucionalidad mendiante anotaciones. Veamos como de simple podría ser el típico ejemplo sencillo de web service Hola mundo como demostración.

Aquí vemos varias anotaciones @Path, @GET y @PathParam. Con la primera estamos indicando parte de la URL en la que el web service responderá, con la segunda indicamos que el método HTTP que llame a esa URL deberá ser get y con la tercera recogemos un parámetro indicado en la URL. La implementación sería:

Una vez que disponemos del web service deberemos añadir al archivo web.xml las cosas necesarias para que RESTEasy recoja las llamadas a las URLs de los servicios web y los invoque, entre ellas el servlet de nombre resteasy de la clase HttpServletDispatcher. El web.xml sería el siguiente:

Lo básico a añadir es el servlet de RESTEasy y el correspondiente servlet-mapping, también deberemos indicar el parámetro de contexto «resteasy.servlet.mapping.prefix» con el prefijo de la ruta del servlet-mapping del servlet de RESTEasy. Con esta configuración todas las URLs que lleguen a la aplicación web y con la ruta «/rest/» corresponderán a un web service REST, una cosa a destacar es que los servicios web pueden convivir con con el resto de la aplicación independientemente del framework que uticemos para desarrollarla, lo único que deberemos hacer es indicar un prefijo para el servlet de RESTEasy tal y como hemos hecho en el ejemplo.

Pero... ¿Como sabe RESTEasy cuales son los servicios web de la aplicación? La forma de indicarle a RESTEasy los servicios web es mediante una clase que extiende de javax.ws.rs.core.Application y utilizando el parámetro de inicialización javax.ws.rs.Application para el servlet de RESTEasy que se puede ver en el web.xml. La implementación no tiene más que un Set con las implementaciones de los servicios web, en el caso del ejemplo:

Para finalizar, comentar que RESTEasy se puede configurar también como un filtro, lo que tiene algunas ventajas como descubrir de forma dinámica los servicios web sin necesidad de la clase Application. El resultado del servicio web invocado desde un navegador web es:


Este es el primer artículo de unos que escribiré sobre RESTEasy, en el siguiente explicaré como crear un cliente javascript o java para consumir este servicio web y en el último hablaré de como devolver datos en formato JSON o XML desde el web service.

Referencia:
Código fuente Hola Mundo con RESTEasy
Conceptos sobre APIs REST
http://www.jboss.org/resteasy
http://stackoverflow.com/questions/4131968/resteasy-path-requiring-a-full-path

viernes, 1 de febrero de 2013

Reproductor de radios Jamendo con Python

Jamendo

Python
Si sigues este blog desde hace un tiempo sabrás que de vez en cuando comento alguna cosa relacionada aunque sea de forma indirecta con la Raspberry Pi ya que es el computador que uso para realizar las descargas via torrent y para reproducir música principalmente con cmus. Dado que la uso sin ningún entorno de interfaz gráfica sino simplemente conectándome via SSH desde mi portátil y trabajando a través de comandos desde la terminal casi todo lo que quiera hacer con ella lo tengo que hacer a través de la terminal.

Para escuchar música suelo hacerlo de varias maneras: escuchar mi propia música en mp3 con cmus, escuchar radios que emitan por internet vía streaming o también las radios de Jamendo a través del reproductor de su página web. Jamendo ofrece una API a través de la cual se pueden escuchar las radios. Esto es lo necesario para poder escuchar las radios de Jamendo desde la RPi utilizando la terminal. Como quería aprender algo de Pyhton y es uno de los objetivos RPi me puse manos a la obra a hacer un pequeño programa, aún no sabiendo nada de este lenguaje de programación, que me permitiese escuhar cualquiera de las radios de Jamendo via streaming.

El resultado lo podéis encontrar en mi repositorio de GitHub en un archivo que no llega a las 100 líneas de código Python. Básicamente utiliza la API Rest que ofrece Jamendo para los desarrolladores que devuelve la información en formato JSON. Permite listar las radios disponibles en Jamendo según el estilo de música y los identificativos que utilizaremos luego para indicar al programa la radio que queremos escuchar.

Para usar el programa necesitaremos tener Python instalado y dado el que reproduce la música realmente es el programa mpg123 necesitaremos instalar también su paquete.

Después de habernos descargado el programa y habiéndole dado permisos de ejecución con:


Podemos obtener un listado de las radios con su nombre e identificativo usando:


Una vez que sepamos la radio que queremos escuhar lo haríamos con, en caso de que fuese la radio Classical:


Este programa se puede usar en cualquier sitio que tenga esas dependencias aunque en un ordenador de escritorio o portátil no nos sea imprescindible como en el caso de la Raspberry Pi ya que en los primeros podremos usar el reproductor web de Jamendo. Aún así aquí está para quien le pueda resultar útil como a mi. El programa no capturará todas las condiciones de error que se puedan producir, tener en cuenta que está realizado por alguien que sabe programar, conoce el lenguaje y API de Java pero no de Python. En cualquier caso si alguien cree que puede ser mejorado solo tiene que comentarmelo, enviarme un parche, ... ;)

Referencia:
Guías de instalación Raspberry Pi y desempaquetado
4 formas de escuchar música a través de internet

viernes, 25 de enero de 2013

4 formas de escuchar música a través de internet

Si nos gusta la música probablemente tendremos una colección amplia de canciones de diferentes artistas y géneros, sin embargo, por muy amplia que sea tal vez en algún momento nos apetezca escuchar algo diferente a la música que tenemos o nos apetezca escuchar la música del momento a través de alguna radio que emita por internet via streaming.

Muchas radios ya emiten a través de internet y por tanto las podemos escuchar desde el ordenador siempre y cuando tengamos una conexión a internet. Si no queremos usar el applet flash que normalmente proporciona cada radio en su propia página web podemos usar VLC, Banshee o incluso desde la terminal o consola. Para esto último ello basta con que tengamos instalado el programa mpg123 y conozcamos la URL en la que emite la radio lo cual a veces no es sencillo ni viendo el código fuente de la página del reproductor del applet flash pero escuchar música o radios por internet disponemos de varias opciones más, estas son algunas de ellas:

VLC

El reproductor multimedia VLC además de reproducir vídeos, música en prácticamente todo formato conocido de medio puede reproducir música por internet de forma bastante sencilla para el usuario. Solo hay que ir a la opción Ver > Lista de reproducción en la opción Internet de la lista de reproducción disponemos de varias opciones en cuanto a música y radios:

  • Free Music Charts: aunque parece que esta opción ha dejado de actualizarse desde hace bastante tiempo.
  • Icecast Radio Directory: esta es una lista de radios que emiten por internet, hay un montón de radios que podemos escuchar solo deberemos encontrar una que nos guste. Algunas de las radios emiten la música que está pegando fuerte en el momento.
  • Jamendo Selections: Jamendo es una colección de música en la que la mayor parte de la misma esta con licencia creative-commons que nos permite además de escucharla también con el propio reproductor de Jamendo en su propia página web poder descarganos las canciones a nuestro ordenador en formato mp3. Con VLC podemos escuchar la música emitida en las radios de Jamendo, hay radios para varios estilos de música: Rock, Pop, Jazz, Dance, Hiphop+Rap, World+Reggae, Lounge+Ambient. También tenemos una lista de las 100 pistas más populares, además de cada estilo junto con las 100 y 20 pistas más populares de la semana.

Con VLC también podemos Escuchar radios a través de internet como la Radio Nacional de España.


Linea de comandos con mpg123

El programa mpg123 nos permite escuchar música desde la linea de comandos con un consumo ridículo de recursos y sin necesidad de un programa con una interfaz gráfica, lo que nos puede ser útil para la Raspberry Pi. Tan sólo deberemos conocer la URL en la que emite la radio. La mayoría de las radios del Icecast Radio Directory proporcionan un enlace M3U con la dirección de la radio y algunas radios de cada país como el caso de la radio nacional de España (RNE):


RNE 1
Radio Clásica
Radio 3
Radio 4
Radio 5 Todo Noticias
Radio Exterior
Lista de radios nacionales

Teniendo la dirección URL de la radio la reproducimos con:




cmus

cmus es un reproductor de música basado en la consola que además de permitirnos escuchar nuestra música local nos permite también escuchar las radios que emitan via streaming. Al igual que con mpg123 solo necesitaremos la URL en la que emite la radio. Una vez que tenemos la URL y cmus iniciado deberemos teclear lo siguiente para añadir la radio a nuestra colección de música en cmus:


La ventaja de cmus sobre mpg123 es que no hará falta que recordemos o obtengamos la URL cada vez que queremos reproducir una emisora ya que con los comandos anteriores, dentro de cmus quedarán añadidos a nuestra librería en el artista «Stream». En el siguiente enlace puedes encontrar un pequeño manual del uso básico de cmus.


Jamendo

Jamendo es una colección de música realizada por artistas no tan comerciales como la que solemos escuchar normalmente en las radios y que muchos artistas publican sus creaciones con una licencia creative-commons que nos permite incluso descargarla para un uso privado por lo que si estamos cansados de escuchar siempre lo mismo puede ser un viento de aire fresco para nuestros oídos además de poder descubrir nuevos grupos. La música la podemos escuchar desde la propia página de Jamendo con el reproductor integrado en su web con el navegador. Podemos escuchar cualquiera de las radios con diferentes estilos de música o utilizar el buscador para seleccionar algún estilo de música más específico.

Si quieres escuchar las radios de Jamendo desde la terminal o desde la Raspberry Pi puedes hacerlo utilizando este reproductor programado en Python.



En definitiva 4 formas diferentes de poder variar lo que solemos escuchar.

Referencia:
Escuchar radios a través de internet con VLC

viernes, 11 de enero de 2013

Autenticación SSH con clave privada y pública

OpenSSH
Siguiendo el artículo de la semana pasada sobre como hacer que los programas no se terminasen al finalizar o perderse la conexión SSH en esta entrada explicaré como conectarnos a un una máquina de forma remota mediante SSH con una clave pública y privada en vez de con la contraseña del usuario.

Normalmente mediante contraseña nos conectamos a la máquina remota mediante el siguiente comando:

Esto nos pedirá la contraseña del usuario con el que trabajaremos en la máquina remota, en este caso la contraseña del usuario raspberrypi, y la deberemos introducir cada vez que realicemos la conexión. Si nos conectamos varias veces, realizamos conexiones a diferentes máquinas o nos conectamos con diferentes usuarios más pronto que tarde nos cansaremos de introducir la contraseña constantemente además de tener que estar recordando cada una de ellas si trabajamos con diferentes usuarios y asignamos a cada uno de ellos una diferente.

Todo esto se puede solucionar usando una clave privada y otra pública SSH con las que no necesitaremos proporcionar ninguna contraseña ya que será la clave privada la que nos autenticará. No necesitaremos proporcionar ninguna contraseña siempre y cuando no protejamos la clave privada mendiante una contraseña para poder usarla.

El par de claves SSH se generan con, se pueden utilizar otros algoritmos como RSA y DSA aunque ECDSA es el recomendado por OpenSSH por ofrecer la misma seguridad con un menor tamaño en bits para las claves. Sin embargo, en el ejemplo usaré RSA por el siguiente bug de GNOME:



Al final del proceso veremos la huella digital de la clave, si en algún otro momento deseasemos ver la huella alfanumérica o visual podríamos hacerlo con:


Una vez que disponemos del par de claves deberemos subir la clave pública a la máquina que posteriormente nos conectaremos identificandonos con la clave privada. Lo hacemos con:


Esta clave pública quedará como autorizada para la máquina y usuario indicados y será añadida al archivo ~/.ssh/authorized_keys en la máquina destino. Si posteriormente quisieramos desautorizar alguna clave solo deberemos borrar la linea de la clave de ese archivo. Posteriormente deberemos indicar en la máquina origen las identidades que queremos que proporcione el comando SSH cuando nos conectemos a alguna máquina con:


Si no hemos protegido la clave privada con ninguna clave la identidad quedará añadida con el comando SSH posterior, si hemos protegido la clave privada deberemos introducir la contraseña para poder añadir la identidad.

Finalmente, nos conectaremos a la máquina con el comando SSH y accederemos a la máquina destino sin tener que proporcionar ninguna clave:


Referencia:
https://wiki.archlinux.org/index.php/Secure_Shell#Client
https://wiki.archlinux.org/index.php/SSH_Keys
Guía instalación Raspberry Pi con Arch Linux ARM (Parte I, instalación base)
Guía instalación Raspberry Pi con Arch Linux ARM (Parte II, programas)

viernes, 4 de enero de 2013

Dejar procesos vivos de conexión SSH con screen

OpenSSH
GNU/Linux
El software libre y Linux es sorprendente, a veces nos surge una necesidad que no sabemos como resolver pero en el mundo del software es muy probable que el mismo problema se lo haya encontrado otra persona antes así que lo primero es buscar en internet, foros y ver cuales son las respuestas que obtiene esa persona que pregunta con el mismo o un problema parecido al nuestro para ver si alguien ha dado con la solución. Dependiendo del problema quizá descubramos un programa específico para resolver el problema.

Este es el caso que me ha surgido recientemente con la Raspberry Pi. Lo explico, a la RPi me conecto por SSH y dado que si se cierra esa conexión SSH se terminan todos los procesos lanzados en esa conexión SSH tengo que tener encendido el ordenador y la conexión SSH abierta hasta que termine de hacer lo que estaba haciendo. En la mayoría de los casos esto no es un problema pero para dejar la RPi reproduciendo música con cmus sí lo es ya que si se cierra la conexión SSH se termina el reproductor y se deja de escuchar la música, con lo que no puedo apagar el ordenador y dejar únicamente la RPi encendida que para reproducir música es mucho mejor que un ordenador porque no hay ruido de ventiladores y discos girando y la música se escucha más limpia sin ruidos adicionales por muy bajos que sean.

Screen, es una herramienta que nos resolverá ese problema además de proporcionarnos alguna funcionalidad adicional interesante. Con esta herramienta podemos dejar una terminal viva y sus procesos ejecutándose aunque se cierre la conexión SSH. Su uso es conectarnos mediante SSH de forma normal, ejecutar:

...que lanzará una segunda terminal en la sesión SSH y cuando queramos dejar la terminal de screen viva ejecutar CTRL+A y a continuación CTRL+D y ya podremos cerrar la terminal SSH original con exit, la terminal de screen y los procesos se seguirán ejecutando. Otra característica de screen es que podemos reconectarnos más tarde a la terminal de screen que dajamos viva, para ello nos volvemos a conectar mediante SSH y ejecutamos:

por si este fuera poco el volvernos a reconectar a la terminal de screen más tarde lo podemos hacer desde cualquier ordenador, no tiene por que ser el mismo ordenador desde el que iniciamos la terminal de screen, con lo que podemos iniciar los procesos en un ordenador, desplazarnos de sitio y continuar en otro. Lo que en algunos otros casos puede ser muy útil.

El paquete para instalarlo en Arch Linux es screen y lo hacemos con:

Referencia:
http://raspi.tv/tag/how-to-detach-a-process-on-ssh-without-killing-it
https://wiki.archlinux.org/index.php/GNU_Screen
Autenticación SSH con clave privada y pública
Guía instalación Raspberry Pi con Arch Linux ARM (Parte I, instalación base)
Guía instalación Raspberry Pi con Arch Linux ARM (Parte II, programas)