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 2019/11/19 23:02:13 UTC

[helix] branch master updated: Modify ZkUtil methods so that they accept ZkAddress as parameter (#606)

This is an automated email from the ASF dual-hosted git repository.

hulee pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/helix.git


The following commit(s) were added to refs/heads/master by this push:
     new 66de313  Modify ZkUtil methods so that they accept ZkAddress as parameter (#606)
66de313 is described below

commit 66de313f1a7f4958565ac2923ca50daa8bbb5040
Author: Hunter Lee <hu...@linkedin.com>
AuthorDate: Tue Nov 19 15:02:07 2019 -0800

    Modify ZkUtil methods so that they accept ZkAddress as parameter (#606)
    
    Replace methods in ZkUtil so that it does not require HelixZkClient
    
    This is so that the users of ZkUtil do not have to create HelixZkClient to use the utility methods.
---
 .../java/org/apache/helix/manager/zk/ZKUtil.java   | 212 ++++++++++++++++++++-
 .../org/apache/helix/manager/zk/TestZKUtil.java    |   5 +-
 2 files changed, 213 insertions(+), 4 deletions(-)

diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ZKUtil.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ZKUtil.java
index 75ba130..daee5a8 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ZKUtil.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ZKUtil.java
@@ -29,12 +29,17 @@ import org.apache.helix.HelixException;
 import org.apache.helix.InstanceType;
 import org.apache.helix.PropertyPathBuilder;
 import org.apache.helix.ZNRecord;
+import org.apache.helix.manager.zk.client.DedicatedZkClientFactory;
 import org.apache.helix.manager.zk.client.HelixZkClient;
 import org.apache.zookeeper.CreateMode;
 import org.apache.zookeeper.data.Stat;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+/**
+ * Using this ZKUtil class for production purposes is NOT recommended since a lot of the static
+ * methods require a ZkClient instance to be passed in.
+ */
 public final class ZKUtil {
   private static Logger logger = LoggerFactory.getLogger(ZKUtil.class);
   private static int RETRYLIMIT = 3;
@@ -42,6 +47,20 @@ public final class ZKUtil {
   private ZKUtil() {
   }
 
+  /**
+   * Note: this method will create a dedicated ZkClient on the fly. Creating and closing a
+   * ZkConnection is a costly operation - use it at your own risk!
+   * @param clusterName
+   * @param zkAddress
+   * @return
+   */
+  public static boolean isClusterSetup(String clusterName, String zkAddress) {
+    HelixZkClient zkClient = getHelixZkClient(zkAddress);
+    boolean result = isClusterSetup(clusterName, zkClient);
+    zkClient.close();
+    return result;
+  }
+
   public static boolean isClusterSetup(String clusterName, HelixZkClient zkClient) {
     if (clusterName == null) {
       logger.info("Fail to check cluster setup : cluster name is null!");
@@ -88,8 +107,25 @@ public final class ZKUtil {
     return isValid;
   }
 
-  public static boolean isInstanceSetup(HelixZkClient zkclient, String clusterName, String instanceName,
+  /**
+   * Note: this method will create a dedicated ZkClient on the fly. Creating and closing a
+   * ZkConnection is a costly operation - use it at your own risk!
+   * @param zkAddress
+   * @param clusterName
+   * @param instanceName
+   * @param type
+   * @return
+   */
+  public static boolean isInstanceSetup(String zkAddress, String clusterName, String instanceName,
       InstanceType type) {
+    HelixZkClient zkClient = getHelixZkClient(zkAddress);
+    boolean result = isInstanceSetup(zkClient, clusterName, instanceName, type);
+    zkClient.close();
+    return result;
+  }
+
+  public static boolean isInstanceSetup(HelixZkClient zkclient, String clusterName,
+      String instanceName, InstanceType type) {
     if (type == InstanceType.PARTICIPANT || type == InstanceType.CONTROLLER_PARTICIPANT) {
       ArrayList<String> requiredPaths = new ArrayList<>();
       requiredPaths.add(PropertyPathBuilder.instanceConfig(clusterName, instanceName));
@@ -121,6 +157,19 @@ public final class ZKUtil {
     return true;
   }
 
+  /**
+   * Note: this method will create a dedicated ZkClient on the fly. Creating and closing a
+   * ZkConnection is a costly operation - use it at your own risk!
+   * @param zkAddress
+   * @param parentPath
+   * @param list
+   */
+  public static void createChildren(String zkAddress, String parentPath, List<ZNRecord> list) {
+    HelixZkClient zkClient = getHelixZkClient(zkAddress);
+    createChildren(zkClient, parentPath, list);
+    zkClient.close();
+  }
+
   public static void createChildren(HelixZkClient client, String parentPath, List<ZNRecord> list) {
     client.createPersistent(parentPath, true);
     if (list != null) {
@@ -130,6 +179,19 @@ public final class ZKUtil {
     }
   }
 
+  /**
+   * Note: this method will create a dedicated ZkClient on the fly. Creating and closing a
+   * ZkConnection is a costly operation - use it at your own risk!
+   * @param zkAddress
+   * @param parentPath
+   * @param nodeRecord
+   */
+  public static void createChildren(String zkAddress, String parentPath, ZNRecord nodeRecord) {
+    HelixZkClient zkClient = getHelixZkClient(zkAddress);
+    createChildren(zkClient, parentPath, nodeRecord);
+    zkClient.close();
+  }
+
   public static void createChildren(HelixZkClient client, String parentPath, ZNRecord nodeRecord) {
     client.createPersistent(parentPath, true);
 
@@ -138,6 +200,19 @@ public final class ZKUtil {
     client.createPersistent(temp, nodeRecord);
   }
 
+  /**
+   * Note: this method will create a dedicated ZkClient on the fly. Creating and closing a
+   * ZkConnection is a costly operation - use it at your own risk!
+   * @param zkAddress
+   * @param parentPath
+   * @param list
+   */
+  public static void dropChildren(String zkAddress, String parentPath, List<ZNRecord> list) {
+    HelixZkClient zkClient = getHelixZkClient(zkAddress);
+    dropChildren(zkClient, parentPath, list);
+    zkClient.close();
+  }
+
   public static void dropChildren(HelixZkClient client, String parentPath, List<ZNRecord> list) {
     // TODO: check if parentPath exists
     if (list != null) {
@@ -147,6 +222,19 @@ public final class ZKUtil {
     }
   }
 
+  /**
+   * Note: this method will create a dedicated ZkClient on the fly. Creating and closing a
+   * ZkConnection is a costly operation - use it at your own risk!
+   * @param zkAddress
+   * @param parentPath
+   * @param nodeRecord
+   */
+  public static void dropChildren(String zkAddress, String parentPath, ZNRecord nodeRecord) {
+    HelixZkClient zkClient = getHelixZkClient(zkAddress);
+    dropChildren(zkClient, parentPath, nodeRecord);
+    zkClient.close();
+  }
+
   public static void dropChildren(HelixZkClient client, String parentPath, ZNRecord nodeRecord) {
     // TODO: check if parentPath exists
     String id = nodeRecord.getId();
@@ -154,6 +242,20 @@ public final class ZKUtil {
     client.deleteRecursively(temp);
   }
 
+  /**
+   * Note: this method will create a dedicated ZkClient on the fly. Creating and closing a
+   * ZkConnection is a costly operation - use it at your own risk!
+   * @param zkAddress
+   * @param path
+   * @return
+   */
+  public static List<ZNRecord> getChildren(String zkAddress, String path) {
+    HelixZkClient zkClient = getHelixZkClient(zkAddress);
+    List<ZNRecord> result = getChildren(zkClient, path);
+    zkClient.close();
+    return result;
+  }
+
   public static List<ZNRecord> getChildren(HelixZkClient client, String path) {
     // parent watch will be set by zkClient
     List<String> children = client.getChildren(path);
@@ -177,6 +279,21 @@ public final class ZKUtil {
     return childRecords;
   }
 
+  /**
+   * Note: this method will create a dedicated ZkClient on the fly. Creating and closing a
+   * ZkConnection is a costly operation - use it at your own risk!
+   * @param zkAddress
+   * @param path
+   * @param record
+   * @param mergeOnUpdate
+   */
+  public static void updateIfExists(String zkAddress, String path, final ZNRecord record,
+      boolean mergeOnUpdate) {
+    HelixZkClient zkClient = getHelixZkClient(zkAddress);
+    updateIfExists(zkClient, path, record, mergeOnUpdate);
+    zkClient.close();
+  }
+
   public static void updateIfExists(HelixZkClient client, String path, final ZNRecord record,
       boolean mergeOnUpdate) {
     if (client.exists(path)) {
@@ -190,6 +307,22 @@ public final class ZKUtil {
     }
   }
 
+  /**
+   * Note: this method will create a dedicated ZkClient on the fly. Creating and closing a
+   * ZkConnection is a costly operation - use it at your own risk!
+   * @param zkAddress
+   * @param path
+   * @param record
+   * @param persistent
+   * @param mergeOnUpdate
+   */
+  public static void createOrMerge(String zkAddress, String path, final ZNRecord record,
+      final boolean persistent, final boolean mergeOnUpdate) {
+    HelixZkClient zkClient = getHelixZkClient(zkAddress);
+    createOrMerge(zkClient, path, record, persistent, mergeOnUpdate);
+    zkClient.close();
+  }
+
   public static void createOrMerge(HelixZkClient client, String path, final ZNRecord record,
       final boolean persistent, final boolean mergeOnUpdate) {
     int retryCount = 0;
@@ -226,6 +359,22 @@ public final class ZKUtil {
     }
   }
 
+  /**
+   * Note: this method will create a dedicated ZkClient on the fly. Creating and closing a
+   * ZkConnection is a costly operation - use it at your own risk!
+   * @param zkAddress
+   * @param path
+   * @param record
+   * @param persistent
+   * @param mergeOnUpdate
+   */
+  public static void createOrUpdate(String zkAddress, String path, final ZNRecord record,
+      final boolean persistent, final boolean mergeOnUpdate) {
+    HelixZkClient zkClient = getHelixZkClient(zkAddress);
+    createOrUpdate(zkClient, path, record, persistent, mergeOnUpdate);
+    zkClient.close();
+  }
+
   public static void createOrUpdate(HelixZkClient client, String path, final ZNRecord record,
       final boolean persistent, final boolean mergeOnUpdate) {
     int retryCount = 0;
@@ -233,7 +382,8 @@ public final class ZKUtil {
       try {
         if (client.exists(path)) {
           DataUpdater<ZNRecord> updater = new DataUpdater<ZNRecord>() {
-            @Override public ZNRecord update(ZNRecord currentData) {
+            @Override
+            public ZNRecord update(ZNRecord currentData) {
               if (currentData != null && mergeOnUpdate) {
                 currentData.update(record);
                 return currentData;
@@ -255,6 +405,22 @@ public final class ZKUtil {
     }
   }
 
+  /**
+   * Note: this method will create a dedicated ZkClient on the fly. Creating and closing a
+   * ZkConnection is a costly operation - use it at your own risk!
+   * @param zkAddress
+   * @param path
+   * @param record
+   * @param persistent
+   * @param mergeOnUpdate
+   */
+  public static void asyncCreateOrMerge(String zkAddress, String path, final ZNRecord record,
+      final boolean persistent, final boolean mergeOnUpdate) {
+    HelixZkClient zkClient = getHelixZkClient(zkAddress);
+    asyncCreateOrMerge(zkClient, path, record, persistent, mergeOnUpdate);
+    zkClient.close();
+  }
+
   public static void asyncCreateOrMerge(HelixZkClient client, String path, final ZNRecord record,
       final boolean persistent, final boolean mergeOnUpdate) {
     try {
@@ -290,6 +456,21 @@ public final class ZKUtil {
     }
   }
 
+  /**
+   * Note: this method will create a dedicated ZkClient on the fly. Creating and closing a
+   * ZkConnection is a costly operation - use it at your own risk!
+   * @param zkAddress
+   * @param path
+   * @param record
+   * @param persistent
+   */
+  public static void createOrReplace(String zkAddress, String path, final ZNRecord record,
+      final boolean persistent) {
+    HelixZkClient zkClient = getHelixZkClient(zkAddress);
+    createOrReplace(zkClient, path, record, persistent);
+    zkClient.close();
+  }
+
   public static void createOrReplace(HelixZkClient client, String path, final ZNRecord record,
       final boolean persistent) {
     int retryCount = 0;
@@ -316,6 +497,20 @@ public final class ZKUtil {
     }
   }
 
+  /**
+   * Note: this method will create a dedicated ZkClient on the fly. Creating and closing a
+   * ZkConnection is a costly operation - use it at your own risk!
+   * @param zkAddress
+   * @param path
+   * @param recordTosubtract
+   */
+  public static void subtract(String zkAddress, final String path,
+      final ZNRecord recordTosubtract) {
+    HelixZkClient zkClient = getHelixZkClient(zkAddress);
+    subtract(zkClient, path, recordTosubtract);
+    zkClient.close();
+  }
+
   public static void subtract(HelixZkClient client, final String path,
       final ZNRecord recordTosubtract) {
     int retryCount = 0;
@@ -341,6 +536,19 @@ public final class ZKUtil {
         logger.warn("Exception trying to createOrReplace " + path + ". Will retry.", e);
       }
     }
+  }
 
+  /**
+   * Returns a dedicated ZkClient.
+   * @return
+   */
+  private static HelixZkClient getHelixZkClient(String zkAddr) {
+    if (zkAddr == null || zkAddr.isEmpty()) {
+      throw new HelixException("ZK Address given is either null or empty!");
+    }
+    HelixZkClient.ZkClientConfig clientConfig = new HelixZkClient.ZkClientConfig();
+    clientConfig.setZkSerializer(new ZNRecordSerializer());
+    return DedicatedZkClientFactory.getInstance()
+        .buildZkClient(new HelixZkClient.ZkConnectionConfig(zkAddr), clientConfig);
   }
 }
diff --git a/helix-core/src/test/java/org/apache/helix/manager/zk/TestZKUtil.java b/helix-core/src/test/java/org/apache/helix/manager/zk/TestZKUtil.java
index 03ea8c3..7974776 100644
--- a/helix-core/src/test/java/org/apache/helix/manager/zk/TestZKUtil.java
+++ b/helix-core/src/test/java/org/apache/helix/manager/zk/TestZKUtil.java
@@ -29,6 +29,7 @@ import org.apache.helix.PropertyPathBuilder;
 import org.apache.helix.TestHelper;
 import org.apache.helix.ZNRecord;
 import org.apache.helix.ZkUnitTestBase;
+import org.apache.helix.manager.zk.client.HelixZkClient;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.AssertJUnit;
@@ -48,10 +49,10 @@ public class TestZKUtil extends ZkUnitTestBase {
     result = ZKUtil.isClusterSetup(null, _gZkClient);
     AssertJUnit.assertFalse(result);
 
-    result = ZKUtil.isClusterSetup(null, null);
+    result = ZKUtil.isClusterSetup(null, (HelixZkClient) null);
     AssertJUnit.assertFalse(result);
 
-    result = ZKUtil.isClusterSetup(clusterName, null);
+    result = ZKUtil.isClusterSetup(clusterName, (HelixZkClient) null);
     AssertJUnit.assertFalse(result);
 
     TestHelper.setupEmptyCluster(_gZkClient, clusterName);