Have your application call my application, Part 3: The resource adapter Geronimo message-driven beans, JCA resource adapters, and e-mail

Skill Level: Intermediate

Madhuri Suda ([email protected]) Java programmer Freelance

05 Sep 2006

In Part 1 and Part 2 of this three-part tutorial series, you learned how to develop message-driven beans (MDBs) and entity beans and deploy and test them in and how to create an e-mail application and deploy it in Java™ Apache Mail Enterprise Server (Apache James). In this final installment, you'll tie the application together by learning all about Java 2 Platform, Enterprise Edition (J2EE) Connector Architecture (JCA) resource adapters and building a sample adapter that connects to the Apache James server.

Section 1. Before you start

This tutorial series is for J2EE and Java Platform, Enterprise Edition (Java EE) programmers who would like to learn how to build integrated solutions using various J2EE components like MDBs, JCA resource adapters, and so on.

About this series

This three-part series walks you through building a sample application to understand how different J2EE components can be integrated to develop complex applications. The sample application demonstrates the flow of data from an e-mail in the Apache James e-mail server to the Apache Geronimo application server via a JCA resource adapter, MDBs, and EJB.

The resource adapter © Copyright IBM Corporation 1994, 2008. All rights reserved. Page 1 of 37 developerWorks® ibm.com/developerWorks

Part 1 demonstrated how to develop MDBs and entity beans, and container-managed persistence (CMP) and how to deploy and test these components in Apache Geronimo.

Part 2 explained how to create an e-mail application (mailers and matchers) and deploy it in Apache James.

Part 3 ties the entire application together. You'll learn how to develop, deploy, and test a JCA resource adapter for Apache James that interacts with both James and Geronimo via MDB.

About this tutorial

This final tutorial in the three-part series explains in detail the interactions between different J2EE components (MDB and JCA adapters). You'll learn about JCA-based resource adapters and build a sample adapter that connects to the Apache James server.

Prerequisites

This tutorial assumes you're familiar with basic Java, J2EE, and Java EE concepts, such as Enterprise Java Beans (EJB), Java Message Service (JMS), MDBs, and Unified Modeling Language (UML) diagrams. You're not required to have any prior knowledge of JCA. However, if you would like to read the JCA specification before starting this tutorial, check the Resources section for a link.

System requirements

You need the following tools to follow along with this tutorial:

• Apache Geronimo -- Java EE application server from Apache • Apache James 2.2 -- Java-based Simple Mail Transfer Protocol (SMTP), version 3 (POP3), and Network News Transfer Protocol (NNTP) news server • The database -- Open source, lightweight database that is embedded within Geronimo, so no separate installations are required • Java 1.4.2 from Example source file

First, download part3.zip (available in the Download section), which includes source, adapter, MDB, and EJB binaries for Part 3. The components of part3.zip include the following: • - deploy (po.ear, which contains both the mailet and matcher)

The resource adapter Page 2 of 37 © Copyright IBM Corporation 1994, 2008. All rights reserved. ibm.com/developerWorks developerWorks®

• - lib (tester.jar, examples.jar, mail-1.3.1.jar, activation.jar) • - src (Java files for resource adapter, mdb, ejb and test client) • - runSendEmail.cmd • - runReadEmail.cmd

Section 2. Overview

In this section, you'll explore the evolution of application integration leading up to the advent of JCA.

A brief history of application integration

Let's travel back in time, say before 2000, when integrating heterogeneous enterprise and legacy systems (for example, SAP, Siebel, and Peoplesoft) was not only expensive, but also a very time-consuming, ad hoc process. This process, popularly known as Enterprise Application Integration (EAI) was offered as a proprietary service by various software vendors.

At the end of 2000, the J2EE Connector Architecture (abbreviated as JCA and not to be mistaken for Java Cryptography Architecture) for the first time introduced standards for EAI. The advent of JCA, along with J2EE 1.3, marked a giant leap in developing integrated solutions in 2001 and set a decline for proprietary technologies in the integration space.

Definitions

Take a look at the following definitions before diving into resource adapters:

• Enterprise Information Systems (EIS): The back-end layer where traditional data processing occurs in an organization. For this tutorial series, the Apache James server is the EIS. • Enterprise Application Integration (EAI): The process of linking various enterprise systems (EIS) in an organization. • Application Programming Interface (API) contract: A predefined set of to communicate among different J2EE components. • Resource Adapter Archive (RAR): Consists of all the libraries and descriptors required by a resource adapter.

The resource adapter © Copyright IBM Corporation 1994, 2008. All rights reserved. Page 3 of 37 developerWorks® ibm.com/developerWorks

• Service Provider Interface (SPI): Contract defined by the JCA specification. • Common Client Interface (CCI): Contract defined by the JCA specification.

What is a resource adapter?

A resource adapter is a J2EE component, such as EJBs, and MDBs. As every J2EE component conforms to some specification, a resource adapter must conform to a well-defined specification called the J2EE Connector Architecture (see Resources for links to the JCA specifications). A resource adapter has an important role in an integrated J2EE solution: It's responsible for all of the communication with a back-end EIS.

A resource adapter serves as a single point of entry for any J2EE component to access the back-end resource, which is usually an EIS. It's solely responsible for connecting to the EIS, invoking the services available on the EIS system, and more. A resource adapter is to an EIS system what an entity bean is to a database.

A resource adapter can be deployed within a J2EE application server, which is called a managed scenario.A non-managed scenario is one where a resource adapter doesn't have to be deployed in any server and is stand alone. In this tutorial, you'll use the managed scenario, because you'll deploy your resource adapter in Apache Geronimo, which is a J2EE application server.

