Package com.linkedin.databus.client.pub

Source Code of com.linkedin.databus.client.pub.TestDatabusClientNode$DummyClient

package com.linkedin.databus.client.pub;
/*
*
* 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.IOException;
import java.util.List;
import java.util.Random;
import java.util.Vector;

import org.I0Itec.zkclient.ZkServer;
import org.testng.AssertJUnit;
import org.testng.annotations.Test;

import com.linkedin.databus.client.DatabusClientDSCUpdater;
import com.linkedin.databus.client.LastWriteTimeTrackerImpl;
import com.linkedin.databus.client.pub.TestDatabusClientNode.DummyClient.DummyClientException;
import com.linkedin.databus.core.Checkpoint;
import com.linkedin.databus.core.DbusClientMode;
import com.linkedin.databus.core.util.InvalidConfigException;
import com.linkedin.databus.groupleader.impl.zkclient.LeaderElectUtils;

public class TestDatabusClientNode
{

  // static private final String CLUSTER_SERVER_LIST = "localhost:2181,localhost:2182,localhost:2183";
  static private final String CLUSTER_SERVER_LIST = "localhost:8100";


  protected static final int _zkServerTickTime = 2000;

  public List<ZkServer> startZk(int port) throws IOException
  {
    String zkTestDataParentDir = ".";
    String zkServerList =  "localhost:" + port;

    String zkTestDataRootDir = zkTestDataParentDir + "/zkroot-client";

     List<Integer> localPortsList = LeaderElectUtils.parseLocalPorts(zkServerList);
     List<ZkServer> localZkServers = LeaderElectUtils.startLocalZookeeper(localPortsList, zkTestDataRootDir, _zkServerTickTime);
     return localZkServers;
  }

  public void stopZk(List<ZkServer> localZkServers)
  {
    LeaderElectUtils.stopLocalZookeeper(localZkServers);
  }


  @Test
  public void testMasterSlave() throws InterruptedException, DummyClientException, IOException
  {
    List<ZkServer> localZkServers = startZk(8100);
    try
    {
      Integer totalCountExpected  = 100;
      int numNodes = 10;
      int delayMs = 10;
      int numIter = 1;
      Integer expectedWorkLoad = totalCountExpected/numNodes;
      long updateTimestamp  = System.currentTimeMillis();
      for (int iter = 0; iter < numIter; ++iter)
      {
        DummyClient nodes[] = new DummyClient[numNodes];
        Thread threads[] = new Thread[numNodes];
        for (int i=0; i < numNodes; ++i)
        {
          nodes[i] new DummyClient(expectedWorkLoad,"counters","worker_" +
                                      (int) (Math.random()*1000),
                                      totalCountExpected,
                                      delayMs,
                                      updateTimestamp);
         // nodes[i] =  new DummyClient(expectedWorkLoad,"counters","worker_"  ,totalCountExpected,delayMs);

          threads[i] = new Thread(nodes[i]);
        }



        for (int i=0; i < threads.length; ++i)
        {
          threads[i].start();
          Thread.sleep(i*(iter*2+20));
        }

        for (int i=0; i < threads.length;++i)
        {
          //wait for 1000ms  - protect against hung processes
          threads[i].join(1000);
        }
        boolean exhausted=false;
        boolean tsExhausted=false;
        for (DummyClient w1: nodes)
        {
          System.err.printf("Worker =%s\n",w1.toString());
          AssertJUnit.assertTrue(w1.getActualWorkCount().intValue() == expectedWorkLoad.intValue());
          if (w1.getSharedWorkCounter().intValue() == totalCountExpected.intValue()) {
            exhausted = true;
          }
          long diff = w1.getDSCTimestamp() - updateTimestamp;
          if (diff == totalCountExpected) {
            tsExhausted = true;
          }
          System.err.println("Timestamp Diff=" + diff);
        }
        AssertJUnit.assertTrue(exhausted);
        AssertJUnit.assertTrue(tsExhausted);
      }
    }
    finally
    {
      stopZk(localZkServers);
    }
  }


  @Test
  public void testSharedCheckPointPersistence() throws InvalidConfigException, IOException
  {
    List<ZkServer> localZkServers = startZk(8100);
    DatabusClientNode clusterNode = null;
    try
    {
       clusterNode = new DatabusClientNode (new DatabusClientNode.StaticConfig(true,CLUSTER_SERVER_LIST,
                                                                                                2000,
                                                                                                5000,
                                                                                                "/DummyClient",
                                                                                                "dbus-client",
                                                                                                "one",true,null));

      DatabusClientGroupMember groupMember = clusterNode.getMember("/DummyClient","dbus-client","one");
      AssertJUnit.assertTrue(groupMember != null);
      SharedCheckpointPersistenceProvider sharedCp =
                            new SharedCheckpointPersistenceProvider(groupMember,
                                                                    new SharedCheckpointPersistenceProvider.StaticConfig(
                                                                                                                         0));

      //join the group;
      AssertJUnit.assertTrue(groupMember.join());

      AssertJUnit.assertTrue(groupMember.waitForLeaderShip(5000));

      Vector<String> sources1 = new Vector<String> ();
      sources1.add("bizfollow_biz"); sources1.add("bizfollow_rev");

      Vector<String> sources2 = new Vector<String> ();
      sources2.add("bizfollow_biz");

      Vector<String> sources3 = new Vector<String> ();
      sources3.add("bizfollow_biz") ; sources3.add("bizfollow_test") ; sources3.add("bizfollow_intl");

      checkSharedCps(sharedCp,sources1);
      checkSharedCps(sharedCp,sources2);
      checkSharedCps(sharedCp,sources3);

      //delete the node;
      groupMember.removeSharedData();

    }
    finally {
      if (clusterNode != null)
      clusterNode.close();
      stopZk(localZkServers);
    }

  }

  @Test
  public void testZkTempIsolation() throws DummyClientException, InterruptedException, IOException
  {
    //zk is up;
    Integer totalCountExpected  = 5000;
    int numNodes = 2;
    int delayMs = 10;
    int interruptCount = 1000;
    Integer expectedWorkLoad = totalCountExpected/numNodes;
    long updateTimestamp=System.currentTimeMillis();
    List<ZkServer> localZkServers = startZk(8100);

    try
    {
      DummyClient nodes[] = new DummyClient[numNodes];
      Thread threads[] = new Thread[numNodes];
      for (int i=0; i < numNodes; ++i)
      {
        nodes[i] new DummyClient(expectedWorkLoad,"counters","worker_" + (int) (Math.random()*1000),totalCountExpected,delayMs,updateTimestamp);
        threads[i] = new Thread(nodes[i]);
      }

      for (int i=0; i < threads.length; ++i)
      {
        threads[i].start();
        Thread.sleep(10);
      }

      Thread.sleep(2000);
      DummyClient origLeader = findLeader(nodes);
      AssertJUnit.assertTrue(origLeader != null);

      System.out.printf("Current leader=%s\n",origLeader.getName());

      //Threads have started; and are writing to shared storage; now kill zookeeper
      Thread.sleep(interruptCount*delayMs);
      origLeader.leaveGroup();
      Thread.sleep(1000);
      origLeader.joinGroup();

      DummyClient newLeader = findLeader(nodes);
      AssertJUnit.assertTrue(newLeader != null);
      System.out.printf("New leader=%s\n",newLeader.getName());

      for (int i=0; i < threads.length;++i)
      {
        //wait for 1000ms  - protect against hung processes
        threads[i].join(10L * expectedWorkLoad * delayMs);
      }

      AssertJUnit.assertFalse(origLeader.getName().equals(newLeader.getName()));
      AssertJUnit.assertTrue(origLeader.getSharedWorkCounter() < expectedWorkLoad);
      AssertJUnit.assertTrue(newLeader.getSharedWorkCounter() < totalCountExpected);
      AssertJUnit.assertTrue(newLeader.getSharedWorkCounter().equals(expectedWorkLoad));
    }
    finally
    {
      stopZk(localZkServers);
    }

  }


  private DummyClient findLeader(DummyClient[] nodes)
  {
      for (DummyClient n: nodes) {
        if (n.isLeader())
        {
            return n;
        }
      }
      return null;
  }

  protected void checkSharedCps(SharedCheckpointPersistenceProvider sharedCp, Vector<String> sources)
  {

    Checkpoint cp = new Checkpoint();
    cp.setConsumptionMode(DbusClientMode.ONLINE_CONSUMPTION);
    Random r = new Random(System.currentTimeMillis());
    long scn = r.nextLong();

    cp.setWindowScn(scn);
    cp.setWindowOffset(-1);
    try
    {
      sharedCp.storeCheckpoint(sources,cp);
    }
    catch (IOException e)
    {
      e.printStackTrace();
      AssertJUnit.assertTrue(false);
    }
    Checkpoint newCp = sharedCp.loadCheckpoint(sources);

    AssertJUnit.assertTrue(newCp != null);
    AssertJUnit.assertTrue(newCp.getWindowScn() == cp.getWindowScn());
    AssertJUnit.assertTrue(newCp.getWindowOffset().equals(cp.getWindowOffset()));
    AssertJUnit.assertTrue(newCp.getConsumptionMode() == cp.getConsumptionMode());

    System.out.printf("Stored scn = %d\n",newCp.getWindowScn());


  }
  /**
   *
   * @author snagaraj
   * Dummy client that uses clientNode to test master/slave relationship;
   * Initially, just use the blocking API;
   * Task is to read a counter from shared state; and increment with a delay -countWorkLoad- number of times and then die;
   */
  public static class DummyClient implements Runnable {

    //represents the logical node/entity participating on the physical connection;
    private final DatabusClientNode _clusterNode;
    //represents the 'physical' node connection to group;
    private final Integer _countWorkload;
    private Integer _actualWorkCount;
    private Integer _sharedWorkCounter;
    private final Integer _totalWorkLoadCount;


    private final static String NAMESPACE = "/DummyClientTest";
    private final  int _delayMs;
    private final static int sessionTimeOutMillis = 10000;
    private final static int connectionTimeOutMillis = 5000;
    private final static String KEY= "dummy-key";

    private final String _group;
    private final String _name;

    private final DatabusClientDSCUpdater _dscUpdater;
    private final long _baseUpdateTimestamp;

    public DummyClient(Integer countWorkload,String group, String name,Integer totalWorkLoadCount,int delayMs,long updateTimeInMs) throws DummyClientException {
       try
      {
         _group = group;
         _name = name;
        _clusterNode = new DatabusClientNode(new DatabusClientNode.StaticConfig(true,CLUSTER_SERVER_LIST,
                                                                                       sessionTimeOutMillis,
                                                                                       connectionTimeOutMillis,
                                                                                       NAMESPACE,
                                                                                       _group,
                                                                                       _name,true,"test-shared"));
      }
      catch (InvalidConfigException e)
      {
        e.printStackTrace();
        throw new DummyClientException();
      }
      _countWorkload = countWorkload;
      _actualWorkCount = 0;
      _sharedWorkCounter=0;
      _totalWorkLoadCount = totalWorkLoadCount;
      _delayMs = delayMs;
      if (!_clusterNode.isConnected()) throw new DummyClientException();
      DatabusClientGroupMember member = _clusterNode.getMember(NAMESPACE, _group, _name);
      _dscUpdater = new DatabusClientDSCUpdater(member,new LastWriteTimeTrackerImpl(),2);
      _baseUpdateTimestamp  = updateTimeInMs;
    }

    public String getName()
    {
      return _name;
    }

    public  boolean isLeader()
    {
      DatabusClientGroupMember member = _clusterNode.getMember(NAMESPACE, _group, _name);
      if (member != null)
      {
        return member.isLeader();
      }
      return false;
    }

    public Integer getActualWorkCount() {
      return _actualWorkCount;
    }

    public Integer getSharedWorkCounter() {
      return _sharedWorkCounter;
    }

    public long getDSCTimestamp() {
      return _dscUpdater.getLocalTimestamp();
    }

    @Override
    public void run()
    {
      Integer start = null;
      long baseTs = 0 ;
      synchronized (this)
      {
        DatabusClientGroupMember member = _clusterNode.getMember(NAMESPACE, _group, _name);
        //hello group;
        if (member.join())
        {
          //sit around till leadership is conferred;
          //start dsc reader thread;
          Thread t = new Thread(_dscUpdater);
          t.start();

          member.waitForLeaderShip();
          System.out.printf("Acquired leadership: %s\n",member.getName());

          //read shared data
          start = (Integer) member.readSharedData(KEY);

          //leader; reads local value: this should contain the last updated time value;
          baseTs = _dscUpdater.getLocalTimestamp();
          if (baseTs==0) {
              baseTs = _baseUpdateTimestamp;
          }
          //stop the dsc thread for master;
          _dscUpdater.stop();
        }
        else
        {
           System.err.printf("%s could not join group!\n",member.getName());
           _clusterNode.close();
           return;
        }
      }


      if (start==null)
      {
        //bootstrap;
        start=0;
        System.err.printf("Start is  null! Start at: %d\n",(int) start);
      }
      System.err.printf("Start at: %d\n",(int) start);
      Integer i=0;
      for (;i < _countWorkload; ++i) {
        start++;
        _actualWorkCount++;
        //shared write of dsc timestamp;
        _dscUpdater.writeTimestamp(baseTs + _actualWorkCount);
        try
        {
          Thread.sleep(_delayMs);
        }
        catch (InterruptedException e)
        {
          e.printStackTrace();
          System.err.printf("start=%d",start);
        }

      }
      boolean wroteSharedData = false;
      synchronized(this)
      {
        DatabusClientGroupMember member = _clusterNode.getMember(NAMESPACE, _group, _name);
        wroteSharedData = member.writeSharedData(KEY,start);
        if (wroteSharedData)
        {
          _sharedWorkCounter = start;
          if (_sharedWorkCounter.equals(_totalWorkLoadCount)) {
            System.err.printf("Cleanup: %s is cleaning up:\n",member.toString());
            member.removeSharedData();
          }
        }
        else
        {
          DatabusClientGroupMember m = _clusterNode.getMember(NAMESPACE, _group, _name);
          System.err.printf("%s write of shared state=%d didn't succeed: Current leader is : %s\n",m.getName(),(int) i,m.getLeader());
        }
        _clusterNode.close();

      }
    }
    //use only in unit-tests
    synchronized void  leaveGroup()
    {
    DatabusClientGroupMember m = _clusterNode.getMember(NAMESPACE, _group, _name);
      m.leave();
       _clusterNode.close();
    }

    //use only in unit-tests
    synchronized void  joinGroup()
    {
      _clusterNode.open();
      DatabusClientGroupMember member = _clusterNode.getMember(NAMESPACE, _group, _name);
      member.join();
    }

    @Override
    public String toString()
    {
      return "name=  " + _name + " countWorkLoad=" + _countWorkload + "; actualWorkCount=" + _actualWorkCount + "; sharedWorkCounter=" + _sharedWorkCounter + " totalWorkLoadCount=" + _totalWorkLoadCount ;
    }

    @SuppressWarnings("serial")
    public static class DummyClientException extends Exception {
      public DummyClientException() {
        super();
      }
    }

  }

}
TOP

Related Classes of com.linkedin.databus.client.pub.TestDatabusClientNode$DummyClient

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.