6.3 Using a Message-Driven Bean in the Benefits Application

Let's look at how the same benefits application described in Chapter 4 might look using a message-driven bean to replace the PayrollEJB session bean. See Figure 6.1.

Figure 6.1. Parts of the Benefits Enrollment Application

graphics/06fig01.gif

Star Enterprise wants to use a loosely coupled integration model between the Benefits Enrollment and other enterprise applications and its own internal payroll system maintained by the payroll department. Star Enterprise needs to implement a loosely coupled integration model for several reasons:

  • The payroll department and application may be geographically distributed.

  • The payroll application may be based on a different hardware or software configuration at different payroll sites, and these configurations may differ from the configurations for the enterprise and Benefits Enrollment applications.

  • The enterprise applications may need to update payroll information without being dependent on the payroll system's availability to process requests.

Star Enterprise can achieve such loose integration by using an enterprise messaging system. After an enterprise messaging system has been implemented, its enterprise applications, including the Benefits Enrollment application, send payroll updates to the PayrollQueue reliable message queue maintained by the payroll department. At some point, unrelated to when updates are sent to the queue, the payroll application receives the payroll-update messages from PayrollQueue asynchronously and processes them.

Chapter 4 discussed Star Enterprise's payroll system organization. In that context, it consists of two principal parts:

  • The PayrollEJB stateless session bean deployed in the payroll department's application server

  • PayrollDatabase, located in the payroll department's database server, for storing payroll information for all Star Enterprise employees

We now add a message-driven bean called PayrollMDB, which enables the payroll application to receive messages from the PayrollQueue message queue.

6.3.1 PayrollMDB Message-Driven Bean

PayrollMDB, a message-driven bean that follows the requirements of the EJB 2.1 architecture, consists of the PayrollMDB class and associated deployment descriptors. Code Example 6.1 shows the complete code for the PayrollMDB implementation class:

Code Example 6.1 PayrollMDB Implementation Class
 public class PayrollMDB implements MessageDrivenBean,            MessageListener {     private PayrollLocal payroll;     public void setMessageDrivenContext(MessageDrivenContext mdc) {         try {             InitialContext ictx = new InitialContext();             PayrollLocalHome payrollHome = (PayrollLocalHome)                    ictx.lookup("java:comp/env/ejb/PayrollEJB");             payroll = payrollHome.create();         } catch ( Exception ex ) {             throw new EJBException("Unable to get Payroll bean", ex);         }     }     public void ejbCreate() { }     public void ejbRemove() { }     public void onMessage(Message msg) {         MapMessage map = (MapMessage)msg;         try {             int emplNumber = map.getInt("Employee");             double deduction = map.getDouble("PayrollDeduction");             payroll.setBenefitsDeduction(emplNumber, deduction);         } catch ( Exception ex ) {             throw new EJBException(ex);         }     } } 

The PayrollMDB class implements two interfaces: javax.ejb.MessageDrivenBean and javax.jms.MessageListener. The JMS MessageListener interface allows the bean to receive JMS messages with the onMessage method. The MessageDrivenBean interface defines a message-driven bean's life-cycle methods called by the EJB container.

Of the three such life-cycle methods, only one is of interest to PayrollMDB setMessageDrivenContext. The container calls setMessageDrivenContext immediately after the PayrollMDB bean instance is created. PayrollMDB uses this method to obtain a local reference to the Payroll stateless session bean, first looking up the PayrollLocalHome local home object and then invoking its create method. The setMessageDrivenContext method then stores the local reference to the stateless bean in the instance variable payroll for later use in the onMessage method.

The ejbCreate and ejbRemove life-cycle methods are empty. They can be used for any initialization and cleanup that the bean needs to do.

The real work of the PayrollMDB bean is done in the onMessage method. The container calls the onMessage method when a JMS message is received in the PayrollQueue queue. The msg parameter is a JMS message that contains the message sent by the Benefits Enrollment application or other enterprise application. The method typecasts the received message to a JMS MapMessage message type, which is a special JMS message type that contains property-value pairs and is particularly useful when receiving messages sent by non-Java applications. The EJB container's JMS provider may convert a message of MapMessage type either from or to a messaging product specific format.

Once the message is in the proper type or format, the onMessage method retrieves the message data: the employee number and payroll deduction amount, using the Employee and PayrollDeduction properties, respectively. The method then invokes the local business method setBenefitsDeduction on the Payroll stateless session bean method to perform the update of the employee's payroll information in PayrollDatabase.

The PayrollMDB bean's deployment descriptor declares its transaction attribute as Required, indicating that the container starts a transaction before invoking the onMessage method and to make the message delivery part of the transaction. This ensures that the Payroll stateless session bean performs its database update as part of the same transaction and that message delivery and database update are atomic. If an exception occurs, the transaction is rolled back, and the message will be delivered again. By using the Required transaction attribute for the message-driven bean, the developer can be confident that the database update will eventually happen.

6.3.2 PayrollEJB Local Interfaces

In the previous section, PayrollMDB used the local interfaces of the PayrollEJB stateless session bean. These interfaces provide the same functionality as the remote interfaces described in Chapter 4. Because these interfaces are local, they can be accessed only by local clients deployed in the same JVM as the PayrollEJB bean. As a result, the PayrollMDB bean can use these local interfaces because it is deployed together with the PayrollEJB bean in the payroll department's application server. See Code Example 6.2:

Code Example 6.2 Payroll Class
 public interface PayrollLocal extends EJBLocalObject {     void setBenefitsDeduction(int emplNumber, double deduction)         throws PayrollException;     double getBenefitsDeduction(int emplNumber)         throws PayrollException;     double getSalary(int emplNumber)         throws PayrollException;     void setSalary(int emplNumber, double salary)         throws PayrollException; } public interface PayrollLocalHome extends EJBLocalHome {     PayrollLocal create() throws CreateException; } 


Applying Enterprise Javabeans
Applying Enterprise JavaBeans(TM): Component-Based Development for the J2EE(TM) Platform
ISBN: 0201702673
EAN: 2147483647
Year: 2003
Pages: 110

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net