use of org.I0Itec.zkclient.IZkDataListener in project samza by apache.
the class TestZkLeaderElector method testLeaderFailure.
/**
* Tests that Leader Failure automatically promotes the next successor to become the leader
*/
@Test
public void testLeaderFailure() {
/**
* electionLatch and count together verify that:
* 1. the registered listeners are actually invoked by the ZkClient on the correct path
* 2. for a single participant failure, at-most 1 other participant is notified
*/
final CountDownLatch electionLatch = new CountDownLatch(1);
final AtomicInteger count = new AtomicInteger(0);
BooleanResult isLeader1 = new BooleanResult();
BooleanResult isLeader2 = new BooleanResult();
BooleanResult isLeader3 = new BooleanResult();
// Processor-1
ZkUtils zkUtils1 = getZkUtilsWithNewClient();
zkUtils1.registerProcessorAndGetId(new ProcessorData("processor1", "1"));
ZkLeaderElector leaderElector1 = new ZkLeaderElector("processor1", zkUtils1, new IZkDataListener() {
@Override
public void handleDataChange(String dataPath, Object data) throws Exception {
}
@Override
public void handleDataDeleted(String dataPath) throws Exception {
count.incrementAndGet();
}
});
leaderElector1.setLeaderElectorListener(() -> isLeader1.res = true);
// Processor-2
ZkUtils zkUtils2 = getZkUtilsWithNewClient();
final String path2 = zkUtils2.registerProcessorAndGetId(new ProcessorData("processor2", "2"));
ZkLeaderElector leaderElector2 = new ZkLeaderElector("processor2", zkUtils2, new IZkDataListener() {
@Override
public void handleDataChange(String dataPath, Object data) throws Exception {
}
@Override
public void handleDataDeleted(String dataPath) throws Exception {
String registeredIdStr = ZkKeyBuilder.parseIdFromPath(path2);
Assert.assertNotNull(registeredIdStr);
String predecessorIdStr = ZkKeyBuilder.parseIdFromPath(dataPath);
Assert.assertNotNull(predecessorIdStr);
try {
int selfId = Integer.parseInt(registeredIdStr);
int predecessorId = Integer.parseInt(predecessorIdStr);
Assert.assertEquals(1, selfId - predecessorId);
} catch (Exception e) {
LOG.error(e.getLocalizedMessage());
}
count.incrementAndGet();
electionLatch.countDown();
}
});
leaderElector2.setLeaderElectorListener(() -> isLeader2.res = true);
// Processor-3
ZkUtils zkUtils3 = getZkUtilsWithNewClient();
zkUtils3.registerProcessorAndGetId(new ProcessorData("processor3", "3"));
ZkLeaderElector leaderElector3 = new ZkLeaderElector("processor3", zkUtils3, new IZkDataListener() {
@Override
public void handleDataChange(String dataPath, Object data) throws Exception {
}
@Override
public void handleDataDeleted(String dataPath) throws Exception {
count.incrementAndGet();
}
});
leaderElector3.setLeaderElectorListener(() -> isLeader3.res = true);
// Join Leader Election
leaderElector1.tryBecomeLeader();
leaderElector2.tryBecomeLeader();
leaderElector3.tryBecomeLeader();
Assert.assertTrue(TestZkUtils.testWithDelayBackOff(() -> isLeader1.res, 2, 100));
Assert.assertFalse(TestZkUtils.testWithDelayBackOff(() -> isLeader2.res, 2, 100));
Assert.assertFalse(TestZkUtils.testWithDelayBackOff(() -> isLeader3.res, 2, 100));
Assert.assertTrue(leaderElector1.amILeader());
Assert.assertFalse(leaderElector2.amILeader());
Assert.assertFalse(leaderElector3.amILeader());
List<String> currentActiveProcessors = zkUtils1.getSortedActiveProcessorsZnodes();
Assert.assertEquals(3, currentActiveProcessors.size());
// Leader Failure
zkUtils1.close();
currentActiveProcessors.remove(0);
try {
Assert.assertTrue(electionLatch.await(5, TimeUnit.SECONDS));
} catch (InterruptedException e) {
Assert.fail("Interrupted while waiting for leaderElection listener callback to complete!");
}
Assert.assertEquals(1, count.get());
Assert.assertEquals(currentActiveProcessors, zkUtils2.getSortedActiveProcessorsZnodes());
// Clean up
zkUtils2.close();
zkUtils3.close();
}
use of org.I0Itec.zkclient.IZkDataListener in project samza by apache.
the class TestZkUtils method testSubscribeToJobModelVersionChange.
@Test
public void testSubscribeToJobModelVersionChange() {
ZkKeyBuilder keyBuilder = new ZkKeyBuilder("test");
String root = keyBuilder.getRootPath();
zkClient.deleteRecursive(root);
class Result {
String res = "";
public String getRes() {
return res;
}
public void updateRes(String newRes) {
res = newRes;
}
}
Assert.assertFalse(zkUtils.exists(root));
// create the paths
zkUtils.makeSurePersistentPathsExists(new String[] { root, keyBuilder.getJobModelVersionPath(), keyBuilder.getProcessorsPath() });
Assert.assertTrue(zkUtils.exists(root));
Assert.assertTrue(zkUtils.exists(keyBuilder.getJobModelVersionPath()));
Assert.assertTrue(zkUtils.exists(keyBuilder.getProcessorsPath()));
final Result res = new Result();
// define the callback
IZkDataListener dataListener = new IZkDataListener() {
@Override
public void handleDataChange(String dataPath, Object data) throws Exception {
res.updateRes((String) data);
}
@Override
public void handleDataDeleted(String dataPath) throws Exception {
Assert.fail("Data wasn't deleted;");
}
};
// subscribe
zkClient.subscribeDataChanges(keyBuilder.getJobModelVersionPath(), dataListener);
zkClient.subscribeDataChanges(keyBuilder.getProcessorsPath(), dataListener);
// update
zkClient.writeData(keyBuilder.getJobModelVersionPath(), "newVersion");
// verify
Assert.assertTrue(testWithDelayBackOff(() -> "newVersion".equals(res.getRes()), 2, 1000));
// update again
zkClient.writeData(keyBuilder.getProcessorsPath(), "newProcessor");
Assert.assertTrue(testWithDelayBackOff(() -> "newProcessor".equals(res.getRes()), 2, 1000));
}
Aggregations