<html>
<head>
<title>HornetQ JMS Bridge Example</title>
<link rel="stylesheet" type="text/css" href="../../common/common.css" />
<link rel="stylesheet" type="text/css" href="../../common/prettify.css" />
<script type="text/javascript" src="../../common/prettify.js"></script>
</head>
<body onload="prettyPrint()">
<h1>JMS Bridge Example</h1>
<p>This example shows how to configure and run a JMS Bridge in WildFly.<br />
A bridge receives messages from a <em>source</em> JMS destination and forwards them to a <em>target</em> destination.</p>
<p>The source and target destinations can be on different servers, even from different JMS providers. For example, you can use this
JMS Bridge to bridge a legacy JMS provider to HornetQ during migration.</p>
<p>This example will show how to configure and run the simplest bridge:</p>
<ul>
<li>the source and target destinations are hosted by a single WildFly instance</li>
<li>the bridge is run on the same WildFly instance</li>
<li>every time a message is consumed by the bridge from the source, it is forward to the target</li>
<li>The application client will send a message to the source and consume the "same" message from the target to
show that the two destinations were indeed bridged.</li>
</ul>
<h3>JMS Bridge configuration</h3>
<p>The JMS Bridge is configured in the "messaging" subsystem.<br />
<p>The Bridge is deployed in the application server when you simply type <code>./build.sh deploy</code> (or <code>build.bat deploy</code> on windows) (it is copied to <code>${JBOSS_HOME}/server/default-with-hornetq/deploy/</code>).</p>
<h2>Example step-by-step</h2>
<p><i>download WildFly 8.0.0.Final from <a href="http://wildfly.org/downloads/">here</a> and install.</i></p>
<p><i>set the JBOSS_HOME property to point to the WildFly install directory</i></p>
<p><i>type <code>mvn verify</code> from the example directory to run</i></p>
<p>The example is simple: the application will send a message to the <em>source</em> queue and consume the same message
from the <em>target</em> queue.</p>
<p>The bridge is configured in the messaging subsystem:</p>
<pre class="prettyprint">
<jms-bridge name="myBridge">
<source>
<connection-factory name="ConnectionFactory" />
<destination name="queue/sourceQueue" />
</source>
<target>
<connection-factory name="ConnectionFactory" />
<destination name="queue/targetQueue" />
</target>
<quality-of-service>AT_MOST_ONCE</quality-of-service>
<failure-retry-interval>1000</failure-retry-interval>
<max-retries>7890</max-retries>
<max-batch-size>1</max-batch-size>
<max-batch-time>1000</max-batch-time>
</jms-bridge>
</pre>
<ol>
<li>First we need to get an initial context so we can look up the JMS resources
</li>
<pre class="prettyprint">
final Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
env.put(Context.PROVIDER_URL, "http-remoting://localhost:8080");
initialContext = new InitialContext(env);
</pre>
<li>We look up the JMS ConnectionFactory</li>
<pre class="prettyprint">
ConnectionFactory cf = (ConnectionFactory)initialContext.lookup("/jms/RemoteConnectionFactory");
</pre>
<p><em>First, we will send a message to the <em>source</em> queue</em>.</p>
<li>We look up the JMS <em>source</em> queue</li>
<pre class="prettyprint">
Queue sourceQueue = (Queue)initialContext.lookup("jms/queues/sourceQueue");
</pre>
<li>We create a JMS connection, a session and a message producer for the <em>source</em> queue</li>
<pre class="prettyprint">
sourceConnection = cf.createConnection("guest", "password");
Session sourceSession = sourceConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer sourceProducer = sourceSession.createProducer(sourceQueue);
</pre>
<li>We create and send a message to the <em>source</em> queue. We also display its Message ID.</li>
<pre class="prettyprint">
TextMessage message = sourceSession.createTextMessage("this is a text message");
sourceProducer.send(message);
System.out.format("Sent message to %s: %s\n",
((Queue)message.getJMSDestination()).getQueueName(),
message.getText());
System.out.format("Message ID : %s\n", message.getJMSMessageID());
</pre>
<li>We close the <em>source</em> connection</li>
<pre class="prettyprint">
sourceConnection.close();
</pre>
<p><em>Now that a message has been sent to the <em>source</em> queue, we will consume a message
from the <em>target</em> queue.<br />
If the bridge runs correctly, it will have consumed the message from the <em>source</em> and
resent it to the <em>target</em> so that we can consume a message from it.</em></p>
<li>We look up the JMS <em>target</em> queue</li>
<pre class="prettyprint">
Queue targetQueue = (Queue)initialContext.lookup("jms/queues/targetQueue");
</pre>
<li>We create a connection, a session and a message consumer for the <em>target</em> queue</li>
<pre class="prettyprint">
targetConnection = cf.createConnection();
Session targetSession = targetConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageConsumer targetConsumer = targetSession.createConsumer(targetQueue);
</pre>
<li>We start the JMS connection to receive messages from the <em>target</em></li>
<pre class="prettyprint">
targetConnection.start();
</pre>
<li>We receive a message from the <em>target</em> queue. It has the same content than the message sent to the <em>source</em> queue</li>
<pre class="prettyprint">
TextMessage messageReceived = (TextMessage)targetConsumer.receive(15000);
System.out.format("\nReceived from %s: %s\n",
((Queue)messageReceived.getJMSDestination()).getQueueName(),
messageReceived.getText());
</pre>
<li>We now display the received message ID. It is not the same than the ID of the message sent to the <em>source</em> queue.
The message received from the <em>target</em> queue was sent by the bridge, not by the <em>source</em> message producer</li>
<pre class="prettyprint">
System.out.format("Message ID : %s\n", messageReceived.getJMSMessageID());
</pre>
<li>If you need to retrieve the message ID of the message <em>sent to the source</em>, you can use the property <code>HQ_BRIDGE_MSG_ID_LIST</code></li>
<pre class="prettyprint">
System.out.format("Bridged Message ID : %s\n", messageReceived.getStringProperty("HQ_BRIDGE_MSG_ID_LIST"));
</pre>
<li>And finally, <b>always</b> remember to close the JMS connections and resources after use, in a <code>finally</code> block. Closing a JMS connection will automatically close all of its sessions, consumers, producer and browser objects</li>
<pre class="prettyprint">
finally
{
if (initialContext != null)
{
initialContext.close();
}
if (sourceConnection != null)
{
sourceConnection.close();
}
if (targetConnection != null)
{
targetConnection.close();
}
}
</pre>
</ol>
</body>
</html>