Package org.hornetq.tests.integration.cluster.topology

Source Code of org.hornetq.tests.integration.cluster.topology.TopologyClusterTestBase

/*
* Copyright 2010 Red Hat, Inc.
* Red Hat licenses this file to you under the Apache License, version
* 2.0 (the "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*    http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied.  See the License for the specific language governing
* permissions and limitations under the License.
*/

package org.hornetq.tests.integration.cluster.topology;

import static java.util.concurrent.TimeUnit.SECONDS;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

import org.hornetq.api.core.HornetQException;
import org.hornetq.api.core.Pair;
import org.hornetq.api.core.TransportConfiguration;
import org.hornetq.api.core.client.ClientSession;
import org.hornetq.api.core.client.ClientSessionFactory;
import org.hornetq.api.core.client.ClusterTopologyListener;
import org.hornetq.api.core.client.ServerLocator;
import org.hornetq.core.client.impl.ServerLocatorImpl;
import org.hornetq.core.logging.Logger;
import org.hornetq.core.server.HornetQServer;
import org.hornetq.core.server.cluster.ClusterConnection;
import org.hornetq.core.server.cluster.ClusterManager;
import org.hornetq.tests.integration.cluster.distribution.ClusterTestBase;
import org.hornetq.tests.util.RandomUtil;

/**
* A TopologyClusterTestBase
*
* @author <a href="mailto:jmesnil@redhat.com">Jeff Mesnil</a>
*
*
*/
public abstract class TopologyClusterTestBase extends ClusterTestBase
{

   // Constants -----------------------------------------------------

   // Attributes ----------------------------------------------------

   // Static --------------------------------------------------------

   // Constructors --------------------------------------------------

   // Public --------------------------------------------------------

   // Package protected ---------------------------------------------

   // Protected -----------------------------------------------------

   private static final Logger log = Logger.getLogger(TopologyClusterTestBase.class);

   private static final long WAIT_TIMEOUT = 5000;

   abstract protected ServerLocator createHAServerLocator();

   abstract protected void setupServers() throws Exception;

   abstract protected void setupCluster() throws Exception;

   abstract protected boolean isNetty() throws Exception;

   protected boolean isFileStorage()
   {
      return false;
   }

   @Override
   protected void setUp() throws Exception
   {
      super.setUp();

      setupServers();

      setupCluster();
   }

   @Override
   protected void tearDown() throws Exception
   {
      stopServers(0, 1, 2, 3, 4);

      super.tearDown();
   }

   /**
    * Check that the actual list of received nodeIDs correspond to the expected order of nodes
    */
   protected void checkOrder(int[] expected, String[] nodeIDs, List<String> actual)
   {
      assertEquals(expected.length, actual.size());
      for (int i = 0; i < expected.length; i++)
      {
         assertEquals("did not receive expected nodeID at " + i, nodeIDs[expected[i]], actual.get(i));
      }
   }

   protected void checkContains(int[] expected, String[] nodeIDs, List<String> actual)
   {
      long start = System.currentTimeMillis();
      do
      {
         if (expected.length != actual.size())
         {
            continue;
         }
         boolean ok = true;
         for (int i = 0; i < expected.length; i++)
         {
            ok = (ok && actual.contains(nodeIDs[expected[i]]));
         }
         if (ok)
         {
            return;
         }
      }
      while (System.currentTimeMillis() - start < 5000);
      fail("did not contain all expected node ID: " + actual);
   }

   protected String[] getNodeIDs(int... nodes)
   {
      String[] nodeIDs = new String[nodes.length];
      for (int i = 0; i < nodes.length; i++)
      {
         nodeIDs[i] = servers[i].getNodeID().toString();
      }
      return nodeIDs;
   }

   protected ClientSession checkSessionOrReconnect(ClientSession session, ServerLocator locator) throws Exception
   {
      try
      {
         String rand = RandomUtil.randomString();
         session.createQueue(rand, rand);
         session.deleteQueue(rand);
         return session;
      }
      catch (HornetQException e)
      {
         if (e.getCode() == HornetQException.OBJECT_CLOSED || e.getCode() == HornetQException.UNBLOCKED)
         {
            ClientSessionFactory sf = locator.createSessionFactory();
            return sf.createSession();
         }
         else
         {
            throw e;
         }
      }
   }

