Esta cap�tulo cubre c�mo crear un Bean Dirigido por Mensaje (MDB). Crear� dos beans MDB, DeliverItems y RequestItems. El primero rellenar� los stocks de varios �tems de MyStore, y RequestItems enviar� peticiones a varios proveedores para que que env�en �tems que est�n fuera de stock. El manager de MyStore generar�/enviar� esta petici�n.

Nota:
Ambos beans dirigidos por mensajes acceden al bean StoreAccessBean a trav�s de su interface remoto, incluso aunque est�n en la misma JVM. Esto es porque hemos implementado StoreAccessBean como un bean Remoto, y s�lo expone su interface remoto. Sin embargo, en los accesos a los beans Manager y Item, que tambi�n son utilizados por estos beans dirigidos por mensaje si podemos utilizar sus interfaces locales ya que est�n en la misma JVM, y hemos expuesto sus interfaces locales. |
�Crear el Bean MDB RequestItems:
- Ve a Package Explorer expande el nodo del proyecto Mystore, selecciona src y pulsa el bot�n derecho.
- En el men� que aparece elige New > Lomboz EJB Creation Wizard.
- Introduce au.com.tusc.mdb como el nombre del paquete, RequestItems como el nombre del bean y selecciona el tipo como Message Drive Bean (Queue):
- Pulsa Finish.
Esto crear� un paquete llamado au.com.tusc.mdb en src y el bean RequestItemsBean dentro de ese paquete:

Nota:
Los beans dirigidos por mensajes escuchan los mensajes de un productor JMS, que obtiene informaci�n de un productor (quiz�s otro bean) y la trasfieren al bean consumidor. Como es el �nico responsable de procesar dichos mensajes, no necesita ninguna clase de ayuda del tipo de los interfaces Remote y RemoteHome, las clases de utilidad, las clases DAO, etc. La �nicas clases de ayuda que tiene que crear son "objetos de valor inmutable", que son los responsables de contener la informaci�n extra�da de los mensajes y trasmitirla a los beans. |
Se crea una etiqueta @ejb.bean que asigna el nombre, el tipo de transaci�n, el tipo de destino y algunas otras propiedades que puedes ver abajo:

Al contrario que los beans anteriores �ste tiene un m�todo setMessageContext para configurar el contexto:

Tiene los m�todos ejbCreate y ejbRemove al igual que los otros tipos de beans:

Tiene un nuevo m�todo llamado onMessage que es uno de los m�s importantes para nosotros, es donde escribiremos toda la l�gica de negocio:

