Utils { public static void zkAsyncCreateFullPathOptimisticRecursive( final ZooKeeperClient zkc, final String pathToCreate, final Optional<String> parentPathShouldNotCreate, final byte[] data, final List<ACL> acl, final CreateMode createMode, final AsyncCallback.StringCallback callback, final Object ctx) { try { zkc.get().create(pathToCreate, data, acl, createMode, new AsyncCallback.StringCallback() { @Override public void processResult(int rc, String path, Object ctx, String name) { if (rc != KeeperException.Code.NONODE.intValue()) { callback.processResult(rc, path, ctx, name); return; } int lastSlash = pathToCreate.lastIndexOf('/'); if (lastSlash <= 0) { callback.processResult(rc, path, ctx, name); return; } String parent = pathToCreate.substring(0, lastSlash); if (parentPathShouldNotCreate.isPresent() && Objects.equal(parentPathShouldNotCreate.get(), parent)) { callback.processResult(rc, path, ctx, name); return; } zkAsyncCreateFullPathOptimisticRecursive(zkc, parent, parentPathShouldNotCreate, new byte[0], acl, CreateMode.PERSISTENT, new AsyncCallback.StringCallback() { @Override public void processResult(int rc, String path, Object ctx, String name) { if (rc == KeeperException.Code.OK.intValue() || rc == KeeperException.Code.NODEEXISTS.intValue()) { zkAsyncCreateFullPathOptimisticRecursive(zkc, pathToCreate, parentPathShouldNotCreate, data, acl, createMode, callback, ctx); } else { callback.processResult(rc, path, ctx, name); } } }, ctx); } }, ctx); } catch (ZooKeeperClient.ZooKeeperConnectionException zkce) { callback.processResult(DistributedLogConstants.ZK_CONNECTION_EXCEPTION_RESULT_CODE, zkce.getMessage(), ctx, pathToCreate); } catch (InterruptedException ie) { callback.processResult(DistributedLogConstants.DL_INTERRUPTED_EXCEPTION_RESULT_CODE, ie.getMessage(), ctx, pathToCreate); } }  static long nowInNanos(); static long nowInMillis(); static long elapsedMSec(long startMsecTime); static boolean randomPercent(double percent); static void zkCreateFullPathOptimistic(
        ZooKeeperClient zkc,
        String path,
        byte[] data,
        final List<ACL> acl,
        final CreateMode createMode); static void zkAsyncCreateFullPathOptimisticRecursive(
        final ZooKeeperClient zkc,
        final String pathToCreate,
        final Optional<String> parentPathShouldNotCreate,
        final byte[] data,
        final List<ACL> acl,
        final CreateMode createMode,
        final AsyncCallback.StringCallback callback,
        final Object ctx); static Future<BoxedUnit> zkAsyncCreateFullPathOptimistic(
        final ZooKeeperClient zkc,
        final String pathToCreate,
        final byte[] data,
        final List<ACL> acl,
        final CreateMode createMode); static Future<BoxedUnit> zkAsyncCreateFullPathOptimistic(
        final ZooKeeperClient zkc,
        final String pathToCreate,
        final Optional<String> parentPathShouldNotCreate,
        final byte[] data,
        final List<ACL> acl,
        final CreateMode createMode); static Future<BoxedUnit> zkAsyncCreateFullPathOptimisticAndSetData(
        final ZooKeeperClient zkc,
        final String pathToCreate,
        final byte[] data,
        final List<ACL> acl,
        final CreateMode createMode); static Future<Versioned<byte[]>> zkGetData(ZooKeeperClient zkc, String path, boolean watch); static Future<Versioned<byte[]>> zkGetData(ZooKeeper zk, String path, boolean watch); static Future<ZkVersion> zkSetData(ZooKeeperClient zkc, String path, byte[] data, ZkVersion version); static Future<ZkVersion> zkSetData(ZooKeeper zk, String path, byte[] data, ZkVersion version); static Future<Void> zkDelete(ZooKeeperClient zkc, String path, ZkVersion version); static Future<Void> zkDelete(ZooKeeper zk, String path, ZkVersion version); static Future<Void> asyncClose(@Nullable AsyncCloseable closeable,
                                          boolean swallowIOException); static ZooKeeper sync(ZooKeeperClient zkc, String path); static void close(@Nullable Closeable closeable); static void close(@Nullable AsyncCloseable closeable); static void closeQuietly(@Nullable AsyncCloseable closeable); static Future<Void> closeSequence(ExecutorService executorService,
                                             AsyncCloseable... closeables); static Future<Void> closeSequence(ExecutorService executorService,
                                             boolean ignoreCloseError,
                                             AsyncCloseable... closeables);  }
@Test(timeout = 60000) public void testZkAsyncCreateFulPathOptimisticRecursive() throws Exception { String path1 = "/a/b/c/d"; Optional<String> parentPathShouldNotCreate = Optional.absent(); final CountDownLatch doneLatch1 = new CountDownLatch(1); Utils.zkAsyncCreateFullPathOptimisticRecursive(zkc, path1, parentPathShouldNotCreate, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT, new AsyncCallback.StringCallback() { @Override public void processResult(int rc, String path, Object ctx, String name) { doneLatch1.countDown(); } }, null); doneLatch1.await(); assertNotNull(zkc.get().exists(path1, false)); String path2 = "/a/b/c/d/e/f/g"; parentPathShouldNotCreate = Optional.of("/a/b/c/d/e"); final CountDownLatch doneLatch2 = new CountDownLatch(1); Utils.zkAsyncCreateFullPathOptimisticRecursive(zkc, path2, parentPathShouldNotCreate, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT, new AsyncCallback.StringCallback() { @Override public void processResult(int rc, String path, Object ctx, String name) { doneLatch2.countDown(); } }, null); doneLatch2.await(); assertNull(zkc.get().exists("/a/b/c/d/e", false)); assertNull(zkc.get().exists("/a/b/c/d/e/f", false)); assertNull(zkc.get().exists("/a/b/c/d/e/f/g", false)); parentPathShouldNotCreate = Optional.of("/a/b"); final CountDownLatch doneLatch3 = new CountDownLatch(1); Utils.zkAsyncCreateFullPathOptimisticRecursive(zkc, path2, parentPathShouldNotCreate, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT, new AsyncCallback.StringCallback() { @Override public void processResult(int rc, String path, Object ctx, String name) { doneLatch3.countDown(); } }, null); doneLatch3.await(); assertNotNull(zkc.get().exists(path2, false)); }