Venkat Nandanavanam
If you are interested to see the other REST tutorials I already blogged, please find them below
As part of series of REST tutorials, I am blogging this simple HorneQ JMS tutorial. HornetQ is the default meessaging system in JBOSS application server.
A detailed documentation about HornetQ is available @ here.Lets get started with the tutorial
Technologies used
Different startup configurations are available in JBOSS server. To have the HORNETQ integrated and started with JBOSS AS one should use standalone-full.xml. For example we will start the server using this command
./standalone.sh --server-config=standalone-full.xml.
We will add the queues needed for our tutorial in standalone-full.xml. There are other ways too to declare the queues/topics which is out of scope of this post. I am gonna develop a order processing system which can receive a order which is a XML file and it will put the order in a queue which will be consumed by other consumers. Lets name that queue as "ticketOrderQueue". Here is how we declare in standalone-full.xml
If our message producer or consumer is in same JAVA VM as HornetQ one should use "java:/ConnectionFactory" and if it is remote client consuming or producing messaging to JMS destinations one should use "RemoteConnectionFactory". Noteworthy about the contexts they use as shown in above snippet. For example, "RemoteConenctionFactory" uses "java:jboss/exported" context. Once this is done, we will define users for JBOSS application server as administrator and for HORNETQ. Use add-user utility to add application users. Note: I am using UBUNTU as my dev env. However for windows it should be the same process with bat files First let us add admin user. Please find the details in below screenshot
Now let us add some application users for HORNETQ. Please find the details below
Now start the server and we will add some security to our HORNETQ. start server
type in and enter the credentials you configured for admin as mentioned above and select JMS destination from left hand menu. You should now be able to see this view with the queues which we defined
To add some security to our HORNETQ lets go to profile view by clicking on profile link on top right side on admin view and select Messaging/destination/view and select security settings and add the role permissions as shown below
This should bring us to end of configuration section. Now lets start coding our producer which is a RESTFUL web service and receives a XML order and pushes it to a queue. OrderSrvc.java
In the above web service I used @Resource annotation which is nothing but through CDI. Inorder to make CDI work one should have a beans.xml defined under WEB-INF folder. This xml will tell JBOSS to enable CDI.Noteworthy that this xml can be empty. I will add tutorials specific to CDI in the near future. For now,please find the xml below
web.xml
pom.xml
Now build,deploy and start your server. We will restful mozilla plugin to post XML file to our URL
To check if the message has reached our "ticketOrderQueue" go to admin view in the JBOSS server and goto JMS view. You should be able to see messages in queue count as one
Now lets code a simple consumer class which will have a main method
Run the application and you should be able to see this output now
Project directory structure
Project dependencies
This brings us to the end of this tutorial!!!!
Dear Readers, kindly like us on facebook
If you are interested to see the other REST tutorials I already blogged, please find them below
As part of series of REST tutorials, I am blogging this simple HorneQ JMS tutorial. HornetQ is the default meessaging system in JBOSS application server.
A detailed documentation about HornetQ is available @ here.Lets get started with the tutorial
Technologies used
- HornetQ
- JBOSS eap 6.1
- JAVA 7
- RESTEasy
- CDI
- Maven
Different startup configurations are available in JBOSS server. To have the HORNETQ integrated and started with JBOSS AS one should use standalone-full.xml. For example we will start the server using this command
./standalone.sh --server-config=standalone-full.xml.
We will add the queues needed for our tutorial in standalone-full.xml. There are other ways too to declare the queues/topics which is out of scope of this post. I am gonna develop a order processing system which can receive a order which is a XML file and it will put the order in a queue which will be consumed by other consumers. Lets name that queue as "ticketOrderQueue". Here is how we declare in standalone-full.xml
To connect to this queues we will use JNDI connection factories. By default JBOSS gives us couple of connection factories like "InvmConnectionFactory" and "RemoteConnectionFactory" which will use netty connector. Code snippet of these factories is below
If our message producer or consumer is in same JAVA VM as HornetQ one should use "java:/ConnectionFactory" and if it is remote client consuming or producing messaging to JMS destinations one should use "RemoteConnectionFactory". Noteworthy about the contexts they use as shown in above snippet. For example, "RemoteConenctionFactory" uses "java:jboss/exported" context. Once this is done, we will define users for JBOSS application server as administrator and for HORNETQ. Use add-user utility to add application users. Note: I am using UBUNTU as my dev env. However for windows it should be the same process with bat files First let us add admin user. Please find the details in below screenshot
Now let us add some application users for HORNETQ. Please find the details below
Now start the server and we will add some security to our HORNETQ. start server
type in and enter the credentials you configured for admin as mentioned above and select JMS destination from left hand menu. You should now be able to see this view with the queues which we defined
To add some security to our HORNETQ lets go to profile view by clicking on profile link on top right side on admin view and select Messaging/destination/view and select security settings and add the role permissions as shown below
This should bring us to end of configuration section. Now lets start coding our producer which is a RESTFUL web service and receives a XML order and pushes it to a queue. OrderSrvc.java
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.Queue; import javax.jms.Session; import javax.jms.TextMessage; 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/ticketOrderQueue") 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"); TextMessage txtMsg = session.createTextMessage(); txtMsg.setText(xmlStr); producer.send(txtMsg); 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(); } }
In the above web service I used @Resource annotation which is nothing but through CDI. Inorder to make CDI work one should have a beans.xml defined under WEB-INF folder. This xml will tell JBOSS to enable CDI.Noteworthy that this xml can be empty. I will add tutorials specific to CDI in the near future. For now,please find the xml below
web.xml
resteasy.resources itsvenkis.blogspot.in.rest.services.OrderSrvc resteasy.servlet.mapping.prefix /resteasy org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap resteasy org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher resteasy /resteasy/*
pom.xml
4.0.0 in.itsvenkis.blogspot JMS-flight-booking 0.0.1-SNAPSHOT war jms-flight-booking Simple application to understand RESTEasy,Hornet Q 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
Now build,deploy and start your server. We will restful mozilla plugin to post XML file to our URL
To check if the message has reached our "ticketOrderQueue" go to admin view in the JBOSS server and goto JMS view. You should be able to see messages in queue count as one
Now lets code a simple consumer class which will have a main method
package itsvenkis.blogspot.in.example.consumer; import java.util.Properties; import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.Destination; import javax.jms.MessageConsumer; import javax.jms.Session; import javax.jms.TextMessage; import javax.naming.Context; import javax.naming.InitialContext; public class JMSConsumerExample { /* * for a remote client use RemoteConnectionFactory JNDI which will be defined in standalone-full.xml * configuration file */ private static final String DEFAULT_CONNECTION_FACTORY = "jms/RemoteConnectionFactory"; //Queue name as mentioned in standalone-full.xml underprivate static final String DEFAULT_DESTINATION = "jms/queue/ticketOrderQueue"; private static final String DEFAULT_USERNAME = "jmsadmin"; private static final String DEFAULT_PASSWORD = "*****"; private static final String INITIAL_CONTEXT_FACTORY = "org.jboss.naming.remote.client.InitialContextFactory"; private static final String PROVIDER_URL = "remote://localhost:4447"; public static void main(String[] args) throws Exception { ConnectionFactory connectionFactory = null; Connection connection = null; Session session = null; MessageConsumer consumer = null; Destination destination = null; TextMessage message = null; Context context = null; try { final Properties env = new Properties(); env.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY); env.put(Context.PROVIDER_URL, System.getProperty(Context.PROVIDER_URL, PROVIDER_URL)); env.put(Context.SECURITY_PRINCIPAL, System.getProperty("username", DEFAULT_USERNAME)); env.put(Context.SECURITY_CREDENTIALS, System.getProperty("password", DEFAULT_PASSWORD)); context = new InitialContext(env); String connectionFactoryString = System.getProperty( "connection.factory", DEFAULT_CONNECTION_FACTORY); connectionFactory = (ConnectionFactory) context .lookup(connectionFactoryString); String destinationString = System.getProperty("destination", DEFAULT_DESTINATION); destination = (Destination) context.lookup(destinationString); connection = connectionFactory.createConnection( System.getProperty("username", DEFAULT_USERNAME), System.getProperty("password", DEFAULT_PASSWORD)); session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); consumer = session.createConsumer(destination); connection.start(); message = (TextMessage) consumer.receive(10000); System.out.println("Received message " + message.getText()); } catch (Exception e) { System.out.println(e.getMessage()); throw e; } finally { if (context != null) { context.close(); } if (connection != null) { connection.close(); } } } }
Run the application and you should be able to see this output now
Project directory structure
Project dependencies
This brings us to the end of this tutorial!!!!
Dear Readers, kindly like us on facebook
Hi,
ReplyDeleteCan you please let me know jars required to run JMSConsumerExample java code.
You just need javax jms jar for JMSConsumerExample.
DeleteHighly doubtful. - In order to run the example one needs whole bunch of JBoss-related packages. The easiest way is to import everything from the $JBOSS_HOME/client directory...
Delete