activemq-artemis/examples/jms/bridge
Andy Taylor 8ecd255f98 ACTIVEMQ6-1 - Initial HornetQ Donation Commit
https://issues.apache.org/jira/browse/ACTIVEMQ6-1

This is the initial donation of the HornetQ codebase as per document http://incubator.apache.org/ip-clearance/hornetq.html
2014-11-10 10:31:25 -06:00
..
src/main ACTIVEMQ6-1 - Initial HornetQ Donation Commit 2014-11-10 10:31:25 -06:00
pom.xml ACTIVEMQ6-1 - Initial HornetQ Donation Commit 2014-11-10 10:31:25 -06:00
readme.html ACTIVEMQ6-1 - Initial HornetQ Donation Commit 2014-11-10 10:31:25 -06:00

readme.html

<html>
  <head>
    <title>HornetQ Core 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>Core Bridge Example</h1>
     
     <p>This example demonstrates a core bridge deployed on one server, which consumes messages from a
     local queue and forwards them to an address on a second server.</p>
     
     <p>Core bridges are used to create message flows between any two HornetQ servers which are remotely separated.
     Core bridges are resilient and will cope with temporary connection failure allowing them to be an ideal
     choice for forwarding over unreliable connections, e.g. a WAN.</p>
     <p>They can also be configured with an optional filter expression, and will only forward messages that
     match that filter.</p>
     <p>Furthermore they can be configured to use an optional Transformer class. A user-defined Transformer class
     can be specified which is called at forwarding time. This gives the user the opportunity to transform
     the message in some ways, e.g. changing its properties or body</p>
     <p>HornetQ also includes a <b>JMS Bridge</b>. This is similar to a core bridge, but uses the JMS API
     and can be used to bridge between any two JMS 1.1 compliant messaging systems. The core bridge is limited to bridging
     between HornetQ instances, but may provide better performance than the JMS bridge. The JMS bridge is covered in
     a separate example.</p>
     <p>For more information on bridges, please see the HornetQ user manual.</p>

     <p>In this example we will demonstrate a simple sausage factory for aardvarks.</p>
     <p>We have a JMS queue on server 0 named <code>sausage-factory</code>, and we have a 
     JMS queue on server 1 named <code>mincing-machine</code></p>
     <p>We want to forward any messages that are sent to the <code>sausage-factory</code> queue on server 0, to the <code>mincing-machine</code>
     on server 1.</p>
     <p>We only want to make aardvark sausages, so we only forward messages where the property "name" is set
     to "aardvark". It is known that other things, such are Sasquatches are also sent to the <code>sausage-factory</code> and we
     want to reject those.</p>
     <p>Moreover it is known that Aardvarks normally wear blue hats, and it's important that we only make sausages using
     Aardvarks with green hats, so on the way we are going transform the property "hat" from "green" to "blue".</p>  
     <p>Here's a snippet from <code>hornetq-configuration.xml</code> showing the bridge configuration</p>
     <pre class="prettyprint">
     <code>
     &lt;bridge name="my-bridge"&gt;
          &lt;queue-name&gt;jms.queue.sausage-factory&lt;/queue-name&gt;
          &lt;forwarding-address&gt;jms.queue.mincing-machine&lt;/forwarding-address&gt;
          &lt;filter string="name='aardvark'"/&gt;
          &lt;transformer-class-name&gt;org.hornetq.jms.example.HatColourChangeTransformer&lt;/transformer-class-name&gt;
          &lt;reconnect-attempts&gt;-1&lt;/reconnect-attempts&gt;
          &lt;static-connectors>
             &lt;connector-ref>remote-connector&lt;/connector-ref>
          &lt;/static-connectors>
     &lt;/bridge&gt;
     </code>
     </pre>              
     <h2>Example step-by-step</h2>
     <p><i>To run the example, simply type <code>mvn verify</code> from this directory</i></p>

     <ol>
        <li>We create an initial context for looking up JNDI on node 0</li>
        <pre class="prettyprint">
           <code>
   ic0 = getContext(0);
   </code>
        </pre>

        <li>We look up the sausage-factory queue from node 0</li>
        <pre class="prettyprint">
           <code>Queue sausageFactory = (Queue)ic0.lookup("/queue/sausage-factory");</code>
        </pre>

        <li>We look up a JMS ConnectionFactory object from node 0</li>
        <pre class="prettyprint">
           <code>ConnectionFactory cf0 = (ConnectionFactory)ic0.lookup("/ConnectionFactory");</code>
        </pre>

        <li>We create an initial context for looking up JNDI on node 1</li>
        <pre class="prettyprint">
           <code>ic1 = getContext(1);</code>
        </pre>

        <li>We look up the mincing-machine queue on node 1</li>
        <pre class="prettyprint">
           <code>Queue mincingMachine = (Queue)ic1.lookup("/queue/mincing-machine");
           </code>
        </pre>

        <li>We look up a JMS ConnectionFactory object from node 1</li>
        <pre class="prettyprint">
          <code>
   ConnectionFactory cf1 = (ConnectionFactory)ic1.lookup("/ConnectionFactory");
          </code>
        </pre>
        
        <li>We create a JMS Connection connection0 which is a connection to server 0</li>
        <pre class="prettyprint">
          <code>
   connection0 = cf0.createConnection();
          </code>
        </pre>
        
        <li>We create a JMS Connection connection1 which is a connection to server 1</li>
        <pre class="prettyprint">
          <code>
   connection1 = cf1.createConnection();
          </code>
        </pre>

        <li>We create a JMS Session on server 0</li>
        <pre class="prettyprint">
           <code>
   Session session0 = connection0.createSession(false, Session.AUTO_ACKNOWLEDGE);
           </code>
        </pre>
        
        <li>We create a JMS Session on server 1</li>
        <pre class="prettyprint">
           <code>
   Session session1 = connection1.createSession(false, Session.AUTO_ACKNOWLEDGE);
            </code>
        </pre>

        <li>We start the connection to ensure delivery occurs on them</li>
        <pre class="prettyprint">
           <code>
   connection1.start();
           </code>
        </pre>

        <li>We create a JMS MessageConsumer object on server 1</li>
        <pre class="prettyprint">
           <code>
   MessageConsumer consumer = session1.createConsumer(mincingMachine);
           </code>
        </pre>

        <li>We create a JMS MessageProducer object on server 0.</li>
        <pre class="prettyprint">
           <code>
   MessageProducer producer = session0.createProducer(sausageFactory);</code>
        </pre>

        <li>We create and send a message representing an aardvark with a green hat to the sausage-factory
         on node 0</li>
        <pre class="prettyprint">
           <code>
         Message message = session0.createMessage();

         message.setStringProperty("name", "aardvark");

         message.setStringProperty("hat", "green");

         producer.send(message);
           </code>
        </pre>
        
        <li>We successfully receive the aardvark message from the mincing-machine one node 1. The aardvark's
         hat is now blue since it has been transformed!</li>
        <pre class="prettyprint">
           <code>
        Message receivedMessage = consumer.receive(5000);
           </code>
        </pre>
        
        <li>We create and send another message, this time representing a sasquatch with a mauve hat to the
          sausage-factory on node 0. This won't be bridged to the mincing-machine since we only want aardvarks, not sasquatches.</li>
        <pre class="prettyprint">
           <code>
         message = session0.createMessage();

         message.setStringProperty("name", "sasquatch");

         message.setStringProperty("hat", "mauve");

         producer.send(message);
           </code>
        </pre>
        
        <li>We don't receive the sasquatch message since it's not an aardvark!</li>
        <pre class="prettyprint">
           <code>
         receivedMessage = (TextMessage)consumer.receive(1000);
           </code>
        </pre>
        

        <li>And finally (no pun intended), <b>always</b> remember to close your JMS 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 (connection0 != null)
         {
            connection0.close();
         }

         if (connection1 != null)
         {
            connection1.close();
         }

         if (ic0 != null)
         {
            ic0.close();
         }

         if (ic1 != null)
         {
            ic1.close();
         }
	}
           </code>
        </pre>

     </ol>
  </body>
</html>