WebSphere and Message Driven Beans

Size: px
Start display at page:

Download "WebSphere and Message Driven Beans"

Transcription

1 WebSphere and Message Driven Beans 1 Messaging Messaging is a method of communication between software components or among applications. A messaging system is a peer-to-peer facility: A messaging client sends messages to, and/or receives messages from, any other clients. Every client connects to one messaging agent which provides facilities for creating, sending, receiving, and reading messages. Messaging enables distributed communication that is loosely coupled. A component sends a message to a destination, and the recipient can retrieve the message from the destination. However, the sender and the receiver are not necessary to communicate each other at the same time. In fact, the sender does not need to know anything about the receiver; nor does the receiver need to know anything about the sender. The sender and the receiver need to know only which message format and which destination are used. In this respect, messaging differs from tightly coupled technologies, such as Remote Method Invocation (RMI), which require an application to know a remote application s methods. Unlike , messaging is used for communication between software applications or software components. 2 JMS( Java Message Service ) The Java Message Service is a set of Java APIs that allows applications to create, send, receive, and read messages. The JMS API defines a set of interfaces and associated semantics that allow programmers write messaging components in Java that

2 communicate with other messaging implementations. JMS API Programming Model Administered Objects: Administered objects are preconfigured JMS objects created by an administrator that consists of two components connection factories and destinations Connections Sessions Message Producers Message Consumers Messages A connection factory is the object for clients to create a connection to a provider. A connection factory encapsulates a set of connection configuration parameters that has been defined by an administrator. Each connection factory is an instance of the ConnectionFactory, QueueConnectionFactory, or Topic-ConnectionFactory interface. Figure 1 JMS Programming Architecture

3 A destination is the object that specifies the target where the producers deliver the created message to and the consumers get the message from. Two kinds of destinations are Queue and Topic. In Queue model, each message must be gotten by zero or one consumer. In Topic model each message can be processed by many consumers, the message is stored in memory until all consumers have gotten it. Figure 2.2 Queue / Topic destination A connection creates a virtual connection on open TCP/IP socket between a client and a provider service daemon. A session is a single-threaded context for producing and consuming messages. The sessions are created by a connection. A message producer implements the MessageProducer interface that is created by a session and used for sending messages to a destination. A message consumer is an object that is created by a session and implements the MessageConsumer interface in order to receive messages sent to a destination which can be either a Queue or a Topic. The purpose of a JMS application is to create and to deliver messages that can then be used by other components. A JMS message has three parts: a header, properties, and a body. Only the header is absolutely necessarily, the other 2 parts can be absence in

4 one message. A JMS message header has a number of predefined fields that are used by clients and providers to identify and to route messages. Each header field has setter and getter methods itself. Table 1 shows all the fields and the place where the fields are setted. Header Field JMSDestination JMSDeliveryMode JMSExpiration JMSPriority JMSMessageID JMSTimestamp JMSCorrelationID JMSReplyTo JMSType JMSRedelivered Set By send or publish method send or publish method send or publish method send or publish method send or publish method send or publish method Client Client Client JMS provider Table 1 Properties of Message Header If we have additional information to set in a message for other components, we could use Message Properties, for an example of needing a property for a message selector. The body contains the content of a message. Eevey messsage content must obey one pre-defined message format, also named message type, which allows software components to send and to receive data in different forms. Table 2 shows the message types. Message Type TextMessage Body Contains A java.lang.string object

5 MapMessage A set of name-value pairs, with names as String objects and values as primitive types in the Java programming language. The entries can be accessed sequentially by enumerator or randomly by name. The order of the entries is undefined. BytesMessage A stream of uninterpreted bytes. This message type is for literallyencoding a body to match an existing message format StreamMessage A stream of primitive values in the Java programming language, filledand read sequentially. ObjectMessage Message A Serializable object in the Java programming language. Nothing. Composed of header fields and properties only. This message type is useful when a message body is not required. Table 2 JMS Message Types 3 MDB ( Messsage Driven Bean ) A message-driven bean is an asynchronous message consumer. In J2EE a MDB acts normally as a consumer and implements the listener interface that has only one method onmessage( ) according the JMS standard. A MDB doesn t provide a client interface and can only be performanced passively. It listens a Queue/ Topic and does nothing until a message is delivered to it. 4 Developing a message-driven bean application Before the developing make sure that you have installed a WebSphere Application Server 6.1 ( WAS6.1) with EJB3 feature pack and Rational Application Developer V 7.5 ( RAD7.5 ) on your system.

6 4.1 Configuration in WAS6.1 Open a Browser and input in the address bar is the default port for WAS6.1, if you don t know which port does your WAS use, look it up in the file <was-home>/ AppServer\profiles\AppSrv01\properties\ portdef.props, where <was-home> is the WAS Install-Path Creating a service integration bus Select Service integration Buses, and click New. Input MDBSIBus as name and deselect the Bus security. (Figure ) Figure Creating a service integration bus Figure Creating a service integration bus Click Next and then click Finish to confirm the MDBSIBus configuration. Note: After each change you must click Save to store all changes in WAS. This

