activemq-artemis/examples/jms/application-layer-failover
Clebert Suconic 3c44e26854 ACTIVEMQ6-3 renaming directories from activemq6 to activemq
https://issues.apache.org/jira/browse/ACTIVEMQ6-3

We are renaming packages from activemq6 to activemq as that's more generic and version independent
On this first commit I'm just renaming the directories otherwise the history would be lost. The next commit will rename the text on the directories.
If I squash these two commits git will make us delete / add again.
2014-11-17 09:33:36 -05:00
..
src/main ACTIVEMQ6-3 renaming directories from activemq6 to activemq 2014-11-17 09:33:36 -05:00
pom.xml Use new package names in config and classes 2014-11-11 18:28:18 +00:00
readme.html ACTIVEMQ6-1 - Initial HornetQ Donation Commit 2014-11-10 10:31:25 -06:00

readme.html

<html>
  <head>
    <title>HornetQ Application-Layer Failover 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>Application-Layer Failover Example</h1>

     <p>HornetQ implements fully transparent <b>automatic</b> failover of connections from a live node to a backup node which requires
     no special coding. This is described in a different example and requires server replication.</p>
     <p>However, HornetQ also supports <b>Application-Layer</b> failover which is useful in the case where replication is not enabled.</p>
     <p>With Application-Layer failover, it's up to the application to register a JMS ExceptionListener with HornetQ.
         This listener will then be called by HornetQ in the event that connection failure is detected.</p>
     <p>User code in the ExceptionListener can then recreate any JMS Connection, Session, etc on another node and the application
     can continue.</p>
     <p>Application-Layer failover is an alternative approach to High Availabilty (HA).</p>
     <p>Application-Layer failover differs from automatic failover in that some client side coding is required in order
     to implement this. Also, with Application-Layer failover, since the old Session object dies and a new is created, any uncommitted
     work in the old Session will be lost, and any unacknowledged messages might be redelivered.</p>    
     <p>For more information on HornetQ failover and HA, and clustering in general, please see the clustering
     section of the user manual.</p>      

     <h2>Example step-by-step</h2>
     <p><i>To run the example, simply type <code>mvn verify</code> from this directory</i></p>
     <p>In this example, the live server is server 1, which will failover onto server 0.</p>
     <p>The connection will initially be created to server1, server 1 will crash, and the client will carry on
     on server 0, the new  server. With Application-Layer failover the node that is failed over onto, does not need to
     be specially configured as a backup server, it can be any node.</p>

     <ol>
        <li> We create our JMS Connection, Session, MessageProducer and MessageConsumer on server 1</li>
        <pre class="prettyprint">
           <code>createJMSObjects(1);</code>
        </pre>

        <li>We set a JMS ExceptionListener on the connection. On failure this will be called and the connection,
         session, etc. will be manually recreated on the backup node.</li>
        <pre class="prettyprint">
           <code>connection.setExceptionListener(new ExampleListener());</code>
        </pre>

        <li>We send some messages to server 1, the live server.</li>
        <pre class="prettyprint">
           <code>
         final int numMessages = 10;

         for (int i = 0; i < numMessages; i++)
         {
            TextMessage message = session.createTextMessage("This is text message " + i);

            producer.send(message);

            System.out.println("Sent message: " + message.getText());
         }
           </code>
        </pre>

        <li>We consume those messages on server 1.</li>
        <pre class="prettyprint">
          <code>
          for (int i = 0; i < numMessages; i++)
         {
            TextMessage message0 = (TextMessage)consumer.receive(5000);

            System.out.println("Got message: " + message0.getText());
         }
          </code>
        </pre>
        
        <li>We now cause server 1, the live server to crash. After a little while the connection's
            ExceptionListener will register the failure and reconnection will occur.</li>
        <pre class="prettyprint">
           <code>killServer(1);</code>
        </pre>
        
        <li>The connection's ExceptionListener gets called, and we lookup the JMS objects and
        recreate the connection, session, etc on the other node 0.</li>
        <pre class="prettyprint">
           <code>
   private class ExampleListener implements ExceptionListener
   {
      public void onException(JMSException exception)
      {
         try
         {
            // Close the old resources

            closeResources();

            // Create new JMS objects on the backup server

            createJMSObjects(0);

            failoverLatch.countDown();
         }
         catch (Exception e)
         {
            System.err.println("Failed to handle failover");

            e.printStackTrace();
         }
      }
   }   
           </code>
        </pre>

        <li>We are now connected to the other node. We now send some more messages.</li>
        <pre class="prettyprint">
           <code>
   for (int i = numMessages; i < numMessages * 2; i++)
         {
            TextMessage message = session.createTextMessage("This is text message " + i);

            producer.send(message);

            System.out.println("Sent message: " + message.getText());
         }
           </code>
        </pre>
        
        <li>And consume them.</li>
        <pre class="prettyprint">
           <code>
   for (int i = 0; i < numMessages; i++)
         {
            TextMessage message0 = (TextMessage)consumer.receive(5000);

            System.out.println("Got message: " + message0.getText());
         }
           </code>
        </pre>


        <li>And finally (no pun intended), <b>always</b> remember to close your 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
	{
	   closeResources();
	}
           </code>
        </pre>

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