Catálogo de Patrones de Diseño J2EE. Y II: Capas de Negocio y de Integración

Los beans enterprise y otros servicios de negocio necesitan una forma de activarse as�ncronamente.

.�Problema

Cuando un cliente necesita acceder a un bean enteprise, primero busca el objeto home del bean. Luego el cliente le pide a ese objeto home que le proporcione una referencia remota al bean enterprise requerido. Entonces el cliente invoca a los m�todos de negocio sobre la referencia remota para acceder a los servicios del bean enterpise. Estas llamadas a m�todos, as� como las b�squedas y las llamdas a m�todos remotos, son s�ncronos. El cliente tiene que esperar hasta que esos metodos retornan.

Otro factor a considerar es el ciclo de vida de un bean enterprise. La especificaci�n EJB permite que el contenedor pasivice un bean enterprise a un almacenamiento intermedio. Como resultado, el contenedor EJB no tiene un mecanismo mediante el cual poder proporcionar un servicio estilo-proceso para mantener un bean enterprise constantemente activado y en estado listo. Como el cliente debe interact�ar con el bean enterprise utilizando su interface remoto, incluso si el bean est� en estado activado en el contenedor, el cliente �un necesita obtener su interface remoto mediante un proceso de b�squeda y todav�a act�a con el bean de forma s�ncrona.

Si una aplicaci�n necesita procesamiento s�ncrono para sus componentes de negocio del lado del servidor, entonces los beans enterprise son una opci�n apropiada. Algunas aplicaciones cliente podr�an requerir este tipo de procesamiento porque los clientes no necesitan esperar o no tienen tiempo para esperar a que se complete el procesamiento. En caso donde la aplicaci�n necesita una forma de procesamiento as�ncrono, los beans enterpise no ofrecen esta capacidad en implementaciones anteriores a la especificaci�n EJB 2.0.

La especificaci�n EJB 2.0 proporciona integraci�n introduciendo el bean dirigido-a-mensaje, que es un tipo especial de bean de sesi�n sin estado que ofrece capacidades de invocaci�n as�ncrona. Sin embargo, la nueva especificaci�n no ofrece invocaci�n as�ncrona para otros tipos de beans enterprise, como los beans con estado o de entidad.

En general, un servicio de negocio como un bean de sesi�n o de entidad s�lo proporciona procesamiento s�ncrono y esto representa un reto para implemenetar procesamiento as�ncrono.

.�Causas

  • Los beans enterprise se exponen a sus clientes mediante sus interfaces remotos, que s�lo permiten acceso s�ncrono.
  • El contenedor maneja los beans enterprise, permitiendo interacciones s�lo mediante referencias remotas. El contenedor EJB no permite acceso directo a la implementaci�n del bean y sus m�todos. As�, implementar el oyente de mensajes JMS no es factible en un bean enterprise, ya que esto viola la especificaci�n EJB al permitir el acceso directo a la implementaci�n del bean.
  • Una aplicaci�n necesita proporcionar un marco de mensajer�a publicar/suscribir o punto-a-punto donde los clientes puedan publicar peticiones a beans enterprise para procesamiento as�ncrono.
  • Los clientes necesitan capacidades de procesamiento as�ncrono en los beans entreprise y otros componentes de negocio que s�lo pueden ofrecer acceso s�ncrono, para que el cliente pueda enviar una petici�n para su procesamiento sin esperar los resultados.
  • Los clientes quieren utilizar interfaces de la capa media orientados a mesnajes (MOM) ofrecidos por el API Java Messaging Service (JMS). Estos interfaces no est�n integrados en los productos servidores EJB que est�n basados en especificaciones anteriores a la la EJB 2.0.
  • Una aplicaci�n necesita proporcionar un servicio estilo "criado(daemon)" para que un bean enterprise pueda estar en modo callado hasta que un evento (o un mensaje) dispare su actividad.
  • Los beans enterprise est�n sujetos al control de su ciclo de vida por parte del contenedor, lo que incluye la pasivizaci�n debido a periodos de inactividad y control de recursos. El cliente tendr� que invocar a un bean enteprise para activarlo de nuevo.
  • La especificaci�n EJB 2.0 introdujo un bean dirigio-a-mensaje como un bean de sesi�n sin estado, pero no es posible invocar otros tipos diferentes de beans enteprise de forma as�ncrona.