7 will not be mentioned again for the future Creating the messaging engine Figure Creating a messaging engine Click MDBSIBus to enter the properties configuration page(figure ). Click Bus members in the Topology section. Click Add and select server1 in the Server drop-down menu. Click Next. Select File store, and click Next. Change the default log size to 20 MB, the minimum permanent and temporary store size to 20 MB, and the maximum to 100 MB. Click Next. Click Finish. Go back to the MDBSIBus panel, click Messaging engines to list all available messaging engines for the MDBSIBus( Figure ).

8 Figure Creating a messaging engine Creating a destination Figure Creating a destination Back to the MDBSIBus panel and select Destinations( Figure ). Click New. Select Queue and click Next (Figure ). Give MDBQueue as Identifier and click Next

9 Ensure that the queue is assigned to the bus member MDBSIBus and click Next. Click Finish in the confirmation panel. Figure Creating a destination Configuring the JMS provider Now we begin to set configuration of the JMS provider and to define a queue connection factory and a queue that matches the JNDI name used in the servlet. In addition, we have to define an activation that matches the MDB: select Resources JMS JMS providers. click the Default messaging provider at the Server level.( Figure ) Figure Select Default message provider

10 Figure Properties Configuration Configurate the properties Queue connecton factories, Queues and Activation specifications( Figure ) Click Queue connection factories. Click New. Enter MDBQueueCF as name and jms/messagequeuecf as JNDI name. Select MDBSIBus for bus name. For Provider endpoints, enter localhost:7276:bootstrapbasicmessaging, where 7276 is the default SIB_ENDPOINT_ADDRESS port of the server. If you don t know which port is used in your WAS, see the file <was-home>\appserver\profiles\appsrv01\properties\ portdef.props, where <was-home> is the WAS Install-Path. Click OK( Figure ).

11 Figure Queue connection factories Configuration Back to the Default messaging provider page, click Queues.(Figure ) Click New. Type MDBQueue as name and jms/messagequeue as JNDI name. Select MDBSIBus for bus name, MDBQueue as queue name, and click OK. Figure Queue Configuration

12 Back to the Default messaging provider page, click Activation specifications (Figure ) Click New. set MDBActivationSpec as name and jms/mdbqueueactivationspec as JNDI name. Select Queue as destination type and input jms/messagequeue as Destination JNDI name. Select MDBSIBus for bus name and click OK. Figure Activation specification Configuration Restart the server to active the messaging engine. 4.2 Creating an enterprise application Creating an Enterprise Application Project Start RAD7.5 and then create an Enterprise Application Project named MDBSampleEAR to contain an EJB Project and a Dynamic Web Application project. (see figure ). In the next window select Generate Deployment Descriptor and click Finish

13 Figure Creating an Enterprise Application project Creating an EJB Project Create a new EJB Project named MDBSampleEJB as part of the MDBSampleEAR enterprise application, and choose 3.0 as the EJB Module Version( Figure ) in the next dialog deselect the option Create an EJB Client Jar module and then click Finish.

14 Figure Creating an EJB Project Click right button on the MDBSampleEJB project and select Java EE->Generate WebSphere Bindings Deployment Descriptor to create the ibm-ejb-jar-bnd.xml file (Figure ).

15 Figure Generating ibm-ejb-jar-bnd.xml In the Design tab, create logical resources mapping their physical components managed by WAS. Click Add to create a new resource. Select Message Driven and click OK. Enter AsyncMessageConsumerBean as name. Select the MDB, click Add and select JCA Adapter. After adding the adapter, input jms/mdbqueueactivationspec as Activation Spec Binding Name, and jms/messagequeue as Destination Binding Name( Figure ). Figure MDB resource mapping

16 Verify the created content in the Source tab, confirm that matches the following source code. <?xml version="1.0" encoding="utf-8"?> <ejb-jar-bnd xmlns=" xmlns:xsi=" xsi:schemalocation=" version="1.0"> <message-driven name="asyncmessageconsumerbean"> <jca-adapter activation-spec-binding-name="jms/mdbqueueactivationspec" destination-binding-name="jms/messagequeue"/> </message-driven> </ejb-jar-bnd> Creating a bean class named AsyncMessageConsumerBean in MDBSampleEJB project which recieves message from Queue and deals with TextMessage. Source Code of AsyncMessageConsumerBean.java import java.util.logging.logger; import javax.annotation.postconstruct; import javax.annotation.predestroy; import javax.ejb.messagedriven; import javax.ejb.activationconfigproperty; import javax.jms.jmsexception; import javax.jms.message; import javax.jms.messagelistener; import javax.jms.textmessage; /** * Message-Driven Bean implementation class for: AsyncMessageConsumerBean

