Configurar acceso WebSocket en Tomcat a través de Apache2

html5-websockets

Desde Tomcat 7, el contenedor de servlets proporciona soporte para WebSocket tal y como se define en RFC6455. En el sitio web de Tomcat 7 se describen algunos elementos específicos de configuración, pero básicamente no hay que modificar nada de la instalación básica para poder hacer uso de este protocolo de comunicación que, recordemos, permite al servidor iniciar el envío de información al cliente web sin que éste la haya solicitado, es decir, la respuesta del servidor no es el resultado de un request previo.

No obstante lo expuesto, existe una situación en la que el asunto se complica un poco y es cuando entre el cliente y Tomcat hay un servidor Apache2 que se encarga de gestionar todas las peticiones del primero y las respuestas del último. Para tratar este caso ya habremos añadido un archivo de configuración para el módulo que actúa como proxy (mod_proxy) de manera que se encargue de redireccionar todo el tráfico dirigido al servidor Apache pero que en realidad debe tratar Tomcat. Este archivo, ubicado en el directorio de sitios disponibles (y debidamente habilitado) será algo como:

/etc/apache2/sites-available/.conf


ProxyPass <aplicacion> ajp://<tomcat ip>:<ajp port>/<aplicacion>/
ProxyPassReverse <aplicacion> ajp://<tomcat ip>:<ajp port>/<aplicacion>/
<Location /<aplicacion>>
   Order allow,deny
   Allow from all
</Location>

Donde es el context path de nuestra aplicación, es la ip de la máquina donde se encuentra instalado Tomcat y es el puerto de escucha del protocolo ajp, tal y como lo tenemos definido en el archivo server.xml.

Pues bien, para dar soporte a WebSocket deberemos asegurarnos que nuestro servidor Apache2  corre al menos la versión 2.4.4, que es donde se introduce el módulo mod_proxy_wstunnel , según puede consultarse aquí. Después, debemos modificar el archivo de configuración anterior de manera que, además de redireccionar todas las peticiones dirigidas al protocolo ajp, haga lo propio con las dirigidas al protocolo ws (websocket). De esta forma, el archivo de configuración ahora quedará como:

/etc/apache2/sites-available/.conf


ProxyPass <aplicacion>/primepush ws://<tomcat ip>:<tomcat port>/<aplicacion>/primepush retry=0
ProxyPassReverse <aplicacion>/primepush ws://<tomcat ip>:<tomcat port>/<aplicacion>/primepush retry=0

ProxyPass <aplicacion> ajp://<tomcat ip>:<ajp port>/<aplicacion>/
ProxyPassReverse /<aplicacion> ajp://<tomcat ip>:<ajp port>/<aplicacion>/
<Location /<aplicacion>>
   Order allow,deny
   Allow from all
</Location>

En esta ocasión debemos tener en consideración el nuevo valor aportado como , que se corresponderá con el puerto de escucha de Tomcat según aparece en server.xml (tipicamente el 8080).

Webservice JAX-WS (desarrollo y producción)

De todos es sabido la cantidad de veces que se necesita probar el código que se está desarrollando para ver si va cumpliendo nuestras espectativas o no. Normalmente uso Netbeans como IDE de desarrollo, con el que puedo efectuar estas tareas de depuración sin demasiada complicacion, pero en el caso del desarrollo de servicios web me encuentro con una restricción, no del IDE, sino del contenedor de servlets que suelo usar: Tomcat. Me gusta Tomcat porque es fácil de instalar, de configurar y es relativamente poco pesado, pero no me deja probar los servicios web conforme los voy desarrollando. Como la alternativa (implementar una aplicación cliente que consuma esos servicios) no me atrae demasiado, no me queda otra que usar GlassFish.

El problema con GlassFish es que soporta nativamente las especificaciones JRS-109, con lo que te encuentras que todo te va de maravilla mientras estas desarrollando, pero empieza a fallar estripitosamente cuando intentas pasarlo a un Tomcat en producción, y es que Tomcat NO soporta esta especificación. Esto no es un problema si tienes la precaución de modificar las propiedades de tu proyecto para que haga uso de un Tomcat en vez de Glassfish justo antes de desplegarlo. Como digo, Netbeans es un buen entorno de desarrollo y como tal te advertirá que el servidor seleccionado no soporta nativamente la citada especificación. Si le autorizas, él solo generará un archivo xml de configuración extra (sun-jaxws.xml) y creará algunas entradas servlet en el archivo de configuración web.xml. Y listo, vuelves a construir el proyecto y lo despliegas en Tomcat.

Ojo, si vuelves seleccionar Glassfish como servidor, Netbeans volverá a avisar, pero esta vez para indicarte que la configuración que acabas de añadir ya está soportada por el servidor, así que la eliminará.

Es un poco molesto andar cambiando de servidor según vayas a desarrollar o desplegar, pero al menos no hay que crear otra aplicación.

