Monday 14 October 2013

How to create MDB that listens on JMS Queue

I recently needed to do a project like this and found the information out there wasn't good enough, especially when you want to create something which uses Oracle WebLogic.

Hope this is helpfull:

I have broken this up into two sections - a JMS creation section and a code snippet which will listen on the queue you'll create on WebLogic



JMS Creation:

For EJB Message Driven Beans to listen and retrieve messages from queue, you need to cerate a queue on WebLogic

I created a project that basically receives messages from external systems. My service is exposed on OSB and will publish the message to my created EmailQueue

1. Log into WebLogic
2. Create JMS Server - Navigate to Services>Messaging>JMS Servers and click new (I called mine EmailJMSServer)
3. Create JMS Module - Navigate to Services>Messaging>JMS Modules and click new
4. Open your Module and create a EmailConnectionFactory and EmailQueue - Note that both must use the same subDeployment

See my JNDI Names below:



5. Restart WebLogic or Managed Server if you have targeted anything else

Code to listen on JMS
Now that you have completed your JMS setup, now you can begin with the MDB to listen on the queue. I used JDeveloper.

1.Create New>All Technologies>EJB>Message Driven Bean

2.Select EJB 3 and click next
3.Name your EJB MDB and select Container, then also chnage the Mapped Name to jms/EmailQueue
4.Go next and Finish

the below Code listens for message on JMS, takes the message which is xml and parses it to SAX to get normal Java Object, it then goes and calls a normal Java jar to email the result.

Code:

package com.ifc.email.model;


import com.ifc.email.SendEmailEngineHelper;
import com.ifc.xml.EmailInfo;
import com.ifc.xml.XMLSaxHandlerParser;

import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;

import javax.ejb.MessageDrivenContext;

import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

@MessageDriven(name = "EmailQueue", description = "EmailMDBQueue",
               mappedName = "jms/EmailQueue",
               messageListenerInterface = MessageListener.class,
               activationConfig =
               { @ActivationConfigProperty(propertyName = "destinationType",
                                           propertyValue = "javax.jms.Queue"),
                 @ActivationConfigProperty(propertyName = "destination",
                                           propertyValue = "queue/MyQueue") })
public class EmailNotificationMDBBean implements MessageListener {


    private MessageDrivenContext context;

    // --------------------------------------------------------------
    // EJB Methods from MessageDrivenBean interface
    // --------------------------------------------------------------

    public void ejbCreate() {
        System.out.println("EmailMDB: ejbCreate called");
    }

    public void ejbRemove() {
        System.out.println("EmailMDB: ejbRemove called");
    }

    public void setMessageDrivenContext(MessageDrivenContext context) {
        System.out.println("setMessageDrivenContext called");
        this.context = context;
    }

    public void onMessage(Message message) {
        try {
            TextMessage textMessage = (TextMessage)message;


            System.out.println("New message received: " +
                               textMessage.toString());

            String xmlString = textMessage.getText().toString();
            System.out.println("XMLString " + xmlString);

            XMLSaxHandlerParser sp = new XMLSaxHandlerParser();
            EmailInfo email = sp.getXml(textMessage.getText());


            String fromAddress = email.getFromAddress();
            System.out.println("FROM " + fromAddress);
            String[] toAddress = email.getToAddress();
            System.out.println("TO " + toAddress);
            String[] ccAddress = email.getCCAddress();
            System.out.println("CC " + ccAddress);
            String[] bccAddress = email.getBCCAddress();
            System.out.println("BCC " + bccAddress);
            String subject = email.getSubject();
            System.out.println("FROM " + subject);
            String body = email.getBody();
            System.out.println("BODY " + body);
            String attachementName = email.getAttachmentName();
            System.out.println("attachementName " + attachementName);
            String attachementBase64 = email.getAttachmentBase64();
            System.out.println("attachementBase64 " + attachementBase64);


            SendEmailEngineHelper sendMail = new SendEmailEngineHelper();

            sendMail.SendMailer(fromAddress, toAddress, ccAddress, bccAddress,
                                subject, body, attachementName,
                                attachementBase64);

        } catch (JMSException e) {
            e.printStackTrace();
        } catch (Exception e) {
        }

    }
}




OSB (Acting as the client)
I used OSB as a client tester to publish messages to my Queue and is quite easy top do. Create a wsdl and xsd to define a schema that you'd like to publish to your queue.

