2. Administración de recursos en WildFly

En esta sesión vamos a centrarnos en la configuración básica de una instancia de WildFly. Aunque hemos hablado de modalidades de trabajo en Dominio, vamos a centrarnos en los modos standalone por sencillez y porque no nos limitan el acceso a características de alta disponibilidad como en otros servidores.

2.1. Fichero de configuración del Bootstrap

Hay una cuestión básica que es definir cuanta memoria puede utilizar la aplicación. La forma de definir el tamaño del Heap en Wildfly es bien especificarlo como parámetro del script de arranque, o lo que es más facil, editar el fichero standalone.conf

	$JBOSS_HOME/bin/standalone.conf

	JAVA_OPTS="-XX:MaxPermSize=256m -Xms64m -Xmx512m"
JDK 8
En la máquina virtual de la versión 8 desaparece el espacio de memoria denominado Permanent Generation y en su lugar se define uno nuevo denominado Metaspace. La forma de limitarlo es muy similar:
	$JBOSS_HOME/bin/standalone.conf

	JAVA_OPTS="-XX:MaxMetaspaceSize=256m -Xms64m -Xmx512m"

En este fichero también podemos especificar una JVM de Java concreta, así como otras propiedades como por ejemplo el número de descriptores de ficheros que podrá utilizar WildFly

2.2. Estructura de los ficheros de configuración

En la sesión anterior comentamos que las herramientas de administración modificación una configuración que físicamente se almacena en ficheros XML. Para cada modo de inicio (Standalone o Domain Managed) existen diferentes configuraciones de inicio, en el caso de operar como servidor independiente. Estos ficheros se encuentran dentro de la carpeta correspondiente a la modalidad (domain o standalone).

  • standalone.xml Configuración por defecto, sin soporte JMS.

  • standalone-full.xml Añade soporte JMS (HornetQ).

  • standalone-ha.xml Soporte Clustering.

  • standalone-full-ha.xml Soporte Clustering y JMS.

Se puede especificar un fichero de configuración específico, distinto de la configuración por defecto con el parámetro "-c"

./standalone.sh -c standalone-full.xml

Los ficheros de configuración presentan la siguiente estructura:

EstructuraCfg

El elemento raíz es la etiqueta <server> y de ella cuelgan los siguientes elementos:

Profiles

Los perfiles son configuraciones de servidor y sus distintos subsistemas. En la modalidad standalone, Wildfly sólo permite un perfil por fichero de configuración, sin embargo en el modo domain, es posible definir varios perfiles para distintos tipos de servidores dentro de un dominio. Ejemplo:

<profile>
  ...
  <subsystem xmlns="urn:jboss:domain:deployment-scanner:2.0">
            <deployment-scanner path="deployments" relative-to="jboss.server.base.dir" scan-interval="5000"/>
        </subsystem>
  ...
</profile>
Extensions

La mayor parte de las funcionalidades de WildFly se configuran como extensiones, que implementan especificaciones de Java EE.

<extensions>
    [...]
    <extension module="org.jboss.as.transactions"/>
    <extension module="org.jboss.as.web" />
    <extension module="org.jboss.as.webservices" />
    <extension module="org.jboss.as.weld" />
</extensions>
Paths

Los paths son rutas a directorios o ficheros de la máquina a las que se les asocia un nombre lógico. Los paths pueden ser rutas absolutas o relativas a otro path, de modo que la configuración sea portable a otras máquinas:

<path name="log.dir" path="/home/wildfly/logs" />  <!-- Ruta absoluta -->

<file relative-to="log.dir" path="server.log"/>    <!-- Ruta relativa a log.dir -->
Interfaces

Una interfaz es un nombre lógico asociado a un nombre de máquina/dirección IP a través de la cual podemos acceder a nuestro servidor. Por defecto se definen tres interfaces:

  • management La dirección que se utilizará para atender peticiones de administración.

  • public Esta es la dirección de servicio que atenderá el acceso a las aplicaciones.

  • unsecure Esta es la dirección que se utilizará para la invocación de objetos remotos IIOP.

<interface name="management">
    <inet-address value="${jboss.bind.address.management:127.0.0.1}"/>
</interface>
<interface name="public">
    <inet-address value="${jboss.bind.address:127.0.0.1}"/>