Una vez que se recibe un mensaje del productor JMS como un objeto Message, se extraen sus datos y se rellena un objeto de valor inmutable con esos datos y luego se transfiere al bean principal. Esto lo cubriremos m�s tarde.
Ahora, antes de a�adir cualquier funcionalidad, crearemos una clase u objeto de valor inmutable para extraer informaci�n del mensaje.
�Crear un Objeto de Valor Inmutable para RequestItem:
- Ve a src bajo el paquete au.com.tusc.mdb elige New >Class
- Aparecer� el wizard de clases Java, elige Add y selecciona el nombre de la clase como RequestItem, la Superclase como java.lang.Object y el Interface como Serializable como se ve en la siguiente figura:
Esto generar� la clase RequestItem en el paquete au.com.tusc.mdb.
- A�ade los siguientes atributos a la clase RequestItem:
private String username; private String passwd; private String itemID; private int quantity;
- Para a�adir m�todos accesores y mutadores para esos atributos; seleccionalos todos, pulsa con el bot�n derecho y selecciona source > Generate Getter and Setter como se ve abajo:
- A�ade un constructor para la clase que tenga par�metros de los mismos tipos que los atributos y asign�los a los atributos:
Ya est� completo el constructor de RequestItem, ahora nos falta implementar el m�todo onMessage del bean RequestItem.
�Implementar el m�todo onMessage:
Este m�todo es responsable de extraer informaci�n del mensaje y transferirla al bean principal. Un Manager de MyStore chequear� los �tems que est�n fuera de stock y genera una petici�n a los proveedores especificando el itemID y la cantidad necesaria.
- Primero importa los paquetes java.util.ArrayList y java.util.Iterator.
- A�ade las siguientes variables para almacenar referencias:
ArrayList outOfStockItems = null; Iterator itemsIterator = null; private StoreAccessHome storeAccess = null; private SupplierLocalHome suppLocalHome = null; private ItemLocalHome itemLocalHome = null;
- Extrae los datos del mensaje en el objeto de valor inmutable como se muestra abajo:
RequestItem ri = (RequestItem) ((ObjectMessage) message).getObject();
- A�ade estas l�neas de c�digo para que el manager pueda hacer el login:
StoreAccess access = StoreAccessUtil.getHome().create(); String mgrAccessID = access.loginUser(ri.getUsername(),ri.getPasswd());
- Obt�n los �tems con stock 0, llamando a getOutOfStockItems() del bean StoreAccess (que devuelve una Collection):
outOfStockItems = access.getOutOfStockItems();
- Ahora, itera sobre cada �tem, obt�n el supplierId asociado con �l llamando a los m�todos finder del bean Supplier, y finalmente env�a el mensaje a ese proveedor llamando al m�todo de negocio requestItem() sobre el bean Supplier:
itemsIterator = outOfStockItems.iterator(); while ( itemsIterator.hasNext() ) { ItemData itemData= ( ItemData ) itemsIterator.next(); String suppID = itemData.getSupplierID(); SupplierLocal supplier = this.suppLocalHome.findByPrimaryKey(suppID); Integer quantity = new Integer (ri.getQuantity()); String itemID = ri.getItemID(); supplier.requestItem( itemID, quantity); }
Abajo puedes ver el c�digo del m�todo onMessage:

Nuestro bean est� completo, y s�lo nos faltan los descriptores de despliegue para el bean.
�Desplegar el Bean RequestItems:
Para desplegar este bean tenemos que a�adir unos cuantos descriptores de despliegue. Como se ve abajo, se han a�adido cinco etiquetas:

- Primero a�ade la siguiente etiqueta a nivel de clase en el bean RequestItems, para obtener una referencia a StoreAccessBean, para poder invocar a sus m�todos:
@ejb.ejb-ref ejb-name="StoreAccess" view-type="remote" ref-name="StoreAccess"
Esta etiqueta generar� los descriptores de despliegue en ejb-jar.xml cuando generes tus clases EJB, ya que este bean de mensaje tiene que autenticarse, antes de transferir la informaci�n al bean principal. Generar� los siguientes descriptores de despliegue:
- A�ade esta otra etiqueta, para obtener una referencia al bean Supplier en este bean:
@ejb.ejb-ref ejb-name="Supplier" view-type="local" ref-name="SupplierLocal"
Esta etiqueta generar� los descriptores de despliegue en ejb-jar.xml cuando generes tus clases EJB, ya que este bean de mensaje transfiere informaci�n al bean Supplier. Se generar�n estos descriptores de despliegue:
- A�ade la siguiente etiqueta. Esta etiqueta es espec�fica de JBOSS, y se utiliza para registrar el bean dirigido por mensaje con un nombre JNDI, utilizando el formato "queue/name":
@jboss.destination-jndi-name name="queue/MdbQueue"
Esta etiqueta genera los siguientes descriptores de despliegue en jboss.xml:
- A�ade esta otra etiqueta, necesaria para que JBOSS pueda encontrar el bean Supplier utilizando su nombre JNDI:
@jboss.ejb-ref-jndi ref-name="SupplierLocal" jndi-name="SupplierLocal"
Nota:
Como se explic� en p�ginas anteriores, esta etiqueta genera descriptores incorrectos dentro de jboss.xml. Para view-type="local" genera una etiqueta <ejb-ref> en vez de <ejb-local-ref>. - Corrige las siguientes etiquetas:
Busca estas etiquetas en jboss.xml y cambialas como <ejb-local-ref> seg�n la siguiente figura:
- Ahora a�de esta �ltima etiqueta en el bean StoreAccess, para referenciarlo utilizando su nombre JNDI:
@jboss.ejb-ref-jndi ref-name="StoreAccess" jndi-name="StoreAccessBean"
Esta etiqueta generar� los siguientes descriptores de despliegue en jboss.xml:
Nota:
Otro descriptor que se ha generado es <ejb-name>, que ha sido generado por la etiqueta @ejb.bean que a�adi� el EJB creation wizard. ![]() Esta etiqueta genera los siguientes descriptores de despliegue en ejb-jar.xml: ![]() |
Ahora ya est� completo nuestro bean RequestItems, a�ade tu bean y genera las clases EJB:
- Ve al nodo RequestItemsBean en el paquete au.com.tusc.mdb, pulsa con el bot�n derecho y selecciona Lomboz J2EE... > Add EJB to Module y pulsa Ok.
- Ve al nodo MyStoreMgr en el explorador de paquetes, pulsa con el bot�n derecho, y selecciona Lomboz J2EE... > Generate EJB classes.
Nota:
Como has regenerado tus clases de nuevo, tendr�s que corregir los descriptores de despliegue incorrectos de jboss.xml, dentro de <message-driven> y <session>. - Ahora para desplegar el bean, ve a Lomboz J2EE View, arranca el servidor si no lo est� y despliega el bean.
Los mensajes de la consola te dir�n el estado del despliegue. Ahora nos falta crear nuestro test de cliente.
�Crear el Test de Cliente:
En este caso no nos servir� el Test Client Wizard para crear el test de cliente, porque requiere que seleccionemos un interface Home y un interface EJB, y los beans dirigidos por mensaje no tienen este tipo de interfaces.
Por eso tenemos que escribir una clase y los m�todos necesarios para llamar a las operaciones sobre el bean RequestItems.
- A�ade una clase llamada RequestMDBClient al paquete au.com.tusc.mdb
- A�ade un m�todo llamado getContext con la siguiente firma:
private InitialContext getContext() throws NamingException
- A�ade las siguientes l�neas de c�digo para obtener el ejemplar de IntialContext:
- A�ade un m�todo llamado testMDBBean con la siguiente firma:
public void testMDBBean()
- Ahora implementa este m�todo, utilizando estos pasos:
- A�ade un Data Object que se enviar� como mensaje.
- Crea una referencia al contexto inicial.
- Crea una referencia a la factor�a conexiones.
- Utiliza este contexto para realizar la b�squeda, donde el string de b�squeda es "queue/MdbQueue".
- Crea la QueueConnection.
- Crea el QueueSender.
- Crea la QueueSession para el bean.
- Crea el objeto Message para el Data Object en el mensaje.
- Env�a el mensaje.
- Finalmente, env�a la sesi�n, y luego cierra tanto la sesi�n como la conexi�n.
Aqu� puedes ver un fragmento de c�digo del m�todo testMDBean:
El test de cliente ya est� completo, vamos a probarlo!
�Probar el Cliente:
- Para probar el cliente, selecciona el nodo RequestMDBClient, ve al men� superior y selecciona el icono del "hombre corriendo".
- En �l, selecciona Run as y luego Java Application.
- Ahora, en la consola deber�as obtener los siguientes mensajes:
Este mensaje no nos dice si se ha enviado o no el mensaje al bean principal. Para verificar esto, ve a la base de datos utilizando JMX Management Console View > Hypersonic > Invoke Database Manager y ejecuta una consulta sobre la tabla supplier para ver si se ha a�adido un mensaje a alg�n proveedor.
Nota:
Los detalles de c�mo acceder a este Database Manager se vieron en la primera p�gina de este tutorial.Como un proveedor llamado Sebastian ha recibido nuestro mensaje, significa que nuestro bean funciona correctamente.
�Ejercicio:
Ahora para seguir progresando, por favor completa el siguiente ejercicio para implementar DeliverItems como un bean MD. Aqu� tienes la lista de tareas:
- Crea un bean MD lamado DeliverItems en el paquete au.com.tusc.mdb.
- Crea un objeto de valor inmutable llamado DeliverItem en el paquete au.com.tusc.mdb. A�adele algunos atributos e implementa sus m�todos accesores y mutadores:
private String username private String passwd private String itemID private int quantity
- Implementa el m�todo onMessage en DeliverItems:
- A�ade estas dos variables para almacenar referencias:
private StoreAccessHome storeAccess = null; private ItemLocalHome itemLocalHome = null;
- Extrae los datos del mensaje en tu objeto de valor inmutable de esta forma:
DelieverItem di = (DeliverItem) ((ObjectMessage) message).getObject();
- Obt�n las referencias de los beans StoreAccess e Item:
StoreAccess access = StoreAccessUtil.getHome().create(); itemLocalHome = ItemUtil.getLocalHome();
- LLama al m�todo loginUser de supplier para obtener su userid(accessID) y luego encontrar la ID del proveedor llamado al m�todo getSupplierData:
String suppAcessID = access.loginUser(di.getUsername(), di.getPasswd()); SupplierData sd = access.getSupplierData(suppAccessID); String suppID = sd.getSupplierID();
- Si suppID no es null, llama al m�todo finder del bean Item para obtener los detalles de los �tems a entregar, extrayendo itemID del mensaje:
ItemLocal item = this.itemLocalHome.findByPrimaryKey(di.getItemID());
- Obt�n la ID del proveedor asociada con el �tem encontrado, para poder actualizar el stock:
String itemSuppID = item.getSupplierID();
-
Compara itemSuppID e ItemID, si son iguales actualiza el stock de ese �tem llamado al m�todo fillStock del bean Item:
if ( suppID.equals(itemSuppID)) { System.out.println ("Delivering items in store now... :"); Integer quantity = new Integer (di.getQuantity()); item.fillStock(quantity); System.out.println ("Stock of iten after dleivery is :" + item.getItemData()); }
- A�ade estas dos variables para almacenar referencias:
- A�ade las siguientes etiquetas para el despliegue a nivel de clase para enlazar/referenciar a Supplier:
1. @ejb.ejb-ref ejb-name="StoreAccess" view-type="remote" ref-name="StoreAccess" 2. @ejb.ejb-ref ejb-name="Item" view-type="local" ref-name="ItemLocal" 3. @jboss.ejb-ref-jndi ref-name="ItemLocal" jndi-name="ItemLocal" 4. @jboss.ejb-ref-jndi ref-name="StoreAccess" jndi-name="StoreAccessBean" 5. @jboss.destination-jndi-name name="queue/DelMdbQueue"
- Despliega el bean DeliverItems.
- Crea un test de cliente llamado DeliverMDBClient en le paquete au.com.tusc.mdb.
- a�ade un m�todo llamado testMDBBean con la siguiente firma:
public void testMDBBean
- Implementa testMDBBean; aqu� tienes unas pistas:
- A�ade un Data Object que se envi� como mensaje.
- Crea el contexto inicial.
- Crea una factor�a de conexiones.
- Utiliza este contexto para realizar la b�squeda JNDI con el string "queue/DelMdbQueue".
- Crea la QueueConnection.
- Crea el QueueSender.
- Crea la QueueSession para el bean.
- Crea el objeto Message y pas�le el Data Object en el mensaje.
- Env�a el mensaje.
- Finalmente, env�a la sesi�n y cierra la sesi�n y la conexi�n.
- Ejecuta el cliente y prueba el bean:
Nota:
Todos estos pasos ya los has realizado para implementar el bean RequestItems. Es necesario que implementes este bean porque lo utilizaremos en las p�ginas siguientes: En el caso de que tengas dificultades, aqu� te proporcionamos las clases para que las descargues: |