Package com.linkedin.databus.cluster

Source Code of com.linkedin.databus.cluster.TestDatabusCluster$TestDatabusClusterNotifier

package com.linkedin.databus.cluster;
/*
*
* Copyright 2013 LinkedIn Corp. All rights reserved
*
* Licensed 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.
*
*/


import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import junit.framework.Assert;

import org.I0Itec.zkclient.ZkServer;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import com.linkedin.databus.client.registration.ClusterRegistrationStaticConfig;
import com.linkedin.databus.cluster.DatabusCluster.DatabusClusterMember;
import com.linkedin.databus.core.util.FileUtils;
import com.linkedin.databus.core.util.Utils;
import com.linkedin.databus2.test.TestUtil;

public class TestDatabusCluster
{
    protected static final Logger LOG = Logger.getLogger(TestDatabusCluster.class);

  static final int localZkPort = Utils.getAvailablePort(2192);
  static final String zkAddr = "localhost:" + localZkPort;
  static final String clusterName = "test-databus-cluster";
  static List<ZkServer> _localZkServers = null;

  @BeforeClass
  public void startZookeeper() throws IOException
  {
      TestUtil.setupLogging(true, null, Level.WARN);
    File zkroot = FileUtils.createTempDir("TestDatabusCluster_zkroot");
    LOG.info("starting ZK on port " + localZkPort + " and datadir " + zkroot.getAbsolutePath());

    ZkServer zkServer = TestUtil.startZkServer(zkroot.getAbsolutePath(), 0, localZkPort, 2000);
    if (zkServer != null)
    {
      _localZkServers  = new Vector<ZkServer>(1);
      _localZkServers.add(zkServer);
    }
  }

  @AfterClass
  public void stopZookeeper()
  {
      if (_localZkServers != null)
      {
          TestUtil.stopLocalZookeeper(_localZkServers);
      }
  }

  public void runBasicDatabusClusterExpt(boolean createClusterConcurrently)
  {
      try
        {
            String cluster = clusterName;
            int startId = 100;
            int numClients = 4;
            int numPartitions = 10;
            int quorum=1;

            Vector<TestDatabusClusterNode> testClients = new Vector<TestDatabusClusterNode>(10);
            for (int i=0;i < numClients; i++)
            {
                Integer id = startId + i;
                TestDatabusClusterNode node = new TestDatabusClusterNode(id.toString(), cluster, numPartitions, quorum);
                if (!createClusterConcurrently)
                {
                    node.createCluster();
                }
                testClients.add(node);
            }

            //start the clients;
            for (TestDatabusClusterNode node: testClients)
            {
                node.start();
            }

            Thread.sleep(6*1000);

            LOG.info("Shutting down one of the clients ");
            testClients.get(numClients-1).shutdown();
            testClients.get(numClients-1).join();

            Thread.sleep(2*1000);

            //Start another client;
            Integer id = startId + numClients;
            testClients.add(new TestDatabusClusterNode(id.toString(), cluster, numPartitions, quorum));
            testClients.get(numClients).start();

            Thread.sleep(10*1000);

            //stop the clients;
            int assignedPartitions = 0;
            for (TestDatabusClusterNode node: testClients)
            {
                node.shutdown();
                node.join(2000);
                Assert.assertTrue(!node.isAlive());
                Vector<Integer> p = node.getPartitions();
                assignedPartitions += p.size();
                LOG.info("Node: " + node.getIdentifier() + " received " + p.size() + " partitions ");
            }
            Assert.assertTrue(assignedPartitions>=numPartitions);
        }
        catch(InterruptedException e)
        {
            Assert.assertTrue(false);
        }
        catch (Exception e)
        {
            LOG.error("run failed! " + e.getMessage());
            Assert.assertTrue(false);
        }

  }

  @Test
  public void testDatabusCluster()
  {
    runBasicDatabusClusterExpt(false);
  }

  @Test
  public void testLeaderFollower()
  {
      try
        {
            String cluster = "leader-follower";
            int startId = 100;
            int numClients = 4;
            int numPartitions = 1;
            int quorum=1;

            Vector<TestDatabusClusterNode> testClients = new Vector<TestDatabusClusterNode>(10);
            for (int i=0;i < numClients; i++)
            {
                Integer id = startId + i;
                TestDatabusClusterNode node = new TestDatabusClusterNode(id.toString(), cluster, numPartitions, quorum);
                node.createCluster();
                testClients.add(node);
            }

            //start the clients;
            for (TestDatabusClusterNode node: testClients)
            {
                node.start();
            }

            Thread.sleep(6*1000);

            LOG.info("Shutting down one of the clients ");
            testClients.get(numClients-1).shutdown();
            testClients.get(numClients-1).join();

            Thread.sleep(2*1000);
            //Start another client;
            Integer id = startId + numClients;
            testClients.add(new TestDatabusClusterNode(id.toString(), cluster, numPartitions, quorum));
            testClients.get(numClients).start();

            Thread.sleep(10*1000);

            //stop the clients;
            int assignedPartitions = 0;
            for (TestDatabusClusterNode node: testClients)
            {
                node.shutdown();
                node.join(2000);
                Assert.assertTrue(!node.isAlive());
                Vector<Integer> p = node.getPartitions();
                assignedPartitions += p.size();
                LOG.info("Node: " + node.getIdentifier() + " received " + p.size() + " partitions ");
            }
            Assert.assertTrue(assignedPartitions>=numPartitions);

        }
        catch(InterruptedException e)
        {
            Assert.assertTrue(false);
        }
      catch (Exception e)
      {
          Assert.assertTrue(false);
      }
  }

