ZookeeperServerSet implements ServerSet, PathChildrenCacheListener { @Override public synchronized void addChangeListener(ChangeListener listener) { if (needToPopulateServers) { try { populateServers(); needToPopulateServers = false; } catch (Exception e) { logger.warn("Error populating server list for service '" + serviceName + "'"); throw new RuntimeException(e); } } for (InetSocketAddress address : servers.keySet()) { listener.onServerAdded(address); } listeners.add(listener); } @AssistedInject  ZookeeperServerSet(@ServicePathCacheFactory PathChildrenCacheFactory childrenCacheFactory,
                            CuratorFramework zkClient,
                            @ServiceReader ZookeeperServerReader reader,
                            @Assisted("serviceName") String serviceName,
                            @Assisted boolean subscribeToUpdates); @Override synchronized void addChangeListener(ChangeListener listener); @Override synchronized void removeChangeListener(ChangeListener listener); @Override void close(); @Override synchronized void childEvent(CuratorFramework client, PathChildrenCacheEvent event); @Override String toString(); @Override Set<InetSocketAddress> getServers();  }
@Test public void testAddChangeListener() throws Exception { ServerSet.ChangeListener listener1 = mock(ServerSet.ChangeListener.class); ServerSet.ChangeListener listener2 = mock(ServerSet.ChangeListener.class); ServerSet.ChangeListener listener3 = mock(ServerSet.ChangeListener.class); ServerSet.ChangeListener listener4 = mock(ServerSet.ChangeListener.class); InetSocketAddress server1 = new InetSocketAddress("192.168.1.1", 256); InetSocketAddress server2 = new InetSocketAddress("192.168.1.2", 512); HostConfig host1 = getHostConfig("node-1", server1); HostConfig host2 = getHostConfig("node-2", server2); ZookeeperServerSet set = new ZookeeperServerSet(mockChildrenCacheFactory, zkClient, serviceReader, "foo", true); ZookeeperServerSet hostSet = new ZookeeperServerSet(mockChildrenCacheFactory, zkClient, hostReader, "foo", true); CuratorFramework mockZk = mock(CuratorFramework.class); set.addChangeListener(listener1); hostSet.addChangeListener(listener3); set.childEvent(mockZk, childAddedEvent("/services/foo/node-1", data(server1))); hostSet.childEvent(mockZk, childAddedEvent("/hosts/node-1", data(host1))); set.childEvent(mockZk, childAddedEvent("/services/foo/node-2", data(server2))); set.childEvent(mockZk, childAddedEvent("/services/foo/node-3", data(server2))); hostSet.childEvent(mockZk, childAddedEvent("/hosts/node-2", data(host2))); hostSet.childEvent(mockZk, childAddedEvent("/hosts/node-3", data(host2))); set.addChangeListener(listener2); hostSet.addChangeListener(listener4); set.childEvent(mockZk, childRemovedEvent("/services/foo/node-1", data(server1))); set.childEvent(mockZk, childRemovedEvent("/services/foo/node-1", data(server1))); hostSet.childEvent(mockZk, childRemovedEvent("/hosts/node-1", data(host1))); hostSet.childEvent(mockZk, childRemovedEvent("/hosts/node-1", data(host1))); verify(childrenCacheListener).addListener(set); verify(listener1).onServerAdded(server1); verify(listener1).onServerAdded(server2); verify(listener2).onServerAdded(server1); verify(listener2).onServerAdded(server2); verify(listener3).onServerAdded(server1); verify(listener3).onServerAdded(server2); verify(listener4).onServerAdded(server1); verify(listener4).onServerAdded(server2); verify(listener1).onServerRemoved(server1); verify(listener2).onServerRemoved(server1); verify(listener3).onServerRemoved(server1); verify(listener4).onServerRemoved(server1); verifyNoMoreInteractions(listener1, listener2, mockZk, listener3, listener4); hostSet.close(); }