You'll learn about the different components of a resource adapter in the later sections. First, you need to understand the specification itself.

Section 3. J2EE connector architecture specification

A JCA specification defines a set of contracts to manage various aspects of a resource adapter, such as connection or transaction. This section explains the contracts defined in both versions 1.0 and 1.5 of JCA.

JCA 1.0

JCA 1.0 was the first specification released in November 2000. On a broader level, it defined two types of contracts, namely system-level and application-level contracts.

System-level contracts define communication and handshaking between the resource adapter and the J2EE application server, whereas application-level contracts define the communication between a client application and a resource adapter. These contracts are transparent to the clients of a resource adapter.

The resource adapter Page 4 of 37 © Copyright IBM Corporation 1994, 2008. All rights reserved. ibm.com/developerWorks developerWorks®

System-level contracts (alternatively called SPIs) define various contracts such as:

• Connection management: Defines the communication between a resource adapter and a J2EE connection manager (a component residing within a J2EE application server) to support connection pooling. The resource adapter connections to EIS are created during deployment and are pooled to increase scalability and performance. • Transaction management: Supports transaction management and defines the handshaking between the transaction manager and the resource adapter. It supports two types of transactions: local and XA. Local transactions, as the name suggests, are local to an EIS and its resource adapter. XA transactions are external to EIS and are managed by the application server transaction manager. An XA transaction is capable of encapsulating multiple calls to different resources, such as different EIS systems, databases, and so on. They support a two-phase commit protocol. • Security management: Supports different security mechanisms, such as authentication and authorization, between a resource adapter and the J2EE application server. Application-level contracts (alternatively called CCIs) define a set of client APIs for application components, such as EJB and application clients, to interact with the resource adapter. They support synchronous communication between a resource adapter and a client application originated by the client application.

JCA 1.5

JCA 1.5, the latest specification, defines the missing aspects of JCA 1.0. In addition to the JCA 1.0 contracts mentioned previously, JCA 1.5 defines management contracts and inbound contracts. Let's take a look at these new contracts.

JCA 1.5 has a different categorization for the supported contracts as listed below.

• Outbound contracts: Three contracts specified in the JCA 1.0 section -- connection, transaction, and security management. These contracts mainly support synchronous outbound communication from a resource adapter to an EIS and back. • Inbound contracts: Support inbound connectivity from EIS to a resource adapter by providing capability to plug in message providers and import transactions. • Message inflow: Provides support for interaction between a resource adapter and any message provider. This contract has extended the definition of an MDB. An MDB is no longer limited to receiving JMS messages. According to this contract, an MDB is capable of listening to any type of messages from a resource adapter.

The resource adapter © Copyright IBM Corporation 1994, 2008. All rights reserved. Page 5 of 37 developerWorks® ibm.com/developerWorks

• Transaction inflow: Supports importing transactions from an EIS to a resource adapter. After importing the transactions, the resource adapter should propagate these transactions to the application server to enable crash recovery, completing transactions, and so on. This contract provides the capability to ensure the ACID (atomicity, consistency, isolation, and durability) properties are preserved by the application server for an incoming transaction. • Management contracts: Support adapter life cycle management and thread management. • Life cycle management: Defines life cycle methods for a resource adapter similar to servlets or an EJB. These methods are invoked by the application server at various events, like during adapter deployment and server shutdown. • Work or thread managements: Specifies a safe mechanism for the J2EE application server to handle and manage resource adapter threads. It also enables the application server to provide thread pooling or reusability of threads for better performance, as threads could be resource intensive. Figure 1 illustrates JCA contracts and the relationship between the resource adapter and other J2EE components.

Figure 1. Resource adapter

For a more detailed description of various JCA contracts, check the specifications listed in the Resources section. Next you'll take a look at the different types of resource adapters.

The resource adapter Page 6 of 37 © Copyright IBM Corporation 1994, 2008. All rights reserved. ibm.com/developerWorks developerWorks®

Section 4. Resource adapter types

The two basic types of resource adapters are outbound and inbound.

Outbound resource adapter

An outbound resource adapter supports synchronous communication between the resource adapter and the EIS and back. The resource adapter first sends a request to the EIS, the EIS processes the request and builds a response, and then it sends the response back to the resource adapter, as illustrated in Figure 2.

Figure 2. Synchronous communication between resource adapter and EIS

As shown in Figure 2, after sending a request to EIS (1), the resource adapter waits to receive the response from EIS (2). This is a bidirectional synchronous communication.

Inbound resource adapter

An inbound resource adapter supports asynchronous communication between EIS and a resource adapter with data coming into a resource adapter -- hence the name inbound. In most cases, the resource adapter registers with the EIS as a listener for specific events on the EIS (for example, when a new customer account is added). When the event occurs, back-end EIS notifies all the registered listeners about the new customer account. This process is subject to EIS capability to provide a mechanism to register listeners. Figure 3 demonstrates the flow of messages between EIS and a resource adapter.

Figure 3. Asynchronous communication between resource adapter and EIS

In this case, a resource adapter spawns a thread to register and listen to the events

The resource adapter © Copyright IBM Corporation 1994, 2008. All rights reserved. Page 7 of 37 developerWorks® ibm.com/developerWorks

on EIS, and they should conform to the work management contracts. The adapter is not waiting to receive a response from EIS; therefore, this is an asynchronous communication between EIS and the adapter.

Both types of resource adapters can coexist with an application, depending on your application needs. You can use either outbound or inbound or both types of resource adapters.

Section 5. Application design