17 * = = "destinationtype", propertyvalue = = "destination", propertyvalue = "jms/messagequeue") }) // a MDB must implements the MessageListene Interface public class AsyncMessageConsumerBean implements MessageListener { Logger logger = void postconstruct() { logger.info("postconstruct called"); void predestroy() { logger.info("predestroy called"); } /** * Default constructor. */ public AsyncMessageConsumerBean() { // TODO Auto-generated constructor stub }

18 /** MessageListener#onMessage(Message) */ public void onmessage(message message) { if (!(message instanceof TextMessage)) { logger.info("received a non-textmessage message; exiting"); System.err.println("received a non-textmessage message; exiting"); return; } TextMessage textmessage = (TextMessage) message; try { System.err.println("AsynchBean Received message: " + textmessage.gettext()); } catch (JMSException e) { // we can simply ignore it (print it out to the console) for now e.printstacktrace(); } } } Creating Dynamic Web Project Now create a new Dynamic Web Project with the name MDBSampleWAR and add it to the MDBSampleEAR enterprise application ( Figure ).

19 Figure Creating a new Dynamic Web Project Open the Web application deployment descriptor. On the References page, click Add. Select Resource reference and click Next. Enter jms/messagequeuecf as name, choose javax.jms.queueconnectionfactory as type, Container for authentication. Click Finish. Now appears the ResourceRef in the list. Enter jms/messagequeuecf as JNDI name under WebSphere Bindings( Figure ). Click Add again, select Message destination reference, and click Next. Create a new destination with name jms/messagequeue, then click Next. Enter jms/mdbmessagequeue as name, javax.jms.queue as type, and Produces as usage. Click Finish ( Figure ). Note: Sometimes the GUI Tool does not performance because of RAD's bugs. We must manually add the code "<message-destination-ref></message-destination-ref>"

20 between "</welcome-file-list>" and "</web-app>" in the application deployment descriptor to active the GUI configuration. The MessageDestRef appears in the list. Enter jms/messagequeue as JNDI name. Save the file Figure Adding a ResourceReference Figure Adding a MessageDestinationReference Create a new Servlet named MessageCreaterServlet.java and click Next. In the next window set its URL-Mapping as "/MessageSender", click Finish. This Servlet gets a parameter with the name Message form a web file, and sends the content as a TextMessage to Queue. Following lists the Source Code.

21 import java.io.ioexception; import java.io.printwriter; import javax.annotation.resource; import javax.jms.messageproducer; import javax.jms.queue; import javax.jms.queueconnection; import javax.jms.queueconnectionfactory; import javax.jms.queuesession; import javax.jms.session; import javax.jms.textmessage; import javax.servlet.servletexception; import javax.servlet.http.httpservlet; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; public class MessageCreaterServlet extends HttpServlet { private static final long serialversionuid = L; // Using the Resource Reference defined in Web Deployment = "jms/messagequeuecf") QueueConnectionFactory = "jms/mdbmessagequeue") Queue queue; protected void doget(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException { performance(request, response); } protected void dopost(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException {

22 performance(request, response);; } private void performance(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException{ try { QueueConnection connection = qcf.createqueueconnection(); QueueSession session = connection.createqueuesession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer producer = session.createproducer(queue); TextMessage txtmsg = session.createtextmessage(); txtmsg.settext(request.getparameter("message")); producer.send(txtmsg); session.close(); connection.close(); // for testing purposes PrintWriter out = response.getwriter(); out.println("message is successfully sent."); out.println("queueconnectionfactory:" +qcf); out.println("queueconnection: "+ connection); out.println("queue: " + queue); out.println("messageproducer: " + producer); out.println("message Content: " + request.getparameter("message")); } catch (Exception e) { throw new ServletException(e); } } }

23 Following we create a simple Web Page named SendMessage.html <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" " <html> <head> <meta http-equiv="content-type" content="text/html; charset=iso "> <title>insert title here</title> </head> <body> <Form action=messagesender> <TABLE width="30%" border="0"> <TR> <TD>Message</TD> <TD><INPUT type="text" name="message"></td> </TR> </TABLE> <input type=submit value="send"/> </Form> </body> </html> 4.3 Running and Testing the projects on WAS Running the projects on WAS Click right button on the MDBSampleEAR project, select Run As -> Run on Server, choose WebSphere Application Server 6.1 at localhost (Figure 4.3.1), select the both modules, MDBSampleEJB and MDBSampleWAR, click Finish to start the project.

24 Figure Testing the project Open a Browser and enter in the Address Bar. The page should be shown as same as Figure Input any message in the text area and click Send. The rusult should be shown like Figure Figure Figure Result Page Return to RD7.5, the Console window should list the messages shown in Figure

25 Figure Messages in Console