.�Soluci�n

Utilizar un Service Activator para recibir peticiones y mensajes as�ncronos de los clientes. Cuando se recibe un mensaje, el Service Activator localiza e invoca a los m�todos de de los componentes de negocio necesarios para cumplir la petici�n de forma as�ncrona.

El ServiceActivator es un oyente JMS y un servicio de delegaci�n que requiere la implementaci�n de un oyente de mensajes JMS. Se puede implementar como un servicio independiente. Los clientes act�an como generadores de mensajes, generando eventos bas�ndose en su actividad.

Cualquier cliente que necesite invocar as�ncronamente un servicio de negocio, como un bean enteprise, podr�a crear y enviar un mensaje al Service Activator. �ste recibe el mensaje y lo analiza para interpretar la petici�n del cliente. Una vez que se ha analizado y desempaquetado la petici�n del cliente, el Service Activator identifica y localiza los componentes de servicio de negocio necesarios e invoca a sus m�todos de negocio para completar el procesamiento de la petici�n del cliente de forma as�ncrona.

Service Activator opcionalmente podr�a enviar un reconocimiento al cliente despu�s de que haya completado el procesamiento de la petici�n. Tambi�n podr�a notificar al cliente o a otros servicios si ocurre un fallo durante el procesamiento de la petici�n.

El Service Activator podr�a utilizar los servicios de un Service Locator.

.�Estructura

La siguiente figura representa las relaciones entre clases para el patr�n Service Activator:

.�Participantes y Responsabilidades

La siguiente figura muestra las interacciones entre los distintos participantes en el patr�n Service Activator:

.�Client

El cliente solicita una facilidad de procesamiento as�ncrono de los objetos de negocio que participan en un flujo de trabajo. El cliente puede ser cualquier tipo de aplicaci�n que tenga la capacidad de crear y enviar mensajes JMS. El cliente tambi�n puede ser un componente EJB que necesite invocar los m�todos de negocio de otro componente EJB de forma as�ncrona. El cliente puede utilizar los servicios ofrecidos por el patr�n Service Locator para buscar o crear componentes EJB, servicios JMS, u objetos JMS, seg�n necesite.

.�Request

Request es el objeto message creado po el cliente y enviado al ServiceActivator mediante MOM. De acuerdo a la especificaci�n JMS, Request es un objeto que implementa el interface javax.jms.Message. El API JMS proporciona varios tipos de mesnajes, como TextMessage, ObjectMessage, etc.

.�ServiceActivator

ServiceActivator es la clase principal del patr�n. Implementa el interface javax.jms.MessageListener, definido por la especificaci�n JMS. ServiceActivator implementa un m�todo onMessage() que se invoca cuando llega un nuevo mensaje. ServiceActivator analiza (desempaqueta) el mensaje (la petici�n) para determinar qu� debe hacer. El ServiceActivator podr�a utilizar los servicios de un patr�n Service Locator para buscar o crear los componentes de servicio de negocio que necesita.

.�BusinessObject

BusinessObject es el objeto destino al que el cliente necesita acceder de forma as�ncrona. El objeto de negocio es un rol que pueden cumplir los beans de sesi�n o de entidad. Tambi�n es posible que el BusinessObject sea un servicio externo en vez de un bean de entidad.

.�Estrategias

.�Entity Bean

Tanto los beans de sesi�n como los de entidad puede cumplir el rol de un BusinessObject. Cuando las aplicaciones J2EE implementan un patr�n Session Fa�ade para proporcionar acceso gen�rico a los beans de entidad y para encapsular el flujo de trabajo, el bean de sesi�n del Session Fa�ade cumple el rol del BusinessObject.

En aplicaciones sencillas con flujo de trabajo m�nimo, un bean de entidad podr�a cumplir el rol del BusinessObject. Sin embargo, para flujos de trabajo complejos que implican varios beans de entidad y otros objetos de negocio, el ServiceActivator normalmente interact�a con un Session Facade que encapsula dicho flujo de trabajo.

