@Override
    public void eventReceived(CuratorFramework client, CuratorEvent event) throws Exception {
      if (event.getType() == CuratorEventType.CHILDREN) {
        if (event.getChildren().isEmpty()) {
          client.getChildren().inBackground(event.getContext()).forPath(event.getPath());
        } else {
          String path = event.getPath() + "/" + event.getChildren().get(0);
          LOG.info("Operations Node registered in ZK. Waiting for transports configration");
          client.getData().inBackground(event.getContext()).forPath(path);
        }
      } else if (event.getType() == CuratorEventType.GET_DATA) {
        if (event.getData() == null) {
          client.getData().inBackground(event.getContext()).forPath(event.getPath());
        } else {
          OperationsNodeInfo nodeInfo =
              OPERATIONS_NODE_INFO_CONVERTER.fromByteArray(event.getData());
          boolean isTransportInitialized = !nodeInfo.getTransports().isEmpty();

          if (isTransportInitialized) {
            LOG.info("Operations Node updated tarnsports configuration in ZK");
            ((CountDownLatch) event.getContext()).countDown();
          } else {
            client.getData().inBackground(event.getContext()).forPath(event.getPath());
          }
        }
      }
    }
  @Before
  public void before() {
    service = new DefaultOperationsServerListService();
    BootstrapNode zkNode = Mockito.mock(BootstrapNode.class);
    OperationsNodeInfo nodeInfo = new OperationsNodeInfo();
    nodeInfo.setConnectionInfo(new ConnectionInfo("localhost", 8000, ByteBuffer.wrap(new byte[0])));
    List<TransportMetaData> mdList = new ArrayList<TransportMetaData>();
    mdList.add(
        new TransportMetaData(
            1,
            42,
            42,
            Collections.singletonList(
                new VersionConnectionInfoPair(42, ByteBuffer.wrap("test".getBytes())))));
    mdList.add(
        new TransportMetaData(
            2,
            73,
            73,
            Collections.singletonList(
                new VersionConnectionInfoPair(73, ByteBuffer.wrap("test".getBytes())))));
    mdList.add(
        new TransportMetaData(
            3,
            1,
            3,
            Arrays.asList(
                new VersionConnectionInfoPair(1, ByteBuffer.wrap("test1".getBytes())),
                new VersionConnectionInfoPair(2, ByteBuffer.wrap("test2".getBytes())),
                new VersionConnectionInfoPair(3, ByteBuffer.wrap("test3".getBytes())))));
    nodeInfo.setTransports(mdList);

    Mockito.when(zkNode.getCurrentOperationServerNodes()).thenReturn(Arrays.asList(nodeInfo));
    service.init(zkNode);
  }
 @Test
 public void testOnNodeRemoved() {
   OperationsNodeInfo nodeInfo = Mockito.mock(OperationsNodeInfo.class);
   ConnectionInfo connectionInfo = Mockito.mock(ConnectionInfo.class);
   Mockito.when(nodeInfo.getConnectionInfo()).thenReturn(connectionInfo);
   Map<String, OperationsNodeInfo> opsMap = Mockito.mock(Map.class);
   ReflectionTestUtils.setField(service, "opsMap", opsMap);
   DefaultOperationsServerListService.Memorizer memorizer =
       Mockito.mock(DefaultOperationsServerListService.Memorizer.class);
   ReflectionTestUtils.setField(service, "cache", memorizer);
   service.onNodeRemoved(nodeInfo);
   Mockito.verify(opsMap, Mockito.only()).remove(Mockito.anyString());
   Mockito.verify(memorizer, Mockito.only()).clear();
 }
 @Override
 public void onNodeRemoved(OperationsNodeInfo node) {
   for (int i = 0; i < replicas; i++) {
     LOG.trace("Removing node {} replica {} from the circle", node.getConnectionInfo(), i);
     circle.remove(hash(node, i));
   }
 }
 @Override
 public void onNodeAdded(OperationsNodeInfo node) {
   for (int i = 0; i < replicas; i++) {
     LOG.trace("Adding node {} replica {} to the circle", node.getConnectionInfo(), i);
     circle.put(hash(node, i), node);
   }
 }
 private byte[] hash(OperationsNodeInfo node, int replica) {
   byte[] key = node.getConnectionInfo().getPublicKey().array();
   ByteBuffer data = ByteBuffer.wrap(new byte[key.length + SIZE_OF_INT]);
   data.put(key);
   data.putInt(replica);
   return md5.get().digest(data.array());
 }