Now that you're familiar with the JCA, its contracts, and the different types of adapters, you can develop the missing piece of the sample application, which is a JCA resource adapter. In this section, you'll build a JCA 1.5-based resource adapter that communicates with Apache James and deploys this adapter in Geronimo. The James adapter will process all of the authorized purchase-request e-mails in James sent by the fictional company Foo, Inc's employees.

Refer back to the Application design section in Part 1, which will help you choose the correct type of adapter and identify the responsibilities for the resource adapter.

Use cases and components refresher

In Part 1 and Part 2, you built various J2EE components for the sample application to take care of some of the following requirements:

1. The sample application is required to process the incoming purchase-request e-mails from employees and move them to a specified folder that's accessible by the purchasing department.

2. The application then reads the requests and checks that the employee is indeed from Foo, Inc.

3. Once authorized, a new purchase order is created for submission to the vendor.

In Part 1, you built an MDB, which, upon receiving a JMS message, invokes an entity EJB to create a new purchase order in the database (requirement 3, above.)

In Part 2, you wrote an e-mail application (mailet and matcher) and deployed it in Apache James. This e-mail application processes all of the incoming e-mails and checks to make sure the e-mail senders are authorized (requirement 1, above.)

In this installment, you'll build the component of the sample application that ties the concepts in both Part 1 and Part 2 together. You'll build a resource adapter for the

The resource adapter Page 8 of 37 © Copyright IBM Corporation 1994, 2008. All rights reserved. ibm.com/developerWorks developerWorks®

Apache James server (EIS), which will be deployed in the Geronimo server. Your James adapter will process all of the purchase-request e-mails authorized by the e-mail application. The use case and requirements for building a resource adapter are:

• Use case: Check for purchase-request e-mails. • Requirement: The application will constantly check for new purchase-request e-mails that are waiting to be processed. Now that you've identified the business process for your adapter, you can evaluate what type of adapter suits your needs.

Outbound or inbound adapter?

As per the application requirements, your resource adapter component has to interact with an MDB. After receiving e-mails, the resource adapter needs to send a message to the MDB. The MDB will then send a request to an entity EJB to create a new entry in the Purchase Order database.

This interaction between a resource adapter and an MDB is clearly supported by the message inflow contract for an inbound adapter. Now that you've decided upon the type of adapter, you can develop an inbound adapter.

Section 6. Building the inbound adapter

Your inbound adapter, running within Geronimo, should be able to register with the Apache James server and receive all the authorized e-mails. After receiving the e-mails, the adapter should then send a message to the MDB with a request to create a new purchase order.

As mentioned earlier, registering the adapter with EIS is possible only if EIS supports it. In this case, James uses a POP3 protocol, which doesn't support registering listeners (and in other cases where EIS doesn't allow registering listeners). The resource adapter will have to poll James (EIS) at regular intervals to check if there are any new e-mail messages in an inbox. This is called a Pull/Poll mechanism.

During deployment in the Geronimo server, the resource adapter will start a polling thread to check the e-mail inbox on James periodically at regular intervals. The life cycle and work management contracts define this process. To build an inbound adapter, you have to implement the work management, life cycle management, and message inflow contracts related to these contracts.

Let's take a look at the basic interfaces and adapter implementations defined by

The resource adapter © Copyright IBM Corporation 1994, 2008. All rights reserved. Page 9 of 37 developerWorks® ibm.com/developerWorks

these contracts.

Life cycle management contract

The life cycle management contract defines a set of life cycle methods for a resource adapter. The J2EE application server invokes these methods at various events, such as adapter deployment, server shutdown, and so on.

ResourceAdapter interface

The resource adapter will implement the javax.resource.spi.ResourceAdapter interface as a Java bean and specify the implementation class name in the descriptor (ra.xml).

The various life cycle methods defined in the ResourceAdapter are:

• start(BootstrapContext): The application server calls the start method while deploying the resource adapter or application server startup. The resource adapter can get the WorkManager from the BootstrapContext and start the work either in start method or when an endpoint is activated. The message endpoint in this case is an MDB deployed in an application server that consumes messages from the resource adapter. • stop(): The stop method is called when the adapter is undeployed or during application server shutdown. • endpointActivation(): The application server invokes this method when a message endpoint is activated (for example, an MDB is initialized). • endpointDeactivation(): The application server invokes this method when a message endpoint is deactivated. The examples.po.adapter.spi.JamesResourceAdapter implements all of the life cycle methods defined in the ResourceAdapter interface, as shown in Listing 1.

Listing 1. Snippet from JamesResourceAdapter

public JamesResourceAdapter() { super(); } public void start(BootstrapContext arg0) throws ResourceAdapterInternalException { ilog("In start()"); workMgr = arg0.getWorkManager(); } public void stop() { ilog("In stop()"); }

The resource adapter Page 10 of 37 © Copyright IBM Corporation 1994, 2008. All rights reserved. ibm.com/developerWorks developerWorks®