</interface>
<interface name="unsecure">
    <inet-address value="${jboss.bind.address.unsecure:127.0.0.1}"/>
</interface>

Por defecto estas interfaces están vinculadas a propiedades del sistema, que se pueden incluso sobrescribir en el inicio del servidor:

./standalone.sh -Djboss.bind.address=192.168.1.100
Socket binding groups

Un socket binding es básicamente la definición de un punto de escucha y se compone de la interfaz y del puerto de red concreto que se va a utilizar.

<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
    <socket-binding name="management-http" interface="management" port="${jboss.management.http.port:9990}"/>
    <socket-binding name="management-https" interface="management" port="${jboss.management.https.port:9993}"/>
    <socket-binding name="ajp" port="${jboss.ajp.port:8009}"/>
    <socket-binding name="http" port="${jboss.http.port:8080}"/>
    <socket-binding name="https" port="${jboss.https.port:8443}"/>
<socket-binding-group/>

El parámetro port-offset se utiliza para desplegar en una misma máquina distintas instancias de un servidor y asignar a cada una de ellas puertos distintos. El valor del offset se suma a todos los puertos especificados. Una buena práctica es establecer el valor de offset como propiedad del sistema en el inicio, en lugar de indicarlo de forma estática en la configuración.

System properties

Estas propiedades de configuración del servidor, se pueden establecer de varias formas:

  • En el fichero de configuración

<system-properties>
  <property-name="propiedad" value="true" />
</system-properties>
  • En el script de arranque del servidor standalone.sh o domain.sh.

  • Por línea de comandos, con elparámetro -D

./standalone.sh -Dpropiedad=true

2.3. Edición desde las herramientas de administración

Como ya hemos comentado, la forma más segura de modificar la configuración, es a través de las herramientas de configuración. Uno de los beneficios que reporta utilizar las herramientas es que WildFly crea automáticamente copias de seguridad de la configuración, por si nos equivocamos en algún cambio.

revisiones

Sin embargo, en el caso concreto de JBoss, la edición de ficheros de configuración ha sido tradicionalmente la forma más efectiva de administración. Gracias a JBoss AS 7 y WildFly, las herramientas de administración comienzan a acercarse al nivel de otros productos.

Descriptores de despliegue
Además de editar los ficheros de configuración del servidor, es posible codificar la mayor parte de los recursos en ficheros denominados descriptores de despliegue. Los descriptores de despliegue de WildFly complementan a los descriptores estándar de Java EE y permiten utilizar todas las características del servidor. Más información en: https://docs.jboss.org/author/display/WFLY8/Deployment+Descriptors+used+In+WildFly

La consola Web es una aplicación ligera que genera de forma automática vistas sobre la estructura de los ficheros de configuración, con lo que si conocemos la estructura del fichero, la representación Web nos resultará familiar:

ConfigConsola

Cuando modifiquemos algunas propiedades que requieran recargar la configuración, la aplicación nos avisará:

Avisos

La recarga de la configuración la podemos realizar desde la pestaña Runtime, opción Server.

Desde CLI, los cambios se pueden realizar más rápidamente, gracias a la forma de navegar y la ayuda para autocompletar rutas:

ConfigTexto

Después de realizar cambios en la configuración, ésta se puede recargar mediante el comando reload o bien parando y arrancando de nuevo el servidor.

2.4. Configuración de recursos

La función más importante de un servidor de aplicaciones es la de proporcionar los recursos necesarios para que las aplicaciones puedan funcionar. A continuación repasaremos cómo configurar los recursos más habituales.

2.4.1. Configuración de Datasources

Para que las aplicaciones puedan tener acceso a base de datos previamente hay que definir un Datasource y un Pool de conexiones. El Pool de conexiones optimiza el acceso a base de datos creando un conjunto de conexiones antes de que las aplicaciones las lleguen a necesitar. El servidor de aplicaciones asigna estas conexiones dinámicamente a las aplicaciones y en cada asignación nos ahorramos el tiempo de conexión/desconexión a la base de datos.

Las propiedades más importantes que definen el comportamiento de un Pool de conexiones en Wildfly son:

Min Pool Size

El número mínimo de conexiones creadas que puede tener un pool.

Max Pool Size

