All Downloads are FREE. Search and download functionalities are using the official Maven repository.

examples.jms.jms-bridge.readme.html Maven / Gradle / Ivy

The newest version!

  
    HornetQ JMS Bridge Example
    
    
    
  
  
     

JMS Bridge Example

This example shows you how to setup a JMS Bridge between two HornetQ servers.

The example will use two HornetQ servers:

  • Server #0 – the Source server. It will be configured with a JMS Topic bound to JNDI under /source/topic
  • Server #1 – the Target server. It will be configured with a JMS Queue bound to JNDI under /target/queue

Both HornetQ server will run their own JNDI server used by the JMS Bridge and the JMS Client to lookup JMS resources (ConnectionFactory and Destination).

The JMS Bridge will run inside the target server and is configured to bridge messages from the source destination (the topic hosted on server #0) and the target destination (the queue hosted on server #1)

The client will check the bridge works by:

  1. sending a message to the source topic
  2. receive a message from the target queue
  3. check that both messages correspond to the same content.

Please note that this example is meant to run on 2 different machines. If you want to run it on a single machine, you will have also to make sure that the HornetQ servers do not share any ports.

Example Configuration

To run this example on 2 machines, you will need to adapt the configuration to your machines:

  1. Setup the source server address so that both the JMS bridge and the JMS client can connect to its JNDI server and send/receive message from it
  2. Setup the target server so that both the JMS bridge and the JMS client can connect to its JNDI server and send/receive message from it
  3. Setup the JMS Bridge configuration so that it can receive message from the source topic and send them to the target queue

As an example, I will use the following network addresses to show how to configure the example:

  • Server #0 – 192.168.0.10
  • Server #1 – 192.168.0.11

First, make sure that HornetQ is setup and installed on both servers

Then, you will have to adapt each server configuration on their respective servers:

  • Server #0 configuration (located in server0/) must be changed on Server #0
  • Server #1 configuration (located in server1/) must be changed on Server #1

Source Server Configuration

On server #0, in server0/hornetq-beans.xml, setup the JNDI server network address by replacing @SOURCE_SERVER@ by the source server address (e.g. 192.168.0.10):

        <bean name="JNDIServer" class="org.jnp.server.Main">
           ...
           <!-- **************************************** -->
           <!-- Replace with the *source* server address -->
           <!-- **************************************** -->
           <property name="bindAddress">192.168.0.10</property>
           <!-- **************************************** -->
           <!-- Replace with the *source* server address -->
           <!-- **************************************** -->
           <property name="rmiBindAddress">192.168.0.10</property>
           ...
        </bean>
     

In server0/hornetq-configuration.xml, configure a Netty connector with the source server address:

        <connectors>
           <connector name="netty">
              <factory-class>org.hornetq.core.remoting.impl.netty.NettyConnectorFactory</factory-class>
              <!-- **************************************** -->
              <!-- Replace with the *source* server address -->
              <!-- **************************************** -->
              <param key="hornetq.remoting.netty.host" value="192.168.0.10" type="String"/>
           </connector>
        </connectors>
     

Note that in server0/hornetq-configuration.xml, we also setup the Netty acceptor to accept connections from any of the source server addresses (by specifying 0.0.0.0)

The source server defines two JMS resources in server0/hornetq-jms.xml:

  • A JMS ConnectionFactory bound to /source/ConnectionFactory
  • A JMS Topic bound to /source/topic

Target Server Configuration

On server #1, in server1/hornetq-beans.xml, setup the JNDI server network address by replacing @TARGET_SERVER@ by the target server address (e.g. 192.168.0.11):

        <bean name="JNDIServer" class="org.jnp.server.Main">
           ...
           <!-- **************************************** -->
           <!-- Replace with the *target* server address -->
           <!-- **************************************** -->
           <property name="bindAddress">192.168.0.11</property>
           <!-- **************************************** -->
           <!-- Replace with the *target* server address -->
           <!-- **************************************** -->
           <property name="rmiBindAddress">192.168.0.11</property>
           ...
        </bean>
     

In server1/hornetq-configuration.xml, configure a Netty connector with the target server address:

        <connectors>
           <connector name="netty">
              <factory-class>org.hornetq.core.remoting.impl.netty.NettyConnectorFactory</factory-class>
              <!-- **************************************** -->
              <!-- Replace with the *target* server address -->
              <!-- **************************************** -->
              <param key="hornetq.remoting.netty.host" value="192.168.0.11" type="String"/>
           </connector>
        </connectors>
     

Note that in server1/hornetq-configuration.xml, we also setup the Netty acceptor to accept connections from any of the target server addresses (by specifying 0.0.0.0)

The target server defines two JMS resources in server1/hornetq-jms.xml:

  • A JMS ConnectionFactory bound to /target/ConnectionFactory
  • A JMS Queue bound to /target/queue

JMS Bridge Configuration

The JMS Bridge is a POJO 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.

The JMS Bridge is defined by the JMSBridge bean in server1/hornetq-beans.xml:

         <!-- The JMS Bridge -->
         <bean name="JMSBridge" class="org.hornetq.jms.bridge.impl.JMSBridgeImpl">
         ...
         </bean>
      

the JMSBridgeImpl constructor is used to inject all the properties required to run the JMS Bridge.

Its first four arguments defines how the bridge will lookup:

  1. its source JMS ConnectionFactory
  2. its source JMS Destination
  3. its target JMS ConnectionFactory
  4. its target JMS Destination

Using other POJOs, the JMS Bridge is configured to retrieve:

  • its source JMS ConnectionFactory by looking up /source/ConnectionFactory using the SourceJNDI configuration
  • its source JMS Destination by looking up /source/topic using the SourceJNDI configuration
  • its target JMS ConnectionFactory by looking up /target/ConnectionFactory using the TargetJNDI configuration
  • its target JMS ConnectionFactory by looking up /target/queue using the TargetJNDI configuration

In turn, SourceJNDI and TargetJNDI 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:

      <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>
      

Example step-by-step

To run the example after having setup both HornetQ servers and the JMS bridge:

  1. on Server #0, run ./build.sh source-server
  2. on Server #1, run ./build.sh target-server (this will start the JMS Bridge too)
  3. on either server, run the client: ./build.sh client -Dsource=<source server address> -Dtarget=<target server address> (for example: ./build.sh client -Dsource=192.168.0.11 -Dtarget=192.168.0.11)

Let's look at the Client code (in JMSBridgeExample class):

  1. First we need to get an initial context so we can look-up the JMS resources (using the source and target server addresses passed as arguments to ./build.sh client)
  2.            InitialContext sourceContext = createContext(sourceServer);
               InitialContext targetContext = createContext(targetServer);
            
  3. We look up the JMS resources from the Source server
  4.            ConnectionFactory sourceConnectionFactory = (ConnectionFactory)sourceContext.lookup("/source/ConnectionFactory");
               Topic sourceTopic = (Topic)sourceContext.lookup("/source/topic");
            
  5. We create JMS objects to send a message to the source destination
  6.            sourceConnection = sourceConnectionFactory.createConnection();
               Session sourceSession = sourceConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
               MessageProducer sourceProducer = sourceSession.createProducer(sourceTopic);
            
  7. We send a message to the source destination
  8.            TextMessage message = sourceSession.createTextMessage("this is a text message sent at " + System.currentTimeMillis());
               sourceProducer.send(message);
            
  9. We close the connection to the source server
  10.            sourceConnection.close();
            

    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.

  11. We look up the JMS resources from the target server
  12.            ConnectionFactory targetConnectionFactory = (ConnectionFactory)targetContext.lookup("/target/ConnectionFactory");
               Queue targetQueue = (Queue)targetContext.lookup("/target/queue");
            
  13. We create JMS objects to receive a message from the target destination
  14.            targetConnection = targetConnectionFactory.createConnection();
               Session targetSession = targetConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
               MessageConsumer targetConsumer = targetSession.createConsumer(targetQueue);
           
  15. We start the target connection to start receiving messages
               targetConnection.start();
            
  16. We receive the message and print it. Its content is the same than the message the client sent to the source topic
  17.            TextMessage messageReceived = (TextMessage)targetConsumer.receive(5000);
            
  18. We display the message ID and its "bridged" message ID
  19.            System.out.format("Message ID         : %s\n", messageReceived.getJMSMessageID());
               System.out.format("Bridged Message ID : %s\n", messageReceived.getStringProperty("HQ_BRIDGE_MSG_ID_LIST"));
            

    Note that the message received from the target queue is not the same message sent to the source topic (their message IDs are different) but they have the same content.

  20. And finally, always remember to close your JMS connections and resources after use, in a finally block. Closing a JMS connection will automatically close all of its sessions, consumers, producer and browser objects
  21.            finally
               {
                  if (initialContext != null)
                  {
                    initialContext.close();
                  }
                  if (connection != null)
                  {
                     connection.close();
                  }
               }
            

More information





© 2015 - 2025 Weber Informatics LLC | Privacy Policy