Venkat Nandanavanam
Introduction
HORNETQ is the defualt messaging system provided by JBOSS Application Server. In one of my previous tutorial I covered how to configure, produce and consume Messages through JMS API using HORNETQ as provider. You can find the tutorial @ HERE.
NOTE: This tutorial uses queue named 'restInterfaceQueue'. To know how to create this queue please take a look into the above tutorial.
This tutorial will focus on creating and consuming messages from HORNETQ using REST API.
Why would one ever need to produce and consume messages through REST?
Well!!! I would say to support CROSS LANGUAGE CLIENTS.... and also to provide web based API for messaging. With these capabilities one no longer needs producer and consumer to be through JMS API. So anyone who understands HTTP can produce and consume messages. This one big advantage of REST interface. HORNETQ provides a very good REST interface. Some of the features of REST interface provided by HORNETQ are given below
Technologies Used
Coplete list of features and more information about REST interface and HORNETQ can be found @here. Lets get started!!!!
Boot strapping HORNETQ with REST
To use HORNETQ REST interface in our application we first need to bootstrap it. This can be done by adding the below listener in web.xml
REST Interface Configuration
hornetq-rest.xml
Server-in-vm-id : This is to differentiate different HORNETQ servers running in
same VM. We can default it to zero
Use-link-headers: To tell HORNETQ how to publish the links. By default it publishes
using cutoms headers. This tutorial uses the default behaviour so we can mark it as
false
default-durable-send: Used to identify if the posted message needs to persisted in
DB.We will mark it as false. This default behaviour can be overriddden by sending
durable custom header as true
dups-ok Should duplicate messages be allowed?
client-window-size Used to identify buffering capabilities. By specifying it as zero we are saying we don't want any buffering to happen for delivery of messages.
Now lets take a look at our complete web.xml
We will reuse the modified OrderSrvc.java class here. It has single method which will consume XML message and puts it in Queue using JMS API.
As we are using JEE 6 i.e. CDI in OrderSrvc.java we are required to turn it on by using a simple beans.xml under WEB-INF directory. It can be a empty XML file
beans.xml
pom.xml
project structure
dependencies
Now build and deploy the application. We are now ready to consume and produce messages using HORNETQ REST interface.
DEMO
Start your server after deploying the war file
Now post our first message to the queue named "restInterfaceQueue" using REST WS call in OrderSrvc.java. It uses regular JMS API to post the message to queue. url to post the xml message using restclient firefox plugin 'http://localhost:8080/jms-rest-examples/resteasy/hornetq/postOrder'
XML posted
The message counter for the queue should be 1 now as shown in admin console of our JBOSS server.
Now let us consume this message using REST interface. First we will do a GET request to 'http://localhost:8080/jms-rest-examples/resteasy/hornetq/queues/jms.queue.restInterfaceQueue'. To understand how this URL is formed lets break it into pieces
Notice the msg-pull-consumer header returned. We will use that URL to create a service so that we can pull the message from the queue. To create a service do a empty post to the URL as mentioned by msg-pull-consumer header
Below are the custom headers returned from above request.
Notice the 'msg-consume-next' header value returned.Do a POST request to this URL to consume/pull the message from the queue.
below is the consumed message
This network roundtrip is just done once and to consume next message we need not issue the GET request again and start the cycle. Instead we can use 'msg-consume-next' header returned to consume next message and do the polling.If by any chance you miss the URL you can issue a get again to get url values as headers.
Now let us look at Produce an message using REST interface
Do a get request to 'http://localhost:8080/jms-rest-examples/resteasy/hornetq/postOrder' and use 'msg-create' header value and do a post
Notice the headers returned from the above POST request.'msg-create-next: http://localhost:8080/jms-rest-examples/resteasy/hornetq/queues/jms.queue.restInterfaceQueue/create'. Do a post to the URL returned as mentioned by 'msg-create-next' to create a message in the queue
This will create a new message in the queue.
This brings us to the end of the tutorial which covers how to post message and consume message using REST interface.
I was really excited to see producers and consumers via REST interface in JMS queue. If your application needs to support cross platform messaging I would strongly suggest to use REST interface.
Hope this tutorial helps you to understand REST interface. If you have any questions please do not hesitate to ask it in comments section. I will be very happy to answer them.
Dear Readers, kindly like us on facebook or follow me on Google+
Introduction
HORNETQ is the defualt messaging system provided by JBOSS Application Server. In one of my previous tutorial I covered how to configure, produce and consume Messages through JMS API using HORNETQ as provider. You can find the tutorial @ HERE.
NOTE: This tutorial uses queue named 'restInterfaceQueue'. To know how to create this queue please take a look into the above tutorial.
This tutorial will focus on creating and consuming messages from HORNETQ using REST API.
Why would one ever need to produce and consume messages through REST?
Well!!! I would say to support CROSS LANGUAGE CLIENTS.... and also to provide web based API for messaging. With these capabilities one no longer needs producer and consumer to be through JMS API. So anyone who understands HTTP can produce and consume messages. This one big advantage of REST interface. HORNETQ provides a very good REST interface. Some of the features of REST interface provided by HORNETQ are given below
- Avoid posting of duplicate messages
- Mix and match JMS and REST producers and consumers
- Acknowledgement and auto acknowledgement
Technologies Used
- JAVA
- J2EE
- RESTEasy
- HORNETQ
- HORNETQ REST Interface
- Maven
Coplete list of features and more information about REST interface and HORNETQ can be found @here. Lets get started!!!!
Boot strapping HORNETQ with REST
To use HORNETQ REST interface in our application we first need to bootstrap it. This can be done by adding the below listener in web.xml
org.hornetq.rest.integration.RestMessagingBootstrapListener
REST Interface Configuration
We should add some configuration information for REST interface. This can be done in an xml file under WEB-INF/classes. The name of the file should be mentioned in web.xml using rest.messaging.config.file context param
hornetq-rest.xml
The entries in above XML file are explained below0 false true true topic-push-store queue-push-store 10 1 300 0
Server-in-vm-id : This is to differentiate different HORNETQ servers running in
same VM. We can default it to zero
Use-link-headers: To tell HORNETQ how to publish the links. By default it publishes
using cutoms headers. This tutorial uses the default behaviour so we can mark it as
false
default-durable-send: Used to identify if the posted message needs to persisted in
DB.We will mark it as false. This default behaviour can be overriddden by sending
durable custom header as true
dups-ok Should duplicate messages be allowed?
client-window-size Used to identify buffering capabilities. By specifying it as zero we are saying we don't want any buffering to happen for delivery of messages.
Now lets take a look at our complete web.xml
rest.messaging.config.file hornetq-rest.xml resteasy.resources itsvenkis.blogspot.in.rest.services.OrderSrvc resteasy.servlet.mapping.prefix /resteasy/hornetq org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap org.hornetq.rest.integration.RestMessagingBootstrapListener resteasy org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher resteasy /resteasy/hornetq/* BASIC Rest-Messaging /resteasy/hornetq/queues/* GET POST PUT HEAD DELETE admin
We will reuse the modified OrderSrvc.java class here. It has single method which will consume XML message and puts it in Queue using JMS API.
package itsvenkis.blogspot.in.rest.services; import javax.annotation.Resource; import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.JMSException; import javax.jms.MessageProducer; import javax.jms.ObjectMessage; import javax.jms.Queue; import javax.jms.Session; import javax.ws.rs.Consumes; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.apache.log4j.Logger; /** * @author itsvenkis * */ @Path("/postOrder") public class OrderSrvc { private final Logger log = Logger.getLogger(OrderSrvc.class); /* * Map a JNDI connection factory name.As this service is going to be in same * JAVA VM as JMS use "java:/ConnectionFactory". You can find this entry in JBOSS server * standalone-full.xml configuration file. */ @Resource(mappedName = "java:/ConnectionFactory") private ConnectionFactory connectionFactory; /* * Map the queue. Note how the queue name is defined here. This should match the context * of JNDI defined which is "java" namespace followed by the entry name as given in * standalone-full.xml configuration file. */ @Resource(mappedName = "java:/queue/restInterfaceQueue") private Queue orderQueue; @POST @Consumes(MediaType.APPLICATION_XML) public Response postOrder(String xmlStr) throws JMSException{ log.debug("Started processing the order...."); Connection con = null; try{ //In real world you may want to do this only once con = connectionFactory.createConnection(); Session session = con.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer producer = session.createProducer(orderQueue); log.debug("starting HornetQ-JMS connection"); con.start(); log.debug("started HornetQ-JMS connection"); //HORNETQ REST accepts only HTTP or OBJECTMESSAGE ObjectMessage objMsg = session.createObjectMessage(); objMsg.setStringProperty("http_content$type", "application/xml"); objMsg.setObject(xmlStr); producer.send(objMsg); log.debug("Sent message HornetQ-JMS to QUEUE"); }catch(JMSException e){ log.error("Failed to push order to the queue ", e); }finally{ if(con != null){ try{ con.close(); }catch(JMSException e){ log.error("Unexpected error while trying to close the connection", e); } } } return Response.status(200).entity("Received XML").build(); } }
As we are using JEE 6 i.e. CDI in OrderSrvc.java we are required to turn it on by using a simple beans.xml under WEB-INF directory. It can be a empty XML file
beans.xml
pom.xml
4.0.0 in.itsvenkis.blogspot JMS-REST-EXAMPLES 0.0.1-SNAPSHOT war A simple HORNETQ examples to demonstrate REST interface jms-rest-examples org.apache.maven.plugins maven-war-plugin org.hornetq jboss http://repository.jboss.org/maven2 org.jboss.resteasy resteasy-jaxrs 3.0.0.Final org.jboss.resteasy resteasy-jaxb-provider 3.0.0.Final org.jboss.spec.javax.jms jboss-jms-api_1.1_spec 1.0.1.Final log4j log4j 1.2.17 org.hornetq.rest hornetq-rest 2.3.5.Final
project structure
dependencies
Now build and deploy the application. We are now ready to consume and produce messages using HORNETQ REST interface.
DEMO
Start your server after deploying the war file
Now post our first message to the queue named "restInterfaceQueue" using REST WS call in OrderSrvc.java. It uses regular JMS API to post the message to queue. url to post the xml message using restclient firefox plugin 'http://localhost:8080/jms-rest-examples/resteasy/hornetq/postOrder'
XML posted
Mumbai 300 f238 OR908765
The message counter for the queue should be 1 now as shown in admin console of our JBOSS server.
Now let us consume this message using REST interface. First we will do a GET request to 'http://localhost:8080/jms-rest-examples/resteasy/hornetq/queues/jms.queue.restInterfaceQueue'. To understand how this URL is formed lets break it into pieces
- http://localhost:8080/jms-rest-examples- your application context path
- /resteasy/hornetq- As mapped for RESTEasy path in web.xml
- /queues- All REST interface URLS should have queues followed by the original queue name itself which is jms.queue.restInterfaceQueue
Notice the msg-pull-consumer header returned. We will use that URL to create a service so that we can pull the message from the queue. To create a service do a empty post to the URL as mentioned by msg-pull-consumer header
Below are the custom headers returned from above request.
Notice the 'msg-consume-next' header value returned.Do a POST request to this URL to consume/pull the message from the queue.
below is the consumed message
This network roundtrip is just done once and to consume next message we need not issue the GET request again and start the cycle. Instead we can use 'msg-consume-next' header returned to consume next message and do the polling.If by any chance you miss the URL you can issue a get again to get url values as headers.
Now let us look at Produce an message using REST interface
Do a get request to 'http://localhost:8080/jms-rest-examples/resteasy/hornetq/postOrder' and use 'msg-create' header value and do a post
Notice the headers returned from the above POST request.'msg-create-next: http://localhost:8080/jms-rest-examples/resteasy/hornetq/queues/jms.queue.restInterfaceQueue/create'. Do a post to the URL returned as mentioned by 'msg-create-next' to create a message in the queue
This will create a new message in the queue.
This brings us to the end of the tutorial which covers how to post message and consume message using REST interface.
I was really excited to see producers and consumers via REST interface in JMS queue. If your application needs to support cross platform messaging I would strongly suggest to use REST interface.
Hope this tutorial helps you to understand REST interface. If you have any questions please do not hesitate to ask it in comments section. I will be very happy to answer them.
Dear Readers, kindly like us on facebook or follow me on Google+
Could you post the project on github or something?
ReplyDeleteThanks!
Thanks for your interest in the tutorial. I will add the code to github asap. In the mean time the code is included in the tutorial post itself.
ReplyDelete