  @Test
  public void testConcurrentClusterCreation()
  {
      //create TestNode concurrently;
      runBasicDatabusClusterExpt(true);
  }

  /**
   *
   * @author snagaraj
   *  client nodes;
   */
  public class TestDatabusClusterNode extends Thread
  {

    private DatabusCluster _cluster = null;
    private DatabusClusterMember _member = null;
    private TestDatabusClusterNotifier _notifier = null;
    private final String _id;
    private volatile boolean _shutdown = false;
    private final int _quorum;
    private final int _numPartitions;
    private final String _clusterName;
    private boolean _error = false;

    public TestDatabusClusterNode(String id,String clusterName, int numPartitions, int quorum)
    {
        super("testClusterNode_"+id);
        _id = id;
            _clusterName = clusterName;
        _numPartitions = numPartitions;
        _quorum = quorum;
    }

    public  void createCluster() throws Exception
    {
        ClusterRegistrationStaticConfig c =
                  new ClusterRegistrationStaticConfig(_clusterName, zkAddr, _numPartitions, _quorum, 0,5*60*1000, 30*1000, 60*100);
        _cluster = new DatabusCluster(c);
        LOG.warn("Created cluster object! " + _clusterName + " id = " + _id);
            _notifier = new TestDatabusClusterNotifier(_id);
            //get global and local allocation notifications
            _cluster.addDataNotifier(_notifier);
            _member = _cluster.addMember(_id,_notifier);
    }

    public String getIdentifier()
    {
        return _id;
    }

    public boolean isError()
    {
        return _error;
    }

    @Override
    public void run()
    {
        try
        {
            LOG.warn("Started TestDatabusClusterNode for id= " + _id);
            if (_cluster==null)
            {
                createCluster();
            }
               LOG.warn("Created TestDatabusClusterNode for id= " + _id);
            _cluster.start();
            if (_member==null)
            {
                LOG.error("No member handle for  " + _id);
                _error=true;
                return;
            }
            boolean t = _member.join();
            if (t)
            {
                synchronized(this)
                {
                    while (!_shutdown)
                    {
                        try
                        {
                            wait();
                        }
                        catch (InterruptedException e)
                        {

                        }
                    }
                }
            }
            else
            {
                LOG.error("Join failed for client node:" + _id);
                   _error=true;
            }
        }
        catch (Exception e)
        {
            LOG.error("Exception in thread: " + _id + " = " + e.getMessage());
            _error=true;
        }
    }



    public void shutdown()
    {
      if (!_shutdown)
      {

        if (_member==null)
        {
          LOG.error("Shutting down failed for member " + _id);
          return;
        }
        _member.leave();
        _cluster.removeDataNotifier(_notifier);
        _cluster.shutdown();
        synchronized(this)
        {
          _shutdown = true;
          notifyAll();
        }
      }
    }

    public Vector<Integer> getPartitions()
    {
      return _notifier.getPartitions();
    }

  }

  public class TestDatabusClusterNotifier implements DatabusClusterNotifier,  DatabusClusterDataNotifier
  {

    final private String _id ;
    final private HashSet<Integer> _partitions;
    private String _leader;

    public TestDatabusClusterNotifier(String id)
    {
      _id = id;
      _partitions = new HashSet<Integer>(10);
    }

    @Override
    public void onGainedPartitionOwnership(int partition)
    {
      synchronized (this)
      {
          if (!_partitions.contains(partition))
          {
              _partitions.add(partition);
          }
          else
          {
              LOG.warn("Node " + _id + " Adding partition before removing. p=" + partition);
          }
      }
    }

    @Override
    public void onLostPartitionOwnership(int partition)
    {
       synchronized (this)
       {
                 LOG.warn("Node " + _id + " Removing partition  p=" + partition);
         _partitions.remove(partition);
       }
    }

    @Override
    public void onError(int partition)
    {
      LOG.warn("Node " + _id + " removed error " + partition );
    }

    @Override
    public void onReset(int partition)
    {
      LOG.warn("Node " + _id + " received reset " + partition );
    }

    public synchronized Vector<Integer> getPartitions()
    {
      Vector<Integer> p = new Vector<Integer>(_partitions.size());
      Iterator<Integer> it = _partitions.iterator();
      while (it.hasNext())
      {
        p.add(it.next());
      }
      return p;
    }

        @Override
        public void onInstanceChange(List<String> activeNodes)
        {
            //no op

        }

        @Override
        public void onPartitionMappingChange(
                Map<Integer, String> activePartitionMap)
        {
            synchronized (this)
            {
                String leader = activePartitionMap.get(0);
                if ((leader != null) && (_leader==null || !_leader.equals(leader)))
                {
                    _leader=leader;
                    LOG.warn("Id: " + _id + " New Leader found! " + _leader );
                }
            }
        }

        synchronized String getLeader()
        {
            return _leader;
        }

  }


}
TOP

Related Classes of com.linkedin.databus.cluster.TestDatabusCluster$TestDatabusClusterNotifier

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.