}
}
@Test
public void testACL() throws IOException, ExecutionException, InterruptedException, NoSuchAlgorithmException {
InMemoryZKServer zkServer = InMemoryZKServer.builder().setDataDir(tmpFolder.newFolder()).setTickTime(1000).build();
zkServer.startAndWait();
try {
String userPass = "user:pass";
String digest = DigestAuthenticationProvider.generateDigest(userPass);
// Creates two zkclients
ZKClientService zkClient = ZKClientService.Builder
.of(zkServer.getConnectionStr())
.addAuthInfo("digest", userPass.getBytes())
.build();
zkClient.startAndWait();
ZKClientService noAuthClient = ZKClientService.Builder.of(zkServer.getConnectionStr()).build();
noAuthClient.startAndWait();
// Create a node that is readable by all client, but admin for the creator
String path = "/testacl";
zkClient.create(path, "test".getBytes(), CreateMode.PERSISTENT,
ImmutableList.of(
new ACL(ZooDefs.Perms.READ, ZooDefs.Ids.ANYONE_ID_UNSAFE),
new ACL(ZooDefs.Perms.ALL, ZooDefs.Ids.AUTH_IDS)
)).get();
// Verify the ACL
ACLData aclData = zkClient.getACL(path).get();
Assert.assertEquals(2, aclData.getACL().size());
ACL acl = aclData.getACL().get(1);
Assert.assertEquals(ZooDefs.Perms.ALL, acl.getPerms());
Assert.assertEquals("digest", acl.getId().getScheme());
Assert.assertEquals(digest, acl.getId().getId());
Assert.assertEquals("test", new String(noAuthClient.getData(path).get().getData()));
// When tries to write using the no-auth zk client, it should fail.
try {
noAuthClient.setData(path, "test2".getBytes()).get();
Assert.fail();
} catch (ExecutionException e) {
Assert.assertTrue(e.getCause() instanceof KeeperException.NoAuthException);
}
// Change ACL to make it open for all
zkClient.setACL(path, ImmutableList.of(new ACL(ZooDefs.Perms.WRITE, ZooDefs.Ids.ANYONE_ID_UNSAFE))).get();
// Write again with the non-auth client, now should succeed.
noAuthClient.setData(path, "test2".getBytes()).get();
noAuthClient.stopAndWait();
zkClient.stopAndWait();
} finally {
zkServer.stopAndWait();
}
}