   protected void waitForClusterConnections(final int node, final int count) throws Exception
   {
      HornetQServer server = servers[node];

      if (server == null)
      {
         throw new IllegalArgumentException("No server at " + node);
      }

      ClusterManager clusterManager = server.getClusterManager();

      long start = System.currentTimeMillis();

      do
      {
         int nodesCount = 0;

         for (ClusterConnection clusterConn : clusterManager.getClusterConnections())
         {
            Map<String, String> nodes = clusterConn.getNodes();
            for (String id : nodes.keySet())
            {
               if (clusterConn.isNodeActive(id))
               {
                  nodesCount++;
               }
            }
         }

         if (nodesCount == count)
         {
            return;
         }

         Thread.sleep(10);
      }
      while (System.currentTimeMillis() - start < WAIT_TIMEOUT);

      log.error(clusterDescription(servers[node]));
      throw new IllegalStateException("Timed out waiting for cluster connections ");
   }

  
   public void testReceiveNotificationsWhenOtherNodesAreStartedAndStopped() throws Throwable
   {
      startServers(0);

      ServerLocator locator = createHAServerLocator();

      try
      {
         ((ServerLocatorImpl)locator).getTopology().setOwner("testReceive");

         final List<String> nodes = new ArrayList<String>();
         final CountDownLatch upLatch = new CountDownLatch(5);
         final CountDownLatch downLatch = new CountDownLatch(4);

         locator.addClusterTopologyListener(new ClusterTopologyListener()
         {
            public void nodeUP(final long uniqueEventID,
                               String nodeID,
                               Pair<TransportConfiguration, TransportConfiguration> connectorPair,
                               boolean last)
            {
               if (!nodes.contains(nodeID))
               {
                  System.out.println("Node UP " + nodeID + " added");
                  log.info("Node UP " + nodeID + " added");
                  nodes.add(nodeID);
                  upLatch.countDown();
               }
               else
               {
                  System.out.println("Node UP " + nodeID + " was already here");
                  log.info("Node UP " + nodeID + " was already here");
               }
            }

            public void nodeDown(final long uniqueEventID, String nodeID)
            {
               if (nodes.contains(nodeID))
               {
                  log.info("Node down " + nodeID + " accepted");
                  System.out.println("Node down " + nodeID + " accepted");
                  nodes.remove(nodeID);
                  downLatch.countDown();
               }
               else
               {
                  log.info("Node down " + nodeID + " already removed");
                  System.out.println("Node down " + nodeID + " already removed");
               }
            }
         });

         ClientSessionFactory sf = locator.createSessionFactory();

         startServers(1, 4, 3, 2);
         String[] nodeIDs = getNodeIDs(0, 1, 2, 3, 4);

         assertTrue("Was not notified that all servers are UP", upLatch.await(10, SECONDS));
         checkContains(new int[] { 0, 1, 4, 3, 2 }, nodeIDs, nodes);

         waitForClusterConnections(0, 4);
         waitForClusterConnections(1, 4);
         waitForClusterConnections(2, 4);
         waitForClusterConnections(3, 4);
         waitForClusterConnections(4, 4);

         stopServers(2, 3, 1, 4);

         assertTrue("Was not notified that all servers are DOWN", downLatch.await(10, SECONDS));
         checkContains(new int[] { 0 }, nodeIDs, nodes);

         sf.close();
      }
      finally
      {
         locator.close();

         stopServers(0);
      }

   }

   public void testReceiveNotifications() throws Throwable
   {
      startServers(0, 1, 2, 3, 4);
      String[] nodeIDs = getNodeIDs(0, 1, 2, 3, 4);

      ServerLocator locator = createHAServerLocator();

      try
      {

         waitForClusterConnections(0, 4);
         waitForClusterConnections(1, 4);
         waitForClusterConnections(2, 4);
         waitForClusterConnections(3, 4);
         waitForClusterConnections(4, 4);

         final List<String> nodes = new ArrayList<String>();
         final CountDownLatch upLatch = new CountDownLatch(5);
         final CountDownLatch downLatch = new CountDownLatch(4);

         locator.addClusterTopologyListener(new ClusterTopologyListener()
         {
            public void nodeUP(final long uniqueEventID,
                               String nodeID,
                               Pair<TransportConfiguration, TransportConfiguration> connectorPair,
                               boolean last)
            {
               if (!nodes.contains(nodeID))
               {
                  nodes.add(nodeID);
                  upLatch.countDown();
               }
            }

            public void nodeDown(final long uniqueEventID, String nodeID)
            {
               if (nodes.contains(nodeID))
               {
                  nodes.remove(nodeID);
                  downLatch.countDown();
               }
            }
         });

         ClientSessionFactory sf = locator.createSessionFactory();

         assertTrue("Was not notified that all servers are UP", upLatch.await(10, SECONDS));
         checkContains(new int[] { 0, 1, 2, 3, 4 }, nodeIDs, nodes);

         ClientSession session = sf.createSession();

         stopServers(0);
         session = checkSessionOrReconnect(session, locator);
         checkContains(new int[] { 1, 2, 3, 4 }, nodeIDs, nodes);

         stopServers(2);
         session = checkSessionOrReconnect(session, locator);
         checkContains(new int[] { 1, 3, 4 }, nodeIDs, nodes);

         stopServers(4);
         session = checkSessionOrReconnect(session, locator);
         checkContains(new int[] { 1, 3 }, nodeIDs, nodes);

         stopServers(3);
         session = checkSessionOrReconnect(session, locator);
         checkContains(new int[] { 1 }, nodeIDs, nodes);

         stopServers(1);

         assertTrue("Was not notified that all servers are DOWN", downLatch.await(10, SECONDS));
         checkContains(new int[] {}, nodeIDs, nodes);

         sf.close();
      }
      finally
      {
         locator.close();
      }

   }