El número maximo de conexiones creadas que puede tener un pool.

Strict Minimum

Si se activa, impide que el número de conexiones pueda bajar más allá del mínimo definido (por ejemplo si las sesiones se liberan por timeout).

Prefill Enabled

Si se activa, al iniciar un pool de conexiones se crean automáticamente el numero de conexiones indicado como mínimo.

Flush Strategy

Especifica el modo en el que se liberan las conexiones de un pool ante un error.

Idle Timeout

Especifica el tiempo en minutos que se puede mantener una conexión sin uso, antes de ser liberada.

Para poder crear una conexión a base de datos en primer lugar hay que instalar el driver jdbc correspondiente. Esto se puede hacer de dos formas:

Instalación del driver como módulo
  1. Crear una estructura de directorio dentro de JBOSS_HOME/modules. En el caso de MySQL debemos crear:

    	JBOSS_HOME/modules/system/layers/base/com/mysql/driver/main
  2. Copiar el Jar dentro de la carpeta main

  3. Crear un descriptor module.xml dentro de la carpeta main:

    <module xmlns="urn:jboss:module:1.3" name="com.mysql.driver">
     <resources>
      <resource-root path="mysql-connector-java-5.1.33.jar" />
     </resources>
     <dependencies>
      <module name="javax.api"/>
      <module name="javax.transaction.api"/>
     </dependencies>
    </module>
  4. Declarar el driver en el fichero standalone.xml. Añadir al subsistema datasources el nuevo driver

<driver name="mysql" module="com.mysql.driver">
	<driver-class>com.mysql.jdbc.Driver</driver-class>
</driver>
Instalación del driver como despliegue

Si no tenemos permisos de administración, podemos simplemente copiar el fichero .jar con el driver de MySQL a la carpeta deployments del servidor. Al iniciar WildFly debemos revisar el nombre exacto del driver con el que se publica por si lo necesitamos referenciar en la creación de un datasource.

Descarga del driver

NOTE: El jar lo podéis descargar desde la página de MySQL o bien desde aquí: http://central.maven.org/maven2/mysql/mysql-connector-java/5.1.33/mysql-connector-java-5.1.33.jar

2.4.2. Creación del Datasource y los pool

Nuevamente tenemos varias formas de configurar un Datasource, a continuación veremos los pasos para configurarlo desde la consola Web:

  1. Definir el nombre del pool y el nombre JNDI del Datasource

    ds1
  2. Seleccionar un driver de los instalados en el servidor:

    ds2
  3. Configurar la cadena de conexión y el usuario/password.

    ds3
  4. Activar el nuevo pool

    ds4
¿Se puede desplegar un Datasource como un Deployment?
Si, se puede crear un fichero *-ds.xml con la configuración de uno o mas datasources. El fichero tiene la misma estructura que la del subsistema datasources del fichero standalone.xml y se puede copiar directamente a la carpeta deployments, o bien empaquetar dentro de una aplicación. Esta forma de crear datasources es recomendable en entornos de desarrollo, si bien, desde la consola web no es posible administrar este tipo de datasources.
<?xml version="1.0" encoding="UTF-8"?>
<datasources>
	<datasource jta="false" jndi-name="java:jboss/datasources/portalDS" pool-name="portalDS" enabled="true" use-ccm="false">
            <connection-url>jdbc:mysql://localhost:3306/experto</connection-url>
            <driver-class>com.mysql.jdbc.Driver</driver-class>
            <driver>mysql</driver>
            <security>
                <user-name>root</user-name>
                <password>expertojavajs</password>
            </security>
            <validation>
                <validate-on-match>false</validate-on-match>
                <background-validation>false</background-validation>
            </validation>
            <statement>
                <share-prepared-statements>false</share-prepared-statements>
            </statement>
        </datasource>
</datasources>
Empaquetar Datasources en la aplicación:

Como hemos comentado el Datasource puede incluirse en las propias aplicaciones. Eso sí, la ubicación del fichero varía en función del tipo de aplicación:

Tipo Aplicación Ubicación

Web App (.war)

WEB-INF

EJB (.jar)

META-INF

Enterprise (.ear)

META-INF (empaquetado principal)

Encriptación del password