Repositorio Subversion

Aunque la instalación de un servidor Subversion no es una tarea complicada en un sistema Linux, a menudo olvidamos los pasos que debemos seguir cada vez que creamos un nuevo repositorio. Esto es debido a que no es una tarea muy habitual. Si bien existen entornos de desarrollo integrados que a través de un escritorio permite la creación automática de repositorios (por ejemplo, el ofrecido por Clinker), cuando somos nosotros los que creamos el repositorio desde un terminal, hemos de seguir los siguientes pasos.

Logo Subversion

Partimos de que hemos ubicado nuestro repositorio de subversion (svn-repos) en /var. Es decir:

/var/svn-repos

Primero, creamos el contenedor para nuestro nuevo proyecto, al que llamaremos project_1

cd /var/svn-repos/
svnadmin create project_1

Como queremos acceder al repositorio a través de HTTP, hay que permitir que Apache pueda acceder a este nuevo repositorio. Lo más fácil es asignar al directorio recién creado el usuario y permisos que corresponde a Apache:

chown -R www-data:subversion /var/svn-repos/proyecto
chmod -R g+ws /var/svn-repos/proyecto

A continuación debemos habilitar y configurar WebDAV y SVN. Para ello, añadimos el siguiente código al archivo dav_svn.conf que ya existe en el directorio /etc/apache2/mods-available/:

sudo nano /etc/apache2/mods-available/dav_svn.conf

<Location /svn/project_1>
   DAV svn
   SVNPath /var/svn-repos/project_1

   Options FollowSymLinks
   order allow,deny
   allow from all
   AuthType Basic
   AuthName "Subversion Repository"
   AuthUserFile /etc/apache2/dav_svn.passwd
   Require valid-user
</Location>

Como vemos, acabamos de indicar que accederemos a nuestro proyecto a través del path /svn/project_1, con lo que la URL de acceso quedará como http://host/svn/project_1, donde host corresponde a la dirección IP o nombre.dominio de nuestro servidor. También hemos establecido la configuración de seguridad dejando que la misma descanse en el archivo de usuarios dav_svn.passwd (podríamos haber elegido otro nombre). Es decir, cada acceso al repositorio va a requerir de un usuario válido definido en este archivo. Con el siguiente comando insertaremos a un usuario (y su contraseña) en el archivo, el que se creará de no existir.

cd /etc/apache2/
htpasswd -cm dav_svn.passwd usuario

Y ya está. Sólamente hay que recodar hacer esto por cada proyecto que creemos.

Redimensionado de máquina virtual VBox

Supongo que a más de uno le ha pasado que al crear la máquina virtual en la que va a ejecutar un nuevo sistema operativo peca de optimista y asigna al disco duro de la misma un espacio que más tarde se comprueba que es insuficiente. ¿Qué podemos hacer en tal caso? Básicamente, tenemos dos opciones:

  1. Eliminar nuestra máquina virtual y crear una nueva, esta vez con más espacio en el disco, lo que supone bastante trabajo además de la pérdida de las aplicaciones que ya tuvieramos instaladas.
  2. Redimensionar el disco duro de la máquina existente. Obviamente, se trata de la mejor opción.
  • Hacer una copia de seguridad de la máquina virtual. La mejor forma es exportando la máquina completa, así, en caso de desastre, sólo tendremos que volver a importarla. Para eso, en el adminstrador de VBox vamos a Archivo>Exportar Servicio Virtualizado… y seguimos el asistente. Tanto para este proceso como para los siguientes, la máquina virtual debe estar detenida.
  • Usaremos el comando VBoxManager para proceder con la expansión del disco duro. Este comando sólo utiliza el formato de archivo .vdi, propio de VirtualBox. Sin embargo, éste también puede iniciar máquinas en formato de archivo .vmdk, que es propio de VMWare. Si este fuera el caso, primero es necesario convertir el archivo al formato apropiado con el siguiente comando:
    VBoxManage clonehd disk1.vmdk disk.vdi --format vdi

    Ejecutado desde el directorio donde se encuentra el archivo .vmdk. Disk1 es el nombre del archivo que contiene la máquina virtual. El clonado puede tardar un rato.

  • Con el archivo en formato vdi sólo nos queda redimensionarlo
    VBoxManage modifyhd disk.vdi --resize 60000

    Donde el nuevo tamaño viene expresado en megabytes.

  • Ahora debemos arrancar la máquina virtual teniendo en cuenta que si hemos convertido el archivo que la contiene de formato vmdkvdi, debemos reemplazar el archivo antiguo por el nuevo.
  • Pero todavía debemos realizar una acción más. Con la máquina iniciada debemos acceder al disco local que queramos redimensionar y expandir haciendo uso del espacio que acabamos de añadir. Este procedimiento variará en función del sistema operativo de virtual.