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";

Reply via email to