WildFly tiene la particularidad de trabajar con passwords en plano en lo que respecta a Datasources. Si la configuración está centralizada en el fichero standalone.xml puede no ser un problema si está protegido para que no sea accesible. Sin embargo si adjuntamos un datasource a una aplicación, o lo copiamos en la carpeta deployments puede ser muy sencillo el averiguar el usuario y la clave de la base de datos. La forma de evitar esto es trabajar con claves encriptadas.

Los pasos son los siguientes:

Encriptar la password de la base de datos mediante la librería PicketBox
expertojavajs@expertojavajs-VirtualBox:/usr/local/wildfly-8.2.1.Final/modules/system/layers/base/org/picketbox/main$ java -classpath picketbox-4.0.21.Final.jar org.picketbox.datasource.security.SecureIdentityLoginModule expertojavajs
Encoded password: -46cea3eadea6ff81c9c59e773c1cfb95
Definir un security-domain asociado a las credenciales, editando el fichero standalone.xml:

Para ello debemos definir un security domain en el servidor, editando el fichero standalone.xml y añadiendo la siguiente información dentro del subsistema urn:jboss:domain:security:

<security-domain name="ds-encrypted" cache-type="default">
            <authentication>
                <login-module code="org.picketbox.datasource.security.SecureIdentityLoginModule"
			flag="required">
                  <module-option name="username" value="root"/>
		  <module-option name="password" value="-46cea3eadea6ff81c9c59e773c1cfb95"/>
                <module-option name="managedConnectionFactoryName"
			value="jboss.jca:service=LocalTxCM,name=portalDS"/>
            </login-module>
            </authentication>
        </security-domain>
Sustituir la información de usuario/password del datasource por la referencia al security domain :
<security>
	<security-domain>ds-encrypted</security-domain>
</security>

2.4.3. Configuración del contenedor de EJB’s

Los EJB son componentes que implementan principalmente la lógica de negocio de una aplicación Java EE y el servidor de aplicaciones proporciona mecanismos para maximizar la capacidad de proceso de estos componentes.

Los EJB’s se dividen en tres tipos:

Stateless Session Beans

Son objetos que implementan funciones de negocio pero no tienen un estado (valores en memoria).

Stateful Session Beans

Son objetos que implementan funciones de negocio pero además tienen un estado, que se conserva durante la vida de la sesión.

Message Driven Beans

Son objetos especializados en el proceso asíncrono de mensajes.

Los Session Beans se pueden instanciar desde cualquier componente de nuestra aplicación que se encuentre en el servidor (servlets, otros EJb’s, etc.) pero también se pueden ejecutar desde procesos externos al servidor, mediante el protocolo Remoting (basado en RMI). Los objetos MDB son componentes especializados que sólo se ejecutan en respuesta a mensajes enviados asíncronamente a través de lo que se denomina tópico o cola de mensajes.

Pool de EJB’s

Los EJB’s son esencialmente POJO’s a los que se les añade anotaciones específicas para integrarlos dentro del ciclo de vida del contenedor de EJB’s. Así los objetos EJB se crean y se destruyen en función de la carga de trabajo. Al igual que ocurre con las conexiones a base de datos podemos definir el número de instancias de estos objetos de modo que podamos controlar los recursos destinados a ejecutar esta lógica de negocio. Esto es muy útil en momentos de picos de carga en los que un número excesivo de EJB’s en ejecución pueden degradar notablemente el rendimiento global del servidor.

Este mecanismo es factible para los objetos que no tienen estado, como los Stateless Session Bean y los Message Driven Beans, pero los stateful son objetos equiparables a la sesión HTTP: contienen información de trabajo que no se puede copiar de una sesión a otra. En este caso hay mecanismos que agilizan la carga de la información, pero en ningún caso se puede crear un pool de objetos.

Pool de Objetos en WildFly
Antes de esta versión, existía una configuración de pool de objetos por defecto que aplicaba a todos los Stateless Session Bean. En WildFly por defecto el pool de objetos está desactivado pues se entiende que hoy en día la mejora de rendimiento derivada del pooling no es tan evidente y el uso como contención de capacidad de proceso dependerá de cada aplicación, y por tanto es responsabilidad del desarrollador (o administrador) el parametrizar estos valores. En el caso de MDB’s sigue estando activo un pool por defecto.

