Featured Post

Applying Email Validation to a JavaFX TextField Using Binding

This example uses the same controller as in a previous post but adds a use case to support email validation.  A Commons Validator object is ...

Saturday, June 9, 2012

A HornetQ Remote Messaging Client Talking to an MDB in JBoss AS 7.1

This is a vendor-specific messaging client for contacting a Message Driven Bean hosted in JBoss AS 7.1.

Messaging is used to exchange data asynchronously.  Asynchronous processing can give a performance boost to a web app.  A calling web page doesn't have to wait for an entire transaction to be processed.  It can also support architectures where processing is distributed which is the case when a transaction takes days to complete, say after a set of service providers responds at their own rate.

MDB

A Message Driven Bean or MDB is a server-side Java component that listens to a message queue.  An MBD is an EJB, so it has access to all of the system services (persistence, security, web services, etc) available in a Java EE-compliant container.


The following is a simple EJB that will respond by outputting the contents of a message when one is placed in a queue.

package msg;

import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;

@MessageDriven(activationConfig = {
  @ActivationConfigProperty(propertyName = "destinationType",
    propertyValue = "javax.jms.Queue"),
  @ActivationConfigProperty(propertyName = "destination",
    propertyValue = "queue/messageTestInbound") }, 
  mappedName = "queue/messageTestInbound")
public class MessageTestBean implements MessageListener {

  public void onMessage(Message message) {
    try {
      System.out.println("MessageTestBean.onMessage(): message="        
         +message.getStringProperty("myprop"));
    } catch (JMSException e) {
      e.printStackTrace();
    }
  }
}

Client

This client is coded using the HornetQ Core API.


package mcli;

import java.util.Date;
import java.util.HashMap;

import org.hornetq.api.core.TransportConfiguration;
import org.hornetq.api.core.client.ClientMessage;
import org.hornetq.api.core.client.ClientProducer;
import org.hornetq.api.core.client.ClientSession;
import org.hornetq.api.core.client.ClientSessionFactory;
import org.hornetq.api.core.client.HornetQClient;
import org.hornetq.api.core.client.ServerLocator;
import org.hornetq.core.remoting.impl.netty.NettyConnectorFactory;
import org.hornetq.core.remoting.impl.netty.TransportConstants;

public class MsgClient {

  public static void main(String[] args) throws Exception {

    HashMap<String, Object> connectionParams = new HashMap<String, Object>();

    connectionParams.put(TransportConstants.HOST_PROP_NAME, "localhost");
    connectionParams.put(TransportConstants.PORT_PROP_NAME, "5445");

    ServerLocator locator = 
        HornetQClient.createServerLocatorWithoutHA(new TransportConfiguration(
      NettyConnectorFactory.class.getName(), connectionParams));

    ClientSessionFactory factory = locator.createSessionFactory();

    ClientSession session = factory.createSession(true, true);

    ClientProducer producer = 
        session.createProducer("jms.queue.messageTestInbound");

    ClientMessage message = session.createMessage(false);

    final String propName = "myprop";
    message.putStringProperty(propName, "Hello sent at " + new Date());

    producer.send(message);

    session.close();
    factory.close();
    locator.close();
  }
}

Eclipse Projects

The MDB is a single source file added to a Dynamic Web Project.  Since the MDB depends on the standard javax.jms classes (rather than the HornetQ classes).

The HornetQ client is also a single Java file added to a Java Project.  The Build Path for this needs to be adjusted to add the HornetQ Core client JAR and the Netty JAR.  Note that the HornetQ JMS JAR does not need to be added.

Build Path for a Hornet Q Client

 
JBoss Config

You set up a queue in JBoss by using the CLI interface or directly manipulating the standalone.xml config.  To add a queue using the CLI interface, start the bin/jboss-cli program and run the following command.  Using aDOS prompt


[standalone@localhost:9999 /] jms-queue add --queue-address=messageTestInbound --entries=queue/messageTestInbound

This example also requires that the messaging subsystems be unsecured.  Add the security-enabled tag with "false" to the block in standalone.xml.

        <subsystem xmlns="urn:jboss:domain:messaging:1.1">
            <hornetq-server>
                <persistence-enabled>true</persistence-enabled>
                <security-enabled>false</security-enabled> 
 Results

The results of a successful run of the client with the server deployed and running in JBoss are as follows.  From the Eclipse console


11:09:28,759 INFO  [org.jboss.as.server] 
  (DeploymentScanner-threads - 2) JBAS018559: Deployed "message-test-project.war"
11:09:38,737 INFO  [stdout] (
  Thread-0 (HornetQ-client-global-threads-1100729355)) 
  MessageTestBean.onMessage(): message=Hello sent at Sat Jun 09 11:09:38 EDT 2012


Even though messaging is considered advanced and is not available in the trimmed down JBoss server profile that ships out of the box, it is really easy to add this capability to your applications and overall IT intrastructure.  A single Java class annotated with @MessageDriven and the right parameters can construct a component that runs at its own pace, possibly hours waiting for service providers to contribute.

1 comment:

  1. check out my new book on HornetQ http://www.amazon.com/dp/1849518408/?tag=packtpubli-20

    ReplyDelete