You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@helix.apache.org by hu...@apache.org on 2022/05/18 12:44:20 UTC
[helix] branch zookeeper-api-ttlcontainer updated: Add TTL and Container modes to sync create API in ZkClient and ZkConnection (#2090)
This is an automated email from the ASF dual-hosted git repository.
hulee pushed a commit to branch zookeeper-api-ttlcontainer
in repository https://gitbox.apache.org/repos/asf/helix.git
The following commit(s) were added to refs/heads/zookeeper-api-ttlcontainer by this push:
new 450c47f77 Add TTL and Container modes to sync create API in ZkClient and ZkConnection (#2090)
450c47f77 is described below
commit 450c47f77020f35dfae06e85dab31809a71f37fb
Author: Ramin Bashizade <ra...@linkedin.com>
AuthorDate: Wed May 18 05:44:15 2022 -0700
Add TTL and Container modes to sync create API in ZkClient and ZkConnection (#2090)
This PR adds methods that support creating persistent nodes with Container and TTL modes synchronously to ZkClient and ZkConnection classes.
---
.../helix/zookeeper/zkclient/IZkConnection.java | 2 +
.../apache/helix/zookeeper/zkclient/ZkClient.java | 327 ++++++++++++++++++++-
.../helix/zookeeper/zkclient/ZkConnection.java | 6 +
.../zookeeper/impl/client/TestRawZkClient.java | 129 ++++++++
4 files changed, 455 insertions(+), 9 deletions(-)
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/IZkConnection.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/IZkConnection.java
index 6fc040fd8..e766bf7d9 100644
--- a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/IZkConnection.java
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/IZkConnection.java
@@ -40,6 +40,8 @@ public interface IZkConnection {
public String create(String path, byte[] data, List<ACL> acl, CreateMode mode) throws KeeperException, InterruptedException;
+ public String create(String path, byte[] data, List<ACL> acl, CreateMode mode, long ttl) throws KeeperException, InterruptedException;
+
public void delete(String path) throws InterruptedException, KeeperException;
boolean exists(final String path, final boolean watch) throws KeeperException, InterruptedException;
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/ZkClient.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/ZkClient.java
index c6b74239b..e4832656b 100644
--- a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/ZkClient.java
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/ZkClient.java
@@ -438,6 +438,41 @@ public class ZkClient implements Watcher {
createPersistent(path, false);
}
+ /**
+ * Create a persistent node with TTL.
+ * @param path the path where you want the node to be created
+ * @param ttl TTL of the node in milliseconds
+ * @throws ZkInterruptedException
+ * if operation was interrupted, or a required reconnection got interrupted
+ * @throws IllegalArgumentException
+ * if called from anything except the ZooKeeper event thread
+ * @throws ZkException
+ * if any ZooKeeper exception occurred
+ * @throws RuntimeException
+ * if any other exception occurs
+ */
+ public void createPersistentWithTTL(String path, long ttl)
+ throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
+ createPersistentWithTTL(path, false, ttl);
+ }
+
+ /**
+ * Create a container node.
+ * @param path the path where you want the node to be created
+ * @throws ZkInterruptedException
+ * if operation was interrupted, or a required reconnection got interrupted
+ * @throws IllegalArgumentException
+ * if called from anything except the ZooKeeper event thread
+ * @throws ZkException
+ * if any ZooKeeper exception occurred
+ * @throws RuntimeException
+ * if any other exception occurs
+ */
+ public void createContainer(String path)
+ throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
+ createContainer(path, false);
+ }
+
/**
* Create a persistent node and set its ACLs.
* @param path
@@ -459,6 +494,45 @@ public class ZkClient implements Watcher {
createPersistent(path, createParents, ZooDefs.Ids.OPEN_ACL_UNSAFE);
}
+ /**
+ * Create a persistent node with TTL and set its ACLs.
+ * @param path the path where you want the node to be created
+ * @param createParents if true all parent dirs are created as well and no
+ * {@link ZkNodeExistsException} is thrown in case the path already exists
+ * @param ttl TTL of the node in milliseconds
+ * @throws ZkInterruptedException
+ * if operation was interrupted, or a required reconnection got interrupted
+ * @throws IllegalArgumentException
+ * if called from anything except the ZooKeeper event thread
+ * @throws ZkException
+ * if any ZooKeeper exception occurred
+ * @throws RuntimeException
+ * if any other exception occurs
+ */
+ public void createPersistentWithTTL(String path, boolean createParents, long ttl)
+ throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
+ createPersistentWithTTL(path, createParents, ZooDefs.Ids.OPEN_ACL_UNSAFE, ttl);
+ }
+
+ /**
+ * Create a container node and set its ACLs.
+ * @param path the path where you want the node to be created
+ * @param createParents if true all parent dirs are created as well and no
+ * {@link ZkNodeExistsException} is thrown in case the path already exists
+ * @throws ZkInterruptedException
+ * if operation was interrupted, or a required reconnection got interrupted
+ * @throws IllegalArgumentException
+ * if called from anything except the ZooKeeper event thread
+ * @throws ZkException
+ * if any ZooKeeper exception occurred
+ * @throws RuntimeException
+ * if any other exception occurs
+ */
+ public void createContainer(String path, boolean createParents)
+ throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
+ createContainer(path, createParents, ZooDefs.Ids.OPEN_ACL_UNSAFE);
+ }
+
/**
* Create a persistent node and set its ACLs.
* @param path
@@ -495,6 +569,73 @@ public class ZkClient implements Watcher {
}
}
+ /**
+ * Create a persistent node with TTL and set its ACLs.
+ * @param path the path where you want the node to be created
+ * @param createParents if true all parent dirs are created as well and no
+ * {@link ZkNodeExistsException} is thrown in case the path already exists
+ * @param acl List of ACL permissions to assign to the node
+ * @param ttl TTL of the node in milliseconds
+ * @throws ZkInterruptedException
+ * if operation was interrupted, or a required reconnection got interrupted
+ * @throws IllegalArgumentException
+ * if called from anything except the ZooKeeper event thread
+ * @throws ZkException
+ * if any ZooKeeper exception occurred
+ * @throws RuntimeException
+ * if any other exception occurs
+ */
+ public void createPersistentWithTTL(String path, boolean createParents, List<ACL> acl, long ttl)
+ throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
+ try {
+ create(path, null, acl, CreateMode.PERSISTENT_WITH_TTL, ttl);
+ } catch (ZkNodeExistsException e) {
+ if (!createParents) {
+ throw e;
+ }
+ } catch (ZkNoNodeException e) {
+ if (!createParents) {
+ throw e;
+ }
+ String parentDir = path.substring(0, path.lastIndexOf('/'));
+ createPersistentWithTTL(parentDir, createParents, acl, ttl);
+ createPersistentWithTTL(path, createParents, acl, ttl);
+ }
+ }
+
+ /**
+ * Create a container node and set its ACLs.
+ * @param path the path where you want the node to be created
+ * @param createParents if true all parent dirs are created as well and no
+ * {@link ZkNodeExistsException} is thrown in case the path already exists
+ * @param acl List of ACL permissions to assign to the node
+ * @throws ZkInterruptedException
+ * if operation was interrupted, or a required reconnection got interrupted
+ * @throws IllegalArgumentException
+ * if called from anything except the ZooKeeper event thread
+ * @throws ZkException
+ * if any ZooKeeper exception occurred
+ * @throws RuntimeException
+ * if any other exception occurs
+ */
+ public void createContainer(String path, boolean createParents, List<ACL> acl)
+ throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
+ try {
+ create(path, null, acl, CreateMode.CONTAINER);
+ } catch (ZkNodeExistsException e) {
+ if (!createParents) {
+ throw e;
+ }
+ } catch (ZkNoNodeException e) {
+ if (!createParents) {
+ throw e;
+ }
+ String parentDir = path.substring(0, path.lastIndexOf('/'));
+ createContainer(parentDir, createParents, acl);
+ createContainer(path, createParents, acl);
+ }
+ }
+
/**
* Create a persistent node.
* @param path
@@ -513,6 +654,43 @@ public class ZkClient implements Watcher {
create(path, data, CreateMode.PERSISTENT);
}
+ /**
+ * Create a persistent node with TTL.
+ * @param path the path where you want the node to be created
+ * @param data data of the node
+ * @param ttl TTL of the node in milliseconds
+ * @throws ZkInterruptedException
+ * if operation was interrupted, or a required reconnection got interrupted
+ * @throws IllegalArgumentException
+ * if called from anything except the ZooKeeper event thread
+ * @throws ZkException
+ * if any ZooKeeper exception occurred
+ * @throws RuntimeException
+ * if any other exception occurs
+ */
+ public void createPersistentWithTTL(String path, Object data, long ttl)
+ throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
+ create(path, data, CreateMode.PERSISTENT_WITH_TTL, ttl);
+ }
+
+ /**
+ * Create a container node.
+ * @param path the path where you want the node to be created
+ * @param data data of the node
+ * @throws ZkInterruptedException
+ * if operation was interrupted, or a required reconnection got interrupted
+ * @throws IllegalArgumentException
+ * if called from anything except the ZooKeeper event thread
+ * @throws ZkException
+ * if any ZooKeeper exception occurred
+ * @throws RuntimeException
+ * if any other exception occurs
+ */
+ public void createContainer(String path, Object data)
+ throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
+ create(path, data, CreateMode.CONTAINER);
+ }
+
/**
* Create a persistent node.
* @param path
@@ -531,6 +709,43 @@ public class ZkClient implements Watcher {
create(path, data, acl, CreateMode.PERSISTENT);
}
+ /**
+ * Create a persistent node with TTL.
+ * @param path the path where you want the node to be created
+ * @param data data of the node
+ * @param acl list of ACL for the node
+ * @param ttl TTL of the node in milliseconds
+ * @throws ZkInterruptedException
+ * if operation was interrupted, or a required reconnection got interrupted
+ * @throws IllegalArgumentException
+ * if called from anything except the ZooKeeper event thread
+ * @throws ZkException
+ * if any ZooKeeper exception occurred
+ * @throws RuntimeException
+ * if any other exception occurs
+ */
+ public void createPersistentWithTTL(String path, Object data, List<ACL> acl, long ttl) {
+ create(path, data, acl, CreateMode.PERSISTENT_WITH_TTL, ttl);
+ }
+
+ /**
+ * Create a container node.
+ * @param path the path where you want the node to be created
+ * @param data data of the node
+ * @param acl list of ACL for the node
+ * @throws ZkInterruptedException
+ * if operation was interrupted, or a required reconnection got interrupted
+ * @throws IllegalArgumentException
+ * if called from anything except the ZooKeeper event thread
+ * @throws ZkException
+ * if any ZooKeeper exception occurred
+ * @throws RuntimeException
+ * if any other exception occurs
+ */
+ public void createContainer(String path, Object data, List<ACL> acl) {
+ create(path, data, acl, CreateMode.CONTAINER);
+ }
+
/**
* Create a persistent, sequental node.
* @param path
@@ -550,6 +765,26 @@ public class ZkClient implements Watcher {
return create(path, data, CreateMode.PERSISTENT_SEQUENTIAL);
}
+ /**
+ * Create a persistent, sequential node.
+ * @param path the path where you want the node to be created
+ * @param data data of the node
+ * @param ttl TTL of the node in milliseconds
+ * @return create node's path
+ * @throws ZkInterruptedException
+ * if operation was interrupted, or a required reconnection got interrupted
+ * @throws IllegalArgumentException
+ * if called from anything except the ZooKeeper event thread
+ * @throws ZkException
+ * if any ZooKeeper exception occurred
+ * @throws RuntimeException
+ * if any other exception occurs
+ */
+ public String createPersistentSequentialWithTTL(String path, Object data, long ttl)
+ throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
+ return create(path, data, CreateMode.PERSISTENT_SEQUENTIAL_WITH_TTL, ttl);
+ }
+
/**
* Create a persistent, sequential node and set its ACL.
* @param path
@@ -570,6 +805,27 @@ public class ZkClient implements Watcher {
return create(path, data, acl, CreateMode.PERSISTENT_SEQUENTIAL);
}
+ /**
+ * Create a persistent, sequential node and set its ACL.
+ * @param path the path where you want the node to be created
+ * @param acl list of ACL for the node
+ * @param data data of the node
+ * @param ttl TTL of the node in milliseconds
+ * @return create node's path
+ * @throws ZkInterruptedException
+ * if operation was interrupted, or a required reconnection got interrupted
+ * @throws IllegalArgumentException
+ * if called from anything except the ZooKeeper event thread
+ * @throws ZkException
+ * if any ZooKeeper exception occurred
+ * @throws RuntimeException
+ * if any other exception occurs
+ */
+ public String createPersistentSequentialWithTTL(String path, Object data, List<ACL> acl, long ttl)
+ throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
+ return create(path, data, acl, CreateMode.PERSISTENT_SEQUENTIAL_WITH_TTL, ttl);
+ }
+
/**
* Create an ephemeral node.
* @param path
@@ -648,7 +904,7 @@ public class ZkClient implements Watcher {
*/
public void createEphemeral(final String path, final List<ACL> acl, final String sessionId)
throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
- create(path, null, acl, CreateMode.EPHEMERAL, sessionId);
+ create(path, null, acl, CreateMode.EPHEMERAL, TTL_NOT_SET, sessionId);
}
/**
@@ -671,6 +927,28 @@ public class ZkClient implements Watcher {
return create(path, data, ZooDefs.Ids.OPEN_ACL_UNSAFE, mode);
}
+ /**
+ * Create a node.
+ * @param path the path where you want the node to be created
+ * @param data data of the node
+ * @param mode {@link CreateMode} of the node
+ * @param ttl TTL of the node in milliseconds, if mode is {@link CreateMode#PERSISTENT_WITH_TTL}
+ * or {@link CreateMode#PERSISTENT_SEQUENTIAL_WITH_TTL}
+ * @return create node's path
+ * @throws ZkInterruptedException
+ * if operation was interrupted, or a required reconnection got interrupted
+ * @throws IllegalArgumentException
+ * if called from anything except the ZooKeeper event thread
+ * @throws ZkException
+ * if any ZooKeeper exception occurred
+ * @throws RuntimeException
+ * if any other exception occurs
+ */
+ public String create(final String path, Object data, final CreateMode mode, long ttl)
+ throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
+ return create(path, data, ZooDefs.Ids.OPEN_ACL_UNSAFE, mode, ttl);
+ }
+
/**
* Create a node with ACL.
* @param path
@@ -689,7 +967,30 @@ public class ZkClient implements Watcher {
*/
public String create(final String path, Object datat, final List<ACL> acl, final CreateMode mode)
throws IllegalArgumentException, ZkException {
- return create(path, datat, acl, mode, null);
+ return create(path, datat, acl, mode, TTL_NOT_SET, null);
+ }
+
+ /**
+ * Create a node with ACL.
+ * @param path the path where you want the node to be created
+ * @param datat data of the node
+ * @param acl list of ACL for the node
+ * @param mode {@link CreateMode} of the node
+ * @param ttl TTL of the node in milliseconds, if mode is {@link CreateMode#PERSISTENT_WITH_TTL}
+ * or {@link CreateMode#PERSISTENT_SEQUENTIAL_WITH_TTL}
+ * @return create node's path
+ * @throws ZkInterruptedException
+ * if operation was interrupted, or a required reconnection got interrupted
+ * @throws IllegalArgumentException
+ * if called from anything except the ZooKeeper event thread
+ * @throws ZkException
+ * if any ZooKeeper exception occurred
+ * @throws RuntimeException
+ * if any other exception occurs
+ */
+ public String create(final String path, Object datat, final List<ACL> acl, final CreateMode mode,
+ long ttl) throws IllegalArgumentException, ZkException {
+ return create(path, datat, acl, mode, ttl, null);
}
/**
@@ -705,6 +1006,8 @@ public class ZkClient implements Watcher {
* @param dataObject data of the node
* @param acl list of ACL for the node
* @param mode {@link CreateMode} of the node
+ * @param ttl TTL of the node in milliseconds, if mode is {@link CreateMode#PERSISTENT_WITH_TTL}
+ * or {@link CreateMode#PERSISTENT_SEQUENTIAL_WITH_TTL}
* @param expectedSessionId the expected session ID of the ZK connection. It is not necessarily the
* session ID of current ZK Connection. If the expected session ID is NOT null,
* the node is guaranteed to be created in the expected session, or creation is
@@ -715,7 +1018,7 @@ public class ZkClient implements Watcher {
* @throws ZkException if any zookeeper exception occurs
*/
private String create(final String path, final Object dataObject, final List<ACL> acl,
- final CreateMode mode, final String expectedSessionId)
+ final CreateMode mode, long ttl, final String expectedSessionId)
throws IllegalArgumentException, ZkException {
if (path == null) {
throw new NullPointerException("Path must not be null.");
@@ -728,8 +1031,14 @@ public class ZkClient implements Watcher {
final byte[] dataBytes = dataObject == null ? null : serialize(dataObject, path);
checkDataSizeLimit(path, dataBytes);
- final String actualPath = retryUntilConnected(
- () -> getExpectedZookeeper(expectedSessionId).create(path, dataBytes, acl, mode));
+ final String actualPath;
+ if (mode.isTTL()) {
+ actualPath = retryUntilConnected(() -> getExpectedZookeeper(expectedSessionId)
+ .create(path, dataBytes, acl, mode, null, ttl));
+ } else {
+ actualPath = retryUntilConnected(() -> getExpectedZookeeper(expectedSessionId)
+ .create(path, dataBytes, acl, mode));
+ }
record(path, dataBytes, startT, ZkClientMonitor.AccessType.WRITE);
return actualPath;
@@ -786,7 +1095,7 @@ public class ZkClient implements Watcher {
*/
public void createEphemeral(final String path, final Object data, final String sessionId)
throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
- create(path, data, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL, sessionId);
+ create(path, data, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL, TTL_NOT_SET, sessionId);
}
/**
@@ -836,7 +1145,7 @@ public class ZkClient implements Watcher {
public void createEphemeral(final String path, final Object data, final List<ACL> acl,
final String sessionId)
throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
- create(path, data, acl, CreateMode.EPHEMERAL, sessionId);
+ create(path, data, acl, CreateMode.EPHEMERAL, TTL_NOT_SET, sessionId);
}
/**
@@ -882,7 +1191,7 @@ public class ZkClient implements Watcher {
public String createEphemeralSequential(final String path, final Object data, final List<ACL> acl,
final String sessionId)
throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
- return create(path, data, acl, CreateMode.EPHEMERAL_SEQUENTIAL, sessionId);
+ return create(path, data, acl, CreateMode.EPHEMERAL_SEQUENTIAL, TTL_NOT_SET, sessionId);
}
/**
@@ -914,7 +1223,7 @@ public class ZkClient implements Watcher {
final String sessionId)
throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
return create(path, data, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL,
- sessionId);
+ TTL_NOT_SET, sessionId);
}
/**
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/ZkConnection.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/ZkConnection.java
index 08a2fb9aa..01935919c 100644
--- a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/ZkConnection.java
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/ZkConnection.java
@@ -133,6 +133,12 @@ public class ZkConnection implements IZkConnection {
return _zk.create(path, data, acl, mode);
}
+ @Override
+ public String create(String path, byte[] data, List<ACL> acl, CreateMode mode, long ttl)
+ throws KeeperException, InterruptedException {
+ return _zk.create(path, data, acl, mode, null, ttl);
+ }
+
@Override
public void delete(String path) throws InterruptedException, KeeperException {
_zk.delete(path, -1);
diff --git a/zookeeper-api/src/test/java/org/apache/helix/zookeeper/impl/client/TestRawZkClient.java b/zookeeper-api/src/test/java/org/apache/helix/zookeeper/impl/client/TestRawZkClient.java
index 20d070b52..9e8a75a73 100644
--- a/zookeeper-api/src/test/java/org/apache/helix/zookeeper/impl/client/TestRawZkClient.java
+++ b/zookeeper-api/src/test/java/org/apache/helix/zookeeper/impl/client/TestRawZkClient.java
@@ -89,6 +89,135 @@ public class TestRawZkClient extends ZkTestBase {
_zkClient.close();
}
+ @Test
+ void testUnimplementedTypes() {
+ // Make sure extended types are disabled
+ System.clearProperty("zookeeper.extendedTypesEnabled");
+
+ // Make sure the test path is clear
+ String parentPath = "/tmp";
+ String path = "/tmp/unimplemented";
+ _zkClient.deleteRecursively(parentPath);
+
+ try {
+ long ttl = 1L;
+ _zkClient.createPersistentWithTTL(path, true, ttl);
+ } catch (ZkException e) {
+ AssertJUnit.assertTrue(e.getCause() instanceof KeeperException.UnimplementedException);
+ return;
+ }
+
+ // Clean up
+ _zkClient.deleteRecursively(parentPath);
+ AssertJUnit.fail();
+ }
+
+ @Test
+ void testCreatePersistentWithTTL() {
+ // Enable extended types and create a ZkClient
+ System.setProperty("zookeeper.extendedTypesEnabled", "true");
+ ZkClient zkClient = new ZkClient(ZkTestBase.ZK_ADDR);
+ zkClient.setZkSerializer(new ZNRecordSerializer());
+
+ // Make sure the test path is clear
+ String parentPath = "/tmp";
+ String path = "/tmp/createTTL";
+ zkClient.deleteRecursively(parentPath);
+ AssertJUnit.assertFalse(zkClient.exists(parentPath));
+ AssertJUnit.assertFalse(zkClient.exists(path));
+
+ long ttl = 1L;
+ ZNRecord record = new ZNRecord("record");
+ String key = "key";
+ String value = "value";
+ record.setSimpleField(key, value);
+
+ // Create a ZNode with the above ZNRecord and read back its data
+ zkClient.createPersistentWithTTL(parentPath, record, ttl);
+ AssertJUnit.assertTrue(zkClient.exists(parentPath));
+ ZNRecord retrievedRecord = zkClient.readData(parentPath);
+ AssertJUnit.assertEquals(value, retrievedRecord.getSimpleField(key));
+
+ // Clear the path and test with createParents = true
+ AssertJUnit.assertTrue(zkClient.delete(parentPath));
+ zkClient.createPersistentWithTTL(path, true, ttl);
+ AssertJUnit.assertTrue(zkClient.exists(path));
+
+ // Clean up
+ zkClient.deleteRecursively(parentPath);
+ zkClient.close();
+ System.clearProperty("zookeeper.extendedTypesEnabled");
+ }
+
+ @Test
+ void testCreatePersistentSequentialWithTTL() {
+ // Enable extended types and create a ZkClient
+ System.setProperty("zookeeper.extendedTypesEnabled", "true");
+ ZkClient zkClient = new ZkClient(ZkTestBase.ZK_ADDR);
+ zkClient.setZkSerializer(new ZNRecordSerializer());
+
+ // Make sure the test path is clear
+ String parentPath = "/tmp";
+ String path = "/tmp/createSequentialTTL";
+ zkClient.deleteRecursively(parentPath);
+ AssertJUnit.assertFalse(zkClient.exists(parentPath));
+ AssertJUnit.assertFalse(zkClient.exists(path + "0000000000"));
+
+ long ttl = 1L;
+ ZNRecord record = new ZNRecord("record");
+ String key = "key";
+ String value = "value";
+ record.setSimpleField(key, value);
+
+ // Create a ZNode with the above ZNRecord and read back its data
+ zkClient.createPersistent(parentPath);
+ zkClient.createPersistentSequentialWithTTL(path, record, ttl);
+ AssertJUnit.assertTrue(zkClient.exists(path + "0000000000"));
+ ZNRecord retrievedRecord = zkClient.readData(path + "0000000000");
+ AssertJUnit.assertEquals(value, retrievedRecord.getSimpleField(key));
+
+ // Clean up
+ zkClient.deleteRecursively(parentPath);
+ zkClient.close();
+ System.clearProperty("zookeeper.extendedTypesEnabled");
+ }
+
+ @Test
+ void testCreateContainer() {
+ // Enable extended types and create a ZkClient
+ System.setProperty("zookeeper.extendedTypesEnabled", "true");
+ ZkClient zkClient = new ZkClient(ZkTestBase.ZK_ADDR);
+ zkClient.setZkSerializer(new ZNRecordSerializer());
+
+ // Make sure the test path is clear
+ String parentPath = "/tmp";
+ String path = "/tmp/createContainer";
+ zkClient.deleteRecursively(parentPath);
+ AssertJUnit.assertFalse(zkClient.exists(parentPath));
+ AssertJUnit.assertFalse(zkClient.exists(path));
+
+ ZNRecord record = new ZNRecord("record");
+ String key = "key";
+ String value = "value";
+ record.setSimpleField(key, value);
+
+ // Create a ZNode with the above ZNRecord and read back its data
+ zkClient.createContainer(parentPath, record);
+ AssertJUnit.assertTrue(zkClient.exists(parentPath));
+ ZNRecord retrievedRecord = zkClient.readData(parentPath);
+ AssertJUnit.assertEquals(value, retrievedRecord.getSimpleField(key));
+
+ // Clear the path and test with createParents = true
+ AssertJUnit.assertTrue(zkClient.delete(parentPath));
+ zkClient.createContainer(path, true);
+ AssertJUnit.assertTrue(zkClient.exists(path));
+
+ // Clean up
+ zkClient.deleteRecursively(parentPath);
+ zkClient.close();
+ System.clearProperty("zookeeper.extendedTypesEnabled");
+ }
+
@Test()
void testGetStat() {
String path = "/tmp/getStatTest";