Para habilitar el pool por defecto slsb-strict-max-pool (límite de 20 instancias y timeout de acceso de 5 minutos) hay que editar el fichero de configuración añadiendo:

<subsystem xmlns="urn:jboss:domain:ejb3:2.0">
 <session-bean>
  <stateless>	<!-- Añadir tag stateless-->
   <bean-instance-pool-ref pool-name="slsb-strict-max-pool"/>
  </stateless>
EJBPool1

Para definir un nuevo pool podemos hacerlo desde CLI o a mano editando el fichero de configuración.

  • Desde CLI, el comando sería el siguiente:

[standalone@localhost:9990 /] /subsystem=ejb3/strict-max-bean-instance-pool=nuevo-pool:add(max-pool-size=5,timeout-unit=SECONDS,timeout=30)

Con este comando definiremos un nuevo pool de hasta 5 instancias

El resultado en el fichero standalone-full.xml es el siguiente:

 <subsystem xmlns="urn:jboss:domain:ejb3:2.0">
 ....
  <pools>
   <bean-instance-pools>
    <strict-max-pool name="nuevo-pool" max-pool-size="5" instance-acquisition-timeout="30" instance-acquisition-timeout-unit="SECONDS"/>
....

Para asociar un pool a un EJB concreto, basta añadir una anotación en la clase correspondiente indicando el nombre del pool:

@Stateless
@Pool (value="ranking-pool")
public class Ranking implements RankingLocal {

2.4.4. Descriptores de despliegue

Java Enterprise proporciona dos métodos para especificar aspectos de la configuración de una aplicación:

  • Descriptores de despliegue (Ficheros XML).

  • Anotaciones en código.

Sin embargo hay propiedades especificas de Wildfly (comportamiento de los EJB’s del servidor Web Undertow, etc.) que no quedan cubiertas por el estándar Java EE y que pueden ser definidas desde la aplicación mediante ficheros de configuración propietarios. En la sección de referencias se encuentra un enlace a la lista de descriptores de WildFly, que a la fecha de este documento no estaba completa (se podría utilizar los propios de JBoss 7.1).

2.4.5. Class Loading

En este apartado trataremos brevemente el orden que sigue el servidor a la hora de localizar las clases que componen una aplicación. En la sesión anterior comentamos los distintos tipos de aplicaciones java y la forma de acceder a componentes compartidos. JBoss proporciona un mecanismo adicional: el uso de módulos.

Los módulos se dividen a su vez en

Módulos estáticos

se integran en las carpetas de módulos del servidor y pueden ser definidos como accesibles por todos los despliegues del servidor.

Módulos dinámicos

Se copian a la carpeta deployments y pueden ser reemplazados en caliente.

Si recordamos el caso del driver de MySQL veremos que hemos propuesto dos instalaciones, una como módulo estático y otra como módulo dinámico. Por defecto si añadimos un módulo dinámico, el nombre interno que tendrá el módulo en WildFly será:

deployment.[nombre del fichero]

La forma de especificar que una aplicación necesita acceder a recursos de un módulo, (estático o dinámico) es indicarlo en el fichero MANIFEST.MF

Dependencies: deployment.WebExample1.war

Por último, comentar el orden que sigue WildFly para resolver la ubicación de una clase Java. Ordenando de mayor prioridad a menor:

  1. Dependencias del sistema: Son dependencias que el contenedor añade de forma automática a la aplicación, como por ejemplo el API de Java EE.

  2. Dependencias de usuario: Son las que el desarrollador define a través del MANIFEST.MF, el Classpath para ficheros JAR o a través del fichero jboss-deployment-structure.xml.

  3. Recursos locales. Son las clases que están ubicadas dentro del propio empaquetado de la aplicación, por ejemplo WEB-INF/classes o WEB-INF/lib de una aplicación WAR.