public void endpointActivation(MessageEndpointFactory arg0, ActivationSpec arg1) throws ResourceException { ilog("In endpointActivation"); emailWork = new JamesWork(emailSpec.getEmailUser(), emailSpec .getEmailPassword(), emailSpec.getEmailHost(), arg0); //starts polling the inbox workMgr.startWork(emailWork); } public void endpointDeactivation(MessageEndpointFactory arg0, ActivationSpec arg1) { //stops polling email inbox emailWork.release(); }

As shown in Listing 1, the JamesResourceAdapter initializes and starts polling the e-mail inbox on the James server when a message endpoint is activated.

To deploy a resource adapter, two descriptors are required (similar to EJB): ra.xml (standard J2EE descriptor) and geronimo-ra.xml (application server specific descriptor, in this case the application server is Apache Geronimo). Now take a look at the part of the deployment descriptor (geronimo-ra.xml) that configures the JamesResourceAdapter (see Listing 2).

Listing 2. ra.xml for JamesResourceAdapter

examples.po.adapter.spi.JamesResourceAdapter

Note how ra.xml defines the implementation class for ResourceAdapter in Listing 3.

Listing 3. geronimo-ra.xml for JamesResourceAdapter

James Inbound Resource Adapter DefaultWorkManager

The geronimo-ra.xml descriptor defines a default WorkManager that is passed over to the JamesResourceAdapter along with BootStrapContext when it's started.

ActivationSpec interface

The resource adapter should implement the javax.resource.spi.ActivationSpec interface as a Java bean. It contains EIS-specific properties to activate a message endpoint. These properties are

The resource adapter © Copyright IBM Corporation 1994, 2008. All rights reserved. Page 11 of 37 developerWorks® ibm.com/developerWorks

specified in the adapter deployment descriptor (ra.xml).

The Validate() method can be used to validate the activationspec properties. It's typically used by tools like the deploy tool.

The examples.po.adapter.spi.JamesActivationSpec has a set of getter and setter methods for the properties in Listing 4.

Listing 4. Snippet of JamesActivationSpec

public class JamesActivationSpec implements ActivationSpec, Serializable { private String emailUser = null; private String emailPassword = null; private String emailHost = null; private ResourceAdapter rar = null;

The ra.xml defines all of the properties required by ActivationSpec to initialize a message endpoint (see Listing 5).

Listing 5. Snippet from ra.xml displaying properties for ActivationSpec

examples.po.mdb.JamesMessageListener examples.po.adapter.spi.JamesActivationSpec emailHost emailUser emailPassword

The properties for JamesActivationSpec are e-mail host, e-mail user name, and e-mail password. These properties are required to poll the e-mail inbox on the James Server.

Work management contract

Now you need to implement the work management contract.

Work interface

The resource adapter Page 12 of 37 © Copyright IBM Corporation 1994, 2008. All rights reserved. ibm.com/developerWorks developerWorks®

The javax.resource.spi.work.Work interface models a work entity that can be managed by the WorkManager. This is a thread and is used by the James resource adapter for polling for e-mails on the James server.

The Work interface contains the following two methods:

• release(): This method marks completion of work. • run(): Since Work is a thread, it has a run() method, which has the actual execution of the thread. examples.po.adapter.spi.JamesWork is a thread that is used to poll for e-mails on the James server. It has a set of getter and setter methods for the properties in Listing 6.

Listing 6. Snippet of JamesWork

public void run() { // periodically check for unread . try { while (poll) { ilog("Polling for new emails ... "); // read the messages and delete them inbox.open(Folder.READ_WRITE); int totalMessages = inbox.getMessageCount(); if (totalMessages == 0) { ilog(inbox + " is empty"); } else { // Get Messages Message[] messages = inbox.getMessages(); // Process each message for (int i = 0; i < messages.length; i++) { MimeMessage mime = (MimeMessage) messages[i]; processMsg(mime); mime.setFlag(Flags.Flag.DELETED, true); } } // close inbox and main store inbox.close(true); mailStore.close(); // Wait ilog("Waiting for 15 sec ...... "); Thread.sleep(15000); }// end while } catch (Exception e) { e.printStackTrace(); throw new IllegalStateException("" + e); } }// end run private void processMsg(MimeMessage msg) { ilog("In Process Message : " + msg); try { MessageEndpoint msgEndPoint = factory.createEndpoint(null);

The resource adapter © Copyright IBM Corporation 1994, 2008. All rights reserved. Page 13 of 37 developerWorks® ibm.com/developerWorks

ilog("Message End Point is: " + msgEndPoint); // msgEndpoint is an app server proxy if (msg != null) { JamesMessage email = new JamesMessage();

PurchaseOrderBean pobean = createPurchaseOrderBean(msg); //set PurchaseOrder bean email.setPoBean(pobean); //ilog("Before posting Message to End Point"); ((JamesMessageListener) msgEndPoint).onMessage(email); ilog("Message is posted to End Point"); } } catch (Exception e) { e.printStackTrace(); } }

As shown in Listing 6, the run() method periodically polls the e-mail inbox on the James server. If it finds e-mails, it calls processMsg(), which creates a new message named JamesMessage. It also parses the e-mail content to create a PurchaseOrderBean, createPurchaseOrderBean(). It then invokes the onMessage() message on the endpoint.

WorkManager interface

The resource adapter does not need to implement the javax.resource.spi.work.WorkManager interface. For the purposes of this tutorial, you'll use the DefaultWorkManager in Geronimo. The work manager implementation class is set in the deployment descriptor (ra.xml).

Figure 4 explains the sequence of events and flow of data during inbound resource adapter deployment.

Figure 4. Sequence diagram for resource adapter deployment

The resource adapter Page 14 of 37 © Copyright IBM Corporation 1994, 2008. All rights reserved. ibm.com/developerWorks developerWorks®

During adapter deployment, the application server creates a new instance of ResourceAdapter and calls the start() method. ResourceAdapter may initialize any resources required for processing later. In the start() method, ResourceAdapter receives the BootStrapContext object, which can be used to retrieve the WorkManager. ResourceAdapter can use WorkManager to submit work, which in turn starts the work thread. The stop() method of ResourceAdapter is invoked when either the application server is shutting down or the resource adapter is being undeployed.

Message inflow contract

To implement a message inflow contract, your James resource adapter defines a custom MessageListener named JamesMessageListener and a custom message type called JamesMessage. You'll modify PurchaseOrderMDB to listen to messages of a custom type defined by the James resource adapter.

Message listener and message type

The James resource adapter defines a custom message listener name, JamesMessageListener, as shown in Listing 7. It also defines a custom message type called JamesMessage. The message listener is listening for messages from the James resource adapter, which in this case is PurchaseOrderMDB. You have to implement the customer message listener to receive messages from the resource

The resource adapter © Copyright IBM Corporation 1994, 2008. All rights reserved. Page 15 of 37 developerWorks® ibm.com/developerWorks

adapter.

Listing 7. JamesListener

public interface JamesMessageListener { public void onMessage(JamesMessage email); }

The JamesMessageListener interface defines only one onMessage() method. This method will be invoked by the James resource adapter (see Listing 8).

Listing 8. JamesMessage

public class JamesMessage { private PurchaseOrderBean poBean = null; public JamesMessage() { super(); } public PurchaseOrderBean getPoBean() { return poBean; } public void setPoBean(PurchaseOrderBean poBean) { this.poBean = poBean; }

JamesMessage has the PurchaseOrderBean, which can be passed to the entity bean to create a new purchase order entry in the database.

Message-driven bean

An MDB is a message endpoint that will be invoked by the application server (Geronimo). Revisit your PurchaseOrderMDB that you built in Part 1 of this series. You implemented PurchaseOrderMDB to listen for JMS messages. To implement message inflow, you'll modify the PurchaseOrderMDB to listen for messages of a custom listener type, say JamesMessageListener. Listing 9 shows the changes to be implemented for PurchaseOrderMDB.

Listing 9. Revisions for PurchaseOrderMDB

Part 1: public class PurchaseOrderMDB implements MessageDrivenBean, MessageListener { Revised: public class PurchaseOrderMDB implements MessageDrivenBean, MessageListener, JamesMessageListener {

Part 1: There was no method for JamesMessgeListener Revised:

The resource adapter Page 16 of 37 © Copyright IBM Corporation 1994, 2008. All rights reserved. ibm.com/developerWorks developerWorks®

public void onMessage(JamesMessage email) { Logger log = Logger.getLogger("PurchaseOrderMDB"); log.info("Received James Message : "+ email); PurchaseOrderBean poBean = null; try { poBean = email.getPoBean(); log.info("A new Purchase Order will be added to POSystem."); addPurchaseOrder(poBean); } catch (Exception e) { e.printStackTrace(); log.severe(""+e); } }//end onMessage(JamesMessage)

Note the differences among what is shown in Listing 9, what existed in Part 1 of the series, and what you're changing now: PurchaseOrderMDB implements JamesMessageListener and, hence, implements onMessage(JamesMessage). You can find the source file for the modified PurchaseOrderMDB in $part3.zip/src/examples/po/mdb, available from the Download section.

Because you modified PurchaseOrderMDB, you'll have to modify the deployment descriptors accordingly. The two deployment descriptors are ejb-jar.xml and openejb-jar.xml, and are modified as seen in Listing 10.

Listing 10. Changes to MDB deployment descriptors (openejb-jar.xml)

Part 1: PurchaseOrderMDB geronimo.server:J2EEApplication=null,J2EEServer=geronimo, JCAResource=geronimo/activemq/1.0/car,j2eeType=JCAResourceAdapter,name= ActiveMQ RA destination POTopic destinationType javax.jms.Topic ejb/PurchaseOrderEJB PurchaseOrderEJB Revised Part 3: PurchaseOrderMDB James Inbound Resource Adapter

The resource adapter © Copyright IBM Corporation 1994, 2008. All rights reserved. Page 17 of 37 developerWorks® ibm.com/developerWorks

emailHost localhost emailUser authorized-orders emailPassword password

In Listing 10, you'll see how in Part 1, the PurchaseOrderMDB was listening for JMS messages on POTopic, but this has been modified, and the MDB now listens for messages from the James resource adapter.

Let's take a look at the the ejb-jar.xml descriptor (see Listing 11).

Listing 11. ejb-jar.xml

Part 1: PurchaseOrderMDB examples.po.mdb.PurchaseOrderMDB Container javax.jms.Topic Part 3: PurchaseOrderMDB examples.po.mdb.PurchaseOrderMDB examples.po.mdb.JamesMessageListener Container emailHost localhost emailUser authorized-orders emailPassword

The resource adapter Page 18 of 37 © Copyright IBM Corporation 1994, 2008. All rights reserved. ibm.com/developerWorks developerWorks®

config-property-name> password

The ejb-jar.xml descriptor in Part 1 (shown in Listing 11) depicted that PurchaseOrderMDB was listening for JMS messages from a JMS resource -- that is, Topic. In this tutorial, you've modified the descriptor to include JamesMessageListener as the listener type for the MDB. The new descriptor also includes the JamesActivationSpec properties.

Figure 5 explains the sequence of actions that takes place during the deployment of a message endpoint, which in your case is an MDB.

Figure 5. Deploying a message endpoint

As shown in Figure 5, during deployment of an MDB, the J2EE application server instantiates and configures the ActivationSpec using the properties in the deployment descriptor. Later it instantiates the MessageEndpointFactory and calls the endpointActivation() method of ResourceAdapter. This method is basically responsible for delivering the message to the Message consumer.

In your sample application, in the endpointActivation() method in JamesResourceAdapter, you start the JamesWork thread that starts polling for e-mail messages on the James server. If there are any e-mails found on the James server, JamesWork processes the e-mails, as shown in Listing 12.

Listing 12. JamesWork thread snippet of processMsg method

private void processMsg(MimeMessage msg) { MessageEndpoint msgEndPoint = factory.createEndpoint(null);

The resource adapter © Copyright IBM Corporation 1994, 2008. All rights reserved. Page 19 of 37 developerWorks® ibm.com/developerWorks

PurchaseOrderBean pobean = createPurchaseOrderBean(msg); JamesMessage email = new JamesMessage();

//set PurchaseOrder bean email.setPoBean(pobean); ((JamesMessageListener) msgEndPoint).onMessage(email);

JamesWork uses the MessageEndointFactory to create an endpoint (in this case the endpoint is an MDB), then it creates a new PurchaseOrderBean from the e-mail message, sets the PurchaseOrderBean in a new JamesMessage, and then at the end delivers the message to the endpoint by calling the onMessage() method on the MDB.

part3.zip, the download included with this tutorial, contains all the source files (.java) for the James resource adapter, PurchaseOrderMDB, and the descriptors ra.xml and geronimo-ra.xml.

Other than the descriptors (ra.xml and geronimo-ra.xml), there is no additional configuration required for the resource adapter in this tutorial. However, for the entire application to work, take a look at the Configuration sections in Part 1 and Part 2 of this series and make sure Apache James and Geronimo are configured.

Section 7. Deployment

Now that you're all set with configuration, it's time to deploy your sample application. Take a look at the sample application packaging.

Deploying the sample application

You'll deploy your sample application in the form of an .ear file, which stands for Enterprise ARchive. .ear files need two descriptors: application.xml and an application server-specific .xml file (in this case, geronimo-application.xml), as shown in Listing 13.

Listing 13. application.xml descriptor

ExampleApp po-ejb.jar james.rar

As in Listing 13, the .ear file consists of two modules: the EJB and the resource adapter. The resource adapter is packaged as a .rar file, where RAR stands for

The resource adapter Page 20 of 37 © Copyright IBM Corporation 1994, 2008. All rights reserved. ibm.com/developerWorks developerWorks®

Resource Adapter Archive.

Hence, po-ejb.jar consists of PurchaseOrderEJB and PurchaseOrderMDB, whereas james.rar is the James Resource Adapter (see Listing 14).

Listing 14. geronimo-application.xml

po-ejb.jar dds/openejb-jar.xml james.rar dds/geronimo-ra.xml

The geronimo-application.xml descriptor has a reference to the EJB and the connector. It also specifies the location of the Apache Geronimo-specific descriptors, which is in the directory names dds within the .ear file.

Let's start the deployment process.

Step 1: Undeploy Part 1 EJB JAR

If you did not deploy the po-ejb.jar as explained in Part 1, you can skip this step.

1. Undeploy po-ejb.jar that you deployed in Part 1, as shown in Figure 6. Figure 6. Undeploying PurchaseOrderEJB

The resource adapter © Copyright IBM Corporation 1994, 2008. All rights reserved. Page 21 of 37 developerWorks® ibm.com/developerWorks

2. Start Geronimo from $GERONIMO_HOME\bin\ startup.bat.

3. Access the Geronimo console at http://localhost.com:8080/console (the default user ID is system and password is manager).

4. Click EJB JARS on the left side, and you'll see PurchaseOrderEJB.

5. Click Uninstall to undeploy the PurchaseOrderEJB and PurchaseOrderMDB. You'll be deploying these J2EE components as a part of our EAR file.

Step 2: Check POMailet and POMatcher.

Ensure that the e-mail application described in Part 2 is deployed in James and that James is running.

Step 3: Deploy the .ear file

Now that you've confirmed that the Apache James and Geronimo servers are running, you can deploy your po.ear file. This file is located in the $part3.zip/deploy dir.

The resource adapter Page 22 of 37 © Copyright IBM Corporation 1994, 2008. All rights reserved. ibm.com/developerWorks developerWorks®

1. Access the Geronimo server console at http://localhost:8080/console (the default user ID is system and password is manager).

2. Click Deploy New on the left side, and you'll see something similar to Figure 7. Figure 7. Deployment console for Apache Geronimo

3. Click the Browse button next to Archive, and select the po.ear file from $part3.zip/deploy dir, as shown in Figure 8. Figure 8. Deployment console for Apache Geronimo

The resource adapter © Copyright IBM Corporation 1994, 2008. All rights reserved. Page 23 of 37 developerWorks® ibm.com/developerWorks

4. After selecting the po.ear file, click Install. Apache Geronimo will now deploy all of the modules listed in the descriptors in the po.ear file, and if the deployment was successful, you'll see a message, as shown in Figure 9. Figure 9. Successful deployment for EAR in Apache Geronimo

The resource adapter Page 24 of 37 © Copyright IBM Corporation 1994, 2008. All rights reserved. ibm.com/developerWorks developerWorks®

After successfully deploying the po.ear file, you'll see some logs on the Geronimo console, as shown in Figure 10.

Figure 10. Geronimo console after deployment

The resource adapter © Copyright IBM Corporation 1994, 2008. All rights reserved. Page 25 of 37 developerWorks® ibm.com/developerWorks

As you can see, upon deployment of the adapter and its endpoint (PurchaseOrderMDB), the JamesResourceAdapter endpointActivated() method is called by Geronimo, and your adapter has started polling for e-mail messages on the James server for user authorized-orders periodically (every 15 seconds). But, as seen in Figure 10, the INBOX is empty message indicates that there are no e-mails in the inbox for the user named authorized-orders.

You've successfully deployed the sample application, which consists of MDBs, entity EJBs, and a resource adapter for Apache James. Now you can create a client, or a test program, to test your application.

Section 8. Test the application

You don't have to write a brand new test client. Instead, you'll modify the EmailClient.java client that you wrote for Part 2. EmailClient has the capability to send e-mails and read e-mails from a user's inbox.

The resource adapter Page 26 of 37 © Copyright IBM Corporation 1994, 2008. All rights reserved. ibm.com/developerWorks developerWorks®

You'll modify this EmailClient to send an e-mail message that has the purchase request data as the body of the e-mail.

E-mail message format

First, you should decide on a standard format so that it will be easy for the James resource adapter to parse the e-mail message and construct a PurchaseOrderBean to send it to PurchaseOrderMDB. The format for the e-mail message is depicted in Listing 15.

Listing 15. E-mail message format

Item=Pens; Description=Low on stock for Marketing Department; Price=10; Quantity=250;

Client

The client program EmailClient.java (see Listing 16) provides methods to send e-mails.

You can look at the entire client program in $part3.home/src/examples/po/test dir.

Listing 16. E-mail client's sendEmail method

/** * Sends an email message * * @param from Sender's email address * @param to Recipient's email address * @param subject Email Subject * @param content Email Message Content * @throws MessagingException */ public void sendEmail(String from, String to, String subject, String content) throws MessagingException { Session session = createSession(host, null, null); MimeMessage msg = new MimeMessage(session); msg.setFrom(new InternetAddress(from)); msg.addRecipients(Message.RecipientType.TO, to); msg.setSubject(subject); msg.setText(content); Transport.send(msg); System.out.println("Email message is successfully sent to " + to); }

In the sendEmail method, you create a new e-mail message (MimeMessage) with the specified sender e-mail address (from), recipient e-mail address (to), subject

The resource adapter © Copyright IBM Corporation 1994, 2008. All rights reserved. Page 27 of 37 developerWorks® ibm.com/developerWorks

(subject), and message body (content). You call Transport.send() to actually deliver the message to the recipient's inbox. You'll use this method to send purchase request e-mails.

Now take a look at the main() method that constructs the e-mail message, as shown in Listing 17.

Listing 17. E-mail client's main method

public static void main(String a[]) throws Exception { //Purchase Order Properties String ITEM = "Pens"; String DESCRIPTION = "Low on stock for Marketing Department"; String UNITPRICE = "2"; String QUANTITY="250"; //check if from and to have been provided String mode = System.getProperty("mode"); String host = null; String user = null; String password = null; String from = null; String to = null; String subject = "Purchase Request"; Calendar cal = Calendar.getInstance(); String content = "Item="+ITEM+";"+ "Description="+DESCRIPTION+";"+ "Price="+UNITPRICE+";"+ "Quantity="+QUANTITY; . . . . EmailClient client = new EmailClient(host); if(isSend) client.sendEmail(from, to, subject, content); else client.readInbox(user, password); }//end main

The main() method expects few command-line parameters for both sending and reading e-mails. As seen in Listing 17, the sendEmail() method needs e-mail host, from, and to values and readInbox() needs e-mail host, user name, and password for an e-mail account.

The main() method is responsible for constructing an e-mail message with the specific format in Listing 15, and then sending an e-mail to [email protected]. This e-mail will be picked up by POMailet/POMatcher, and if the sender is authorized, the e-mail will be moved to a different folder named authorized-orders.

Now the James resource adapter is polling on this folder, and once it detects an e-mail, it will pick it up, parse the e-mail message, construct a PurchaseOrderBean, and send a JamesMessage to PurchaseOrderMDB. This MDB will then invoke the PurchaseOrderEJB, which is an entity bean, and it will create a new purchase order entry in the Geronimo Derby database table.

The resource adapter Page 28 of 37 © Copyright IBM Corporation 1994, 2008. All rights reserved. ibm.com/developerWorks developerWorks®

Run tests

You'll use the runSendEmail.cmd script provided in the part3.zip file to test the entire application flow. If you configured your application as explained in this tutorial, you'll only have to modify JAVA_HOME to run these tests.

Now, start the Apache James and Apache Geronimo servers, if they are not already running.

Before running the test, take a look at the PurchaseOrder table (see Figure 11).

Figure 11. PurchaseOrder table contents before testing

As you can see, there are no entries in the PurchaseOrder table.

Now you can run the runSendEmail.cmd script to send purchase order e-mails to [email protected] (this address can be modified in the runSendEmail.cmd by changing EMAIL_TO parameter) from e-mail address [email protected] (remember [email protected] is an authorized sender).

You'll see a few logs after running runSendEmail.cmd, as shown in Figure 12.

The resource adapter © Copyright IBM Corporation 1994, 2008. All rights reserved. Page 29 of 37 developerWorks® ibm.com/developerWorks

Figure 12. Testing application by running runSendEmail.cmd

If you see a message as shown in Figure 12, it means the e-mail was delivered successfully. This incoming e-mail in the James server will be processed by your POMatcher-POMailet.

The James server first calls POMatcher's match() method. Since the sender [email protected] is an authorized sender, the service() method of POMailet is invoked, and the e-mail should have been forwarded to [email protected]. You must be wondering why POMatcher match() is called again (see Figure 13).

Figure 13. Console log for James server

The resource adapter Page 30 of 37 © Copyright IBM Corporation 1994, 2008. All rights reserved. ibm.com/developerWorks developerWorks®

POMatcher match() is called again because your POMailet's service() method sends the e-mail to [email protected]. This e-mail is treated as any other incoming e-mail within the James server, so the server invokes the POMatcher match() method.

Tip: This is the reason why you change the from to [email protected] or any unauthorized sender before forwarding the e-mail to [email protected] to avoid an indefinite recursive loop. This is a little workaround, because the POP3 protocol does not support moving e-mails between folders. (IMAP supports this feature.)

Now, because the sender's e-mail address is [email protected], it's not an authorized sender, so this forwarded e-mail is not processed by POMailet.

Check to see if the e-mail was indeed delivered to [email protected] by POMailet.

Run the runReadEmail.cmd, and you'll see the results shown in Figure 14.

Figure 14. Display the e-mails

The resource adapter © Copyright IBM Corporation 1994, 2008. All rights reserved. Page 31 of 37 developerWorks® ibm.com/developerWorks

The e-mails in the authorized-orders inbox are displayed.

If you check your Geronimo console, you'll see log messages from JamesWork, as shown in Figure 15.

Figure 15. Geronimo console after sending an e-mail

The resource adapter Page 32 of 37 © Copyright IBM Corporation 1994, 2008. All rights reserved. ibm.com/developerWorks developerWorks®

The e-mail message is received by the JamesWork thread running in Geronimo and is parsed into Item, Description, Unit Price, and Quantity to create a PurchaseOrderBean. This bean is then wrapped within a JamesMessage and sent to the PurchaseOrderMDB, which invokes the PurchaseOrderEJB to create a purchase order in the database.

View the results

Now you can check to see if the PurchaseOrderEJB entered a new purchase order in the Derby database. If you go to the Geronimo Web console and access the DBManager displayed in the left navigation pane, you can view the contents of the PurchaseOrder table, as shown in Figure 16.

Figure 16. Geronimo Web console DBManager

The resource adapter © Copyright IBM Corporation 1994, 2008. All rights reserved. Page 33 of 37 developerWorks® ibm.com/developerWorks

Bingo! There you see an entry for a purchase order in the table.

Section 9. Summary

Congratulations! Your sample application is now complete. In this tutorial series, you learned to build integrated solutions using MDBs, entity beans, mailets, matchers, and resource adapters. You also learned various configurations and deployments in Apache Geronimo and the James server. Now consider yourself a Java guru!

The resource adapter Page 34 of 37 © Copyright IBM Corporation 1994, 2008. All rights reserved. ibm.com/developerWorks developerWorks®

Downloads

Description Name Size Download method Part 3 source code part3.zip 1088KB HTTP

Information about download methods

The resource adapter © Copyright IBM Corporation 1994, 2008. All rights reserved. Page 35 of 37 developerWorks® ibm.com/developerWorks

Resources

Learn • Refer to the JCA 1.0 specification and the JCA 1.5 specification. • Learn more about Apache James. • Read "Integrate remote enterprise information systems with JCA, JMS, and Web services" (developerWorks, March 2004) to learn how to integrate legacy transactions running on a geographically remote enterprise information systems (EIS) into your business processes. • Learn how the various levels of transaction support provided by different EISs and resource adapters can affect application design in "Understanding JCA transactions" (developerWorks, October 2004). • See "Build JCA-compliant resource adapters with WebSphere Studio Application Developer" (developerWorks, August 2003) to learn how to use IBM WebSphere Studio Application Developer to help debug, unit test, build, and deploy a JCA-compliant resource adapter. • Discover the criteria for choosing among J2C Connector Architecture (JCA), Java Message Service (JMS), and Web services implementations in this developerWorks article (March 2003). • Learn to hone the deployment of your Apache Geronimo distribution to the necessary core services and applications in "Optimize your Apache Geronimo distribution" (developerWorks, May 2006). • Get an overview of the JMS in "Introducing the Java Message Service" (developerWorks, June 2004). • Take a look at helpful online and print documentation about Geronimo, including articles and interviews. • Find out how to get involved with Apache Geronimo's community. • Check out the tutorials in this three-part series, which teach you all sorts of technologies you can use to develop Geronimo J2EE applications: •"The Apache Geronimo machine shop sampler, Part 1: Servlets, JSPs, security, and JCA" (developerWorks, March 2006) •"The Apache Geronimo machine shop sampler, Part 2: Data sources, JDBC, and Web services" (developerWorks, April 2006) •"The Apache Geronimo machine shop sampler, Part 3: EJBs: Bean-managed persistence and container-managed persistence" (developerWorks, April 2006)

• Visit the developerWorks Open source zone for extensive how-to information, tools, and project updates to help you develop with open source technologies and use them with IBM's products.

The resource adapter Page 36 of 37 © Copyright IBM Corporation 1994, 2008. All rights reserved. ibm.com/developerWorks developerWorks®

• Check out the developerWorks Apache Geronimo project area for articles, tutorials, and other resources to help you get started developing with Geronimo today. • Get the IBM Support for Apache Geronimo offering, which lets you develop Geronimo applications backed by world-class IBM support. • Find helpful resources for beginners and experienced users at the Get started now with Apache Geronimo section of developerWorks. • Get involved in the developerWorks community by participating in developerWorks blogs. • Browse all the Apache articles and free Apache tutorials available in the developerWorks Open source zone. • Browse for books on these and other technical topics at the Safari bookstore. Get products and technologies • Download Apache Geronimo. • Get the EJB 2.1 specification. • Innovate your next open source development project with IBM trial software, available for download or on DVD. • Download your free copy of IBM WebSphere® Application Server Community Edition V1.0 -- a lightweight J2EE application server built on Apache Geronimo open source technology that is designed to help you accelerate your development and deployment efforts. Discuss • Participate in the discussion forum for this content. • Stay up to date on Geronimo developments at the Apache Geronimo blog. • Get involved in the developerWorks community by participating in developerWorks blogs.

About the author

Madhuri Suda Madhuri Suda graduated with a master's degree in computer science from Illinois Institute of Technology in 2002. She has been working as a Java/Java EE programmer since 1999.

The resource adapter © Copyright IBM Corporation 1994, 2008. All rights reserved. Page 37 of 37