.�Session Bean

Cuando un bean de sesi�n cumple el rol del BusinessObject, los requerimientos del negocio determinan si el bean deber�a ser con o sin estado. Como el cliente del BusinessObject es un ServiceActivator que activa el BusinessObject cuando recibe un nuevo mensaje, el flujo de trabajo para procesar el mensaje puede definir si el bean deber�a tener estado o no. En muchos casos, un mensaje simplemente activa un s�lo m�todo en el BusinessObject que delega el procesamiento dentro del mensaje. En estos casos se puede utilizar un bean de sesi�n sin estado. Si el ServiceActivator necesita invocar varios m�todos en el BusinessObject o necesita trabajar con m�s de un BusinessObject para cumplir los requerimientos de procesamiento, podr�a ser �til considerar la utilizaci�n de un bean de sesi�n con estado para retener el estdo entre varias llamadas.

.�ServiceActivator Server

La estrategia m�s correcta para implementar el oyente o ServiceActivator es una aplicaci�n JMS independiente que escuche y procese mensajes JMS.

Una alternativa es implementar el ServiceActivator como servicio del servidor de aplicaciones. Esto hace m�s f�cil de manejar el ServiceActivator, porque utiliza las caracter�sticas del servidor de aplicaciones para monitorizar el estado del ServiceActivator y para arrancar, reiniciar y parar el ServiceActivator cuando sea necesario, manual o autom�ticamente.

.�Enterprise Bean as Client

El Cliente puede ser cualquier cliente, incluyendo otro bean enterprise que requiera procesamiento as�ncrono. Cuando se integran aplicaciones legales en la plataforma J2EE, es l�gico elegir aplicaciones Java como clientes para act�ar como generadores de mensajes bas�ndose en la actividad del sistema legal. El ServiceActivator puede recibir mensajes y realizar cualquier invocaci�n a bean de enterprise necesaria para procesar la petici�n desde sistemas legales.

.�Consecuencias

  • Integra JMS en implementaciones Pre-EJB 2.0
    Anteriormente a la especificaci�n EJB 2.0 no hab�a integraci�n entre beans enterprise y componentes JMS. Este partr�n proporciona una forma de integrar JMS en una aplicaci�n EJB y permite procesamiento as�ncrono. La especificaci�n EJB 2.0 define un nuevo tipo de bean de sesi�n, llamado bean dirigido-a-mensaje, para integrar JMS y componentes EJB. Este bean especial implementa el interface javax.jms.MessageListener y recibe mensajes as�ncronos. En este caso, el servidor de aplicaciones juega el rol del Service Activator. Este patr�n hace posible ejecutar aplicaciones en implementaciones EJB 2.0 as� como en implementaciones de EJB anteriores.
  • Proporciona Procesamiento As�ncrono para cualquier Bean Enterprise
    En la especificaci�n EJB 2.0, el bean dirigido-a-mensaje es un bean de sesi�n sin estado. Utilizando el patr�n Service Activator, es posible proporcionar invocaci�n as�ncrona a todos los tipos de beans enterprise, incluyeno beans de sesi�n con o sin estado y beans de entidad. Como se explic� anteriormente, ya que el Service Activator se implementa abiertamente, sin las limitaciones del bean dirigido-a-mensaje, el Service Activator puede realizar llamadas as�ncronas a cualquier tipo de servicio de negocio. As�, este patr�n presenta una forma de proporcionar procesamiento as�ncrono para clientes que no necesitan esperar los resultados o no quieren esperar a que se complete el procesamiento. El procesamiento se puede retrasar y realizarse m�s tarde, permitiendo que el cliente complete el servicio en menos tiempo.
  • Proceso Independiente
    Service Activator se puede ejecutar como un proceso independiente. Sin embargo, en una aplicaci�n cr�tica, necesitamos monitorizar el Service Activator para asegurarnos de su disponibilidad. Este control y manteminiento adicional puede a�adir una peque�a sobrecarga a la aplicaci�n.