  4. Dependencias compartidas. Son las dependencias compartidas entre varios componentes de una aplicación. Típicamente las librerías compartidas dentro de una aplicación EAR.

2.4.6. Rendimiento

Hablar de rendimiento en un servidor de aplicaciones nos permitiría llenar más de una sesión entera del curso, si bien, lo más importante es dimensionar los recursos del servidor (memoria, pool de objetos, conexiónes a base de datos) en función de la carga de trabajo que va a soportar. Dado que gran parte de la programación que se verá en el curso gira en torno a JavaScript, comentar que hay una forma muy sencilla de agilizar los tiempos de carga de las aplicaciones y consiste en habilitar la compresión GZIP en las comunicaciones con el servidor. Descargar con compresión código JavaScript o texto estático en HTML puede reducir el tiempo de descarga hasta un 90%, a costa de un mayor consumo de CPU en el servidor.

La forma de habilitarlo en WildFly consiste en definir un filtro y según el tipo de recurso aplicar compresión o no (es contraproducente comprimir recursos estáticos ya comprimidos como imágenes o documentos PDF).

<subsystem xmlns="urn:jboss:domain:undertow:1.0">
   <buffer-caches>
      <buffer-cache name="default" buffer-size="1024" buffers-per-region="1024" max-regions="10"/>
   </buffer-caches>
   <server name="default-server">
      <http-listener name="default" socket-binding="http"/>
      <host name="default-host" alias="localhost">
          <location name="/" handler="welcome-content" />
          <filter-ref name="gzipFilter" predicate="path-suffix['.css'] or path-suffix['.js']" />
          <filter-ref name="server-header"/>
          <filter-ref name="x-powered-by-header"/>
      </host>
   </server>
   <servlet-container name="default" default-buffer-cache="default" stack-trace-on-error="local-only">
      <jsp-config/>
   </servlet-container>
   <handlers>
      <file name="welcome-content" path="${jboss.home.dir}/welcome-content" directory-listing="true"/>
   </handlers>
   <filters>
      <response-header name="server-header" header-name="Server" header-value="Wildfly 8"/>
      <response-header name="x-powered-by-header" header-name="X-Powered-By" header-value="Undertow 1"/>
      <gzip name="gzipFilter"/>
   </filters>
</subsystem>

Se añade la referencia al filtro gzipFilter en la lista de filtros y en el tag <filter-ref name> se define la expresión regular que determina si un elemento se debe comprimir o no.

2.6. Ejercicios de Administración de recursos en Wildfly

JMS y WildFly
Para que se pueda acceder a determinados recursos como las connection factory o colas del servidor desde un proceso externo, hay que utilizar un nombre JNDI adicional que comience por java:jboss/exported. El cliente jboss-client de WildFly 8.x no implementa JMS 2.0, si no que se corresponde con la especificación Java EE 6.0 La clase genérica Destination no está definida.

Ahora que ya tenemos una visión general sobre la configuración de recursos en WildFly, vamos a realizar una serie de ejercicios para poner en práctica lo que hemos aprendido.

2.6.1. Librería compartida de Logs (0.6 puntos)

Vuestro primer reto será crear una sencilla librería de log, que registre cualquier evento en una tabla de base de datos. Un evento tendrá los siguientes atributos: timestamp, un mensaje y un tipo: I:informativo, D:debug W:aviso E:error.

Debéis realizar las siguientes tareas:

  • Iniciar WildFly en modo standalone en modo Full Profile Java EE (standalone-full.xml).

  • Desplegar la libreria _apli-loglibrary- como librería compartida, que contiene las clases necesarias para implementar la interfaz de log.

  • Definir el datasource java:jboss/datasources/appLogger en un descriptor de despliegue con el password encriptado, que se debe incluir en la propia librería.

  • Desplegar una sencilla aplicación Web con un único Servlet que registre en base de datos cada llamada que reciba. Debe enlazar externamente con la librería de logs.

Se os proporciona un script eurovision.sql con la tabla de logs y la base de datos para el siguiente ejercicio. También contaréis con los tres proyectos Maven que componen esta aplicación:

  • Proyecto "Java Application" de nombre apli-logLibrary con la interfaz de Log predefinida.

  • Proyecto "Web Application", apli-AppLogger, con el servlet de prueba: se invocará mediante la llamada a http://localhost:8080/App/Test

  • Proyecto "Enterprise Application" apli-Enterprise Logger que incluirá únicamente al proyecto Web.

Debéis desplegar tanto la librería compartida como el EAR y comprobar que se registran en la tabla las llamadas al servlet. Los entregables serán los fuentes de todos los proyectos.

Pistas
Si queréis probar la librería sin desplegarla en WildFly debéis utilizar el denominado cliente completo de WildFly. Es un jar que se utiliza en clientes pesados que incluye todas las clases de WildFly necesarias para trabajar en remoto.

Para dar de alta el cliente de WildFly como una dependencia de Maven hay que hacer lo siguiente:

  1. Acceder a la carpeta /usr/local/wildfly-8.2.1.Final/bin/client .

  2. Ejecutar:

mvn install:install-file -Dfile=jboss-client.jar \
-DgroupId=org.wildfly \
-DartifactId=jboss-client \
-Dversion=8.2.1 \
-Dpackaging=jar \
-DgeneratePom=true

2.6.2. Camino a Eurovisión (1 punto)

Tenemos la tarea de desplegar un sistema de votaciones que se utilizará para determinar la próxima canción candidata española a Eurovisión. Esta aplicación presenta una estructura de proyectos típica de las aplicaciones Java Entreprise de hace algunos años. Se trata de una aplicación EAR con distintos subproyectos para cada uno de los módulos que contiene y un pom principal que compila toda la solución. Esta basada en Java EE 5 aunque tiene referencias a las librerías actuales. En resumen, algo muy parecido a lo que os podéis encontrar en el mundo laboral. Los módulos son los siguientes:

  • Una librería con un EJB que implementa la lógica de negocio.

  • Una aplicación Web que implementa la presentación.

  • Una aplicación empresarial EAR que engloba a todo el proyecto.

  • Un cliente Java EE externo.

Gráficamente, la arquitectura de la aplicación es la siguiente:

arquitectura

Se utiliza una aplicación externa para simular una pasarela que recoge los votos emitidos mediante mensajes de móvil. La información que os interesará de dichos mensajes es el número de teléfono origen y el número de la canción votada. El formato del mensaje será el teléfono, de longitud variables, el símbolo "#" como separador y por último la palabra EURO más un número del 01 al 12, ejemplo: 654736534#EURO04.

Partiréis de los proyectos Maven ya creados y un script SQL para la creación de la base de datos eurovision. Aunque no se estudia en detalle en esta sesión, dentro de la aplicación tenemos un ejemplo de procesamiento asíncrono mediante colas de mensajes y objetos MDB’s. Para que esta parte funcione correctamente hay que crear un usuario de aplicación denominado jmsuser. Para que este nuevo usuario tenga permisos de lectura/escritura hay que asociarlo al grupo guest.

ejercicios1

Para completar el ejercicio teneis que cubrir los siguientes objetivos:

  1. Configurar la aplicación EAR para que utilice la librería compartida de logs del ejercicio anterior.

  2. Ajustar la configuración del EJB Ranking que implementa la lógica de negocio añadiéndole un límite máximo de 5 objetos simultáneos para el EJB. Como esta configuración es específica de WildFly hay que añadir la siguiente dependencia al proyecto del EJB:

    <dependency>
    	<groupId>org.wildfly</groupId>
    	<artifactId>wildfly-ejb3</artifactId>
    	<version>8.2.1.Final</version>
    	<scope>provided</scope>
    </dependency>
  3. La aplicación contiene un MDB que recibe los votos y los almacena en base de datos. Hay que revisar cómo está implementado y crear la conexión a base de datos que necesita desde la consola de WildFly.

  4. Configurar el usuario JMS que utilizará el cliente Java apli-EnvioSMS. Se trata de una aplicación Java EE que se ejecuta fuera del servidor de aplicaciones pero utiliza los servicios que ofrece, concretamente una cola JMS, denominada jms/entradaMensajes a donde enviará los votos del

  5. Desplegar la aplicación y acceder a la consulta de votaciones para ver las posibles canciones a las que se puede votar.

  6. Utilizar la aplicación cliente para enviar varios votos y asegurarse de que se contabilizan correctamente.

Los entregables del ejercicio serán:

  • El fichero de configuración standalone-full.xml

  • El código fuente de todos los proyectos solicitados, apli-EnvioSMS y Apli-CaminoAEurovision.

Pistas
Para poder compilar la aplicación externa Java EE necesitaréis construir el cliente completo de WildFly, tal y como se explicaba en el ejercicio anterior. Estad muy pendientes del log de WildFly, que es donde se os dará una pista más clara de lo que ocurre en caso de problemas.