2014-10-31 06:20:28 -04:00
< html >
< head >
2014-11-19 03:44:57 -05:00
< title > ActiveMQ JMS Bridge Example< / title >
2014-10-31 06:20:28 -04:00
< 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 >
2014-11-19 03:44:57 -05:00
< p > This example shows you how to create a JMS Bridge between two ActiveMQ servers.< / p >
2014-10-31 06:20:28 -04:00
< img src = "jms-bridge.png" / >
2014-11-19 03:44:57 -05:00
< p > The example will use two ActiveMQ servers:< / p >
2014-10-31 06:20:28 -04:00
< ul >
< li > Server #0 – the < em > Source< / em > server. It will be configured with a JMS Topic bound to JNDI under < code > /source/topic< / code >
< li > Server #1 – the < em > Target< / em > server. It will be configured with a JMS Queue bound to JNDI under < code > /target/queue< / code > < br / >
< / ul >
2014-11-19 03:44:57 -05:00
< p > Both ActiveMQ server will run their own JNDI server used by the JMS Bridge and the JMS Client to lookup JMS
2014-10-31 06:20:28 -04:00
resources (ConnectionFactory and Destination).< / p >
< p > The JMS Bridge will be started in the example code and be configured to bridge messages from the < em > source< / em > destination
(the topic hosted on server #0) and the < em > target< / em > destination (the queue hosted on server #1)< / p >
< p > The client will check the bridge works by:< / p >
< ol >
< li > sending a message to the < em > source< / em > topic< / li >
< li > receive a message from the < em > target< / em > queue< / li >
< li > check that both messages correspond to the same content.< / li >
< / ol >
< h3 > JMS Bridge Configuration< / h3 >
< p > The JMS Bridge is a < abbr title = "Plain Old Java Object" > POJO< / abbr > that we configure with both source and target
JNDI configurations. In the actual example we are programatically creating the Bridge, however the following section
2014-11-19 14:58:44 -05:00
describes how you would do this if you wanted to deploy with an actual ActiveMQ server via the activemq-beans.xml.
2014-10-31 06:20:28 -04:00
< h4 > Configuring the Bridge with the JBoss Microcontainer< / h4 >
< p >
in which we inject JNDI configurations
so that it looks up its source and target JMS resources.
The JMS Bridge is defined a bean and setup by JBoss Microntainer in the same VM than Server #1, the target server.< / p >
2014-11-19 14:58:44 -05:00
< / p > The JMS Bridge sample configuration can be found in < code > resources/activemq-beans.xml< / code > , firstly we define the
2014-10-31 06:20:28 -04:00
Bridge itself:< / p >
< pre class = "prettyprint" >
< !-- The JMS Bridge -->
2014-11-17 09:23:06 -05:00
< bean name="JMSBridge" class="org.apache.activemq.jms.bridge.impl.JMSBridgeImpl">
2014-10-31 06:20:28 -04:00
...
< /bean>
< / pre >
< p > the < code > JMSBridgeImpl< / code > constructor is used to inject all the properties required to run the JMS Bridge.< / p >
< p > Its first four arguments defines how the bridge will lookup:< / p >
< ol >
< li > its < em > source< / em > JMS ConnectionFactory< / li >
< li > its < em > source< / em > JMS Destination< / li >
< li > its < em > target< / em > JMS ConnectionFactory< / li >
< li > its < em > target< / em > JMS Destination< / li >
< / ol >
< p > Using other POJOs, the JMS Bridge is configured to retrieve:< / p >
< ul >
< li > its < em > source< / em > JMS ConnectionFactory by looking up < code > /source/ConnectionFactory< / code > using
the < code > SourceJNDI< / code > configuration< / li >
< li > its < em > source< / em > JMS Destination by looking up < code > /source/topic< / code > using
the < code > SourceJNDI< / code > configuration< / li >
< li > its < em > target< / em > JMS ConnectionFactory by looking up < code > /target/ConnectionFactory< / code > using
the < code > TargetJNDI< / code > configuration< / li >
< li > its < em > target< / em > JMS ConnectionFactory by looking up < code > /target/queue< / code > using
the < code > TargetJNDI< / code > configuration< / li >
< / ul >
< p > In turn, < code > SourceJNDI< / code > and < code > TargetJNDI< / code > are POJOs defining how to connect to JNDI server.
SourceJNDI URL must point to your source server, while LocalJNDI must point to your target server:< / p >
< pre class = "prettyprint" >
< bean name="SourceJNDI" class="java.util.Hashtable">
...
< entry>
< key>java.naming.provider.url< /key>
< !-- **************************************** -->
< !-- Replace with the *source* server address -->
< !-- **************************************** -->
< value>jnp://192.168.0.10:1099< /value>
...
< /bean>
< bean name="TargetJNDI" class="java.util.Hashtable">
...
< ntry>
< key>java.naming.provider.url< /key>
< !-- **************************************** -->
< !-- Replace with the *target* server address -->
< !-- **************************************** -->
< value>jnp://1192.168.0.11:1099< /value>
< /entry>
...
< /bean>
< / pre >
< h2 > Example step-by-step< / h2 >
2014-11-19 03:44:57 -05:00
< p > To run the example after having setup both ActiveMQ servers and the JMS bridge:< / p >
2014-10-31 06:20:28 -04:00
< ol >
< li > To run the example simply run < code > mvn verify< / code > < / li >
< / ol >
< p > Let's look at the Client code (in < code > JMSBridgeExample< / code > class):< / p >
< ol >
< li > First we need to get an initial context so we can look-up the JMS resources< / li >
< pre class = "prettyprint" >
InitialContext sourceContext = createContext(sourceServer);
InitialContext targetContext = createContext(targetServer);
< / pre >
< li > We then create a JMS Bridge and start it, Note, the Bridge needs a transaction manager, in this instance we will use the JBoss TM< / li >
< pre class = "prettyprint" >
JMSBridge jmsBridge = new JMSBridgeImpl(
new JNDIConnectionFactoryFactory(sourceJndiParams, "/source/ConnectionFactory"),
new JNDIConnectionFactoryFactory(targetJndiParams, "/target/ConnectionFactory"),
new JNDIDestinationFactory(sourceJndiParams, "/source/topic"),
new JNDIDestinationFactory(targetJndiParams, "/target/queue"),
null,
null,
null,
null,
null,
5000,
10,
QualityOfServiceMode.ONCE_AND_ONLY_ONCE,
1,
-1,
null,
null,
true);
jmsBridge.setTransactionManager(new TransactionManagerImple());
....
jmsBridge.start();
< / pre >
< li > We look up the JMS resources from the Source server< / li >
< pre class = "prettyprint" >
ConnectionFactory sourceConnectionFactory = (ConnectionFactory)sourceContext.lookup("/source/ConnectionFactory");
Topic sourceTopic = (Topic)sourceContext.lookup("/source/topic");
< / pre >
< li > We create JMS objects to send a message to the source destination< / li >
< pre class = "prettyprint" >
sourceConnection = sourceConnectionFactory.createConnection();
Session sourceSession = sourceConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer sourceProducer = sourceSession.createProducer(sourceTopic);
< / pre >
< li > We send a message to the source destination< / li >
< pre class = "prettyprint" >
TextMessage message = sourceSession.createTextMessage("this is a text message sent at " + System.currentTimeMillis());
sourceProducer.send(message);
< / pre >
< li > We close the connection to the source server< / li >
< pre class = "prettyprint" >
sourceConnection.close();
< / pre >
< p > At this point, the JMS Bridge will consume the message from the source topic and
sends it to the target queue.
The client will check the bridge works by consuming a message from the target queue.< / p >
< li > We look up the JMS resources from the target server< / li >
< pre class = "prettyprint" >
ConnectionFactory targetConnectionFactory = (ConnectionFactory)targetContext.lookup("/target/ConnectionFactory");
Queue targetQueue = (Queue)targetContext.lookup("/target/queue");
< / pre >
< li > We create JMS objects to receive a message from the target destination< / li >
< pre class = "prettyprint" >
targetConnection = targetConnectionFactory.createConnection();
Session targetSession = targetConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageConsumer targetConsumer = targetSession.createConsumer(targetQueue);
< / pre >
< li > We start the target connection to start receiving messages
< pre class = "prettyprint" >
targetConnection.start();
< / pre >
< li > We receive the message and print it. Its content is the same than the message
the client sent to the source topic< / li >
< pre class = "prettyprint" >
TextMessage messageReceived = (TextMessage)targetConsumer.receive(5000);
< / pre >
< li > We display the message ID and its "bridged" message ID< / li >
< pre class = "prettyprint" >
System.out.format("Message ID : %s\n", messageReceived.getJMSMessageID());
System.out.format("Bridged Message ID : %s\n", messageReceived.getStringProperty("HQ_BRIDGE_MSG_ID_LIST"));
< / pre >
< p > Note that the message received from the target queue is < em > not the same message< / em > sent to the source topic
(their message IDs are different) but they have the < em > same content< / em > .
< li > And finally, we stop the Bridge and < b > always< / b > remember to close your 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" >
< code > finally
{
if (jmsBridge != null)
{
jmsBridge.stop();
}
if (initialContext != null)
{
initialContext.close();
}
if (connection != null)
{
connection.close();
}
}< / code >
< / pre >
< / ol >
< h2 > More information< / h2 >
< ul >
< li > User Manual's < a href = "../../../docs/user-manual/en/html_single/appserver-integration.html#jms-bridge" > JMS Bridge chapter< / a > < / li >
< li > The < a href = "../../javaee/jms-bridge/readme.html" > Java EE JMS Bridge example< / a > shows how to configure a JMS Bridge
inside JBoss Application Server to bridge destinations from the same server.< / a >
< / p >
< / body >
< / html >