.�C�digo de Ejemplo

Consideremos una aplicaci�n de procesamiento de pedidos donde los clientes compran on-line y los otros procesos se realizan en segundo plano. En algunos casos, el cumplimiento del pedido podr�a externalizarse a un almacen de terceros. En dichos casos, el almacen on-line necesita invocar estos servicios de forma as�ncrona. Este es un ejemplo que demuestra la utilizaci�n de la mensajer�a punto-a-punto (PTP) para conseguir el procesamiento as�ncrono. Sin embargo, la utilizaci�n de la mensajer�a publicar/suscribir ser�a similar, excepto en que se utilizar�a un Topic en lugar de una Queue. La elecci�n del m�todo autilizado, PTP o publicar/suscribir, depedende de los requerimientos de la aplicaci�n, y se sale fuera del �mbito de este patr�n.

En la siguiente figura podemos ver el diagrama de clases como los m�todos importantes de este ejemplo:

El siguiente fragmento de c�digo demuestra la implementaci�n de un Service Activator. Esta es la clase que se puede ejemplarizar en un servidor de aplicaciones o ejecutar como un servicio independiente, como se explic� en las estrategias anteriores:


public class OrderServiceActivator implements 
  javax.jms.MessageListener{

  // Queue session and receiver: see JMS API for
  // details
  private QueueSession orderQueueSession;
  private QueueReceiver orderQueueReceiver;

  // Note: values should come from property files or 
  // environment instead of hard coding.
  private String connFactoryName = 
    "PendingOrdersQueueFactory";
  private String queueName = "PendingOrders";

  // use a service locator to locate administered
  // JMS components such as a Queue or a Queue 
  // Connection factory
  private JMSServiceLocator serviceLocator;

  public OrderServiceActivator(String connFactoryName, 
      String queueName) {
    super();
    this.connFactoryName = connFactoryName;
    this.queueName = queueName;
    startListener();
  }

  private void startListener() {
    try {
      serviceLocator = new JMSServiceLocator
            (connFactoryName);
      qConnFactory = 
          serviceLocator.getQueueConnectionFactory();
      qConn = qConnFactory.createQueueConnection();

      // See JMS API for method usage and arguments
      orderQueueSession = qConn.createQueueSession (...);
      Queue ordersQueue = 
              serviceLocator.getQueue(queueName);
      orderQueueReceiver = 
        orderQueueSession.createReceiver(ordersQueue);
      orderQueueReceiver.setMessageListener(this);
    }
    catch (JMSException excp) {
         // handle error
    } 
  }

  // The JMS API specifies the onMessage method in the
  // javax.jms.MessageListener interface. 
  // This method is asynchronously invoked 
  // when a message arrives on the Queue being
  // listened to by the ServiceActivator.  
  // See JMS Specification and API for more details.
  public void onMessage(Message msg) {
    try {
        // parse Message msg. See JMS API for Message.
        ...

        // Invoke business method on an enterprise
        // bean using the bean's business delegate.
        // OrderProcessorDelegate is the business 
        // delegate for OrderProcessor Session bean.
        // See Business Delegate pattern for details.      
          OrderProcessorDelegate orderProcDeleg = 
            new OrderProcessorDelegate();

        // Use data values from the parsed message to
        // invoke business method on bean via delegate
        orderProcDeleg.fulfillOrder(...);

        // send any acknowledgement here...
    }
    catch (JMSException jmsexcp) {
      // Handle JMSExceptions, if any
    } 
    catch (Exception excp) {
      // Handle any other exceptions
    }
  }
  
  public void close() {
    try {
      // cleanup before closing
      orderQueueReceiver.setMessageListener (null);   
      orderQueueSession.close();     
    }
    catch(Exception excp) {
      // Handle exception - Failure to close
    }
  }
}

En el siguiente c�dido est� el ejemplo del Session Facade para despachar los pedidos a este servicio as�ncromo. El cliente Service Activator puede ser un bean de sesi�n que implementa el patr�n Session Fa�ade para proporcionar servicio de procesamiento de pedidos a una aplicaci�n de almacen on-line. Cuando se llama al m�todo createOrder(), despu�s de validar y de crear satisfactoriamente un nuevo pedido, se llama la m�todo sendOrder() para despachar el nuevo pedido al sevicio de env�o:


// imports...
public class OrderDispatcherFacade 
  implements javax.ejb.SessionBean {
  ...
  // business method to create new Order
  public int createOrder(...) throws OrderException {

    // create new business order entity bean
    ...

    // successfully created Order. send Order to
    // asynchronous backend processing 
    OrderSender orderSender = new OrderSender();
    orderSender.sendOrder(order);

    // close the sender, if done...
    orderSender.close();

    // other processing
    ...
  }
}

El c�digo JMS se puede separar en una clase diferente para que pueda ser reutilizado por diferentes clientes. Podemos ver esta clase en el siguiente listado:


// imports...
public class OrderSender {
  // Queue session and sender: see JMS API for details
  private QueueSession orderQueueSession;
  private QueueSender orderQueueSender;

  // These values could come from some property files
  private String connFactoryName = 
    "PendingOrdersQueueFactory";
  private String queueName = "PendingOrders";

  // use a service locator to locate administered
  // JMS components such as a Queue or a Queue.
  // Connection factory
  private JMSServiceLocator serviceLocator;
  ...
  // method to initialize and create queue sender
  private void createSender() {
    try {
      // using ServiceLocator and getting Queue
      // Connection Factory is similar to the
      // Service Activator code.
      serviceLocator = new JMSServiceLocator
            (connFactoryName);
      qConnFactory = 
          serviceLocator.getQueueConnectionFactory();
      qConn = qConnFactory.createQueueConnection();

      // See JMS API for method usage and arguments
      orderQueueSession = qConn.createQueueSession
          (...);
      Queue ordersQueue = 
              serviceLocator.getQueue(queueName);
      orderQueueSender = 
          orderQueueSession.createSender(ordersQueue);
    catch(Exception excp) {
      // Handle exception - Failure to create sender
    }
  }

  // method to dispatch order to fulfillment service
  // for asynchronous processing
  public void sendOrder(Order newOrder) {

      // create a new Message to send Order object
      ObjectMessage objMessage = 
        queueSession.createObjectMessage(order);

      // set object message properties and delivery 
      // mode as required.
      // See JMS API for ObjectMessage

      // Set the Order into the object message
      objMessage.setObject(order);

      // send the message to the Queue
      orderQueueSender.send(objMessage);
      
      ...
    } catch (Exception e) {
      // Handle exceptions
}
    ...
  }
  ...
  public void close() {
    try {
      // cleanup before closing
      orderQueueReceiver.setMessageListener (null);   
      orderQueueSession.close();     
    }
    catch(Exception excp) {
      // Handle exception - Failure to close
    }
  }
}

.�Patrones Relacionados

  • Session Facade
    El patr�n Session Facade encapsula la complejidad del sistema y prorporciona acceso gen�rico a los objetos de negocio. Este patr�n Service Activator podria acceder a un Session Fa�ade como objeto de negocio principal para invocar m�todos de negocio de otros servicios de forma as�ncrona por cuenta del cliente.
  • Business Delegate
    El patr�n Service Activator podr�a utilizar un Business Delegate para acceder al Session Fa�ade u otra implementaci�n de bean enterprise. Esto resulta en un c�digo m�s sencillo para el Service Activator y en que el Business Delegate se pueda reutilizar entre diferentes capas.
  • Service Locator
    El cliente puede utilizar el patr�n Service Locator para buscar y crear objetos de servicios relacionados con JMS. El Service Activator puede utilizar el patr�n Service Locator para buscar y crear componentes beans enterprise.
  • Half-Sync/Half-Async [POSA2]
    El patr�n Service Activator est� relacionado con el patr�n Half-Sync/Half-Async, que describe el desacoplamiento arquitectural de procesamientos s�ncronos y as�ncronos sugiriendo diferentes capas para s�ncronos y as�ncronso con una cola intermedia entre ellos.

COMPARTE ESTE ARTÍCULO

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