Construir Aplicaciones EJB con JBoss, Lomboz y Eclipse

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:

  • 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:
  • 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:

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:
    1. A�ade un Data Object que se enviar� como mensaje.
    2. Crea una referencia al contexto inicial.
    3. Crea una referencia a la factor�a conexiones.
    4. Utiliza este contexto para realizar la b�squeda, donde el string de b�squeda es "queue/MdbQueue".
    5. Crea la QueueConnection.
    6. Crea el QueueSender.
    7. Crea la QueueSession para el bean.
    8. Crea el objeto Message para el Data Object en el mensaje.
    9. Env�a el mensaje.
    10. 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:

  1. Crea un bean MD lamado DeliverItems en el paquete au.com.tusc.mdb.
  2. 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
    
  3. 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());
      }
      
  4. 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"
    
  5. Despliega el bean DeliverItems.
  6. Crea un test de cliente llamado DeliverMDBClient en le paquete au.com.tusc.mdb.
  7. a�ade un m�todo llamado testMDBBean con la siguiente firma:
    public void testMDBBean
  8. 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.
  9. 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:

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP
ARTÍCULO ANTERIOR

SIGUIENTE ARTÍCULO