Proyecto de Integración
 

Integración con Mensajes: JMS

Introducción

El objetivo de esta sesión es integrar las tecnologías JMS/MDB dentro de nuestro proyecto de integración. Para ello, vamos a permitir que la aplicación envíe mensajes a un cola a través de un EJB, y que consuma mensajes mediante un MDB.

Ambos ejercicios los crearemos dentro del proyecto EJB que ya tenemos.

Multas Externas

Crearemos un MDB (org.especialistajee.jbib.mdb.MultasExternasMDB dentro del proyecto jbib-negocio-ejb) que escuche peticiones de multa de usuarios de sistemas externos. Así pues, la aplicación escuchará de una cola (BibliotecaMultasUsuariosQueue) los envíos de sistemas externos respecto a los usuarios que tienen multas, mediante un mensaje de texto que contiene el login y el número de días de multa, ambos separados mediante el carácter '#'.

Una vez recibido el mensaje, el MDB debe guardar la multa en la base de datos, y cambiar el estado del usuario de activo a moroso. En el caso de que el usuario ya fuese moroso, crearemos una nueva multa activa.

Todas las operaciones deben formar parte de una transacción distribuida, de modo que si salta alguna excepción en alguna operación, se deshagan todas los operaciones.

Deshaciendo las Reservas

En este ejercicio, vamos a crear un Timer para deshaga las reservas que han caducado. Una vez se invoque al método marcado con @TimeOut, a parte de borrar las reservas caducadas, vamos a enviar un mensaje a la cola (BibliotecaReservasCaducadasQueue) con el login y el isbn de la reserva que acaba de caducar.

Si al mismo tiempo caduca más de una reserva, se enviarán tantos mensajes como reservas caducadas.

Para invocar el timer, lo haremos desde el método singleton de FactoriaBOBeans:

public static FactoriaBos getInstance() {
    if (me == null) {
        me = new FactoriaBos();
        operacionBo.initTimer();
    }
    return me;
}

Para que el método initTimer sea accesible desde fuera del EJB pero que no puedan acceder a él los clientes no EJB, es necesario crearlo en el interfaz OperacionBOLocal:

@Local
public interface OperacionBoLocal extends IOperacionBo {
    public void initTimer();
}

Vamos a crear el método que caduca las reservas dentro del EJB OperacionBoEjb. El esqueleto del método es el siguiente:

public void initTimer() {
	context.getTimerService().createTimer(1000, 1000*10, "TimerCaducaReserva");
}

@Timeout
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void caducaReservas(Timer timer) {
	String nombre = (String) timer.getInfo();

	if ("TimerCaducaReserva".equals(nombre)) {
		// 1º comprobamos si hay reservas caducadas
		// 2º por cada reserva caducada,
		// eliminamos la reserva y enviamos mensaje a la cola
	}
}

Recordad que deberéis crear y cerrar la conexión JMS mediante los callbacks EJB, tal como vimos en la cuarta sesión de teoría.

Consulta de Reservas Caducadas
Para obtener las reservas que tenéis caducadas, podeis reutilizar la consulta de obtener las reservas activas y recorrer las que han caducada, o aún mejor, crear una consulta que únicamente devuelva las reservas caducadas.

Probando...

Para comprobar ambos ejercicios, vamos a crear dos aplicaciones cliente:

  • jbib-multas-client: cliente JMS que envía un mensaje de texto a BibliotecaMultasUsuariosQueue con el login y el número de días de la multa separados por '#'.
  • jbib-reservas-client: cliente JMS que escucha en modo asíncrono un mensaje de texto de BibliotecaReservasCaducadasQueue con el login y el isbn del libro cuya reserva ha caducado, ambos separados por '#'.

Para que ambos ejercicios funcionen, tenéis que crear los recursos JMS necesarios:

  • Una factoria de conexiones denominada BibliotecaConnectionFactory.
  • 2 colas, una para las multas (BibliotecaMultasUsuariosQueue) y otra para las reservas caducadas (BibliotecaReservasCaducadasQueue).

A Entregar

Debéis entregar únicamente el proyecto ejb.