This is an automated email from the ASF dual-hosted git repository.
xyuanlu pushed a commit to branch metaclient
in repository https://gitbox.apache.org/repos/asf/helix.git
The following commit(s) were added to refs/heads/metaclient by this push:
new 873b071f3 Add API for getDataAndStat (#2535)
873b071f3 is described below
commit 873b071f3dd9bc42ae8e381c6b1ca769a4d5fe12
Author: xyuanlu <[email protected]>
AuthorDate: Wed Jun 21 09:05:02 2023 -0700
Add API for getDataAndStat (#2535)
Add API for getDataAndStat
---
.../helix/metaclient/api/MetaClientInterface.java | 13 ++++++++--
.../helix/metaclient/impl/zk/ZkMetaClient.java | 16 +++++++++++--
.../metaclient/impl/zk/util/ZkMetaClientUtil.java | 8 +++++++
.../helix/metaclient/impl/zk/TestZkMetaClient.java | 28 ++++++++++++++++++++++
4 files changed, 61 insertions(+), 4 deletions(-)
diff --git
a/meta-client/src/main/java/org/apache/helix/metaclient/api/MetaClientInterface.java
b/meta-client/src/main/java/org/apache/helix/metaclient/api/MetaClientInterface.java
index 375c0814c..b4bfaac2e 100644
---
a/meta-client/src/main/java/org/apache/helix/metaclient/api/MetaClientInterface.java
+++
b/meta-client/src/main/java/org/apache/helix/metaclient/api/MetaClientInterface.java
@@ -23,7 +23,9 @@ import java.util.List;
import java.util.concurrent.TimeUnit;
import org.apache.commons.lang3.NotImplementedException;
+import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.helix.metaclient.exception.MetaClientInterruptException;
+import org.apache.helix.metaclient.exception.MetaClientNoNodeException;
import org.apache.helix.metaclient.exception.MetaClientTimeoutException;
@@ -195,12 +197,19 @@ public interface MetaClientInterface<T> {
/**
* Fetch the data for a given key.
- * TODO: define exception type when key does not exist
* @param key key to identify the entry
- * @return Return data of the entry
+ * @return Return data of the entry. Return null if data does not exists.
*/
T get(final String key);
+ /**
+ * Fetch the data and stat for a given key.
+ * @param key key to identify the entry
+ * @return Return an ImmutablePair of data and stat for the entry.
+ * @throws MetaClientNoNodeException if no such entry
+ */
+ ImmutablePair<T, Stat> getDataAndStat(final String key);
+
/**
* API for transaction. The list of operation will be executed as an atomic
operation.
* @param ops a list of operations. These operations will all be executed or
none of them.
diff --git
a/meta-client/src/main/java/org/apache/helix/metaclient/impl/zk/ZkMetaClient.java
b/meta-client/src/main/java/org/apache/helix/metaclient/impl/zk/ZkMetaClient.java
index 4398e8e3a..fc8998e95 100644
---
a/meta-client/src/main/java/org/apache/helix/metaclient/impl/zk/ZkMetaClient.java
+++
b/meta-client/src/main/java/org/apache/helix/metaclient/impl/zk/ZkMetaClient.java
@@ -28,6 +28,7 @@ import java.util.concurrent.locks.ReentrantLock;
import com.google.common.annotations.VisibleForTesting;
import org.apache.commons.lang3.NotImplementedException;
+import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.helix.metaclient.api.AsyncCallback;
import org.apache.helix.metaclient.api.ChildChangeListener;
import org.apache.helix.metaclient.api.ConnectStateChangeListener;
@@ -166,8 +167,7 @@ public class ZkMetaClient<T> implements
MetaClientInterface<T>, AutoCloseable {
if (zkStats == null) {
return null;
}
- return new
Stat(convertZkEntryModeToMetaClientEntryMode(zkStats.getEphemeralOwner()),
- zkStats.getVersion(), zkStats.getCtime(), zkStats.getMtime(), -1);
+ return ZkMetaClientUtil.convertZkStatToStat(zkStats);
} catch (ZkException e) {
throw translateZkExceptionToMetaclientException(e);
}
@@ -178,6 +178,18 @@ public class ZkMetaClient<T> implements
MetaClientInterface<T>, AutoCloseable {
return _zkClient.readData(key, true);
}
+
+ @Override
+ public ImmutablePair<T, Stat> getDataAndStat(final String key) {
+ try {
+ org.apache.zookeeper.data.Stat zkStat = new
org.apache.zookeeper.data.Stat();
+ T data = _zkClient.readData(key, zkStat);
+ return ImmutablePair.of(data,
ZkMetaClientUtil.convertZkStatToStat(zkStat));
+ } catch (ZkException e) {
+ throw translateZkExceptionToMetaclientException(e);
+ }
+ }
+
@Override
public List<String> getDirectChildrenKeys(String key) {
try {
diff --git
a/meta-client/src/main/java/org/apache/helix/metaclient/impl/zk/util/ZkMetaClientUtil.java
b/meta-client/src/main/java/org/apache/helix/metaclient/impl/zk/util/ZkMetaClientUtil.java
index f21a883f3..6bf0ce74b 100644
---
a/meta-client/src/main/java/org/apache/helix/metaclient/impl/zk/util/ZkMetaClientUtil.java
+++
b/meta-client/src/main/java/org/apache/helix/metaclient/impl/zk/util/ZkMetaClientUtil.java
@@ -262,6 +262,14 @@ public class ZkMetaClientUtil {
}
}
+ public static MetaClientInterface.Stat convertZkStatToStat(
+ org.apache.zookeeper.data.Stat zkStat) {
+ return new MetaClientInterface.Stat(
+ convertZkEntryModeToMetaClientEntryMode(zkStat.getEphemeralOwner()),
zkStat.getVersion(),
+ zkStat.getCtime(), zkStat.getMtime(),
+ EphemeralType.TTL.getValue(zkStat.getEphemeralOwner()));
+ }
+
/**
* This function translate and group Zk exception code to metaclient code.
* It currently includes all ZK code on 3.6.3.
diff --git
a/meta-client/src/test/java/org/apache/helix/metaclient/impl/zk/TestZkMetaClient.java
b/meta-client/src/test/java/org/apache/helix/metaclient/impl/zk/TestZkMetaClient.java
index 69724c9fe..8aca150b0 100644
---
a/meta-client/src/test/java/org/apache/helix/metaclient/impl/zk/TestZkMetaClient.java
+++
b/meta-client/src/test/java/org/apache/helix/metaclient/impl/zk/TestZkMetaClient.java
@@ -19,6 +19,7 @@ package org.apache.helix.metaclient.impl.zk;
* under the License.
*/
+import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.helix.metaclient.api.ChildChangeListener;
import org.apache.helix.metaclient.api.DataUpdater;
import org.apache.helix.metaclient.api.MetaClientInterface;
@@ -208,6 +209,33 @@ public class TestZkMetaClient extends ZkMetaClientTestBase{
}
}
+ @Test
+ public void testGetDataAndStat() {
+ final String key = "/TestZkMetaClient_testGetDataAndStat";
+ ZkMetaClientConfig config =
+ new
ZkMetaClientConfig.ZkMetaClientConfigBuilder().setConnectionAddress(ZK_ADDR).build();
+ try (ZkMetaClient<Integer> zkMetaClient = new ZkMetaClient<>(config)) {
+ zkMetaClient.connect();
+ int initValue = 3;
+ zkMetaClient.create(key, initValue);
+ MetaClientInterface.Stat entryStat = zkMetaClient.exists(key);
+ Assert.assertEquals(entryStat.getVersion(), 0);
+ zkMetaClient.set(key, initValue+1, -1);
+ ImmutablePair<Integer, MetaClientInterface.Stat> touple =
zkMetaClient.getDataAndStat(key);
+ Assert.assertEquals(touple.right.getVersion(), 1);
+ zkMetaClient.delete(key);
+
+ // test non exist key
+ try{
+ zkMetaClient.getDataAndStat(key);
+ } catch (MetaClientException ex){
+ Assert.assertEquals(ex.getClass().getName(),
+ "org.apache.helix.metaclient.exception.MetaClientNoNodeException");
+ }
+
+ }
+ }
+
@Test
public void testGetAndCountChildrenAndRecursiveDelete() {
final String key = "/TestZkMetaClient_testGetAndCountChildren";