1 - The business Service will publish messages
2 - Proxy Service will expose wsdl contract
3 I have an artifact folder from my wsdl and xsd



If you don't have something to test your queue with yet - use the below code to publish to the queue:

package com.ifc.email.client;

import java.util.Hashtable;

import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;

import javax.jms.QueueSender;
import javax.jms.QueueSession;

import javax.jms.TextMessage;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;


public class JMSSender {
   private static InitialContext ctx = null;
   private static QueueConnectionFactory qcf = null;
   private static QueueConnection qc = null;
   private static QueueSession qsess = null;
   private static Queue q = null;
   private static QueueSender qsndr = null;
   private static TextMessage message = null;
   // NOTE: The next two lines set the name of the Queue Connection Factory
   //       and the Queue that we want to use.
   private static final String QCF_NAME = "jms/EmailConnectionFactory";
   private static final String QUEUE_NAME = "jms/EmailQueue";
   public JMSSender() {
       super();
   }
   public static void sendMessage(String messageText) {
       // create InitialContext
       Hashtable properties = new Hashtable();
       properties.put(Context.INITIAL_CONTEXT_FACTORY,
                      "weblogic.jndi.WLInitialContextFactory");
       // NOTE: The port number of the server is provided in the next line,
       //       followed by the userid and password on the next two lines.
       properties.put(Context.PROVIDER_URL, "t3://localhost:7001");
       properties.put(Context.SECURITY_PRINCIPAL, "weblogic");
       properties.put(Context.SECURITY_CREDENTIALS, "weblogic1");
     
     
       try {
           ctx = new InitialContext(properties);
       } catch (NamingException ne) {
           ne.printStackTrace(System.err);
           System.exit(0);
       }
       System.out.println("Got InitialContext " + ctx.toString());
       // create QueueConnectionFactory
       try {
           qcf = (QueueConnectionFactory)ctx.lookup(QCF_NAME);
       }
       catch (NamingException ne) {
           ne.printStackTrace(System.err);
           System.exit(0);
       }
       System.out.println("Got QueueConnectionFactory " + qcf.toString());
       // create QueueConnection
       try {
           qc = qcf.createQueueConnection();
       }
       catch (JMSException jmse) {
           jmse.printStackTrace(System.err);
           System.exit(0);
       }
       System.out.println("Got QueueConnection " + qc.toString());
       // create QueueSession
       try {
           qsess = qc.createQueueSession(false, 0);
       }
       catch (JMSException jmse) {
           jmse.printStackTrace(System.err);
           System.exit(0);
       }
       System.out.println("Got QueueSession " + qsess.toString());
       // lookup Queue
       try {
           q = (Queue) ctx.lookup(QUEUE_NAME);
       }
       catch (NamingException ne) {
           ne.printStackTrace(System.err);
           System.exit(0);
       }
       System.out.println("Got Queue " + q.toString());
       // create QueueSender
       try {
           qsndr = qsess.createSender(q);
       }
       catch (JMSException jmse) {
           jmse.printStackTrace(System.err);
           System.exit(0);
       }
       System.out.println("Got QueueSender " + qsndr.toString());
       // create TextMessage
       try {
           message = qsess.createTextMessage();
       }
       catch (JMSException jmse) {
           jmse.printStackTrace(System.err);
           System.exit(0);
       }
       System.out.println("Got TextMessage " + message.toString());
       // set message text in TextMessage
       try {
           message.setText(messageText);
       }
       catch (JMSException jmse) {
           jmse.printStackTrace(System.err);
           System.exit(0);
       }
       System.out.println("Set text in TextMessage " + message.toString());
       // send message
       try {
           qsndr.send(message);
       }
       catch (JMSException jmse) {
           jmse.printStackTrace(System.err);
           System.exit(0);
       }
       System.out.println("Sent message ");
       // clean up
       try {
           message = null;
           qsndr.close();
           qsndr = null;
           q = null;
           qsess.close();
           qsess = null;
           qc.close();
           qc = null;
           qcf = null;
           ctx = null;
       }
       catch (JMSException jmse) {
           jmse.printStackTrace(System.err);
       }
       System.out.println("Cleaned up and done.");
   }
   public static void main(String args[]) {
       sendMessage("Hello Justin How are you?");
       sendMessage("hahahahahah?");
   }
}

No comments:

Post a Comment