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).

Instalar Tomcat en Linux

Instalar Tomcat en un servidor Linux es sencillo. Te vas a la página de descargas de Tomcat, eliges la versión que mejor te venga, la descargas y la descomprimes. Y ya está. Bueno te puedes crear un script de arranque y parada y colocarlo en /etc/init.d, pero en realidad no es necesario.

Simple, no? Pues no, no es tan simple. Hace tiempo que tenía pendiente la puesta en marcha de un servidor Tomcat que había instalado de la manera que acabo de indicar pero que en realidad no había llegado a probar. Esta tarde, cuando he ido a arrancar el servidor mi SO (un Debian sin escritorio) me ha sorprendido con un mensaje: Tomcat no puede iniciar porque no tiene definida la ruta a un JDK.

Lo primero que he hecho es comprobar que la variable de entorno JAVA_HOME estaba definida. Así era. Entonces, qué ha pasado? Tras un rato de busqueda he averiguado que que durante el inicio de Tomcat, éste busca en varios sitios del sistema predefinidos por alguna referencia a una ubicación válida del JDK, además de en el propio script de inicio. Así, pues, la solución es sencilla. O le dejamos que encuentra la ruta en uno de esos lugares predefidos, lo que podemos hacer creando un enlace simbólico a la ubicación del JDK…

ln -s /usr/lib/jvm/java-8-oracle /usr/lib/jvm/default-java

…o creamos la variable JAVA_HOME dentro de un archivo que el script de inicialización va a leer durante la misma y que es /etc/defaults/tomcat (si no existe, se debe crear). En él solo debemos añadir la ubicación del JDK

JAVA_HOME=/opt/java-oracle/jdk1.8.0_20

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.

Instalación de StarUML 5 en Linux

staruml_logo

StarUML es una herramienta de modelado UML fantástica que, por desgracia, sólo está disponible para Windows y MacOS. Hasta ahora siempre me he conformado con instalarla y ejecutarla en una máquina virtual con Windows, pero hoy, harto de iniciar la VM cada vez que necesitaba hacer uso de la aplicación, me he decidido por correrla en Linux con la inestimable ayuda de Wine. Estos son los pasos a seguir (gracias a José Antonio de La Neurona Absurda).

  1. Abrimos un terminal e instalamos Wine y otras dependencias:
    $ sudo apt-get install wine wine-gecko winetricks
  2. Ejecutamos Winetricks y aceptamos la instalacion de las herramientas que nos sugiera, básicamente Mono y Gecko.
    $ winetricks vcrun6
    $ winetricks msxml4
  3. Descargamos StarUML desde Sourceforge teniendo en cuenta que la opción de descarga ofrecida bajo el título «Estás buscando la última versión?» corresponde a los fuentes si accedes a la página desde Linux. Por tanto, buscamos y seleccionamos el archivo staruml-5.0-with-cm.exe, que contiene el instalador. Vale, es un instalador Windows, pero recuerda que vamos a ejecutarlo bajo Wine.
  4. Ahora sólo tenemos que ejecutar el instalador y seguir las instrucciones del asistente (no olvides marcar la casilla que crea un acceso directo en el escritorio).
    $ cd Descargas/
    $ wine staruml-5.0-with-cm.exe

Y eso es todo, a partir de ahora podrás ejecutar StarUML simplemente haciendo click en sobre el icono del escritorio (si es que seleccionaste esta opción durante la instalación) o buscándolo entre las aplicaciones de tu ordenador.

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.

Instalando OpenCV

OpenCV (Open source computer vision) fue diseñado bajo la premisa de la eficiencia computacional y enfocado a aplicaciones en tiempo real. Desarollado en C/C++, dispone de interfaces para C, C++, Java y Phyton y soporta Linux, Windows, MacOS, Android y iOS.

En este artículo nos centraremos en la instalación en plataformas Windows y Linux.

  • Windows. Aunque entre la documentación oficial de OpenCV podemos encontrar el procedimiento para efectuar la instalación en Windows, haremos un resúmen del mismo, que básicamente consiste en descargar el software ya compilado para la plataforma:
    • Abrir un navegador y acceder al repositorio del código en Sourceforge.
    • Seleccionar y descargar una versión.
    • Con un usuario con permisos de administrador sobre el equipo, ejecutar el archivo descargado, que basicamente efectuará una descompresión de archivos en la ruta que se elija. Los archivos obtenidos serán los binarios a utilizar.
    • Definir la variable de entorno de OpenCV y añadirla al path según se describe aquí.
  • Linux. La instalación bajo Linux es algo más complicada, principalmente porque sólo se dispone del código fuente de OpenCV y es necesario compilarlo una vez descargado. Si bien esto suele verse como una ventaja frente a la descarga e instalación de los binarios puesto que el resultado será un código ejecutable construido ad-hoc para cada máquina, también tiene ciertos inconvenientes y es que el proceso de construcción es más engorroso. Veámoslo:
      • Instalar los siguientes paquetes requeridos (puede hacerse a través de apt-get desde un Terminal o del gestor de paquetes):
        • GCC 4.4.x o posterior. Puede instalarse con:
          sudo apt-get install build-essential
        • CMake 2.6 o superior.
        • Git.
        • GTK+2.x o superior incluyendo las cabeceras (libgtk2.0-dev).
        • pkg-config.
        • Python 2.6 o superior y Numpy 1.5 o superior con paquetes de desarrollo (python-dev, python-numpy).
        • Java JDK. Nos aseguramos que la variable de entorno JAVA_HOME esté correctamente definida y añadida al PATH.
        • Apache Ant. Nos aseguramos que la variable de entorno ANT_HOME esté correctamente definida y añadida al PAHT.
        • ffmpeg o libav development packages: libavcodec-dev, libavformat-dev, libswscale-dev.
        • [opcional] libdc1394 2.x.
        • [opcional] libjpeg-dev, libpng-dev, libtiff-dev, libjasper-dev.
      • Abrir un terminal y acceder al directorio en el que queramos descargar el código fuente de OpenCV.
      • Ejecutar:
        git clone https://github.com/Itseez/opencv.git
      • Una vez completada la descarga, tendremos el directorio opencv con todo el código fuente.
      • Accedemos al directorio opencv y creamos el directorio donde queremos que se construya el código binario:
        mkdir build
        cd build
      • Construimos:
        cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D BUILD_SHARED_LIBS=0FF ..

    Si todo ha ido bien, debemos tener OpenCV instalado en nuestro equipo y listo. Para eliminarlo completamente, podemos efectuar un borrado desde un terminal:

    sudo find / -name "*opencv*" -exec rm -r {} \;
  • Usando OpenCV Java en Eclipse. El siguiente enlace ofrece información muy precisa y fiable sobre cómo configurar Eclipse y crear un proyecto Java que utilice las librerías OpenCV. No obstante, como es necesario disponer del archivo .jar que recoge todas las funciones de OpenCV, será necesario efectuar una compilación sin errores en el caso de sistemas Linux para llegar a obtener el citado archivo. En el caso de Windows, dado que la instalación consiste en la descarga del código ya compilado, no tendremos problemas al respecto.