Enterprise Integration Zone is brought to you in partnership with:

Masoud Kalali has a software engineering degree and has been working on software development projects since 1998. He has experience with a variety of technologies (.NET, J2EE, CORBA, and COM+) on diverse platforms (Solaris, Linux, and Windows). His experience is in software architecture, design, and server-side development. Masoud has published several articles at Java.net and Dzone. He has authored multiple refcards, published by Dzone, including but not limited to Using XML in Java, Java EE Security and GlassFish v3 refcardz. He is one of the founder members of NetBeans Dream Team and a GlassFish community spotlighted developer. Recently Masoud's new book, GlassFish Security has been published which covers GlassFish v3 security and Java EE 6 security. Masoud's main area of research and interest includes service-oriented architecture and large scale systems' development and deployment and in his leisure time he enjoys photography, mountaineering and camping. Masoud's can be followed at his Twitter account. Masoud has posted 82 posts at DZone. You can read more from them at their website. View Full User Profile

JMS Over HTTP Using OpenMQ (Sun Java System Message Queue and HTTP Tunneling)

06.22.2009
| 21846 views |
  • submit to reddit

You may have already faced a situation where you need to have messaging capabilities in your application while your client application runs in an environment, which you have no control over its network configuration and restrictions. Such situation lead to the fact that you can not use JMS communication over designated ports like 7676 and so.

You may simply put JMS away and follow another protocol or even plain HTTP communication to address your architecture and design requirement, but we can not easily put pure JMS API capabilities away as we may need durable subscription over a proven and already well tested and established design and architecture. Different JMS implementation providers provide different type capabilities to address such a requirement. ActiveMQ provide HTTP and HTTPS transport for JMS API and described it here.

OpenMQ provide different transport protocol and access channels to access OpenMQ functionalities from different prgramming . One of the access channles which involve HTTP is named Universal Message Service (UMS) which provide a simple REST interaction template to place messages and comsume them from any programming language and device which can interact with a network server. UMS has some limitations which is simply understandable based on the RESTful nature of UMS. For current version of OpenMQ, it only supports Message Queues as destinations so there is no publish-subscribe functionality available.

Another capability which involve HTTP is JMS over HTTP or simply JMS HTTP tunneling. OpenMQ JMS implementation supports HTTP/s as transport protocol if we configure the message broker properly. Well I said the JMS implementation support HTTP/S as a transport protocol which means we as user of the JMS API see almost no difference in the way that we use the JMS API. We can use publish-subscribe, point to point, durable subscription, transaction and whatever provided in the JMS API.

First, lets overview the OpenMQ installation and configuration then we will take a look at an example to see what changes between using JMS API and JMS API over HTTP transport. Installation process is as follow:

    OpenMQ project provides a Java EE web application which interact with OpenMQ broker from one side and Sun JMS implementation on the other side. Interaction of this application with the client and MQ broker is highly customizable in different aspects like Broker port number, client poll inrval, Broker address and so on.

  • Download OpenMQ from https://mq.dev.java.net/ it should be a zip which is different for each platform.
  • Install the MQ by unzipping the above file and running ./installer or installer.bat or so.
  • After the installation completed, go to install_folder/var/mq/instances/imqbroker/props and open the config.properties in a text editor like notepad or emeditor or gedit.
  • Add the following line to the end of the above file:

  • imq.service.activelist=jms,admin,httpjms

  • Now goto install_folder/mq/lib/ and pick the imqhttp.war file. deploy the file into your Servlet container or application server (I went with GlassFish). After you deployed the file start the application server or Servlet container
  • Now it is time to start the MQ broker: launch a terminal or cmd console and goto install_folder/mq/bin now execute ./imqbrokerd -port 7979 (it maybe like imqbrokerd.bat -port 7979 for Windows ) This command will start the MQ broker and keep it listening on port 7979 for incoming connection
  • To test the overall operations: Open a browser and tray to surf http://127.0.0.1:8080/imqhttp/tunnel or whatever URL which points to the newly deployed application . If you saw "HTTP tunneling Servlet ready." as the first line in the response page then we are ready for last step.

Now let's see how we can publish some messages, this sample code assume that we have configured the message broker and assumes that we have the following two JAR files in the classpath. These JAR files are available in install_folder/mq/lib/

 

  1. imq.jar
  2. jms.jar

Now the Publisher code:

public class Publisher {

public void publish(String messageContent) {
try {
String addressList = "http://127.0.0.1:8080/imqhttp/tunnel";
com.sun.messaging.TopicConnectionFactory topicConnectionFactory = new com.sun.messaging.TopicConnectionFactory();
topicConnectionFactory.setProperty(com.sun.messaging.ConnectionConfiguration.imqAddressList, addressList);
javax.jms.Topic top;
javax.jms.Connection con = topicConnectionFactory.createTopicConnection("admin", "admin");

javax.jms.Session session = con.createSession(false, javax.jms.Session.AUTO_ACKNOWLEDGE);
top = session.createTopic("DIRECT_TOPIC");
MessageProducer prod = session.createProducer(top);
Message textMessage = session.createTextMessage(messageContent);
prod.send(textMessage);

prod.close();
session.close();
con.close();

} catch (JMSException ex) {
ex.printStackTrace();
}

}

public static void main(String args[]) {

Publisher p = new Publisher();
for (int i = 1; i < 10; i++) {
p.publish("Sample Text Message Content: " + i);
}
}
}

 

As you can see the only difference is the connection URL which uses http instead of mq and point to a Servlet container address instead of pointing to the Broker listening address.

The subscriber sample code follow a similar pattern. Here I write a sample durable subscriber so you can see that we can use durable subscribtion over HTTP. But you should note that HTTP transport uses polling and continuesly open communication channel which can introduce some overload on the server.

class SimpleListener implements MessageListener {

public void onMessage(Message msg) {
System.out.println("On Message Called");
if (msg instanceof TextMessage) {
try {
System.out.print(((TextMessage) msg).getText());
} catch (JMSException ex) {
ex.printStackTrace();
}

}
}
}

public class Subscriber {

/**
* @param args the command line arguments
*/
public void subscribe(String clientID, String susbscritpionID) {
try {
// TODO code application logic here

String addressList = "http://127.0.0.1:8080/imqhttp/tunnel";
com.sun.messaging.TopicConnectionFactory topicConnectionFactory = new com.sun.messaging.TopicConnectionFactory();
topicConnectionFactory.setProperty(com.sun.messaging.ConnectionConfiguration.imqAddressList, addressList);
javax.jms.Topic top;
javax.jms.Connection con = topicConnectionFactory.createTopicConnection("admin", "admin");
con.setClientID(clientID);
javax.jms.Session session = con.createSession(false, javax.jms.Session.AUTO_ACKNOWLEDGE);
top = session.createTopic("DIRECT_TOPIC");
TopicSubscriber topicSubscriber = session.createDurableSubscriber(top, susbscritpionID);
topicSubscriber.setMessageListener(new SimpleListener());

con.start();


} catch (JMSException ex) {
ex.printStackTrace();
}
}

public static void main(String args[]) {

Subscriber sub = new Subscriber();
sub.subscribe("C19", "C1_011");
}
}

 

Now how you can test the entire example and monitor the MQ? it is very simple by utilizing the provided tools.

Do the following steps to test the overall durable subscription system:

  • Run a subscriber
  • Run another subscriber with a different client ID
  • Run a publisher once or twice
  • Kill the second subscriber
  • Run a publisher once
  • Run the subscriber and you can see that the subscriber will fetch all messages which arrived after it shut down-ed.

Note that we can not have two separate client with same client ID running because the broker will not be able to distinguish which client it should send the messages.

  • You can monitor the queue and the broker using: ./imqadmin which can be found in install_folder/mq/bin this software shows how many durable subscribers are around and how many messages are pending for each subscriber and so on.
  • You can monitor the Queue in real-time mode using the following command which can be executed in install_folder/mq/bin
  • ./imqcmd -b 127.0.0.1:7979 metrics dst -t t -n DIRECT_TOPIC The command will ask for username and password, give admin/admin for it

    The sample code for this entry can be found Here. The sample code is a NetBeans project with the publisher and the subscriber source code.

    A complete documentation of OpenMQ is available at its documentation centre. You can see how you can change different port numbers or configure different properties of the Broker and HTTP tunneling web application communication.

    References
    Published at DZone with permission of its author, Masoud Kalali. (source)

    (Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

    Comments

    sub online replied on Fri, 2009/06/26 - 2:34am

    that was close.Tiffany JewelleryThat's rubbish! It's no like that at all. That's rubbish.links of londonNo wonder.Looking for trouble.links of londonDo you have an opinion!That's the way it is.It's not my fault.You ain't seen nothin' yet.I'm speechless.What brings you here!If I'm not mistaken…You're not so great yourself.

    Comment viewing options

    Select your preferred way to display the comments and click "Save settings" to activate your changes.