   public void testStopNodes() throws Throwable
   {
      startServers(0, 1, 2, 3, 4);
      String[] nodeIDs = getNodeIDs(0, 1, 2, 3, 4);

      ServerLocator locator = createHAServerLocator();

      try
      {
         waitForClusterConnections(0, 4);
         waitForClusterConnections(1, 4);
         waitForClusterConnections(2, 4);
         waitForClusterConnections(3, 4);
         waitForClusterConnections(4, 4);

         final List<String> nodes = new ArrayList<String>();
         final CountDownLatch upLatch = new CountDownLatch(5);

         locator.addClusterTopologyListener(new ClusterTopologyListener()
         {
            public void nodeUP(final long uniqueEventID,
                               String nodeID,
                               Pair<TransportConfiguration, TransportConfiguration> connectorPair,
                               boolean last)
            {
               if (!nodes.contains(nodeID))
               {
                  nodes.add(nodeID);
                  upLatch.countDown();
               }
            }

            public void nodeDown(final long uniqueEventID, String nodeID)
            {
               if (nodes.contains(nodeID))
               {
                  nodes.remove(nodeID);
               }
            }
         });

         ClientSessionFactory sf = locator.createSessionFactory();

         assertTrue("Was not notified that all servers are UP", upLatch.await(10, SECONDS));
         checkContains(new int[] { 0, 1, 2, 3, 4 }, nodeIDs, nodes);

         ClientSession session = sf.createSession();

         stopServers(0);
         assertFalse(servers[0].isStarted());
         session = checkSessionOrReconnect(session, locator);
         checkContains(new int[] { 1, 2, 3, 4 }, nodeIDs, nodes);

         stopServers(2);
         assertFalse(servers[2].isStarted());
         session = checkSessionOrReconnect(session, locator);
         checkContains(new int[] { 1, 3, 4 }, nodeIDs, nodes);

         stopServers(4);
         assertFalse(servers[4].isStarted());
         session = checkSessionOrReconnect(session, locator);
         checkContains(new int[] { 1, 3 }, nodeIDs, nodes);

         stopServers(3);
         assertFalse(servers[3].isStarted());

         session = checkSessionOrReconnect(session, locator);
         checkContains(new int[] { 1 }, nodeIDs, nodes);

         stopServers(1);
         assertFalse(servers[1].isStarted());
         try
         {
            session = checkSessionOrReconnect(session, locator);
            fail();
         }
         catch (Exception e)
         {

         }
      }
      finally
      {
         locator.close();
      }

   }

   public void testMultipleClientSessionFactories() throws Throwable
   {
      startServers(0, 1, 2, 3, 4);
      String[] nodeIDs = getNodeIDs(0, 1, 2, 3, 4);

      ServerLocator locator = createHAServerLocator();

      try
      {

         waitForClusterConnections(0, 4);
         waitForClusterConnections(1, 4);
         waitForClusterConnections(2, 4);
         waitForClusterConnections(3, 4);
         waitForClusterConnections(4, 4);

         final List<String> nodes = new ArrayList<String>();
         final CountDownLatch upLatch = new CountDownLatch(5);
         final CountDownLatch downLatch = new CountDownLatch(4);

         locator.addClusterTopologyListener(new ClusterTopologyListener()
         {
            public void nodeUP(final long uniqueEventID,
                               String nodeID,
                               Pair<TransportConfiguration, TransportConfiguration> connectorPair,
                               boolean last)
            {
               if (!nodes.contains(nodeID))
               {
                  nodes.add(nodeID);
                  upLatch.countDown();
               }
            }

            public void nodeDown(final long uniqueEventID, String nodeID)
            {
               if (nodes.contains(nodeID))
               {
                  nodes.remove(nodeID);
                  downLatch.countDown();
               }
            }
         });

         ClientSessionFactory[] sfs = new ClientSessionFactory[] { locator.createSessionFactory(),
                                                                  locator.createSessionFactory(),
                                                                  locator.createSessionFactory(),
                                                                  locator.createSessionFactory(),
                                                                  locator.createSessionFactory() };
         assertTrue("Was not notified that all servers are UP", upLatch.await(10, SECONDS));
         checkContains(new int[] { 0, 1, 2, 3, 4 }, nodeIDs, nodes);

         // we cant close all of the servers, we need to leave one up to notify us
         stopServers(4, 2, 3, 1);

         boolean ok = downLatch.await(10, SECONDS);
         if (!ok)
         {
            log.warn("TopologyClusterTestBase.testMultipleClientSessionFactories will fail");
         }
         assertTrue("Was not notified that all servers are Down", ok);
         checkContains(new int[] { 0 }, nodeIDs, nodes);

         for (int i = 0; i < sfs.length; i++)
         {
            ClientSessionFactory sf = sfs[i];
            sf.close();
         }
      }
      finally
      {
         locator.close();

         stopServers(0);
      }

   }

   // Private -------------------------------------------------------

   // Inner classes -------------------------------------------------

}
TOP

Related Classes of org.hornetq.tests.integration.cluster.topology.TopologyClusterTestBase

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.