Add metrics-common, zookeeper-api, helix-common modules (#684)
We want to create a new module called zookeeper-api in order to decouple Helix's ZooKeeper APIs from helix-core. The goal is to enable non-Helix applications to use Helix's ZooKeeper APIs. This change also allows for better modularity and separation of concerns.
diff --git a/bump-up.command b/bump-up.command
index d67616c..b59f314 100755
--- a/bump-up.command
+++ b/bump-up.command
@@ -41,6 +41,40 @@
# git diff pom.xml
grep -C 1 "$new_version" pom.xml
+echo "bump up helix-common/pom.xml"
+sed -i "s/${version}/${new_version}/g" helix-common/pom.xml
+grep -C 1 "$new_version" helix-common/pom.xml
+# git diff helix-common/pom.xml
+
+ivy_file="helix-common-"$version".ivy"
+new_ivy_file="helix-common-"$new_version".ivy"
+# echo "$ivy_file"
+if [ -f helix-common/$ivy_file ]; then
+ echo "bump up helix-common/$ivy_file"
+ git mv "helix-common/$ivy_file" "helix-common/$new_ivy_file"
+ sed -i "s/${version}/${new_version}/g" "helix-common/$new_ivy_file"
+ grep -C 1 "$new_version" "helix-common/$new_ivy_file"
+else
+ echo "helix-common/$ivy_file not exist"
+fi
+
+echo "bump up zookeeper-api/pom.xml"
+sed -i "s/${version}/${new_version}/g" zookeeper-api/pom.xml
+grep -C 1 "$new_version" zookeeper-api/pom.xml
+# git diff zookeeper-api/pom.xml
+
+ivy_file="zookeeper-api-"$version".ivy"
+new_ivy_file="zookeeper-api-"$new_version".ivy"
+# echo "$ivy_file"
+if [ -f zookeeper-api/$ivy_file ]; then
+ echo "bump up zookeeper-api/$ivy_file"
+ git mv "zookeeper-api/$ivy_file" "zookeeper-api/$new_ivy_file"
+ sed -i "s/${version}/${new_version}/g" "zookeeper-api/$new_ivy_file"
+ grep -C 1 "$new_version" "zookeeper-api/$new_ivy_file"
+else
+ echo "zookeeper-api/$ivy_file not exist"
+fi
+
echo "bump up helix-core/pom.xml"
sed -i "s/${version}/${new_version}/g" helix-core/pom.xml
grep -C 1 "$new_version" helix-core/pom.xml
@@ -109,6 +143,7 @@
echo "helix-agent/$ivy_file not exist"
fi
+
for POM in helix-agent/pom.xml recipes/task-execution/pom.xml recipes/pom.xml recipes/distributed-lock-manager/pom.xml recipes/rsync-replicated-file-system/pom.xml recipes/rabbitmq-consumer-group/pom.xml recipes/service-discovery/pom.xml
do
echo "bump up $POM"
diff --git a/helix-admin-webapp/pom.xml b/helix-admin-webapp/pom.xml
index 87e7d8e..bd89133 100644
--- a/helix-admin-webapp/pom.xml
+++ b/helix-admin-webapp/pom.xml
@@ -34,8 +34,11 @@
org.apache.helix*,
org.codehaus.jackson*,
org.apache.commons.cli*,
+ org.apache.commons.cli;version="[1.2,2)",
+ org.apache.commons.io*;version="[1.4,2)",
org.restlet*,
org.slf4j*;version="[1.6,2)",
+ org.apache.zookeeper*;version="[3.4,4)",
*
</osgi.import>
<osgi.export>org.apache.helix.webapp*;version="${project.version};-noimport:=true</osgi.export>
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/HelixAdminWebApp.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/HelixAdminWebApp.java
index 9785537..a68c85d 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/HelixAdminWebApp.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/HelixAdminWebApp.java
@@ -21,7 +21,7 @@
import org.apache.helix.manager.zk.ByteArraySerializer;
import org.apache.helix.manager.zk.ZNRecordSerializer;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.webapp.resources.ResourceUtil;
import org.restlet.Component;
import org.restlet.Context;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ClusterRepresentationUtil.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ClusterRepresentationUtil.java
index 2710684..3adc6af 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ClusterRepresentationUtil.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ClusterRepresentationUtil.java
@@ -34,11 +34,11 @@
import org.apache.helix.PropertyKey.Builder;
import org.apache.helix.PropertyPathBuilder;
import org.apache.helix.PropertyType;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.manager.zk.ZKHelixDataAccessor;
import org.apache.helix.manager.zk.ZNRecordSerializer;
import org.apache.helix.manager.zk.ZkBaseDataAccessor;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.model.LiveInstance.LiveInstanceProperty;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonParseException;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ClusterResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ClusterResource.java
index e168903..f4d1de3 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ClusterResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ClusterResource.java
@@ -25,8 +25,8 @@
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.HelixException;
import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.model.LiveInstance;
import org.apache.helix.tools.ClusterSetup;
import org.codehaus.jackson.JsonGenerationException;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ClustersResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ClustersResource.java
index fe6a6d5..05a2e8f 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ClustersResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ClustersResource.java
@@ -23,8 +23,8 @@
import java.util.List;
import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.tools.ClusterSetup;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ConfigResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ConfigResource.java
index c7a58b5..65f468d 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ConfigResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ConfigResource.java
@@ -25,8 +25,8 @@
import org.apache.helix.HelixAdmin;
import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.model.HelixConfigScope;
import org.apache.helix.model.HelixConfigScope.ConfigScopeProperty;
import org.apache.helix.model.builder.HelixConfigScopeBuilder;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ConstraintResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ConstraintResource.java
index dc16c18..56fc1cf 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ConstraintResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ConstraintResource.java
@@ -22,9 +22,9 @@
import java.util.Map;
import org.apache.helix.HelixAdmin;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.manager.zk.ZKHelixAdmin;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.model.ClusterConstraints.ConstraintType;
import org.apache.helix.tools.ClusterSetup;
import org.restlet.data.MediaType;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ControllerResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ControllerResource.java
index fede1b6..2004992 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ControllerResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ControllerResource.java
@@ -30,10 +30,10 @@
import org.apache.helix.PropertyKey;
import org.apache.helix.PropertyKey.Builder;
import org.apache.helix.PropertyType;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.manager.zk.ZKHelixDataAccessor;
import org.apache.helix.manager.zk.ZkBaseDataAccessor;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.model.LiveInstance;
import org.apache.helix.tools.ClusterSetup;
import org.apache.helix.util.StatusUpdateUtil.Level;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ControllerStatusUpdateResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ControllerStatusUpdateResource.java
index 6a6a7b7..54875c1 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ControllerStatusUpdateResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ControllerStatusUpdateResource.java
@@ -23,7 +23,7 @@
import org.apache.helix.PropertyKey;
import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.webapp.RestAdminApplication;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/CurrentStateResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/CurrentStateResource.java
index 424ce92..6a84ddd 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/CurrentStateResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/CurrentStateResource.java
@@ -23,7 +23,7 @@
import org.apache.helix.PropertyKey;
import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.webapp.RestAdminApplication;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/CurrentStatesResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/CurrentStatesResource.java
index 02582a3..5787075 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/CurrentStatesResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/CurrentStatesResource.java
@@ -22,7 +22,7 @@
import java.io.IOException;
import org.apache.helix.PropertyType;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.webapp.RestAdminApplication;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ErrorResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ErrorResource.java
index 0c12705..5952bc2 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ErrorResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ErrorResource.java
@@ -23,7 +23,7 @@
import org.apache.helix.PropertyKey;
import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.webapp.RestAdminApplication;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ErrorsResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ErrorsResource.java
index 671c528..efb3d97 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ErrorsResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ErrorsResource.java
@@ -22,7 +22,7 @@
import java.io.IOException;
import org.apache.helix.PropertyType;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.webapp.RestAdminApplication;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ExternalViewResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ExternalViewResource.java
index 801a86f..48d0967 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ExternalViewResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ExternalViewResource.java
@@ -23,7 +23,7 @@
import org.apache.helix.PropertyKey;
import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.restlet.data.MediaType;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/IdealStateResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/IdealStateResource.java
index b927a35..ae1a0ab 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/IdealStateResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/IdealStateResource.java
@@ -26,8 +26,8 @@
import org.apache.helix.HelixException;
import org.apache.helix.PropertyKey;
import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.model.IdealState;
import org.apache.helix.tools.ClusterSetup;
import org.codehaus.jackson.JsonGenerationException;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/InstanceResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/InstanceResource.java
index 23d6303..f251cbb 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/InstanceResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/InstanceResource.java
@@ -25,7 +25,7 @@
import org.apache.helix.HelixException;
import org.apache.helix.PropertyKey;
import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.tools.ClusterSetup;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/InstancesResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/InstancesResource.java
index 5909d72..9c03400 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/InstancesResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/InstancesResource.java
@@ -28,8 +28,8 @@
import com.google.common.collect.Lists;
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.model.InstanceConfig;
import org.apache.helix.model.LiveInstance;
import org.apache.helix.tools.ClusterSetup;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobQueueResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobQueueResource.java
index 10c603d..bacd0ea 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobQueueResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobQueueResource.java
@@ -24,8 +24,8 @@
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.HelixException;
import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.model.ResourceConfig;
import org.apache.helix.task.JobConfig;
import org.apache.helix.task.TaskDriver;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobQueuesResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobQueuesResource.java
index 2937026..debdb49 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobQueuesResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobQueuesResource.java
@@ -29,8 +29,8 @@
import org.apache.helix.HelixException;
import org.apache.helix.HelixProperty;
import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.task.JobQueue;
import org.apache.helix.task.TaskDriver;
import org.apache.helix.task.Workflow;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobResource.java
index 8389e5d..aab37ed 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JobResource.java
@@ -22,8 +22,8 @@
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.HelixProperty;
import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.task.JobContext;
import org.apache.helix.task.TaskDriver;
import org.apache.helix.task.TaskUtil;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JsonParameters.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JsonParameters.java
index 41d9a77..69e4de0 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JsonParameters.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/JsonParameters.java
@@ -29,7 +29,7 @@
import java.util.TreeMap;
import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.tools.ClusterSetup;
import org.codehaus.jackson.map.ObjectMapper;
import org.restlet.data.Form;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ResourceGroupResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ResourceGroupResource.java
index a8c7634..860199e 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ResourceGroupResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ResourceGroupResource.java
@@ -25,7 +25,7 @@
import org.apache.helix.HelixException;
import org.apache.helix.PropertyKey;
import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.tools.ClusterSetup;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ResourceGroupsResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ResourceGroupsResource.java
index 75f8fb5..d974987 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ResourceGroupsResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ResourceGroupsResource.java
@@ -27,8 +27,8 @@
import com.google.common.collect.Maps;
import org.apache.helix.HelixException;
import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.model.IdealState;
import org.apache.helix.model.IdealState.RebalanceMode;
import org.apache.helix.tools.ClusterSetup;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ResourceUtil.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ResourceUtil.java
index 78a760a..053b542 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ResourceUtil.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ResourceUtil.java
@@ -30,7 +30,7 @@
import org.apache.helix.HelixException;
import org.apache.helix.PropertyKey;
import org.apache.helix.manager.zk.ZkBaseDataAccessor;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.webapp.RestAdminApplication;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/SchedulerTasksResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/SchedulerTasksResource.java
index 9e4b849..d38c8e4 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/SchedulerTasksResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/SchedulerTasksResource.java
@@ -31,7 +31,7 @@
import org.apache.helix.InstanceType;
import org.apache.helix.PropertyPathBuilder;
import org.apache.helix.manager.zk.DefaultSchedulerMessageHandlerFactory;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.model.LiveInstance;
import org.apache.helix.model.Message;
import org.apache.helix.model.Message.MessageType;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/StateModelResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/StateModelResource.java
index efb5776..ea451eb 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/StateModelResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/StateModelResource.java
@@ -25,8 +25,8 @@
import org.apache.helix.HelixException;
import org.apache.helix.PropertyKey;
import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.model.StateModelDefinition;
import org.apache.helix.tools.ClusterSetup;
import org.apache.helix.webapp.RestAdminApplication;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/StateModelsResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/StateModelsResource.java
index 326fa54..5340067 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/StateModelsResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/StateModelsResource.java
@@ -24,8 +24,8 @@
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.model.StateModelDefinition;
import org.apache.helix.tools.ClusterSetup;
import org.apache.helix.webapp.RestAdminApplication;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/StatusUpdateResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/StatusUpdateResource.java
index 2d81a22..2e9aafe 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/StatusUpdateResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/StatusUpdateResource.java
@@ -23,7 +23,7 @@
import org.apache.helix.PropertyKey;
import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.webapp.RestAdminApplication;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/StatusUpdatesResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/StatusUpdatesResource.java
index 0838a85..4867365 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/StatusUpdatesResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/StatusUpdatesResource.java
@@ -22,7 +22,7 @@
import java.io.IOException;
import org.apache.helix.PropertyType;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.webapp.RestAdminApplication;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/WorkflowsResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/WorkflowsResource.java
index a695c36..658e98d 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/WorkflowsResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/WorkflowsResource.java
@@ -32,8 +32,8 @@
import org.apache.helix.HelixProperty;
import org.apache.helix.InstanceType;
import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.task.TaskDriver;
import org.apache.helix.task.Workflow;
import org.apache.helix.task.WorkflowConfig;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ZkChildResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ZkChildResource.java
index d321e38..2c81de2 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ZkChildResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ZkChildResource.java
@@ -21,8 +21,8 @@
import java.util.List;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.webapp.RestAdminApplication;
import org.apache.zookeeper.data.Stat;
import org.restlet.data.MediaType;
diff --git a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ZkPathResource.java b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ZkPathResource.java
index 3e49284..99294e4 100644
--- a/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ZkPathResource.java
+++ b/helix-admin-webapp/src/main/java/org/apache/helix/webapp/resources/ZkPathResource.java
@@ -23,8 +23,8 @@
import java.util.List;
import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.webapp.RestAdminApplication;
import org.apache.zookeeper.data.Stat;
import org.restlet.data.MediaType;
diff --git a/helix-admin-webapp/src/test/java/org/apache/helix/webapp/AdminTestBase.java b/helix-admin-webapp/src/test/java/org/apache/helix/webapp/AdminTestBase.java
index 0037a5b..6af49de 100644
--- a/helix-admin-webapp/src/test/java/org/apache/helix/webapp/AdminTestBase.java
+++ b/helix-admin-webapp/src/test/java/org/apache/helix/webapp/AdminTestBase.java
@@ -21,13 +21,13 @@
import java.util.logging.Level;
-import org.I0Itec.zkclient.ZkServer;
import org.apache.helix.TestHelper;
import org.apache.helix.manager.zk.ZNRecordSerializer;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.tools.ClusterSetup;
import org.apache.helix.util.ZKClientPool;
import org.apache.helix.webapp.AdminTestHelper.AdminThread;
+import org.apache.helix.zookeeper.zkclient.ZkServer;
import org.restlet.Client;
import org.restlet.data.Protocol;
import org.slf4j.Logger;
diff --git a/helix-admin-webapp/src/test/java/org/apache/helix/webapp/AdminTestHelper.java b/helix-admin-webapp/src/test/java/org/apache/helix/webapp/AdminTestHelper.java
index f5f05c9..acc15ef 100644
--- a/helix-admin-webapp/src/test/java/org/apache/helix/webapp/AdminTestHelper.java
+++ b/helix-admin-webapp/src/test/java/org/apache/helix/webapp/AdminTestHelper.java
@@ -24,7 +24,7 @@
import java.io.StringWriter;
import java.util.concurrent.CountDownLatch;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.codehaus.jackson.map.ObjectMapper;
import org.restlet.Client;
import org.restlet.Request;
diff --git a/helix-admin-webapp/src/test/java/org/apache/helix/webapp/TestClusterManagementWebapp.java b/helix-admin-webapp/src/test/java/org/apache/helix/webapp/TestClusterManagementWebapp.java
index 486af07..0e45ac3 100644
--- a/helix-admin-webapp/src/test/java/org/apache/helix/webapp/TestClusterManagementWebapp.java
+++ b/helix-admin-webapp/src/test/java/org/apache/helix/webapp/TestClusterManagementWebapp.java
@@ -27,7 +27,7 @@
import java.util.Map;
import org.apache.helix.PropertyPathBuilder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.model.InstanceConfig.InstanceConfigProperty;
import org.apache.helix.tools.ClusterSetup;
import org.apache.helix.webapp.resources.ClusterRepresentationUtil;
diff --git a/helix-admin-webapp/src/test/java/org/apache/helix/webapp/TestDisableResource.java b/helix-admin-webapp/src/test/java/org/apache/helix/webapp/TestDisableResource.java
index 9800179..e85fa87 100644
--- a/helix-admin-webapp/src/test/java/org/apache/helix/webapp/TestDisableResource.java
+++ b/helix-admin-webapp/src/test/java/org/apache/helix/webapp/TestDisableResource.java
@@ -27,7 +27,7 @@
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.PropertyKey;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.manager.zk.ZKHelixDataAccessor;
import org.apache.helix.manager.zk.ZkBaseDataAccessor;
import org.apache.helix.model.IdealState;
diff --git a/helix-admin-webapp/src/test/java/org/apache/helix/webapp/TestHelixAdminScenariosRest.java b/helix-admin-webapp/src/test/java/org/apache/helix/webapp/TestHelixAdminScenariosRest.java
index 0b49096..e78e074 100644
--- a/helix-admin-webapp/src/test/java/org/apache/helix/webapp/TestHelixAdminScenariosRest.java
+++ b/helix-admin-webapp/src/test/java/org/apache/helix/webapp/TestHelixAdminScenariosRest.java
@@ -30,7 +30,7 @@
import org.apache.helix.HelixAdmin;
import org.apache.helix.HelixDataAccessor;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.integration.manager.ClusterControllerManager;
import org.apache.helix.integration.manager.ClusterDistributedController;
import org.apache.helix.integration.manager.MockParticipantManager;
diff --git a/helix-admin-webapp/src/test/java/org/apache/helix/webapp/TestResetPartitionState.java b/helix-admin-webapp/src/test/java/org/apache/helix/webapp/TestResetPartitionState.java
index 8d994e8..42bcbad 100644
--- a/helix-admin-webapp/src/test/java/org/apache/helix/webapp/TestResetPartitionState.java
+++ b/helix-admin-webapp/src/test/java/org/apache/helix/webapp/TestResetPartitionState.java
@@ -28,7 +28,7 @@
import org.apache.helix.NotificationContext;
import org.apache.helix.PropertyKey.Builder;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.integration.manager.ClusterControllerManager;
import org.apache.helix.integration.manager.MockParticipantManager;
import org.apache.helix.manager.zk.ZKHelixDataAccessor;
diff --git a/helix-admin-webapp/src/test/java/org/apache/helix/webapp/resources/TestJobQueuesResource.java b/helix-admin-webapp/src/test/java/org/apache/helix/webapp/resources/TestJobQueuesResource.java
index 6d5d5e2..ca34d52 100644
--- a/helix-admin-webapp/src/test/java/org/apache/helix/webapp/resources/TestJobQueuesResource.java
+++ b/helix-admin-webapp/src/test/java/org/apache/helix/webapp/resources/TestJobQueuesResource.java
@@ -25,7 +25,7 @@
import com.google.common.collect.Lists;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.integration.manager.ClusterControllerManager;
import org.apache.helix.integration.manager.MockParticipantManager;
import org.apache.helix.integration.task.MockTask;
diff --git a/helix-common/LICENSE b/helix-common/LICENSE
new file mode 100644
index 0000000..d78ae52
--- /dev/null
+++ b/helix-common/LICENSE
@@ -0,0 +1,270 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+
+For xstream:
+
+Copyright (c) 2003-2006, Joe Walnes
+Copyright (c) 2006-2009, 2011 XStream Committers
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this list of
+conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice, this list of
+conditions and the following disclaimer in the documentation and/or other materials provided
+with the distribution.
+
+3. Neither the name of XStream nor the names of its contributors may be used to endorse
+or promote products derived from this software without specific prior written
+permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
+for jline:
+
+Copyright (c) 2002-2006, Marc Prud'hommeaux <mwp1@cornell.edu>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or
+without modification, are permitted provided that the following
+conditions are met:
+
+Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with
+the distribution.
+
+Neither the name of JLine nor the names of its contributors
+may be used to endorse or promote products derived from this
+software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/helix-common/NOTICE b/helix-common/NOTICE
new file mode 100644
index 0000000..ff5a745
--- /dev/null
+++ b/helix-common/NOTICE
@@ -0,0 +1,37 @@
+Apache Helix
+Copyright 2014 The Apache Software Foundation
+
+
+I. Included Software
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+Licensed under the Apache License 2.0.
+
+This product includes software developed at
+Codehaus (http://www.codehaus.org/).
+Licensed under the BSD License.
+
+This product includes software developed at
+jline (http://jline.sourceforge.net/).
+Licensed under the BSD License.
+
+This product includes software developed at
+restlet (http://www.restlet.org/about/legal).
+Licensed under the Apache License 2.0.
+
+This product includes software developed at
+Google (http://www.google.com/).
+Licensed under the Apache License 2.0.
+
+This product includes software developed at
+snakeyaml (http://www.snakeyaml.org/).
+Licensed under the Apache License 2.0.
+
+This product includes software developed at
+zkclient (https://github.com/sgroschupf/zkclient).
+Licensed under the Apache License 2.0.
+
+II. License Summary
+- Apache License 2.0
+- BSD License
\ No newline at end of file
diff --git a/helix-common/helix-common-0.9.2-SNAPSHOT.ivy b/helix-common/helix-common-0.9.2-SNAPSHOT.ivy
new file mode 100644
index 0000000..e1aa2f5
--- /dev/null
+++ b/helix-common/helix-common-0.9.2-SNAPSHOT.ivy
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<ivy-module version="1.0">
+ <info organisation="org.apache.helix"
+ module="helix-common"
+ revision="0.9.2-SNAPSHOT"
+ status="integration"
+ publication="20170128141623"
+ />
+ <configurations>
+ <conf name="default" visibility="public" description="runtime dependencies and master artifact can be used with this conf" extends="runtime,master"/>
+ <conf name="master" visibility="public" description="contains only the artifact published by this module itself, with no transitive dependencies"/>
+ <conf name="compile" visibility="public" description="this is the default scope, used if none is specified. Compile dependencies are available in all classpaths."/>
+ <conf name="provided" visibility="public" description="this is much like compile, but indicates you expect the JDK or a container to provide it. It is only available on the compilation classpath, and is not transitive."/>
+ <conf name="runtime" visibility="public" description="this scope indicates that the dependency is not required for compilation, but is for execution. It is in the runtime and test classpaths, but not the compile classpath." extends="compile"/>
+ <conf name="test" visibility="private" description="this scope indicates that the dependency is not required for normal use of the application, and is only available for the test compilation and execution phases."/>
+ <conf name="system" visibility="public" description="this scope is similar to provided except that you have to provide the JAR which contains it explicitly. The artifact is always available and is not looked up in a repository."/>
+ </configurations>
+ <publications>
+ <artifact name="helix-common" type="jar" ext="jar" conf="master"/>
+ </publications>
+ <dependencies>
+ <dependency org="org.slf4j" name="slf4j-api" rev="1.7.25" force="true" conf="compile->compile(*),master(*);runtime->runtime(*)">
+ <artifact name="slf4j-api" ext="jar"/>
+ </dependency>
+ <dependency org="org.slf4j" name="slf4j-log4j12" rev="1.7.14" force="true" conf="compile->compile(*),master(*);runtime->runtime(*)">
+ <artifact name="slf4j-log4j12" ext="jar"/>
+ </dependency>
+ <dependency org="org.yaml" name="snakeyaml" rev="1.12" conf="compile->compile(default);runtime->runtime(default);default->default"/>
+ <dependency org="org.codehaus.jackson" name="jackson-core-asl" rev="1.8.5" force="true" conf="compile->compile(*),master(*);runtime->runtime(*)"/>
+ <dependency org="org.codehaus.jackson" name="jackson-mapper-asl" rev="1.8.5" force="true" conf="compile->compile(*),master(*);runtime->runtime(*)"/>
+ <dependency org="commons-cli" name="commons-cli" rev="1.2" force="true" conf="compile->compile(*),master(*);runtime->runtime(*)"/>
+ </dependencies>
+</ivy-module>
diff --git a/helix-common/pom.xml b/helix-common/pom.xml
new file mode 100644
index 0000000..64a5f88
--- /dev/null
+++ b/helix-common/pom.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <groupId>org.apache.helix</groupId>
+ <artifactId>helix</artifactId>
+ <version>0.9.2-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>helix-common</artifactId>
+ <packaging>bundle</packaging>
+ <name>Apache Helix :: Helix Common</name>
+
+ <properties>
+ <osgi.import>
+ org.codehaus.jackson*,
+ org.slf4j*;version="[1.6,2)",
+ *
+ </osgi.import>
+ <osgi.export>org.apache.helix*;version="${project.version};-noimport:=true</osgi.export>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.helix</groupId>
+ <artifactId>metrics-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.helix</groupId>
+ <artifactId>zookeeper-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>1.7.25</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>1.7.14</version>
+ </dependency>
+ <dependency>
+ <groupId>org.testng</groupId>
+ <artifactId>testng</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <resources>
+ <resource>
+ <directory>${basedir}</directory>
+ <includes>
+ <include>DISCLAIMER</include>
+ </includes>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <configuration>
+ <descriptors>
+ <descriptor>src/assemble/assembly.xml</descriptor>
+ </descriptors>
+ </configuration>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/helix-common/src/assemble/assembly.xml b/helix-common/src/assemble/assembly.xml
new file mode 100644
index 0000000..79e2f5c
--- /dev/null
+++ b/helix-common/src/assemble/assembly.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<assembly>
+ <id>pkg</id>
+ <formats>
+ <format>tar</format>
+ </formats>
+ <fileSets>
+ <fileSet>
+ <directory>target/helix-common-pkg/bin</directory>
+ <outputDirectory>bin</outputDirectory>
+ <lineEnding>unix</lineEnding>
+ <fileMode>0755</fileMode>
+ <directoryMode>0755</directoryMode>
+ </fileSet>
+ <fileSet>
+ <directory>target/helix-common-pkg/repo/</directory>
+ <outputDirectory>repo</outputDirectory>
+ <fileMode>0755</fileMode>
+ <directoryMode>0755</directoryMode>
+ <excludes>
+ <exclude>**/*.xml</exclude>
+ </excludes>
+ </fileSet>
+ <fileSet>
+ <directory>target/helix-common-pkg/conf</directory>
+ <outputDirectory>conf</outputDirectory>
+ <lineEnding>unix</lineEnding>
+ <fileMode>0755</fileMode>
+ <directoryMode>0755</directoryMode>
+ </fileSet>
+ <fileSet>
+ <directory>${project.basedir}</directory>
+ <outputDirectory>/</outputDirectory>
+ <includes>
+ <include>LICENSE</include>
+ <include>NOTICE</include>
+ <include>DISCLAIMER</include>
+ </includes>
+ <fileMode>0755</fileMode>
+ </fileSet>
+ </fileSets>
+</assembly>
diff --git a/helix-core/src/main/java/org/apache/helix/HelixException.java b/helix-common/src/main/java/org/apache/helix/HelixException.java
similarity index 100%
rename from helix-core/src/main/java/org/apache/helix/HelixException.java
rename to helix-common/src/main/java/org/apache/helix/HelixException.java
diff --git a/helix-common/src/main/java/org/apache/helix/SystemPropertyKeys.java b/helix-common/src/main/java/org/apache/helix/SystemPropertyKeys.java
new file mode 100644
index 0000000..bcb8405
--- /dev/null
+++ b/helix-common/src/main/java/org/apache/helix/SystemPropertyKeys.java
@@ -0,0 +1,60 @@
+package org.apache.helix;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+public class SystemPropertyKeys {
+ // Task Driver
+ public static final String TASK_CONFIG_LIMITATION = "helixTask.configsLimitation";
+
+ // ZKHelixManager
+ public static final String CLUSTER_MANAGER_VERSION = "cluster-manager-version.properties";
+
+ public static final String FLAPPING_TIME_WINDOW = "helixmanager.flappingTimeWindow";
+
+ // max disconnect count during the flapping time window to trigger HelixManager flapping handling
+ public static final String MAX_DISCONNECT_THRESHOLD = "helixmanager.maxDisconnectThreshold";
+
+ public static final String ZK_SESSION_TIMEOUT = "zk.session.timeout";
+
+ public static final String ZK_CONNECTION_TIMEOUT = "zk.connection.timeout";
+
+ @Deprecated
+ public static final String ZK_REESTABLISHMENT_CONNECTION_TIMEOUT =
+ "zk.connectionReEstablishment.timeout";
+
+ public static final String ZK_WAIT_CONNECTED_TIMEOUT = "helixmanager.waitForConnectedTimeout";
+
+ public static final String PARTICIPANT_HEALTH_REPORT_LATENCY =
+ "helixmanager.participantHealthReport.reportLatency";
+
+ // Indicate monitoring level of the HelixManager metrics
+ public static final String MONITOR_LEVEL = "helixmanager.monitorLevel";
+
+ // CallbackHandler
+ public static final String ASYNC_BATCH_MODE_ENABLED = "helix.callbackhandler.isAsyncBatchModeEnabled";
+
+ public static final String LEGACY_ASYNC_BATCH_MODE_ENABLED = "isAsyncBatchModeEnabled";
+
+ // Controller
+ public static final String CONTROLLER_MESSAGE_PURGE_DELAY = "helix.controller.stages.MessageGenerationPhase.messagePurgeDelay";
+
+ // MBean monitor for helix.
+ public static final String HELIX_MONITOR_TIME_WINDOW_LENGTH_MS = "helix.monitor.slidingTimeWindow.ms";
+}
diff --git a/helix-common/src/main/java/org/apache/helix/ZNRecord.java b/helix-common/src/main/java/org/apache/helix/ZNRecord.java
new file mode 100644
index 0000000..a8018fd
--- /dev/null
+++ b/helix-common/src/main/java/org/apache/helix/ZNRecord.java
@@ -0,0 +1,48 @@
+package org.apache.helix;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion;
+
+
+/**
+ * Deprecated; please use ZNRecord in zookeeper-api instead.
+ *
+ * Generic Record Format to store data at a Node This can be used to store
+ * simpleFields mapFields listFields
+ */
+@Deprecated
+@JsonIgnoreProperties(ignoreUnknown = true)
+@JsonSerialize(include = Inclusion.NON_NULL)
+public class ZNRecord extends org.apache.helix.zookeeper.datamodel.ZNRecord {
+ public ZNRecord(String id) {
+ super(id);
+ }
+
+ public ZNRecord(org.apache.helix.zookeeper.datamodel.ZNRecord record) {
+ super(record);
+ }
+
+ public ZNRecord(org.apache.helix.zookeeper.datamodel.ZNRecord record, String id) {
+ super(record, id);
+ }
+}
diff --git a/helix-common/src/main/java/org/apache/helix/ZNRecordDelta.java b/helix-common/src/main/java/org/apache/helix/ZNRecordDelta.java
new file mode 100644
index 0000000..2529d94
--- /dev/null
+++ b/helix-common/src/main/java/org/apache/helix/ZNRecordDelta.java
@@ -0,0 +1,29 @@
+package org.apache.helix;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Deprecated; please use ZNRecordDelta in zookeeper-api instead.
+ *
+ * A ZNRecord container that specifies how it should be merged with another ZNRecord
+ */
+@Deprecated
+public class ZNRecordDelta {
+}
diff --git a/helix-common/src/main/java/org/apache/helix/manager/zk/serializer/JacksonPayloadSerializer.java b/helix-common/src/main/java/org/apache/helix/manager/zk/serializer/JacksonPayloadSerializer.java
new file mode 100644
index 0000000..651836b
--- /dev/null
+++ b/helix-common/src/main/java/org/apache/helix/manager/zk/serializer/JacksonPayloadSerializer.java
@@ -0,0 +1,29 @@
+package org.apache.helix.manager.zk.serializer;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Deprecated; please use JacksonPayloadSerializer in zookeeper-api instead.
+ *
+ * Serializes and deserializes data of a generic type using Jackson
+ */
+@Deprecated
+public class JacksonPayloadSerializer extends org.apache.helix.zookeeper.datamodel.serializer.JacksonPayloadSerializer {
+}
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/serializer/PayloadSerializer.java b/helix-common/src/main/java/org/apache/helix/manager/zk/serializer/PayloadSerializer.java
similarity index 62%
copy from helix-core/src/main/java/org/apache/helix/manager/zk/serializer/PayloadSerializer.java
copy to helix-common/src/main/java/org/apache/helix/manager/zk/serializer/PayloadSerializer.java
index a9531bd..a26e7fb 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/serializer/PayloadSerializer.java
+++ b/helix-common/src/main/java/org/apache/helix/manager/zk/serializer/PayloadSerializer.java
@@ -20,22 +20,10 @@
*/
/**
+ * Deprecated; please use PayloadSerializer in zookeeper-api instead.
+ *
* Interface for converting back and forth between raw bytes and generic objects
*/
-public interface PayloadSerializer {
-
- /**
- * Convert a generic object instance to raw bytes
- * @param data instance of the generic type
- * @return byte array representing the object
- */
- public <T> byte[] serialize(final T data);
-
- /**
- * Convert raw bytes to a generic object instance
- * @param clazz The class represented by the deserialized bytes
- * @param bytes byte array representing the object
- * @return instance of the generic type or null if the conversion failed
- */
- public <T> T deserialize(final Class<T> clazz, final byte[] bytes);
+@Deprecated
+public interface PayloadSerializer extends org.apache.helix.zookeeper.datamodel.serializer.PayloadSerializer {
}
diff --git a/helix-common/src/test/conf/testng.xml b/helix-common/src/test/conf/testng.xml
new file mode 100644
index 0000000..46911d2
--- /dev/null
+++ b/helix-common/src/test/conf/testng.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
+<suite name="Suite" parallel="false">
+ <test name="Test" preserve-order="true">
+ <packages>
+ <package name="org.apache.helix.helix.common.*"/>
+ </packages>
+ </test>
+</suite>
diff --git a/helix-common/src/test/resources/log4j.properties b/helix-common/src/test/resources/log4j.properties
new file mode 100644
index 0000000..24b6d10
--- /dev/null
+++ b/helix-common/src/test/resources/log4j.properties
@@ -0,0 +1,41 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# Set root logger level to DEBUG and its only appender to R.
+log4j.rootLogger=ERROR, C
+
+# A1 is set to be a ConsoleAppender.
+log4j.appender.C=org.apache.log4j.ConsoleAppender
+log4j.appender.C.layout=org.apache.log4j.PatternLayout
+log4j.appender.C.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
+
+log4j.appender.R=org.apache.log4j.RollingFileAppender
+log4j.appender.R.layout=org.apache.log4j.PatternLayout
+log4j.appender.R.layout.ConversionPattern=%5p [%C:%M] (%F:%L) - %m%n
+log4j.appender.R.File=target/ClusterManagerLogs/log.txt
+
+log4j.appender.STATUSDUMP=org.apache.log4j.RollingFileAppender
+log4j.appender.STATUSDUMP.layout=org.apache.log4j.SimpleLayout
+log4j.appender.STATUSDUMP.File=target/ClusterManagerLogs/statusUpdates.log
+
+log4j.logger.org.I0Itec=ERROR
+log4j.logger.org.apache=ERROR
+log4j.logger.com.noelios=ERROR
+log4j.logger.org.restlet=ERROR
+
+log4j.logger.org.apache.helix.monitoring.ZKPathDataDumpTask=ERROR,STATUSDUMP
diff --git a/helix-core/helix-core-0.9.2-SNAPSHOT.ivy b/helix-core/helix-core-0.9.2-SNAPSHOT.ivy
index 07dd266..6a1cdee 100644
--- a/helix-core/helix-core-0.9.2-SNAPSHOT.ivy
+++ b/helix-core/helix-core-0.9.2-SNAPSHOT.ivy
@@ -57,9 +57,8 @@
<dependency org="org.codehaus.jackson" name="jackson-mapper-asl" rev="1.8.5" conf="compile->compile(default);runtime->runtime(default);default->default"/>
<dependency org="commons-io" name="commons-io" rev="1.4" conf="compile->compile(default);runtime->runtime(default);default->default"/>
<dependency org="commons-cli" name="commons-cli" rev="1.2" conf="compile->compile(default);runtime->runtime(default);default->default"/>
- <dependency org="org.apache.commons" name="commons-math" rev="2.1" conf="compile->compile(default);runtime->runtime(default);default->default"/>
- <dependency org="org.apache.commons" name="commons-math3" rev="3.6.1" conf="compile->compile(default);runtime->runtime(default);default->default"/>
- <dependency org="com.101tec" name="zkclient" rev="0.5" conf="compile->compile(default);runtime->runtime(default);default->default"/>
+ <dependency org="commons-math" name="commons-math" rev="2.1" conf="compile->compile(default);runtime->runtime(default);default->default"/>
+ <dependency org="commons-math" name="commons-math3" rev="3.6.1" conf="compile->compile(default);runtime->runtime(default);default->default"/>
<dependency org="com.google.guava" name="guava" rev="15.0" conf="compile->compile(default);runtime->runtime(default);default->default"/>
<dependency org="org.yaml" name="snakeyaml" rev="1.12" conf="compile->compile(default);runtime->runtime(default);default->default"/>
<dependency org="commons-logging" name="commons-logging-api" rev="1.1" conf="compile->compile(*),master(*);runtime->runtime(*)"/>
diff --git a/helix-core/pom.xml b/helix-core/pom.xml
index 1077cc0..18113e1 100644
--- a/helix-core/pom.xml
+++ b/helix-core/pom.xml
@@ -34,7 +34,6 @@
<osgi.import>
javax.management*,
javax.xml.bind*,
- org.I0Itec.zkclient*,
org.apache.commons.cli*;version="[1.2,2)",
org.apache.commons.io*;version="[1.4,2)",
org.apache.commons.math*;version="[2.1,4)",
@@ -55,6 +54,11 @@
<dependencies>
<dependency>
+ <groupId>org.apache.helix</groupId>
+ <artifactId>helix-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
@@ -114,11 +118,6 @@
<version>1.2</version>
</dependency>
<dependency>
- <groupId>com.101tec</groupId>
- <artifactId>zkclient</artifactId>
- <version>0.5</version>
- </dependency>
- <dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<scope>test</scope>
diff --git a/helix-core/src/main/java/org/apache/helix/BaseDataAccessor.java b/helix-core/src/main/java/org/apache/helix/BaseDataAccessor.java
index 34a20ea..ba64664 100644
--- a/helix-core/src/main/java/org/apache/helix/BaseDataAccessor.java
+++ b/helix-core/src/main/java/org/apache/helix/BaseDataAccessor.java
@@ -21,9 +21,9 @@
import java.util.List;
-import org.I0Itec.zkclient.DataUpdater;
-import org.I0Itec.zkclient.IZkChildListener;
-import org.I0Itec.zkclient.IZkDataListener;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
+import org.apache.helix.zookeeper.zkclient.IZkChildListener;
+import org.apache.helix.zookeeper.zkclient.IZkDataListener;
import org.apache.zookeeper.data.Stat;
diff --git a/helix-core/src/main/java/org/apache/helix/ConfigAccessor.java b/helix-core/src/main/java/org/apache/helix/ConfigAccessor.java
index 018743d..b5f06ef 100644
--- a/helix-core/src/main/java/org/apache/helix/ConfigAccessor.java
+++ b/helix-core/src/main/java/org/apache/helix/ConfigAccessor.java
@@ -29,8 +29,6 @@
import org.apache.helix.manager.zk.ZKUtil;
import org.apache.helix.manager.zk.ZNRecordSerializer;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.client.SharedZkClientFactory;
import org.apache.helix.model.ClusterConfig;
import org.apache.helix.model.ConfigScope;
import org.apache.helix.model.HelixConfigScope;
@@ -40,6 +38,9 @@
import org.apache.helix.model.ResourceConfig;
import org.apache.helix.model.builder.HelixConfigScopeBuilder;
import org.apache.helix.util.StringTemplate;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/GroupCommit.java b/helix-core/src/main/java/org/apache/helix/GroupCommit.java
index b23fc2e..7146e37 100644
--- a/helix-core/src/main/java/org/apache/helix/GroupCommit.java
+++ b/helix-core/src/main/java/org/apache/helix/GroupCommit.java
@@ -25,11 +25,13 @@
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
-import org.I0Itec.zkclient.exception.ZkNoNodeException;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNoNodeException;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
// TODO: move to mananger.zk
+
/**
* Support committing updates to data such that they are ordered for each key
*/
@@ -94,8 +96,9 @@
if (queue._running.compareAndSet(null, Thread.currentThread())) {
ArrayList<Entry> processed = new ArrayList<>();
try {
- if (queue._pending.peek() == null)
+ if (queue._pending.peek() == null) {
return true;
+ }
// remove from queue
Entry first = queue._pending.poll();
@@ -123,8 +126,9 @@
Iterator<Entry> it = queue._pending.iterator();
while (it.hasNext()) {
Entry ent = it.next();
- if (!ent._key.equals(mergedKey))
+ if (!ent._key.equals(mergedKey)) {
continue;
+ }
processed.add(ent);
merged.merge(ent._record);
// System.out.println("After merging:" + merged);
@@ -162,7 +166,8 @@
try {
entry.wait(10);
} catch (InterruptedException e) {
- LOG.error("Interrupted while committing change, key: " + key + ", record: " + record, e);
+ LOG.error("Interrupted while committing change, key: " + key + ", record: " + record,
+ e);
// Restore interrupt status
Thread.currentThread().interrupt();
return false;
@@ -172,5 +177,4 @@
}
return success;
}
-
}
diff --git a/helix-core/src/main/java/org/apache/helix/HelixDataAccessor.java b/helix-core/src/main/java/org/apache/helix/HelixDataAccessor.java
index d8dde1e..2a763df 100644
--- a/helix-core/src/main/java/org/apache/helix/HelixDataAccessor.java
+++ b/helix-core/src/main/java/org/apache/helix/HelixDataAccessor.java
@@ -22,12 +22,14 @@
import java.util.List;
import java.util.Map;
-import org.I0Itec.zkclient.DataUpdater;
import org.apache.helix.model.LiveInstance;
import org.apache.helix.model.MaintenanceSignal;
import org.apache.helix.model.Message;
import org.apache.helix.model.PauseSignal;
import org.apache.helix.model.StateModelDefinition;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+
/**
* Interface used to interact with Helix Data Types like IdealState, Config,
@@ -36,9 +38,13 @@
*/
public interface HelixDataAccessor {
boolean createStateModelDef(StateModelDefinition stateModelDef);
+
boolean createControllerMessage(Message message);
+
boolean createControllerLeader(LiveInstance leader);
+
boolean createPause(PauseSignal pauseSignal);
+
boolean createMaintenance(MaintenanceSignal maintenanceSignal);
/**
@@ -67,7 +73,8 @@
* @param value
* @return true if the update was successful
*/
- <T extends HelixProperty> boolean updateProperty(PropertyKey key, DataUpdater<ZNRecord> updater, T value);
+ <T extends HelixProperty> boolean updateProperty(PropertyKey key, DataUpdater<ZNRecord> updater,
+ T value);
/**
* Return the property value, it must be refer to a single Helix Property. i.e
diff --git a/helix-core/src/main/java/org/apache/helix/HelixManager.java b/helix-core/src/main/java/org/apache/helix/HelixManager.java
index 67d77ec..2191153 100644
--- a/helix-core/src/main/java/org/apache/helix/HelixManager.java
+++ b/helix-core/src/main/java/org/apache/helix/HelixManager.java
@@ -43,6 +43,8 @@
import org.apache.helix.participant.StateMachineEngine;
import org.apache.helix.spectator.RoutingTableProvider;
import org.apache.helix.store.zk.ZkHelixPropertyStore;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+
/**
* Class that represents the Helix Agent.
diff --git a/helix-core/src/main/java/org/apache/helix/HelixProperty.java b/helix-core/src/main/java/org/apache/helix/HelixProperty.java
index 540e4c6..a9db500 100644
--- a/helix-core/src/main/java/org/apache/helix/HelixProperty.java
+++ b/helix-core/src/main/java/org/apache/helix/HelixProperty.java
@@ -27,7 +27,9 @@
import java.util.List;
import java.util.Map;
-import org.I0Itec.zkclient.serialize.ZkSerializer;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecordDelta;
+import org.apache.helix.zookeeper.zkclient.serialize.ZkSerializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -39,8 +41,7 @@
private static Logger LOG = LoggerFactory.getLogger(HelixProperty.class);
public enum HelixPropertyAttribute {
- BUCKET_SIZE,
- BATCH_MESSAGE_MODE
+ BUCKET_SIZE, BATCH_MESSAGE_MODE
}
protected final ZNRecord _record;
@@ -172,7 +173,8 @@
*/
public HelixProperty(ZNRecord record, String id) {
_record = new ZNRecord(record, id);
- _stat = new Stat(_record.getVersion(), _record.getCreationTime(), _record.getModifiedTime(), _record.getEphemeralOwner());
+ _stat = new Stat(_record.getVersion(), _record.getCreationTime(), _record.getModifiedTime(),
+ _record.getEphemeralOwner());
}
/**
@@ -201,7 +203,7 @@
@Override
public String toString() {
- return "ZnRecord=" + _record.toString() + ", Stat=" + _stat.toString() ;
+ return "ZnRecord=" + _record.toString() + ", Stat=" + _stat.toString();
}
/**
@@ -226,8 +228,9 @@
* @param bucketSize the bucket size (will default to 0 if negative)
*/
public void setBucketSize(int bucketSize) {
- if (bucketSize <= 0)
+ if (bucketSize <= 0) {
bucketSize = 0;
+ }
_record.setSimpleField(HelixPropertyAttribute.BUCKET_SIZE.toString(), "" + bucketSize);
}
@@ -238,7 +241,8 @@
* @param record the ZNRecord describing the property
* @return typed instance corresponding to the record, or null if conversion fails
*/
- public static <T extends HelixProperty> T convertToTypedInstance(Class<T> clazz, ZNRecord record) {
+ public static <T extends HelixProperty> T convertToTypedInstance(Class<T> clazz,
+ ZNRecord record) {
if (record == null) {
return null;
}
@@ -302,7 +306,7 @@
return Collections.emptyList();
}
- List<ZNRecord> records = new ArrayList<ZNRecord>();
+ List<ZNRecord> records = new ArrayList<>();
for (T typedInstance : typedInstances) {
records.add(typedInstance.getRecord());
}
diff --git a/helix-core/src/main/java/org/apache/helix/LiveInstanceInfoProvider.java b/helix-core/src/main/java/org/apache/helix/LiveInstanceInfoProvider.java
index 91d6194..827d434 100644
--- a/helix-core/src/main/java/org/apache/helix/LiveInstanceInfoProvider.java
+++ b/helix-core/src/main/java/org/apache/helix/LiveInstanceInfoProvider.java
@@ -19,6 +19,9 @@
* under the License.
*/
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+
+
/**
* Interface to provide additional information about a live instance at creation time
*/
diff --git a/helix-core/src/main/java/org/apache/helix/SystemPropertyKeys.java b/helix-core/src/main/java/org/apache/helix/SystemPropertyKeys.java
index d316986..2d824cb 100644
--- a/helix-core/src/main/java/org/apache/helix/SystemPropertyKeys.java
+++ b/helix-core/src/main/java/org/apache/helix/SystemPropertyKeys.java
@@ -1,5 +1,24 @@
package org.apache.helix;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
public class SystemPropertyKeys {
// Task Driver
public static final String TASK_CONFIG_LIMITATION = "helixTask.configsLimitation";
diff --git a/helix-core/src/main/java/org/apache/helix/ZNRecordAssembler.java b/helix-core/src/main/java/org/apache/helix/ZNRecordAssembler.java
index 87231cd..8028007 100644
--- a/helix-core/src/main/java/org/apache/helix/ZNRecordAssembler.java
+++ b/helix-core/src/main/java/org/apache/helix/ZNRecordAssembler.java
@@ -19,33 +19,10 @@
* under the License.
*/
-import java.util.List;
-
/**
+ * Deprecated - use ZNRecordAssembler in zookeeper-api instead.
* Constructs ZNRecords from collections of ZNRecords
*/
-public class ZNRecordAssembler {
- /**
- * Merge a list of ZNRecords into a single ZNRecord
- * @param records
- * @return {@link ZNRecord}
- */
- public ZNRecord assemble(List<ZNRecord> records) {
- ZNRecord assembledRecord = null;
- if (records != null && records.size() > 0) {
- for (ZNRecord record : records) {
- if (record == null) {
- continue;
- }
-
- if (assembledRecord == null) {
- assembledRecord = new ZNRecord(record.getId());
- }
-
- assembledRecord.merge(record);
- }
- }
- return assembledRecord;
- }
-
+@Deprecated
+public class ZNRecordAssembler extends org.apache.helix.zookeeper.datamodel.ZNRecordAssembler {
}
diff --git a/helix-core/src/main/java/org/apache/helix/ZNRecordBucketizer.java b/helix-core/src/main/java/org/apache/helix/ZNRecordBucketizer.java
index 79b56cb..a490572 100644
--- a/helix-core/src/main/java/org/apache/helix/ZNRecordBucketizer.java
+++ b/helix-core/src/main/java/org/apache/helix/ZNRecordBucketizer.java
@@ -19,106 +19,17 @@
* under the License.
*/
-import java.util.HashMap;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
/**
+ * Deprecated - use ZNRecordBucketizer in zookeeper-api instead.
* Operations to divide a ZNRecord into specified buckets
*/
-public class ZNRecordBucketizer {
- private static Logger LOG = LoggerFactory.getLogger(ZNRecordBucketizer.class);
- final int _bucketSize;
-
+@Deprecated
+public class ZNRecordBucketizer extends org.apache.helix.zookeeper.datamodel.ZNRecordBucketizer {
/**
* Instantiate a bucketizer with the number of buckets
* @param bucketSize
*/
public ZNRecordBucketizer(int bucketSize) {
- if (bucketSize <= 0) {
- LOG.debug("bucketSize <= 0 (was " + bucketSize
- + "). Set to 0 to use non-bucketized HelixProperty.");
- bucketSize = 0;
- }
-
- _bucketSize = bucketSize;
- }
-
- /**
- * Calculate bucketName in form of "resourceName_p{startPartition}-p{endPartition}
- * @param partitionName
- * @return the bucket name
- */
- public String getBucketName(String key) {
- if (_bucketSize == 0) {
- // no bucketize
- return null;
- }
-
- int idx = key.lastIndexOf('_');
- if (idx < 0) {
- throw new IllegalArgumentException("Could NOT find partition# in " + key
- + ". partitionName should be in format of resourceName_partition#");
- }
-
- try {
- int partitionNb = Integer.parseInt(key.substring(idx + 1));
- int bucketNb = partitionNb / _bucketSize;
- int startPartition = bucketNb * _bucketSize;
- int endPartition = bucketNb * _bucketSize + (_bucketSize - 1);
- return key.substring(0, idx) + "_p" + startPartition + "-p" + endPartition;
- } catch (NumberFormatException e) {
- throw new IllegalArgumentException("Could NOT parse partition# (" + key.substring(idx + 1)
- + ") in " + key);
- }
- }
-
- /**
- * Bucketize a ZNRecord
- * @param record
- * @return A map of bucket names to bucketized records
- */
- public Map<String, ZNRecord> bucketize(ZNRecord record) {
- Map<String, ZNRecord> map = new HashMap<String, ZNRecord>();
- if (_bucketSize == 0) {
- map.put(record.getId(), record);
- return map;
- }
-
- // bucketize list field
- for (String partitionName : record.getListFields().keySet()) {
- String bucketName = getBucketName(partitionName);
- if (bucketName != null) {
- if (!map.containsKey(bucketName)) {
- map.put(bucketName, new ZNRecord(bucketName));
- }
- ZNRecord bucketizedRecord = map.get(bucketName);
- bucketizedRecord.setListField(partitionName, record.getListField(partitionName));
- } else {
- LOG.error("Can't bucketize " + partitionName + " in list field");
- }
- }
-
- // bucketize map field
- for (String partitionName : record.getMapFields().keySet()) {
- String bucketName = getBucketName(partitionName);
- if (bucketName != null) {
- if (!map.containsKey(bucketName)) {
- map.put(bucketName, new ZNRecord(bucketName));
- }
- ZNRecord bucketizedRecord = map.get(bucketName);
- bucketizedRecord.setMapField(partitionName, record.getMapField(partitionName));
- } else {
- LOG.error("Can't bucketize " + partitionName + " in map field");
- }
- }
-
- // copy all simple fields
- for (ZNRecord bucketizedRecord : map.values()) {
- bucketizedRecord.setSimpleFields(record.getSimpleFields());
- }
- return map;
+ super(bucketSize);
}
}
diff --git a/helix-core/src/main/java/org/apache/helix/ZNRecordUpdater.java b/helix-core/src/main/java/org/apache/helix/ZNRecordUpdater.java
index 6b74dd1..bedb0e4 100644
--- a/helix-core/src/main/java/org/apache/helix/ZNRecordUpdater.java
+++ b/helix-core/src/main/java/org/apache/helix/ZNRecordUpdater.java
@@ -19,28 +19,20 @@
* under the License.
*/
-import org.I0Itec.zkclient.DataUpdater;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+
/**
+ * Deprecated - Use ZNRecordUpdater in zookeeper-api intstead.
* Class that specifies how a ZNRecord should be updated with another ZNRecord
*/
-public class ZNRecordUpdater implements DataUpdater<ZNRecord> {
- final ZNRecord _record;
-
+@Deprecated
+public class ZNRecordUpdater extends org.apache.helix.zookeeper.datamodel.ZNRecordUpdater {
/**
* Initialize with the record that will be updated
* @param record
*/
public ZNRecordUpdater(ZNRecord record) {
- _record = record;
- }
-
- @Override
- public ZNRecord update(ZNRecord current) {
- if (current != null) {
- current.merge(_record);
- return current;
- }
- return _record;
+ super(record);
}
}
diff --git a/helix-core/src/main/java/org/apache/helix/api/config/RebalanceConfig.java b/helix-core/src/main/java/org/apache/helix/api/config/RebalanceConfig.java
index 3750554..8ea1c22 100644
--- a/helix-core/src/main/java/org/apache/helix/api/config/RebalanceConfig.java
+++ b/helix-core/src/main/java/org/apache/helix/api/config/RebalanceConfig.java
@@ -22,7 +22,7 @@
import java.util.HashMap;
import java.util.Map;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.controller.rebalancer.Rebalancer;
import org.apache.helix.task.TaskRebalancer;
import org.slf4j.Logger;
diff --git a/helix-core/src/main/java/org/apache/helix/api/config/StateTransitionTimeoutConfig.java b/helix-core/src/main/java/org/apache/helix/api/config/StateTransitionTimeoutConfig.java
index d39f466..b846b00 100644
--- a/helix-core/src/main/java/org/apache/helix/api/config/StateTransitionTimeoutConfig.java
+++ b/helix-core/src/main/java/org/apache/helix/api/config/StateTransitionTimeoutConfig.java
@@ -22,7 +22,7 @@
import java.util.HashMap;
import java.util.Map;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
public class StateTransitionTimeoutConfig {
public enum StateTransitionTimeoutProperty {
diff --git a/helix-core/src/main/java/org/apache/helix/api/listeners/PreFetch.java b/helix-core/src/main/java/org/apache/helix/api/listeners/PreFetch.java
index b601680..594f533 100644
--- a/helix-core/src/main/java/org/apache/helix/api/listeners/PreFetch.java
+++ b/helix-core/src/main/java/org/apache/helix/api/listeners/PreFetch.java
@@ -22,7 +22,10 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-
+/**
+ * This annotation has been deprecated. Use PreFetch in zookeeper-api module instead.
+ */
+@Deprecated
@Retention(RetentionPolicy.RUNTIME)
public @interface PreFetch {
boolean enabled() default true;
diff --git a/helix-core/src/main/java/org/apache/helix/common/DedupEventProcessor.java b/helix-core/src/main/java/org/apache/helix/common/DedupEventProcessor.java
index c26ecd8..c761a30 100644
--- a/helix-core/src/main/java/org/apache/helix/common/DedupEventProcessor.java
+++ b/helix-core/src/main/java/org/apache/helix/common/DedupEventProcessor.java
@@ -1,6 +1,6 @@
package org.apache.helix.common;
-import org.I0Itec.zkclient.exception.ZkInterruptedException;
+import org.apache.helix.zookeeper.zkclient.exception.ZkInterruptedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/common/caches/TaskDataCache.java b/helix-core/src/main/java/org/apache/helix/common/caches/TaskDataCache.java
index 58c1220..b16e484 100644
--- a/helix-core/src/main/java/org/apache/helix/common/caches/TaskDataCache.java
+++ b/helix-core/src/main/java/org/apache/helix/common/caches/TaskDataCache.java
@@ -30,7 +30,7 @@
import org.apache.helix.AccessOption;
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.PropertyType;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.common.controllers.ControlContextProvider;
import org.apache.helix.controller.LogUtil;
import org.apache.helix.model.ResourceAssignment;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/ExternalViewGenerator.java b/helix-core/src/main/java/org/apache/helix/controller/ExternalViewGenerator.java
index ab25118..2533b97 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/ExternalViewGenerator.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/ExternalViewGenerator.java
@@ -27,7 +27,7 @@
import java.util.TreeMap;
import java.util.TreeSet;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.model.CurrentState.CurrentStateProperty;
import org.apache.helix.model.Message;
import org.slf4j.Logger;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/GenericHelixController.java b/helix-core/src/main/java/org/apache/helix/controller/GenericHelixController.java
index e47c420..8f7da2d 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/GenericHelixController.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/GenericHelixController.java
@@ -38,7 +38,6 @@
import java.util.concurrent.atomic.AtomicReference;
import com.google.common.collect.Sets;
-import org.I0Itec.zkclient.exception.ZkInterruptedException;
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.HelixManager;
import org.apache.helix.NotificationContext;
@@ -99,6 +98,7 @@
import org.apache.helix.model.ResourceConfig;
import org.apache.helix.monitoring.mbeans.ClusterEventMonitor;
import org.apache.helix.monitoring.mbeans.ClusterStatusMonitor;
+import org.apache.helix.zookeeper.zkclient.exception.ZkInterruptedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/HelixControllerMain.java b/helix-core/src/main/java/org/apache/helix/controller/HelixControllerMain.java
index d8e5a3f..d446fec 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/HelixControllerMain.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/HelixControllerMain.java
@@ -35,7 +35,6 @@
import java.util.Arrays;
-import org.I0Itec.zkclient.exception.ZkInterruptedException;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
@@ -50,6 +49,7 @@
import org.apache.helix.manager.zk.HelixManagerShutdownHook;
import org.apache.helix.participant.DistClusterControllerStateModelFactory;
import org.apache.helix.participant.StateMachineEngine;
+import org.apache.helix.zookeeper.zkclient.exception.ZkInterruptedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/HierarchicalDataHolder.java b/helix-core/src/main/java/org/apache/helix/controller/HierarchicalDataHolder.java
index 27ecc40..a6e71ee 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/HierarchicalDataHolder.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/HierarchicalDataHolder.java
@@ -26,7 +26,7 @@
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/changedetector/ResourceChangeSnapshot.java b/helix-core/src/main/java/org/apache/helix/controller/changedetector/ResourceChangeSnapshot.java
index fc8c5c4..4d31ad4 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/changedetector/ResourceChangeSnapshot.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/changedetector/ResourceChangeSnapshot.java
@@ -27,7 +27,7 @@
import java.util.stream.Collectors;
import org.apache.helix.HelixConstants;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
import org.apache.helix.model.ClusterConfig;
import org.apache.helix.model.IdealState;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/dataproviders/ResourceControllerDataProvider.java b/helix-core/src/main/java/org/apache/helix/controller/dataproviders/ResourceControllerDataProvider.java
index 1631d50..74a93c7 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/dataproviders/ResourceControllerDataProvider.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/dataproviders/ResourceControllerDataProvider.java
@@ -29,7 +29,7 @@
import org.apache.helix.HelixConstants;
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.common.caches.AbstractDataCache;
import org.apache.helix.common.caches.PropertyCache;
import org.apache.helix.controller.LogUtil;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/dataproviders/WorkflowControllerDataProvider.java b/helix-core/src/main/java/org/apache/helix/controller/dataproviders/WorkflowControllerDataProvider.java
index 714b659..20308a4 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/dataproviders/WorkflowControllerDataProvider.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/dataproviders/WorkflowControllerDataProvider.java
@@ -26,7 +26,7 @@
import org.apache.helix.HelixConstants;
import org.apache.helix.HelixDataAccessor;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.common.caches.AbstractDataCache;
import org.apache.helix.common.caches.TaskDataCache;
import org.apache.helix.controller.LogUtil;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/AbstractRebalancer.java b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/AbstractRebalancer.java
index 4a6eff8..17343e6 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/AbstractRebalancer.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/AbstractRebalancer.java
@@ -32,7 +32,7 @@
import org.apache.helix.HelixDefinedState;
import org.apache.helix.HelixException;
import org.apache.helix.HelixManager;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.controller.dataproviders.BaseControllerDataProvider;
import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
import org.apache.helix.controller.rebalancer.internal.MappingCalculator;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/AutoRebalancer.java b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/AutoRebalancer.java
index c0b6f26..f74f1eb 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/AutoRebalancer.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/AutoRebalancer.java
@@ -28,7 +28,7 @@
import java.util.Set;
import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
import org.apache.helix.controller.stages.CurrentStateOutput;
import org.apache.helix.model.IdealState;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/DelayedAutoRebalancer.java b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/DelayedAutoRebalancer.java
index 63870ec..448cc73 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/DelayedAutoRebalancer.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/DelayedAutoRebalancer.java
@@ -30,7 +30,7 @@
import java.util.Set;
import org.apache.helix.HelixDefinedState;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.api.config.StateTransitionThrottleConfig;
import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
import org.apache.helix.controller.rebalancer.util.DelayedRebalanceUtil;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/constraint/dataprovider/ZkBasedCapacityProvider.java b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/constraint/dataprovider/ZkBasedCapacityProvider.java
index b4fefb3..f2ba28c 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/constraint/dataprovider/ZkBasedCapacityProvider.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/constraint/dataprovider/ZkBasedCapacityProvider.java
@@ -26,7 +26,7 @@
import org.apache.helix.HelixException;
import org.apache.helix.HelixProperty;
import org.apache.helix.PropertyPathBuilder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.api.rebalancer.constraint.dataprovider.CapacityProvider;
import org.apache.helix.manager.zk.ZNRecordSerializer;
import org.apache.helix.store.zk.ZkHelixPropertyStore;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/constraint/dataprovider/ZkBasedPartitionWeightProvider.java b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/constraint/dataprovider/ZkBasedPartitionWeightProvider.java
index 8325682..bea711f 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/constraint/dataprovider/ZkBasedPartitionWeightProvider.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/constraint/dataprovider/ZkBasedPartitionWeightProvider.java
@@ -26,7 +26,7 @@
import org.apache.helix.HelixException;
import org.apache.helix.HelixProperty;
import org.apache.helix.PropertyPathBuilder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.api.rebalancer.constraint.dataprovider.PartitionWeightProvider;
import org.apache.helix.manager.zk.ZNRecordSerializer;
import org.apache.helix.store.zk.ZkHelixPropertyStore;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/AbstractEvenDistributionRebalanceStrategy.java b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/AbstractEvenDistributionRebalanceStrategy.java
index 267ac1a..71daaad 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/AbstractEvenDistributionRebalanceStrategy.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/AbstractEvenDistributionRebalanceStrategy.java
@@ -32,7 +32,7 @@
import java.util.stream.Collectors;
import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.controller.LogUtil;
import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
import org.apache.helix.controller.rebalancer.strategy.crushMapping.CardDealingAdjustmentAlgorithmV2;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/AutoRebalanceStrategy.java b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/AutoRebalanceStrategy.java
index bd7e46a..0bdaed8 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/AutoRebalanceStrategy.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/AutoRebalanceStrategy.java
@@ -34,7 +34,7 @@
import java.util.TreeSet;
import org.apache.helix.HelixManager;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/ConstraintRebalanceStrategy.java b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/ConstraintRebalanceStrategy.java
index 4d8b41f..a555d34 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/ConstraintRebalanceStrategy.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/ConstraintRebalanceStrategy.java
@@ -28,7 +28,7 @@
import java.util.Random;
import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.api.rebalancer.constraint.AbstractRebalanceHardConstraint;
import org.apache.helix.api.rebalancer.constraint.AbstractRebalanceSoftConstraint;
import org.apache.helix.api.rebalancer.constraint.dataprovider.CapacityProvider;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/CrushRebalanceStrategy.java b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/CrushRebalanceStrategy.java
index 4c1d972..5db5b2a 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/CrushRebalanceStrategy.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/CrushRebalanceStrategy.java
@@ -30,7 +30,7 @@
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.controller.LogUtil;
import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
import org.apache.helix.controller.rebalancer.strategy.crushMapping.CRUSHPlacementAlgorithm;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/MultiRoundCrushRebalanceStrategy.java b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/MultiRoundCrushRebalanceStrategy.java
index 04b084b..847109c 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/MultiRoundCrushRebalanceStrategy.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/MultiRoundCrushRebalanceStrategy.java
@@ -31,7 +31,7 @@
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.controller.LogUtil;
import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
import org.apache.helix.controller.rebalancer.strategy.crushMapping.CRUSHPlacementAlgorithm;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/RebalanceStrategy.java b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/RebalanceStrategy.java
index 223cf8e..4c885cf 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/RebalanceStrategy.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/strategy/RebalanceStrategy.java
@@ -23,7 +23,7 @@
import java.util.List;
import java.util.Map;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.controller.dataproviders.BaseControllerDataProvider;
/**
diff --git a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/AssignmentMetadataStore.java b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/AssignmentMetadataStore.java
index afd0187..381b612 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/AssignmentMetadataStore.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/rebalancer/waged/AssignmentMetadataStore.java
@@ -24,16 +24,15 @@
import java.util.HashMap;
import java.util.Map;
-import org.I0Itec.zkclient.exception.ZkNoNodeException;
-import org.I0Itec.zkclient.serialize.ZkSerializer;
import org.apache.helix.BucketDataAccessor;
import org.apache.helix.HelixException;
import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.manager.zk.ZNRecordJacksonSerializer;
import org.apache.helix.manager.zk.ZkBucketDataAccessor;
import org.apache.helix.model.ResourceAssignment;
-
+import org.apache.helix.zookeeper.zkclient.exception.ZkNoNodeException;
+import org.apache.helix.zookeeper.zkclient.serialize.ZkSerializer;
/**
* A placeholder before we have the real assignment metadata store.
@@ -178,8 +177,8 @@
HelixProperty property = new HelixProperty(name);
// Add each resource's assignment as a simple field in one ZNRecord
// Node that don't use Arrays.toString() for the record converting. The deserialize will fail.
- assignmentMap.forEach((resource, assignment) -> property.getRecord()
- .setSimpleField(resource, new String(SERIALIZER.serialize(assignment.getRecord()))));
+ assignmentMap.forEach((resource, assignment) -> property.getRecord().setSimpleField(resource,
+ new String(SERIALIZER.serialize(assignment.getRecord()))));
return property;
}
@@ -192,8 +191,8 @@
Map<String, ResourceAssignment> assignmentMap = new HashMap<>();
// Convert each resource's assignment String into a ResourceAssignment object and put it in a
// map
- property.getRecord().getSimpleFields().forEach((resource, assignmentStr) -> assignmentMap
- .put(resource,
+ property.getRecord().getSimpleFields()
+ .forEach((resource, assignmentStr) -> assignmentMap.put(resource,
new ResourceAssignment((ZNRecord) SERIALIZER.deserialize(assignmentStr.getBytes()))));
return assignmentMap;
}
diff --git a/helix-core/src/main/java/org/apache/helix/controller/stages/ClusterDataCache.java b/helix-core/src/main/java/org/apache/helix/controller/stages/ClusterDataCache.java
index 0f321e1..c64dc94 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/stages/ClusterDataCache.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/stages/ClusterDataCache.java
@@ -25,7 +25,7 @@
import java.util.concurrent.ConcurrentHashMap;
import org.apache.helix.HelixDataAccessor;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.common.caches.CurrentStateCache;
import org.apache.helix.common.caches.IdealStateCache;
import org.apache.helix.common.caches.InstanceMessagesCache;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/stages/ExternalViewComputeStage.java b/helix-core/src/main/java/org/apache/helix/controller/stages/ExternalViewComputeStage.java
index 0580485..ed5cbc3 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/stages/ExternalViewComputeStage.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/stages/ExternalViewComputeStage.java
@@ -35,9 +35,6 @@
import org.apache.helix.HelixManager;
import org.apache.helix.PropertyKey;
import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.ZNRecordDelta;
-import org.apache.helix.ZNRecordDelta.MergeOperation;
import org.apache.helix.controller.LogUtil;
import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
import org.apache.helix.controller.pipeline.AbstractAsyncBaseStage;
@@ -54,6 +51,8 @@
import org.apache.helix.model.StateModelDefinition;
import org.apache.helix.model.StatusUpdate;
import org.apache.helix.monitoring.mbeans.ClusterStatusMonitor;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecordDelta;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -316,7 +315,7 @@
}
if (finishedTasks.getListFields().size() > 0) {
- ZNRecordDelta znDelta = new ZNRecordDelta(finishedTasks, MergeOperation.SUBTRACT);
+ ZNRecordDelta znDelta = new ZNRecordDelta(finishedTasks, ZNRecordDelta.MergeOperation.SUBTRACT);
List<ZNRecordDelta> deltaList = new LinkedList<ZNRecordDelta>();
deltaList.add(znDelta);
IdealState delta = new IdealState(taskQueueIdealState.getResourceName());
diff --git a/helix-core/src/main/java/org/apache/helix/controller/stages/PersistAssignmentStage.java b/helix-core/src/main/java/org/apache/helix/controller/stages/PersistAssignmentStage.java
index d33cdfc..4959646 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/stages/PersistAssignmentStage.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/stages/PersistAssignmentStage.java
@@ -26,12 +26,11 @@
import java.util.Map;
import java.util.Set;
-import org.I0Itec.zkclient.DataUpdater;
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.HelixException;
import org.apache.helix.HelixManager;
import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.controller.LogUtil;
import org.apache.helix.controller.common.PartitionStateMap;
import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
@@ -43,6 +42,7 @@
import org.apache.helix.model.MasterSlaveSMD;
import org.apache.helix.model.Partition;
import org.apache.helix.model.Resource;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/controller/strategy/AutoRebalanceStrategy.java b/helix-core/src/main/java/org/apache/helix/controller/strategy/AutoRebalanceStrategy.java
index 270e6de..1c325e1 100644
--- a/helix-core/src/main/java/org/apache/helix/controller/strategy/AutoRebalanceStrategy.java
+++ b/helix-core/src/main/java/org/apache/helix/controller/strategy/AutoRebalanceStrategy.java
@@ -33,7 +33,7 @@
import java.util.TreeSet;
import org.apache.helix.HelixManager;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/examples/ExampleHelper.java b/helix-core/src/main/java/org/apache/helix/examples/ExampleHelper.java
index 44ee1e5..c1e87b0 100644
--- a/helix-core/src/main/java/org/apache/helix/examples/ExampleHelper.java
+++ b/helix-core/src/main/java/org/apache/helix/examples/ExampleHelper.java
@@ -22,9 +22,11 @@
import java.io.File;
import java.io.IOException;
-import org.I0Itec.zkclient.IDefaultNameSpace;
-import org.I0Itec.zkclient.ZkServer;
import org.apache.commons.io.FileUtils;
+import org.apache.helix.zookeeper.zkclient.IDefaultNameSpace;
+import org.apache.helix.zookeeper.zkclient.ZkClient;
+import org.apache.helix.zookeeper.zkclient.ZkServer;
+
public class ExampleHelper {
@@ -45,7 +47,7 @@
IDefaultNameSpace defaultNameSpace = new IDefaultNameSpace() {
@Override
- public void createDefaultNameSpace(org.I0Itec.zkclient.ZkClient zkClient) {
+ public void createDefaultNameSpace(ZkClient zkClient) {
// do nothing
}
};
diff --git a/helix-core/src/main/java/org/apache/helix/examples/IdealStateBuilderExample.java b/helix-core/src/main/java/org/apache/helix/examples/IdealStateBuilderExample.java
index 71e6662..f413c46 100644
--- a/helix-core/src/main/java/org/apache/helix/examples/IdealStateBuilderExample.java
+++ b/helix-core/src/main/java/org/apache/helix/examples/IdealStateBuilderExample.java
@@ -22,8 +22,6 @@
import org.apache.helix.controller.HelixControllerMain;
import org.apache.helix.manager.zk.ZKHelixAdmin;
import org.apache.helix.manager.zk.ZNRecordSerializer;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.client.SharedZkClientFactory;
import org.apache.helix.model.IdealState;
import org.apache.helix.model.IdealState.RebalanceMode;
import org.apache.helix.model.InstanceConfig;
@@ -32,6 +30,9 @@
import org.apache.helix.model.builder.FullAutoModeISBuilder;
import org.apache.helix.model.builder.SemiAutoModeISBuilder;
import org.apache.helix.tools.StateModelConfigGenerator;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
+
public class IdealStateBuilderExample {
diff --git a/helix-core/src/main/java/org/apache/helix/examples/IdealStateExample.java b/helix-core/src/main/java/org/apache/helix/examples/IdealStateExample.java
index 723cbbe..988eaa7 100644
--- a/helix-core/src/main/java/org/apache/helix/examples/IdealStateExample.java
+++ b/helix-core/src/main/java/org/apache/helix/examples/IdealStateExample.java
@@ -22,12 +22,13 @@
import org.apache.helix.controller.HelixControllerMain;
import org.apache.helix.manager.zk.ZKHelixAdmin;
import org.apache.helix.manager.zk.ZNRecordSerializer;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.client.SharedZkClientFactory;
import org.apache.helix.model.IdealState.RebalanceMode;
import org.apache.helix.model.InstanceConfig;
import org.apache.helix.model.StateModelDefinition;
import org.apache.helix.tools.StateModelConfigGenerator;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
+
/**
* Ideal state json format file used in this example for CUSTOMIZED ideal state mode
diff --git a/helix-core/src/main/java/org/apache/helix/examples/Quickstart.java b/helix-core/src/main/java/org/apache/helix/examples/Quickstart.java
index 6773848..854b649 100644
--- a/helix-core/src/main/java/org/apache/helix/examples/Quickstart.java
+++ b/helix-core/src/main/java/org/apache/helix/examples/Quickstart.java
@@ -25,9 +25,6 @@
import java.util.Map;
import java.util.TreeSet;
-import org.I0Itec.zkclient.IDefaultNameSpace;
-import org.I0Itec.zkclient.ZkClient;
-import org.I0Itec.zkclient.ZkServer;
import org.apache.helix.HelixAdmin;
import org.apache.helix.HelixManager;
import org.apache.helix.HelixManagerFactory;
@@ -38,6 +35,10 @@
import org.apache.helix.model.InstanceConfig;
import org.apache.helix.model.StateModelDefinition;
import org.apache.helix.participant.StateMachineEngine;
+import org.apache.helix.zookeeper.zkclient.IDefaultNameSpace;
+import org.apache.helix.zookeeper.zkclient.ZkClient;
+import org.apache.helix.zookeeper.zkclient.ZkServer;
+
public class Quickstart {
diff --git a/helix-core/src/main/java/org/apache/helix/examples/WeightAwareRebalanceUtilExample.java b/helix-core/src/main/java/org/apache/helix/examples/WeightAwareRebalanceUtilExample.java
index 13d22ba..a9a4cc4 100644
--- a/helix-core/src/main/java/org/apache/helix/examples/WeightAwareRebalanceUtilExample.java
+++ b/helix-core/src/main/java/org/apache/helix/examples/WeightAwareRebalanceUtilExample.java
@@ -1,12 +1,30 @@
package org.apache.helix.examples;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import org.I0Itec.zkclient.ZkServer;
import org.apache.helix.HelixAdmin;
import org.apache.helix.api.rebalancer.constraint.AbstractRebalanceHardConstraint;
import org.apache.helix.api.rebalancer.constraint.AbstractRebalanceSoftConstraint;
@@ -22,6 +40,8 @@
import org.apache.helix.model.InstanceConfig;
import org.apache.helix.model.ResourceConfig;
import org.apache.helix.util.WeightAwareRebalanceUtil;
+import org.apache.helix.zookeeper.zkclient.ZkServer;
+
public class WeightAwareRebalanceUtilExample {
private static String ZK_ADDRESS = "localhost:2199";
diff --git a/helix-core/src/main/java/org/apache/helix/healthcheck/ParticipantHealthReportCollector.java b/helix-core/src/main/java/org/apache/helix/healthcheck/ParticipantHealthReportCollector.java
index 5ba6cb4..1e92e2a 100644
--- a/helix-core/src/main/java/org/apache/helix/healthcheck/ParticipantHealthReportCollector.java
+++ b/helix-core/src/main/java/org/apache/helix/healthcheck/ParticipantHealthReportCollector.java
@@ -19,7 +19,7 @@
* under the License.
*/
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
public interface ParticipantHealthReportCollector {
void addHealthReportProvider(HealthReportProvider provider);
diff --git a/helix-core/src/main/java/org/apache/helix/healthcheck/ParticipantHealthReportCollectorImpl.java b/helix-core/src/main/java/org/apache/helix/healthcheck/ParticipantHealthReportCollectorImpl.java
index 2ca9dd2..ca08653 100644
--- a/helix-core/src/main/java/org/apache/helix/healthcheck/ParticipantHealthReportCollectorImpl.java
+++ b/helix-core/src/main/java/org/apache/helix/healthcheck/ParticipantHealthReportCollectorImpl.java
@@ -25,7 +25,7 @@
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.HelixManager;
import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.model.HealthStat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/BasicZkSerializer.java b/helix-core/src/main/java/org/apache/helix/manager/zk/BasicZkSerializer.java
index df165b1..99612a0 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/BasicZkSerializer.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/BasicZkSerializer.java
@@ -19,25 +19,17 @@
* under the License.
*/
-import org.I0Itec.zkclient.serialize.ZkSerializer;
+import org.apache.helix.zookeeper.zkclient.serialize.ZkSerializer;
+
/**
- * Basic path based serializer which ignores the path and delegates
- * serialization into a regular {@link ZkSerializer}
+ * Use BasicZkSerializer in zookeeper-api module instead.
*/
-public class BasicZkSerializer implements PathBasedZkSerializer {
- private final ZkSerializer _delegate;
-
- public BasicZkSerializer(ZkSerializer delegate) {
- _delegate = delegate;
- }
-
- public byte[] serialize(Object data, String path) {
- return _delegate.serialize(data);
- }
-
- @Override
- public Object deserialize(byte[] bytes, String path) {
- return _delegate.deserialize(bytes);
+@Deprecated
+public class BasicZkSerializer
+ extends org.apache.helix.zookeeper.zkclient.serialize.BasicZkSerializer {
+ public BasicZkSerializer(
+ ZkSerializer delegate) {
+ super(delegate);
}
}
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ByteArraySerializer.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ByteArraySerializer.java
index d054011..a1889ea 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ByteArraySerializer.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ByteArraySerializer.java
@@ -19,8 +19,9 @@
* under the License.
*/
-import org.I0Itec.zkclient.exception.ZkMarshallingError;
-import org.I0Itec.zkclient.serialize.ZkSerializer;
+import org.apache.helix.zookeeper.zkclient.exception.ZkMarshallingError;
+import org.apache.helix.zookeeper.zkclient.serialize.ZkSerializer;
+
public class ByteArraySerializer implements ZkSerializer {
@Override
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java b/helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
index 0f03ee4..82c9b29 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
@@ -29,9 +29,6 @@
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
-import org.I0Itec.zkclient.IZkChildListener;
-import org.I0Itec.zkclient.IZkDataListener;
-import org.I0Itec.zkclient.exception.ZkNoNodeException;
import org.apache.helix.BaseDataAccessor;
import org.apache.helix.HelixConstants.ChangeType;
import org.apache.helix.HelixDataAccessor;
@@ -43,7 +40,6 @@
import org.apache.helix.PropertyKey;
import org.apache.helix.PropertyPathConfig;
import org.apache.helix.SystemPropertyKeys;
-import org.apache.helix.ZNRecord;
import org.apache.helix.api.listeners.BatchMode;
import org.apache.helix.api.listeners.ClusterConfigChangeListener;
import org.apache.helix.api.listeners.ConfigChangeListener;
@@ -58,7 +54,6 @@
import org.apache.helix.api.listeners.ResourceConfigChangeListener;
import org.apache.helix.api.listeners.ScopedConfigChangeListener;
import org.apache.helix.common.DedupEventProcessor;
-import org.apache.helix.manager.zk.client.HelixZkClient;
import org.apache.helix.model.ClusterConfig;
import org.apache.helix.model.CurrentState;
import org.apache.helix.model.ExternalView;
@@ -68,6 +63,11 @@
import org.apache.helix.model.Message;
import org.apache.helix.model.ResourceConfig;
import org.apache.helix.monitoring.mbeans.HelixCallbackMonitor;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.zkclient.IZkChildListener;
+import org.apache.helix.zookeeper.zkclient.IZkDataListener;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNoNodeException;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ChainedPathZkSerializer.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ChainedPathZkSerializer.java
index 6975ea1..bb815c1 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ChainedPathZkSerializer.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ChainedPathZkSerializer.java
@@ -23,8 +23,9 @@
import java.util.Collections;
import java.util.List;
-import org.I0Itec.zkclient.exception.ZkMarshallingError;
-import org.I0Itec.zkclient.serialize.ZkSerializer;
+import org.apache.helix.zookeeper.zkclient.exception.ZkMarshallingError;
+import org.apache.helix.zookeeper.zkclient.serialize.ZkSerializer;
+
public class ChainedPathZkSerializer implements PathBasedZkSerializer {
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ControllerManagerHelper.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ControllerManagerHelper.java
index eeb2242..3b25f0f 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ControllerManagerHelper.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ControllerManagerHelper.java
@@ -21,13 +21,13 @@
import java.util.List;
-import org.I0Itec.zkclient.exception.ZkInterruptedException;
import org.apache.helix.HelixManager;
import org.apache.helix.HelixTimerTask;
import org.apache.helix.PropertyKey;
import org.apache.helix.controller.GenericHelixController;
import org.apache.helix.messaging.DefaultMessagingService;
import org.apache.helix.messaging.handling.MultiTypeMessageHandlerFactory;
+import org.apache.helix.zookeeper.zkclient.exception.ZkInterruptedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/CurStateCarryOverUpdater.java b/helix-core/src/main/java/org/apache/helix/manager/zk/CurStateCarryOverUpdater.java
index f52a669..8fff9d2 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/CurStateCarryOverUpdater.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/CurStateCarryOverUpdater.java
@@ -19,11 +19,11 @@
* under the License.
*/
-import org.I0Itec.zkclient.DataUpdater;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.model.CurrentState;
import org.apache.helix.task.TaskConstants;
import org.apache.helix.task.TaskPartitionState;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
/**
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/DefaultSchedulerMessageHandlerFactory.java b/helix-core/src/main/java/org/apache/helix/manager/zk/DefaultSchedulerMessageHandlerFactory.java
index 93819f9..defdd6b 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/DefaultSchedulerMessageHandlerFactory.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/DefaultSchedulerMessageHandlerFactory.java
@@ -36,7 +36,7 @@
import org.apache.helix.InstanceType;
import org.apache.helix.NotificationContext;
import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.messaging.AsyncCallback;
import org.apache.helix.messaging.handling.HelixTaskResult;
import org.apache.helix.messaging.handling.MessageHandler;
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/DistributedLeaderElection.java b/helix-core/src/main/java/org/apache/helix/manager/zk/DistributedLeaderElection.java
index 0a9d72d..ed9027b 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/DistributedLeaderElection.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/DistributedLeaderElection.java
@@ -32,7 +32,7 @@
import org.apache.helix.PropertyKey;
import org.apache.helix.PropertyKey.Builder;
import org.apache.helix.PropertyType;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.api.listeners.ControllerChangeListener;
import org.apache.helix.controller.GenericHelixController;
import org.apache.helix.model.ControllerHistory;
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/HelixGroupCommit.java b/helix-core/src/main/java/org/apache/helix/manager/zk/HelixGroupCommit.java
index 9cada74..79f1a51 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/HelixGroupCommit.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/HelixGroupCommit.java
@@ -25,9 +25,9 @@
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
-import org.I0Itec.zkclient.DataUpdater;
-import org.I0Itec.zkclient.exception.ZkBadVersionException;
-import org.I0Itec.zkclient.exception.ZkNoNodeException;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
+import org.apache.helix.zookeeper.zkclient.exception.ZkBadVersionException;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNoNodeException;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ParticipantManager.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ParticipantManager.java
index 7af69c6..411d937 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ParticipantManager.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ParticipantManager.java
@@ -25,8 +25,6 @@
import java.util.Map;
import java.util.concurrent.TimeUnit;
-import org.I0Itec.zkclient.DataUpdater;
-import org.I0Itec.zkclient.exception.ZkNodeExistsException;
import org.apache.helix.AccessOption;
import org.apache.helix.BaseDataAccessor;
import org.apache.helix.ConfigAccessor;
@@ -37,9 +35,6 @@
import org.apache.helix.LiveInstanceInfoProvider;
import org.apache.helix.PreConnectCallback;
import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.ZNRecordBucketizer;
-import org.apache.helix.manager.zk.client.HelixZkClient;
import org.apache.helix.messaging.DefaultMessagingService;
import org.apache.helix.model.CurrentState;
import org.apache.helix.model.HelixConfigScope;
@@ -51,6 +46,12 @@
import org.apache.helix.model.builder.HelixConfigScopeBuilder;
import org.apache.helix.participant.StateMachineEngine;
import org.apache.helix.participant.statemachine.ScheduledTaskStateModelFactory;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecordBucketizer;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNodeExistsException;
+import org.apache.helix.zookeeper.zkclient.exception.ZkSessionMismatchedException;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/PathBasedZkSerializer.java b/helix-core/src/main/java/org/apache/helix/manager/zk/PathBasedZkSerializer.java
index c717298..a248fb8 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/PathBasedZkSerializer.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/PathBasedZkSerializer.java
@@ -19,26 +19,10 @@
* under the License.
*/
-import org.I0Itec.zkclient.exception.ZkMarshallingError;
-
-public interface PathBasedZkSerializer {
-
- /**
- * Serialize data differently according to different paths
- * @param data
- * @param path
- * @return
- * @throws ZkMarshallingError
- */
- public byte[] serialize(Object data, String path) throws ZkMarshallingError;
-
- /**
- * Deserialize data differently according to different paths
- * @param bytes
- * @param path
- * @return
- * @throws ZkMarshallingError
- */
- public Object deserialize(byte[] bytes, String path) throws ZkMarshallingError;
-
+/**
+ * Use PathBasedZkSerializer in zookeeper-api module instead.
+ */
+@Deprecated
+public interface PathBasedZkSerializer
+ extends org.apache.helix.zookeeper.zkclient.serialize.PathBasedZkSerializer {
}
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/WriteThroughCache.java b/helix-core/src/main/java/org/apache/helix/manager/zk/WriteThroughCache.java
index 82e9b21..1dd84f7 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/WriteThroughCache.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/WriteThroughCache.java
@@ -21,11 +21,11 @@
import java.util.List;
-import org.I0Itec.zkclient.exception.ZkNoNodeException;
import org.apache.helix.AccessOption;
import org.apache.helix.BaseDataAccessor;
import org.apache.helix.store.zk.ZNode;
import org.apache.helix.util.HelixUtil;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNoNodeException;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ZKExceptionHandler.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ZKExceptionHandler.java
index 3746e31..1f9e73d 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ZKExceptionHandler.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ZKExceptionHandler.java
@@ -19,7 +19,7 @@
* under the License.
*/
-import org.I0Itec.zkclient.exception.ZkInterruptedException;
+import org.apache.helix.zookeeper.zkclient.exception.ZkInterruptedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ZKHelixAdmin.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ZKHelixAdmin.java
index 61e75b3..77d8103 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ZKHelixAdmin.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ZKHelixAdmin.java
@@ -37,9 +37,6 @@
import java.util.UUID;
import java.util.concurrent.TimeUnit;
-import org.I0Itec.zkclient.DataUpdater;
-import org.I0Itec.zkclient.exception.ZkException;
-import org.I0Itec.zkclient.exception.ZkNoNodeException;
import org.apache.helix.AccessOption;
import org.apache.helix.BaseDataAccessor;
import org.apache.helix.ConfigAccessor;
@@ -53,16 +50,11 @@
import org.apache.helix.PropertyKey.Builder;
import org.apache.helix.PropertyPathBuilder;
import org.apache.helix.PropertyType;
-import org.apache.helix.ZNRecord;
import org.apache.helix.controller.rebalancer.DelayedAutoRebalancer;
import org.apache.helix.controller.rebalancer.strategy.CrushEdRebalanceStrategy;
import org.apache.helix.controller.rebalancer.strategy.RebalanceStrategy;
import org.apache.helix.controller.rebalancer.util.WagedValidationUtil;
import org.apache.helix.controller.rebalancer.waged.WagedRebalancer;
-import org.apache.helix.controller.rebalancer.waged.model.AssignableNode;
-import org.apache.helix.controller.rebalancer.waged.model.AssignableReplica;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.client.SharedZkClientFactory;
import org.apache.helix.model.ClusterConfig;
import org.apache.helix.model.ClusterConstraints;
import org.apache.helix.model.ClusterConstraints.ConstraintType;
@@ -85,6 +77,12 @@
import org.apache.helix.tools.DefaultIdealStateCalculator;
import org.apache.helix.util.HelixUtil;
import org.apache.helix.util.RebalanceUtil;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
+import org.apache.helix.zookeeper.zkclient.exception.ZkException;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNoNodeException;
import org.apache.zookeeper.KeeperException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -491,22 +489,20 @@
// Record a MaintenanceSignal history
if (!accessor.getBaseDataAccessor()
- .update(keyBuilder.controllerLeaderHistory().getPath(), new DataUpdater<ZNRecord>() {
- @Override
- public ZNRecord update(ZNRecord oldRecord) {
- try {
- if (oldRecord == null) {
- oldRecord = new ZNRecord(PropertyType.HISTORY.toString());
+ .update(keyBuilder.controllerLeaderHistory().getPath(),
+ (DataUpdater<ZNRecord>) oldRecord -> {
+ try {
+ if (oldRecord == null) {
+ oldRecord = new ZNRecord(PropertyType.HISTORY.toString());
+ }
+ return new ControllerHistory(oldRecord)
+ .updateMaintenanceHistory(enabled, reason, currentTime, internalReason,
+ customFields, triggeringEntity);
+ } catch (IOException e) {
+ logger.error("Failed to update maintenance history! Exception: {}", e);
+ return oldRecord;
}
- return new ControllerHistory(oldRecord)
- .updateMaintenanceHistory(enabled, reason, currentTime, internalReason,
- customFields, triggeringEntity);
- } catch (IOException e) {
- logger.error("Failed to update maintenance history! Exception: {}", e);
- return oldRecord;
- }
- }
- }, AccessOption.PERSISTENT)) {
+ }, AccessOption.PERSISTENT)) {
logger.error("Failed to write maintenance history to ZK!");
}
}
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ZKHelixDataAccessor.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ZKHelixDataAccessor.java
index 8d3eafa..9f9ddc9 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ZKHelixDataAccessor.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ZKHelixDataAccessor.java
@@ -25,8 +25,6 @@
import java.util.List;
import java.util.Map;
-import org.I0Itec.zkclient.DataUpdater;
-import org.I0Itec.zkclient.exception.ZkNoNodeException;
import org.apache.helix.AccessOption;
import org.apache.helix.BaseDataAccessor;
import org.apache.helix.GroupCommit;
@@ -37,16 +35,18 @@
import org.apache.helix.PropertyKey.Builder;
import org.apache.helix.PropertyPathBuilder;
import org.apache.helix.PropertyType;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.ZNRecordAssembler;
-import org.apache.helix.ZNRecordBucketizer;
-import org.apache.helix.ZNRecordUpdater;
import org.apache.helix.api.exceptions.HelixMetaDataAccessException;
import org.apache.helix.model.LiveInstance;
import org.apache.helix.model.MaintenanceSignal;
import org.apache.helix.model.Message;
import org.apache.helix.model.PauseSignal;
import org.apache.helix.model.StateModelDefinition;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecordAssembler;
+import org.apache.helix.zookeeper.datamodel.ZNRecordBucketizer;
+import org.apache.helix.zookeeper.datamodel.ZNRecordUpdater;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNoNodeException;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ZKHelixManager.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ZKHelixManager.java
index ef0308e..b4368f9 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ZKHelixManager.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ZKHelixManager.java
@@ -31,7 +31,7 @@
import javax.management.JMException;
import com.google.common.collect.Sets;
-import org.I0Itec.zkclient.exception.ZkInterruptedException;
+
import org.apache.helix.BaseDataAccessor;
import org.apache.helix.ClusterMessagingService;
import org.apache.helix.ConfigAccessor;
@@ -50,7 +50,6 @@
import org.apache.helix.PropertyPathBuilder;
import org.apache.helix.PropertyType;
import org.apache.helix.SystemPropertyKeys;
-import org.apache.helix.ZNRecord;
import org.apache.helix.api.listeners.ClusterConfigChangeListener;
import org.apache.helix.api.listeners.ConfigChangeListener;
import org.apache.helix.api.listeners.ControllerChangeListener;
@@ -67,10 +66,6 @@
import org.apache.helix.healthcheck.ParticipantHealthReportCollector;
import org.apache.helix.healthcheck.ParticipantHealthReportCollectorImpl;
import org.apache.helix.healthcheck.ParticipantHealthReportTask;
-import org.apache.helix.manager.zk.client.DedicatedZkClientFactory;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.client.SharedZkClientFactory;
-import org.apache.helix.manager.zk.zookeeper.IZkStateListener;
import org.apache.helix.messaging.DefaultMessagingService;
import org.apache.helix.model.BuiltInStateModelDefinitions;
import org.apache.helix.model.HelixConfigScope.ConfigScopeProperty;
@@ -83,6 +78,13 @@
import org.apache.helix.store.zk.AutoFallbackPropertyStore;
import org.apache.helix.store.zk.ZkHelixPropertyStore;
import org.apache.helix.util.HelixUtil;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.factory.DedicatedZkClientFactory;
+import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
+import org.apache.helix.zookeeper.zkclient.IZkStateListener;
+import org.apache.helix.zookeeper.zkclient.exception.ZkInterruptedException;
+import org.apache.helix.zookeeper.zkclient.serialize.PathBasedZkSerializer;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.slf4j.Logger;
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 821af52..126ae38 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
@@ -23,14 +23,14 @@
import java.util.Collections;
import java.util.List;
-import org.I0Itec.zkclient.DataUpdater;
import org.apache.helix.BaseDataAccessor;
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.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.factory.DedicatedZkClientFactory;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ZNRecordJacksonSerializer.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ZNRecordJacksonSerializer.java
index b375e80..4f139ce 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ZNRecordJacksonSerializer.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ZNRecordJacksonSerializer.java
@@ -19,49 +19,12 @@
* under the License.
*/
-import java.io.IOException;
-import org.I0Itec.zkclient.exception.ZkMarshallingError;
-import org.I0Itec.zkclient.serialize.ZkSerializer;
-import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
-import org.codehaus.jackson.map.ObjectMapper;
-
/**
+ * Use ZNRecordJacksonSerializer in zookeeper-api instead.
+ *
* ZNRecordJacksonSerializer serializes ZNRecord objects into a byte array using Jackson. Note that
* this serializer doesn't check for the size of the resulting binary.
*/
-public class ZNRecordJacksonSerializer implements ZkSerializer {
- private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
-
- @Override
- public byte[] serialize(Object record) throws ZkMarshallingError {
- if (!(record instanceof ZNRecord)) {
- // null is NOT an instance of any class
- throw new HelixException("Input object is not of type ZNRecord (was " + record + ")");
- }
- ZNRecord znRecord = (ZNRecord) record;
-
- try {
- return OBJECT_MAPPER.writeValueAsBytes(znRecord);
- } catch (IOException e) {
- throw new HelixException(
- String.format("Exception during serialization. ZNRecord id: %s", znRecord.getId()), e);
- }
- }
-
- @Override
- public Object deserialize(byte[] bytes) throws ZkMarshallingError {
- if (bytes == null || bytes.length == 0) {
- // reading a parent/null node
- return null;
- }
-
- ZNRecord record;
- try {
- record = OBJECT_MAPPER.readValue(bytes, ZNRecord.class);
- } catch (IOException e) {
- throw new HelixException("Exception during deserialization!", e);
- }
- return record;
- }
+@Deprecated
+public class ZNRecordJacksonSerializer extends org.apache.helix.zookeeper.datamodel.serializer.ZNRecordJacksonSerializer {
}
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ZNRecordSerializer.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ZNRecordSerializer.java
index df9acaa..ba1892f 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ZNRecordSerializer.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ZNRecordSerializer.java
@@ -19,115 +19,9 @@
* under the License.
*/
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.util.List;
-import java.util.Map;
-
-import org.I0Itec.zkclient.serialize.ZkSerializer;
-import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.util.GZipCompressionUtil;
-import org.codehaus.jackson.map.DeserializationConfig;
-import org.codehaus.jackson.map.ObjectMapper;
-import org.codehaus.jackson.map.SerializationConfig;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ZNRecordSerializer implements ZkSerializer {
- private static Logger logger = LoggerFactory.getLogger(ZNRecordSerializer.class);
-
- private static int getListFieldBound(ZNRecord record) {
- int max = Integer.MAX_VALUE;
- if (record.getSimpleFields().containsKey(ZNRecord.LIST_FIELD_BOUND)) {
- String maxStr = record.getSimpleField(ZNRecord.LIST_FIELD_BOUND);
- try {
- max = Integer.parseInt(maxStr);
- } catch (Exception e) {
- logger.error("IllegalNumberFormat for list field bound: " + maxStr);
- }
- }
- return max;
- }
-
- @Override
- public byte[] serialize(Object data) {
- if (!(data instanceof ZNRecord)) {
- // null is NOT an instance of any class
- logger.error("Input object must be of type ZNRecord but it is " + data
- + ". Will not write to zk");
- throw new HelixException("Input object is not of type ZNRecord (was " + data + ")");
- }
-
- ZNRecord record = (ZNRecord) data;
-
- // apply retention policy
- int max = getListFieldBound(record);
- if (max < Integer.MAX_VALUE) {
- Map<String, List<String>> listMap = record.getListFields();
- for (String key : listMap.keySet()) {
- List<String> list = listMap.get(key);
- if (list.size() > max) {
- listMap.put(key, list.subList(0, max));
- }
- }
- }
-
- // do serialization
- ObjectMapper mapper = new ObjectMapper();
- SerializationConfig serializationConfig = mapper.getSerializationConfig();
- serializationConfig.set(SerializationConfig.Feature.INDENT_OUTPUT, true);
- serializationConfig.set(SerializationConfig.Feature.AUTO_DETECT_FIELDS, true);
- serializationConfig.set(SerializationConfig.Feature.CAN_OVERRIDE_ACCESS_MODIFIERS, true);
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- byte[] serializedBytes;
- try {
- mapper.writeValue(baos, data);
- serializedBytes = baos.toByteArray();
- // apply compression if needed
- if (record.getBooleanField("enableCompression", false) || serializedBytes.length > ZNRecord.SIZE_LIMIT) {
- serializedBytes = GZipCompressionUtil.compress(serializedBytes);
- }
- } catch (Exception e) {
- logger.error("Exception during data serialization. Will not write to zk. Data (first 1k): "
- + new String(baos.toByteArray()).substring(0, 1024), e);
- throw new HelixException(e);
- }
- if (serializedBytes.length > ZNRecord.SIZE_LIMIT) {
- logger.error("Data size larger than 1M, ZNRecord.id: " + record.getId()
- + ". Will not write to zk. Data (first 1k): "
- + new String(serializedBytes).substring(0, 1024));
- throw new HelixException("Data size larger than 1M, ZNRecord.id: " + record.getId());
- }
- return serializedBytes;
- }
-
- @Override
- public Object deserialize(byte[] bytes) {
- if (bytes == null || bytes.length == 0) {
- // reading a parent/null node
- return null;
- }
-
- ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
-
- ObjectMapper mapper = new ObjectMapper();
- DeserializationConfig deserializationConfig = mapper.getDeserializationConfig();
- deserializationConfig.set(DeserializationConfig.Feature.AUTO_DETECT_FIELDS, true);
- deserializationConfig.set(DeserializationConfig.Feature.AUTO_DETECT_SETTERS, true);
- deserializationConfig.set(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, true);
- try {
- //decompress the data if its already compressed
- if (GZipCompressionUtil.isCompressed(bytes)) {
- byte[] uncompressedBytes = GZipCompressionUtil.uncompress(bais);
- bais = new ByteArrayInputStream(uncompressedBytes);
- }
- ZNRecord zn = mapper.readValue(bais, ZNRecord.class);
-
- return zn;
- } catch (Exception e) {
- logger.error("Exception during deserialization of bytes: " + new String(bytes), e);
- return null;
- }
- }
+/**
+ * Use ZNRecordSerializer in zookeeper-api instead.
+ */
+@Deprecated
+public class ZNRecordSerializer extends org.apache.helix.zookeeper.datamodel.serializer.ZNRecordSerializer {
}
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ZNRecordStreamingSerializer.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ZNRecordStreamingSerializer.java
index 769baa0..bd18eff 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ZNRecordStreamingSerializer.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ZNRecordStreamingSerializer.java
@@ -19,292 +19,9 @@
* under the License.
*/
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
-
-import com.google.common.collect.Maps;
-import org.I0Itec.zkclient.exception.ZkMarshallingError;
-import org.I0Itec.zkclient.serialize.ZkSerializer;
-import org.apache.commons.codec.binary.Base64;
-import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.util.GZipCompressionUtil;
-import org.codehaus.jackson.JsonFactory;
-import org.codehaus.jackson.JsonGenerator;
-import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ZNRecordStreamingSerializer implements ZkSerializer {
- private static Logger LOG = LoggerFactory.getLogger(ZNRecordStreamingSerializer.class);
-
- private static int getListFieldBound(ZNRecord record) {
- int max = Integer.MAX_VALUE;
- if (record.getSimpleFields().containsKey(ZNRecord.LIST_FIELD_BOUND)) {
- String maxStr = record.getSimpleField(ZNRecord.LIST_FIELD_BOUND);
- try {
- max = Integer.parseInt(maxStr);
- } catch (Exception e) {
- LOG.error("IllegalNumberFormat for list field bound: " + maxStr);
- }
- }
- return max;
- }
-
- @Override
- public byte[] serialize(Object data) throws ZkMarshallingError {
- if (!(data instanceof ZNRecord)) {
- // null is NOT an instance of any class
- LOG.error("Input object must be of type ZNRecord but it is " + data
- + ". Will not write to zk");
- throw new HelixException("Input object is not of type ZNRecord (was " + data + ")");
- }
-
- // apply retention policy on list field
- ZNRecord record = (ZNRecord) data;
- int max = getListFieldBound(record);
- if (max < Integer.MAX_VALUE) {
- Map<String, List<String>> listMap = record.getListFields();
- for (String key : listMap.keySet()) {
- List<String> list = listMap.get(key);
- if (list.size() > max) {
- listMap.put(key, list.subList(0, max));
- }
- }
- }
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- byte[] serializedBytes = null;
- try {
- JsonFactory f = new JsonFactory();
- JsonGenerator g = f.createJsonGenerator(baos);
-
- g.writeStartObject();
-
- // write id field
- g.writeRaw("\n ");
- g.writeStringField("id", record.getId());
-
- // write simepleFields
- g.writeRaw("\n ");
- g.writeObjectFieldStart("simpleFields");
- for (String key : record.getSimpleFields().keySet()) {
- g.writeRaw("\n ");
- g.writeStringField(key, record.getSimpleField(key));
- }
- g.writeRaw("\n ");
- g.writeEndObject(); // for simpleFields
-
- // write listFields
- g.writeRaw("\n ");
- g.writeObjectFieldStart("listFields");
- for (String key : record.getListFields().keySet()) {
- // g.writeStringField(key, record.getListField(key).toString());
-
- // g.writeObjectFieldStart(key);
- g.writeRaw("\n ");
- g.writeArrayFieldStart(key);
- List<String> list = record.getListField(key);
- for (String listValue : list) {
- g.writeString(listValue);
- }
- // g.writeEndObject();
- g.writeEndArray();
-
- }
- g.writeRaw("\n ");
- g.writeEndObject(); // for listFields
-
- // write mapFields
- g.writeRaw("\n ");
- g.writeObjectFieldStart("mapFields");
- for (String key : record.getMapFields().keySet()) {
- // g.writeStringField(key, record.getMapField(key).toString());
- g.writeRaw("\n ");
- g.writeObjectFieldStart(key);
- Map<String, String> map = record.getMapField(key);
- for (String mapKey : map.keySet()) {
- g.writeRaw("\n ");
- g.writeStringField(mapKey, map.get(mapKey));
- }
- g.writeRaw("\n ");
- g.writeEndObject();
-
- }
- g.writeRaw("\n ");
- g.writeEndObject(); // for mapFields
-
- byte[] rawPayload = record.getRawPayload();
- if (rawPayload != null && rawPayload.length > 0) {
- // write rawPayload
- g.writeRaw("\n ");
- g.writeStringField("rawPayload", new String(Base64.encodeBase64(rawPayload), "UTF-8"));
- }
-
- g.writeRaw("\n");
- g.writeEndObject(); // for whole znrecord
-
- // important: will force flushing of output, close underlying output
- // stream
- g.close();
- serializedBytes = baos.toByteArray();
- // apply compression if needed
- if (record.getBooleanField("enableCompression", false) || serializedBytes.length > ZNRecord.SIZE_LIMIT) {
- serializedBytes = GZipCompressionUtil.compress(serializedBytes);
- }
- } catch (Exception e) {
- LOG.error("Exception during data serialization. Will not write to zk. Data (first 1k): "
- + new String(baos.toByteArray()).substring(0, 1024), e);
- throw new HelixException(e);
- }
- // check size
- if (serializedBytes.length > ZNRecord.SIZE_LIMIT) {
- LOG.error("Data size larger than 1M, ZNRecord.id: " + record.getId()
- + ". Will not write to zk. Data (first 1k): "
- + new String(serializedBytes).substring(0, 1024));
- throw new HelixException("Data size larger than 1M, ZNRecord.id: " + record.getId());
- }
-
- return serializedBytes;
- }
-
- @Override
- public Object deserialize(byte[] bytes) throws ZkMarshallingError {
- if (bytes == null || bytes.length == 0) {
- LOG.error("ZNode is empty.");
- return null;
- }
-
- ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
-
- ZNRecord record = null;
- String id = null;
- Map<String, String> simpleFields = Maps.newHashMap();
- Map<String, List<String>> listFields = Maps.newHashMap();
- Map<String, Map<String, String>> mapFields = Maps.newHashMap();
- byte[] rawPayload = null;
-
- try {
- // decompress the data if its already compressed
- if (GZipCompressionUtil.isCompressed(bytes)) {
- byte[] uncompressedBytes = GZipCompressionUtil.uncompress(bais);
- bais = new ByteArrayInputStream(uncompressedBytes);
- }
- JsonFactory f = new JsonFactory();
- JsonParser jp = f.createJsonParser(bais);
-
- jp.nextToken(); // will return JsonToken.START_OBJECT (verify?)
- while (jp.nextToken() != JsonToken.END_OBJECT) {
- String fieldname = jp.getCurrentName();
- jp.nextToken(); // move to value, or START_OBJECT/START_ARRAY
- if ("id".equals(fieldname)) {
- // contains an object
- id = jp.getText();
- } else if ("simpleFields".equals(fieldname)) {
- while (jp.nextToken() != JsonToken.END_OBJECT) {
- String key = jp.getCurrentName();
- jp.nextToken(); // move to value
- simpleFields.put(key, jp.getText());
- }
- } else if ("mapFields".equals(fieldname)) {
- // user.setVerified(jp.getCurrentToken() == JsonToken.VALUE_TRUE);
- while (jp.nextToken() != JsonToken.END_OBJECT) {
- String key = jp.getCurrentName();
- mapFields.put(key, new TreeMap<String, String>());
- jp.nextToken(); // move to value
-
- while (jp.nextToken() != JsonToken.END_OBJECT) {
- String mapKey = jp.getCurrentName();
- jp.nextToken(); // move to value
- mapFields.get(key).put(mapKey, jp.getText());
- }
- }
-
- } else if ("listFields".equals(fieldname)) {
- // user.setUserImage(jp.getBinaryValue());
- while (jp.nextToken() != JsonToken.END_OBJECT) {
- String key = jp.getCurrentName();
- listFields.put(key, new ArrayList<String>());
- jp.nextToken(); // move to value
- while (jp.nextToken() != JsonToken.END_ARRAY) {
- listFields.get(key).add(jp.getText());
- }
-
- }
-
- } else if ("rawPayload".equals(fieldname)) {
- rawPayload = Base64.decodeBase64(jp.getText());
- } else {
- throw new IllegalStateException("Unrecognized field '" + fieldname + "'!");
- }
- }
- jp.close(); // ensure resources get cleaned up timely and properly
-
- if (id == null) {
- throw new IllegalStateException("ZNRecord id field is required!");
- }
- record = new ZNRecord(id);
- record.setSimpleFields(simpleFields);
- record.setListFields(listFields);
- record.setMapFields(mapFields);
- record.setRawPayload(rawPayload);
- } catch (Exception e) {
- LOG.error("Exception during deserialization of bytes: " + new String(bytes), e);
- }
- return record;
- }
-
- public static void main(String[] args) {
- ZNRecord record = new ZNRecord("record");
- final int recordSize = 10;
- for (int i = 0; i < recordSize; i++) {
- record.setSimpleField("" + i, "" + i);
- record.setListField("" + i, new ArrayList<String>());
- for (int j = 0; j < recordSize; j++) {
- record.getListField("" + i).add("" + j);
- }
-
- record.setMapField("" + i, new TreeMap<String, String>());
- for (int j = 0; j < recordSize; j++) {
- record.getMapField("" + i).put("" + j, "" + j);
- }
- }
-
- ZNRecordStreamingSerializer serializer = new ZNRecordStreamingSerializer();
- byte[] bytes = serializer.serialize(record);
- System.out.println(new String(bytes));
- ZNRecord record2 = (ZNRecord) serializer.deserialize(bytes);
- System.out.println(record2);
-
- long start = System.currentTimeMillis();
- for (int i = 0; i < 100; i++) {
- bytes = serializer.serialize(record);
- // System.out.println(new String(bytes));
- record2 = (ZNRecord) serializer.deserialize(bytes);
- // System.out.println(record2);
- }
- long end = System.currentTimeMillis();
- System.out.println("ZNRecordStreamingSerializer time used: " + (end - start));
-
- ZNRecordSerializer serializer2 = new ZNRecordSerializer();
- bytes = serializer2.serialize(record);
- // System.out.println(new String(bytes));
- record2 = (ZNRecord) serializer2.deserialize(bytes);
- // System.out.println(record2);
-
- start = System.currentTimeMillis();
- for (int i = 0; i < 100; i++) {
- bytes = serializer2.serialize(record);
- // System.out.println(new String(bytes));
- record2 = (ZNRecord) serializer2.deserialize(bytes);
- // System.out.println(record2);
- }
- end = System.currentTimeMillis();
- System.out.println("ZNRecordSerializer time used: " + (end - start));
-
- }
+/**
+ * Use ZNRecordStreamingSerializer in zookeeper-api module instead.
+ */
+@Deprecated
+public class ZNRecordStreamingSerializer extends org.apache.helix.zookeeper.datamodel.serializer.ZNRecordStreamingSerializer {
}
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ZkAsyncCallbacks.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ZkAsyncCallbacks.java
index 6b51b47..566a6e0 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ZkAsyncCallbacks.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ZkAsyncCallbacks.java
@@ -19,174 +19,10 @@
* under the License.
*/
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.apache.helix.monitoring.mbeans.ZkClientMonitor;
-import org.apache.zookeeper.AsyncCallback.DataCallback;
-import org.apache.zookeeper.AsyncCallback.StatCallback;
-import org.apache.zookeeper.AsyncCallback.StringCallback;
-import org.apache.zookeeper.AsyncCallback.VoidCallback;
-import org.apache.zookeeper.KeeperException.Code;
-import org.apache.zookeeper.data.Stat;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ZkAsyncCallbacks {
- private static Logger LOG = LoggerFactory.getLogger(ZkAsyncCallbacks.class);
-
- public static class GetDataCallbackHandler extends DefaultCallback implements DataCallback {
- byte[] _data;
- Stat _stat;
-
- @Override
- public void handle() {
- // TODO Auto-generated method stub
- }
-
- @Override
- public void processResult(int rc, String path, Object ctx, byte[] data, Stat stat) {
- if (rc == 0) {
- _data = data;
- _stat = stat;
- // update ctx with data size
- if (_data != null && ctx != null && ctx instanceof ZkAsyncCallContext) {
- ZkAsyncCallContext zkCtx = (ZkAsyncCallContext) ctx;
- zkCtx._bytes = _data.length;
- }
- }
- callback(rc, path, ctx);
- }
- }
-
- public static class SetDataCallbackHandler extends DefaultCallback implements StatCallback {
- Stat _stat;
-
- @Override
- public void handle() {
- // TODO Auto-generated method stub
- }
-
- @Override
- public void processResult(int rc, String path, Object ctx, Stat stat) {
- if (rc == 0) {
- _stat = stat;
- }
- callback(rc, path, ctx);
- }
-
- public Stat getStat() {
- return _stat;
- }
- }
-
- public static class ExistsCallbackHandler extends DefaultCallback implements StatCallback {
- Stat _stat;
-
- @Override
- public void handle() {
- // TODO Auto-generated method stub
- }
-
- @Override
- public void processResult(int rc, String path, Object ctx, Stat stat) {
- if (rc == 0) {
- _stat = stat;
- }
- callback(rc, path, ctx);
- }
- }
-
- public static class CreateCallbackHandler extends DefaultCallback implements StringCallback {
- @Override
- public void processResult(int rc, String path, Object ctx, String name) {
- callback(rc, path, ctx);
- }
-
- @Override
- public void handle() {
- // TODO Auto-generated method stub
- }
- }
-
- public static class DeleteCallbackHandler extends DefaultCallback implements VoidCallback {
- @Override
- public void processResult(int rc, String path, Object ctx) {
- callback(rc, path, ctx);
- }
-
- @Override
- public void handle() {
- // TODO Auto-generated method stub
- }
- }
-
- /**
- * Default callback for zookeeper async api
- */
- public static abstract class DefaultCallback {
- AtomicBoolean _lock = new AtomicBoolean(false);
- int _rc = -1;
-
- public void callback(int rc, String path, Object ctx) {
- if (rc != 0 && LOG.isDebugEnabled()) {
- LOG.debug(this + ", rc:" + Code.get(rc) + ", path: " + path);
- }
-
- if (ctx != null && ctx instanceof ZkAsyncCallContext) {
- ZkAsyncCallContext zkCtx = (ZkAsyncCallContext) ctx;
- if (zkCtx._monitor != null) {
- if (zkCtx._isRead) {
- zkCtx._monitor.record(path, zkCtx._bytes, zkCtx._startTimeMilliSec,
- ZkClientMonitor.AccessType.READ);
- } else {
- zkCtx._monitor.record(path, zkCtx._bytes, zkCtx._startTimeMilliSec,
- ZkClientMonitor.AccessType.WRITE);
- }
- }
- }
-
- _rc = rc;
- handle();
-
- synchronized (_lock) {
- _lock.set(true);
- _lock.notify();
- }
- }
-
- public boolean waitForSuccess() {
- try {
- synchronized (_lock) {
- while (!_lock.get()) {
- _lock.wait();
- }
- }
- } catch (InterruptedException e) {
- LOG.error("Interrupted waiting for success", e);
- }
- return true;
- }
-
- public int getRc() {
- return _rc;
- }
-
- abstract public void handle();
- }
-
- public static class ZkAsyncCallContext {
- private long _startTimeMilliSec;
- private int _bytes;
- private ZkClientMonitor _monitor;
- private boolean _isRead;
-
- public ZkAsyncCallContext(final ZkClientMonitor monitor, long startTimeMilliSec, int bytes,
- boolean isRead) {
- _monitor = monitor;
- _startTimeMilliSec = startTimeMilliSec;
- _bytes = bytes;
- _isRead = isRead;
- }
- }
-
+/**
+ * This class has been deprecated. Please use ZkAsyncCallbacks in zookeeper-api module instead.
+ */
+@Deprecated
+public class ZkAsyncCallbacks
+ extends org.apache.helix.zookeeper.zkclient.callback.ZkAsyncCallbacks {
}
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ZkBaseDataAccessor.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ZkBaseDataAccessor.java
index c1abccb..bc84a1d 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ZkBaseDataAccessor.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ZkBaseDataAccessor.java
@@ -27,28 +27,25 @@
import java.util.List;
import java.util.Map;
-import org.I0Itec.zkclient.DataUpdater;
-import org.I0Itec.zkclient.IZkChildListener;
-import org.I0Itec.zkclient.IZkDataListener;
-import org.I0Itec.zkclient.exception.ZkBadVersionException;
-import org.I0Itec.zkclient.exception.ZkException;
-import org.I0Itec.zkclient.exception.ZkNoNodeException;
-import org.I0Itec.zkclient.exception.ZkNodeExistsException;
-import org.I0Itec.zkclient.serialize.ZkSerializer;
import org.apache.helix.AccessOption;
import org.apache.helix.BaseDataAccessor;
import org.apache.helix.HelixException;
import org.apache.helix.api.exceptions.HelixMetaDataAccessException;
-import org.apache.helix.manager.zk.ZkAsyncCallbacks.CreateCallbackHandler;
-import org.apache.helix.manager.zk.ZkAsyncCallbacks.DeleteCallbackHandler;
-import org.apache.helix.manager.zk.ZkAsyncCallbacks.ExistsCallbackHandler;
-import org.apache.helix.manager.zk.ZkAsyncCallbacks.GetDataCallbackHandler;
-import org.apache.helix.manager.zk.ZkAsyncCallbacks.SetDataCallbackHandler;
-import org.apache.helix.manager.zk.client.DedicatedZkClientFactory;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.client.SharedZkClientFactory;
import org.apache.helix.store.zk.ZNode;
import org.apache.helix.util.HelixUtil;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.factory.DedicatedZkClientFactory;
+import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
+import org.apache.helix.zookeeper.zkclient.IZkChildListener;
+import org.apache.helix.zookeeper.zkclient.IZkDataListener;
+import org.apache.helix.zookeeper.zkclient.callback.ZkAsyncCallbacks;
+import org.apache.helix.zookeeper.zkclient.exception.ZkBadVersionException;
+import org.apache.helix.zookeeper.zkclient.exception.ZkException;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNoNodeException;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNodeExistsException;
+import org.apache.helix.zookeeper.zkclient.serialize.ZkSerializer;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException.Code;
import org.apache.zookeeper.data.Stat;
@@ -143,7 +140,7 @@
}
/**
- * Creates a ZkBaseDataAccessor with {@link org.apache.helix.ZNRecord} as the data model.
+ * Creates a ZkBaseDataAccessor with {@link ZNRecord} as the data model.
* Uses a shared ZkConnection resource.
* Does NOT support ephemeral node creation, callbacks, or session management.
* Uses {@link ZNRecordSerializer} serializer
@@ -154,7 +151,7 @@
}
/**
- * Creates a ZkBaseDataAccessor with {@link org.apache.helix.ZNRecord} as the data model.
+ * Creates a ZkBaseDataAccessor with {@link ZNRecord} as the data model.
* If DEDICATED, it will use a dedicated ZkConnection, which allows ephemeral
* node creation, callbacks, and session management.
* If SHARED, it will use a shared ZkConnection, which only allows simple
@@ -492,13 +489,13 @@
try {
// issue asyn get requests
- GetDataCallbackHandler[] cbList = new GetDataCallbackHandler[paths.size()];
+ ZkAsyncCallbacks.GetDataCallbackHandler[] cbList = new ZkAsyncCallbacks.GetDataCallbackHandler[paths.size()];
for (int i = 0; i < paths.size(); i++) {
if (!needRead[i])
continue;
String path = paths.get(i);
- cbList[i] = new GetDataCallbackHandler();
+ cbList[i] = new ZkAsyncCallbacks.GetDataCallbackHandler();
_zkClient.asyncGetData(path, cbList[i]);
}
@@ -507,7 +504,7 @@
if (!needRead[i])
continue;
- GetDataCallbackHandler cb = cbList[i];
+ ZkAsyncCallbacks.GetDataCallbackHandler cb = cbList[i];
cb.waitForSuccess();
}
@@ -518,7 +515,7 @@
if (!needRead[i])
continue;
- GetDataCallbackHandler cb = cbList[i];
+ ZkAsyncCallbacks.GetDataCallbackHandler cb = cbList[i];
if (Code.get(cb.getRc()) == Code.OK) {
@SuppressWarnings("unchecked")
T record = (T) _zkClient.deserialize(cb._data, paths.get(i));
@@ -684,7 +681,7 @@
/**
* async create. give up on error other than NONODE
*/
- CreateCallbackHandler[] create(List<String> paths, List<T> records, boolean[] needCreate,
+ ZkAsyncCallbacks.CreateCallbackHandler[] create(List<String> paths, List<T> records, boolean[] needCreate,
List<List<String>> pathsCreated, int options) {
if ((records != null && records.size() != paths.size()) || needCreate.length != paths.size()
|| (pathsCreated != null && pathsCreated.size() != paths.size())) {
@@ -692,7 +689,7 @@
"paths, records, needCreate, and pathsCreated should be of same size");
}
- CreateCallbackHandler[] cbList = new CreateCallbackHandler[paths.size()];
+ ZkAsyncCallbacks.CreateCallbackHandler[] cbList = new ZkAsyncCallbacks.CreateCallbackHandler[paths.size()];
CreateMode mode = AccessOption.getMode(options);
if (mode == null) {
@@ -710,7 +707,7 @@
String path = paths.get(i);
T record = records == null ? null : records.get(i);
- cbList[i] = new CreateCallbackHandler();
+ cbList[i] = new ZkAsyncCallbacks.CreateCallbackHandler();
_zkClient.asyncCreate(path, record, mode, cbList[i]);
}
@@ -721,7 +718,7 @@
if (!needCreate[i])
continue;
- CreateCallbackHandler cb = cbList[i];
+ ZkAsyncCallbacks.CreateCallbackHandler cb = cbList[i];
cb.waitForSuccess();
String path = paths.get(i);
@@ -747,10 +744,10 @@
if (failOnNoNode) {
boolean[] needCreateParent = Arrays.copyOf(needCreate, needCreate.length);
- CreateCallbackHandler[] parentCbList =
+ ZkAsyncCallbacks.CreateCallbackHandler[] parentCbList =
create(parentPaths, null, needCreateParent, pathsCreated, AccessOption.PERSISTENT);
for (int i = 0; i < parentCbList.length; i++) {
- CreateCallbackHandler parentCb = parentCbList[i];
+ ZkAsyncCallbacks.CreateCallbackHandler parentCb = parentCbList[i];
if (parentCb == null)
continue;
@@ -790,10 +787,10 @@
long startT = System.nanoTime();
try {
- CreateCallbackHandler[] cbList = create(paths, records, needCreate, pathsCreated, options);
+ ZkAsyncCallbacks.CreateCallbackHandler[] cbList = create(paths, records, needCreate, pathsCreated, options);
for (int i = 0; i < cbList.length; i++) {
- CreateCallbackHandler cb = cbList[i];
+ ZkAsyncCallbacks.CreateCallbackHandler cb = cbList[i];
success[i] = (Code.get(cb.getRc()) == Code.OK);
}
@@ -840,8 +837,8 @@
}
List<Stat> setStats = new ArrayList<>(Collections.<Stat> nCopies(paths.size(), null));
- SetDataCallbackHandler[] cbList = new SetDataCallbackHandler[paths.size()];
- CreateCallbackHandler[] createCbList = null;
+ ZkAsyncCallbacks.SetDataCallbackHandler[] cbList = new ZkAsyncCallbacks.SetDataCallbackHandler[paths.size()];
+ ZkAsyncCallbacks.CreateCallbackHandler[] createCbList = null;
boolean[] needSet = new boolean[paths.size()];
Arrays.fill(needSet, true);
@@ -858,7 +855,7 @@
String path = paths.get(i);
T record = records.get(i);
- cbList[i] = new SetDataCallbackHandler();
+ cbList[i] = new ZkAsyncCallbacks.SetDataCallbackHandler();
_zkClient.asyncSetData(path, record, -1, cbList[i]);
}
@@ -866,7 +863,7 @@
boolean failOnNoNode = false;
for (int i = 0; i < cbList.length; i++) {
- SetDataCallbackHandler cb = cbList[i];
+ ZkAsyncCallbacks.SetDataCallbackHandler cb = cbList[i];
cb.waitForSuccess();
Code rc = Code.get(cb.getRc());
switch (rc) {
@@ -890,7 +887,7 @@
boolean[] needCreate = Arrays.copyOf(needSet, needSet.length);
createCbList = create(paths, records, needCreate, pathsCreated, options);
for (int i = 0; i < createCbList.length; i++) {
- CreateCallbackHandler createCb = createCbList[i];
+ ZkAsyncCallbacks.CreateCallbackHandler createCb = createCbList[i];
if (createCb == null) {
continue;
}
@@ -916,13 +913,13 @@
// construct return results
for (int i = 0; i < cbList.length; i++) {
- SetDataCallbackHandler cb = cbList[i];
+ ZkAsyncCallbacks.SetDataCallbackHandler cb = cbList[i];
Code rc = Code.get(cb.getRc());
if (rc == Code.OK) {
success[i] = true;
} else if (rc == Code.NONODE) {
- CreateCallbackHandler createCb = createCbList[i];
+ ZkAsyncCallbacks.CreateCallbackHandler createCb = createCbList[i];
if (Code.get(createCb.getRc()) == Code.OK) {
success[i] = true;
}
@@ -986,8 +983,8 @@
return updateData;
}
- SetDataCallbackHandler[] cbList = new SetDataCallbackHandler[paths.size()];
- CreateCallbackHandler[] createCbList = null;
+ ZkAsyncCallbacks.SetDataCallbackHandler[] cbList = new ZkAsyncCallbacks.SetDataCallbackHandler[paths.size()];
+ ZkAsyncCallbacks.CreateCallbackHandler[] createCbList = null;
boolean[] needUpdate = new boolean[paths.size()];
Arrays.fill(needUpdate, true);
@@ -1026,7 +1023,7 @@
failOnNoNode = true;
needCreate[i] = true;
} else {
- cbList[i] = new SetDataCallbackHandler();
+ cbList[i] = new ZkAsyncCallbacks.SetDataCallbackHandler();
_zkClient.asyncSetData(path, newData, curStat.getVersion(), cbList[i]);
}
}
@@ -1035,7 +1032,7 @@
boolean failOnBadVersion = false;
for (int i = 0; i < paths.size(); i++) {
- SetDataCallbackHandler cb = cbList[i];
+ ZkAsyncCallbacks.SetDataCallbackHandler cb = cbList[i];
if (cb == null)
continue;
@@ -1066,7 +1063,7 @@
if (failOnNoNode) {
createCbList = create(paths, newDataList, needCreate, pathsCreated, options);
for (int i = 0; i < paths.size(); i++) {
- CreateCallbackHandler createCb = createCbList[i];
+ ZkAsyncCallbacks.CreateCallbackHandler createCb = createCbList[i];
if (createCb == null) {
continue;
}
@@ -1141,15 +1138,15 @@
long startT = System.nanoTime();
try {
- ExistsCallbackHandler[] cbList = new ExistsCallbackHandler[paths.size()];
+ ZkAsyncCallbacks.ExistsCallbackHandler[] cbList = new ZkAsyncCallbacks.ExistsCallbackHandler[paths.size()];
for (int i = 0; i < paths.size(); i++) {
String path = paths.get(i);
- cbList[i] = new ExistsCallbackHandler();
+ cbList[i] = new ZkAsyncCallbacks.ExistsCallbackHandler();
_zkClient.asyncExists(path, cbList[i]);
}
for (int i = 0; i < cbList.length; i++) {
- ExistsCallbackHandler cb = cbList[i];
+ ZkAsyncCallbacks.ExistsCallbackHandler cb = cbList[i];
cb.waitForSuccess();
stats[i] = cb._stat;
}
@@ -1175,19 +1172,19 @@
boolean[] success = new boolean[paths.size()];
- DeleteCallbackHandler[] cbList = new DeleteCallbackHandler[paths.size()];
+ ZkAsyncCallbacks.DeleteCallbackHandler[] cbList = new ZkAsyncCallbacks.DeleteCallbackHandler[paths.size()];
long startT = System.nanoTime();
try {
for (int i = 0; i < paths.size(); i++) {
String path = paths.get(i);
- cbList[i] = new DeleteCallbackHandler();
+ cbList[i] = new ZkAsyncCallbacks.DeleteCallbackHandler();
_zkClient.asyncDelete(path, cbList[i]);
}
for (int i = 0; i < cbList.length; i++) {
- DeleteCallbackHandler cb = cbList[i];
+ ZkAsyncCallbacks.DeleteCallbackHandler cb = cbList[i];
cb.waitForSuccess();
success[i] = (cb.getRc() == 0);
}
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ZkBucketDataAccessor.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ZkBucketDataAccessor.java
index bc13471..ffed9f3 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ZkBucketDataAccessor.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ZkBucketDataAccessor.java
@@ -30,18 +30,18 @@
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
-import org.I0Itec.zkclient.DataUpdater;
-import org.I0Itec.zkclient.exception.ZkMarshallingError;
-import org.I0Itec.zkclient.exception.ZkNoNodeException;
-import org.I0Itec.zkclient.serialize.ZkSerializer;
import org.apache.helix.AccessOption;
import org.apache.helix.BucketDataAccessor;
import org.apache.helix.HelixException;
import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.manager.zk.client.DedicatedZkClientFactory;
-import org.apache.helix.manager.zk.client.HelixZkClient;
import org.apache.helix.util.GZipCompressionUtil;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.factory.DedicatedZkClientFactory;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
+import org.apache.helix.zookeeper.zkclient.exception.ZkMarshallingError;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNoNodeException;
+import org.apache.helix.zookeeper.zkclient.serialize.ZkSerializer;
import org.codehaus.jackson.map.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ZkCacheBaseDataAccessor.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ZkCacheBaseDataAccessor.java
index b230827..6d2c5cf 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ZkCacheBaseDataAccessor.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ZkCacheBaseDataAccessor.java
@@ -29,22 +29,22 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
-import org.I0Itec.zkclient.DataUpdater;
-import org.I0Itec.zkclient.IZkChildListener;
-import org.I0Itec.zkclient.IZkDataListener;
-import org.I0Itec.zkclient.exception.ZkNoNodeException;
-import org.I0Itec.zkclient.serialize.ZkSerializer;
import org.apache.helix.AccessOption;
import org.apache.helix.HelixException;
-import org.apache.helix.manager.zk.ZkAsyncCallbacks.CreateCallbackHandler;
import org.apache.helix.manager.zk.ZkBaseDataAccessor.RetCode;
-import org.apache.helix.manager.zk.client.DedicatedZkClientFactory;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.client.SharedZkClientFactory;
import org.apache.helix.store.HelixPropertyListener;
import org.apache.helix.store.HelixPropertyStore;
import org.apache.helix.store.zk.ZNode;
import org.apache.helix.util.PathUtils;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.factory.DedicatedZkClientFactory;
+import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
+import org.apache.helix.zookeeper.zkclient.IZkChildListener;
+import org.apache.helix.zookeeper.zkclient.IZkDataListener;
+import org.apache.helix.zookeeper.zkclient.callback.ZkAsyncCallbacks;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNoNodeException;
+import org.apache.helix.zookeeper.zkclient.serialize.ZkSerializer;
import org.apache.zookeeper.KeeperException.Code;
import org.apache.zookeeper.data.Stat;
import org.apache.zookeeper.server.DataTree;
@@ -451,12 +451,12 @@
Arrays.fill(needCreate, true);
List<List<String>> pathsCreatedList =
new ArrayList<List<String>>(Collections.<List<String>>nCopies(size, null));
- CreateCallbackHandler[] createCbList =
+ ZkAsyncCallbacks.CreateCallbackHandler[] createCbList =
_baseAccessor.create(serverPaths, records, needCreate, pathsCreatedList, options);
boolean[] success = new boolean[size];
for (int i = 0; i < size; i++) {
- CreateCallbackHandler cb = createCbList[i];
+ ZkAsyncCallbacks.CreateCallbackHandler cb = createCbList[i];
success[i] = (Code.get(cb.getRc()) == Code.OK);
updateCache(cache, pathsCreatedList.get(i), success[i], serverPaths.get(i),
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ZkCacheEventThread.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ZkCacheEventThread.java
index 9c208d3..5dc1ebb 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ZkCacheEventThread.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ZkCacheEventThread.java
@@ -23,7 +23,7 @@
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
-import org.I0Itec.zkclient.exception.ZkInterruptedException;
+import org.apache.helix.zookeeper.zkclient.exception.ZkInterruptedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ZkCallbackCache.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ZkCallbackCache.java
index 49037eb..4b08d27 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ZkCallbackCache.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ZkCallbackCache.java
@@ -25,9 +25,6 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
-import org.I0Itec.zkclient.IZkChildListener;
-import org.I0Itec.zkclient.IZkDataListener;
-import org.I0Itec.zkclient.exception.ZkNoNodeException;
import org.apache.helix.AccessOption;
import org.apache.helix.BaseDataAccessor;
import org.apache.helix.manager.zk.ZkCacheEventThread.ZkCacheEvent;
@@ -35,6 +32,9 @@
import org.apache.helix.store.HelixPropertyListener;
import org.apache.helix.store.zk.ZNode;
import org.apache.helix.util.HelixUtil;
+import org.apache.helix.zookeeper.zkclient.IZkChildListener;
+import org.apache.helix.zookeeper.zkclient.IZkDataListener;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNoNodeException;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.data.Stat;
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ZkClient.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ZkClient.java
index 55c7048..4e38f26 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ZkClient.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/ZkClient.java
@@ -19,12 +19,14 @@
* under the License.
*/
-import org.I0Itec.zkclient.IZkConnection;
-import org.I0Itec.zkclient.serialize.SerializableSerializer;
-import org.I0Itec.zkclient.serialize.ZkSerializer;
import org.apache.helix.HelixException;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.zookeeper.ZkConnection;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.zkclient.IZkConnection;
+import org.apache.helix.zookeeper.zkclient.ZkConnection;
+import org.apache.helix.zookeeper.zkclient.serialize.BasicZkSerializer;
+import org.apache.helix.zookeeper.zkclient.serialize.PathBasedZkSerializer;
+import org.apache.helix.zookeeper.zkclient.serialize.SerializableSerializer;
+import org.apache.helix.zookeeper.zkclient.serialize.ZkSerializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -189,7 +191,8 @@
return this;
}
- public Builder setZkSerializer(PathBasedZkSerializer zkSerializer) {
+ public Builder setZkSerializer(
+ PathBasedZkSerializer zkSerializer) {
this._zkSerializer = zkSerializer;
return this;
}
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/ZkSessionMismatchedException.java b/helix-core/src/main/java/org/apache/helix/manager/zk/ZkSessionMismatchedException.java
deleted file mode 100644
index e336bb6..0000000
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/ZkSessionMismatchedException.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package org.apache.helix.manager.zk;
-
-import org.I0Itec.zkclient.exception.ZkException;
-import org.apache.zookeeper.KeeperException;
-
-
-/**
- * Exception thrown when an action is taken by an expected zk session which
- * does not match the actual zk session.
- */
-public class ZkSessionMismatchedException extends ZkException {
-
- private static final long serialVersionUID = 1L;
-
- public ZkSessionMismatchedException(String message) {
- super(message);
- }
-}
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/client/DedicatedZkClientFactory.java b/helix-core/src/main/java/org/apache/helix/manager/zk/client/DedicatedZkClientFactory.java
index edeb978..c82c1fc 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/client/DedicatedZkClientFactory.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/client/DedicatedZkClientFactory.java
@@ -1,35 +1,29 @@
package org.apache.helix.manager.zk.client;
-import org.apache.helix.manager.zk.ZkClient;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
/**
+ * Deprecated; please use DedicatedZkClientFactory in zookeeper-api instead.
+ *
* Singleton factory that build dedicated clients using the raw ZkClient.
*/
-public class DedicatedZkClientFactory extends HelixZkClientFactory {
-
- protected DedicatedZkClientFactory() {}
-
- private static class SingletonHelper{
- private static final DedicatedZkClientFactory INSTANCE = new DedicatedZkClientFactory();
- }
-
- public static DedicatedZkClientFactory getInstance(){
- return SingletonHelper.INSTANCE;
- }
-
- /**
- * Build a Dedicated ZkClient based on connection config and client config
- *
- * @param connectionConfig
- * @param clientConfig
- * @return
- */
- @Override
- public HelixZkClient buildZkClient(HelixZkClient.ZkConnectionConfig connectionConfig,
- HelixZkClient.ZkClientConfig clientConfig) {
- return new ZkClient(createZkConnection(connectionConfig),
- (int) clientConfig.getConnectInitTimeout(), clientConfig.getOperationRetryTimeout(),
- clientConfig.getZkSerializer(), clientConfig.getMonitorType(), clientConfig.getMonitorKey(),
- clientConfig.getMonitorInstanceName(), clientConfig.isMonitorRootPathOnly());
- }
+@Deprecated
+public class DedicatedZkClientFactory extends org.apache.helix.zookeeper.impl.factory.DedicatedZkClientFactory {
}
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/client/HelixZkClient.java b/helix-core/src/main/java/org/apache/helix/manager/zk/client/HelixZkClient.java
index 5f58b69..a2aa114 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/client/HelixZkClient.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/client/HelixZkClient.java
@@ -1,442 +1,9 @@
package org.apache.helix.manager.zk.client;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-import org.I0Itec.zkclient.DataUpdater;
-import org.I0Itec.zkclient.IZkChildListener;
-import org.I0Itec.zkclient.IZkDataListener;
-import org.I0Itec.zkclient.exception.ZkTimeoutException;
-import org.I0Itec.zkclient.serialize.SerializableSerializer;
-import org.I0Itec.zkclient.serialize.ZkSerializer;
-import org.apache.helix.manager.zk.BasicZkSerializer;
-import org.apache.helix.manager.zk.PathBasedZkSerializer;
-import org.apache.helix.manager.zk.ZkAsyncCallbacks;
-import org.apache.helix.manager.zk.zookeeper.IZkStateListener;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.Op;
-import org.apache.zookeeper.OpResult;
-import org.apache.zookeeper.Watcher.Event.KeeperState;
-import org.apache.zookeeper.data.ACL;
-import org.apache.zookeeper.data.Stat;
-
/**
- * Helix ZkClient interface.
+ * NOTE: this interface has been deprecated. Please use HelixZkClient or RealmAwareZkClient in zookeeper-api instead.
+ * HelixZkClient interface.
*/
-public interface HelixZkClient {
- int DEFAULT_OPERATION_TIMEOUT = Integer.MAX_VALUE;
- int DEFAULT_CONNECTION_TIMEOUT = 60 * 1000;
- int DEFAULT_SESSION_TIMEOUT = 30 * 1000;
-
- // listener subscription
- List<String> subscribeChildChanges(String path, IZkChildListener listener);
-
- void unsubscribeChildChanges(String path, IZkChildListener listener);
-
- void subscribeDataChanges(String path, IZkDataListener listener);
-
- void unsubscribeDataChanges(String path, IZkDataListener listener);
-
- /*
- * This is for backwards compatibility.
- *
- * TODO: remove below default implementation when getting rid of I0Itec in the new zk client.
- */
- default void subscribeStateChanges(final IZkStateListener listener) {
- subscribeStateChanges(new I0ItecIZkStateListenerHelixImpl(listener));
- }
-
- /*
- * This is for backwards compatibility.
- *
- * TODO: remove below default implementation when getting rid of I0Itec in the new zk client.
- */
- default void unsubscribeStateChanges(IZkStateListener listener) {
- unsubscribeStateChanges(new I0ItecIZkStateListenerHelixImpl(listener));
- }
-
- /**
- * Subscribes state changes for a {@link org.I0Itec.zkclient.IZkStateListener} listener.
- *
- * @deprecated
- * This is deprecated. It is kept for backwards compatibility. Please use
- * {@link #subscribeStateChanges(org.apache.helix.manager.zk.zookeeper.IZkStateListener)}.
- *
- * @param listener {@link org.I0Itec.zkclient.IZkStateListener} listener
- */
- @Deprecated
- void subscribeStateChanges(final org.I0Itec.zkclient.IZkStateListener listener);
-
- /**
- * Unsubscribes state changes for a {@link org.I0Itec.zkclient.IZkStateListener} listener.
- *
- * @deprecated
- * This is deprecated. It is kept for backwards compatibility. Please use
- * {@link #unsubscribeStateChanges(org.apache.helix.manager.zk.zookeeper.IZkStateListener)}.
- *
- * @param listener {@link org.I0Itec.zkclient.IZkStateListener} listener
- */
- @Deprecated
- void unsubscribeStateChanges(org.I0Itec.zkclient.IZkStateListener listener);
-
- void unsubscribeAll();
-
- // data access
- void createPersistent(String path);
-
- void createPersistent(String path, boolean createParents);
-
- void createPersistent(String path, boolean createParents, List<ACL> acl);
-
- void createPersistent(String path, Object data);
-
- void createPersistent(String path, Object data, List<ACL> acl);
-
- String createPersistentSequential(String path, Object data);
-
- String createPersistentSequential(String path, Object data, List<ACL> acl);
-
- void createEphemeral(final String path);
-
- void createEphemeral(final String path, final String sessionId);
-
- void createEphemeral(final String path, final List<ACL> acl);
-
- void createEphemeral(final String path, final List<ACL> acl, final String sessionId);
-
- String create(final String path, Object data, final CreateMode mode);
-
- String create(final String path, Object datat, final List<ACL> acl, final CreateMode mode);
-
- void createEphemeral(final String path, final Object data);
-
- void createEphemeral(final String path, final Object data, final String sessionId);
-
- void createEphemeral(final String path, final Object data, final List<ACL> acl);
-
- void createEphemeral(final String path, final Object data, final List<ACL> acl,
- final String sessionId);
-
- String createEphemeralSequential(final String path, final Object data);
-
- String createEphemeralSequential(final String path, final Object data, final List<ACL> acl);
-
- String createEphemeralSequential(final String path, final Object data, final String sessionId);
-
- String createEphemeralSequential(final String path, final Object data, final List<ACL> acl,
- final String sessionId);
-
- List<String> getChildren(String path);
-
- int countChildren(String path);
-
- boolean exists(final String path);
-
- Stat getStat(final String path);
-
- boolean waitUntilExists(String path, TimeUnit timeUnit, long time);
-
- void deleteRecursively(String path);
-
- boolean delete(final String path);
-
- <T extends Object> T readData(String path);
-
- <T extends Object> T readData(String path, boolean returnNullIfPathNotExists);
-
- <T extends Object> T readData(String path, Stat stat);
-
- <T extends Object> T readData(final String path, final Stat stat, final boolean watch);
-
- <T extends Object> T readDataAndStat(String path, Stat stat, boolean returnNullIfPathNotExists);
-
- void writeData(String path, Object object);
-
- <T extends Object> void updateDataSerialized(String path, DataUpdater<T> updater);
-
- void writeData(final String path, Object datat, final int expectedVersion);
-
- Stat writeDataReturnStat(final String path, Object datat, final int expectedVersion);
-
- Stat writeDataGetStat(final String path, Object datat, final int expectedVersion);
-
- void asyncCreate(final String path, Object datat, final CreateMode mode,
- final ZkAsyncCallbacks.CreateCallbackHandler cb);
-
- void asyncSetData(final String path, Object datat, final int version,
- final ZkAsyncCallbacks.SetDataCallbackHandler cb);
-
- void asyncGetData(final String path, final ZkAsyncCallbacks.GetDataCallbackHandler cb);
-
- void asyncExists(final String path, final ZkAsyncCallbacks.ExistsCallbackHandler cb);
-
- void asyncDelete(final String path, final ZkAsyncCallbacks.DeleteCallbackHandler cb);
-
- void watchForData(final String path);
-
- List<String> watchForChilds(final String path);
-
- long getCreationTime(String path);
-
- List<OpResult> multi(final Iterable<Op> ops);
-
- // ZK state control
- boolean waitUntilConnected(long time, TimeUnit timeUnit);
-
- /**
- * Waits for SyncConnected state and returns a valid session ID(non-zero). The implementation of
- * this method should wait for SyncConnected state and ZK session to be established, and should
- * guarantee the established session's ID is returned before keeper state changes.
- *
- * Please note: this default implementation may have race condition issue and return an unexpected
- * session ID that is zero or another new session's ID. The default implementation is for backward
- * compatibility purpose.
- *
- * @param timeout Max waiting time for connecting to ZK server.
- * @param timeUnit Time unit for the timeout.
- * @return A valid ZK session ID which is non-zero.
- */
- default long waitForEstablishedSession(long timeout, TimeUnit timeUnit) {
- if (!waitUntilConnected(timeout, timeUnit)) {
- throw new ZkTimeoutException(
- "Failed to get established session because connecting to ZK server has timed out in "
- + timeout + " " + timeUnit);
- }
- return getSessionId();
- }
-
- String getServers();
-
- long getSessionId();
-
- void close();
-
- boolean isClosed();
-
- // other
- byte[] serialize(Object data, String path);
-
- <T extends Object> T deserialize(byte[] data, String path);
-
- void setZkSerializer(ZkSerializer zkSerializer);
-
- void setZkSerializer(PathBasedZkSerializer zkSerializer);
-
- PathBasedZkSerializer getZkSerializer();
-
- /**
- * A class that wraps a default implementation of
- * {@link org.apache.helix.manager.zk.zookeeper.IZkStateListener}, which means this listener
- * runs the methods of {@link org.apache.helix.manager.zk.zookeeper.IZkStateListener}.
- * This is for backward compatibility and to avoid breaking the original implementation of
- * {@link org.I0Itec.zkclient.IZkStateListener}.
- */
- class I0ItecIZkStateListenerHelixImpl implements org.I0Itec.zkclient.IZkStateListener {
- private IZkStateListener _listener;
-
- I0ItecIZkStateListenerHelixImpl(IZkStateListener listener) {
- _listener = listener;
- }
-
- @Override
- public void handleStateChanged(KeeperState keeperState) throws Exception {
- _listener.handleStateChanged(keeperState);
- }
-
- @Override
- public void handleNewSession() throws Exception {
- /*
- * org.apache.helix.manager.zk.zookeeper.IZkStateListener does not have handleNewSession(),
- * so null is passed into handleNewSession(sessionId).
- */
- _listener.handleNewSession(null);
- }
-
- @Override
- public void handleSessionEstablishmentError(Throwable error) throws Exception {
- _listener.handleSessionEstablishmentError(error);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == this) {
- return true;
- }
- if (!(obj instanceof I0ItecIZkStateListenerHelixImpl)) {
- return false;
- }
- if (_listener == null) {
- return false;
- }
-
- I0ItecIZkStateListenerHelixImpl defaultListener = (I0ItecIZkStateListenerHelixImpl) obj;
-
- return _listener.equals(defaultListener._listener);
- }
-
- @Override
- public int hashCode() {
- /*
- * The original listener's hashcode helps find the wrapped listener with the same original
- * listener. This is helpful in unsubscribeStateChanges(listener).
- */
- return _listener.hashCode();
- }
- }
-
- /**
- * Configuration for creating a new ZkConnection.
- */
- class ZkConnectionConfig {
- // Connection configs
- private final String _zkServers;
- private int _sessionTimeout = HelixZkClient.DEFAULT_SESSION_TIMEOUT;
-
- public ZkConnectionConfig(String zkServers) {
- _zkServers = zkServers;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == this) {
- return true;
- }
- if (!(obj instanceof ZkConnectionConfig)) {
- return false;
- }
- ZkConnectionConfig configObj = (ZkConnectionConfig) obj;
- return (_zkServers == null && configObj._zkServers == null ||
- _zkServers != null && _zkServers.equals(configObj._zkServers)) &&
- _sessionTimeout == configObj._sessionTimeout;
- }
-
- @Override
- public int hashCode() {
- return _sessionTimeout * 31 + _zkServers.hashCode();
- }
-
- @Override
- public String toString() {
- return (_zkServers + "_" + _sessionTimeout).replaceAll("[\\W]", "_");
- }
-
- public ZkConnectionConfig setSessionTimeout(Integer sessionTimeout) {
- this._sessionTimeout = sessionTimeout;
- return this;
- }
-
- public String getZkServers() {
- return _zkServers;
- }
-
- public int getSessionTimeout() {
- return _sessionTimeout;
- }
- }
-
- /**
- * Configuration for creating a new ZkClient with serializer and monitor.
- */
- class ZkClientConfig {
- // For client to init the connection
- private long _connectInitTimeout = HelixZkClient.DEFAULT_CONNECTION_TIMEOUT;
-
- // Data access configs
- private long _operationRetryTimeout = HelixZkClient.DEFAULT_OPERATION_TIMEOUT;
-
- // Others
- private PathBasedZkSerializer _zkSerializer;
-
- // Monitoring
- private String _monitorType;
- private String _monitorKey;
- private String _monitorInstanceName = null;
- private boolean _monitorRootPathOnly = true;
-
- public ZkClientConfig setZkSerializer(PathBasedZkSerializer zkSerializer) {
- this._zkSerializer = zkSerializer;
- return this;
- }
-
- public ZkClientConfig setZkSerializer(ZkSerializer zkSerializer) {
- this._zkSerializer = new BasicZkSerializer(zkSerializer);
- return this;
- }
-
- /**
- * Used as part of the MBean ObjectName. This item is required for enabling monitoring.
- *
- * @param monitorType
- */
- public ZkClientConfig setMonitorType(String monitorType) {
- this._monitorType = monitorType;
- return this;
- }
-
- /**
- * Used as part of the MBean ObjectName. This item is required for enabling monitoring.
- *
- * @param monitorKey
- */
- public ZkClientConfig setMonitorKey(String monitorKey) {
- this._monitorKey = monitorKey;
- return this;
- }
-
- /**
- * Used as part of the MBean ObjectName. This item is optional.
- *
- * @param instanceName
- */
- public ZkClientConfig setMonitorInstanceName(String instanceName) {
- this._monitorInstanceName = instanceName;
- return this;
- }
-
- public ZkClientConfig setMonitorRootPathOnly(Boolean monitorRootPathOnly) {
- this._monitorRootPathOnly = monitorRootPathOnly;
- return this;
- }
-
- public ZkClientConfig setOperationRetryTimeout(Long operationRetryTimeout) {
- this._operationRetryTimeout = operationRetryTimeout;
- return this;
- }
-
- public ZkClientConfig setConnectInitTimeout(long _connectInitTimeout) {
- this._connectInitTimeout = _connectInitTimeout;
- return this;
- }
-
- public PathBasedZkSerializer getZkSerializer() {
- if (_zkSerializer == null) {
- _zkSerializer = new BasicZkSerializer(new SerializableSerializer());
- }
- return _zkSerializer;
- }
-
- public long getOperationRetryTimeout() {
- return _operationRetryTimeout;
- }
-
- public String getMonitorType() {
- return _monitorType;
- }
-
- public String getMonitorKey() {
- return _monitorKey;
- }
-
- public String getMonitorInstanceName() {
- return _monitorInstanceName;
- }
-
- public boolean isMonitorRootPathOnly() {
- return _monitorRootPathOnly;
- }
-
- public long getConnectInitTimeout() {
- return _connectInitTimeout;
- }
- }
+@Deprecated
+public interface HelixZkClient extends org.apache.helix.zookeeper.api.client.HelixZkClient {
}
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/client/HelixZkClientFactory.java b/helix-core/src/main/java/org/apache/helix/manager/zk/client/HelixZkClientFactory.java
deleted file mode 100644
index e6dc90e..0000000
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/client/HelixZkClientFactory.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package org.apache.helix.manager.zk.client;
-
-import org.I0Itec.zkclient.IZkConnection;
-import org.apache.helix.HelixException;
-import org.apache.helix.manager.zk.zookeeper.ZkConnection;
-
-/**
- * Abstract class of the ZkClient factory.
- */
-abstract class HelixZkClientFactory {
-
- /**
- * Build a ZkClient using specified connection config and client config
- *
- * @param connectionConfig
- * @param clientConfig
- * @return HelixZkClient
- */
- public abstract HelixZkClient buildZkClient(HelixZkClient.ZkConnectionConfig connectionConfig,
- HelixZkClient.ZkClientConfig clientConfig);
-
- /**
- * Build a ZkClient using specified connection config and default client config
- *
- * @param connectionConfig
- * @return HelixZkClient
- */
- public HelixZkClient buildZkClient(HelixZkClient.ZkConnectionConfig connectionConfig) {
- return buildZkClient(connectionConfig, new HelixZkClient.ZkClientConfig());
- }
-
- /**
- * Construct a new ZkConnection instance based on connection configuration.
- * Note that the connection is not really made until someone calls zkConnection.connect().
- * @param connectionConfig
- * @return
- */
- protected IZkConnection createZkConnection(HelixZkClient.ZkConnectionConfig connectionConfig) {
- if (connectionConfig.getZkServers() == null) {
- throw new HelixException(
- "Failed to build ZkClient since no connection or ZK server address is specified.");
- } else {
- return new ZkConnection(connectionConfig.getZkServers(), connectionConfig.getSessionTimeout());
- }
- }
-}
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/client/SharedZkClient.java b/helix-core/src/main/java/org/apache/helix/manager/zk/client/SharedZkClient.java
index 5c6ade0..52a2c17 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/client/SharedZkClient.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/client/SharedZkClient.java
@@ -1,92 +1,37 @@
package org.apache.helix.manager.zk.client;
-import java.util.List;
-
-import org.I0Itec.zkclient.IZkConnection;
-import org.apache.helix.HelixException;
-import org.apache.helix.manager.zk.zookeeper.ZkConnection;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.data.ACL;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
/**
- * ZkClient that uses shared ZkConnection.
- * A SharedZkClient won't manipulate the shared ZkConnection directly.
+ * Deprecated; use SharedZkClient in zookeeper-api instead.
*/
-class SharedZkClient extends org.apache.helix.manager.zk.ZkClient implements HelixZkClient {
- private static Logger LOG = LoggerFactory.getLogger(SharedZkClient.class);
- /*
- * Since we cannot really disconnect the ZkConnection, we need a dummy ZkConnection placeholder.
- * This is to ensure connection field is never null even the shared ZkClient instance is closed so as to avoid NPE.
- */
- private final static ZkConnection IDLE_CONNECTION = new ZkConnection("Dummy_ZkServers");
- private final OnCloseCallback _onCloseCallback;
- private final ZkConnectionManager _connectionManager;
-
- interface OnCloseCallback {
- /**
- * Triggered after the ZkClient is closed.
- */
- void onClose();
- }
-
+@Deprecated
+class SharedZkClient extends org.apache.helix.zookeeper.impl.client.SharedZkClient {
/**
- * Construct a shared ZkClient that uses a shared ZkConnection.
- *
- * @param connectionManager The manager of the shared ZkConnection.
- * @param clientConfig ZkClientConfig details to create the shared ZkClient.
- * @param callback Clean up logic when the shared ZkClient is closed.
+ * Construct a shared RealmAwareZkClient that uses a shared ZkConnection.
+ * @param connectionManager The manager of the shared ZkConnection.
+ * @param clientConfig ZkClientConfig details to create the shared RealmAwareZkClient.
+ * @param callback Clean up logic when the shared RealmAwareZkClient is closed.
*/
protected SharedZkClient(ZkConnectionManager connectionManager, ZkClientConfig clientConfig,
- OnCloseCallback callback) {
- super(connectionManager.getConnection(), 0, clientConfig.getOperationRetryTimeout(),
- clientConfig.getZkSerializer(), clientConfig.getMonitorType(), clientConfig.getMonitorKey(),
- clientConfig.getMonitorInstanceName(), clientConfig.isMonitorRootPathOnly());
- _connectionManager = connectionManager;
- // Register to the base dedicated ZkClient
- _connectionManager.registerWatcher(this);
- _onCloseCallback = callback;
- }
-
- @Override
- public void close() {
- super.close();
- if (isClosed()) {
- // Note that if register is not done while constructing, these private fields may not be init yet.
- if (_connectionManager != null) {
- _connectionManager.unregisterWatcher(this);
- }
- if (_onCloseCallback != null) {
- _onCloseCallback.onClose();
- }
- }
- }
-
- @Override
- public IZkConnection getConnection() {
- if (isClosed()) {
- return IDLE_CONNECTION;
- }
- return super.getConnection();
- }
-
- /**
- * Since ZkConnection session is shared in this ZkClient, do not create ephemeral node using a SharedZKClient.
- */
- @Override
- public String create(final String path, Object datat, final List<ACL> acl,
- final CreateMode mode) {
- if (mode.isEphemeral()) {
- throw new HelixException(
- "Create ephemeral nodes using a " + SharedZkClient.class.getSimpleName()
- + " ZkClient is not supported.");
- }
- return super.create(path, datat, acl, mode);
- }
-
- @Override
- protected boolean isManagingZkConnection() {
- return false;
+ org.apache.helix.zookeeper.impl.client.SharedZkClient.OnCloseCallback callback) {
+ super(connectionManager, clientConfig, callback);
}
}
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/client/SharedZkClientFactory.java b/helix-core/src/main/java/org/apache/helix/manager/zk/client/SharedZkClientFactory.java
index ed4b5de..0a00336 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/client/SharedZkClientFactory.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/client/SharedZkClientFactory.java
@@ -1,87 +1,29 @@
package org.apache.helix.manager.zk.client;
-import java.util.HashMap;
-
-import org.apache.helix.HelixException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
/**
+ * Deprecated: Please use SharedZkClientFactory in zookeeper-api module instead.
+ *
* Singleton factory that build shared ZkClient which use a shared ZkConnection.
*/
-public class SharedZkClientFactory extends HelixZkClientFactory {
- private static Logger LOG = LoggerFactory.getLogger(SharedZkClient.class);
- // The connection pool to track all created connections.
- private final HashMap<HelixZkClient.ZkConnectionConfig, ZkConnectionManager>
- _connectionManagerPool = new HashMap<>();
-
- protected SharedZkClientFactory() {}
-
- private static class SingletonHelper {
- private static final SharedZkClientFactory INSTANCE = new SharedZkClientFactory();
- }
-
- public static SharedZkClientFactory getInstance() {
- return SingletonHelper.INSTANCE;
- }
-
- /**
- * Build a Shared ZkClient that uses sharing ZkConnection that is created based on the specified connection config.
- *
- * @param connectionConfig The connection configuration that is used to search for a shared connection. Or create new connection if necessary.
- * @param clientConfig
- * @return Shared ZkClient
- */
- @Override
- public HelixZkClient buildZkClient(HelixZkClient.ZkConnectionConfig connectionConfig,
- HelixZkClient.ZkClientConfig clientConfig) {
- synchronized (_connectionManagerPool) {
- final ZkConnectionManager zkConnectionManager =
- getOrCreateZkConnectionNamanger(connectionConfig, clientConfig.getConnectInitTimeout());
- if (zkConnectionManager == null) {
- throw new HelixException("Failed to create a connection manager in the pool to share.");
- }
- LOG.info("Sharing ZkConnection {} to a new SharedZkClient.", connectionConfig.toString());
- return new SharedZkClient(zkConnectionManager, clientConfig,
- new SharedZkClient.OnCloseCallback() {
- @Override
- public void onClose() {
- cleanupConnectionManager(zkConnectionManager);
- }
- });
- }
- }
-
- private ZkConnectionManager getOrCreateZkConnectionNamanger(
- HelixZkClient.ZkConnectionConfig connectionConfig, long connectInitTimeout) {
- ZkConnectionManager connectionManager = _connectionManagerPool.get(connectionConfig);
- if (connectionManager == null || connectionManager.isClosed()) {
- connectionManager = new ZkConnectionManager(createZkConnection(connectionConfig), connectInitTimeout,
- connectionConfig.toString());
- _connectionManagerPool.put(connectionConfig, connectionManager);
- }
- return connectionManager;
- }
-
- // Close the ZkConnectionManager if no other shared client is referring to it.
- // Note the close operation of connection manager needs to be synchronized with the pool operation
- // to avoid race condition.
- private void cleanupConnectionManager(ZkConnectionManager zkConnectionManager) {
- synchronized (_connectionManagerPool) {
- zkConnectionManager.close(true);
- }
- }
-
- // For test only
- protected int getActiveConnectionCount() {
- int count = 0;
- synchronized (_connectionManagerPool) {
- for (ZkConnectionManager manager : _connectionManagerPool.values()) {
- if (!manager.isClosed()) {
- count++;
- }
- }
- }
- return count;
- }
+@Deprecated
+public class SharedZkClientFactory extends org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory {
}
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/client/ZkConnectionManager.java b/helix-core/src/main/java/org/apache/helix/manager/zk/client/ZkConnectionManager.java
index 0a9ddc1..c3ccfaa 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/client/ZkConnectionManager.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/client/ZkConnectionManager.java
@@ -1,113 +1,53 @@
package org.apache.helix.manager.zk.client;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
import java.util.HashSet;
import java.util.Set;
-import org.I0Itec.zkclient.IZkConnection;
-import org.I0Itec.zkclient.serialize.SerializableSerializer;
-import org.apache.helix.HelixException;
-import org.apache.helix.manager.zk.BasicZkSerializer;
-import org.apache.zookeeper.WatchedEvent;
+import org.apache.helix.zookeeper.zkclient.IZkConnection;
import org.apache.zookeeper.Watcher;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+
/**
- * A ZkConnection manager that maintain connection status and allows additional watchers to be registered.
- * It will forward events to those watchers.
- *
- * TODO Separate connection management logic from the raw ZkClient class.
- * So this manager is a peer to the ZkClient. Connection Manager for maintaining the connection and
- * ZkClient to handle user request.
- * After this is done, Dedicated ZkClient hires one manager for it's connection.
- * While multiple Shared ZkClients can use single connection manager if possible.
+ * Deprecated - use ZkConnectionManager in zookeeper-api instead.
*/
-class ZkConnectionManager extends org.apache.helix.manager.zk.ZkClient {
- private static Logger LOG = LoggerFactory.getLogger(ZkConnectionManager.class);
- // Client type that is used in monitor, and metrics.
- private final static String MONITOR_TYPE = "ZkConnectionManager";
- private final String _monitorKey;
- // Set of all registered watchers
- private final Set<Watcher> _sharedWatchers = new HashSet<>();
-
+@Deprecated
+class ZkConnectionManager extends org.apache.helix.zookeeper.impl.factory.ZkConnectionManager {
/**
* Construct and init a ZkConnection Manager.
- *
- * @param zkConnection
+ * @param zkConnection
* @param connectionTimeout
+ * @param monitorKey
*/
protected ZkConnectionManager(IZkConnection zkConnection, long connectionTimeout,
String monitorKey) {
- super(zkConnection, (int) connectionTimeout, HelixZkClient.DEFAULT_OPERATION_TIMEOUT,
- new BasicZkSerializer(new SerializableSerializer()), MONITOR_TYPE, monitorKey, null, true);
- _monitorKey = monitorKey;
- LOG.info("ZkConnection {} was created for sharing.", _monitorKey);
+ super(zkConnection, connectionTimeout, monitorKey);
}
/**
- * Register event watcher.
- *
- * @param watcher
- * @return true if the watcher is newly added. false if it is already in record.
+ * Need to override because of the "instanceof" usage doesn't cover subclasses.
*/
- protected synchronized boolean registerWatcher(Watcher watcher) {
- if (isClosed()) {
- throw new HelixException("Cannot add watcher to a closed client.");
- }
- return _sharedWatchers.add(watcher);
- }
-
- /**
- * Unregister the event watcher.
- *
- * @param watcher
- * @return number of the remaining event watchers
- */
- protected synchronized int unregisterWatcher(Watcher watcher) {
- _sharedWatchers.remove(watcher);
- return _sharedWatchers.size();
- }
-
@Override
- public void process(final WatchedEvent event) {
- super.process(event);
- forwardingEvent(event);
- }
-
- private synchronized void forwardingEvent(final WatchedEvent event) {
- // note that process (then forwardingEvent) could be triggered during construction, when sharedWatchers is still null.
- if (_sharedWatchers == null || _sharedWatchers.isEmpty()) {
- return;
- }
- // forward event to all the watchers' event queue
- for (final Watcher watcher : _sharedWatchers) {
- watcher.process(event);
- }
- }
-
- @Override
- public void close() {
- // Enforce closing, if any watcher exists, throw Exception.
- close(false);
- }
-
- protected synchronized void close(boolean skipIfWatched) {
- cleanupInactiveWatchers();
- if (_sharedWatchers.size() > 0) {
- if (skipIfWatched) {
- LOG.debug("Skip closing ZkConnection due to existing watchers. Watcher count {}.",
- _sharedWatchers.size());
- return;
- } else {
- throw new HelixException(
- "Cannot close the connection when there are still shared watchers listen on the event.");
- }
- }
- super.close();
- LOG.info("ZkConnection {} was closed.", _monitorKey);
- }
-
- private void cleanupInactiveWatchers() {
+ protected void cleanupInactiveWatchers() {
+ super.cleanupInactiveWatchers();
Set<Watcher> closedWatchers = new HashSet<>();
for (Watcher watcher : _sharedWatchers) {
// TODO ideally, we shall have a ClosableWatcher interface so as to check accordingly. -- JJ
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/zookeeper/IZkStateListener.java b/helix-core/src/main/java/org/apache/helix/manager/zk/zookeeper/IZkStateListener.java
index aa1fdd6..32e203d 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/zookeeper/IZkStateListener.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/zookeeper/IZkStateListener.java
@@ -19,43 +19,10 @@
* under the License.
*/
-import org.apache.zookeeper.Watcher.Event.KeeperState;
+/**
+ * Use IZkStateListener in zookeeper-api module instead.
+ */
+@Deprecated
+public interface IZkStateListener extends org.apache.helix.zookeeper.zkclient.IZkStateListener {
-
-public interface IZkStateListener {
-
- /**
- * Called when the zookeeper connection state has changed.
- *
- * @param state the new zookeeper state.
- * @throws Exception if any error occurs.
- */
- void handleStateChanged(KeeperState state) throws Exception;
-
- /**
- * Called after the zookeeper session has expired and a new session has been created. The new
- * session id has to be passed in as the parameter.
- * And you would have to re-create any ephemeral nodes here. This is a session aware operation.
- * The ephemeral nodes have to be created within the expected session id, which means passed-in
- * session id has to be checked with current zookeeper's session id. If the passed-in session id
- * does not match current zookeeper's session id, ephemeral nodes should not be created.
- * Otherwise, session race condition may occur and the newly created ephemeral nodes may not be in
- * the expected session.
- *
- * @param sessionId the new session's id. The ephemeral nodes are expected to be created in this
- * session. If this session id is expired, ephemeral nodes should not be created.
- * @throws Exception if any error occurs.
- */
- void handleNewSession(final String sessionId) throws Exception;
-
- /**
- * Called when a session cannot be re-established. This should be used to implement connection
- * failure handling e.g. retry to connect or pass the error up
- *
- * @param error
- * The error that prevents a session from being established
- * @throws Exception
- * On any error.
- */
- void handleSessionEstablishmentError(final Throwable error) throws Exception;
}
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/zookeeper/ZkClient.java b/helix-core/src/main/java/org/apache/helix/manager/zk/zookeeper/ZkClient.java
index 453c8c3..39e80ba 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/zookeeper/ZkClient.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/zookeeper/ZkClient.java
@@ -10,2154 +10,19 @@
*/
package org.apache.helix.manager.zk.zookeeper;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.OptionalLong;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CopyOnWriteArraySet;
-import java.util.concurrent.TimeUnit;
-import javax.management.JMException;
-
-import org.I0Itec.zkclient.DataUpdater;
-import org.I0Itec.zkclient.ExceptionUtil;
-import org.I0Itec.zkclient.IZkChildListener;
-import org.I0Itec.zkclient.IZkConnection;
-import org.I0Itec.zkclient.IZkDataListener;
-import org.I0Itec.zkclient.ZkLock;
-import org.I0Itec.zkclient.exception.ZkBadVersionException;
-import org.I0Itec.zkclient.exception.ZkException;
-import org.I0Itec.zkclient.exception.ZkInterruptedException;
-import org.I0Itec.zkclient.exception.ZkNoNodeException;
-import org.I0Itec.zkclient.exception.ZkNodeExistsException;
-import org.I0Itec.zkclient.exception.ZkTimeoutException;
-import org.I0Itec.zkclient.serialize.ZkSerializer;
-import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.api.listeners.PreFetch;
-import org.apache.helix.manager.zk.BasicZkSerializer;
-import org.apache.helix.manager.zk.PathBasedZkSerializer;
-import org.apache.helix.manager.zk.ZKUtil;
-import org.apache.helix.manager.zk.ZkAsyncCallbacks;
-import org.apache.helix.manager.zk.ZkSessionMismatchedException;
-import org.apache.helix.manager.zk.zookeeper.ZkEventThread.ZkEvent;
-import org.apache.helix.monitoring.mbeans.ZkClientMonitor;
-import org.apache.helix.util.ExponentialBackoffStrategy;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.KeeperException.ConnectionLossException;
-import org.apache.zookeeper.KeeperException.SessionExpiredException;
-import org.apache.zookeeper.Op;
-import org.apache.zookeeper.OpResult;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.Watcher;
-import org.apache.zookeeper.Watcher.Event.EventType;
-import org.apache.zookeeper.Watcher.Event.KeeperState;
-import org.apache.zookeeper.ZooDefs;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.data.ACL;
-import org.apache.zookeeper.data.Stat;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.apache.helix.zookeeper.zkclient.IZkConnection;
+import org.apache.helix.zookeeper.zkclient.serialize.PathBasedZkSerializer;
/**
- * Abstracts the interaction with zookeeper and allows permanent (not just one time) watches on
- * nodes in ZooKeeper.
- * WARN: Do not use this class directly, use {@link org.apache.helix.manager.zk.ZkClient} instead.
+ * Use ZkClient in zookeeper-api module instead.
*/
-public class ZkClient implements Watcher {
- private static Logger LOG = LoggerFactory.getLogger(ZkClient.class);
- private static long MAX_RECONNECT_INTERVAL_MS = 30000; // 30 seconds
-
- private final IZkConnection _connection;
- private final long _operationRetryTimeoutInMillis;
- private final Map<String, Set<IZkChildListener>> _childListener = new ConcurrentHashMap<>();
- private final ConcurrentHashMap<String, Set<IZkDataListenerEntry>> _dataListener =
- new ConcurrentHashMap<>();
- private final Set<IZkStateListener> _stateListener = new CopyOnWriteArraySet<>();
- private KeeperState _currentState;
- private final ZkLock _zkEventLock = new ZkLock();
-
- // When a new zookeeper instance is created in reconnect, its session id is not yet valid before
- // the zookeeper session is established(SyncConnected). To avoid session race condition in
- // handling new session, the new session event is only fired after SyncConnected. Meanwhile,
- // SyncConnected state is also received when re-opening the zk connection. So to avoid firing
- // new session event more than once, this flag is used to check.
- // It is set to false right after the new zookeeper instance is created in reconnect before the
- // session is established. And set it to true once the new session event is fired the first time.
- private boolean _isNewSessionEventFired;
-
- private boolean _shutdownTriggered;
- private ZkEventThread _eventThread;
- // TODO PVo remove this later
- private Thread _zookeeperEventThread;
- private volatile boolean _closed;
- private PathBasedZkSerializer _pathBasedZkSerializer;
- private ZkClientMonitor _monitor;
-
- private class IZkDataListenerEntry {
- final IZkDataListener _dataListener;
- final boolean _prefetchData;
-
- public IZkDataListenerEntry(IZkDataListener dataListener, boolean prefetchData) {
- _dataListener = dataListener;
- _prefetchData = prefetchData;
- }
-
- public IZkDataListenerEntry(IZkDataListener dataListener) {
- _dataListener = dataListener;
- _prefetchData = false;
- }
-
- public IZkDataListener getDataListener() {
- return _dataListener;
- }
-
- public boolean isPrefetchData() {
- return _prefetchData;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (!(o instanceof IZkDataListenerEntry)) {
- return false;
- }
-
- IZkDataListenerEntry that = (IZkDataListenerEntry) o;
-
- return _dataListener.equals(that._dataListener);
- }
-
- @Override
- public int hashCode() {
- return _dataListener.hashCode();
- }
- }
-
- private class ZkPathStatRecord {
- private final String _path;
- private Stat _stat = null;
- private boolean _checked = false;
-
- public ZkPathStatRecord(String path) {
- _path = path;
- }
-
- public boolean pathExists() {
- return _stat != null;
- }
-
- public boolean pathChecked() {
- return _checked;
- }
-
- /*
- * Note this method is not thread safe.
- */
- public void recordPathStat(Stat stat, OptionalLong notificationTime) {
- _checked = true;
- _stat = stat;
-
- if (_monitor != null && stat != null && notificationTime.isPresent()) {
- long updateTime = Math.max(stat.getCtime(), stat.getMtime());
- if (notificationTime.getAsLong() > updateTime) {
- _monitor.recordDataPropagationLatency(_path, notificationTime.getAsLong() - updateTime);
- } // else, the node was updated again after the notification. Propagation latency is
- // unavailable.
- }
- }
- }
-
+@Deprecated
+public class ZkClient extends org.apache.helix.zookeeper.zkclient.ZkClient {
protected ZkClient(IZkConnection zkConnection, int connectionTimeout, long operationRetryTimeout,
PathBasedZkSerializer zkSerializer, String monitorType, String monitorKey,
String monitorInstanceName, boolean monitorRootPathOnly) {
- if (zkConnection == null) {
- throw new NullPointerException("Zookeeper connection is null!");
- }
- _connection = zkConnection;
- _pathBasedZkSerializer = zkSerializer;
- _operationRetryTimeoutInMillis = operationRetryTimeout;
- _isNewSessionEventFired = false;
-
- connect(connectionTimeout, this);
-
- // initiate monitor
- try {
- if (monitorKey != null && !monitorKey.isEmpty() && monitorType != null
- && !monitorType.isEmpty()) {
- _monitor = new ZkClientMonitor(monitorType, monitorKey, monitorInstanceName,
- monitorRootPathOnly, _eventThread);
- _monitor.register();
- } else {
- LOG.info("ZkClient monitor key or type is not provided. Skip monitoring.");
- }
- } catch (JMException e) {
- LOG.error("Error in creating ZkClientMonitor", e);
- }
- }
-
- public List<String> subscribeChildChanges(String path, IZkChildListener listener) {
- synchronized (_childListener) {
- Set<IZkChildListener> listeners = _childListener.get(path);
- if (listeners == null) {
- listeners = new CopyOnWriteArraySet<>();
- _childListener.put(path, listeners);
- }
- listeners.add(listener);
- }
- return watchForChilds(path);
- }
-
- public void unsubscribeChildChanges(String path, IZkChildListener childListener) {
- synchronized (_childListener) {
- final Set<IZkChildListener> listeners = _childListener.get(path);
- if (listeners != null) {
- listeners.remove(childListener);
- }
- }
- }
-
- /**
- * Subscribe the path and the listener will handle data events of the path
- * WARNING: if the path is created after deletion, users need to re-subscribe the path
- * @param path The zookeeper path
- * @param listener Instance of {@link IZkDataListener}
- */
- public void subscribeDataChanges(String path, IZkDataListener listener) {
- Set<IZkDataListenerEntry> listenerEntries;
- synchronized (_dataListener) {
- listenerEntries = _dataListener.get(path);
- if (listenerEntries == null) {
- listenerEntries = new CopyOnWriteArraySet<>();
- _dataListener.put(path, listenerEntries);
- }
-
- boolean prefetchEnabled = isPrefetchEnabled(listener);
- IZkDataListenerEntry listenerEntry = new IZkDataListenerEntry(listener, prefetchEnabled);
- listenerEntries.add(listenerEntry);
- if (prefetchEnabled) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Subscribed data changes for " + path + ", listener: " + listener
- + ", prefetch data: " + prefetchEnabled);
- }
- }
- }
- watchForData(path);
- if (LOG.isDebugEnabled()) {
- LOG.debug("Subscribed data changes for " + path);
- }
- }
-
- private boolean isPrefetchEnabled(IZkDataListener dataListener) {
- PreFetch preFetch = dataListener.getClass().getAnnotation(PreFetch.class);
- if (preFetch != null) {
- return preFetch.enabled();
- }
-
- Method callbackMethod = IZkDataListener.class.getMethods()[0];
- try {
- Method method = dataListener.getClass().getMethod(callbackMethod.getName(),
- callbackMethod.getParameterTypes());
- PreFetch preFetchInMethod = method.getAnnotation(PreFetch.class);
- if (preFetchInMethod != null) {
- return preFetchInMethod.enabled();
- }
- } catch (NoSuchMethodException e) {
- LOG.warn("No method " + callbackMethod.getName() + " defined in listener "
- + dataListener.getClass().getCanonicalName());
- }
-
- return true;
- }
-
- public void unsubscribeDataChanges(String path, IZkDataListener dataListener) {
- synchronized (_dataListener) {
- final Set<IZkDataListenerEntry> listeners = _dataListener.get(path);
- if (listeners != null) {
- IZkDataListenerEntry listenerEntry = new IZkDataListenerEntry(dataListener);
- listeners.remove(listenerEntry);
- }
- if (listeners == null || listeners.isEmpty()) {
- _dataListener.remove(path);
- }
- }
- }
-
- public void subscribeStateChanges(final IZkStateListener listener) {
- synchronized (_stateListener) {
- _stateListener.add(listener);
- }
- }
-
- /**
- * Subscribes state changes for a {@link org.I0Itec.zkclient.IZkStateListener} listener.
- *
- * @deprecated
- * This is deprecated. It is kept for backwards compatibility. Please use
- * {@link #subscribeStateChanges(IZkStateListener)}.
- *
- * @param listener {@link org.I0Itec.zkclient.IZkStateListener} listener
- */
- @Deprecated
- public void subscribeStateChanges(final org.I0Itec.zkclient.IZkStateListener listener) {
- subscribeStateChanges(new IZkStateListenerI0ItecImpl(listener));
- }
-
- public void unsubscribeStateChanges(IZkStateListener stateListener) {
- synchronized (_stateListener) {
- _stateListener.remove(stateListener);
- }
- }
-
- /**
- * Unsubscribes state changes for a {@link org.I0Itec.zkclient.IZkStateListener} listener.
- *
- * @deprecated
- * This is deprecated. It is kept for backwards compatibility. Please use
- * {@link #unsubscribeStateChanges(IZkStateListener)}.
- *
- * @param stateListener {@link org.I0Itec.zkclient.IZkStateListener} listener
- */
- @Deprecated
- public void unsubscribeStateChanges(org.I0Itec.zkclient.IZkStateListener stateListener) {
- unsubscribeStateChanges(new IZkStateListenerI0ItecImpl(stateListener));
- }
-
- public void unsubscribeAll() {
- synchronized (_childListener) {
- _childListener.clear();
- }
- synchronized (_dataListener) {
- _dataListener.clear();
- }
- synchronized (_stateListener) {
- _stateListener.clear();
- }
- }
-
- // </listeners>
-
- /**
- * Create a persistent node.
- * @param 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 void createPersistent(String path)
- throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
- createPersistent(path, false);
- }
-
- /**
- * Create a persistent node and set its ACLs.
- * @param path
- * @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 createPersistent(String path, boolean createParents)
- throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
- createPersistent(path, createParents, ZooDefs.Ids.OPEN_ACL_UNSAFE);
- }
-
- /**
- * Create a persistent node and set its ACLs.
- * @param path
- * @param acl
- * List of ACL permissions to assign to the node
- * @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 createPersistent(String path, boolean createParents, List<ACL> acl)
- throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
- try {
- create(path, null, acl, CreateMode.PERSISTENT);
- } catch (ZkNodeExistsException e) {
- if (!createParents) {
- throw e;
- }
- } catch (ZkNoNodeException e) {
- if (!createParents) {
- throw e;
- }
- String parentDir = path.substring(0, path.lastIndexOf('/'));
- createPersistent(parentDir, createParents, acl);
- createPersistent(path, createParents, acl);
- }
- }
-
- /**
- * Create a persistent node.
- * @param path
- * @param data
- * @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 createPersistent(String path, Object data)
- throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
- create(path, data, CreateMode.PERSISTENT);
- }
-
- /**
- * Create a persistent node.
- * @param path
- * @param data
- * @param acl
- * @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 createPersistent(String path, Object data, List<ACL> acl) {
- create(path, data, acl, CreateMode.PERSISTENT);
- }
-
- /**
- * Create a persistent, sequental node.
- * @param path
- * @param data
- * @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 createPersistentSequential(String path, Object data)
- throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
- return create(path, data, CreateMode.PERSISTENT_SEQUENTIAL);
- }
-
- /**
- * Create a persistent, sequential node and set its ACL.
- * @param path
- * @param acl
- * @param data
- * @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 createPersistentSequential(String path, Object data, List<ACL> acl)
- throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
- return create(path, data, acl, CreateMode.PERSISTENT_SEQUENTIAL);
- }
-
- /**
- * Create an ephemeral node.
- * @param 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 void createEphemeral(final String path)
- throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
- create(path, null, CreateMode.EPHEMERAL);
- }
-
- /**
- * Creates an ephemeral node. This ephemeral node is created by the expected(passed-in) ZK session.
- * If the expected session does not match the current ZK session, the node will not be created.
- *
- * @param path path of the node
- * @param sessionId expected session id of the ZK connection. If the session id of current ZK
- * connection does not match the expected session id, ephemeral creation will
- * fail
- * @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 createEphemeral(final String path, final String sessionId)
- throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
- createEphemeral(path, null, sessionId);
- }
-
- /**
- * Create an ephemeral node and set its ACL.
- * @param path
- * @param acl
- * @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 createEphemeral(final String path, final List<ACL> acl)
- throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
- create(path, null, acl, CreateMode.EPHEMERAL);
- }
-
- /**
- * Creates an ephemeral node and set its ACL. This ephemeral node is created by the
- * expected(passed-in) ZK session. If the expected session does not match the current ZK session,
- * the node will not be created.
- *
- * @param path path of the ephemeral node
- * @param acl a list of ACL for the ephemeral node.
- * @param sessionId expected session id of the ZK connection. If the session id of current ZK
- * connection does not match the expected session id, ephemeral creation will
- * fail.
- * @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 createEphemeral(final String path, final List<ACL> acl, final String sessionId)
- throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
- create(path, null, acl, CreateMode.EPHEMERAL, sessionId);
- }
-
- /**
- * Create a node.
- * @param path
- * @param data
- * @param mode
- * @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)
- throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
- return create(path, data, ZooDefs.Ids.OPEN_ACL_UNSAFE, mode);
- }
-
- /**
- * Create a node with ACL.
- * @param path
- * @param datat
- * @param acl
- * @param mode
- * @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)
- throws IllegalArgumentException, ZkException {
- return create(path, datat, acl, mode, null);
- }
-
- /**
- * Creates a node and returns the actual path of the created node.
- *
- * Given an expected non-null session id, if the node is successfully created, it is guaranteed to
- * be created in the expected(passed-in) session.
- *
- * If the expected session is expired, which means the expected session does not match the current
- * session of ZK connection, the node will not be created.
- *
- * @param path the path where you want the node to be created
- * @param dataObject data of the node
- * @param acl list of ACL for the node
- * @param mode {@link CreateMode} of the node
- * @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
- * failed if the expected session id doesn't match current connected zk session.
- * If the session id is null, it means the create operation is NOT session aware.
- * @return path of the node created
- * @throws IllegalArgumentException if called from anything else except the ZooKeeper event thread
- * @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)
- throws IllegalArgumentException, ZkException {
- if (path == null) {
- throw new NullPointerException("Path must not be null.");
- }
- if (acl == null || acl.size() == 0) {
- throw new NullPointerException("Missing value for ACL");
- }
- long startT = System.currentTimeMillis();
- try {
- final byte[] dataBytes = dataObject == null ? null : serialize(dataObject, path);
- checkDataSizeLimit(dataBytes);
-
- final String actualPath = retryUntilConnected(() -> {
- ZooKeeper zooKeeper = ((ZkConnection) getConnection()).getZookeeper();
-
- /*
- * 1. If operation is session aware, we have to check whether or not the
- * passed-in(expected) session id matches actual session's id.
- * If not, ephemeral node creation is failed. This validation is
- * critical to guarantee the ephemeral node created by the expected ZK session.
- *
- * 2. Otherwise, the operation is NOT session aware.
- * In this case, we will use the actual zookeeper session to create the node.
- */
- if (isSessionAwareOperation(expectedSessionId, mode)) {
- acquireEventLock();
- try {
- final String actualSessionId = ZKUtil.toHexSessionId(zooKeeper.getSessionId());
- if (!actualSessionId.equals(expectedSessionId)) {
- throw new ZkSessionMismatchedException(
- "Failed to create ephemeral node! There is a session id mismatch. Expected: "
- + expectedSessionId + ". Actual: " + actualSessionId);
- }
-
- /*
- * Cache the zookeeper reference and make sure later zooKeeper.create() is being run
- * under this zookeeper connection. This is to avoid locking zooKeeper.create() which
- * may cause potential performance issue.
- */
- zooKeeper = ((ZkConnection) getConnection()).getZookeeper();
- } finally {
- getEventLock().unlock();
- }
- }
-
- return zooKeeper.create(path, dataBytes, acl, mode);
- });
-
- record(path, dataBytes, startT, ZkClientMonitor.AccessType.WRITE);
- return actualPath;
- } catch (Exception e) {
- recordFailure(path, ZkClientMonitor.AccessType.WRITE);
- throw e;
- } finally {
- long endT = System.currentTimeMillis();
- if (LOG.isTraceEnabled()) {
- LOG.trace("create, path: " + path + ", time: " + (endT - startT) + " ms");
- }
- }
- }
-
- /**
- * Create an ephemeral node.
- * @param path
- * @param data
- * @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 createEphemeral(final String path, final Object data)
- throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
- create(path, data, CreateMode.EPHEMERAL);
- }
-
- /**
- * Creates an ephemeral node. Given an expected non-null session id, if the ephemeral
- * node is successfully created, it is guaranteed to be in the expected(passed-in) session.
- *
- * If the expected session is expired, which means the expected session does not match the session
- * of current ZK connection, the ephemeral node will not be created.
- * If connection is timed out or interrupted, exception is thrown.
- *
- * @param path path of the ephemeral node being created
- * @param data data of the ephemeral node being created
- * @param sessionId 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
- * failed if the expected session id doesn't match current connected zk session.
- * If the session id is null, it means the operation is NOT session aware
- * and the node will be created by current ZK session.
- * @throws ZkInterruptedException if operation is interrupted, or a required reconnection gets
- * interrupted
- * @throws IllegalArgumentException if called from anything except the ZooKeeper event thread
- * @throws ZkException if any ZooKeeper exception occurs
- * @throws RuntimeException if any other exception occurs
- */
- 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 an ephemeral node.
- * @param path
- * @param data
- * @param acl
- * @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 createEphemeral(final String path, final Object data, final List<ACL> acl)
- throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
- create(path, data, acl, CreateMode.EPHEMERAL);
- }
-
- /**
- * Creates an ephemeral node in an expected ZK session. Given an expected non-null session id,
- * if the ephemeral node is successfully created, it is guaranteed to be in the expected session.
- * If the expected session is expired, which means the expected session does not match the session
- * of current ZK connection, the ephemeral node will not be created.
- * If connection is timed out or interrupted, exception is thrown.
- *
- * @param path path of the ephemeral node being created
- * @param data data of the ephemeral node being created
- * @param acl list of ACL for the ephemeral node
- * @param sessionId 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
- * failed if the expected session id doesn't match current connected zk session.
- * If the session id is null, it means the create operation is NOT session aware
- * and the node will be created by current ZK session.
- * @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 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 an ephemeral, sequential node.
- * @param path
- * @param data
- * @return created 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 createEphemeralSequential(final String path, final Object data)
- throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
- return create(path, data, CreateMode.EPHEMERAL_SEQUENTIAL);
- }
-
- /**
- * Creates an ephemeral, sequential node with ACL in an expected ZK session.
- * Given an expected non-null session id, if the ephemeral node is successfully created,
- * it is guaranteed to be in the expected session.
- * If the expected session is expired, which means the expected session does not match the session
- * of current ZK connection, the ephemeral node will not be created.
- * If connection is timed out or interrupted, exception is thrown.
- *
- * @param path path of the node
- * @param data data of the node
- * @param acl list of ACL for the node
- * @return created 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 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);
- }
-
- /**
- * Creates an ephemeral, sequential node. Given an expected non-null session id,
- * if the ephemeral node is successfully created, it is guaranteed to be in the expected session.
- * If the expected session is expired, which means the expected session does not match the session
- * of current ZK connection, the ephemeral node will not be created.
- * If connection is timed out or interrupted, exception is thrown.
- *
- * @param path path of the node
- * @param data data of the node
- * @param sessionId 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
- * failed if the expected session id doesn't match current connected zk session.
- * If the session id is null, it means the create operation is NOT session aware
- * and the node will be created by current ZK session.
- * @return created 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 createEphemeralSequential(final String path, final Object data,
- final String sessionId)
- throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
- return create(path, data, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL,
- sessionId);
- }
-
- /**
- * Create an ephemeral, sequential node with ACL.
- * @param path
- * @param data
- * @param acl
- * @return created 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 createEphemeralSequential(final String path, final Object data, final List<ACL> acl)
- throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
- return create(path, data, acl, CreateMode.EPHEMERAL_SEQUENTIAL);
- }
-
- @Override
- public void process(WatchedEvent event) {
- long notificationTime = System.currentTimeMillis();
- if (LOG.isDebugEnabled()) {
- LOG.debug("Received event: " + event);
- }
- _zookeeperEventThread = Thread.currentThread();
-
- boolean stateChanged = event.getPath() == null;
- boolean znodeChanged = event.getPath() != null;
- boolean dataChanged = event.getType() == Event.EventType.NodeDataChanged
- || event.getType() == Event.EventType.NodeDeleted
- || event.getType() == Event.EventType.NodeCreated
- || event.getType() == Event.EventType.NodeChildrenChanged;
- if (event.getType() == EventType.NodeDeleted) {
- LOG.debug("Path {} is deleted", event.getPath());
- }
-
- getEventLock().lock();
- try {
- // We might have to install child change event listener if a new node was created
- if (getShutdownTrigger()) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("ignoring event '{" + event.getType() + " | " + event.getPath()
- + "}' since shutdown triggered");
- }
- return;
- }
- if (stateChanged) {
- processStateChanged(event);
- }
- if (dataChanged) {
- processDataOrChildChange(event, notificationTime);
- }
- } finally {
- if (stateChanged) {
- getEventLock().getStateChangedCondition().signalAll();
-
- // If the session expired we have to signal all conditions, because watches might have been
- // removed and
- // there is no guarantee that those
- // conditions will be signaled at all after an Expired event
- // TODO PVo write a test for this
- if (event.getState() == KeeperState.Expired) {
- getEventLock().getZNodeEventCondition().signalAll();
- getEventLock().getDataChangedCondition().signalAll();
- }
- }
- if (znodeChanged) {
- getEventLock().getZNodeEventCondition().signalAll();
- }
- if (dataChanged) {
- getEventLock().getDataChangedCondition().signalAll();
- }
- getEventLock().unlock();
-
- // update state change counter.
- recordStateChange(stateChanged, dataChanged);
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("Leaving process event");
- }
- }
- }
-
- private void fireAllEvents() {
- //TODO: During handling new session, if the path is deleted, watcher leakage could still happen
- for (Entry<String, Set<IZkChildListener>> entry : _childListener.entrySet()) {
- fireChildChangedEvents(entry.getKey(), entry.getValue(), true);
- }
- for (Entry<String, Set<IZkDataListenerEntry>> entry : _dataListener.entrySet()) {
- fireDataChangedEvents(entry.getKey(), entry.getValue(), OptionalLong.empty(), true);
- }
- }
-
- public List<String> getChildren(String path) {
- return getChildren(path, hasListeners(path));
- }
-
- protected List<String> getChildren(final String path, final boolean watch) {
- long startT = System.currentTimeMillis();
- try {
- List<String> children = retryUntilConnected(new Callable<List<String>>() {
- @Override
- public List<String> call() throws Exception {
- return getConnection().getChildren(path, watch);
- }
- });
- record(path, null, startT, ZkClientMonitor.AccessType.READ);
- return children;
- } catch (ZkNoNodeException e) {
- record(path, null, startT, ZkClientMonitor.AccessType.READ);
- throw e;
- } catch (Exception e) {
- recordFailure(path, ZkClientMonitor.AccessType.READ);
- throw e;
- } finally {
- long endT = System.currentTimeMillis();
- if (LOG.isTraceEnabled()) {
- LOG.trace("getChildren, path: " + path + ", time: " + (endT - startT) + " ms");
- }
- }
- }
-
- /**
- * Counts number of children for the given path.
- * @param path
- * @return number of children or 0 if path does not exist.
- */
- public int countChildren(String path) {
- try {
- return getChildren(path).size();
- } catch (ZkNoNodeException e) {
- return 0;
- }
- }
-
- public boolean exists(final String path) {
- return exists(path, hasListeners(path));
- }
-
- protected boolean exists(final String path, final boolean watch) {
- long startT = System.currentTimeMillis();
- try {
- boolean exists = retryUntilConnected(new Callable<Boolean>() {
- @Override
- public Boolean call() throws Exception {
- return getConnection().exists(path, watch);
- }
- });
- record(path, null, startT, ZkClientMonitor.AccessType.READ);
- return exists;
- } catch (ZkNoNodeException e) {
- record(path, null, startT, ZkClientMonitor.AccessType.READ);
- throw e;
- } catch (Exception e) {
- recordFailure(path, ZkClientMonitor.AccessType.READ);
- throw e;
- } finally {
- long endT = System.currentTimeMillis();
- if (LOG.isTraceEnabled()) {
- LOG.trace("exists, path: " + path + ", time: " + (endT - startT) + " ms");
- }
- }
- }
-
- public Stat getStat(final String path) {
- return getStat(path, false);
- }
-
- private Stat getStat(final String path, final boolean watch) {
- long startT = System.currentTimeMillis();
- try {
- Stat stat = retryUntilConnected(
- () -> ((ZkConnection) getConnection()).getZookeeper().exists(path, watch));
- record(path, null, startT, ZkClientMonitor.AccessType.READ);
- return stat;
- } catch (ZkNoNodeException e) {
- record(path, null, startT, ZkClientMonitor.AccessType.READ);
- throw e;
- } catch (Exception e) {
- recordFailure(path, ZkClientMonitor.AccessType.READ);
- throw e;
- } finally {
- long endT = System.currentTimeMillis();
- if (LOG.isTraceEnabled()) {
- LOG.trace("exists, path: " + path + ", time: " + (endT - startT) + " ms");
- }
- }
- }
-
- protected void processStateChanged(WatchedEvent event) {
- LOG.info("zookeeper state changed (" + event.getState() + ")");
- setCurrentState(event.getState());
- if (getShutdownTrigger()) {
- return;
- }
-
- fireStateChangedEvent(event.getState());
-
- if (!isManagingZkConnection()) {
- return;
- }
-
- if (event.getState() == KeeperState.SyncConnected) {
- if (!_isNewSessionEventFired && !"0".equals(getHexSessionId())) {
- /*
- * Before the new zookeeper instance is connected to the zookeeper service and its session
- * is established, its session id is 0.
- * New session event is not fired until the new zookeeper session receives the first
- * SyncConnected state(the zookeeper session is established).
- * Now the session id is available and non-zero, and we can fire new session events.
- */
- fireNewSessionEvents();
- /*
- * Set it true to avoid firing events again for the same session next time
- * when SyncConnected events are received.
- */
- _isNewSessionEventFired = true;
-
- /*
- * With this first SyncConnected state, we just get connected to zookeeper service after
- * reconnecting when the session expired. Because previous session expired, we also have to
- * notify all listeners that something might have changed.
- */
- fireAllEvents();
- }
- } else if (event.getState() == KeeperState.Expired) {
- reconnectOnExpiring();
- }
- }
-
- private void reconnectOnExpiring() {
- int retryCount = 0;
- ExponentialBackoffStrategy retryStrategy =
- new ExponentialBackoffStrategy(MAX_RECONNECT_INTERVAL_MS, true);
-
- Exception reconnectException = new ZkException("Shutdown triggered.");
- while (!isClosed()) {
- try {
- reconnect();
- return;
- } catch (ZkInterruptedException interrupt) {
- reconnectException = interrupt;
- break;
- } catch (Exception e) {
- reconnectException = e;
- long waitInterval = retryStrategy.getNextWaitInterval(retryCount++);
- LOG.warn("ZkClient reconnect on expiring failed. Will retry after {} ms", waitInterval, e);
- try {
- Thread.sleep(waitInterval);
- } catch (InterruptedException ex) {
- reconnectException = ex;
- break;
- }
- }
- }
-
- LOG.info("Unable to re-establish connection. Notifying consumer of the following exception: ",
- reconnectException);
- fireSessionEstablishmentError(reconnectException);
- }
-
- private void reconnect() {
- getEventLock().lock();
- try {
- ZkConnection connection = ((ZkConnection) getConnection());
- connection.reconnect(this);
- _isNewSessionEventFired = false;
- } catch (InterruptedException e) {
- throw new ZkInterruptedException(e);
- } finally {
- getEventLock().unlock();
- }
- }
-
- private void fireNewSessionEvents() {
- final String sessionId = getHexSessionId();
- for (final IZkStateListener stateListener : _stateListener) {
- _eventThread.send(new ZkEvent("New session event sent to " + stateListener, sessionId) {
-
- @Override
- public void run() throws Exception {
- stateListener.handleNewSession(sessionId);
- }
- });
- }
- }
-
- protected void fireStateChangedEvent(final KeeperState state) {
- final String sessionId = getHexSessionId();
- for (final IZkStateListener stateListener : _stateListener) {
- final String description = "State changed to " + state + " sent to " + stateListener;
- _eventThread.send(new ZkEvent(description, sessionId) {
-
- @Override
- public void run() throws Exception {
- stateListener.handleStateChanged(state);
- }
- });
- }
- }
-
- private void fireSessionEstablishmentError(final Throwable error) {
- for (final IZkStateListener stateListener : _stateListener) {
- _eventThread
- .send(new ZkEvent("Session establishment error(" + error + ") sent to " + stateListener) {
-
- @Override
- public void run() throws Exception {
- stateListener.handleSessionEstablishmentError(error);
- }
- });
- }
- }
-
- private boolean hasListeners(String path) {
- Set<IZkDataListenerEntry> dataListeners = _dataListener.get(path);
- if (dataListeners != null && dataListeners.size() > 0) {
- return true;
- }
- Set<IZkChildListener> childListeners = _childListener.get(path);
- if (childListeners != null && childListeners.size() > 0) {
- return true;
- }
- return false;
- }
-
- /**
- * Delete the path as well as all its children.
- * This method is deprecated, please use {@link #deleteRecursively(String)}} instead
- * @param path ZK path
- * @return true if successfully deleted all children, and the given path, else false
- */
- @Deprecated
- public boolean deleteRecursive(String path) {
- try {
- deleteRecursively(path);
- return true;
- } catch (HelixException e) {
- LOG.error("Failed to recursively delete path " + path, e);
- return false;
- }
- }
-
- /**
- * Delete the path as well as all its children.
- * @param path
- * @throws HelixException
- */
- public void deleteRecursively(String path) throws HelixException {
- List<String> children;
- try {
- children = getChildren(path, false);
- } catch (ZkNoNodeException e) {
- // if the node to be deleted does not exist, treat it as success.
- return;
- }
-
- for (String subPath : children) {
- deleteRecursively(path + "/" + subPath);
- }
-
- // delete() function call will return true if successful, false if the path does not
- // exist (in this context, it should be treated as successful), and throw exception
- // if there is any other failure case.
- try {
- delete(path);
- } catch (Exception e) {
- LOG.error("Failed to delete " + path, e);
- throw new HelixException("Failed to delete " + path, e);
- }
- }
-
- private void processDataOrChildChange(WatchedEvent event, long notificationTime) {
- final String path = event.getPath();
- final boolean pathExists = event.getType() != EventType.NodeDeleted;
-
- if (event.getType() == EventType.NodeChildrenChanged || event.getType() == EventType.NodeCreated
- || event.getType() == EventType.NodeDeleted) {
- Set<IZkChildListener> childListeners = _childListener.get(path);
- if (childListeners != null && !childListeners.isEmpty()) {
- // TODO recording child changed event propagation latency as well. Note this change will
- // introduce additional ZK access.
- fireChildChangedEvents(path, childListeners, pathExists);
- }
- }
-
- if (event.getType() == EventType.NodeDataChanged || event.getType() == EventType.NodeDeleted
- || event.getType() == EventType.NodeCreated) {
- Set<IZkDataListenerEntry> listeners = _dataListener.get(path);
- if (listeners != null && !listeners.isEmpty()) {
- fireDataChangedEvents(event.getPath(), listeners, OptionalLong.of(notificationTime), pathExists);
- }
- }
- }
-
- private void fireDataChangedEvents(final String path, Set<IZkDataListenerEntry> listeners,
- final OptionalLong notificationTime, boolean pathExists) {
- try {
- final ZkPathStatRecord pathStatRecord = new ZkPathStatRecord(path);
- // Trigger listener callbacks
- for (final IZkDataListenerEntry listener : listeners) {
- _eventThread.send(new ZkEvent("Data of " + path + " changed sent to "
- + listener.getDataListener() + " prefetch data: " + listener.isPrefetchData()) {
- @Override
- public void run() throws Exception {
- if (!pathStatRecord.pathChecked()) {
- // getStat will re-install watcher only when the path exists
- pathStatRecord.recordPathStat(getStat(path, pathExists), notificationTime);
- }
- if (!pathStatRecord.pathExists()) {
- listener.getDataListener().handleDataDeleted(path);
- } else {
- Object data = null;
- if (listener.isPrefetchData()) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Prefetch data for path: {}", path);
- }
- try {
- // TODO: the data is redundantly read multiple times when multiple listeners exist
- data = readData(path, null, true);
- } catch (ZkNoNodeException e) {
- LOG.warn("Prefetch data for path: {} failed.", path, e);
- listener.getDataListener().handleDataDeleted(path);
- return;
- }
- }
- listener.getDataListener().handleDataChange(path, data);
- }
- }
- });
- }
- } catch (Exception e) {
- LOG.error("Failed to fire data changed event for path: {}", path, e);
- }
- }
-
- private void fireChildChangedEvents(final String path, Set<IZkChildListener> childListeners, boolean pathExists) {
- try {
- final ZkPathStatRecord pathStatRecord = new ZkPathStatRecord(path);
- for (final IZkChildListener listener : childListeners) {
- _eventThread.send(new ZkEvent("Children of " + path + " changed sent to " + listener) {
- @Override
- public void run() throws Exception {
- if (!pathStatRecord.pathChecked()) {
- pathStatRecord.recordPathStat(getStat(path, hasListeners(path) && pathExists),
- OptionalLong.empty());
- }
- List<String> children = null;
- if (pathStatRecord.pathExists()) {
- try {
- //TODO: duplicate reads when multiple child listener exists
- children = getChildren(path);
- } catch (ZkNoNodeException e) {
- LOG.warn("Get children under path: {} failed.", path, e);
- // Continue trigger the change handler
- }
- }
- listener.handleChildChange(path, children);
- }
- });
- }
- } catch (Exception e) {
- LOG.error("Failed to fire child changed event. Unable to getChildren.", e);
- }
- }
-
- public boolean waitUntilExists(String path, TimeUnit timeUnit, long time)
- throws ZkInterruptedException {
- Date timeout = new Date(System.currentTimeMillis() + timeUnit.toMillis(time));
- if (LOG.isDebugEnabled()) {
- LOG.debug("Waiting until znode '" + path + "' becomes available.");
- }
- if (exists(path)) {
- return true;
- }
- acquireEventLock();
- try {
- while (!exists(path, true)) {
- boolean gotSignal = getEventLock().getZNodeEventCondition().awaitUntil(timeout);
- if (!gotSignal) {
- return false;
- }
- }
- return true;
- } catch (InterruptedException e) {
- throw new ZkInterruptedException(e);
- } finally {
- getEventLock().unlock();
- }
- }
-
- public IZkConnection getConnection() {
- return _connection;
- }
-
- public long waitForEstablishedSession(long timeout, TimeUnit timeUnit) {
- validateCurrentThread();
-
- acquireEventLock();
- try {
- if (!waitForKeeperState(KeeperState.SyncConnected, timeout, timeUnit)) {
- throw new ZkTimeoutException("Waiting to be connected to ZK server has timed out.");
- }
- // Reading session ID before unlocking event lock is critical to guarantee the established
- // session's ID won't change.
- return getSessionId();
- } finally {
- getEventLock().unlock();
- }
- }
-
- public boolean waitUntilConnected(long time, TimeUnit timeUnit) throws ZkInterruptedException {
- return waitForKeeperState(KeeperState.SyncConnected, time, timeUnit);
- }
-
- public boolean waitForKeeperState(KeeperState keeperState, long time, TimeUnit timeUnit)
- throws ZkInterruptedException {
- validateCurrentThread();
- Date timeout = new Date(System.currentTimeMillis() + timeUnit.toMillis(time));
-
- LOG.debug("Waiting for keeper state " + keeperState);
- acquireEventLock();
- try {
- boolean stillWaiting = true;
- while (_currentState != keeperState) {
- if (!stillWaiting) {
- return false;
- }
- stillWaiting = getEventLock().getStateChangedCondition().awaitUntil(timeout);
- }
- LOG.debug("State is " + (_currentState == null ? "CLOSED" : _currentState));
- return true;
- } catch (InterruptedException e) {
- throw new ZkInterruptedException(e);
- } finally {
- getEventLock().unlock();
- }
- }
-
- private void acquireEventLock() {
- try {
- getEventLock().lockInterruptibly();
- } catch (InterruptedException e) {
- throw new ZkInterruptedException(e);
- }
- }
-
- /**
- * @param <T>
- * @param callable
- * @return result of Callable
- * @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 from invoking the Callable
- */
- public <T> T retryUntilConnected(final Callable<T> callable)
- throws IllegalArgumentException, ZkException {
- if (_zookeeperEventThread != null && Thread.currentThread() == _zookeeperEventThread) {
- throw new IllegalArgumentException("Must not be done in the zookeeper event thread.");
- }
- final long operationStartTime = System.currentTimeMillis();
- if (_monitor != null) {
- _monitor.increaseOutstandingRequestGauge();
- }
- try {
- while (true) {
- // Because ConnectionLossException and SessionExpiredException are caught but not thrown,
- // we don't know what causes retry. This is used to record which one of the two exceptions
- // causes retry in ZkTimeoutException.
- // This also helps the test testConnectionLossWhileCreateEphemeral.
- KeeperException.Code retryCauseCode;
-
- if (isClosed()) {
- throw new IllegalStateException("ZkClient already closed!");
- }
- try {
- final ZkConnection zkConnection = (ZkConnection) getConnection();
- // Validate that the connection is not null before trigger callback
- if (zkConnection == null || zkConnection.getZookeeper() == null) {
- throw new IllegalStateException(
- "ZkConnection is in invalid state! Please close this ZkClient and create new client.");
- }
- return callable.call();
- } catch (ConnectionLossException e) {
- retryCauseCode = e.code();
- // we give the event thread some time to update the status to 'Disconnected'
- Thread.yield();
- waitForRetry();
- } catch (SessionExpiredException e) {
- retryCauseCode = e.code();
- // we give the event thread some time to update the status to 'Expired'
- Thread.yield();
- waitForRetry();
- } catch (ZkSessionMismatchedException e) {
- throw e;
- } catch (KeeperException e) {
- throw ZkException.create(e);
- } catch (InterruptedException e) {
- throw new ZkInterruptedException(e);
- } catch (Exception e) {
- throw ExceptionUtil.convertToRuntimeException(e);
- }
- // before attempting a retry, check whether retry timeout has elapsed
- if (System.currentTimeMillis() - operationStartTime > _operationRetryTimeoutInMillis) {
- throw new ZkTimeoutException("Operation cannot be retried because of retry timeout ("
- + _operationRetryTimeoutInMillis + " milli seconds). Retry was caused by "
- + retryCauseCode);
- }
- }
- } finally {
- if (_monitor != null) {
- _monitor.decreaseOutstandingRequestGauge();
- }
- }
- }
-
- private void waitForRetry() {
- waitUntilConnected(_operationRetryTimeoutInMillis, TimeUnit.MILLISECONDS);
- }
-
- public void setCurrentState(KeeperState currentState) {
- getEventLock().lock();
- try {
- _currentState = currentState;
- } finally {
- getEventLock().unlock();
- }
- }
-
- /**
- * Returns a mutex all zookeeper events are synchronized aginst. So in case you need to do
- * something without getting
- * any zookeeper event interruption synchronize against this mutex. Also all threads waiting on
- * this mutex object
- * will be notified on an event.
- * @return the mutex.
- */
- public ZkLock getEventLock() {
- return _zkEventLock;
- }
-
- /**
- * Delete the given path. Path should not have any children or the deletion will fail.
- * This function will throw exception if we fail to delete an existing path
- * @param path
- * @return true if path is successfully deleted, false if path does not exist
- */
- public boolean delete(final String path) {
- long startT = System.currentTimeMillis();
- boolean success;
- try {
- try {
- retryUntilConnected(new Callable<Object>() {
-
- @Override
- public Object call() throws Exception {
- getConnection().delete(path);
- return null;
- }
- });
- success = true;
- } catch (ZkNoNodeException e) {
- success = false;
- if (LOG.isDebugEnabled()) {
- LOG.debug("Failed to delete path " + path + ", znode does not exist!");
- }
- }
- record(path, null, startT, ZkClientMonitor.AccessType.WRITE);
- } catch (Exception e) {
- recordFailure(path, ZkClientMonitor.AccessType.WRITE);
- LOG.warn("Failed to delete path " + path + "! " + e);
- throw e;
- } finally {
- long endT = System.currentTimeMillis();
- if (LOG.isTraceEnabled()) {
- LOG.trace("delete, path: " + path + ", time: " + (endT - startT) + " ms");
- }
- }
- return success;
- }
-
- public void setZkSerializer(ZkSerializer zkSerializer) {
- _pathBasedZkSerializer = new BasicZkSerializer(zkSerializer);
- }
-
- public void setZkSerializer(PathBasedZkSerializer zkSerializer) {
- _pathBasedZkSerializer = zkSerializer;
- }
-
- public PathBasedZkSerializer getZkSerializer() {
- return _pathBasedZkSerializer;
- }
-
- public byte[] serialize(Object data, String path) {
- return _pathBasedZkSerializer.serialize(data, path);
- }
-
- @SuppressWarnings("unchecked")
- public <T extends Object> T deserialize(byte[] data, String path) {
- if (data == null) {
- return null;
- }
- return (T) _pathBasedZkSerializer.deserialize(data, path);
- }
-
- @SuppressWarnings("unchecked")
- public <T extends Object> T readData(String path) {
- return (T) readData(path, false);
- }
-
- @SuppressWarnings("unchecked")
- public <T extends Object> T readData(String path, boolean returnNullIfPathNotExists) {
- T data = null;
- try {
- data = (T) readData(path, null);
- } catch (ZkNoNodeException e) {
- if (!returnNullIfPathNotExists) {
- throw e;
- }
- }
- return data;
- }
-
- @SuppressWarnings("unchecked")
- public <T extends Object> T readData(String path, Stat stat) {
- return (T) readData(path, stat, hasListeners(path));
- }
-
- @SuppressWarnings("unchecked")
- public <T extends Object> T readData(final String path, final Stat stat, final boolean watch) {
- long startT = System.currentTimeMillis();
- byte[] data = null;
- try {
- data = retryUntilConnected(new Callable<byte[]>() {
-
- @Override
- public byte[] call() throws Exception {
- return getConnection().readData(path, stat, watch);
- }
- });
- record(path, data, startT, ZkClientMonitor.AccessType.READ);
- return (T) deserialize(data, path);
- } catch (ZkNoNodeException e) {
- record(path, data, startT, ZkClientMonitor.AccessType.READ);
- throw e;
- } catch (Exception e) {
- recordFailure(path, ZkClientMonitor.AccessType.READ);
- throw e;
- } finally {
- long endT = System.currentTimeMillis();
- if (LOG.isTraceEnabled()) {
- LOG.trace("getData, path: " + path + ", time: " + (endT - startT) + " ms");
- }
- }
- }
-
- @SuppressWarnings("unchecked")
- public <T extends Object> T readDataAndStat(String path, Stat stat,
- boolean returnNullIfPathNotExists) {
- T data = null;
- try {
- data = readData(path, stat);
- } catch (ZkNoNodeException e) {
- if (!returnNullIfPathNotExists) {
- throw e;
- }
- }
- return data;
- }
-
- public void writeData(String path, Object object) {
- writeData(path, object, -1);
- }
-
- /**
- * Updates data of an existing znode. The current content of the znode is passed to the
- * {@link DataUpdater} that is
- * passed into this method, which returns the new content. The new content is only written back to
- * ZooKeeper if
- * nobody has modified the given znode in between. If a concurrent change has been detected the
- * new data of the
- * znode is passed to the updater once again until the new contents can be successfully written
- * back to ZooKeeper.
- * @param <T>
- * @param path
- * The path of the znode.
- * @param updater
- * Updater that creates the new contents.
- */
- @SuppressWarnings("unchecked")
- public <T extends Object> void updateDataSerialized(String path, DataUpdater<T> updater) {
- Stat stat = new Stat();
- boolean retry;
- do {
- retry = false;
- try {
- T oldData = (T) readData(path, stat);
- T newData = updater.update(oldData);
- writeData(path, newData, stat.getVersion());
- } catch (ZkBadVersionException e) {
- retry = true;
- }
- } while (retry);
- }
-
- public void writeData(final String path, Object datat, final int expectedVersion) {
- writeDataReturnStat(path, datat, expectedVersion);
- }
-
- public Stat writeDataReturnStat(final String path, Object datat, final int expectedVersion) {
- long startT = System.currentTimeMillis();
- try {
- final byte[] data = serialize(datat, path);
- checkDataSizeLimit(data);
- final Stat stat = (Stat) retryUntilConnected(new Callable<Object>() {
- @Override
- public Object call() throws Exception {
- return getConnection().writeDataReturnStat(path, data, expectedVersion);
- }
- });
- record(path, data, startT, ZkClientMonitor.AccessType.WRITE);
- return stat;
- } catch (Exception e) {
- recordFailure(path, ZkClientMonitor.AccessType.WRITE);
- throw e;
- } finally {
- long endT = System.currentTimeMillis();
- if (LOG.isTraceEnabled()) {
- LOG.trace("setData, path: " + path + ", time: " + (endT - startT) + " ms");
- }
- }
- }
-
- public Stat writeDataGetStat(final String path, Object datat, final int expectedVersion) {
- return writeDataReturnStat(path, datat, expectedVersion);
- }
-
- public void asyncCreate(final String path, Object datat, final CreateMode mode,
- final ZkAsyncCallbacks.CreateCallbackHandler cb) {
- final long startT = System.currentTimeMillis();
- final byte[] data = (datat == null ? null : serialize(datat, path));
- retryUntilConnected(new Callable<Object>() {
- @Override
- public Object call() throws Exception {
- ((ZkConnection) getConnection()).getZookeeper().create(path, data,
- ZooDefs.Ids.OPEN_ACL_UNSAFE,
- // Arrays.asList(DEFAULT_ACL),
- mode, cb, new ZkAsyncCallbacks.ZkAsyncCallContext(_monitor, startT,
- data == null ? 0 : data.length, false));
- return null;
- }
- });
- }
-
- // Async Data Accessors
- public void asyncSetData(final String path, Object datat, final int version,
- final ZkAsyncCallbacks.SetDataCallbackHandler cb) {
- final long startT = System.currentTimeMillis();
- final byte[] data = serialize(datat, path);
- retryUntilConnected(new Callable<Object>() {
- @Override
- public Object call() throws Exception {
- ((ZkConnection) getConnection()).getZookeeper().setData(path, data, version, cb,
- new ZkAsyncCallbacks.ZkAsyncCallContext(_monitor, startT,
- data == null ? 0 : data.length, false));
- return null;
- }
- });
- }
-
- public void asyncGetData(final String path, final ZkAsyncCallbacks.GetDataCallbackHandler cb) {
- final long startT = System.currentTimeMillis();
- retryUntilConnected(new Callable<Object>() {
- @Override
- public Object call() throws Exception {
- ((ZkConnection) getConnection()).getZookeeper().getData(path, null, cb,
- new ZkAsyncCallbacks.ZkAsyncCallContext(_monitor, startT, 0, true));
- return null;
- }
- });
- }
-
- public void asyncExists(final String path, final ZkAsyncCallbacks.ExistsCallbackHandler cb) {
- final long startT = System.currentTimeMillis();
- retryUntilConnected(new Callable<Object>() {
- @Override
- public Object call() throws Exception {
- ((ZkConnection) getConnection()).getZookeeper().exists(path, null, cb,
- new ZkAsyncCallbacks.ZkAsyncCallContext(_monitor, startT, 0, true));
- return null;
- }
- });
- }
-
- public void asyncDelete(final String path, final ZkAsyncCallbacks.DeleteCallbackHandler cb) {
- final long startT = System.currentTimeMillis();
- retryUntilConnected(new Callable<Object>() {
- @Override
- public Object call() throws Exception {
- ((ZkConnection) getConnection()).getZookeeper().delete(path, -1, cb,
- new ZkAsyncCallbacks.ZkAsyncCallContext(_monitor, startT, 0, false));
- return null;
- }
- });
- }
-
- private void checkDataSizeLimit(byte[] data) {
- if (data != null && data.length > ZNRecord.SIZE_LIMIT) {
- LOG.error("Data size larger than 1M, will not write to zk. Data (first 1k): "
- + new String(data).substring(0, 1024));
- throw new HelixException("Data size larger than 1M");
- }
- }
-
- public void watchForData(final String path) {
- retryUntilConnected(new Callable<Object>() {
- @Override
- public Object call() throws Exception {
- getConnection().exists(path, true);
- return null;
- }
- });
- }
-
- /**
- * Installs a child watch for the given path.
- * @param path
- * @return the current children of the path or null if the zk node with the given path doesn't
- * exist.
- */
- public List<String> watchForChilds(final String path) {
- if (_zookeeperEventThread != null && Thread.currentThread() == _zookeeperEventThread) {
- throw new IllegalArgumentException("Must not be done in the zookeeper event thread.");
- }
- return retryUntilConnected(new Callable<List<String>>() {
- @Override
- public List<String> call() throws Exception {
- exists(path, true);
- try {
- return getChildren(path, true);
- } catch (ZkNoNodeException e) {
- // ignore, the "exists" watch will listen for the parent node to appear
- }
- return null;
- }
- });
- }
-
- /**
- * Add authentication information to the connection. This will be used to identify the user and
- * check access to
- * nodes protected by ACLs
- * @param scheme
- * @param auth
- */
- public void addAuthInfo(final String scheme, final byte[] auth) {
- retryUntilConnected(new Callable<Object>() {
- @Override
- public Object call() throws Exception {
- getConnection().addAuthInfo(scheme, auth);
- return null;
- }
- });
- }
-
- /**
- * Connect to ZooKeeper.
- * @param maxMsToWaitUntilConnected
- * @param watcher
- * @throws ZkInterruptedException
- * if the connection timed out due to thread interruption
- * @throws ZkTimeoutException
- * if the connection timed out
- * @throws IllegalStateException
- * if the connection timed out due to thread interruption
- */
- public void connect(final long maxMsToWaitUntilConnected, Watcher watcher)
- throws ZkInterruptedException, ZkTimeoutException, IllegalStateException {
- if (isClosed()) {
- throw new IllegalStateException("ZkClient already closed!");
- }
- boolean started = false;
- acquireEventLock();
- try {
- setShutdownTrigger(false);
-
- IZkConnection zkConnection = getConnection();
- _eventThread = new ZkEventThread(zkConnection.getServers());
- _eventThread.start();
-
- if (isManagingZkConnection()) {
- zkConnection.connect(watcher);
- LOG.debug("Awaiting connection to Zookeeper server");
- if (!waitUntilConnected(maxMsToWaitUntilConnected, TimeUnit.MILLISECONDS)) {
- throw new ZkTimeoutException(
- "Unable to connect to zookeeper server within timeout: " + maxMsToWaitUntilConnected);
- }
- } else {
- // if the client is not managing connection, the input connection is supposed to connect.
- if (isConnectionClosed()) {
- throw new HelixException(
- "Unable to connect to zookeeper server with the specified ZkConnection");
- }
- // TODO Refine the init state here. Here we pre-config it to be connected. This may not be
- // the case, if the connection is connecting or recovering. -- JJ
- // For shared client, the event notification will not be forwarded before wather add to the
- // connection manager.
- setCurrentState(KeeperState.SyncConnected);
- }
-
- started = true;
- } finally {
- getEventLock().unlock();
-
- // we should close the zookeeper instance, otherwise it would keep
- // on trying to connect
- if (!started) {
- close();
- }
- }
- }
-
- public long getCreationTime(String path) {
- acquireEventLock();
- try {
- return getConnection().getCreateTime(path);
- } catch (KeeperException e) {
- throw ZkException.create(e);
- } catch (InterruptedException e) {
- throw new ZkInterruptedException(e);
- } finally {
- getEventLock().unlock();
- }
- }
-
- public String getServers() {
- return getConnection().getServers();
- }
-
- /**
- * Close the client.
- * @throws ZkInterruptedException
- */
- public void close() throws ZkInterruptedException {
- if (LOG.isTraceEnabled()) {
- StackTraceElement[] calls = Thread.currentThread().getStackTrace();
- LOG.trace("closing a zkclient. callStack: " + Arrays.asList(calls));
- }
- getEventLock().lock();
- IZkConnection connection = getConnection();
- try {
- if (connection == null || _closed) {
- return;
- }
- setShutdownTrigger(true);
- _eventThread.interrupt();
- _eventThread.join(2000);
- if (isManagingZkConnection()) {
- LOG.info("Closing zkclient: " + ((ZkConnection) connection).getZookeeper());
- connection.close();
- }
- _closed = true;
-
- // send state change notification to unlock any wait
- setCurrentState(null);
- getEventLock().getStateChangedCondition().signalAll();
-
- } catch (InterruptedException e) {
- /**
- * Workaround for HELIX-264: calling ZkClient#close() in its own eventThread context will
- * throw ZkInterruptedException and skip ZkConnection#close()
- */
- if (connection != null) {
- try {
- /**
- * ZkInterruptedException#construct() honors InterruptedException by calling
- * Thread.currentThread().interrupt(); clear it first, so we can safely close the
- * zk-connection
- */
- Thread.interrupted();
- if (isManagingZkConnection()) {
- connection.close();
- }
- /**
- * restore interrupted status of current thread
- */
- Thread.currentThread().interrupt();
- } catch (InterruptedException e1) {
- throw new ZkInterruptedException(e1);
- }
- }
- } finally {
- getEventLock().unlock();
- if (_monitor != null) {
- _monitor.unregister();
- }
- LOG.info("Closed zkclient");
- }
- }
-
- public boolean isClosed() {
- try {
- getEventLock().lock();
- return _closed;
- } finally {
- getEventLock().unlock();
- }
- }
-
- public boolean isConnectionClosed() {
- IZkConnection connection = getConnection();
- return (connection == null || connection.getZookeeperState() == null
- || !connection.getZookeeperState().isAlive());
- }
-
- public void setShutdownTrigger(boolean triggerState) {
- _shutdownTriggered = triggerState;
- }
-
- public boolean getShutdownTrigger() {
- return _shutdownTriggered;
- }
-
- public int numberOfListeners() {
- int listeners = 0;
- for (Set<IZkChildListener> childListeners : _childListener.values()) {
- listeners += childListeners.size();
- }
- for (Set<IZkDataListenerEntry> dataListeners : _dataListener.values()) {
- listeners += dataListeners.size();
- }
- listeners += _stateListener.size();
-
- return listeners;
- }
-
- public List<OpResult> multi(final Iterable<Op> ops) throws ZkException {
- if (ops == null) {
- throw new NullPointerException("ops must not be null.");
- }
-
- return retryUntilConnected(new Callable<List<OpResult>>() {
-
- @Override
- public List<OpResult> call() throws Exception {
- return getConnection().multi(ops);
- }
- });
- }
-
- /**
- * @return true if this ZkClient is managing the ZkConnection.
- */
- protected boolean isManagingZkConnection() {
- return true;
- }
-
- public long getSessionId() {
- ZkConnection zkConnection = ((ZkConnection) getConnection());
- ZooKeeper zk = zkConnection.getZookeeper();
- if (zk == null) {
- throw new HelixException(
- "ZooKeeper connection information is not available now. ZkClient might be disconnected.");
- } else {
- return zkConnection.getZookeeper().getSessionId();
- }
- }
-
- /*
- * Gets a session id in hexadecimal notation.
- * Ex. 1000a5ceb930004 is returned.
- */
- private String getHexSessionId() {
- return ZKUtil.toHexSessionId(getSessionId());
- }
-
- /*
- * Session aware operation needs below requirements:
- * 1. the session id is NOT null or empty
- * 2. create mode is EPHEMERAL or EPHEMERAL_SEQUENTIAL
- */
- private boolean isSessionAwareOperation(String expectedSessionId, CreateMode mode) {
- return expectedSessionId != null && !expectedSessionId.isEmpty()
- && (mode == CreateMode.EPHEMERAL || mode == CreateMode.EPHEMERAL_SEQUENTIAL);
- }
-
- // operations to update monitor's counters
- private void record(String path, byte[] data, long startTimeMilliSec,
- ZkClientMonitor.AccessType accessType) {
- if (_monitor != null) {
- int dataSize = (data != null) ? data.length : 0;
- _monitor.record(path, dataSize, startTimeMilliSec, accessType);
- }
- }
-
- private void recordFailure(String path, ZkClientMonitor.AccessType accessType) {
- if (_monitor != null) {
- _monitor.recordFailure(path, accessType);
- }
- }
-
- private void recordStateChange(boolean stateChanged, boolean dataChanged) {
- // update state change counter.
- if (_monitor != null) {
- if (stateChanged) {
- _monitor.increaseStateChangeEventCounter();
- }
- if (dataChanged) {
- _monitor.increaseDataChangeEventCounter();
- }
- }
- }
-
- /**
- * Creates a {@link org.apache.helix.manager.zk.zookeeper.IZkStateListener} that wraps a default
- * implementation of {@link org.I0Itec.zkclient.IZkStateListener}, which means the returned
- * listener runs the methods of {@link org.I0Itec.zkclient.IZkStateListener}.
- * This is for backward compatibility with {@link org.I0Itec.zkclient.IZkStateListener}.
- */
- private static class IZkStateListenerI0ItecImpl implements IZkStateListener {
- private org.I0Itec.zkclient.IZkStateListener _listener;
-
- IZkStateListenerI0ItecImpl(org.I0Itec.zkclient.IZkStateListener listener) {
- _listener = listener;
- }
-
- @Override
- public void handleStateChanged(Watcher.Event.KeeperState keeperState) throws Exception {
- _listener.handleStateChanged(keeperState);
- }
-
- @Override
- public void handleNewSession(final String sessionId) throws Exception {
- /*
- * org.I0Itec.zkclient.IZkStateListener does not have handleNewSession(sessionId),
- * so just call handleNewSession() by default.
- */
- _listener.handleNewSession();
- }
-
- @Override
- public void handleSessionEstablishmentError(Throwable error) throws Exception {
- _listener.handleSessionEstablishmentError(error);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == this) {
- return true;
- }
- if (!(obj instanceof IZkStateListenerI0ItecImpl)) {
- return false;
- }
- if (_listener == null) {
- return false;
- }
-
- IZkStateListenerI0ItecImpl defaultListener = (IZkStateListenerI0ItecImpl) obj;
-
- return _listener.equals(defaultListener._listener);
- }
-
- @Override
- public int hashCode() {
- /*
- * The original listener's hashcode helps find the wrapped listener with the same original
- * listener. This is helpful in unsubscribeStateChanges(listener) when finding the listener
- * to remove.
- */
- return _listener.hashCode();
- }
- }
-
- private void validateCurrentThread() {
- if (_zookeeperEventThread != null && Thread.currentThread() == _zookeeperEventThread) {
- throw new IllegalArgumentException("Must not be done in the zookeeper event thread.");
- }
+ super(zkConnection, connectionTimeout, operationRetryTimeout, zkSerializer, monitorType,
+ monitorKey, monitorInstanceName, monitorRootPathOnly);
}
}
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/zookeeper/ZkConnection.java b/helix-core/src/main/java/org/apache/helix/manager/zk/zookeeper/ZkConnection.java
index 07397ed..c623824 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/zookeeper/ZkConnection.java
+++ b/helix-core/src/main/java/org/apache/helix/manager/zk/zookeeper/ZkConnection.java
@@ -11,177 +11,17 @@
package org.apache.helix.manager.zk.zookeeper;
-import java.io.IOException;
-import java.util.List;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-
-import org.I0Itec.zkclient.IZkConnection;
-import org.I0Itec.zkclient.exception.ZkException;
-import org.apache.log4j.Logger;
-import org.apache.zookeeper.CreateMode;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.Op;
-import org.apache.zookeeper.OpResult;
-import org.apache.zookeeper.Watcher;
-import org.apache.zookeeper.ZooDefs.Ids;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.ZooKeeper.States;
-import org.apache.zookeeper.data.ACL;
-import org.apache.zookeeper.data.Stat;
-
-public class ZkConnection implements IZkConnection {
- private static final Logger LOG = Logger.getLogger(ZkConnection.class);
-
- /** It is recommended to use quite large sessions timeouts for ZooKeeper. */
- private static final int DEFAULT_SESSION_TIMEOUT = 30000;
-
- private ZooKeeper _zk = null;
- private Lock _zookeeperLock = new ReentrantLock();
-
- private final String _servers;
- private final int _sessionTimeOut;
+/**
+ * Use ZkConnection in zookeeper-api module instead.
+ */
+@Deprecated
+public class ZkConnection extends org.apache.helix.zookeeper.zkclient.ZkConnection {
public ZkConnection(String zkServers) {
- this(zkServers, DEFAULT_SESSION_TIMEOUT);
+ super(zkServers);
}
public ZkConnection(String zkServers, int sessionTimeOut) {
- _servers = zkServers;
- _sessionTimeOut = sessionTimeOut;
- }
-
- @Override
- public void connect(Watcher watcher) {
- _zookeeperLock.lock();
- try {
- if (_zk != null) {
- throw new IllegalStateException("zk client has already been started");
- }
- try {
- LOG.debug("Creating new ZookKeeper instance to connect to " + _servers + ".");
- _zk = new ZooKeeper(_servers, _sessionTimeOut, watcher);
- } catch (IOException e) {
- throw new ZkException("Unable to connect to " + _servers, e);
- }
- } finally {
- _zookeeperLock.unlock();
- }
- }
-
- @Override
- public void close() throws InterruptedException {
- _zookeeperLock.lock();
- try {
- if (_zk != null) {
- LOG.debug("Closing ZooKeeper connected to " + _servers);
- _zk.close();
- _zk = null;
- }
- } finally {
- _zookeeperLock.unlock();
- }
- }
-
- protected void reconnect(Watcher watcher) throws InterruptedException {
- _zookeeperLock.lock();
- try {
- if (_zk == null) {
- throw new IllegalStateException("zk client has not been connected or already been closed");
- }
- ZooKeeper prevZk = _zk;
- try {
- LOG.debug("Creating new ZookKeeper instance to reconnect to " + _servers + ".");
- _zk = new ZooKeeper(_servers, _sessionTimeOut, watcher);
- prevZk.close();
- } catch (IOException e) {
- throw new ZkException("Unable to connect to " + _servers, e);
- }
- } finally {
- _zookeeperLock.unlock();
- }
- }
-
- @Override
- public String create(String path, byte[] data, CreateMode mode)
- throws KeeperException, InterruptedException {
- return _zk.create(path, data, Ids.OPEN_ACL_UNSAFE, mode);
- }
-
- @Override
- public String create(String path, byte[] data, List<ACL> acl, CreateMode mode)
- throws KeeperException, InterruptedException {
- return _zk.create(path, data, acl, mode);
- }
-
- @Override
- public void delete(String path) throws InterruptedException, KeeperException {
- _zk.delete(path, -1);
- }
-
- @Override
- public boolean exists(String path, boolean watch) throws KeeperException, InterruptedException {
- return _zk.exists(path, watch) != null;
- }
-
- @Override
- public List<String> getChildren(final String path, final boolean watch)
- throws KeeperException, InterruptedException {
- return _zk.getChildren(path, watch);
- }
-
- @Override
- public byte[] readData(String path, Stat stat, boolean watch)
- throws KeeperException, InterruptedException {
- return _zk.getData(path, watch, stat);
- }
-
- public void writeData(String path, byte[] data) throws KeeperException, InterruptedException {
- writeData(path, data, -1);
- }
-
- @Override
- public void writeData(String path, byte[] data, int version)
- throws KeeperException, InterruptedException {
- _zk.setData(path, data, version);
- }
-
- @Override
- public Stat writeDataReturnStat(String path, byte[] data, int version)
- throws KeeperException, InterruptedException {
- return _zk.setData(path, data, version);
- }
-
- @Override
- public States getZookeeperState() {
- return _zk != null ? _zk.getState() : null;
- }
-
- public ZooKeeper getZookeeper() {
- return _zk;
- }
-
- @Override
- public long getCreateTime(String path) throws KeeperException, InterruptedException {
- Stat stat = _zk.exists(path, false);
- if (stat != null) {
- return stat.getCtime();
- }
- return -1;
- }
-
- @Override
- public String getServers() {
- return _servers;
- }
-
- @Override
- public List<OpResult> multi(Iterable<Op> ops) throws KeeperException, InterruptedException {
- return _zk.multi(ops);
- }
-
- @Override
- public void addAuthInfo(String scheme, byte[] auth) {
- _zk.addAuthInfo(scheme, auth);
+ super(zkServers, sessionTimeOut);
}
}
diff --git a/helix-core/src/main/java/org/apache/helix/messaging/ZNRecordRow.java b/helix-core/src/main/java/org/apache/helix/messaging/ZNRecordRow.java
index 5a2effd..d1289aa 100644
--- a/helix-core/src/main/java/org/apache/helix/messaging/ZNRecordRow.java
+++ b/helix-core/src/main/java/org/apache/helix/messaging/ZNRecordRow.java
@@ -25,7 +25,7 @@
import java.util.List;
import java.util.Map;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
/**
* A Normalized form of ZNRecord
diff --git a/helix-core/src/main/java/org/apache/helix/messaging/handling/HelixStateTransitionHandler.java b/helix-core/src/main/java/org/apache/helix/messaging/handling/HelixStateTransitionHandler.java
index 316284b..7229bc7 100644
--- a/helix-core/src/main/java/org/apache/helix/messaging/handling/HelixStateTransitionHandler.java
+++ b/helix-core/src/main/java/org/apache/helix/messaging/handling/HelixStateTransitionHandler.java
@@ -38,10 +38,10 @@
import org.apache.helix.NotificationContext.MapKey;
import org.apache.helix.PropertyKey;
import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.ZNRecordBucketizer;
-import org.apache.helix.ZNRecordDelta;
-import org.apache.helix.ZNRecordDelta.MergeOperation;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecordBucketizer;
+import org.apache.helix.zookeeper.datamodel.ZNRecordDelta;
+import org.apache.helix.zookeeper.datamodel.ZNRecordDelta.MergeOperation;
import org.apache.helix.model.CurrentState;
import org.apache.helix.model.Message;
import org.apache.helix.model.Message.Attributes;
diff --git a/helix-core/src/main/java/org/apache/helix/model/AlertHistory.java b/helix-core/src/main/java/org/apache/helix/model/AlertHistory.java
index 58db71d..ccfcb8c 100644
--- a/helix-core/src/main/java/org/apache/helix/model/AlertHistory.java
+++ b/helix-core/src/main/java/org/apache/helix/model/AlertHistory.java
@@ -19,7 +19,7 @@
* under the License.
*/
import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
/**
* Maintains a history of alerts that have been fired, as well as actions taken, if any.
diff --git a/helix-core/src/main/java/org/apache/helix/model/AlertStatus.java b/helix-core/src/main/java/org/apache/helix/model/AlertStatus.java
index d90ec1a..e6c1e99 100644
--- a/helix-core/src/main/java/org/apache/helix/model/AlertStatus.java
+++ b/helix-core/src/main/java/org/apache/helix/model/AlertStatus.java
@@ -22,7 +22,7 @@
import java.util.Map;
import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.model.Alerts.AlertsProperty;
/**
diff --git a/helix-core/src/main/java/org/apache/helix/model/Alerts.java b/helix-core/src/main/java/org/apache/helix/model/Alerts.java
index 506e3d5..e32efb3 100644
--- a/helix-core/src/main/java/org/apache/helix/model/Alerts.java
+++ b/helix-core/src/main/java/org/apache/helix/model/Alerts.java
@@ -22,7 +22,7 @@
import java.util.Map;
import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
/**
* Describe alerts and corresponding metrics. An alert is triggered when cluster health
diff --git a/helix-core/src/main/java/org/apache/helix/model/ClusterConfig.java b/helix-core/src/main/java/org/apache/helix/model/ClusterConfig.java
index f88d2f5..165919c 100644
--- a/helix-core/src/main/java/org/apache/helix/model/ClusterConfig.java
+++ b/helix-core/src/main/java/org/apache/helix/model/ClusterConfig.java
@@ -30,7 +30,7 @@
import com.google.common.collect.Maps;
import org.apache.helix.HelixException;
import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.api.config.HelixConfigProperty;
import org.apache.helix.api.config.StateTransitionThrottleConfig;
import org.apache.helix.api.config.StateTransitionTimeoutConfig;
diff --git a/helix-core/src/main/java/org/apache/helix/model/ClusterConstraints.java b/helix-core/src/main/java/org/apache/helix/model/ClusterConstraints.java
index 520f17d..12beabe 100644
--- a/helix-core/src/main/java/org/apache/helix/model/ClusterConstraints.java
+++ b/helix-core/src/main/java/org/apache/helix/model/ClusterConstraints.java
@@ -26,7 +26,7 @@
import java.util.TreeMap;
import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.model.Message.MessageType;
import org.apache.helix.model.builder.ConstraintItemBuilder;
import org.slf4j.Logger;
diff --git a/helix-core/src/main/java/org/apache/helix/model/ControllerHistory.java b/helix-core/src/main/java/org/apache/helix/model/ControllerHistory.java
index 955a5bf..a76a957 100644
--- a/helix-core/src/main/java/org/apache/helix/model/ControllerHistory.java
+++ b/helix-core/src/main/java/org/apache/helix/model/ControllerHistory.java
@@ -30,7 +30,7 @@
import java.util.TimeZone;
import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.codehaus.jackson.map.ObjectMapper;
/**
diff --git a/helix-core/src/main/java/org/apache/helix/model/CurrentState.java b/helix-core/src/main/java/org/apache/helix/model/CurrentState.java
index c227060..0bc9052 100644
--- a/helix-core/src/main/java/org/apache/helix/model/CurrentState.java
+++ b/helix-core/src/main/java/org/apache/helix/model/CurrentState.java
@@ -24,7 +24,7 @@
import java.util.TreeMap;
import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/model/Error.java b/helix-core/src/main/java/org/apache/helix/model/Error.java
index 7744b91..a64905e 100644
--- a/helix-core/src/main/java/org/apache/helix/model/Error.java
+++ b/helix-core/src/main/java/org/apache/helix/model/Error.java
@@ -20,7 +20,7 @@
*/
import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
/**
* Defines an error that occurs in computing a valid ideal state or external view
diff --git a/helix-core/src/main/java/org/apache/helix/model/ExternalView.java b/helix-core/src/main/java/org/apache/helix/model/ExternalView.java
index efe6b4d..7ae9e34 100644
--- a/helix-core/src/main/java/org/apache/helix/model/ExternalView.java
+++ b/helix-core/src/main/java/org/apache/helix/model/ExternalView.java
@@ -24,7 +24,7 @@
import java.util.TreeMap;
import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
/**
* External view is an aggregation (across all instances)
diff --git a/helix-core/src/main/java/org/apache/helix/model/HealthStat.java b/helix-core/src/main/java/org/apache/helix/model/HealthStat.java
index b8ac32f..f1fee8c 100644
--- a/helix-core/src/main/java/org/apache/helix/model/HealthStat.java
+++ b/helix-core/src/main/java/org/apache/helix/model/HealthStat.java
@@ -24,7 +24,7 @@
import java.util.Map;
import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.model.Message.Attributes;
/**
diff --git a/helix-core/src/main/java/org/apache/helix/model/IdealState.java b/helix-core/src/main/java/org/apache/helix/model/IdealState.java
index 3908a95..f41bc2c 100644
--- a/helix-core/src/main/java/org/apache/helix/model/IdealState.java
+++ b/helix-core/src/main/java/org/apache/helix/model/IdealState.java
@@ -29,7 +29,6 @@
import org.apache.helix.HelixConstants;
import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
import org.apache.helix.controller.rebalancer.Rebalancer;
import org.apache.helix.model.ResourceConfig.ResourceConfigProperty;
import org.apache.helix.task.FixedTargetTaskRebalancer;
@@ -37,6 +36,7 @@
import org.apache.helix.task.JobRebalancer;
import org.apache.helix.task.TaskRebalancer;
import org.apache.helix.task.WorkflowRebalancer;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/model/InstanceConfig.java b/helix-core/src/main/java/org/apache/helix/model/InstanceConfig.java
index b55ba83..24e6154 100644
--- a/helix-core/src/main/java/org/apache/helix/model/InstanceConfig.java
+++ b/helix-core/src/main/java/org/apache/helix/model/InstanceConfig.java
@@ -32,8 +32,8 @@
import com.google.common.base.Splitter;
import org.apache.helix.HelixException;
import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
import org.apache.helix.util.HelixUtil;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/model/LeaderStandbySMD.java b/helix-core/src/main/java/org/apache/helix/model/LeaderStandbySMD.java
index 092f8ba..5d98d23 100644
--- a/helix-core/src/main/java/org/apache/helix/model/LeaderStandbySMD.java
+++ b/helix-core/src/main/java/org/apache/helix/model/LeaderStandbySMD.java
@@ -25,7 +25,7 @@
import java.util.Map;
import org.apache.helix.HelixDefinedState;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
/**
* Helix built-in Leader-standby state model definition
diff --git a/helix-core/src/main/java/org/apache/helix/model/LiveInstance.java b/helix-core/src/main/java/org/apache/helix/model/LiveInstance.java
index f9a5d6a..74260cc 100644
--- a/helix-core/src/main/java/org/apache/helix/model/LiveInstance.java
+++ b/helix-core/src/main/java/org/apache/helix/model/LiveInstance.java
@@ -22,7 +22,7 @@
import java.util.Map;
import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/model/MaintenanceSignal.java b/helix-core/src/main/java/org/apache/helix/model/MaintenanceSignal.java
index 511e6f3..6a30525 100644
--- a/helix-core/src/main/java/org/apache/helix/model/MaintenanceSignal.java
+++ b/helix-core/src/main/java/org/apache/helix/model/MaintenanceSignal.java
@@ -19,7 +19,7 @@
* under the License.
*/
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
/**
* A ZNode that signals that the cluster is in maintenance mode.
diff --git a/helix-core/src/main/java/org/apache/helix/model/MasterSlaveSMD.java b/helix-core/src/main/java/org/apache/helix/model/MasterSlaveSMD.java
index f2eca27..45f63a3 100644
--- a/helix-core/src/main/java/org/apache/helix/model/MasterSlaveSMD.java
+++ b/helix-core/src/main/java/org/apache/helix/model/MasterSlaveSMD.java
@@ -25,7 +25,7 @@
import java.util.Map;
import org.apache.helix.HelixDefinedState;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
/**
* Helix built-in Master-slave state model definition
diff --git a/helix-core/src/main/java/org/apache/helix/model/Message.java b/helix-core/src/main/java/org/apache/helix/model/Message.java
index 6317af1..eefecec 100644
--- a/helix-core/src/main/java/org/apache/helix/model/Message.java
+++ b/helix-core/src/main/java/org/apache/helix/model/Message.java
@@ -36,7 +36,7 @@
import org.apache.helix.InstanceType;
import org.apache.helix.PropertyKey;
import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
/**
* Messages sent internally among nodes in the system to respond to changes in state.
diff --git a/helix-core/src/main/java/org/apache/helix/model/OnlineOfflineSMD.java b/helix-core/src/main/java/org/apache/helix/model/OnlineOfflineSMD.java
index 56c477d..4e0d968 100644
--- a/helix-core/src/main/java/org/apache/helix/model/OnlineOfflineSMD.java
+++ b/helix-core/src/main/java/org/apache/helix/model/OnlineOfflineSMD.java
@@ -25,7 +25,7 @@
import java.util.Map;
import org.apache.helix.HelixDefinedState;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
/**
* Helix built-in Online-offline state model definition
diff --git a/helix-core/src/main/java/org/apache/helix/model/ParticipantHistory.java b/helix-core/src/main/java/org/apache/helix/model/ParticipantHistory.java
index 6e5a8c6..c17d172 100644
--- a/helix-core/src/main/java/org/apache/helix/model/ParticipantHistory.java
+++ b/helix-core/src/main/java/org/apache/helix/model/ParticipantHistory.java
@@ -29,7 +29,7 @@
import java.util.TimeZone;
import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/model/PauseSignal.java b/helix-core/src/main/java/org/apache/helix/model/PauseSignal.java
index ed89e9a..80a2aa7 100644
--- a/helix-core/src/main/java/org/apache/helix/model/PauseSignal.java
+++ b/helix-core/src/main/java/org/apache/helix/model/PauseSignal.java
@@ -20,7 +20,7 @@
*/
import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
/**
* Represent a pause in the cluster
diff --git a/helix-core/src/main/java/org/apache/helix/model/PersistentStats.java b/helix-core/src/main/java/org/apache/helix/model/PersistentStats.java
index 8f0cb69..b61e413 100644
--- a/helix-core/src/main/java/org/apache/helix/model/PersistentStats.java
+++ b/helix-core/src/main/java/org/apache/helix/model/PersistentStats.java
@@ -22,7 +22,7 @@
import java.util.Map;
import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/model/RESTConfig.java b/helix-core/src/main/java/org/apache/helix/model/RESTConfig.java
index 7e7cb22..b42b208 100644
--- a/helix-core/src/main/java/org/apache/helix/model/RESTConfig.java
+++ b/helix-core/src/main/java/org/apache/helix/model/RESTConfig.java
@@ -1,7 +1,7 @@
package org.apache.helix.model;
import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
/**
diff --git a/helix-core/src/main/java/org/apache/helix/model/ResourceAssignment.java b/helix-core/src/main/java/org/apache/helix/model/ResourceAssignment.java
index b9f6a15..756f373 100644
--- a/helix-core/src/main/java/org/apache/helix/model/ResourceAssignment.java
+++ b/helix-core/src/main/java/org/apache/helix/model/ResourceAssignment.java
@@ -25,7 +25,7 @@
import java.util.Map;
import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
/**
* Represents the assignments of replicas for an entire resource, keyed on partitions of the
diff --git a/helix-core/src/main/java/org/apache/helix/model/ResourceConfig.java b/helix-core/src/main/java/org/apache/helix/model/ResourceConfig.java
index 9cdb673..f4d8b2b 100644
--- a/helix-core/src/main/java/org/apache/helix/model/ResourceConfig.java
+++ b/helix-core/src/main/java/org/apache/helix/model/ResourceConfig.java
@@ -27,7 +27,7 @@
import java.util.TreeMap;
import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.api.config.HelixConfigProperty;
import org.apache.helix.api.config.RebalanceConfig;
import org.apache.helix.api.config.StateTransitionTimeoutConfig;
diff --git a/helix-core/src/main/java/org/apache/helix/model/ScheduledTaskSMD.java b/helix-core/src/main/java/org/apache/helix/model/ScheduledTaskSMD.java
index c85e5dd..c267f16 100644
--- a/helix-core/src/main/java/org/apache/helix/model/ScheduledTaskSMD.java
+++ b/helix-core/src/main/java/org/apache/helix/model/ScheduledTaskSMD.java
@@ -25,7 +25,7 @@
import java.util.Map;
import org.apache.helix.HelixDefinedState;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.manager.zk.DefaultSchedulerMessageHandlerFactory;
import org.apache.helix.model.builder.StateTransitionTableBuilder;
diff --git a/helix-core/src/main/java/org/apache/helix/model/StateModelDefinition.java b/helix-core/src/main/java/org/apache/helix/model/StateModelDefinition.java
index 0a40331..9a24816 100644
--- a/helix-core/src/main/java/org/apache/helix/model/StateModelDefinition.java
+++ b/helix-core/src/main/java/org/apache/helix/model/StateModelDefinition.java
@@ -32,9 +32,10 @@
import org.apache.helix.HelixDefinedState;
import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
import org.apache.helix.model.builder.StateTransitionTableBuilder;
import org.apache.helix.model.util.StateModelDefinitionValidator;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+
/**
* Describe the state model
diff --git a/helix-core/src/main/java/org/apache/helix/model/StatusUpdate.java b/helix-core/src/main/java/org/apache/helix/model/StatusUpdate.java
index f4857ee..8f162e3 100644
--- a/helix-core/src/main/java/org/apache/helix/model/StatusUpdate.java
+++ b/helix-core/src/main/java/org/apache/helix/model/StatusUpdate.java
@@ -20,7 +20,7 @@
*/
import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
/**
* Wraps updates to Helix constructs, e.g. state transitions and controller task statuses
diff --git a/helix-core/src/main/java/org/apache/helix/model/StorageSchemataSMD.java b/helix-core/src/main/java/org/apache/helix/model/StorageSchemataSMD.java
index 46d54a9..d9dad7e 100644
--- a/helix-core/src/main/java/org/apache/helix/model/StorageSchemataSMD.java
+++ b/helix-core/src/main/java/org/apache/helix/model/StorageSchemataSMD.java
@@ -25,7 +25,7 @@
import java.util.Map;
import org.apache.helix.HelixDefinedState;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
/**
* Helix built-in StorageSchemata state model definition
diff --git a/helix-core/src/main/java/org/apache/helix/model/TaskSMD.java b/helix-core/src/main/java/org/apache/helix/model/TaskSMD.java
index 33b62e7..6f8f1e9 100644
--- a/helix-core/src/main/java/org/apache/helix/model/TaskSMD.java
+++ b/helix-core/src/main/java/org/apache/helix/model/TaskSMD.java
@@ -24,7 +24,7 @@
import java.util.List;
import java.util.Map;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.model.builder.StateTransitionTableBuilder;
import org.apache.helix.task.TaskConstants;
import org.apache.helix.task.TaskPartitionState;
diff --git a/helix-core/src/main/java/org/apache/helix/model/builder/IdealStateBuilder.java b/helix-core/src/main/java/org/apache/helix/model/builder/IdealStateBuilder.java
index 4701181..1fd3916 100644
--- a/helix-core/src/main/java/org/apache/helix/model/builder/IdealStateBuilder.java
+++ b/helix-core/src/main/java/org/apache/helix/model/builder/IdealStateBuilder.java
@@ -21,7 +21,7 @@
import org.apache.helix.HelixConstants;
import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.model.IdealState;
public abstract class IdealStateBuilder {
diff --git a/helix-core/src/main/java/org/apache/helix/monitoring/ZKPathDataDumpTask.java b/helix-core/src/main/java/org/apache/helix/monitoring/ZKPathDataDumpTask.java
index c0d6285..1028b85 100644
--- a/helix-core/src/main/java/org/apache/helix/monitoring/ZKPathDataDumpTask.java
+++ b/helix-core/src/main/java/org/apache/helix/monitoring/ZKPathDataDumpTask.java
@@ -28,7 +28,7 @@
import org.apache.helix.HelixManager;
import org.apache.helix.PropertyKey.Builder;
import org.apache.helix.PropertyPathBuilder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.manager.zk.ZNRecordSerializer;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
diff --git a/helix-core/src/main/java/org/apache/helix/monitoring/mbeans/ZkClientMonitor.java b/helix-core/src/main/java/org/apache/helix/monitoring/mbeans/ZkClientMonitor.java
index 61b574c..f76a459 100644
--- a/helix-core/src/main/java/org/apache/helix/monitoring/mbeans/ZkClientMonitor.java
+++ b/helix-core/src/main/java/org/apache/helix/monitoring/mbeans/ZkClientMonitor.java
@@ -19,231 +19,16 @@
* under the License.
*/
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import javax.management.JMException;
-import javax.management.MBeanAttributeInfo;
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
+import org.apache.helix.zookeeper.zkclient.ZkEventThread;
-import org.apache.helix.HelixException;
-import org.apache.helix.manager.zk.zookeeper.ZkEventThread;
-import org.apache.helix.monitoring.mbeans.dynamicMBeans.DynamicMBeanProvider;
-import org.apache.helix.monitoring.mbeans.dynamicMBeans.DynamicMetric;
-import org.apache.helix.monitoring.mbeans.dynamicMBeans.SimpleDynamicMetric;
-
-public class ZkClientMonitor extends DynamicMBeanProvider {
- public static final String MONITOR_TYPE = "Type";
- public static final String MONITOR_KEY = "Key";
- protected static final String MBEAN_DESCRIPTION = "Helix Zookeeper Client Monitor";
-
- public enum AccessType {
- READ, WRITE
- }
-
- private String _sensorName;
- private String _monitorType;
- private String _monitorKey;
- private String _monitorInstanceName;
- private boolean _monitorRootOnly;
-
- private SimpleDynamicMetric<Long> _stateChangeEventCounter;
- private SimpleDynamicMetric<Long> _dataChangeEventCounter;
- private SimpleDynamicMetric<Long> _outstandingRequestGauge;
-
- private ZkThreadMetric _zkEventThreadMetric;
-
- private Map<ZkClientPathMonitor.PredefinedPath, ZkClientPathMonitor> _zkClientPathMonitorMap =
- new ConcurrentHashMap<>();
-
+/**
+ * Use ZkClientMonitor in zookeeper-api module instead.
+ */
+@Deprecated
+public class ZkClientMonitor
+ extends org.apache.helix.zookeeper.zkclient.metric.ZkClientMonitor {
public ZkClientMonitor(String monitorType, String monitorKey, String monitorInstanceName,
boolean monitorRootOnly, ZkEventThread zkEventThread) {
- if (monitorKey == null || monitorKey.isEmpty() || monitorType == null || monitorType
- .isEmpty()) {
- throw new HelixException("Cannot create ZkClientMonitor without monitor key and type.");
- }
-
- _sensorName =
- String.format("%s.%s.%s", MonitorDomainNames.HelixZkClient.name(), monitorType, monitorKey);
- _monitorType = monitorType;
- _monitorKey = monitorKey;
- _monitorInstanceName = monitorInstanceName;
- _monitorRootOnly = monitorRootOnly;
-
- _stateChangeEventCounter = new SimpleDynamicMetric("StateChangeEventCounter", 0l);
- _dataChangeEventCounter = new SimpleDynamicMetric("DataChangeEventCounter", 0l);
- _outstandingRequestGauge = new SimpleDynamicMetric("OutstandingRequestGauge", 0l);
- if (zkEventThread != null) {
- _zkEventThreadMetric = new ZkThreadMetric(zkEventThread);
- }
- }
-
- protected static ObjectName getObjectName(String monitorType, String monitorKey,
- String monitorInstanceName) throws MalformedObjectNameException {
- return MBeanRegistrar
- .buildObjectName(MonitorDomainNames.HelixZkClient.name(), MONITOR_TYPE, monitorType,
- MONITOR_KEY,
- (monitorKey + (monitorInstanceName == null ? "" : "." + monitorInstanceName)));
- }
-
- @Override
- public DynamicMBeanProvider register() throws JMException {
- List<DynamicMetric<?, ?>> attributeList = new ArrayList<>();
- attributeList.add(_dataChangeEventCounter);
- attributeList.add(_outstandingRequestGauge);
- attributeList.add(_stateChangeEventCounter);
- if (_zkEventThreadMetric != null) {
- attributeList.add(_zkEventThreadMetric);
- }
- doRegister(attributeList, MBEAN_DESCRIPTION,
- getObjectName(_monitorType, _monitorKey, _monitorInstanceName));
- for (ZkClientPathMonitor.PredefinedPath path : ZkClientPathMonitor.PredefinedPath.values()) {
- // If monitor root path only, check if the current path is Root.
- // Otherwise, add monitors for every path.
- if (!_monitorRootOnly || path.equals(ZkClientPathMonitor.PredefinedPath.Root)) {
- _zkClientPathMonitorMap.put(path,
- new ZkClientPathMonitor(path, _monitorType, _monitorKey, _monitorInstanceName)
- .register());
- }
- }
- return this;
- }
-
- /**
- * After unregistered, the MBean can't be registered again, a new monitor has be to created.
- */
- public void unregister() {
- super.unregister();
- for (ZkClientPathMonitor zkClientPathMonitor : _zkClientPathMonitorMap.values()) {
- zkClientPathMonitor.unregister();
- }
- }
-
- @Override
- public String getSensorName() {
- return _sensorName;
- }
-
- public void increaseStateChangeEventCounter() {
- synchronized (_stateChangeEventCounter) {
- _stateChangeEventCounter.updateValue(_stateChangeEventCounter.getValue() + 1);
- }
- }
-
- public void increaseDataChangeEventCounter() {
- synchronized (_dataChangeEventCounter) {
- _dataChangeEventCounter.updateValue(_dataChangeEventCounter.getValue() + 1);
- }
- }
-
- public void increaseOutstandingRequestGauge() {
- synchronized (_outstandingRequestGauge) {
- _outstandingRequestGauge.updateValue(_outstandingRequestGauge.getValue() + 1);
- }
- }
-
- public void decreaseOutstandingRequestGauge() {
- synchronized (_outstandingRequestGauge) {
- _outstandingRequestGauge.updateValue(_outstandingRequestGauge.getValue() - 1);
- }
- }
-
- public void recordDataPropagationLatency(String path, long latencyMilliSec) {
- if (null == path) {
- return;
- }
- Arrays.stream(ZkClientPathMonitor.PredefinedPath.values())
- .filter(predefinedPath -> predefinedPath.match(path))
- .forEach(predefinedPath -> {
- ZkClientPathMonitor zkClientPathMonitor = _zkClientPathMonitorMap.get(predefinedPath);
- if (zkClientPathMonitor != null) {
- zkClientPathMonitor.recordDataPropagationLatency(latencyMilliSec);
- }
- });
- }
-
- private void record(String path, int bytes, long latencyMilliSec, boolean isFailure,
- boolean isRead) {
- if (null == path) {
- return;
- }
- Arrays.stream(ZkClientPathMonitor.PredefinedPath.values())
- .filter(predefinedPath -> predefinedPath.match(path))
- .forEach(predefinedPath -> {
- ZkClientPathMonitor zkClientPathMonitor = _zkClientPathMonitorMap.get(predefinedPath);
- if (zkClientPathMonitor != null) {
- zkClientPathMonitor.record(bytes, latencyMilliSec, isFailure, isRead);
- }
- });
- }
-
- public void record(String path, int dataSize, long startTimeMilliSec, AccessType accessType) {
- switch (accessType) {
- case READ:
- record(path, dataSize, System.currentTimeMillis() - startTimeMilliSec, false, true);
- return;
- case WRITE:
- record(path, dataSize, System.currentTimeMillis() - startTimeMilliSec, false, false);
- return;
- default:
- return;
- }
- }
-
- public void recordFailure(String path, AccessType accessType) {
- switch (accessType) {
- case READ:
- record(path, 0, 0, true, true);
- return;
- case WRITE:
- record(path, 0, 0, true, false);
- return;
- default:
- return;
- }
- }
-
- class ZkThreadMetric extends DynamicMetric<ZkEventThread, ZkEventThread> {
- public ZkThreadMetric(ZkEventThread eventThread) {
- super("ZkEventThead", eventThread);
- }
-
- @Override
- protected Set<MBeanAttributeInfo> generateAttributeInfos(String metricName,
- ZkEventThread eventThread) {
- Set<MBeanAttributeInfo> attributeInfoSet = new HashSet<>();
- attributeInfoSet.add(new MBeanAttributeInfo("PendingCallbackGauge", Long.TYPE.getName(),
- DEFAULT_ATTRIBUTE_DESCRIPTION, true, false, false));
- attributeInfoSet.add(new MBeanAttributeInfo("TotalCallbackCounter", Long.TYPE.getName(),
- DEFAULT_ATTRIBUTE_DESCRIPTION, true, false, false));
- attributeInfoSet.add(
- new MBeanAttributeInfo("TotalCallbackHandledCounter", Long.TYPE.getName(),
- DEFAULT_ATTRIBUTE_DESCRIPTION, true, false, false));
- return attributeInfoSet;
- }
-
- @Override
- public Object getAttributeValue(String attributeName) {
- switch (attributeName) {
- case "PendingCallbackGauge":
- return getMetricObject().getPendingEventsCount();
- case "TotalCallbackCounter":
- return getMetricObject().getTotalEventCount();
- case "TotalCallbackHandledCounter":
- return getMetricObject().getTotalHandledEventCount();
- default:
- throw new HelixException("Unknown attribute name: " + attributeName);
- }
- }
-
- @Override
- public void updateValue(ZkEventThread newEventThread) {
- setMetricObject(newEventThread);
- }
+ super(monitorType, monitorKey, monitorInstanceName, monitorRootOnly, zkEventThread);
}
}
diff --git a/helix-core/src/main/java/org/apache/helix/monitoring/mbeans/ZkClientPathMonitor.java b/helix-core/src/main/java/org/apache/helix/monitoring/mbeans/ZkClientPathMonitor.java
index 1795243..6b8d642 100644
--- a/helix-core/src/main/java/org/apache/helix/monitoring/mbeans/ZkClientPathMonitor.java
+++ b/helix-core/src/main/java/org/apache/helix/monitoring/mbeans/ZkClientPathMonitor.java
@@ -19,228 +19,14 @@
* under the License.
*/
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-import javax.management.JMException;
-import javax.management.ObjectName;
-
-import com.codahale.metrics.Histogram;
-import com.codahale.metrics.SlidingTimeWindowArrayReservoir;
-import org.apache.helix.monitoring.mbeans.dynamicMBeans.DynamicMBeanProvider;
-import org.apache.helix.monitoring.mbeans.dynamicMBeans.DynamicMetric;
-import org.apache.helix.monitoring.mbeans.dynamicMBeans.HistogramDynamicMetric;
-import org.apache.helix.monitoring.mbeans.dynamicMBeans.SimpleDynamicMetric;
-
-public class ZkClientPathMonitor extends DynamicMBeanProvider {
- public static final String MONITOR_PATH = "PATH";
- private final String _sensorName;
- private final String _type;
- private final String _key;
- private final String _instanceName;
- private final PredefinedPath _path;
-
- public enum PredefinedPath {
- IdealStates(".*/IDEALSTATES/.*"),
- Instances(".*/INSTANCES/.*"),
- Configs(".*/CONFIGS/.*"),
- Controller(".*/CONTROLLER/.*"),
- ExternalView(".*/EXTERNALVIEW/.*"),
- LiveInstances(".*/LIVEINSTANCES/.*"),
- PropertyStore(".*/PROPERTYSTORE/.*"),
- CurrentStates(".*/CURRENTSTATES/.*"),
- Messages(".*/MESSAGES/.*"),
- Root(".*");
-
- private final String _matchString;
-
- PredefinedPath(String matchString) {
- _matchString = matchString;
- }
-
- public boolean match(String path) {
- return path.matches(this._matchString);
- }
- }
-
- public enum PredefinedMetricDomains {
- WriteTotalLatencyCounter,
- ReadTotalLatencyCounter,
- WriteFailureCounter,
- ReadFailureCounter,
- WriteBytesCounter,
- ReadBytesCounter,
- WriteCounter,
- ReadCounter,
- ReadLatencyGauge,
- WriteLatencyGauge,
- ReadBytesGauge,
- WriteBytesGauge,
- /*
- * The latency between a ZK data change happening on the server side and the client side.
- */
- DataPropagationLatencyGauge,
- /**
- * @deprecated
- * This domain name has a typo. Keep it in case its historical metric data is being used.
- */
- @Deprecated
- DataPropagationLatencyGuage
- }
-
- private SimpleDynamicMetric<Long> _readCounter;
- private SimpleDynamicMetric<Long> _writeCounter;
- private SimpleDynamicMetric<Long> _readBytesCounter;
- private SimpleDynamicMetric<Long> _writeBytesCounter;
- private SimpleDynamicMetric<Long> _readFailureCounter;
- private SimpleDynamicMetric<Long> _writeFailureCounter;
- private SimpleDynamicMetric<Long> _readTotalLatencyCounter;
- private SimpleDynamicMetric<Long> _writeTotalLatencyCounter;
-
- private HistogramDynamicMetric _readLatencyGauge;
- private HistogramDynamicMetric _writeLatencyGauge;
- private HistogramDynamicMetric _readBytesGauge;
- private HistogramDynamicMetric _writeBytesGauge;
- private HistogramDynamicMetric _dataPropagationLatencyGauge;
-
- /**
- * @deprecated
- * Keep it for backward-compatibility purpose.
- */
- @Deprecated
- private HistogramDynamicMetric _dataPropagationLatencyGuage;
-
- @Override
- public String getSensorName() {
- return _sensorName;
- }
-
+/**
+ * Use ZkClientPathMonitor in zookeeper-api module instead.
+ */
+@Deprecated
+public class ZkClientPathMonitor
+ extends org.apache.helix.zookeeper.zkclient.metric.ZkClientPathMonitor {
public ZkClientPathMonitor(PredefinedPath path, String monitorType, String monitorKey,
String monitorInstanceName) {
- _type = monitorType;
- _key = monitorKey;
- _instanceName = monitorInstanceName;
- _path = path;
- _sensorName = String
- .format("%s.%s.%s.%s", MonitorDomainNames.HelixZkClient.name(), monitorType, monitorKey,
- path.name());
-
- _writeTotalLatencyCounter =
- new SimpleDynamicMetric(PredefinedMetricDomains.WriteTotalLatencyCounter.name(), 0l);
- _readTotalLatencyCounter =
- new SimpleDynamicMetric(PredefinedMetricDomains.ReadTotalLatencyCounter.name(), 0l);
- _writeFailureCounter =
- new SimpleDynamicMetric(PredefinedMetricDomains.WriteFailureCounter.name(), 0l);
- _readFailureCounter =
- new SimpleDynamicMetric(PredefinedMetricDomains.ReadFailureCounter.name(), 0l);
- _writeBytesCounter =
- new SimpleDynamicMetric(PredefinedMetricDomains.WriteBytesCounter.name(), 0l);
- _readBytesCounter =
- new SimpleDynamicMetric(PredefinedMetricDomains.ReadBytesCounter.name(), 0l);
- _writeCounter = new SimpleDynamicMetric(PredefinedMetricDomains.WriteCounter.name(), 0l);
- _readCounter = new SimpleDynamicMetric(PredefinedMetricDomains.ReadCounter.name(), 0l);
-
- _readLatencyGauge = new HistogramDynamicMetric(PredefinedMetricDomains.ReadLatencyGauge.name(),
- new Histogram(
- new SlidingTimeWindowArrayReservoir(getResetIntervalInMs(), TimeUnit.MILLISECONDS)));
- _writeLatencyGauge =
- new HistogramDynamicMetric(PredefinedMetricDomains.WriteLatencyGauge.name(), new Histogram(
- new SlidingTimeWindowArrayReservoir(getResetIntervalInMs(), TimeUnit.MILLISECONDS)));
- _readBytesGauge = new HistogramDynamicMetric(PredefinedMetricDomains.ReadBytesGauge.name(),
- new Histogram(
- new SlidingTimeWindowArrayReservoir(getResetIntervalInMs(), TimeUnit.MILLISECONDS)));
- _writeBytesGauge = new HistogramDynamicMetric(PredefinedMetricDomains.WriteBytesGauge.name(),
- new Histogram(
- new SlidingTimeWindowArrayReservoir(getResetIntervalInMs(), TimeUnit.MILLISECONDS)));
- _dataPropagationLatencyGauge =
- new HistogramDynamicMetric(PredefinedMetricDomains.DataPropagationLatencyGauge.name(),
- new Histogram(new SlidingTimeWindowArrayReservoir(getResetIntervalInMs(),
- TimeUnit.MILLISECONDS)));
-
- // This is deprecated and keep it for backward-compatibility purpose.
- _dataPropagationLatencyGuage =
- new HistogramDynamicMetric(PredefinedMetricDomains.DataPropagationLatencyGuage.name(),
- new Histogram(new SlidingTimeWindowArrayReservoir(getResetIntervalInMs(),
- TimeUnit.MILLISECONDS)));
- }
-
- public ZkClientPathMonitor register() throws JMException {
- List<DynamicMetric<?, ?>> attributeList = new ArrayList<>();
- attributeList.add(_readCounter);
- attributeList.add(_writeCounter);
- attributeList.add(_readBytesCounter);
- attributeList.add(_writeBytesCounter);
- attributeList.add(_readFailureCounter);
- attributeList.add(_writeFailureCounter);
- attributeList.add(_readTotalLatencyCounter);
- attributeList.add(_writeTotalLatencyCounter);
- attributeList.add(_readLatencyGauge);
- attributeList.add(_writeLatencyGauge);
- attributeList.add(_readBytesGauge);
- attributeList.add(_writeBytesGauge);
- attributeList.add(_dataPropagationLatencyGauge);
- // This is deprecated and keep it for backward-compatibility purpose.
- attributeList.add(_dataPropagationLatencyGuage);
-
- ObjectName objectName = new ObjectName(String
- .format("%s,%s=%s", ZkClientMonitor.getObjectName(_type, _key, _instanceName).toString(),
- MONITOR_PATH, _path.name()));
- doRegister(attributeList, ZkClientMonitor.MBEAN_DESCRIPTION, objectName);
-
- return this;
- }
-
- protected synchronized void record(int bytes, long latencyMilliSec, boolean isFailure,
- boolean isRead) {
- if (isFailure) {
- increaseFailureCounter(isRead);
- } else {
- increaseCounter(isRead);
- increaseTotalLatency(isRead, latencyMilliSec);
- if (bytes > 0) {
- increaseBytesCounter(isRead, bytes);
- }
- }
- }
-
- public void recordDataPropagationLatency(long latency) {
- _dataPropagationLatencyGauge.updateValue(latency);
- _dataPropagationLatencyGuage.updateValue(latency);
- }
-
- private void increaseFailureCounter(boolean isRead) {
- if (isRead) {
- _readFailureCounter.updateValue(_readFailureCounter.getValue() + 1);
- } else {
- _writeFailureCounter.updateValue(_writeFailureCounter.getValue() + 1);
- }
- }
-
- private void increaseCounter(boolean isRead) {
- if (isRead) {
- _readCounter.updateValue(_readCounter.getValue() + 1);
- } else {
- _writeCounter.updateValue(_writeCounter.getValue() + 1);
- }
- }
-
- private void increaseBytesCounter(boolean isRead, int bytes) {
- if (isRead) {
- _readBytesCounter.updateValue(_readBytesCounter.getValue() + bytes);
- _readBytesGauge.updateValue((long) bytes);
- } else {
- _writeBytesCounter.updateValue(_writeBytesCounter.getValue() + bytes);
- _writeBytesGauge.updateValue((long) bytes);
- }
- }
-
- private void increaseTotalLatency(boolean isRead, long latencyDelta) {
- if (isRead) {
- _readTotalLatencyCounter.updateValue(_readTotalLatencyCounter.getValue() + latencyDelta);
- _readLatencyGauge.updateValue(latencyDelta);
- } else {
- _writeTotalLatencyCounter.updateValue(_writeTotalLatencyCounter.getValue() + latencyDelta);
- _writeLatencyGauge.updateValue(latencyDelta);
- }
+ super(path, monitorType, monitorKey, monitorInstanceName);
}
}
diff --git a/helix-core/src/main/java/org/apache/helix/participant/HelixCustomCodeRunner.java b/helix-core/src/main/java/org/apache/helix/participant/HelixCustomCodeRunner.java
index b29126c..8d10e8f 100644
--- a/helix-core/src/main/java/org/apache/helix/participant/HelixCustomCodeRunner.java
+++ b/helix-core/src/main/java/org/apache/helix/participant/HelixCustomCodeRunner.java
@@ -23,21 +23,21 @@
import java.util.Arrays;
import java.util.List;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
import org.apache.helix.HelixConstants.ChangeType;
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.HelixManager;
import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.ZNRecord;
import org.apache.helix.manager.zk.ZKHelixDataAccessor;
import org.apache.helix.manager.zk.ZNRecordSerializer;
import org.apache.helix.manager.zk.ZkBaseDataAccessor;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.client.SharedZkClientFactory;
import org.apache.helix.model.IdealState;
import org.apache.helix.model.IdealState.RebalanceMode;
+import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
/**
* This provides the ability for users to run a custom code in exactly one
* process using a LeaderStandBy state model. <br/>
@@ -136,12 +136,11 @@
// model
HelixZkClient.ZkClientConfig clientConfig = new HelixZkClient.ZkClientConfig();
clientConfig.setZkSerializer(new ZNRecordSerializer());
- zkClient = SharedZkClientFactory
- .getInstance().buildZkClient(new HelixZkClient.ZkConnectionConfig(_zkAddr), clientConfig);
+ zkClient = SharedZkClientFactory.getInstance()
+ .buildZkClient(new HelixZkClient.ZkConnectionConfig(_zkAddr), clientConfig);
HelixDataAccessor accessor =
- new ZKHelixDataAccessor(_manager.getClusterName(), new ZkBaseDataAccessor<ZNRecord>(
- zkClient));
+ new ZKHelixDataAccessor(_manager.getClusterName(), new ZkBaseDataAccessor<>(zkClient));
Builder keyBuilder = accessor.keyBuilder();
IdealState idealState = new IdealState(_resourceName);
@@ -150,8 +149,8 @@
idealState.setNumPartitions(1);
idealState.setStateModelDefRef(LEADER_STANDBY);
idealState.setStateModelFactoryName(_resourceName);
- List<String> prefList =
- new ArrayList<String>(Arrays.asList(IdealState.IdealStateConstants.ANY_LIVEINSTANCE.toString()));
+ List<String> prefList = new ArrayList<String>(
+ Arrays.asList(IdealState.IdealStateConstants.ANY_LIVEINSTANCE.toString()));
idealState.getRecord().setListField(_resourceName + "_0", prefList);
List<String> idealStates = accessor.getChildNames(keyBuilder.idealStates());
@@ -160,14 +159,13 @@
idealStates = accessor.getChildNames(keyBuilder.idealStates());
}
- LOG.info("Set idealState for participantLeader:" + _resourceName + ", idealState:"
- + idealState);
+ LOG.info(
+ "Set idealState for participantLeader:" + _resourceName + ", idealState:" + idealState);
} finally {
if (zkClient != null && !zkClient.isClosed()) {
zkClient.close();
}
}
-
}
/**
@@ -175,7 +173,7 @@
*/
public void stop() {
LOG.info("Removing stateModelFactory for " + _resourceName);
- _manager.getStateMachineEngine().removeStateModelFactory(LEADER_STANDBY, _stateModelFty,
- _resourceName);
+ _manager.getStateMachineEngine()
+ .removeStateModelFactory(LEADER_STANDBY, _stateModelFty, _resourceName);
}
}
diff --git a/helix-core/src/main/java/org/apache/helix/participant/statemachine/ScheduledTaskStateModel.java b/helix-core/src/main/java/org/apache/helix/participant/statemachine/ScheduledTaskStateModel.java
index 750c7c9..8a54570 100644
--- a/helix-core/src/main/java/org/apache/helix/participant/statemachine/ScheduledTaskStateModel.java
+++ b/helix-core/src/main/java/org/apache/helix/participant/statemachine/ScheduledTaskStateModel.java
@@ -23,7 +23,7 @@
import org.apache.helix.HelixException;
import org.apache.helix.NotificationContext;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.messaging.handling.HelixTaskExecutor;
import org.apache.helix.messaging.handling.MessageHandler;
import org.apache.helix.model.Message;
diff --git a/helix-core/src/main/java/org/apache/helix/store/PropertyJsonSerializer.java b/helix-core/src/main/java/org/apache/helix/store/PropertyJsonSerializer.java
index d9bb82d..75d056b 100644
--- a/helix-core/src/main/java/org/apache/helix/store/PropertyJsonSerializer.java
+++ b/helix-core/src/main/java/org/apache/helix/store/PropertyJsonSerializer.java
@@ -23,7 +23,7 @@
import java.io.StringWriter;
import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
diff --git a/helix-core/src/main/java/org/apache/helix/store/ZNRecordJsonSerializer.java b/helix-core/src/main/java/org/apache/helix/store/ZNRecordJsonSerializer.java
index dfb0a0d..64bf74f 100644
--- a/helix-core/src/main/java/org/apache/helix/store/ZNRecordJsonSerializer.java
+++ b/helix-core/src/main/java/org/apache/helix/store/ZNRecordJsonSerializer.java
@@ -19,7 +19,7 @@
* under the License.
*/
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.manager.zk.ZNRecordSerializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/store/zk/AutoFallbackPropertyStore.java b/helix-core/src/main/java/org/apache/helix/store/zk/AutoFallbackPropertyStore.java
index dafa36d..47b1dfa 100644
--- a/helix-core/src/main/java/org/apache/helix/store/zk/AutoFallbackPropertyStore.java
+++ b/helix-core/src/main/java/org/apache/helix/store/zk/AutoFallbackPropertyStore.java
@@ -26,9 +26,9 @@
import java.util.Map;
import java.util.Set;
-import org.I0Itec.zkclient.DataUpdater;
import org.apache.helix.AccessOption;
import org.apache.helix.manager.zk.ZkBaseDataAccessor;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/store/zk/ZkHelixPropertyStore.java b/helix-core/src/main/java/org/apache/helix/store/zk/ZkHelixPropertyStore.java
index a6e7a9c..1ea9c6f 100644
--- a/helix-core/src/main/java/org/apache/helix/store/zk/ZkHelixPropertyStore.java
+++ b/helix-core/src/main/java/org/apache/helix/store/zk/ZkHelixPropertyStore.java
@@ -21,9 +21,10 @@
import java.util.List;
-import org.I0Itec.zkclient.serialize.ZkSerializer;
import org.apache.helix.manager.zk.ZkBaseDataAccessor;
import org.apache.helix.manager.zk.ZkCacheBaseDataAccessor;
+import org.apache.helix.zookeeper.zkclient.serialize.ZkSerializer;
+
public class ZkHelixPropertyStore<T> extends ZkCacheBaseDataAccessor<T> {
public static final String MONITOR_TYPE = "HelixPropertyStore";
diff --git a/helix-core/src/main/java/org/apache/helix/task/DeprecatedTaskRebalancer.java b/helix-core/src/main/java/org/apache/helix/task/DeprecatedTaskRebalancer.java
index 115237f..d508d1b 100644
--- a/helix-core/src/main/java/org/apache/helix/task/DeprecatedTaskRebalancer.java
+++ b/helix-core/src/main/java/org/apache/helix/task/DeprecatedTaskRebalancer.java
@@ -44,14 +44,13 @@
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
-import org.I0Itec.zkclient.DataUpdater;
import org.apache.helix.AccessOption;
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.HelixDefinedState;
import org.apache.helix.HelixManager;
import org.apache.helix.HelixProperty;
import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.controller.dataproviders.WorkflowControllerDataProvider;
import org.apache.helix.controller.rebalancer.Rebalancer;
import org.apache.helix.controller.rebalancer.internal.MappingCalculator;
@@ -62,6 +61,7 @@
import org.apache.helix.model.Partition;
import org.apache.helix.model.Resource;
import org.apache.helix.model.ResourceAssignment;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/task/JobContext.java b/helix-core/src/main/java/org/apache/helix/task/JobContext.java
index 26628a4..9917c83 100644
--- a/helix-core/src/main/java/org/apache/helix/task/JobContext.java
+++ b/helix-core/src/main/java/org/apache/helix/task/JobContext.java
@@ -29,7 +29,7 @@
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
/**
* Provides a typed interface to the context information stored by {@link TaskRebalancer} in the
diff --git a/helix-core/src/main/java/org/apache/helix/task/JobDispatcher.java b/helix-core/src/main/java/org/apache/helix/task/JobDispatcher.java
index 90729d6..479b47c 100644
--- a/helix-core/src/main/java/org/apache/helix/task/JobDispatcher.java
+++ b/helix-core/src/main/java/org/apache/helix/task/JobDispatcher.java
@@ -30,7 +30,7 @@
import java.util.TreeSet;
import com.google.common.collect.ImmutableMap;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.controller.dataproviders.WorkflowControllerDataProvider;
import org.apache.helix.controller.stages.CurrentStateOutput;
import org.apache.helix.model.Message;
diff --git a/helix-core/src/main/java/org/apache/helix/task/TaskDriver.java b/helix-core/src/main/java/org/apache/helix/task/TaskDriver.java
index 9eb46fc..0b8fa17 100644
--- a/helix-core/src/main/java/org/apache/helix/task/TaskDriver.java
+++ b/helix-core/src/main/java/org/apache/helix/task/TaskDriver.java
@@ -28,7 +28,6 @@
import java.util.Map;
import java.util.Set;
-import org.I0Itec.zkclient.DataUpdater;
import org.apache.helix.AccessOption;
import org.apache.helix.BaseDataAccessor;
import org.apache.helix.ConfigAccessor;
@@ -39,17 +38,18 @@
import org.apache.helix.PropertyKey;
import org.apache.helix.PropertyPathBuilder;
import org.apache.helix.SystemPropertyKeys;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.manager.zk.ZKHelixAdmin;
import org.apache.helix.manager.zk.ZKHelixDataAccessor;
import org.apache.helix.manager.zk.ZkBaseDataAccessor;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
import org.apache.helix.model.IdealState;
import org.apache.helix.model.ResourceConfig;
import org.apache.helix.model.builder.CustomModeISBuilder;
import org.apache.helix.store.HelixPropertyStore;
import org.apache.helix.store.zk.ZkHelixPropertyStore;
import org.apache.helix.util.HelixUtil;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/task/TaskUtil.java b/helix-core/src/main/java/org/apache/helix/task/TaskUtil.java
index 5c93469..6b36db4 100644
--- a/helix-core/src/main/java/org/apache/helix/task/TaskUtil.java
+++ b/helix-core/src/main/java/org/apache/helix/task/TaskUtil.java
@@ -29,14 +29,13 @@
import com.google.common.base.Joiner;
import com.google.common.collect.Sets;
-import org.I0Itec.zkclient.DataUpdater;
import org.apache.helix.AccessOption;
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.HelixException;
import org.apache.helix.HelixManager;
import org.apache.helix.HelixProperty;
import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.controller.dataproviders.WorkflowControllerDataProvider;
import org.apache.helix.controller.rebalancer.util.RebalanceScheduler;
import org.apache.helix.model.HelixConfigScope;
@@ -44,6 +43,7 @@
import org.apache.helix.model.builder.HelixConfigScopeBuilder;
import org.apache.helix.store.HelixPropertyStore;
import org.apache.helix.util.RebalanceUtil;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
import org.slf4j.Logger;
diff --git a/helix-core/src/main/java/org/apache/helix/task/WorkflowContext.java b/helix-core/src/main/java/org/apache/helix/task/WorkflowContext.java
index c915e3b..3cbdad8 100644
--- a/helix-core/src/main/java/org/apache/helix/task/WorkflowContext.java
+++ b/helix-core/src/main/java/org/apache/helix/task/WorkflowContext.java
@@ -27,7 +27,7 @@
import java.util.TreeMap;
import org.apache.helix.HelixProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/task/WorkflowDispatcher.java b/helix-core/src/main/java/org/apache/helix/task/WorkflowDispatcher.java
index 1ed9ab0..11d6687 100644
--- a/helix-core/src/main/java/org/apache/helix/task/WorkflowDispatcher.java
+++ b/helix-core/src/main/java/org/apache/helix/task/WorkflowDispatcher.java
@@ -37,7 +37,7 @@
import org.apache.helix.HelixManager;
import org.apache.helix.HelixProperty;
import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.common.caches.TaskDataCache;
import org.apache.helix.controller.LogUtil;
import org.apache.helix.controller.dataproviders.WorkflowControllerDataProvider;
diff --git a/helix-core/src/main/java/org/apache/helix/tools/ClusterExternalViewVerifier.java b/helix-core/src/main/java/org/apache/helix/tools/ClusterExternalViewVerifier.java
index a342c2e..d10ba71 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/ClusterExternalViewVerifier.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/ClusterExternalViewVerifier.java
@@ -35,7 +35,7 @@
import org.apache.helix.controller.stages.ClusterEventType;
import org.apache.helix.controller.stages.CurrentStateComputationStage;
import org.apache.helix.controller.stages.ResourceComputationStage;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
import org.apache.helix.model.ExternalView;
import org.apache.helix.model.Partition;
import org.slf4j.Logger;
diff --git a/helix-core/src/main/java/org/apache/helix/tools/ClusterLiveNodesVerifier.java b/helix-core/src/main/java/org/apache/helix/tools/ClusterLiveNodesVerifier.java
index 164cfcc..c5c1311 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/ClusterLiveNodesVerifier.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/ClusterLiveNodesVerifier.java
@@ -22,7 +22,7 @@
import java.util.Collections;
import java.util.List;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
/**
* Please use the class is in tools.ClusterVerifiers.
diff --git a/helix-core/src/main/java/org/apache/helix/tools/ClusterSetup.java b/helix-core/src/main/java/org/apache/helix/tools/ClusterSetup.java
index 5d5f864..7ac20a1 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/ClusterSetup.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/ClusterSetup.java
@@ -27,7 +27,6 @@
import java.util.List;
import java.util.Map;
-import org.I0Itec.zkclient.DataUpdater;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
@@ -41,13 +40,13 @@
import org.apache.helix.HelixConstants;
import org.apache.helix.HelixException;
import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.manager.zk.ZKHelixAdmin;
import org.apache.helix.manager.zk.ZKHelixDataAccessor;
import org.apache.helix.manager.zk.ZNRecordSerializer;
import org.apache.helix.manager.zk.ZkBaseDataAccessor;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.client.SharedZkClientFactory;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
import org.apache.helix.model.BuiltInStateModelDefinitions;
import org.apache.helix.model.ClusterConfig;
import org.apache.helix.model.ClusterConstraints;
@@ -64,6 +63,7 @@
import org.apache.helix.model.builder.ConstraintItemBuilder;
import org.apache.helix.model.builder.HelixConfigScopeBuilder;
import org.apache.helix.util.HelixUtil;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/tools/ClusterStateVerifier.java b/helix-core/src/main/java/org/apache/helix/tools/ClusterStateVerifier.java
index a398c24..80ccb68 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/ClusterStateVerifier.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/ClusterStateVerifier.java
@@ -29,9 +29,6 @@
import java.util.concurrent.TimeUnit;
import com.google.common.collect.Sets;
-import org.I0Itec.zkclient.IZkChildListener;
-import org.I0Itec.zkclient.IZkDataListener;
-import org.I0Itec.zkclient.exception.ZkNodeExistsException;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
@@ -45,7 +42,8 @@
import org.apache.helix.PropertyKey;
import org.apache.helix.PropertyKey.Builder;
import org.apache.helix.PropertyPathBuilder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.api.listeners.PreFetch;
import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
import org.apache.helix.controller.pipeline.Stage;
@@ -60,14 +58,16 @@
import org.apache.helix.manager.zk.ZKHelixDataAccessor;
import org.apache.helix.manager.zk.ZNRecordSerializer;
import org.apache.helix.manager.zk.ZkBaseDataAccessor;
-import org.apache.helix.manager.zk.ZkClient;
-import org.apache.helix.manager.zk.client.DedicatedZkClientFactory;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.factory.DedicatedZkClientFactory;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
import org.apache.helix.model.ExternalView;
import org.apache.helix.model.IdealState;
import org.apache.helix.model.Partition;
import org.apache.helix.model.Resource;
import org.apache.helix.task.TaskConstants;
+import org.apache.helix.zookeeper.zkclient.IZkChildListener;
+import org.apache.helix.zookeeper.zkclient.IZkDataListener;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNodeExistsException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifier.java b/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifier.java
index bbae075..272d8ae 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifier.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifier.java
@@ -23,15 +23,15 @@
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
-import org.I0Itec.zkclient.IZkChildListener;
-import org.I0Itec.zkclient.IZkDataListener;
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.api.listeners.PreFetch;
import org.apache.helix.manager.zk.ZKHelixDataAccessor;
import org.apache.helix.manager.zk.ZkBaseDataAccessor;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.zkclient.IZkChildListener;
+import org.apache.helix.zookeeper.zkclient.IZkDataListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/BestPossibleExternalViewVerifier.java b/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/BestPossibleExternalViewVerifier.java
index 66143fe..0efd187 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/BestPossibleExternalViewVerifier.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/BestPossibleExternalViewVerifier.java
@@ -50,8 +50,8 @@
import org.apache.helix.controller.stages.CurrentStateOutput;
import org.apache.helix.controller.stages.ResourceComputationStage;
import org.apache.helix.manager.zk.ZkBucketDataAccessor;
-import org.apache.helix.manager.zk.ZkClient;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
import org.apache.helix.model.ClusterConfig;
import org.apache.helix.model.ExternalView;
import org.apache.helix.model.IdealState;
diff --git a/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/ClusterLiveNodesVerifier.java b/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/ClusterLiveNodesVerifier.java
index b4d3862..0c284ff 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/ClusterLiveNodesVerifier.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/ClusterLiveNodesVerifier.java
@@ -24,7 +24,7 @@
import java.util.List;
import java.util.Set;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
public class ClusterLiveNodesVerifier extends ZkHelixClusterVerifier {
diff --git a/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/StrictMatchExternalViewVerifier.java b/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/StrictMatchExternalViewVerifier.java
index 0b3c97e..fcc7261 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/StrictMatchExternalViewVerifier.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/StrictMatchExternalViewVerifier.java
@@ -33,8 +33,8 @@
import org.apache.helix.PropertyKey;
import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
import org.apache.helix.controller.rebalancer.AbstractRebalancer;
-import org.apache.helix.manager.zk.ZkClient;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
import org.apache.helix.model.ClusterConfig;
import org.apache.helix.model.ExternalView;
import org.apache.helix.model.IdealState;
diff --git a/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/ZkHelixClusterVerifier.java b/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/ZkHelixClusterVerifier.java
index 6efdff5..e82fccf 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/ZkHelixClusterVerifier.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/ClusterVerifiers/ZkHelixClusterVerifier.java
@@ -25,17 +25,17 @@
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
-import org.I0Itec.zkclient.IZkChildListener;
-import org.I0Itec.zkclient.IZkDataListener;
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.PropertyKey;
import org.apache.helix.api.listeners.PreFetch;
import org.apache.helix.manager.zk.ZKHelixDataAccessor;
import org.apache.helix.manager.zk.ZNRecordSerializer;
import org.apache.helix.manager.zk.ZkBaseDataAccessor;
-import org.apache.helix.manager.zk.ZkClient;
-import org.apache.helix.manager.zk.client.DedicatedZkClientFactory;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
+import org.apache.helix.zookeeper.impl.factory.DedicatedZkClientFactory;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.zkclient.IZkChildListener;
+import org.apache.helix.zookeeper.zkclient.IZkDataListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/tools/DefaultIdealStateCalculator.java b/helix-core/src/main/java/org/apache/helix/tools/DefaultIdealStateCalculator.java
index 886790a..ae68a8f 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/DefaultIdealStateCalculator.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/DefaultIdealStateCalculator.java
@@ -27,7 +27,7 @@
import java.util.TreeMap;
import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.model.IdealState.IdealStateProperty;
/**
diff --git a/helix-core/src/main/java/org/apache/helix/tools/IdealCalculatorByConsistentHashing.java b/helix-core/src/main/java/org/apache/helix/tools/IdealCalculatorByConsistentHashing.java
index 1101a6d..8c1e8d7 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/IdealCalculatorByConsistentHashing.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/IdealCalculatorByConsistentHashing.java
@@ -29,7 +29,7 @@
import java.util.TreeMap;
import java.util.TreeSet;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.model.IdealState.IdealStateProperty;
public class IdealCalculatorByConsistentHashing {
diff --git a/helix-core/src/main/java/org/apache/helix/tools/IdealStateCalculatorByRush.java b/helix-core/src/main/java/org/apache/helix/tools/IdealStateCalculatorByRush.java
index 7677b42..d776952 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/IdealStateCalculatorByRush.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/IdealStateCalculatorByRush.java
@@ -26,7 +26,7 @@
import java.util.Random;
import java.util.TreeMap;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.model.IdealState.IdealStateProperty;
public class IdealStateCalculatorByRush {
diff --git a/helix-core/src/main/java/org/apache/helix/tools/IdealStateCalculatorByShuffling.java b/helix-core/src/main/java/org/apache/helix/tools/IdealStateCalculatorByShuffling.java
index d4764ef..57bf276 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/IdealStateCalculatorByShuffling.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/IdealStateCalculatorByShuffling.java
@@ -26,7 +26,7 @@
import java.util.Random;
import java.util.TreeMap;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.model.IdealState.IdealStateProperty;
/*
diff --git a/helix-core/src/main/java/org/apache/helix/tools/MessagePoster.java b/helix-core/src/main/java/org/apache/helix/tools/MessagePoster.java
index 4d096e9..b2b5689 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/MessagePoster.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/MessagePoster.java
@@ -22,10 +22,10 @@
import java.util.UUID;
import org.apache.helix.PropertyPathBuilder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.manager.zk.ZNRecordSerializer;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.client.SharedZkClientFactory;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
import org.apache.helix.model.LiveInstance.LiveInstanceProperty;
import org.apache.helix.model.Message;
import org.apache.helix.model.Message.MessageState;
diff --git a/helix-core/src/main/java/org/apache/helix/tools/StateModelConfigGenerator.java b/helix-core/src/main/java/org/apache/helix/tools/StateModelConfigGenerator.java
index 992797f..1cbb0f9 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/StateModelConfigGenerator.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/StateModelConfigGenerator.java
@@ -19,7 +19,7 @@
* under the License.
*/
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.manager.zk.ZNRecordSerializer;
import org.apache.helix.model.LeaderStandbySMD;
import org.apache.helix.model.MasterSlaveSMD;
diff --git a/helix-core/src/main/java/org/apache/helix/tools/TestExecutor.java b/helix-core/src/main/java/org/apache/helix/tools/TestExecutor.java
index df14af4..565a860 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/TestExecutor.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/TestExecutor.java
@@ -29,17 +29,17 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
-import org.I0Itec.zkclient.exception.ZkBadVersionException;
-import org.I0Itec.zkclient.exception.ZkNodeExistsException;
import org.apache.helix.HelixManager;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.manager.zk.ZNRecordSerializer;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.client.SharedZkClientFactory;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
import org.apache.helix.store.PropertyJsonComparator;
import org.apache.helix.store.PropertyJsonSerializer;
import org.apache.helix.store.PropertyStoreException;
import org.apache.helix.tools.TestCommand.CommandType;
+import org.apache.helix.zookeeper.zkclient.exception.ZkBadVersionException;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNodeExistsException;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/tools/TestTrigger.java b/helix-core/src/main/java/org/apache/helix/tools/TestTrigger.java
index 7c5bdf4..96253ee 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/TestTrigger.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/TestTrigger.java
@@ -22,7 +22,7 @@
import java.util.List;
import java.util.Map;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
public class TestTrigger {
public long _startTime;
diff --git a/helix-core/src/main/java/org/apache/helix/tools/ZnodeOpArg.java b/helix-core/src/main/java/org/apache/helix/tools/ZnodeOpArg.java
index e60ce8e..53801f6 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/ZnodeOpArg.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/ZnodeOpArg.java
@@ -22,7 +22,7 @@
import java.util.List;
import java.util.Map;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.tools.TestExecutor.ZnodePropertyType;
public class ZnodeOpArg {
diff --git a/helix-core/src/main/java/org/apache/helix/tools/ZnodeValue.java b/helix-core/src/main/java/org/apache/helix/tools/ZnodeValue.java
index c975b6f..be40449 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/ZnodeValue.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/ZnodeValue.java
@@ -22,7 +22,7 @@
import java.util.List;
import java.util.Map;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
public class ZnodeValue {
public String _singleValue;
diff --git a/helix-core/src/main/java/org/apache/helix/tools/commandtools/CurrentStateCleanUp.java b/helix-core/src/main/java/org/apache/helix/tools/commandtools/CurrentStateCleanUp.java
index 29bcdf8..5c276f3 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/commandtools/CurrentStateCleanUp.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/commandtools/CurrentStateCleanUp.java
@@ -4,7 +4,6 @@
import java.util.List;
import java.util.Set;
-import org.I0Itec.zkclient.DataUpdater;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
@@ -18,8 +17,9 @@
import org.apache.helix.HelixManagerFactory;
import org.apache.helix.InstanceType;
import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.model.CurrentState;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/main/java/org/apache/helix/tools/commandtools/IntegrationTestUtil.java b/helix-core/src/main/java/org/apache/helix/tools/commandtools/IntegrationTestUtil.java
index ed7f479..ba9628f 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/commandtools/IntegrationTestUtil.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/commandtools/IntegrationTestUtil.java
@@ -33,10 +33,10 @@
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.manager.zk.ZNRecordSerializer;
-import org.apache.helix.manager.zk.client.DedicatedZkClientFactory;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.factory.DedicatedZkClientFactory;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
import org.apache.helix.tools.ClusterExternalViewVerifier;
import org.apache.helix.tools.ClusterVerifiers.BestPossibleExternalViewVerifier;
import org.apache.helix.tools.ClusterVerifiers.ClusterLiveNodesVerifier;
diff --git a/helix-core/src/main/java/org/apache/helix/tools/commandtools/LocalZKServer.java b/helix-core/src/main/java/org/apache/helix/tools/commandtools/LocalZKServer.java
index bb13380..d15d39f 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/commandtools/LocalZKServer.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/commandtools/LocalZKServer.java
@@ -19,9 +19,10 @@
* under the License.
*/
-import org.I0Itec.zkclient.IDefaultNameSpace;
-import org.I0Itec.zkclient.ZkClient;
-import org.I0Itec.zkclient.ZkServer;
+import org.apache.helix.zookeeper.zkclient.IDefaultNameSpace;
+import org.apache.helix.zookeeper.zkclient.ZkClient;
+import org.apache.helix.zookeeper.zkclient.ZkServer;
+
/**
* Provides ability to start zookeeper locally on a particular port
diff --git a/helix-core/src/main/java/org/apache/helix/tools/commandtools/ZKDumper.java b/helix-core/src/main/java/org/apache/helix/tools/commandtools/ZKDumper.java
index 7d9eeec..bb69e9d 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/commandtools/ZKDumper.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/commandtools/ZKDumper.java
@@ -28,7 +28,6 @@
import java.io.OutputStream;
import java.util.List;
-import org.I0Itec.zkclient.serialize.ZkSerializer;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
@@ -38,8 +37,10 @@
import org.apache.commons.cli.Options;
import org.apache.commons.cli.PosixParser;
import org.apache.helix.manager.zk.ByteArraySerializer;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.client.SharedZkClientFactory;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
+import org.apache.helix.zookeeper.zkclient.serialize.ZkSerializer;
+
/**
* Dumps the Zookeeper file structure on to Disk
diff --git a/helix-core/src/main/java/org/apache/helix/tools/commandtools/ZkCopy.java b/helix-core/src/main/java/org/apache/helix/tools/commandtools/ZkCopy.java
index 805847c..2ea48a3 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/commandtools/ZkCopy.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/commandtools/ZkCopy.java
@@ -37,8 +37,8 @@
import org.apache.helix.BaseDataAccessor;
import org.apache.helix.manager.zk.ByteArraySerializer;
import org.apache.helix.manager.zk.ZkBaseDataAccessor;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.client.SharedZkClientFactory;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
import org.apache.zookeeper.common.PathUtils;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
diff --git a/helix-core/src/main/java/org/apache/helix/tools/commandtools/ZkLogCSVFormatter.java b/helix-core/src/main/java/org/apache/helix/tools/commandtools/ZkLogCSVFormatter.java
index d9d4f98..3052441 100644
--- a/helix-core/src/main/java/org/apache/helix/tools/commandtools/ZkLogCSVFormatter.java
+++ b/helix-core/src/main/java/org/apache/helix/tools/commandtools/ZkLogCSVFormatter.java
@@ -32,7 +32,7 @@
import java.util.List;
import java.util.Map;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.manager.zk.ZNRecordSerializer;
import org.apache.helix.model.IdealState.IdealStateProperty;
import org.apache.helix.util.HelixUtil;
diff --git a/helix-core/src/main/java/org/apache/helix/util/ExponentialBackoffStrategy.java b/helix-core/src/main/java/org/apache/helix/util/ExponentialBackoffStrategy.java
index b1a66c9..40b81e3 100644
--- a/helix-core/src/main/java/org/apache/helix/util/ExponentialBackoffStrategy.java
+++ b/helix-core/src/main/java/org/apache/helix/util/ExponentialBackoffStrategy.java
@@ -1,33 +1,31 @@
package org.apache.helix.util;
-import java.util.Random;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
-public class ExponentialBackoffStrategy {
- private final long INIT_RETRY_INTERVAL = 500;
- private final long _maxRetryInterval;
- private final boolean _addJitter;
- private final Random _ran;
-
+/**
+ * Use ExponentialBackoffStrategy in zookeeper-api module instead.
+ */
+@Deprecated
+public class ExponentialBackoffStrategy
+ extends org.apache.helix.zookeeper.zkclient.util.ExponentialBackoffStrategy {
public ExponentialBackoffStrategy(long maxRetryInterval, boolean addJitter) {
- _maxRetryInterval = maxRetryInterval;
- _addJitter = addJitter;
- _ran = new Random(System.currentTimeMillis());
- }
-
- public long getNextWaitInterval(int numberOfTriesFailed) {
- double exponentialMultiplier = Math.pow(2.0, numberOfTriesFailed - 1);
- double result = exponentialMultiplier * INIT_RETRY_INTERVAL;
-
- if (_maxRetryInterval > 0 && result > _maxRetryInterval) {
- result = _maxRetryInterval;
- }
-
- if (_addJitter) {
- // Adding jitter so the real result would be 75% to 100% of the original result.
- // Don't directly add jitter here, since it may exceed the max retry interval setup
- result = result * (0.75 + _ran.nextDouble() % 0.25);
- }
-
- return (long) result;
+ super(maxRetryInterval, addJitter);
}
}
diff --git a/helix-core/src/main/java/org/apache/helix/util/GZipCompressionUtil.java b/helix-core/src/main/java/org/apache/helix/util/GZipCompressionUtil.java
index f29a301..358c969 100644
--- a/helix-core/src/main/java/org/apache/helix/util/GZipCompressionUtil.java
+++ b/helix-core/src/main/java/org/apache/helix/util/GZipCompressionUtil.java
@@ -19,55 +19,9 @@
* under the License.
*/
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.zip.GZIPInputStream;
-import java.util.zip.GZIPOutputStream;
-
-public class GZipCompressionUtil {
- /**
- * Compresses a byte array by applying GZIP compression
- * @param serializedBytes
- * @return
- * @throws IOException
- */
- public static byte[] compress(byte[] buffer) throws IOException {
- ByteArrayOutputStream gzipByteArrayOutputStream = new ByteArrayOutputStream();
- GZIPOutputStream gzipOutputStream = null;
- gzipOutputStream = new GZIPOutputStream(gzipByteArrayOutputStream);
- gzipOutputStream.write(buffer, 0, buffer.length);
- gzipOutputStream.close();
- byte[] compressedBytes = gzipByteArrayOutputStream.toByteArray();
- return compressedBytes;
- }
-
- public static byte[] uncompress(ByteArrayInputStream bais) throws IOException {
- GZIPInputStream gzipInputStream = new GZIPInputStream(bais);
- byte[] buffer = new byte[1024];
- int length;
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- while ((length = gzipInputStream.read(buffer)) != -1) {
- baos.write(buffer, 0, length);
- }
- gzipInputStream.close();
- baos.close();
- byte[] uncompressedBytes = baos.toByteArray();
- return uncompressedBytes;
- }
-
- /*
- * Determines if a byte array is compressed. The java.util.zip GZip
- * implementaiton does not expose the GZip header so it is difficult to determine
- * if a string is compressed.
- * @param bytes an array of bytes
- * @return true if the array is compressed or false otherwise
- */
- public static boolean isCompressed(byte[] bytes) {
- if ((bytes == null) || (bytes.length < 2)) {
- return false;
- } else {
- return ((bytes[0] == (byte) (GZIPInputStream.GZIP_MAGIC)) && (bytes[1] == (byte) (GZIPInputStream.GZIP_MAGIC >> 8)));
- }
- }
+/**
+ * Deprecated - please use GZipCompressionUtil in zookeeper-api.
+ */
+@Deprecated
+public class GZipCompressionUtil extends org.apache.helix.zookeeper.util.GZipCompressionUtil {
}
diff --git a/helix-core/src/main/java/org/apache/helix/util/StatusUpdateUtil.java b/helix-core/src/main/java/org/apache/helix/util/StatusUpdateUtil.java
index 1249fec..7a82347 100644
--- a/helix-core/src/main/java/org/apache/helix/util/StatusUpdateUtil.java
+++ b/helix-core/src/main/java/org/apache/helix/util/StatusUpdateUtil.java
@@ -39,7 +39,7 @@
import org.apache.helix.InstanceType;
import org.apache.helix.PropertyKey;
import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.model.Error;
import org.apache.helix.model.Message;
import org.apache.helix.model.Message.MessageType;
diff --git a/helix-core/src/main/java/org/apache/helix/util/WeightAwareRebalanceUtil.java b/helix-core/src/main/java/org/apache/helix/util/WeightAwareRebalanceUtil.java
index 7bef7b7..f6f692a 100644
--- a/helix-core/src/main/java/org/apache/helix/util/WeightAwareRebalanceUtil.java
+++ b/helix-core/src/main/java/org/apache/helix/util/WeightAwareRebalanceUtil.java
@@ -7,7 +7,7 @@
import java.util.Map;
import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.api.config.RebalanceConfig;
import org.apache.helix.api.rebalancer.constraint.AbstractRebalanceHardConstraint;
import org.apache.helix.api.rebalancer.constraint.AbstractRebalanceSoftConstraint;
diff --git a/helix-core/src/main/java/org/apache/helix/util/ZKClientPool.java b/helix-core/src/main/java/org/apache/helix/util/ZKClientPool.java
index 3350d57..51b1ab9 100644
--- a/helix-core/src/main/java/org/apache/helix/util/ZKClientPool.java
+++ b/helix-core/src/main/java/org/apache/helix/util/ZKClientPool.java
@@ -23,7 +23,7 @@
import java.util.concurrent.ConcurrentHashMap;
import org.apache.helix.manager.zk.ZNRecordSerializer;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.zookeeper.ZooKeeper.States;
public class ZKClientPool {
diff --git a/helix-core/src/main/java/org/apache/helix/util/ZNRecordUtil.java b/helix-core/src/main/java/org/apache/helix/util/ZNRecordUtil.java
index 989b54a..d2127b9 100644
--- a/helix-core/src/main/java/org/apache/helix/util/ZNRecordUtil.java
+++ b/helix-core/src/main/java/org/apache/helix/util/ZNRecordUtil.java
@@ -25,12 +25,13 @@
import java.util.List;
import java.util.Map;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
//TODO find a proper place for these methods
-public final class ZNRecordUtil {
+public class ZNRecordUtil {
private static final Logger logger = LoggerFactory.getLogger(ZNRecordUtil.class.getName());
private ZNRecordUtil() {
diff --git a/helix-core/src/test/java/org/apache/helix/MockAccessor.java b/helix-core/src/test/java/org/apache/helix/MockAccessor.java
index c0a0e46..4e9a014 100644
--- a/helix-core/src/test/java/org/apache/helix/MockAccessor.java
+++ b/helix-core/src/test/java/org/apache/helix/MockAccessor.java
@@ -24,15 +24,18 @@
import java.util.List;
import java.util.Map;
-import org.I0Itec.zkclient.DataUpdater;
-import org.I0Itec.zkclient.exception.ZkNoNodeException;
import org.apache.helix.mock.MockBaseDataAccessor;
import org.apache.helix.model.LiveInstance;
import org.apache.helix.model.MaintenanceSignal;
import org.apache.helix.model.Message;
import org.apache.helix.model.PauseSignal;
import org.apache.helix.model.StateModelDefinition;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNoNodeException;
import org.apache.zookeeper.data.Stat;
+import org.apache.helix.zookeeper.datamodel.ZNRecordUpdater;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+
public class MockAccessor implements HelixDataAccessor {
private final String _clusterName;
@@ -69,11 +72,13 @@
return false;
}
- @Override public boolean createMaintenance(MaintenanceSignal maintenanceSignal) {
+ @Override
+ public boolean createMaintenance(MaintenanceSignal maintenanceSignal) {
return false;
}
- @Override public boolean setProperty(PropertyKey key, HelixProperty value) {
+ @Override
+ public boolean setProperty(PropertyKey key, HelixProperty value) {
String path = key.getPath();
_baseDataAccessor.set(path, value.getRecord(), AccessOption.PERSISTENT);
return true;
@@ -81,11 +86,12 @@
@Override
public <T extends HelixProperty> boolean updateProperty(PropertyKey key, T value) {
- return updateProperty(key, new ZNRecordUpdater(value.getRecord()) , value);
+ return updateProperty(key, new ZNRecordUpdater(value.getRecord()), value);
}
@Override
- public <T extends HelixProperty> boolean updateProperty(PropertyKey key, DataUpdater<ZNRecord> updater, T value) {
+ public <T extends HelixProperty> boolean updateProperty(PropertyKey key,
+ DataUpdater<ZNRecord> updater, T value) {
String path = key.getPath();
PropertyType type = key.getType();
if (type.updateOnlyOnExists) {
@@ -143,7 +149,8 @@
try {
Stat stat = _baseDataAccessor.getStat(path, 0);
if (stat != null) {
- return new HelixProperty.Stat(stat.getVersion(), stat.getCtime(), stat.getMtime(), stat.getEphemeralOwner());
+ return new HelixProperty.Stat(stat.getVersion(), stat.getCtime(), stat.getMtime(),
+ stat.getEphemeralOwner());
}
} catch (ZkNoNodeException e) {
@@ -170,7 +177,8 @@
HelixProperty.Stat propertyStat = null;
if (zkStat != null) {
propertyStat =
- new HelixProperty.Stat(zkStat.getVersion(), zkStat.getCtime(), zkStat.getMtime(), zkStat.getEphemeralOwner());
+ new HelixProperty.Stat(zkStat.getVersion(), zkStat.getCtime(), zkStat.getMtime(),
+ zkStat.getEphemeralOwner());
}
propertyStats.add(propertyStat);
}
@@ -185,14 +193,15 @@
}
@SuppressWarnings("unchecked")
- @Override public <T extends HelixProperty> List<T> getChildValues(PropertyKey propertyKey) {
+ @Override
+ public <T extends HelixProperty> List<T> getChildValues(PropertyKey propertyKey) {
String path = propertyKey.getPath(); // PropertyPathConfig.getPath(type,
List<ZNRecord> children = _baseDataAccessor.getChildren(path, null, 0);
return (List<T>) HelixProperty.convertToTypedList(propertyKey.getTypeClass(), children);
}
- @Override public <T extends HelixProperty> List<T> getChildValues(PropertyKey key,
- boolean throwException) {
+ @Override
+ public <T extends HelixProperty> List<T> getChildValues(PropertyKey key, boolean throwException) {
return getChildValues(key);
}
@@ -202,7 +211,8 @@
return HelixProperty.convertListToMap(list);
}
- @Override public <T extends HelixProperty> Map<String, T> getChildValuesMap(PropertyKey key,
+ @Override
+ public <T extends HelixProperty> Map<String, T> getChildValuesMap(PropertyKey key,
boolean throwException) {
return getChildValuesMap(key);
}
@@ -250,7 +260,8 @@
return list;
}
- @Override public <T extends HelixProperty> List<T> getProperty(List<PropertyKey> keys,
+ @Override
+ public <T extends HelixProperty> List<T> getProperty(List<PropertyKey> keys,
boolean throwException) {
return getProperty(keys);
}
diff --git a/helix-core/src/test/java/org/apache/helix/TestEspressoStorageClusterIdealState.java b/helix-core/src/test/java/org/apache/helix/TestEspressoStorageClusterIdealState.java
index 6cad5af..18cc84b 100644
--- a/helix-core/src/test/java/org/apache/helix/TestEspressoStorageClusterIdealState.java
+++ b/helix-core/src/test/java/org/apache/helix/TestEspressoStorageClusterIdealState.java
@@ -33,6 +33,8 @@
import org.testng.Assert;
import org.testng.AssertJUnit;
import org.testng.annotations.Test;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+
public class TestEspressoStorageClusterIdealState {
@Test()
@@ -82,7 +84,6 @@
slaveKeepRatio = result[1];
Assert.assertTrue(0.66 < masterKeepRatio && 0.67 > masterKeepRatio);
Assert.assertTrue(0.49 < slaveKeepRatio && 0.51 > slaveKeepRatio);
-
}
@Test
@@ -209,7 +210,6 @@
AssertJUnit.assertTrue(slaveCountMap.get(masterPartitionId) == replicas);
}
}
-
}
public void printStat(Map<String, Object> result) {
@@ -259,8 +259,9 @@
}
result[0] = 1.0 * commonMasters / partitions;
- System.out.println(commonMasters + " master partitions are kept, "
- + (partitions - commonMasters) + " moved, keep ratio:" + 1.0 * commonMasters / partitions);
+ System.out.println(
+ commonMasters + " master partitions are kept, " + (partitions - commonMasters)
+ + " moved, keep ratio:" + 1.0 * commonMasters / partitions);
// maps from the partition id to the instance names that holds its slave partition
Map<Integer, Set<String>> slaveMap1 = new TreeMap<Integer, Set<String>>();
@@ -290,10 +291,9 @@
}
}
result[1] = 1.0 * commonSlaves / partitions / replicas;
- System.out.println(commonSlaves + " slave partitions are kept, "
- + (partitions * replicas - commonSlaves) + " moved. keep ratio:" + 1.0 * commonSlaves
- / partitions / replicas);
+ System.out.println(
+ commonSlaves + " slave partitions are kept, " + (partitions * replicas - commonSlaves)
+ + " moved. keep ratio:" + 1.0 * commonSlaves / partitions / replicas);
return result;
}
-
}
diff --git a/helix-core/src/test/java/org/apache/helix/TestGroupCommit.java b/helix-core/src/test/java/org/apache/helix/TestGroupCommit.java
index 8465033..cd8d598 100644
--- a/helix-core/src/test/java/org/apache/helix/TestGroupCommit.java
+++ b/helix-core/src/test/java/org/apache/helix/TestGroupCommit.java
@@ -23,6 +23,8 @@
import java.util.concurrent.Executors;
import org.apache.helix.mock.MockBaseDataAccessor;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+
public class TestGroupCommit {
// @Test
@@ -38,7 +40,6 @@
System.out.println(accessor.get("test", null, 0));
System.out.println(accessor.get("test", null, 0).getSimpleFields().size());
}
-
}
class MyClass implements Runnable {
@@ -63,5 +64,4 @@
// System.out.println("END " + System.currentTimeMillis() + " --"
// + Thread.currentThread().getId());
}
-
}
diff --git a/helix-core/src/test/java/org/apache/helix/TestHelper.java b/helix-core/src/test/java/org/apache/helix/TestHelper.java
index fa93a72..9cac992 100644
--- a/helix-core/src/test/java/org/apache/helix/TestHelper.java
+++ b/helix-core/src/test/java/org/apache/helix/TestHelper.java
@@ -38,11 +38,6 @@
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
-import org.I0Itec.zkclient.IDefaultNameSpace;
-import org.I0Itec.zkclient.IZkChildListener;
-import org.I0Itec.zkclient.IZkDataListener;
-import org.I0Itec.zkclient.ZkServer;
-import org.I0Itec.zkclient.exception.ZkNoNodeException;
import org.apache.commons.io.FileUtils;
import org.apache.helix.PropertyKey.Builder;
import org.apache.helix.integration.manager.ZkTestManager;
@@ -51,8 +46,8 @@
import org.apache.helix.manager.zk.ZKHelixDataAccessor;
import org.apache.helix.manager.zk.ZNRecordSerializer;
import org.apache.helix.manager.zk.ZkBaseDataAccessor;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.client.SharedZkClientFactory;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
import org.apache.helix.model.CurrentState;
import org.apache.helix.model.ExternalView;
import org.apache.helix.model.IdealState.RebalanceMode;
@@ -63,11 +58,19 @@
import org.apache.helix.store.zk.ZNode;
import org.apache.helix.tools.ClusterSetup;
import org.apache.helix.util.ZKClientPool;
+import org.apache.helix.zookeeper.zkclient.IDefaultNameSpace;
+import org.apache.helix.zookeeper.zkclient.IZkChildListener;
+import org.apache.helix.zookeeper.zkclient.IZkDataListener;
+import org.apache.helix.zookeeper.zkclient.ZkClient;
+import org.apache.helix.zookeeper.zkclient.ZkServer;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNoNodeException;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
+
public class TestHelper {
private static final Logger LOG = LoggerFactory.getLogger(TestHelper.class);
public static final long WAIT_DURATION = 20 * 1000L; // 20 seconds
@@ -103,8 +106,8 @@
static public ZkServer startZkServer(final String zkAddress, final List<String> rootNamespaces,
boolean overwrite) throws Exception {
- System.out.println("Start zookeeper at " + zkAddress + " in thread "
- + Thread.currentThread().getName());
+ System.out.println(
+ "Start zookeeper at " + zkAddress + " in thread " + Thread.currentThread().getName());
String zkDir = zkAddress.replace(':', '_');
final String logDir = "/tmp/" + zkDir + "/logs";
@@ -117,7 +120,7 @@
IDefaultNameSpace defaultNameSpace = new IDefaultNameSpace() {
@Override
- public void createDefaultNameSpace(org.I0Itec.zkclient.ZkClient zkClient) {
+ public void createDefaultNameSpace(ZkClient zkClient) {
if (rootNamespaces == null) {
return;
}
@@ -142,8 +145,9 @@
static public void stopZkServer(ZkServer zkServer) {
if (zkServer != null) {
zkServer.shutdown();
- System.out.println("Shut down zookeeper at port " + zkServer.getPort() + " in thread "
- + Thread.currentThread().getName());
+ System.out.println(
+ "Shut down zookeeper at port " + zkServer.getPort() + " in thread " + Thread
+ .currentThread().getName());
}
}
@@ -186,8 +190,8 @@
// debug
// LOG.info(verifierName + ": wait " + ((i + 1) * 1000) + "ms to verify ("
// + result + ")");
- System.err.println(verifierName + ": wait " + ((i + 1) * 1000) + "ms to verify " + " ("
- + result + ")");
+ System.err.println(
+ verifierName + ": wait " + ((i + 1) * 1000) + "ms to verify " + " (" + result + ")");
LOG.debug("args:" + Arrays.toString(args));
// System.err.println("args:" + Arrays.toString(args));
@@ -240,7 +244,6 @@
if (extView != null && extView.getRecord().getMapFields().size() != 0) {
return false;
}
-
}
return true;
@@ -256,9 +259,10 @@
public static void setupCluster(String clusterName, String zkAddr, int startPort,
String participantNamePrefix, String resourceNamePrefix, int resourceNb, int partitionNb,
int nodesNb, int replica, String stateModelDef, boolean doRebalance) throws Exception {
- TestHelper.setupCluster(clusterName, zkAddr, startPort, participantNamePrefix,
- resourceNamePrefix, resourceNb, partitionNb, nodesNb, replica, stateModelDef,
- RebalanceMode.SEMI_AUTO, doRebalance);
+ TestHelper
+ .setupCluster(clusterName, zkAddr, startPort, participantNamePrefix, resourceNamePrefix,
+ resourceNb, partitionNb, nodesNb, replica, stateModelDef, RebalanceMode.SEMI_AUTO,
+ doRebalance);
}
public static void setupCluster(String clusterName, String zkAddr, int startPort,
@@ -338,12 +342,13 @@
ExternalView extView = accessor.getProperty(keyBuilder.externalView(resGroup));
for (String instance : stateMap.get(resGroupPartitionKey)) {
String actualState = extView.getStateMap(partitionKey).get(instance);
- Assert.assertNotNull(actualState, "externalView doesn't contain state for " + resGroup
- + "/" + partitionKey + " on " + instance + " (expect " + state + ")");
+ Assert.assertNotNull(actualState,
+ "externalView doesn't contain state for " + resGroup + "/" + partitionKey + " on "
+ + instance + " (expect " + state + ")");
- Assert
- .assertEquals(actualState, state, "externalView for " + resGroup + "/" + partitionKey
- + " on " + instance + " is " + actualState + " (expect " + state + ")");
+ Assert.assertEquals(actualState, state,
+ "externalView for " + resGroup + "/" + partitionKey + " on " + instance + " is "
+ + actualState + " (expect " + state + ")");
}
}
} finally {
@@ -519,8 +524,9 @@
ZNode node = map.get(key);
TreeSet<String> childSet = new TreeSet<String>();
childSet.addAll(node.getChildSet());
- System.out.print(key + "=" + node.getData() + ", " + childSet + ", "
- + (node.getStat() == null ? "null\n" : node.getStat()));
+ System.out.print(
+ key + "=" + node.getData() + ", " + childSet + ", " + (node.getStat() == null ? "null\n"
+ : node.getStat()));
}
System.out.println("END:Print cache");
}
@@ -600,8 +606,8 @@
Map<String, ZNode> cache, Map<String, ZNode> zkMap, boolean needVerifyStat) {
// equal size
if (zkMap.size() != cache.size()) {
- System.err.println("size mismatch: cacheSize: " + cache.size() + ", zkMapSize: "
- + zkMap.size());
+ System.err
+ .println("size mismatch: cacheSize: " + cache.size() + ", zkMapSize: " + zkMap.size());
System.out.println("cache: (" + cache.size() + ")");
TestHelper.printCache(cache);
@@ -622,31 +628,33 @@
return false;
}
- if ((zkNode.getData() == null && cacheNode.getData() != null)
- || (zkNode.getData() != null && cacheNode.getData() == null)
- || (zkNode.getData() != null && cacheNode.getData() != null && !zkNode.getData().equals(
- cacheNode.getData()))) {
+ if ((zkNode.getData() == null && cacheNode.getData() != null) || (zkNode.getData() != null
+ && cacheNode.getData() == null) || (zkNode.getData() != null
+ && cacheNode.getData() != null && !zkNode.getData().equals(cacheNode.getData()))) {
// data not equal
- System.err.println("data mismatch on path: " + path + ", inCache: " + cacheNode.getData()
- + ", onZk: " + zkNode.getData());
+ System.err.println(
+ "data mismatch on path: " + path + ", inCache: " + cacheNode.getData() + ", onZk: "
+ + zkNode.getData());
return false;
}
- if ((zkNode.getChildSet() == null && cacheNode.getChildSet() != null)
- || (zkNode.getChildSet() != null && cacheNode.getChildSet() == null)
- || (zkNode.getChildSet() != null && cacheNode.getChildSet() != null && !zkNode
- .getChildSet().equals(cacheNode.getChildSet()))) {
+ if ((zkNode.getChildSet() == null && cacheNode.getChildSet() != null) || (
+ zkNode.getChildSet() != null && cacheNode.getChildSet() == null) || (
+ zkNode.getChildSet() != null && cacheNode.getChildSet() != null && !zkNode.getChildSet()
+ .equals(cacheNode.getChildSet()))) {
// childSet not equal
- System.err.println("childSet mismatch on path: " + path + ", inCache: "
- + cacheNode.getChildSet() + ", onZk: " + zkNode.getChildSet());
+ System.err.println(
+ "childSet mismatch on path: " + path + ", inCache: " + cacheNode.getChildSet()
+ + ", onZk: " + zkNode.getChildSet());
return false;
}
if (needVerifyStat && pathsExcludeForStat != null && !pathsExcludeForStat.contains(path)) {
if (cacheNode.getStat() == null || !zkNode.getStat().equals(cacheNode.getStat())) {
// stat not equal
- System.err.println("Stat mismatch on path: " + path + ", inCache: " + cacheNode.getStat()
- + ", onZk: " + zkNode.getStat());
+ System.err.println(
+ "Stat mismatch on path: " + path + ", inCache: " + cacheNode.getStat() + ", onZk: "
+ + zkNode.getStat());
return false;
}
}
@@ -800,8 +808,8 @@
for (int i = 0; i < handlers.size(); i++) {
CallbackHandler handler = handlers.get(i);
String path = handler.getPath();
- sb.append(path.substring(manager.getClusterName().length() + 1) + ": "
- + handler.getListener());
+ sb.append(
+ path.substring(manager.getClusterName().length() + 1) + ": " + handler.getListener());
if (i < (handlers.size() - 1)) {
sb.append(", ");
}
diff --git a/helix-core/src/test/java/org/apache/helix/TestHierarchicalDataStore.java b/helix-core/src/test/java/org/apache/helix/TestHierarchicalDataStore.java
index aafcbf1..76ba625 100644
--- a/helix-core/src/test/java/org/apache/helix/TestHierarchicalDataStore.java
+++ b/helix-core/src/test/java/org/apache/helix/TestHierarchicalDataStore.java
@@ -22,8 +22,8 @@
import java.io.FileFilter;
import org.apache.helix.controller.HierarchicalDataHolder;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.client.SharedZkClientFactory;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
import org.testng.AssertJUnit;
import org.testng.annotations.Test;
diff --git a/helix-core/src/test/java/org/apache/helix/TestShuffledIdealState.java b/helix-core/src/test/java/org/apache/helix/TestShuffledIdealState.java
index 1297322..b5c9b26 100644
--- a/helix-core/src/test/java/org/apache/helix/TestShuffledIdealState.java
+++ b/helix-core/src/test/java/org/apache/helix/TestShuffledIdealState.java
@@ -34,6 +34,8 @@
import org.testng.Assert;
import org.testng.AssertJUnit;
import org.testng.annotations.Test;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+
public class TestShuffledIdealState {
@Test()
@@ -46,19 +48,17 @@
instanceNames.add("localhost_1233");
instanceNames.add("localhost_1234");
- ZNRecord result =
- IdealStateCalculatorByShuffling.calculateIdealState(instanceNames, partitions, replicas,
- dbName);
+ ZNRecord result = IdealStateCalculatorByShuffling
+ .calculateIdealState(instanceNames, partitions, replicas, dbName);
IdealCalculatorByConsistentHashing.printIdealStateStats(result, "MASTER");
IdealCalculatorByConsistentHashing.printIdealStateStats(result, "SLAVE");
- ZNRecord result2 =
- IdealStateCalculatorByRush.calculateIdealState(instanceNames, 1, partitions, replicas,
- dbName);
+ ZNRecord result2 = IdealStateCalculatorByRush
+ .calculateIdealState(instanceNames, 1, partitions, replicas, dbName);
- ZNRecord result3 =
- IdealCalculatorByConsistentHashing.calculateIdealState(instanceNames, partitions, replicas,
- dbName, new IdealCalculatorByConsistentHashing.FnvHash());
+ ZNRecord result3 = IdealCalculatorByConsistentHashing
+ .calculateIdealState(instanceNames, partitions, replicas, dbName,
+ new IdealCalculatorByConsistentHashing.FnvHash());
IdealCalculatorByConsistentHashing.printIdealStateStats(result3, "MASTER");
IdealCalculatorByConsistentHashing.printIdealStateStats(result3, "SLAVE");
IdealCalculatorByConsistentHashing.printIdealStateStats(result3, "");
@@ -95,7 +95,6 @@
System.out.println(zn3.toString());
AssertJUnit.assertTrue(zn3.toString().equalsIgnoreCase(result3.toString()));
System.out.println();
-
}
@Test
@@ -109,9 +108,8 @@
instanceNames.add("localhost_1233");
instanceNames.add("localhost_1234");
- ZNRecord result =
- IdealStateCalculatorByShuffling.calculateIdealState(instanceNames, partitions, replicas,
- dbName);
+ ZNRecord result = IdealStateCalculatorByShuffling
+ .calculateIdealState(instanceNames, partitions, replicas, dbName);
IdealCalculatorByConsistentHashing.printIdealStateStats(result, "MASTER");
IdealCalculatorByConsistentHashing.printIdealStateStats(result, "SLAVE");
Assert.assertTrue(verify(result));
@@ -125,9 +123,8 @@
for (int i = 0; i < instances; i++) {
instanceNames.add("localhost_" + (1231 + i));
}
- result =
- IdealStateCalculatorByShuffling.calculateIdealState(instanceNames, partitions, replicas,
- dbName);
+ result = IdealStateCalculatorByShuffling
+ .calculateIdealState(instanceNames, partitions, replicas, dbName);
IdealCalculatorByConsistentHashing.printIdealStateStats(result, "MASTER");
IdealCalculatorByConsistentHashing.printIdealStateStats(result, "SLAVE");
Assert.assertTrue(verify(result));
@@ -141,9 +138,8 @@
for (int i = 0; i < instances; i++) {
instanceNames.add("localhost_" + (1231 + i));
}
- result =
- IdealStateCalculatorByShuffling.calculateIdealState(instanceNames, partitions, replicas,
- dbName);
+ result = IdealStateCalculatorByShuffling
+ .calculateIdealState(instanceNames, partitions, replicas, dbName);
IdealCalculatorByConsistentHashing.printIdealStateStats(result, "MASTER");
IdealCalculatorByConsistentHashing.printIdealStateStats(result, "SLAVE");
Assert.assertTrue(verify(result));
@@ -157,9 +153,8 @@
for (int i = 0; i < instances; i++) {
instanceNames.add("localhost_" + (1231 + i));
}
- result =
- IdealStateCalculatorByShuffling.calculateIdealState(instanceNames, partitions, replicas,
- dbName);
+ result = IdealStateCalculatorByShuffling
+ .calculateIdealState(instanceNames, partitions, replicas, dbName);
IdealCalculatorByConsistentHashing.printIdealStateStats(result, "MASTER");
IdealCalculatorByConsistentHashing.printIdealStateStats(result, "SLAVE");
Assert.assertTrue(verify(result));
@@ -173,9 +168,8 @@
for (int i = 0; i < instances; i++) {
instanceNames.add("localhost_" + (1231 + i));
}
- result =
- IdealStateCalculatorByShuffling.calculateIdealState(instanceNames, partitions, replicas,
- dbName);
+ result = IdealStateCalculatorByShuffling
+ .calculateIdealState(instanceNames, partitions, replicas, dbName);
IdealCalculatorByConsistentHashing.printIdealStateStats(result, "MASTER");
IdealCalculatorByConsistentHashing.printIdealStateStats(result, "SLAVE");
Assert.assertTrue(verify(result));
@@ -189,9 +183,8 @@
for (int i = 0; i < instances; i++) {
instanceNames.add("localhost_" + (1231 + i));
}
- result =
- IdealStateCalculatorByShuffling.calculateIdealState(instanceNames, partitions, replicas,
- dbName);
+ result = IdealStateCalculatorByShuffling
+ .calculateIdealState(instanceNames, partitions, replicas, dbName);
IdealCalculatorByConsistentHashing.printIdealStateStats(result, "MASTER");
IdealCalculatorByConsistentHashing.printIdealStateStats(result, "SLAVE");
Assert.assertTrue(verify(result));
diff --git a/helix-core/src/test/java/org/apache/helix/TestZKRoutingInfoProvider.java b/helix-core/src/test/java/org/apache/helix/TestZKRoutingInfoProvider.java
index 5addcfe..d1e22f7 100644
--- a/helix-core/src/test/java/org/apache/helix/TestZKRoutingInfoProvider.java
+++ b/helix-core/src/test/java/org/apache/helix/TestZKRoutingInfoProvider.java
@@ -32,6 +32,8 @@
import org.apache.helix.model.Message;
import org.testng.AssertJUnit;
import org.testng.annotations.Test;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+
public class TestZKRoutingInfoProvider {
public Map<String, List<ZNRecord>> createCurrentStates(String[] dbNames, String[] nodeNames,
diff --git a/helix-core/src/test/java/org/apache/helix/TestZkBasis.java b/helix-core/src/test/java/org/apache/helix/TestZkBasis.java
index ef6d054..2b54ec0 100644
--- a/helix-core/src/test/java/org/apache/helix/TestZkBasis.java
+++ b/helix-core/src/test/java/org/apache/helix/TestZkBasis.java
@@ -27,11 +27,11 @@
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
-import org.I0Itec.zkclient.IZkChildListener;
-import org.I0Itec.zkclient.IZkDataListener;
import org.apache.helix.manager.zk.ZNRecordSerializer;
-import org.apache.helix.manager.zk.ZkClient;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.zkclient.IZkChildListener;
+import org.apache.helix.zookeeper.zkclient.IZkDataListener;
import org.testng.Assert;
import org.testng.annotations.Test;
diff --git a/helix-core/src/test/java/org/apache/helix/ZkTestHelper.java b/helix-core/src/test/java/org/apache/helix/ZkTestHelper.java
index 5b99fa4..c2b3d35 100644
--- a/helix-core/src/test/java/org/apache/helix/ZkTestHelper.java
+++ b/helix-core/src/test/java/org/apache/helix/ZkTestHelper.java
@@ -38,16 +38,16 @@
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
-import org.I0Itec.zkclient.IZkChildListener;
-import org.I0Itec.zkclient.IZkDataListener;
import org.apache.helix.PropertyKey.Builder;
import org.apache.helix.manager.zk.ZKHelixDataAccessor;
import org.apache.helix.manager.zk.ZkBaseDataAccessor;
-import org.apache.helix.manager.zk.ZkClient;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.zookeeper.IZkStateListener;
-import org.apache.helix.manager.zk.zookeeper.ZkConnection;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
import org.apache.helix.model.ExternalView;
+import org.apache.helix.zookeeper.zkclient.IZkChildListener;
+import org.apache.helix.zookeeper.zkclient.IZkDataListener;
+import org.apache.helix.zookeeper.zkclient.IZkStateListener;
+import org.apache.helix.zookeeper.zkclient.ZkClient;
+import org.apache.helix.zookeeper.zkclient.ZkConnection;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.EventType;
@@ -57,6 +57,8 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+
public class ZkTestHelper {
private static Logger LOG = LoggerFactory.getLogger(ZkTestHelper.class);
@@ -116,7 +118,7 @@
};
zkClient.subscribeStateChanges(listener);
- ZkConnection connection = ((ZkConnection) zkClient.getConnection());
+ ZkConnection connection = (ZkConnection) zkClient.getConnection();
ZooKeeper curZookeeper = connection.getZookeeper();
LOG.info("Before expiry. sessionId: " + Long.toHexString(curZookeeper.getSessionId()));
@@ -202,8 +204,8 @@
String newSessionId = Long.toHexString(curZookeeper.getSessionId());
LOG.info("After session expiry. sessionId: " + newSessionId + ", zk: " + curZookeeper);
- Assert.assertFalse(newSessionId.equals(oldSessionId), "Fail to expire current session, zk: "
- + curZookeeper);
+ Assert.assertFalse(newSessionId.equals(oldSessionId),
+ "Fail to expire current session, zk: " + curZookeeper);
}
/**
@@ -270,8 +272,9 @@
String expectState = expectInstanceStateMap.get(expectInstance);
boolean equals = expectState.equals(actualState);
if (op.equals("==") && !equals || op.equals("!=") && equals) {
- System.out.println(partition + "/" + instance + " state mismatch. actual state: "
- + actualState + ", but expect: " + expectState + ", op: " + op);
+ System.out.println(
+ partition + "/" + instance + " state mismatch. actual state: " + actualState
+ + ", but expect: " + expectState + ", op: " + op);
result = false;
}
}
@@ -345,8 +348,9 @@
// so add this retry logic
retry--;
} finally {
- if (sock != null)
+ if (sock != null) {
sock.close();
+ }
}
}
return listenerMap;
diff --git a/helix-core/src/test/java/org/apache/helix/common/ZkTestBase.java b/helix-core/src/test/java/org/apache/helix/common/ZkTestBase.java
index 61c2544..b9c08a9 100644
--- a/helix-core/src/test/java/org/apache/helix/common/ZkTestBase.java
+++ b/helix-core/src/test/java/org/apache/helix/common/ZkTestBase.java
@@ -33,7 +33,6 @@
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
-import org.I0Itec.zkclient.ZkServer;
import org.apache.helix.BaseDataAccessor;
import org.apache.helix.ConfigAccessor;
import org.apache.helix.HelixAdmin;
@@ -45,7 +44,8 @@
import org.apache.helix.PropertyPathBuilder;
import org.apache.helix.SystemPropertyKeys;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.api.config.HelixConfigProperty;
import org.apache.helix.controller.pipeline.AbstractAsyncBaseStage;
import org.apache.helix.controller.pipeline.Pipeline;
@@ -60,11 +60,8 @@
import org.apache.helix.manager.zk.ZKHelixDataAccessor;
import org.apache.helix.manager.zk.ZNRecordSerializer;
import org.apache.helix.manager.zk.ZkBaseDataAccessor;
-import org.apache.helix.manager.zk.ZkClient;
-import org.apache.helix.manager.zk.client.DedicatedZkClientFactory;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.zookeeper.IZkStateListener;
-import org.apache.helix.manager.zk.zookeeper.ZkConnection;
+import org.apache.helix.zookeeper.impl.factory.DedicatedZkClientFactory;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
import org.apache.helix.model.BuiltInStateModelDefinitions;
import org.apache.helix.model.ClusterConfig;
import org.apache.helix.model.ConfigScope;
@@ -81,6 +78,9 @@
import org.apache.helix.tools.ClusterSetup;
import org.apache.helix.tools.ClusterStateVerifier;
import org.apache.helix.tools.StateModelConfigGenerator;
+import org.apache.helix.zookeeper.zkclient.IZkStateListener;
+import org.apache.helix.zookeeper.zkclient.ZkConnection;
+import org.apache.helix.zookeeper.zkclient.ZkServer;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
diff --git a/helix-core/src/test/java/org/apache/helix/common/caches/TestCurrentStateSnapshot.java b/helix-core/src/test/java/org/apache/helix/common/caches/TestCurrentStateSnapshot.java
index 62514a4..b9b6270 100644
--- a/helix-core/src/test/java/org/apache/helix/common/caches/TestCurrentStateSnapshot.java
+++ b/helix-core/src/test/java/org/apache/helix/common/caches/TestCurrentStateSnapshot.java
@@ -7,7 +7,7 @@
import org.apache.helix.MockAccessor;
import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.model.CurrentState;
import org.apache.helix.model.LiveInstance;
import org.testng.Assert;
diff --git a/helix-core/src/test/java/org/apache/helix/controller/changedetector/TestResourceChangeDetector.java b/helix-core/src/test/java/org/apache/helix/controller/changedetector/TestResourceChangeDetector.java
index bac9842..000964b 100644
--- a/helix-core/src/test/java/org/apache/helix/controller/changedetector/TestResourceChangeDetector.java
+++ b/helix-core/src/test/java/org/apache/helix/controller/changedetector/TestResourceChangeDetector.java
@@ -276,11 +276,16 @@
* Remove an instance completely and see if detector detects.
*/
@Test(dependsOnMethods = "testDisconnectReconnectInstance")
- public void testRemoveInstance() {
+ public void testRemoveInstance()
+ throws Exception {
_participants[0].syncStop();
InstanceConfig instanceConfig =
_dataAccessor.getProperty(_keyBuilder.instanceConfig(_participants[0].getInstanceName()));
_gSetupTool.getClusterManagementTool().dropInstance(CLUSTER_NAME, instanceConfig);
+ // Verify that instance has been removed
+ Assert.assertTrue(TestHelper.verify(() -> _dataAccessor
+ .getProperty(_dataAccessor.keyBuilder().instance(_participants[0].getInstanceName()))
+ == null, TestHelper.WAIT_DURATION));
_dataProvider.notifyDataChange(ChangeType.LIVE_INSTANCE);
_dataProvider.notifyDataChange(ChangeType.INSTANCE_CONFIG);
diff --git a/helix-core/src/test/java/org/apache/helix/controller/rebalancer/TestAutoRebalanceStrategy.java b/helix-core/src/test/java/org/apache/helix/controller/rebalancer/TestAutoRebalanceStrategy.java
index 26c8e62..0b1370e 100644
--- a/helix-core/src/test/java/org/apache/helix/controller/rebalancer/TestAutoRebalanceStrategy.java
+++ b/helix-core/src/test/java/org/apache/helix/controller/rebalancer/TestAutoRebalanceStrategy.java
@@ -41,7 +41,7 @@
import org.apache.helix.HelixDefinedState;
import org.apache.helix.MockAccessor;
import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
import org.apache.helix.controller.rebalancer.strategy.AutoRebalanceStrategy;
import org.apache.helix.controller.rebalancer.strategy.RebalanceStrategy;
diff --git a/helix-core/src/test/java/org/apache/helix/controller/rebalancer/TestAutoRebalanceStrategyImbalanceAssignment.java b/helix-core/src/test/java/org/apache/helix/controller/rebalancer/TestAutoRebalanceStrategyImbalanceAssignment.java
index a15077c..dc4f0d4 100644
--- a/helix-core/src/test/java/org/apache/helix/controller/rebalancer/TestAutoRebalanceStrategyImbalanceAssignment.java
+++ b/helix-core/src/test/java/org/apache/helix/controller/rebalancer/TestAutoRebalanceStrategyImbalanceAssignment.java
@@ -25,7 +25,7 @@
import java.util.List;
import java.util.Map;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
import org.apache.helix.controller.rebalancer.strategy.AutoRebalanceStrategy;
import org.testng.Assert;
diff --git a/helix-core/src/test/java/org/apache/helix/controller/rebalancer/TestZeroReplicaAvoidance.java b/helix-core/src/test/java/org/apache/helix/controller/rebalancer/TestZeroReplicaAvoidance.java
index 53a8f49..9a5e085 100644
--- a/helix-core/src/test/java/org/apache/helix/controller/rebalancer/TestZeroReplicaAvoidance.java
+++ b/helix-core/src/test/java/org/apache/helix/controller/rebalancer/TestZeroReplicaAvoidance.java
@@ -32,7 +32,7 @@
import java.util.Set;
import java.util.UUID;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.controller.stages.BaseStageTest;
import org.apache.helix.controller.stages.CurrentStateOutput;
import org.apache.helix.model.BuiltInStateModelDefinitions;
diff --git a/helix-core/src/test/java/org/apache/helix/controller/stages/BaseStageTest.java b/helix-core/src/test/java/org/apache/helix/controller/stages/BaseStageTest.java
index a91d220..3e85643 100644
--- a/helix-core/src/test/java/org/apache/helix/controller/stages/BaseStageTest.java
+++ b/helix-core/src/test/java/org/apache/helix/controller/stages/BaseStageTest.java
@@ -31,7 +31,7 @@
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.HelixManager;
import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.controller.pipeline.Stage;
import org.apache.helix.controller.pipeline.StageContext;
import org.apache.helix.mock.MockHelixAdmin;
diff --git a/helix-core/src/test/java/org/apache/helix/controller/stages/DummyClusterManager.java b/helix-core/src/test/java/org/apache/helix/controller/stages/DummyClusterManager.java
index e221f45..05631c8 100644
--- a/helix-core/src/test/java/org/apache/helix/controller/stages/DummyClusterManager.java
+++ b/helix-core/src/test/java/org/apache/helix/controller/stages/DummyClusterManager.java
@@ -31,7 +31,7 @@
import org.apache.helix.LiveInstanceInfoProvider;
import org.apache.helix.PreConnectCallback;
import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.api.listeners.ClusterConfigChangeListener;
import org.apache.helix.api.listeners.ConfigChangeListener;
import org.apache.helix.api.listeners.ControllerChangeListener;
diff --git a/helix-core/src/test/java/org/apache/helix/controller/stages/TestBestPossibleCalcStageCompatibility.java b/helix-core/src/test/java/org/apache/helix/controller/stages/TestBestPossibleCalcStageCompatibility.java
index 2205c23..73f4c88 100644
--- a/helix-core/src/test/java/org/apache/helix/controller/stages/TestBestPossibleCalcStageCompatibility.java
+++ b/helix-core/src/test/java/org/apache/helix/controller/stages/TestBestPossibleCalcStageCompatibility.java
@@ -25,7 +25,7 @@
import java.util.Map;
import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
import org.apache.helix.model.IdealState;
import org.apache.helix.model.IdealState.IdealStateModeProperty;
diff --git a/helix-core/src/test/java/org/apache/helix/controller/stages/TestCompatibilityCheckStage.java b/helix-core/src/test/java/org/apache/helix/controller/stages/TestCompatibilityCheckStage.java
index d30ec5e..f910da5 100644
--- a/helix-core/src/test/java/org/apache/helix/controller/stages/TestCompatibilityCheckStage.java
+++ b/helix-core/src/test/java/org/apache/helix/controller/stages/TestCompatibilityCheckStage.java
@@ -23,7 +23,7 @@
import java.util.List;
import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
import org.apache.helix.controller.pipeline.StageContext;
import org.apache.helix.mock.MockManager;
diff --git a/helix-core/src/test/java/org/apache/helix/controller/stages/TestCurrentStateComputationStage.java b/helix-core/src/test/java/org/apache/helix/controller/stages/TestCurrentStateComputationStage.java
index be7c208..1f354d7 100644
--- a/helix-core/src/test/java/org/apache/helix/controller/stages/TestCurrentStateComputationStage.java
+++ b/helix-core/src/test/java/org/apache/helix/controller/stages/TestCurrentStateComputationStage.java
@@ -22,7 +22,7 @@
import java.util.Map;
import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
import org.apache.helix.model.CurrentState;
import org.apache.helix.model.Message;
diff --git a/helix-core/src/test/java/org/apache/helix/controller/stages/TestMessageThrottleStage.java b/helix-core/src/test/java/org/apache/helix/controller/stages/TestMessageThrottleStage.java
index 1c84e65..e0433d9 100644
--- a/helix-core/src/test/java/org/apache/helix/controller/stages/TestMessageThrottleStage.java
+++ b/helix-core/src/test/java/org/apache/helix/controller/stages/TestMessageThrottleStage.java
@@ -29,7 +29,7 @@
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.HelixManager;
import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.ZkUnitTestBase;
import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
import org.apache.helix.controller.pipeline.Pipeline;
diff --git a/helix-core/src/test/java/org/apache/helix/controller/stages/TestResourceComputationStage.java b/helix-core/src/test/java/org/apache/helix/controller/stages/TestResourceComputationStage.java
index 8b0119a..b04d7d5 100644
--- a/helix-core/src/test/java/org/apache/helix/controller/stages/TestResourceComputationStage.java
+++ b/helix-core/src/test/java/org/apache/helix/controller/stages/TestResourceComputationStage.java
@@ -26,7 +26,7 @@
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
import org.apache.helix.controller.pipeline.StageContext;
import org.apache.helix.model.CurrentState;
diff --git a/helix-core/src/test/java/org/apache/helix/controller/stages/TestTaskStage.java b/helix-core/src/test/java/org/apache/helix/controller/stages/TestTaskStage.java
index 0d98ed8..fefc737 100644
--- a/helix-core/src/test/java/org/apache/helix/controller/stages/TestTaskStage.java
+++ b/helix-core/src/test/java/org/apache/helix/controller/stages/TestTaskStage.java
@@ -3,7 +3,7 @@
import org.apache.helix.AccessOption;
import org.apache.helix.PropertyKey;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.common.caches.TaskDataCache;
import org.apache.helix.controller.dataproviders.WorkflowControllerDataProvider;
import org.apache.helix.controller.stages.task.TaskPersistDataStage;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/TestAddStateModelFactoryAfterConnect.java b/helix-core/src/test/java/org/apache/helix/integration/TestAddStateModelFactoryAfterConnect.java
index 413c343..9106587 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/TestAddStateModelFactoryAfterConnect.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/TestAddStateModelFactoryAfterConnect.java
@@ -24,7 +24,7 @@
import org.apache.helix.PropertyKey.Builder;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.common.ZkTestBase;
import org.apache.helix.integration.manager.ClusterControllerManager;
import org.apache.helix.integration.manager.MockParticipantManager;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/TestBucketizedResource.java b/helix-core/src/test/java/org/apache/helix/integration/TestBucketizedResource.java
index a9c6053..1590058 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/TestBucketizedResource.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/TestBucketizedResource.java
@@ -28,7 +28,7 @@
import org.apache.helix.NotificationContext.Type;
import org.apache.helix.PropertyKey;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.common.ZkTestBase;
import org.apache.helix.integration.manager.ClusterControllerManager;
import org.apache.helix.integration.manager.MockParticipantManager;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/TestCarryOverBadCurState.java b/helix-core/src/test/java/org/apache/helix/integration/TestCarryOverBadCurState.java
index c1da527..d0bfe86 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/TestCarryOverBadCurState.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/TestCarryOverBadCurState.java
@@ -23,7 +23,7 @@
import org.apache.helix.PropertyPathBuilder;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.common.ZkTestBase;
import org.apache.helix.integration.manager.ClusterControllerManager;
import org.apache.helix.integration.manager.MockParticipantManager;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/TestCleanupExternalView.java b/helix-core/src/test/java/org/apache/helix/integration/TestCleanupExternalView.java
index f5b87c5..9096a86 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/TestCleanupExternalView.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/TestCleanupExternalView.java
@@ -23,7 +23,7 @@
import org.apache.helix.PropertyKey;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.ZkTestHelper;
import org.apache.helix.ZkUnitTestBase;
import org.apache.helix.integration.manager.ClusterControllerManager;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/TestCorrectnessOnConnectivityLoss.java b/helix-core/src/test/java/org/apache/helix/integration/TestCorrectnessOnConnectivityLoss.java
index b7acfda..f97b10f 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/TestCorrectnessOnConnectivityLoss.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/TestCorrectnessOnConnectivityLoss.java
@@ -23,7 +23,6 @@
import java.util.Map;
import com.google.common.collect.Maps;
-import org.I0Itec.zkclient.ZkServer;
import org.apache.helix.HelixManager;
import org.apache.helix.HelixManagerFactory;
import org.apache.helix.InstanceType;
@@ -40,6 +39,7 @@
import org.apache.helix.spectator.RoutingTableProvider;
import org.apache.helix.tools.ClusterStateVerifier;
import org.apache.helix.tools.ClusterStateVerifier.BestPossAndExtViewZkVerifier;
+import org.apache.helix.zookeeper.zkclient.ZkServer;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/TestDisable.java b/helix-core/src/test/java/org/apache/helix/integration/TestDisable.java
index 5db4f82..9c5861d 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/TestDisable.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/TestDisable.java
@@ -25,7 +25,7 @@
import org.apache.helix.PropertyKey.Builder;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.ZkTestHelper;
import org.apache.helix.common.ZkTestBase;
import org.apache.helix.integration.manager.ClusterControllerManager;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/TestDisableCustomCodeRunner.java b/helix-core/src/test/java/org/apache/helix/integration/TestDisableCustomCodeRunner.java
index 3c84a28..d087026 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/TestDisableCustomCodeRunner.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/TestDisableCustomCodeRunner.java
@@ -31,7 +31,7 @@
import org.apache.helix.NotificationContext;
import org.apache.helix.PropertyKey;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.ZkUnitTestBase;
import org.apache.helix.integration.manager.ClusterControllerManager;
import org.apache.helix.integration.manager.MockParticipantManager;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/TestDisableExternalView.java b/helix-core/src/test/java/org/apache/helix/integration/TestDisableExternalView.java
index a021153..d8c5a48 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/TestDisableExternalView.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/TestDisableExternalView.java
@@ -23,7 +23,7 @@
import org.apache.helix.HelixProperty;
import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.common.ZkTestBase;
import org.apache.helix.integration.manager.ClusterControllerManager;
import org.apache.helix.integration.manager.MockParticipantManager;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/TestDisableResource.java b/helix-core/src/test/java/org/apache/helix/integration/TestDisableResource.java
index 3b75821..d12cc7e 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/TestDisableResource.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/TestDisableResource.java
@@ -29,7 +29,7 @@
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.PropertyKey;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.ZkUnitTestBase;
import org.apache.helix.integration.manager.ClusterControllerManager;
import org.apache.helix.integration.manager.MockParticipantManager;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/TestDistributedCMMain.java b/helix-core/src/test/java/org/apache/helix/integration/TestDistributedCMMain.java
index 5ee5aa9..6237378 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/TestDistributedCMMain.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/TestDistributedCMMain.java
@@ -25,7 +25,7 @@
import org.apache.helix.PropertyKey.Builder;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.common.ZkTestBase;
import org.apache.helix.integration.manager.ClusterDistributedController;
import org.apache.helix.integration.manager.MockParticipantManager;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/TestDistributedClusterController.java b/helix-core/src/test/java/org/apache/helix/integration/TestDistributedClusterController.java
index 581759a..b6db274 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/TestDistributedClusterController.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/TestDistributedClusterController.java
@@ -25,7 +25,7 @@
import org.apache.helix.PropertyKey.Builder;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.common.ZkTestBase;
import org.apache.helix.integration.manager.ClusterDistributedController;
import org.apache.helix.integration.manager.MockParticipantManager;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/TestDriver.java b/helix-core/src/test/java/org/apache/helix/integration/TestDriver.java
index cc8eef5..e4dc10d 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/TestDriver.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/TestDriver.java
@@ -28,13 +28,13 @@
import org.apache.helix.HelixManager;
import org.apache.helix.PropertyPathBuilder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.common.ZkTestBase;
import org.apache.helix.integration.manager.ClusterControllerManager;
import org.apache.helix.integration.manager.MockParticipantManager;
import org.apache.helix.manager.zk.ZNRecordSerializer;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.client.SharedZkClientFactory;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
import org.apache.helix.model.IdealState.IdealStateProperty;
import org.apache.helix.model.IdealState.RebalanceMode;
import org.apache.helix.store.PropertyJsonSerializer;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/TestEnableCompression.java b/helix-core/src/test/java/org/apache/helix/integration/TestEnableCompression.java
index 2110705..39e412c 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/TestEnableCompression.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/TestEnableCompression.java
@@ -4,19 +4,19 @@
import java.util.Date;
import java.util.List;
-import org.I0Itec.zkclient.serialize.BytesPushThroughSerializer;
import org.apache.helix.PropertyPathBuilder;
import org.apache.helix.TestHelper;
import org.apache.helix.common.ZkTestBase;
import org.apache.helix.integration.manager.ClusterControllerManager;
import org.apache.helix.integration.manager.MockParticipantManager;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.client.SharedZkClientFactory;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
import org.apache.helix.model.IdealState;
import org.apache.helix.model.builder.CustomModeISBuilder;
import org.apache.helix.tools.ClusterStateVerifier;
import org.apache.helix.tools.ClusterStateVerifier.BestPossAndExtViewZkVerifier;
import org.apache.helix.util.GZipCompressionUtil;
+import org.apache.helix.zookeeper.zkclient.serialize.BytesPushThroughSerializer;
import org.testng.Assert;
import org.testng.annotations.Test;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/TestEntropyFreeNodeBounce.java b/helix-core/src/test/java/org/apache/helix/integration/TestEntropyFreeNodeBounce.java
index 3bd01ad..8d558f9 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/TestEntropyFreeNodeBounce.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/TestEntropyFreeNodeBounce.java
@@ -31,14 +31,14 @@
import org.apache.helix.NotificationContext;
import org.apache.helix.PropertyKey;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.ZkUnitTestBase;
import org.apache.helix.integration.manager.ClusterControllerManager;
import org.apache.helix.manager.zk.ZKHelixAdmin;
import org.apache.helix.manager.zk.ZKHelixDataAccessor;
import org.apache.helix.manager.zk.ZKHelixManager;
import org.apache.helix.manager.zk.ZkBaseDataAccessor;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.model.ExternalView;
import org.apache.helix.model.IdealState.RebalanceMode;
import org.apache.helix.model.Message;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/TestExternalViewUpdates.java b/helix-core/src/test/java/org/apache/helix/integration/TestExternalViewUpdates.java
index 46dc4e4..5d01a1d 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/TestExternalViewUpdates.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/TestExternalViewUpdates.java
@@ -26,7 +26,7 @@
import org.apache.helix.BaseDataAccessor;
import org.apache.helix.PropertyKey.Builder;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.common.ZkTestBase;
import org.apache.helix.integration.manager.ClusterControllerManager;
import org.apache.helix.integration.manager.MockParticipantManager;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/TestNoThrottleDisabledPartitions.java b/helix-core/src/test/java/org/apache/helix/integration/TestNoThrottleDisabledPartitions.java
index 573aebf..07eaf4e 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/TestNoThrottleDisabledPartitions.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/TestNoThrottleDisabledPartitions.java
@@ -26,7 +26,7 @@
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.PropertyKey;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.api.config.StateTransitionThrottleConfig;
import org.apache.helix.common.ZkTestBase;
import org.apache.helix.integration.manager.ClusterControllerManager;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/TestNullReplica.java b/helix-core/src/test/java/org/apache/helix/integration/TestNullReplica.java
index 03cd323..9749ab0 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/TestNullReplica.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/TestNullReplica.java
@@ -23,7 +23,7 @@
import org.apache.helix.PropertyPathBuilder;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.common.ZkTestBase;
import org.apache.helix.integration.manager.ClusterControllerManager;
import org.apache.helix.integration.manager.MockParticipantManager;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/TestPartitionLevelTransitionConstraint.java b/helix-core/src/test/java/org/apache/helix/integration/TestPartitionLevelTransitionConstraint.java
index d74b4ac..6deb6e1 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/TestPartitionLevelTransitionConstraint.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/TestPartitionLevelTransitionConstraint.java
@@ -29,7 +29,7 @@
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.NotificationContext;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.common.ZkTestBase;
import org.apache.helix.integration.manager.ClusterControllerManager;
import org.apache.helix.integration.manager.MockParticipantManager;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/TestPersistAssignmentStage.java b/helix-core/src/test/java/org/apache/helix/integration/TestPersistAssignmentStage.java
index b029ee4..94147d2 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/TestPersistAssignmentStage.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/TestPersistAssignmentStage.java
@@ -6,7 +6,7 @@
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
import org.apache.helix.controller.stages.AttributeName;
import org.apache.helix.controller.stages.BestPossibleStateOutput;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/TestPreferenceListAsQueue.java b/helix-core/src/test/java/org/apache/helix/integration/TestPreferenceListAsQueue.java
index 79a26a5..52bb979 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/TestPreferenceListAsQueue.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/TestPreferenceListAsQueue.java
@@ -27,7 +27,6 @@
import java.util.concurrent.TimeUnit;
import com.google.common.collect.Lists;
-import org.I0Itec.zkclient.DataUpdater;
import org.apache.helix.AccessOption;
import org.apache.helix.HelixAdmin;
import org.apache.helix.HelixDataAccessor;
@@ -37,7 +36,7 @@
import org.apache.helix.NotificationContext;
import org.apache.helix.PropertyKey;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.ZkUnitTestBase;
import org.apache.helix.model.ClusterConstraints.ConstraintAttribute;
import org.apache.helix.model.ClusterConstraints.ConstraintType;
@@ -50,6 +49,7 @@
import org.apache.helix.participant.statemachine.StateModel;
import org.apache.helix.participant.statemachine.StateModelFactory;
import org.apache.helix.tools.ClusterSetup;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/TestRenamePartition.java b/helix-core/src/test/java/org/apache/helix/integration/TestRenamePartition.java
index a8e89aa..66623f8 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/TestRenamePartition.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/TestRenamePartition.java
@@ -27,7 +27,7 @@
import org.apache.helix.PropertyKey.Builder;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.common.ZkTestBase;
import org.apache.helix.integration.manager.ClusterControllerManager;
import org.apache.helix.integration.manager.MockParticipantManager;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/TestResetPartitionState.java b/helix-core/src/test/java/org/apache/helix/integration/TestResetPartitionState.java
index 3a653f2..5e850ba 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/TestResetPartitionState.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/TestResetPartitionState.java
@@ -27,7 +27,7 @@
import org.apache.helix.NotificationContext;
import org.apache.helix.PropertyKey.Builder;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.common.ZkTestBase;
import org.apache.helix.integration.manager.ClusterControllerManager;
import org.apache.helix.integration.manager.MockParticipantManager;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/TestResourceGroupEndtoEnd.java b/helix-core/src/test/java/org/apache/helix/integration/TestResourceGroupEndtoEnd.java
index 5f82fe6..0aa5787 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/TestResourceGroupEndtoEnd.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/TestResourceGroupEndtoEnd.java
@@ -36,7 +36,7 @@
import org.apache.helix.manager.zk.CallbackHandler;
import org.apache.helix.manager.zk.ZKHelixAdmin;
import org.apache.helix.manager.zk.ZKHelixManager;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
import org.apache.helix.mock.participant.DummyProcess;
import org.apache.helix.model.BuiltInStateModelDefinitions;
import org.apache.helix.model.IdealState;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/TestResourceWithSamePartitionKey.java b/helix-core/src/test/java/org/apache/helix/integration/TestResourceWithSamePartitionKey.java
index 23bc801..0d1313a 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/TestResourceWithSamePartitionKey.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/TestResourceWithSamePartitionKey.java
@@ -25,7 +25,7 @@
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.PropertyKey;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.ZkUnitTestBase;
import org.apache.helix.integration.manager.ClusterControllerManager;
import org.apache.helix.integration.manager.MockParticipantManager;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/TestSyncSessionToController.java b/helix-core/src/test/java/org/apache/helix/integration/TestSyncSessionToController.java
index 8b503a5..5eefc32 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/TestSyncSessionToController.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/TestSyncSessionToController.java
@@ -27,7 +27,7 @@
import org.apache.helix.NotificationContext;
import org.apache.helix.PropertyKey;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.ZkTestHelper;
import org.apache.helix.api.listeners.MessageListener;
import org.apache.helix.common.ZkTestBase;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/TestWeightBasedRebalanceUtil.java b/helix-core/src/test/java/org/apache/helix/integration/TestWeightBasedRebalanceUtil.java
index 9dfda50..ee3a3d0 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/TestWeightBasedRebalanceUtil.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/TestWeightBasedRebalanceUtil.java
@@ -28,7 +28,7 @@
import java.util.Map;
import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.api.config.RebalanceConfig;
import org.apache.helix.api.rebalancer.constraint.AbstractRebalanceHardConstraint;
import org.apache.helix.api.rebalancer.constraint.AbstractRebalanceSoftConstraint;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/TestZkCallbackHandlerLeak.java b/helix-core/src/test/java/org/apache/helix/integration/TestZkCallbackHandlerLeak.java
index b514e3d..4682c52 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/TestZkCallbackHandlerLeak.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/TestZkCallbackHandlerLeak.java
@@ -24,8 +24,6 @@
import java.util.Map;
import java.util.Set;
-import org.I0Itec.zkclient.IZkChildListener;
-import org.I0Itec.zkclient.IZkDataListener;
import org.apache.helix.CurrentStateChangeListener;
import org.apache.helix.NotificationContext;
import org.apache.helix.PropertyKey;
@@ -36,11 +34,13 @@
import org.apache.helix.integration.manager.MockParticipantManager;
import org.apache.helix.integration.manager.ZkTestManager;
import org.apache.helix.manager.zk.CallbackHandler;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
import org.apache.helix.model.CurrentState;
import org.apache.helix.tools.ClusterStateVerifier;
import org.apache.helix.tools.ClusterVerifiers.BestPossibleExternalViewVerifier;
import org.apache.helix.tools.ClusterVerifiers.ZkHelixClusterVerifier;
+import org.apache.helix.zookeeper.zkclient.IZkChildListener;
+import org.apache.helix.zookeeper.zkclient.IZkDataListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/TestZkConnectionLost.java b/helix-core/src/test/java/org/apache/helix/integration/TestZkConnectionLost.java
index 0bbfb52..c790a45 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/TestZkConnectionLost.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/TestZkConnectionLost.java
@@ -27,7 +27,6 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
-import org.I0Itec.zkclient.ZkServer;
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.HelixException;
import org.apache.helix.SystemPropertyKeys;
@@ -40,8 +39,8 @@
import org.apache.helix.integration.task.WorkflowGenerator;
import org.apache.helix.manager.zk.ZKHelixDataAccessor;
import org.apache.helix.manager.zk.ZNRecordSerializer;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.client.SharedZkClientFactory;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
import org.apache.helix.task.JobConfig;
import org.apache.helix.task.JobQueue;
import org.apache.helix.task.TaskState;
@@ -49,6 +48,7 @@
import org.apache.helix.tools.ClusterSetup;
import org.apache.helix.tools.ClusterVerifiers.BestPossibleExternalViewVerifier;
import org.apache.helix.tools.ClusterVerifiers.ZkHelixClusterVerifier;
+import org.apache.helix.zookeeper.zkclient.ZkServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/controller/TestControllerDataProviderSelectiveUpdate.java b/helix-core/src/test/java/org/apache/helix/integration/controller/TestControllerDataProviderSelectiveUpdate.java
index a34c064..9115e21 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/controller/TestControllerDataProviderSelectiveUpdate.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/controller/TestControllerDataProviderSelectiveUpdate.java
@@ -22,7 +22,7 @@
import org.apache.helix.HelixConstants;
import org.apache.helix.PropertyType;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
import org.apache.helix.integration.common.ZkStandAloneCMTestBase;
import org.apache.helix.integration.task.WorkflowGenerator;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/controller/TestControllerLeadershipChange.java b/helix-core/src/test/java/org/apache/helix/integration/controller/TestControllerLeadershipChange.java
index 73eeb55..8a1ff03 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/controller/TestControllerLeadershipChange.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/controller/TestControllerLeadershipChange.java
@@ -34,7 +34,7 @@
import org.apache.helix.integration.manager.ClusterControllerManager;
import org.apache.helix.integration.manager.MockParticipantManager;
import org.apache.helix.manager.zk.CallbackHandler;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
import org.apache.helix.model.IdealState;
import org.apache.helix.model.LiveInstance;
import org.apache.helix.monitoring.mbeans.MonitorDomainNames;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/controller/TestControllerLiveLock.java b/helix-core/src/test/java/org/apache/helix/integration/controller/TestControllerLiveLock.java
index 0dff764..ce5db71 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/controller/TestControllerLiveLock.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/controller/TestControllerLiveLock.java
@@ -27,7 +27,7 @@
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.PropertyKey;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.ZkUnitTestBase;
import org.apache.helix.integration.manager.ClusterControllerManager;
import org.apache.helix.integration.manager.MockParticipantManager;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/manager/ClusterControllerManager.java b/helix-core/src/test/java/org/apache/helix/integration/manager/ClusterControllerManager.java
index d4c3283..7d810fb 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/manager/ClusterControllerManager.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/manager/ClusterControllerManager.java
@@ -26,7 +26,7 @@
import org.apache.helix.InstanceType;
import org.apache.helix.manager.zk.CallbackHandler;
import org.apache.helix.manager.zk.ZKHelixManager;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/manager/ClusterDistributedController.java b/helix-core/src/test/java/org/apache/helix/integration/manager/ClusterDistributedController.java
index d17f96c..8e15928 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/manager/ClusterDistributedController.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/manager/ClusterDistributedController.java
@@ -25,7 +25,7 @@
import org.apache.helix.InstanceType;
import org.apache.helix.manager.zk.CallbackHandler;
import org.apache.helix.manager.zk.ZKHelixManager;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
import org.apache.helix.participant.DistClusterControllerStateModelFactory;
import org.apache.helix.participant.StateMachineEngine;
import org.slf4j.Logger;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/manager/MockParticipantManager.java b/helix-core/src/test/java/org/apache/helix/integration/manager/MockParticipantManager.java
index ed4612e..0036e0d 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/manager/MockParticipantManager.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/manager/MockParticipantManager.java
@@ -25,7 +25,7 @@
import org.apache.helix.InstanceType;
import org.apache.helix.manager.zk.CallbackHandler;
import org.apache.helix.manager.zk.ZKHelixManager;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
import org.apache.helix.mock.participant.DummyProcess.DummyLeaderStandbyStateModelFactory;
import org.apache.helix.mock.participant.DummyProcess.DummyOnlineOfflineStateModelFactory;
import org.apache.helix.mock.participant.MockMSModelFactory;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/manager/TestConsecutiveZkSessionExpiry.java b/helix-core/src/test/java/org/apache/helix/integration/manager/TestConsecutiveZkSessionExpiry.java
index e64306e..a948496 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/manager/TestConsecutiveZkSessionExpiry.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/manager/TestConsecutiveZkSessionExpiry.java
@@ -27,7 +27,7 @@
import org.apache.helix.PreConnectCallback;
import org.apache.helix.PropertyKey;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.ZkTestHelper;
import org.apache.helix.ZkUnitTestBase;
import org.apache.helix.manager.zk.CallbackHandler;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/manager/TestHelixDataAccessor.java b/helix-core/src/test/java/org/apache/helix/integration/manager/TestHelixDataAccessor.java
index 6789d1c..5277a52 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/manager/TestHelixDataAccessor.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/manager/TestHelixDataAccessor.java
@@ -28,7 +28,7 @@
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.HelixProperty;
import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.api.exceptions.HelixMetaDataAccessException;
import org.apache.helix.common.ZkTestBase;
import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/manager/TestParticipantManager.java b/helix-core/src/test/java/org/apache/helix/integration/manager/TestParticipantManager.java
index 55053a5..aef7ff6 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/manager/TestParticipantManager.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/manager/TestParticipantManager.java
@@ -37,7 +37,7 @@
import org.apache.helix.PropertyPathBuilder;
import org.apache.helix.SystemPropertyKeys;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.ZkTestHelper;
import org.apache.helix.common.ZkTestBase;
import org.apache.helix.manager.zk.ZKHelixDataAccessor;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/manager/ZkTestManager.java b/helix-core/src/test/java/org/apache/helix/integration/manager/ZkTestManager.java
index bf4209b..1a6903a 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/manager/ZkTestManager.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/manager/ZkTestManager.java
@@ -22,7 +22,7 @@
import java.util.List;
import org.apache.helix.manager.zk.CallbackHandler;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
public interface ZkTestManager {
HelixZkClient getZkClient();
diff --git a/helix-core/src/test/java/org/apache/helix/integration/messaging/TestBatchMessage.java b/helix-core/src/test/java/org/apache/helix/integration/messaging/TestBatchMessage.java
index 0b16df2..590c9c9 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/messaging/TestBatchMessage.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/messaging/TestBatchMessage.java
@@ -25,11 +25,10 @@
import java.util.Map;
import java.util.Set;
-import org.I0Itec.zkclient.IZkChildListener;
import org.apache.helix.HelixProperty.HelixPropertyAttribute;
import org.apache.helix.PropertyKey.Builder;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.common.ZkTestBase;
import org.apache.helix.integration.manager.ClusterControllerManager;
import org.apache.helix.integration.manager.MockParticipantManager;
@@ -41,6 +40,7 @@
import org.apache.helix.tools.ClusterSetup;
import org.apache.helix.tools.ClusterStateVerifier;
import org.apache.helix.tools.ClusterStateVerifier.BestPossAndExtViewZkVerifier;
+import org.apache.helix.zookeeper.zkclient.IZkChildListener;
import org.testng.Assert;
import org.testng.annotations.Test;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/messaging/TestBatchMessageWrapper.java b/helix-core/src/test/java/org/apache/helix/integration/messaging/TestBatchMessageWrapper.java
index 093c943..72ae3cb 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/messaging/TestBatchMessageWrapper.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/messaging/TestBatchMessageWrapper.java
@@ -24,7 +24,7 @@
import org.apache.helix.NotificationContext;
import org.apache.helix.PropertyKey.Builder;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.ZkUnitTestBase;
import org.apache.helix.integration.manager.ClusterControllerManager;
import org.apache.helix.integration.manager.MockParticipantManager;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/messaging/TestMessageThrottle.java b/helix-core/src/test/java/org/apache/helix/integration/messaging/TestMessageThrottle.java
index b4a0b32..0e1c9c3 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/messaging/TestMessageThrottle.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/messaging/TestMessageThrottle.java
@@ -23,11 +23,10 @@
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
-import org.I0Itec.zkclient.IZkChildListener;
import org.apache.helix.HelixAdmin;
import org.apache.helix.PropertyPathBuilder;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.common.ZkTestBase;
import org.apache.helix.integration.manager.ClusterControllerManager;
import org.apache.helix.integration.manager.MockParticipantManager;
@@ -40,6 +39,7 @@
import org.apache.helix.tools.ClusterStateVerifier;
import org.apache.helix.tools.ClusterStateVerifier.BestPossAndExtViewZkVerifier;
import org.apache.helix.tools.ClusterStateVerifier.MasterNbInExtViewVerifier;
+import org.apache.helix.zookeeper.zkclient.IZkChildListener;
import org.testng.Assert;
import org.testng.annotations.Test;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/messaging/TestMessageThrottle2.java b/helix-core/src/test/java/org/apache/helix/integration/messaging/TestMessageThrottle2.java
index 7b73643..df7cea5 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/messaging/TestMessageThrottle2.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/messaging/TestMessageThrottle2.java
@@ -41,7 +41,7 @@
import org.apache.helix.NotificationContext;
import org.apache.helix.PropertyKey.Builder;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.common.ZkTestBase;
import org.apache.helix.controller.HelixControllerMain;
import org.apache.helix.manager.zk.ZKHelixAdmin;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/messaging/TestSchedulerMessage.java b/helix-core/src/test/java/org/apache/helix/integration/messaging/TestSchedulerMessage.java
index dfe6b19..1ca4c2a 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/messaging/TestSchedulerMessage.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/messaging/TestSchedulerMessage.java
@@ -39,7 +39,7 @@
import org.apache.helix.PropertyKey;
import org.apache.helix.PropertyKey.Builder;
import org.apache.helix.PropertyPathBuilder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.integration.common.ZkStandAloneCMTestBase;
import org.apache.helix.manager.zk.DefaultSchedulerMessageHandlerFactory;
import org.apache.helix.messaging.AsyncCallback;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/messaging/TestSchedulerMessage2.java b/helix-core/src/test/java/org/apache/helix/integration/messaging/TestSchedulerMessage2.java
index 3691384..5cea518 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/messaging/TestSchedulerMessage2.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/messaging/TestSchedulerMessage2.java
@@ -28,7 +28,7 @@
import org.apache.helix.HelixManager;
import org.apache.helix.InstanceType;
import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.integration.common.ZkStandAloneCMTestBase;
import org.apache.helix.manager.zk.DefaultSchedulerMessageHandlerFactory;
import org.apache.helix.model.Message;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/messaging/TestSchedulerMsgContraints.java b/helix-core/src/test/java/org/apache/helix/integration/messaging/TestSchedulerMsgContraints.java
index c283301..aedc738 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/messaging/TestSchedulerMsgContraints.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/messaging/TestSchedulerMsgContraints.java
@@ -30,7 +30,7 @@
import org.apache.helix.HelixManager;
import org.apache.helix.InstanceType;
import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.integration.common.ZkStandAloneCMTestBase;
import org.apache.helix.manager.zk.DefaultSchedulerMessageHandlerFactory;
import org.apache.helix.model.ClusterConstraints.ConstraintType;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/messaging/TestSchedulerMsgUsingQueue.java b/helix-core/src/test/java/org/apache/helix/integration/messaging/TestSchedulerMsgUsingQueue.java
index f0068d3..dea9ba8 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/messaging/TestSchedulerMsgUsingQueue.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/messaging/TestSchedulerMsgUsingQueue.java
@@ -28,7 +28,7 @@
import org.apache.helix.HelixManager;
import org.apache.helix.InstanceType;
import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.integration.common.ZkStandAloneCMTestBase;
import org.apache.helix.manager.zk.DefaultSchedulerMessageHandlerFactory;
import org.apache.helix.model.Message;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/paticipant/TestStateTransitionTimeoutWithResource.java b/helix-core/src/test/java/org/apache/helix/integration/paticipant/TestStateTransitionTimeoutWithResource.java
index 1d33b6c..52ca2eb 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/paticipant/TestStateTransitionTimeoutWithResource.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/paticipant/TestStateTransitionTimeoutWithResource.java
@@ -32,7 +32,7 @@
import org.apache.helix.InstanceType;
import org.apache.helix.NotificationContext;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.api.config.RebalanceConfig;
import org.apache.helix.api.config.StateTransitionTimeoutConfig;
import org.apache.helix.integration.common.ZkStandAloneCMTestBase;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/rebalancer/TestAutoIsWithEmptyMap.java b/helix-core/src/test/java/org/apache/helix/integration/rebalancer/TestAutoIsWithEmptyMap.java
index 06d9654..acaf8b1 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/rebalancer/TestAutoIsWithEmptyMap.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/rebalancer/TestAutoIsWithEmptyMap.java
@@ -25,7 +25,7 @@
import org.apache.helix.PropertyPathBuilder;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.common.ZkTestBase;
import org.apache.helix.integration.manager.ClusterControllerManager;
import org.apache.helix.integration.manager.MockParticipantManager;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/rebalancer/TestAutoRebalance.java b/helix-core/src/test/java/org/apache/helix/integration/rebalancer/TestAutoRebalance.java
index 0a4ec4b..90b09ec 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/rebalancer/TestAutoRebalance.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/rebalancer/TestAutoRebalance.java
@@ -28,15 +28,15 @@
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.PropertyKey.Builder;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
import org.apache.helix.integration.common.ZkStandAloneCMTestBase;
import org.apache.helix.integration.manager.ClusterControllerManager;
import org.apache.helix.integration.manager.MockParticipantManager;
import org.apache.helix.manager.zk.ZKHelixDataAccessor;
import org.apache.helix.manager.zk.ZkBaseDataAccessor;
-import org.apache.helix.manager.zk.ZkClient;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
import org.apache.helix.model.ExternalView;
import org.apache.helix.model.IdealState;
import org.apache.helix.model.IdealState.RebalanceMode;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/rebalancer/TestAutoRebalancePartitionLimit.java b/helix-core/src/test/java/org/apache/helix/integration/rebalancer/TestAutoRebalancePartitionLimit.java
index 91d4cb8..c78a4f2 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/rebalancer/TestAutoRebalancePartitionLimit.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/rebalancer/TestAutoRebalancePartitionLimit.java
@@ -26,15 +26,15 @@
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.HelixManager;
import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
import org.apache.helix.integration.common.ZkStandAloneCMTestBase;
import org.apache.helix.integration.manager.ClusterControllerManager;
import org.apache.helix.integration.manager.MockParticipantManager;
import org.apache.helix.manager.zk.ZKHelixDataAccessor;
import org.apache.helix.manager.zk.ZkBaseDataAccessor;
-import org.apache.helix.manager.zk.ZkClient;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
import org.apache.helix.model.ExternalView;
import org.apache.helix.model.IdealState.RebalanceMode;
import org.apache.helix.tools.ClusterStateVerifier;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/rebalancer/TestCustomizedIdealStateRebalancer.java b/helix-core/src/test/java/org/apache/helix/integration/rebalancer/TestCustomizedIdealStateRebalancer.java
index 8fa87c2..28f02a3 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/rebalancer/TestCustomizedIdealStateRebalancer.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/rebalancer/TestCustomizedIdealStateRebalancer.java
@@ -27,15 +27,15 @@
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.HelixManager;
import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.controller.dataproviders.ResourceControllerDataProvider;
import org.apache.helix.controller.rebalancer.Rebalancer;
import org.apache.helix.controller.stages.CurrentStateOutput;
import org.apache.helix.integration.common.ZkStandAloneCMTestBase;
import org.apache.helix.manager.zk.ZKHelixDataAccessor;
import org.apache.helix.manager.zk.ZkBaseDataAccessor;
-import org.apache.helix.manager.zk.ZkClient;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
import org.apache.helix.model.ExternalView;
import org.apache.helix.model.IdealState;
import org.apache.helix.model.IdealState.IdealStateProperty;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/rebalancer/TestFullAutoNodeTagging.java b/helix-core/src/test/java/org/apache/helix/integration/rebalancer/TestFullAutoNodeTagging.java
index 074f5b9..e108bde 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/rebalancer/TestFullAutoNodeTagging.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/rebalancer/TestFullAutoNodeTagging.java
@@ -32,7 +32,7 @@
import org.apache.helix.PropertyKey;
import org.apache.helix.TestHelper;
import org.apache.helix.TestHelper.Verifier;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.ZkUnitTestBase;
import org.apache.helix.integration.manager.ClusterControllerManager;
import org.apache.helix.integration.manager.MockParticipantManager;
@@ -40,9 +40,9 @@
import org.apache.helix.manager.zk.ZKHelixDataAccessor;
import org.apache.helix.manager.zk.ZNRecordSerializer;
import org.apache.helix.manager.zk.ZkBaseDataAccessor;
-import org.apache.helix.manager.zk.ZkClient;
-import org.apache.helix.manager.zk.client.DedicatedZkClientFactory;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
+import org.apache.helix.zookeeper.impl.factory.DedicatedZkClientFactory;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
import org.apache.helix.model.ExternalView;
import org.apache.helix.model.IdealState;
import org.apache.helix.model.IdealState.RebalanceMode;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/task/TaskTestUtil.java b/helix-core/src/test/java/org/apache/helix/integration/task/TaskTestUtil.java
index 9c36786..23f99a0 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/task/TaskTestUtil.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/task/TaskTestUtil.java
@@ -33,7 +33,7 @@
import org.apache.helix.HelixManager;
import org.apache.helix.PropertyKey;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.common.DedupEventProcessor;
import org.apache.helix.controller.dataproviders.WorkflowControllerDataProvider;
import org.apache.helix.controller.pipeline.AsyncWorkerType;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/task/TestTaskStopQueue.java b/helix-core/src/test/java/org/apache/helix/integration/task/TestTaskStopQueue.java
index 5b85457..43551f7 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/task/TestTaskStopQueue.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/task/TestTaskStopQueue.java
@@ -28,7 +28,7 @@
import org.apache.helix.TestHelper;
import org.apache.helix.ZkTestHelper;
import org.apache.helix.integration.manager.ClusterControllerManager;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.task.JobConfig;
import org.apache.helix.task.JobQueue;
import org.apache.helix.task.TaskDriver;
diff --git a/helix-core/src/test/java/org/apache/helix/integration/task/TestWorkflowContextWithoutConfig.java b/helix-core/src/test/java/org/apache/helix/integration/task/TestWorkflowContextWithoutConfig.java
index ad75e15..b7d6016 100644
--- a/helix-core/src/test/java/org/apache/helix/integration/task/TestWorkflowContextWithoutConfig.java
+++ b/helix-core/src/test/java/org/apache/helix/integration/task/TestWorkflowContextWithoutConfig.java
@@ -22,7 +22,7 @@
import org.apache.helix.AccessOption;
import org.apache.helix.HelixAdmin;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.integration.manager.ClusterControllerManager;
import org.apache.helix.model.IdealState;
import org.apache.helix.task.JobConfig;
diff --git a/helix-core/src/test/java/org/apache/helix/manager/zk/TestAddBuiltInStateModelDef.java b/helix-core/src/test/java/org/apache/helix/manager/zk/TestAddBuiltInStateModelDef.java
index 3fb5fc9..2ca98da 100644
--- a/helix-core/src/test/java/org/apache/helix/manager/zk/TestAddBuiltInStateModelDef.java
+++ b/helix-core/src/test/java/org/apache/helix/manager/zk/TestAddBuiltInStateModelDef.java
@@ -25,7 +25,7 @@
import org.apache.helix.HelixAdmin;
import org.apache.helix.PropertyKey;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.ZkUnitTestBase;
import org.apache.helix.integration.manager.ClusterControllerManager;
import org.apache.helix.model.BuiltInStateModelDefinitions;
diff --git a/helix-core/src/test/java/org/apache/helix/manager/zk/TestHandleNewSession.java b/helix-core/src/test/java/org/apache/helix/manager/zk/TestHandleNewSession.java
index 8cae2f7..00bedcf 100644
--- a/helix-core/src/test/java/org/apache/helix/manager/zk/TestHandleNewSession.java
+++ b/helix-core/src/test/java/org/apache/helix/manager/zk/TestHandleNewSession.java
@@ -34,15 +34,16 @@
import org.apache.helix.common.ZkTestBase;
import org.apache.helix.controller.GenericHelixController;
import org.apache.helix.integration.manager.MockParticipantManager;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.model.LiveInstance;
import org.testng.Assert;
import org.testng.annotations.Test;
+
public class TestHandleNewSession extends ZkTestBase {
@Test
public void testHandleNewSession() throws Exception {
- // Logger.getRootLogger().setLevel(Level.INFO);
String className = TestHelper.getTestClassName();
String methodName = TestHelper.getTestMethodName();
String clusterName = className + "_" + methodName;
@@ -127,8 +128,9 @@
accessor.removeProperty(keyBuilder.controllerLeader());
// 3. expire the session and create a new session
ZkTestHelper.asyncExpireSession(manager._zkclient);
- Assert.assertTrue(TestHelper.verify(
- () -> !((ZkClient) manager._zkclient).getConnection().getZookeeperState().isAlive(), 3000));
+ Assert.assertTrue(TestHelper
+ .verify(() -> !((ZkClient) manager._zkclient).getConnection().getZookeeperState().isAlive(),
+ 3000));
// 4. start processing event again
((ZkClient) manager._zkclient).getEventLock().unlock();
@@ -151,14 +153,17 @@
// Newly created node should have a new creating time but with old session.
LiveInstance invalidLeaderNode = accessor.getProperty(keyBuilder.controllerLeader());
// node exist
- if (invalidLeaderNode == null)
+ if (invalidLeaderNode == null) {
return false;
+ }
// node is newly created
- if (invalidLeaderNode.getStat().getCreationTime() == originalCreationTime)
+ if (invalidLeaderNode.getStat().getCreationTime() == originalCreationTime) {
return false;
+ }
// node has the same session as the old one, so it's invalid
- if (!invalidLeaderNode.getSessionId().equals(originalSessionId))
+ if (!invalidLeaderNode.getSessionId().equals(originalSessionId)) {
return false;
+ }
return true;
}, 2000));
Assert.assertFalse(manager.isLeader());
@@ -194,16 +199,14 @@
new ZKHelixDataAccessor(clusterName, new ZkBaseDataAccessor<>(ZK_ADDR));
final PropertyKey.Builder keyBuilder = accessor.keyBuilder();
- TestHelper.setupCluster(clusterName, ZK_ADDR,
- 12918, // participant port
+ TestHelper.setupCluster(clusterName, ZK_ADDR, 12918, // participant port
"localhost", // participant name prefix
"TestDB", // resource name prefix
1, // resources
10, // partitions per resource
5, // number of nodes
3, // replicas
- "MasterSlave",
- true); // do rebalance
+ "MasterSlave", true); // do rebalance
final String instanceName = "localhost_12918";
final BlockingHandleNewSessionZkHelixManager manager =
@@ -319,16 +322,14 @@
new ZKHelixDataAccessor(clusterName, new ZkBaseDataAccessor<>(ZK_ADDR));
final PropertyKey.Builder keyBuilder = accessor.keyBuilder();
- TestHelper.setupCluster(clusterName, ZK_ADDR,
- 12918, // participant port
+ TestHelper.setupCluster(clusterName, ZK_ADDR, 12918, // participant port
"localhost", // participant name prefix
"TestDB", // resource name prefix
1, // resources
10, // partitions per resource
5, // number of nodes
3, // replicas
- "MasterSlave",
- true); // do rebalance
+ "MasterSlave", true); // do rebalance
// 1. Original session S0 initialized
final String instanceName = "localhost_12918";
@@ -412,7 +413,6 @@
// Notify the main thread that live instance is already created by session S2.
mainThreadBlocker.countDown();
-
}).start();
// Lock zk event processing to simulate a long backlog queue.
@@ -452,14 +452,14 @@
// and have a new creation time.
LiveInstance newLiveInstance = accessor.getProperty(keyBuilder.liveInstance(instanceName));
return newLiveInstance != null
- && newLiveInstance.getStat().getCreationTime() != originalCreationTime
- && newLiveInstance.getEphemeralOwner().equals(latestSessionId);
+ && newLiveInstance.getStat().getCreationTime() != originalCreationTime && newLiveInstance
+ .getEphemeralOwner().equals(latestSessionId);
}, 2000L));
// All the callback handlers shall be recovered.
Assert.assertTrue(TestHelper.verify(() -> manager.getHandlers().size() == handlerCount, 1000L));
- Assert.assertTrue(TestHelper.verify(
- () -> manager.getHandlers().stream().allMatch(CallbackHandler::isReady), 3000L));
+ Assert.assertTrue(TestHelper
+ .verify(() -> manager.getHandlers().stream().allMatch(CallbackHandler::isReady), 3000L));
// Clean up.
manager.disconnect();
diff --git a/helix-core/src/test/java/org/apache/helix/manager/zk/TestRawZkClient.java b/helix-core/src/test/java/org/apache/helix/manager/zk/TestRawZkClient.java
index 111bd7a..a713996 100644
--- a/helix-core/src/test/java/org/apache/helix/manager/zk/TestRawZkClient.java
+++ b/helix-core/src/test/java/org/apache/helix/manager/zk/TestRawZkClient.java
@@ -33,19 +33,20 @@
import javax.management.MBeanServer;
import javax.management.ObjectName;
-import org.I0Itec.zkclient.IZkDataListener;
-import org.I0Itec.zkclient.ZkServer;
-import org.I0Itec.zkclient.exception.ZkTimeoutException;
import org.apache.helix.HelixException;
import org.apache.helix.TestHelper;
import org.apache.helix.ZkTestHelper;
import org.apache.helix.ZkUnitTestBase;
-import org.apache.helix.manager.zk.zookeeper.IZkStateListener;
-import org.apache.helix.manager.zk.zookeeper.ZkConnection;
import org.apache.helix.monitoring.mbeans.MBeanRegistrar;
import org.apache.helix.monitoring.mbeans.MonitorDomainNames;
import org.apache.helix.monitoring.mbeans.ZkClientMonitor;
import org.apache.helix.monitoring.mbeans.ZkClientPathMonitor;
+import org.apache.helix.zookeeper.zkclient.IZkDataListener;
+import org.apache.helix.zookeeper.zkclient.IZkStateListener;
+import org.apache.helix.zookeeper.zkclient.ZkConnection;
+import org.apache.helix.zookeeper.zkclient.ZkServer;
+import org.apache.helix.zookeeper.zkclient.exception.ZkSessionMismatchedException;
+import org.apache.helix.zookeeper.zkclient.exception.ZkTimeoutException;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
@@ -143,7 +144,8 @@
* Tests session expiry for the helix's IZkStateListener.
*/
@Test
- void testSessionExpiry() throws Exception {
+ void testSessionExpiry()
+ throws Exception {
long lastSessionId = _zkClient.getSessionId();
// Test multiple times to make sure each time the new session id is increasing.
@@ -165,27 +167,29 @@
@Test
public void testSubscribeStateChangesForI0ItecIZkStateListener() {
int numListeners = _zkClient.numberOfListeners();
- List<org.I0Itec.zkclient.IZkStateListener> listeners = new ArrayList<>();
+ List<org.apache.helix.zookeeper.zkclient.deprecated.IZkStateListener> listeners =
+ new ArrayList<>();
// Subscribe multiple listeners to test that listener's hashcode works as expected.
// Each listener is subscribed and unsubscribed successfully.
for (int i = 0; i < 3; i++) {
- org.I0Itec.zkclient.IZkStateListener listener = new org.I0Itec.zkclient.IZkStateListener() {
- @Override
- public void handleStateChanged(KeeperState state) {
- System.out.println("Handle new state: " + state);
- }
+ org.apache.helix.zookeeper.zkclient.deprecated.IZkStateListener listener =
+ new org.apache.helix.zookeeper.zkclient.deprecated.IZkStateListener() {
+ @Override
+ public void handleStateChanged(KeeperState state) {
+ System.out.println("Handle new state: " + state);
+ }
- @Override
- public void handleNewSession() {
- System.out.println("Handle new session: ");
- }
+ @Override
+ public void handleNewSession() {
+ System.out.println("Handle new session: ");
+ }
- @Override
- public void handleSessionEstablishmentError(Throwable error) {
- System.out.println("Handle session establishment error: " + error);
- }
- };
+ @Override
+ public void handleSessionEstablishmentError(Throwable error) {
+ System.out.println("Handle session establishment error: " + error);
+ }
+ };
_zkClient.subscribeStateChanges(listener);
Assert.assertEquals(_zkClient.numberOfListeners(), ++numListeners);
@@ -198,7 +202,7 @@
listeners.add(listener);
}
- for (org.I0Itec.zkclient.IZkStateListener listener : listeners) {
+ for (org.apache.helix.zookeeper.zkclient.deprecated.IZkStateListener listener : listeners) {
_zkClient.unsubscribeStateChanges(listener);
Assert.assertEquals(_zkClient.numberOfListeners(), --numListeners);
}
@@ -211,9 +215,10 @@
* TODO: remove this test when getting rid of I0Itec.
*/
@Test
- public void testSessionExpiryForI0IItecZkStateListener() throws Exception {
- org.I0Itec.zkclient.IZkStateListener listener =
- new org.I0Itec.zkclient.IZkStateListener() {
+ public void testSessionExpiryForI0IItecZkStateListener()
+ throws Exception {
+ org.apache.helix.zookeeper.zkclient.deprecated.IZkStateListener listener =
+ new org.apache.helix.zookeeper.zkclient.deprecated.IZkStateListener() {
@Override
public void handleStateChanged(KeeperState state) {
@@ -236,8 +241,9 @@
long oldSessionId = zookeeper.getSessionId();
System.out.println("old sessionId= " + oldSessionId);
Watcher watcher = event -> System.out.println("In New connection In process event:" + event);
- ZooKeeper newZookeeper = new ZooKeeper(connection.getServers(), zookeeper.getSessionTimeout(),
- watcher, zookeeper.getSessionId(), zookeeper.getSessionPasswd());
+ ZooKeeper newZookeeper =
+ new ZooKeeper(connection.getServers(), zookeeper.getSessionTimeout(), watcher,
+ zookeeper.getSessionId(), zookeeper.getSessionPasswd());
Thread.sleep(3000);
System.out.println("New sessionId= " + newZookeeper.getSessionId());
Thread.sleep(3000);
@@ -251,7 +257,8 @@
}
@Test
- public void testZkClientMonitor() throws Exception {
+ public void testZkClientMonitor()
+ throws Exception {
final String TEST_KEY = "testZkClientMonitor";
ZkClient.Builder builder = new ZkClient.Builder();
builder.setZkServer(ZK_ADDR).setMonitorKey(TEST_KEY).setMonitorType(TEST_TAG)
@@ -272,14 +279,17 @@
MBeanServer beanServer = ManagementFactory.getPlatformMBeanServer();
- ObjectName name = MBeanRegistrar.buildObjectName(MonitorDomainNames.HelixZkClient.name(),
- ZkClientMonitor.MONITOR_TYPE, TEST_TAG, ZkClientMonitor.MONITOR_KEY, TEST_KEY);
- ObjectName rootname = MBeanRegistrar.buildObjectName(MonitorDomainNames.HelixZkClient.name(),
- ZkClientMonitor.MONITOR_TYPE, TEST_TAG, ZkClientMonitor.MONITOR_KEY, TEST_KEY,
- ZkClientPathMonitor.MONITOR_PATH, "Root");
- ObjectName idealStatename = MBeanRegistrar.buildObjectName(
- MonitorDomainNames.HelixZkClient.name(), ZkClientMonitor.MONITOR_TYPE, TEST_TAG,
- ZkClientMonitor.MONITOR_KEY, TEST_KEY, ZkClientPathMonitor.MONITOR_PATH, "IdealStates");
+ ObjectName name = MBeanRegistrar
+ .buildObjectName(MonitorDomainNames.HelixZkClient.name(), ZkClientMonitor.MONITOR_TYPE,
+ TEST_TAG, ZkClientMonitor.MONITOR_KEY, TEST_KEY);
+ ObjectName rootname = MBeanRegistrar
+ .buildObjectName(MonitorDomainNames.HelixZkClient.name(), ZkClientMonitor.MONITOR_TYPE,
+ TEST_TAG, ZkClientMonitor.MONITOR_KEY, TEST_KEY, ZkClientPathMonitor.MONITOR_PATH,
+ "Root");
+ ObjectName idealStatename = MBeanRegistrar
+ .buildObjectName(MonitorDomainNames.HelixZkClient.name(), ZkClientMonitor.MONITOR_TYPE,
+ TEST_TAG, ZkClientMonitor.MONITOR_KEY, TEST_KEY, ZkClientPathMonitor.MONITOR_PATH,
+ "IdealStates");
Assert.assertTrue(beanServer.isRegistered(rootname));
Assert.assertTrue(beanServer.isRegistered(idealStatename));
@@ -336,27 +346,27 @@
Assert.assertEquals((long) beanServer.getAttribute(idealStatename, "ReadLatencyGauge.Max"), 0);
zkClient.readData(TEST_PATH, new Stat());
Assert.assertEquals((long) beanServer.getAttribute(rootname, "ReadCounter"), 2);
- Assert.assertEquals((long) beanServer.getAttribute(rootname, "ReadBytesCounter"),
- TEST_DATA_SIZE);
+ Assert
+ .assertEquals((long) beanServer.getAttribute(rootname, "ReadBytesCounter"), TEST_DATA_SIZE);
Assert.assertEquals((long) beanServer.getAttribute(idealStatename, "ReadCounter"), 1);
Assert.assertEquals((long) beanServer.getAttribute(idealStatename, "ReadBytesCounter"),
TEST_DATA_SIZE);
- Assert.assertTrue((long) beanServer.getAttribute(rootname,
- "ReadTotalLatencyCounter") >= origReadTotalLatencyCounter);
- Assert.assertTrue((long) beanServer.getAttribute(idealStatename,
- "ReadTotalLatencyCounter") >= origIdealStatesReadTotalLatencyCounter);
+ Assert.assertTrue((long) beanServer.getAttribute(rootname, "ReadTotalLatencyCounter")
+ >= origReadTotalLatencyCounter);
+ Assert.assertTrue((long) beanServer.getAttribute(idealStatename, "ReadTotalLatencyCounter")
+ >= origIdealStatesReadTotalLatencyCounter);
Assert.assertTrue((long) beanServer.getAttribute(idealStatename, "ReadLatencyGauge.Max") >= 0);
zkClient.getChildren(TEST_PATH);
Assert.assertEquals((long) beanServer.getAttribute(rootname, "ReadCounter"), 3);
- Assert.assertEquals((long) beanServer.getAttribute(rootname, "ReadBytesCounter"),
- TEST_DATA_SIZE);
+ Assert
+ .assertEquals((long) beanServer.getAttribute(rootname, "ReadBytesCounter"), TEST_DATA_SIZE);
Assert.assertEquals((long) beanServer.getAttribute(idealStatename, "ReadCounter"), 2);
Assert.assertEquals((long) beanServer.getAttribute(idealStatename, "ReadBytesCounter"),
TEST_DATA_SIZE);
zkClient.getStat(TEST_PATH);
Assert.assertEquals((long) beanServer.getAttribute(rootname, "ReadCounter"), 4);
- Assert.assertEquals((long) beanServer.getAttribute(rootname, "ReadBytesCounter"),
- TEST_DATA_SIZE);
+ Assert
+ .assertEquals((long) beanServer.getAttribute(rootname, "ReadBytesCounter"), TEST_DATA_SIZE);
Assert.assertEquals((long) beanServer.getAttribute(idealStatename, "ReadCounter"), 3);
Assert.assertEquals((long) beanServer.getAttribute(idealStatename, "ReadBytesCounter"),
TEST_DATA_SIZE);
@@ -377,10 +387,10 @@
Assert.assertEquals((long) beanServer.getAttribute(idealStatename, "WriteCounter"), 2);
Assert.assertEquals((long) beanServer.getAttribute(idealStatename, "WriteBytesCounter"),
TEST_DATA_SIZE * 2);
- Assert.assertTrue((long) beanServer.getAttribute(rootname,
- "WriteTotalLatencyCounter") >= origWriteTotalLatencyCounter);
- Assert.assertTrue((long) beanServer.getAttribute(idealStatename,
- "WriteTotalLatencyCounter") >= origIdealStatesWriteTotalLatencyCounter);
+ Assert.assertTrue((long) beanServer.getAttribute(rootname, "WriteTotalLatencyCounter")
+ >= origWriteTotalLatencyCounter);
+ Assert.assertTrue((long) beanServer.getAttribute(idealStatename, "WriteTotalLatencyCounter")
+ >= origIdealStatesWriteTotalLatencyCounter);
// Test data change count
final Lock lock = new ReentrantLock();
@@ -427,12 +437,14 @@
}
@Test(dependsOnMethods = "testZkClientMonitor")
- void testPendingRequestGauge() throws Exception {
+ void testPendingRequestGauge()
+ throws Exception {
final String TEST_KEY = "testPendingRequestGauge";
final MBeanServer beanServer = ManagementFactory.getPlatformMBeanServer();
- final ObjectName name = MBeanRegistrar.buildObjectName(MonitorDomainNames.HelixZkClient.name(),
- ZkClientMonitor.MONITOR_TYPE, TEST_TAG, ZkClientMonitor.MONITOR_KEY, TEST_KEY);
+ final ObjectName name = MBeanRegistrar
+ .buildObjectName(MonitorDomainNames.HelixZkClient.name(), ZkClientMonitor.MONITOR_TYPE,
+ TEST_TAG, ZkClientMonitor.MONITOR_KEY, TEST_KEY);
final int zkPort = TestHelper.getRandomPort();
final String zkAddr = String.format("localhost:%d", zkPort);
@@ -455,13 +467,15 @@
executorService.submit(() -> {
zkClient.exists(TEST_ROOT);
});
- Assert.assertTrue(TestHelper.verify(
- () -> (long) beanServer.getAttribute(name, "OutstandingRequestGauge") == 1, 1000));
+ Assert.assertTrue(TestHelper
+ .verify(() -> (long) beanServer.getAttribute(name, "OutstandingRequestGauge") == 1,
+ 1000));
zkServer.start();
Assert.assertTrue(zkClient.waitUntilConnected(5000, TimeUnit.MILLISECONDS));
- Assert.assertTrue(TestHelper.verify(
- () -> (long) beanServer.getAttribute(name, "OutstandingRequestGauge") == 0, 2000));
+ Assert.assertTrue(TestHelper
+ .verify(() -> (long) beanServer.getAttribute(name, "OutstandingRequestGauge") == 0,
+ 2000));
zkClient.close();
} finally {
zkServer.shutdown();
@@ -472,21 +486,20 @@
* This test checks that a valid session can successfully create an ephemeral node.
*/
@Test
- public void testCreateEphemeralWithValidSession() throws Exception {
+ public void testCreateEphemeralWithValidSession()
+ throws Exception {
final String className = TestHelper.getTestClassName();
final String methodName = TestHelper.getTestMethodName();
final String clusterName = className + "_" + methodName;
- TestHelper.setupCluster(clusterName, ZK_ADDR,
- 12918, // participant port
+ TestHelper.setupCluster(clusterName, ZK_ADDR, 12918, // participant port
"localhost", // participant name prefix
"TestDB", // resource name prefix
1, // resources
10, // partitions per resource
5, // number of nodes
3, // replicas
- "MasterSlave",
- true); // do rebalance
+ "MasterSlave", true); // do rebalance
final String originalSessionId = ZKUtil.toHexSessionId(_zkClient.getSessionId());
final String path = "/" + methodName;
@@ -532,21 +545,20 @@
* 4. ZkSessionMismatchedException is expected for the creation and ephemeral node is not created
*/
@Test
- public void testCreateEphemeralWithMismatchedSession() throws Exception {
+ public void testCreateEphemeralWithMismatchedSession()
+ throws Exception {
final String className = TestHelper.getTestClassName();
final String methodName = TestHelper.getTestMethodName();
final String clusterName = className + "_" + methodName;
- TestHelper.setupCluster(clusterName, ZK_ADDR,
- 12918, // participant port
+ TestHelper.setupCluster(clusterName, ZK_ADDR, 12918, // participant port
"localhost", // participant name prefix
"TestDB", // resource name prefix
1, // resources
10, // partitions per resource
5, // number of nodes
3, // replicas
- "MasterSlave",
- true); // do rebalance
+ "MasterSlave", true); // do rebalance
final long originalSessionId = _zkClient.getSessionId();
final String originalHexSessionId = ZKUtil.toHexSessionId(originalSessionId);
@@ -591,13 +603,13 @@
* see if ConnectionLossException was thrown before retry.
*/
@Test(timeOut = 5 * 60 * 1000L)
- public void testConnectionLossWhileCreateEphemeral() throws Exception {
+ public void testConnectionLossWhileCreateEphemeral()
+ throws Exception {
final String methodName = TestHelper.getTestMethodName();
- final ZkClient zkClient = new ZkClient.Builder()
- .setZkServer(ZK_ADDR)
- .setOperationRetryTimeout(3000L) // 3 seconds
- .build();
+ final ZkClient zkClient =
+ new ZkClient.Builder().setZkServer(ZK_ADDR).setOperationRetryTimeout(3000L) // 3 seconds
+ .build();
final String expectedSessionId = ZKUtil.toHexSessionId(zkClient.getSessionId());
final String path = "/" + methodName;
@@ -655,7 +667,8 @@
* 5. zk client reconnects successfully and creates an ephemeral node
*/
@Test(timeOut = 5 * 60 * 1000L)
- public void testRetryUntilConnectedAfterConnectionLoss() throws Exception {
+ public void testRetryUntilConnectedAfterConnectionLoss()
+ throws Exception {
final String methodName = TestHelper.getTestMethodName();
final String expectedSessionId = ZKUtil.toHexSessionId(_zkClient.getSessionId());
diff --git a/helix-core/src/test/java/org/apache/helix/manager/zk/TestWtCacheAsyncOpMultiThread.java b/helix-core/src/test/java/org/apache/helix/manager/zk/TestWtCacheAsyncOpMultiThread.java
index 7b030ce..7339512 100644
--- a/helix-core/src/test/java/org/apache/helix/manager/zk/TestWtCacheAsyncOpMultiThread.java
+++ b/helix-core/src/test/java/org/apache/helix/manager/zk/TestWtCacheAsyncOpMultiThread.java
@@ -25,13 +25,13 @@
import java.util.List;
import java.util.concurrent.Callable;
-import org.I0Itec.zkclient.DataUpdater;
import org.apache.helix.AccessOption;
import org.apache.helix.PropertyPathBuilder;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.ZNRecordUpdater;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecordUpdater;
import org.apache.helix.ZkUnitTestBase;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
import org.testng.Assert;
import org.testng.annotations.Test;
diff --git a/helix-core/src/test/java/org/apache/helix/manager/zk/TestWtCacheAsyncOpSingleThread.java b/helix-core/src/test/java/org/apache/helix/manager/zk/TestWtCacheAsyncOpSingleThread.java
index 9eea08c..e84d1b0 100644
--- a/helix-core/src/test/java/org/apache/helix/manager/zk/TestWtCacheAsyncOpSingleThread.java
+++ b/helix-core/src/test/java/org/apache/helix/manager/zk/TestWtCacheAsyncOpSingleThread.java
@@ -24,13 +24,13 @@
import java.util.Date;
import java.util.List;
-import org.I0Itec.zkclient.DataUpdater;
import org.apache.helix.AccessOption;
import org.apache.helix.PropertyPathBuilder;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.ZNRecordUpdater;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecordUpdater;
import org.apache.helix.ZkUnitTestBase;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
import org.testng.Assert;
import org.testng.annotations.Test;
diff --git a/helix-core/src/test/java/org/apache/helix/manager/zk/TestWtCacheSyncOpSingleThread.java b/helix-core/src/test/java/org/apache/helix/manager/zk/TestWtCacheSyncOpSingleThread.java
index 9572ae0..b80ff9c 100644
--- a/helix-core/src/test/java/org/apache/helix/manager/zk/TestWtCacheSyncOpSingleThread.java
+++ b/helix-core/src/test/java/org/apache/helix/manager/zk/TestWtCacheSyncOpSingleThread.java
@@ -27,8 +27,8 @@
import org.apache.helix.AccessOption;
import org.apache.helix.PropertyPathBuilder;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.ZNRecordUpdater;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecordUpdater;
import org.apache.helix.ZkUnitTestBase;
import org.testng.Assert;
import org.testng.annotations.Test;
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 9c0c60a..de2c6c8 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
@@ -27,9 +27,9 @@
import org.apache.helix.PropertyPathBuilder;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.ZkUnitTestBase;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.AssertJUnit;
diff --git a/helix-core/src/test/java/org/apache/helix/manager/zk/TestZKWatch.java b/helix-core/src/test/java/org/apache/helix/manager/zk/TestZKWatch.java
index 9d247d4..53017cb 100644
--- a/helix-core/src/test/java/org/apache/helix/manager/zk/TestZKWatch.java
+++ b/helix-core/src/test/java/org/apache/helix/manager/zk/TestZKWatch.java
@@ -23,10 +23,10 @@
import java.util.Map;
import java.util.concurrent.CountDownLatch;
-import org.I0Itec.zkclient.IZkChildListener;
-import org.I0Itec.zkclient.IZkDataListener;
import org.apache.helix.ZkTestHelper;
import org.apache.helix.ZkUnitTestBase;
+import org.apache.helix.zookeeper.zkclient.IZkChildListener;
+import org.apache.helix.zookeeper.zkclient.IZkDataListener;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
diff --git a/helix-core/src/test/java/org/apache/helix/manager/zk/TestZNRecordSerializer.java b/helix-core/src/test/java/org/apache/helix/manager/zk/TestZNRecordSerializer.java
index d3f5746..496196a 100644
--- a/helix-core/src/test/java/org/apache/helix/manager/zk/TestZNRecordSerializer.java
+++ b/helix-core/src/test/java/org/apache/helix/manager/zk/TestZNRecordSerializer.java
@@ -14,8 +14,8 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
-import org.I0Itec.zkclient.serialize.ZkSerializer;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.zkclient.serialize.ZkSerializer;
import org.testng.Assert;
import org.testng.annotations.Test;
diff --git a/helix-core/src/test/java/org/apache/helix/manager/zk/TestZNRecordSizeLimit.java b/helix-core/src/test/java/org/apache/helix/manager/zk/TestZNRecordSizeLimit.java
index 6130062..447478c 100644
--- a/helix-core/src/test/java/org/apache/helix/manager/zk/TestZNRecordSizeLimit.java
+++ b/helix-core/src/test/java/org/apache/helix/manager/zk/TestZNRecordSizeLimit.java
@@ -25,10 +25,10 @@
import org.apache.helix.HelixException;
import org.apache.helix.HelixProperty;
import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.ZkUnitTestBase;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.client.SharedZkClientFactory;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
import org.apache.helix.model.IdealState;
import org.apache.helix.model.IdealState.RebalanceMode;
import org.apache.helix.model.InstanceConfig;
diff --git a/helix-core/src/test/java/org/apache/helix/manager/zk/TestZNRecordStreamingSerializer.java b/helix-core/src/test/java/org/apache/helix/manager/zk/TestZNRecordStreamingSerializer.java
index 50a84e6..925b8f3 100644
--- a/helix-core/src/test/java/org/apache/helix/manager/zk/TestZNRecordStreamingSerializer.java
+++ b/helix-core/src/test/java/org/apache/helix/manager/zk/TestZNRecordStreamingSerializer.java
@@ -6,7 +6,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.testng.Assert;
import org.testng.annotations.Test;
diff --git a/helix-core/src/test/java/org/apache/helix/manager/zk/TestZkBaseDataAccessor.java b/helix-core/src/test/java/org/apache/helix/manager/zk/TestZkBaseDataAccessor.java
index fb78d1c..3e03125 100644
--- a/helix-core/src/test/java/org/apache/helix/manager/zk/TestZkBaseDataAccessor.java
+++ b/helix-core/src/test/java/org/apache/helix/manager/zk/TestZkBaseDataAccessor.java
@@ -26,18 +26,18 @@
import java.util.stream.Collectors;
import com.google.common.collect.ImmutableList;
-import org.I0Itec.zkclient.DataUpdater;
-import org.I0Itec.zkclient.exception.ZkMarshallingError;
-import org.I0Itec.zkclient.serialize.ZkSerializer;
import org.apache.helix.AccessOption;
import org.apache.helix.BaseDataAccessor;
import org.apache.helix.PropertyPathBuilder;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.ZNRecordUpdater;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecordUpdater;
import org.apache.helix.ZkUnitTestBase;
import org.apache.helix.manager.zk.ZkBaseDataAccessor.AccessResult;
import org.apache.helix.manager.zk.ZkBaseDataAccessor.RetCode;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
+import org.apache.helix.zookeeper.zkclient.exception.ZkMarshallingError;
+import org.apache.helix.zookeeper.zkclient.serialize.ZkSerializer;
import org.apache.zookeeper.data.Stat;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
diff --git a/helix-core/src/test/java/org/apache/helix/manager/zk/TestZkBucketDataAccessor.java b/helix-core/src/test/java/org/apache/helix/manager/zk/TestZkBucketDataAccessor.java
index c7b5cbf..fdd0c8a 100644
--- a/helix-core/src/test/java/org/apache/helix/manager/zk/TestZkBucketDataAccessor.java
+++ b/helix-core/src/test/java/org/apache/helix/manager/zk/TestZkBucketDataAccessor.java
@@ -27,18 +27,18 @@
import java.util.List;
import java.util.Map;
import java.util.Random;
-import org.I0Itec.zkclient.exception.ZkMarshallingError;
-import org.I0Itec.zkclient.serialize.ZkSerializer;
import org.apache.helix.AccessOption;
import org.apache.helix.BaseDataAccessor;
import org.apache.helix.BucketDataAccessor;
import org.apache.helix.HelixException;
import org.apache.helix.HelixProperty;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.common.ZkTestBase;
-import org.apache.helix.manager.zk.client.DedicatedZkClientFactory;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.factory.DedicatedZkClientFactory;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.zkclient.exception.ZkMarshallingError;
+import org.apache.helix.zookeeper.zkclient.serialize.ZkSerializer;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
diff --git a/helix-core/src/test/java/org/apache/helix/manager/zk/TestZkCacheAsyncOpSingleThread.java b/helix-core/src/test/java/org/apache/helix/manager/zk/TestZkCacheAsyncOpSingleThread.java
index 89d4f18..a003a4b 100644
--- a/helix-core/src/test/java/org/apache/helix/manager/zk/TestZkCacheAsyncOpSingleThread.java
+++ b/helix-core/src/test/java/org/apache/helix/manager/zk/TestZkCacheAsyncOpSingleThread.java
@@ -24,15 +24,15 @@
import java.util.Date;
import java.util.List;
-import org.I0Itec.zkclient.DataUpdater;
import org.apache.helix.AccessOption;
import org.apache.helix.PropertyPathBuilder;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.ZNRecordUpdater;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecordUpdater;
import org.apache.helix.ZkUnitTestBase;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.client.SharedZkClientFactory;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
import org.testng.Assert;
import org.testng.annotations.Test;
diff --git a/helix-core/src/test/java/org/apache/helix/manager/zk/TestZkCacheSyncOpSingleThread.java b/helix-core/src/test/java/org/apache/helix/manager/zk/TestZkCacheSyncOpSingleThread.java
index fcace67..f04d53e 100644
--- a/helix-core/src/test/java/org/apache/helix/manager/zk/TestZkCacheSyncOpSingleThread.java
+++ b/helix-core/src/test/java/org/apache/helix/manager/zk/TestZkCacheSyncOpSingleThread.java
@@ -31,11 +31,11 @@
import org.apache.helix.AccessOption;
import org.apache.helix.PropertyPathBuilder;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.ZNRecordUpdater;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecordUpdater;
import org.apache.helix.ZkUnitTestBase;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.client.SharedZkClientFactory;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
import org.apache.helix.store.HelixPropertyListener;
import org.testng.Assert;
import org.testng.annotations.Test;
diff --git a/helix-core/src/test/java/org/apache/helix/manager/zk/TestZkClusterManager.java b/helix-core/src/test/java/org/apache/helix/manager/zk/TestZkClusterManager.java
index 0169c41..9c5b64b 100644
--- a/helix-core/src/test/java/org/apache/helix/manager/zk/TestZkClusterManager.java
+++ b/helix-core/src/test/java/org/apache/helix/manager/zk/TestZkClusterManager.java
@@ -34,7 +34,7 @@
import org.apache.helix.LiveInstanceInfoProvider;
import org.apache.helix.PropertyKey.Builder;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.ZkTestHelper;
import org.apache.helix.ZkUnitTestBase;
import org.apache.helix.integration.manager.MockParticipantManager;
diff --git a/helix-core/src/test/java/org/apache/helix/manager/zk/TestZkFlapping.java b/helix-core/src/test/java/org/apache/helix/manager/zk/TestZkFlapping.java
index 7a90fe3..3795756 100644
--- a/helix-core/src/test/java/org/apache/helix/manager/zk/TestZkFlapping.java
+++ b/helix-core/src/test/java/org/apache/helix/manager/zk/TestZkFlapping.java
@@ -33,9 +33,11 @@
import org.apache.helix.manager.zk.zookeeper.IZkStateListener;
import org.apache.helix.model.LiveInstance;
import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.testng.Assert;
import org.testng.annotations.Test;
+
public class TestZkFlapping extends ZkUnitTestBase {
private final int _disconnectThreshold = 5;
diff --git a/helix-core/src/test/java/org/apache/helix/manager/zk/TestZkHelixAdmin.java b/helix-core/src/test/java/org/apache/helix/manager/zk/TestZkHelixAdmin.java
index c391085..ac1cc09 100644
--- a/helix-core/src/test/java/org/apache/helix/manager/zk/TestZkHelixAdmin.java
+++ b/helix-core/src/test/java/org/apache/helix/manager/zk/TestZkHelixAdmin.java
@@ -40,7 +40,7 @@
import org.apache.helix.PropertyPathBuilder;
import org.apache.helix.PropertyType;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.ZkUnitTestBase;
import org.apache.helix.controller.rebalancer.waged.WagedRebalancer;
import org.apache.helix.examples.MasterSlaveStateModelFactory;
diff --git a/helix-core/src/test/java/org/apache/helix/manager/zk/TestZkReconnect.java b/helix-core/src/test/java/org/apache/helix/manager/zk/TestZkReconnect.java
index 45ca347..9fdba9c 100644
--- a/helix-core/src/test/java/org/apache/helix/manager/zk/TestZkReconnect.java
+++ b/helix-core/src/test/java/org/apache/helix/manager/zk/TestZkReconnect.java
@@ -22,7 +22,6 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
-import org.I0Itec.zkclient.ZkServer;
import org.apache.helix.HelixException;
import org.apache.helix.HelixManager;
import org.apache.helix.HelixManagerFactory;
@@ -30,9 +29,10 @@
import org.apache.helix.SystemPropertyKeys;
import org.apache.helix.TestHelper;
import org.apache.helix.ZkTestHelper;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
import org.apache.helix.store.zk.ZkHelixPropertyStore;
import org.apache.helix.tools.ClusterSetup;
+import org.apache.helix.zookeeper.zkclient.ZkServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
diff --git a/helix-core/src/test/java/org/apache/helix/manager/zk/client/TestHelixZkClient.java b/helix-core/src/test/java/org/apache/helix/manager/zk/client/TestHelixZkClient.java
index 796d393..c228c4b 100644
--- a/helix-core/src/test/java/org/apache/helix/manager/zk/client/TestHelixZkClient.java
+++ b/helix-core/src/test/java/org/apache/helix/manager/zk/client/TestHelixZkClient.java
@@ -21,14 +21,16 @@
import java.util.concurrent.TimeUnit;
-import org.I0Itec.zkclient.IZkDataListener;
-import org.apache.helix.HelixException;
import org.apache.helix.TestHelper;
import org.apache.helix.ZkUnitTestBase;
-import org.apache.helix.manager.zk.zookeeper.ZkConnection;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.exception.ZkClientException;
+import org.apache.helix.zookeeper.zkclient.IZkDataListener;
+import org.apache.helix.zookeeper.zkclient.ZkConnection;
import org.testng.Assert;
import org.testng.annotations.Test;
+
public class TestHelixZkClient extends ZkUnitTestBase {
private final String TEST_NODE = "/test_helix_zkclient";
@@ -37,8 +39,9 @@
final String TEST_ROOT = "/testZkConnectionManager/IDEALSTATES";
final String TEST_PATH = TEST_ROOT + TEST_NODE;
- ZkConnectionManager zkConnectionManager = new ZkConnectionManager(new ZkConnection(ZK_ADDR),
- HelixZkClient.DEFAULT_CONNECTION_TIMEOUT, null);
+ ZkConnectionManager zkConnectionManager =
+ new ZkConnectionManager(new ZkConnection(ZK_ADDR), HelixZkClient.DEFAULT_CONNECTION_TIMEOUT,
+ null);
Assert.assertTrue(zkConnectionManager.waitUntilConnected(1, TimeUnit.SECONDS));
// This client can write/read from ZK
@@ -53,7 +56,7 @@
try {
zkConnectionManager.close();
Assert.fail("Dedicated ZkClient cannot be closed while sharing!");
- } catch (HelixException hex) {
+ } catch (ZkClientException hex) {
// expected
}
@@ -70,7 +73,7 @@
try {
new SharedZkClient(zkConnectionManager, new HelixZkClient.ZkClientConfig(), null);
Assert.fail("Sharing a closed dedicated ZkClient shall fail.");
- } catch (HelixException hex) {
+ } catch (ZkClientException hex) {
// expected
}
@@ -102,9 +105,7 @@
Assert.assertEquals(sharedZkClientA.getSessionId(), sharedZkClientB.getSessionId());
long sessionId = sharedZkClientA.getSessionId();
- final int[] notificationCountA = {
- 0, 0
- };
+ final int[] notificationCountA = {0, 0};
sharedZkClientA.subscribeDataChanges(TEST_PATH, new IZkDataListener() {
@Override
public void handleDataChange(String s, Object o) {
@@ -116,9 +117,7 @@
notificationCountA[1]++;
}
});
- final int[] notificationCountB = {
- 0, 0
- };
+ final int[] notificationCountB = {0, 0};
sharedZkClientB.subscribeDataChanges(TEST_PATH, new IZkDataListener() {
@Override
public void handleDataChange(String s, Object o) {
@@ -143,7 +142,7 @@
try {
sharedZkClientA.createEphemeral(TEST_PATH, true);
Assert.fail("Create Ephemeral nodes using shared client should fail.");
- } catch (HelixException he) {
+ } catch (UnsupportedOperationException e) {
// expected.
}
diff --git a/helix-core/src/test/java/org/apache/helix/manager/zk/serializer/TestJacksonPayloadSerializer.java b/helix-core/src/test/java/org/apache/helix/manager/zk/serializer/TestJacksonPayloadSerializer.java
index 85a362f..7a6a54a 100644
--- a/helix-core/src/test/java/org/apache/helix/manager/zk/serializer/TestJacksonPayloadSerializer.java
+++ b/helix-core/src/test/java/org/apache/helix/manager/zk/serializer/TestJacksonPayloadSerializer.java
@@ -23,7 +23,7 @@
import java.util.LinkedList;
import java.util.List;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.manager.zk.ZNRecordSerializer;
import org.apache.helix.manager.zk.ZNRecordStreamingSerializer;
import org.codehaus.jackson.JsonNode;
diff --git a/helix-core/src/test/java/org/apache/helix/messaging/TestDefaultMessagingService.java b/helix-core/src/test/java/org/apache/helix/messaging/TestDefaultMessagingService.java
index f431ab6..dcd5754 100644
--- a/helix-core/src/test/java/org/apache/helix/messaging/TestDefaultMessagingService.java
+++ b/helix-core/src/test/java/org/apache/helix/messaging/TestDefaultMessagingService.java
@@ -34,7 +34,7 @@
import org.apache.helix.NotificationContext;
import org.apache.helix.PropertyKey;
import org.apache.helix.PropertyType;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.messaging.handling.HelixTaskResult;
import org.apache.helix.messaging.handling.MessageHandler;
import org.apache.helix.messaging.handling.MessageHandlerFactory;
diff --git a/helix-core/src/test/java/org/apache/helix/mock/MockBaseDataAccessor.java b/helix-core/src/test/java/org/apache/helix/mock/MockBaseDataAccessor.java
index f50cd83..f9383b0 100644
--- a/helix-core/src/test/java/org/apache/helix/mock/MockBaseDataAccessor.java
+++ b/helix-core/src/test/java/org/apache/helix/mock/MockBaseDataAccessor.java
@@ -25,12 +25,12 @@
import java.util.List;
import java.util.Map;
-import org.I0Itec.zkclient.DataUpdater;
-import org.I0Itec.zkclient.IZkChildListener;
-import org.I0Itec.zkclient.IZkDataListener;
import org.apache.helix.BaseDataAccessor;
import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
+import org.apache.helix.zookeeper.zkclient.IZkChildListener;
+import org.apache.helix.zookeeper.zkclient.IZkDataListener;
import org.apache.zookeeper.data.Stat;
public class MockBaseDataAccessor implements BaseDataAccessor<ZNRecord> {
diff --git a/helix-core/src/test/java/org/apache/helix/mock/MockHelixAdmin.java b/helix-core/src/test/java/org/apache/helix/mock/MockHelixAdmin.java
index 8e17d73..b3502eb 100644
--- a/helix-core/src/test/java/org/apache/helix/mock/MockHelixAdmin.java
+++ b/helix-core/src/test/java/org/apache/helix/mock/MockHelixAdmin.java
@@ -30,7 +30,7 @@
import org.apache.helix.HelixManager;
import org.apache.helix.PropertyPathBuilder;
import org.apache.helix.PropertyType;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.model.ClusterConfig;
import org.apache.helix.model.ClusterConstraints;
import org.apache.helix.model.ConstraintItem;
diff --git a/helix-core/src/test/java/org/apache/helix/mock/MockManager.java b/helix-core/src/test/java/org/apache/helix/mock/MockManager.java
index bbe7d7b..dfb90ec 100644
--- a/helix-core/src/test/java/org/apache/helix/mock/MockManager.java
+++ b/helix-core/src/test/java/org/apache/helix/mock/MockManager.java
@@ -33,7 +33,7 @@
import org.apache.helix.MockAccessor;
import org.apache.helix.PreConnectCallback;
import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.api.listeners.ClusterConfigChangeListener;
import org.apache.helix.api.listeners.ConfigChangeListener;
import org.apache.helix.api.listeners.ControllerChangeListener;
diff --git a/helix-core/src/test/java/org/apache/helix/mock/MockZkClient.java b/helix-core/src/test/java/org/apache/helix/mock/MockZkClient.java
index b65c2dc..1acff11 100644
--- a/helix-core/src/test/java/org/apache/helix/mock/MockZkClient.java
+++ b/helix-core/src/test/java/org/apache/helix/mock/MockZkClient.java
@@ -6,8 +6,8 @@
import org.apache.helix.manager.zk.ZNRecordSerializer;
import org.apache.helix.manager.zk.ZkAsyncCallbacks;
-import org.apache.helix.manager.zk.ZkClient;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
public class MockZkClient extends ZkClient implements HelixZkClient {
Map<String, byte[]> _dataMap;
diff --git a/helix-core/src/test/java/org/apache/helix/mock/MockZkHelixDataAccessor.java b/helix-core/src/test/java/org/apache/helix/mock/MockZkHelixDataAccessor.java
index 9b71ff2..480be70 100644
--- a/helix-core/src/test/java/org/apache/helix/mock/MockZkHelixDataAccessor.java
+++ b/helix-core/src/test/java/org/apache/helix/mock/MockZkHelixDataAccessor.java
@@ -8,7 +8,7 @@
import org.apache.helix.HelixProperty;
import org.apache.helix.PropertyKey;
import org.apache.helix.PropertyType;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.manager.zk.ZKHelixDataAccessor;
public class MockZkHelixDataAccessor extends ZKHelixDataAccessor {
diff --git a/helix-core/src/test/java/org/apache/helix/mock/controller/MockController.java b/helix-core/src/test/java/org/apache/helix/mock/controller/MockController.java
index 55535e3..56710d2 100644
--- a/helix-core/src/test/java/org/apache/helix/mock/controller/MockController.java
+++ b/helix-core/src/test/java/org/apache/helix/mock/controller/MockController.java
@@ -30,12 +30,12 @@
import org.apache.helix.PropertyKey.Builder;
import org.apache.helix.PropertyPathBuilder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.manager.zk.ZKHelixDataAccessor;
import org.apache.helix.manager.zk.ZNRecordSerializer;
import org.apache.helix.manager.zk.ZkBaseDataAccessor;
-import org.apache.helix.manager.zk.client.DedicatedZkClientFactory;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.factory.DedicatedZkClientFactory;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
import org.apache.helix.model.ExternalView;
import org.apache.helix.model.IdealState.IdealStateProperty;
import org.apache.helix.model.LiveInstance.LiveInstanceProperty;
diff --git a/helix-core/src/test/java/org/apache/helix/mock/participant/StoreAccessDiffNodeTransition.java b/helix-core/src/test/java/org/apache/helix/mock/participant/StoreAccessDiffNodeTransition.java
index cee2a79..e3d3833 100644
--- a/helix-core/src/test/java/org/apache/helix/mock/participant/StoreAccessDiffNodeTransition.java
+++ b/helix-core/src/test/java/org/apache/helix/mock/participant/StoreAccessDiffNodeTransition.java
@@ -19,14 +19,15 @@
* under the License.
*/
-import org.I0Itec.zkclient.DataUpdater;
-import org.I0Itec.zkclient.exception.ZkNoNodeException;
import org.apache.helix.AccessOption;
import org.apache.helix.HelixManager;
import org.apache.helix.NotificationContext;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.model.Message;
import org.apache.helix.store.zk.ZkHelixPropertyStore;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNoNodeException;
+
// simulate access property store and update different znodes
public class StoreAccessDiffNodeTransition extends MockTransition {
diff --git a/helix-core/src/test/java/org/apache/helix/mock/participant/StoreAccessOneNodeTransition.java b/helix-core/src/test/java/org/apache/helix/mock/participant/StoreAccessOneNodeTransition.java
index 9e1c487..216fb57 100644
--- a/helix-core/src/test/java/org/apache/helix/mock/participant/StoreAccessOneNodeTransition.java
+++ b/helix-core/src/test/java/org/apache/helix/mock/participant/StoreAccessOneNodeTransition.java
@@ -19,14 +19,15 @@
* under the License.
*/
-import org.I0Itec.zkclient.DataUpdater;
-import org.I0Itec.zkclient.exception.ZkNoNodeException;
import org.apache.helix.AccessOption;
import org.apache.helix.HelixManager;
import org.apache.helix.NotificationContext;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.model.Message;
import org.apache.helix.store.zk.ZkHelixPropertyStore;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNoNodeException;
+
// simulate access property store and update one znode
public class StoreAccessOneNodeTransition extends MockTransition {
diff --git a/helix-core/src/test/java/org/apache/helix/mock/spectator/MockSpectatorProcess.java b/helix-core/src/test/java/org/apache/helix/mock/spectator/MockSpectatorProcess.java
index 60c0003..db00bb7 100644
--- a/helix-core/src/test/java/org/apache/helix/mock/spectator/MockSpectatorProcess.java
+++ b/helix-core/src/test/java/org/apache/helix/mock/spectator/MockSpectatorProcess.java
@@ -21,17 +21,18 @@
import java.util.List;
-import org.I0Itec.zkclient.IDefaultNameSpace;
-import org.I0Itec.zkclient.ZkServer;
import org.apache.helix.HelixManager;
import org.apache.helix.HelixManagerFactory;
import org.apache.helix.InstanceType;
import org.apache.helix.PropertyPathBuilder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.manager.zk.ZNRecordSerializer;
import org.apache.helix.model.InstanceConfig;
import org.apache.helix.spectator.RoutingTableProvider;
import org.apache.helix.tools.ClusterSetup;
+import org.apache.helix.zookeeper.zkclient.IDefaultNameSpace;
+import org.apache.helix.zookeeper.zkclient.ZkClient;
+import org.apache.helix.zookeeper.zkclient.ZkServer;
/**
@@ -79,7 +80,7 @@
IDefaultNameSpace defaultNameSpace = new IDefaultNameSpace() {
@Override
- public void createDefaultNameSpace(org.I0Itec.zkclient.ZkClient client) {
+ public void createDefaultNameSpace(ZkClient client) {
client.deleteRecursive("/" + clusterName);
}
diff --git a/helix-core/src/test/java/org/apache/helix/model/TestClusterConfig.java b/helix-core/src/test/java/org/apache/helix/model/TestClusterConfig.java
index d688827..8e4a016 100644
--- a/helix-core/src/test/java/org/apache/helix/model/TestClusterConfig.java
+++ b/helix-core/src/test/java/org/apache/helix/model/TestClusterConfig.java
@@ -26,7 +26,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.testng.Assert;
import org.testng.annotations.Test;
diff --git a/helix-core/src/test/java/org/apache/helix/model/TestConstraint.java b/helix-core/src/test/java/org/apache/helix/model/TestConstraint.java
index 78df6d3..43b9ee2 100644
--- a/helix-core/src/test/java/org/apache/helix/model/TestConstraint.java
+++ b/helix-core/src/test/java/org/apache/helix/model/TestConstraint.java
@@ -27,7 +27,7 @@
import org.apache.helix.PropertyKey.Builder;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.ZkUnitTestBase;
import org.apache.helix.manager.zk.ZKHelixDataAccessor;
import org.apache.helix.manager.zk.ZkBaseDataAccessor;
diff --git a/helix-core/src/test/java/org/apache/helix/model/TestInstanceConfig.java b/helix-core/src/test/java/org/apache/helix/model/TestInstanceConfig.java
index f4c7715..9b47677 100644
--- a/helix-core/src/test/java/org/apache/helix/model/TestInstanceConfig.java
+++ b/helix-core/src/test/java/org/apache/helix/model/TestInstanceConfig.java
@@ -20,7 +20,7 @@
*/
import com.google.common.collect.ImmutableMap;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.testng.Assert;
import org.testng.annotations.Test;
diff --git a/helix-core/src/test/java/org/apache/helix/model/TestResourceConfig.java b/helix-core/src/test/java/org/apache/helix/model/TestResourceConfig.java
index 8099486..2e13c3e 100644
--- a/helix-core/src/test/java/org/apache/helix/model/TestResourceConfig.java
+++ b/helix-core/src/test/java/org/apache/helix/model/TestResourceConfig.java
@@ -20,7 +20,7 @@
*/
import com.google.common.collect.ImmutableMap;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.codehaus.jackson.map.ObjectMapper;
import org.testng.Assert;
import org.testng.annotations.Test;
diff --git a/helix-core/src/test/java/org/apache/helix/model/TestStateModelValidity.java b/helix-core/src/test/java/org/apache/helix/model/TestStateModelValidity.java
index c3b8beb..88cbb39 100644
--- a/helix-core/src/test/java/org/apache/helix/model/TestStateModelValidity.java
+++ b/helix-core/src/test/java/org/apache/helix/model/TestStateModelValidity.java
@@ -26,7 +26,7 @@
import com.google.common.collect.Lists;
import org.apache.helix.HelixDefinedState;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.model.StateModelDefinition.StateModelDefinitionProperty;
import org.apache.helix.tools.StateModelConfigGenerator;
import org.testng.Assert;
diff --git a/helix-core/src/test/java/org/apache/helix/model/TestStateTransitionProperty.java b/helix-core/src/test/java/org/apache/helix/model/TestStateTransitionProperty.java
index 86ab7fb..a5ea1e1 100644
--- a/helix-core/src/test/java/org/apache/helix/model/TestStateTransitionProperty.java
+++ b/helix-core/src/test/java/org/apache/helix/model/TestStateTransitionProperty.java
@@ -19,7 +19,7 @@
* under the License.
*/
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.api.config.StateTransitionTimeoutConfig;
import org.testng.Assert;
import org.testng.annotations.Test;
diff --git a/helix-core/src/test/java/org/apache/helix/monitoring/TestZKPathDataDumpTask.java b/helix-core/src/test/java/org/apache/helix/monitoring/TestZKPathDataDumpTask.java
index 8085a93..a724d3e 100644
--- a/helix-core/src/test/java/org/apache/helix/monitoring/TestZKPathDataDumpTask.java
+++ b/helix-core/src/test/java/org/apache/helix/monitoring/TestZKPathDataDumpTask.java
@@ -26,7 +26,7 @@
import org.apache.helix.HelixManager;
import org.apache.helix.PropertyKey;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.ZkUnitTestBase;
import org.apache.helix.manager.zk.ZKHelixDataAccessor;
import org.apache.helix.manager.zk.ZkBaseDataAccessor;
diff --git a/helix-core/src/test/java/org/apache/helix/monitoring/mbeans/TestClusterStatusMonitor.java b/helix-core/src/test/java/org/apache/helix/monitoring/mbeans/TestClusterStatusMonitor.java
index f4ba01f..dee1f86 100644
--- a/helix-core/src/test/java/org/apache/helix/monitoring/mbeans/TestClusterStatusMonitor.java
+++ b/helix-core/src/test/java/org/apache/helix/monitoring/mbeans/TestClusterStatusMonitor.java
@@ -42,7 +42,7 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.controller.stages.BestPossibleStateOutput;
import org.apache.helix.model.BuiltInStateModelDefinitions;
import org.apache.helix.model.ExternalView;
diff --git a/helix-core/src/test/java/org/apache/helix/monitoring/mbeans/TestResourceMonitor.java b/helix-core/src/test/java/org/apache/helix/monitoring/mbeans/TestResourceMonitor.java
index f630124..623ae58 100644
--- a/helix-core/src/test/java/org/apache/helix/monitoring/mbeans/TestResourceMonitor.java
+++ b/helix-core/src/test/java/org/apache/helix/monitoring/mbeans/TestResourceMonitor.java
@@ -37,7 +37,7 @@
import com.google.common.collect.ImmutableMap;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.model.BuiltInStateModelDefinitions;
import org.apache.helix.model.ExternalView;
import org.apache.helix.model.IdealState;
diff --git a/helix-core/src/test/java/org/apache/helix/participant/MockZKHelixManager.java b/helix-core/src/test/java/org/apache/helix/participant/MockZKHelixManager.java
index f22484e..85b376f 100644
--- a/helix-core/src/test/java/org/apache/helix/participant/MockZKHelixManager.java
+++ b/helix-core/src/test/java/org/apache/helix/participant/MockZKHelixManager.java
@@ -32,7 +32,7 @@
import org.apache.helix.LiveInstanceInfoProvider;
import org.apache.helix.PreConnectCallback;
import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.api.listeners.ClusterConfigChangeListener;
import org.apache.helix.api.listeners.ConfigChangeListener;
import org.apache.helix.api.listeners.ControllerChangeListener;
@@ -48,7 +48,7 @@
import org.apache.helix.healthcheck.ParticipantHealthReportCollector;
import org.apache.helix.manager.zk.ZKHelixDataAccessor;
import org.apache.helix.manager.zk.ZkBaseDataAccessor;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
import org.apache.helix.messaging.DefaultMessagingService;
import org.apache.helix.model.HelixConfigScope.ConfigScopeProperty;
import org.apache.helix.store.zk.ZkHelixPropertyStore;
diff --git a/helix-core/src/test/java/org/apache/helix/participant/TestDistControllerStateModel.java b/helix-core/src/test/java/org/apache/helix/participant/TestDistControllerStateModel.java
index 28c0fb0..51bb209 100644
--- a/helix-core/src/test/java/org/apache/helix/participant/TestDistControllerStateModel.java
+++ b/helix-core/src/test/java/org/apache/helix/participant/TestDistControllerStateModel.java
@@ -21,7 +21,7 @@
import org.apache.helix.NotificationContext;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.ZkUnitTestBase;
import org.apache.helix.model.Message;
import org.apache.helix.model.Message.MessageType;
diff --git a/helix-core/src/test/java/org/apache/helix/participant/TestDistControllerStateModelFactory.java b/helix-core/src/test/java/org/apache/helix/participant/TestDistControllerStateModelFactory.java
index b7aa419..e7d3d76 100644
--- a/helix-core/src/test/java/org/apache/helix/participant/TestDistControllerStateModelFactory.java
+++ b/helix-core/src/test/java/org/apache/helix/participant/TestDistControllerStateModelFactory.java
@@ -19,7 +19,7 @@
* under the License.
*/
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.ZkUnitTestBase;
import org.apache.helix.model.Message;
import org.testng.annotations.Test;
diff --git a/helix-core/src/test/java/org/apache/helix/spectator/TestRoutingDataCache.java b/helix-core/src/test/java/org/apache/helix/spectator/TestRoutingDataCache.java
index 2cfc62a..146dd37 100644
--- a/helix-core/src/test/java/org/apache/helix/spectator/TestRoutingDataCache.java
+++ b/helix-core/src/test/java/org/apache/helix/spectator/TestRoutingDataCache.java
@@ -24,7 +24,7 @@
import org.apache.helix.HelixConstants;
import org.apache.helix.PropertyType;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.integration.common.ZkStandAloneCMTestBase;
import org.apache.helix.manager.zk.ZkBaseDataAccessor;
import org.apache.helix.mock.MockZkHelixDataAccessor;
diff --git a/helix-core/src/test/java/org/apache/helix/store/TestJsonComparator.java b/helix-core/src/test/java/org/apache/helix/store/TestJsonComparator.java
index 5af3d55..fdfbbce 100644
--- a/helix-core/src/test/java/org/apache/helix/store/TestJsonComparator.java
+++ b/helix-core/src/test/java/org/apache/helix/store/TestJsonComparator.java
@@ -21,7 +21,7 @@
import java.util.Date;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.testng.AssertJUnit;
import org.testng.annotations.Test;
diff --git a/helix-core/src/test/java/org/apache/helix/store/zk/TestAutoFallbackPropertyStore.java b/helix-core/src/test/java/org/apache/helix/store/zk/TestAutoFallbackPropertyStore.java
index 4b44cb1..f322397 100644
--- a/helix-core/src/test/java/org/apache/helix/store/zk/TestAutoFallbackPropertyStore.java
+++ b/helix-core/src/test/java/org/apache/helix/store/zk/TestAutoFallbackPropertyStore.java
@@ -23,13 +23,13 @@
import java.util.Date;
import java.util.List;
-import org.I0Itec.zkclient.DataUpdater;
import org.apache.helix.AccessOption;
import org.apache.helix.PropertyType;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.ZkUnitTestBase;
import org.apache.helix.manager.zk.ZkBaseDataAccessor;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
import org.apache.zookeeper.data.Stat;
import org.testng.Assert;
import org.testng.annotations.Test;
diff --git a/helix-core/src/test/java/org/apache/helix/store/zk/TestZkHelixPropertyStore.java b/helix-core/src/test/java/org/apache/helix/store/zk/TestZkHelixPropertyStore.java
index 8b882a7..98fa298 100644
--- a/helix-core/src/test/java/org/apache/helix/store/zk/TestZkHelixPropertyStore.java
+++ b/helix-core/src/test/java/org/apache/helix/store/zk/TestZkHelixPropertyStore.java
@@ -31,18 +31,18 @@
import javax.management.MBeanServer;
import javax.management.ObjectName;
-import org.I0Itec.zkclient.exception.ZkNoNodeException;
-import org.I0Itec.zkclient.serialize.SerializableSerializer;
import org.apache.helix.AccessOption;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.ZkUnitTestBase;
import org.apache.helix.manager.zk.ZkBaseDataAccessor;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
import org.apache.helix.monitoring.mbeans.MBeanRegistrar;
import org.apache.helix.monitoring.mbeans.MonitorDomainNames;
import org.apache.helix.monitoring.mbeans.ZkClientMonitor;
import org.apache.helix.monitoring.mbeans.ZkClientPathMonitor;
import org.apache.helix.store.HelixPropertyListener;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNoNodeException;
+import org.apache.helix.zookeeper.zkclient.serialize.SerializableSerializer;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.Test;
diff --git a/helix-core/src/test/java/org/apache/helix/store/zk/TestZkManagerWithAutoFallbackStore.java b/helix-core/src/test/java/org/apache/helix/store/zk/TestZkManagerWithAutoFallbackStore.java
index ed22835..df78aa9 100644
--- a/helix-core/src/test/java/org/apache/helix/store/zk/TestZkManagerWithAutoFallbackStore.java
+++ b/helix-core/src/test/java/org/apache/helix/store/zk/TestZkManagerWithAutoFallbackStore.java
@@ -24,7 +24,7 @@
import org.apache.helix.AccessOption;
import org.apache.helix.BaseDataAccessor;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.ZkUnitTestBase;
import org.apache.helix.integration.manager.MockParticipantManager;
import org.testng.Assert;
diff --git a/helix-core/src/test/java/org/apache/helix/task/TestAssignableInstanceManager.java b/helix-core/src/test/java/org/apache/helix/task/TestAssignableInstanceManager.java
index 76197f7..08b4166 100644
--- a/helix-core/src/test/java/org/apache/helix/task/TestAssignableInstanceManager.java
+++ b/helix-core/src/test/java/org/apache/helix/task/TestAssignableInstanceManager.java
@@ -27,7 +27,7 @@
import java.util.Map;
import java.util.Set;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.common.caches.TaskDataCache;
import org.apache.helix.model.ClusterConfig;
import org.apache.helix.model.InstanceConfig;
diff --git a/helix-core/src/test/java/org/apache/helix/tools/TestClusterSetup.java b/helix-core/src/test/java/org/apache/helix/tools/TestClusterSetup.java
index df3f341..2a3e04a 100644
--- a/helix-core/src/test/java/org/apache/helix/tools/TestClusterSetup.java
+++ b/helix-core/src/test/java/org/apache/helix/tools/TestClusterSetup.java
@@ -29,7 +29,7 @@
import org.apache.helix.PropertyKey.Builder;
import org.apache.helix.PropertyPathBuilder;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.ZkUnitTestBase;
import org.apache.helix.manager.zk.ZKHelixAdmin;
import org.apache.helix.manager.zk.ZKHelixDataAccessor;
diff --git a/helix-core/src/test/java/org/apache/helix/tools/TestHelixAdminCli.java b/helix-core/src/test/java/org/apache/helix/tools/TestHelixAdminCli.java
index 1008371..660c8de 100644
--- a/helix-core/src/test/java/org/apache/helix/tools/TestHelixAdminCli.java
+++ b/helix-core/src/test/java/org/apache/helix/tools/TestHelixAdminCli.java
@@ -29,7 +29,7 @@
import org.apache.helix.BaseDataAccessor;
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.common.ZkTestBase;
import org.apache.helix.integration.manager.ClusterDistributedController;
import org.apache.helix.integration.manager.MockParticipantManager;
diff --git a/helix-core/src/test/java/org/apache/helix/tools/TestZkCopy.java b/helix-core/src/test/java/org/apache/helix/tools/TestZkCopy.java
index 17d857e..a241719 100644
--- a/helix-core/src/test/java/org/apache/helix/tools/TestZkCopy.java
+++ b/helix-core/src/test/java/org/apache/helix/tools/TestZkCopy.java
@@ -23,7 +23,7 @@
import org.apache.helix.InstanceType;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.ZkUnitTestBase;
import org.apache.helix.manager.zk.ZKUtil;
import org.apache.helix.tools.commandtools.ZkCopy;
diff --git a/helix-core/src/test/java/org/apache/helix/util/TestPropertyKeyGetPath.java b/helix-core/src/test/java/org/apache/helix/util/TestPropertyKeyGetPath.java
index fc0a3f3..572c5c6 100644
--- a/helix-core/src/test/java/org/apache/helix/util/TestPropertyKeyGetPath.java
+++ b/helix-core/src/test/java/org/apache/helix/util/TestPropertyKeyGetPath.java
@@ -22,7 +22,7 @@
import com.google.common.base.Joiner;
import org.apache.helix.AccessOption;
import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.integration.task.TaskTestBase;
import org.apache.helix.task.TaskConstants;
import org.apache.helix.task.WorkflowContext;
diff --git a/helix-core/src/test/java/org/apache/helix/util/TestZKClientPool.java b/helix-core/src/test/java/org/apache/helix/util/TestZKClientPool.java
index 5c5c8ae..d94d2aa 100644
--- a/helix-core/src/test/java/org/apache/helix/util/TestZKClientPool.java
+++ b/helix-core/src/test/java/org/apache/helix/util/TestZKClientPool.java
@@ -21,11 +21,11 @@
import java.util.Date;
-import org.I0Itec.zkclient.ZkServer;
-import org.I0Itec.zkclient.exception.ZkNoNodeException;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
+import org.apache.helix.zookeeper.zkclient.ZkServer;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNoNodeException;
import org.testng.Assert;
import org.testng.annotations.Test;
diff --git a/helix-rest/pom.xml b/helix-rest/pom.xml
index b14b902..e3421d5 100644
--- a/helix-rest/pom.xml
+++ b/helix-rest/pom.xml
@@ -36,6 +36,8 @@
org.apache.commons.cli*,
org.restlet*,
org.slf4j*;version="[1.6,2)",
+ org.apache.zookeeper*;version="[3.4,4)",
+ org.apache.commons.io*;version="[1.4,2)",
*
</osgi.import>
<osgi.export>org.apache.helix.rest*;version="${project.version};-noimport:=true</osgi.export>
diff --git a/helix-rest/src/main/java/org/apache/helix/rest/common/HelixDataAccessorWrapper.java b/helix-rest/src/main/java/org/apache/helix/rest/common/HelixDataAccessorWrapper.java
index 6a501f0..e68276c 100644
--- a/helix-rest/src/main/java/org/apache/helix/rest/common/HelixDataAccessorWrapper.java
+++ b/helix-rest/src/main/java/org/apache/helix/rest/common/HelixDataAccessorWrapper.java
@@ -34,7 +34,7 @@
import org.apache.helix.HelixProperty;
import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.manager.zk.ZKHelixDataAccessor;
import org.apache.helix.model.RESTConfig;
import org.apache.helix.rest.client.CustomRestClient;
diff --git a/helix-rest/src/main/java/org/apache/helix/rest/server/ServerContext.java b/helix-rest/src/main/java/org/apache/helix/rest/server/ServerContext.java
index acacce9..5a0530a 100644
--- a/helix-rest/src/main/java/org/apache/helix/rest/server/ServerContext.java
+++ b/helix-rest/src/main/java/org/apache/helix/rest/server/ServerContext.java
@@ -23,22 +23,22 @@
import java.util.HashMap;
import java.util.Map;
-import org.I0Itec.zkclient.exception.ZkMarshallingError;
-import org.I0Itec.zkclient.serialize.ZkSerializer;
import org.apache.helix.ConfigAccessor;
import org.apache.helix.HelixAdmin;
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.InstanceType;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.manager.zk.ZKHelixAdmin;
import org.apache.helix.manager.zk.ZKHelixDataAccessor;
import org.apache.helix.manager.zk.ZNRecordSerializer;
import org.apache.helix.manager.zk.ZkBaseDataAccessor;
-import org.apache.helix.manager.zk.ZkClient;
-import org.apache.helix.manager.zk.client.HelixZkClient;
-import org.apache.helix.manager.zk.client.SharedZkClientFactory;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.factory.SharedZkClientFactory;
import org.apache.helix.task.TaskDriver;
import org.apache.helix.tools.ClusterSetup;
+import org.apache.helix.zookeeper.zkclient.exception.ZkMarshallingError;
+import org.apache.helix.zookeeper.zkclient.serialize.ZkSerializer;
public class ServerContext {
diff --git a/helix-rest/src/main/java/org/apache/helix/rest/server/json/instance/InstanceInfo.java b/helix-rest/src/main/java/org/apache/helix/rest/server/json/instance/InstanceInfo.java
index 6855e44..b37f033 100644
--- a/helix-rest/src/main/java/org/apache/helix/rest/server/json/instance/InstanceInfo.java
+++ b/helix-rest/src/main/java/org/apache/helix/rest/server/json/instance/InstanceInfo.java
@@ -25,7 +25,7 @@
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/AbstractHelixResource.java b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/AbstractHelixResource.java
index b13e740..f1bb583 100644
--- a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/AbstractHelixResource.java
+++ b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/AbstractHelixResource.java
@@ -24,10 +24,10 @@
import org.apache.helix.ConfigAccessor;
import org.apache.helix.HelixAdmin;
import org.apache.helix.HelixDataAccessor;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.manager.zk.ZkBaseDataAccessor;
-import org.apache.helix.manager.zk.ZkClient;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
import org.apache.helix.rest.common.ContextPropertyKeys;
import org.apache.helix.rest.server.ServerContext;
import org.apache.helix.rest.server.resources.AbstractResource;
diff --git a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/ClusterAccessor.java b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/ClusterAccessor.java
index f7f9af5..1257cdb 100644
--- a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/ClusterAccessor.java
+++ b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/ClusterAccessor.java
@@ -44,9 +44,9 @@
import org.apache.helix.HelixException;
import org.apache.helix.PropertyKey;
import org.apache.helix.PropertyPathBuilder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.manager.zk.ZKUtil;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
import org.apache.helix.model.ClusterConfig;
import org.apache.helix.model.ControllerHistory;
import org.apache.helix.model.HelixConfigScope;
diff --git a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/JobAccessor.java b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/JobAccessor.java
index ee84df7..3a6afee 100644
--- a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/JobAccessor.java
+++ b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/JobAccessor.java
@@ -34,14 +34,14 @@
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
-import org.I0Itec.zkclient.exception.ZkNoNodeException;
import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.task.JobConfig;
import org.apache.helix.task.JobContext;
import org.apache.helix.task.TaskConfig;
import org.apache.helix.task.TaskDriver;
import org.apache.helix.task.WorkflowConfig;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNoNodeException;
import org.codehaus.jackson.node.ArrayNode;
import org.codehaus.jackson.node.JsonNodeFactory;
import org.codehaus.jackson.node.ObjectNode;
diff --git a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/PerInstanceAccessor.java b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/PerInstanceAccessor.java
index 368c730..2f861bc 100644
--- a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/PerInstanceAccessor.java
+++ b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/PerInstanceAccessor.java
@@ -40,7 +40,7 @@
import org.apache.helix.HelixAdmin;
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.manager.zk.ZKHelixDataAccessor;
import org.apache.helix.model.CurrentState;
import org.apache.helix.model.Error;
diff --git a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/PropertyStoreAccessor.java b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/PropertyStoreAccessor.java
index 95a8723..4ccc610 100644
--- a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/PropertyStoreAccessor.java
+++ b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/PropertyStoreAccessor.java
@@ -27,7 +27,7 @@
import org.apache.helix.AccessOption;
import org.apache.helix.PropertyPathBuilder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.manager.zk.ZNRecordSerializer;
import org.apache.helix.manager.zk.ZkBaseDataAccessor;
import org.apache.helix.rest.server.resources.zookeeper.ZooKeeperAccessor;
diff --git a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/ResourceAccessor.java b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/ResourceAccessor.java
index c41d024..ca2189e 100644
--- a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/ResourceAccessor.java
+++ b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/ResourceAccessor.java
@@ -41,8 +41,8 @@
import org.apache.helix.HelixAdmin;
import org.apache.helix.HelixException;
import org.apache.helix.PropertyPathBuilder;
-import org.apache.helix.ZNRecord;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
import org.apache.helix.model.ExternalView;
import org.apache.helix.model.HelixConfigScope;
import org.apache.helix.model.IdealState;
diff --git a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/TaskAccessor.java b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/TaskAccessor.java
index 22617db..115813d 100644
--- a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/TaskAccessor.java
+++ b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/TaskAccessor.java
@@ -29,8 +29,8 @@
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
-import org.I0Itec.zkclient.exception.ZkNoNodeException;
import org.apache.helix.task.TaskDriver;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNoNodeException;
import org.codehaus.jackson.type.TypeReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/WorkflowAccessor.java b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/WorkflowAccessor.java
index 714571e..384b37c 100644
--- a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/WorkflowAccessor.java
+++ b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/helix/WorkflowAccessor.java
@@ -36,9 +36,8 @@
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
-import org.I0Itec.zkclient.exception.ZkNoNodeException;
import org.apache.helix.HelixException;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.task.JobConfig;
import org.apache.helix.task.JobDag;
import org.apache.helix.task.JobQueue;
@@ -46,6 +45,7 @@
import org.apache.helix.task.Workflow;
import org.apache.helix.task.WorkflowConfig;
import org.apache.helix.task.WorkflowContext;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNoNodeException;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.type.TypeFactory;
import org.codehaus.jackson.node.ArrayNode;
diff --git a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/zookeeper/ZooKeeperAccessor.java b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/zookeeper/ZooKeeperAccessor.java
index cae7dc1..0774bc7 100644
--- a/helix-rest/src/main/java/org/apache/helix/rest/server/resources/zookeeper/ZooKeeperAccessor.java
+++ b/helix-rest/src/main/java/org/apache/helix/rest/server/resources/zookeeper/ZooKeeperAccessor.java
@@ -19,8 +19,6 @@
* under the License.
*/
-import java.io.UnsupportedEncodingException;
-import java.util.Base64;
import java.util.List;
import java.util.Map;
import javax.ws.rs.GET;
@@ -159,9 +157,9 @@
* @return list of child ZNodes
*/
private Response getChildren(ZkBaseDataAccessor<byte[]> zkBaseDataAccessor, String path) {
- if (_zkBaseDataAccessor.exists(path, AccessOption.PERSISTENT)) {
+ if (zkBaseDataAccessor.exists(path, AccessOption.PERSISTENT)) {
Map<String, List<String>> result = ImmutableMap.of(ZooKeeperCommand.getChildren.name(),
- _zkBaseDataAccessor.getChildNames(path, AccessOption.PERSISTENT));
+ zkBaseDataAccessor.getChildNames(path, AccessOption.PERSISTENT));
return JSONRepresentation(result);
} else {
throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND)
diff --git a/helix-rest/src/test/java/org/apache/helix/rest/common/TestHelixDataAccessorWrapper.java b/helix-rest/src/test/java/org/apache/helix/rest/common/TestHelixDataAccessorWrapper.java
index 5cf4fba..0449aa9 100644
--- a/helix-rest/src/test/java/org/apache/helix/rest/common/TestHelixDataAccessorWrapper.java
+++ b/helix-rest/src/test/java/org/apache/helix/rest/common/TestHelixDataAccessorWrapper.java
@@ -30,7 +30,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import org.apache.helix.PropertyKey;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.manager.zk.ZKHelixDataAccessor;
import org.apache.helix.model.HealthStat;
import org.apache.helix.model.RESTConfig;
diff --git a/helix-rest/src/test/java/org/apache/helix/rest/server/AbstractTestClass.java b/helix-rest/src/test/java/org/apache/helix/rest/server/AbstractTestClass.java
index e3b33fb..cc04984 100644
--- a/helix-rest/src/test/java/org/apache/helix/rest/server/AbstractTestClass.java
+++ b/helix-rest/src/test/java/org/apache/helix/rest/server/AbstractTestClass.java
@@ -37,22 +37,21 @@
import javax.ws.rs.core.Response;
import com.google.common.base.Joiner;
-import org.I0Itec.zkclient.ZkServer;
import org.apache.helix.AccessOption;
import org.apache.helix.BaseDataAccessor;
import org.apache.helix.ConfigAccessor;
import org.apache.helix.PropertyPathBuilder;
import org.apache.helix.PropertyType;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.integration.manager.ClusterControllerManager;
import org.apache.helix.integration.manager.MockParticipantManager;
import org.apache.helix.integration.task.MockTask;
import org.apache.helix.integration.task.TaskTestUtil;
import org.apache.helix.manager.zk.ZNRecordSerializer;
import org.apache.helix.manager.zk.ZkBaseDataAccessor;
-import org.apache.helix.manager.zk.client.DedicatedZkClientFactory;
-import org.apache.helix.manager.zk.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.factory.DedicatedZkClientFactory;
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
import org.apache.helix.model.ClusterConfig;
import org.apache.helix.model.IdealState;
import org.apache.helix.model.InstanceConfig;
@@ -80,6 +79,7 @@
import org.apache.helix.task.WorkflowContext;
import org.apache.helix.tools.ClusterSetup;
import org.apache.helix.util.ZKClientPool;
+import org.apache.helix.zookeeper.zkclient.ZkServer;
import org.codehaus.jackson.map.ObjectMapper;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.server.ResourceConfig;
diff --git a/helix-rest/src/test/java/org/apache/helix/rest/server/TestClusterAccessor.java b/helix-rest/src/test/java/org/apache/helix/rest/server/TestClusterAccessor.java
index 05525c0..e7fda60 100644
--- a/helix-rest/src/test/java/org/apache/helix/rest/server/TestClusterAccessor.java
+++ b/helix-rest/src/test/java/org/apache/helix/rest/server/TestClusterAccessor.java
@@ -36,7 +36,7 @@
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.PropertyKey;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.controller.rebalancer.DelayedAutoRebalancer;
import org.apache.helix.controller.rebalancer.strategy.CrushEdRebalanceStrategy;
import org.apache.helix.controller.rebalancer.waged.WagedRebalancer;
diff --git a/helix-rest/src/test/java/org/apache/helix/rest/server/TestPerInstanceAccessor.java b/helix-rest/src/test/java/org/apache/helix/rest/server/TestPerInstanceAccessor.java
index d57bbde..68a4e85 100644
--- a/helix-rest/src/test/java/org/apache/helix/rest/server/TestPerInstanceAccessor.java
+++ b/helix-rest/src/test/java/org/apache/helix/rest/server/TestPerInstanceAccessor.java
@@ -36,7 +36,7 @@
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.HelixException;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.manager.zk.ZKHelixDataAccessor;
import org.apache.helix.model.ClusterConfig;
import org.apache.helix.model.InstanceConfig;
diff --git a/helix-rest/src/test/java/org/apache/helix/rest/server/TestPropertyStoreAccessor.java b/helix-rest/src/test/java/org/apache/helix/rest/server/TestPropertyStoreAccessor.java
index cfc6461..fc0a701 100644
--- a/helix-rest/src/test/java/org/apache/helix/rest/server/TestPropertyStoreAccessor.java
+++ b/helix-rest/src/test/java/org/apache/helix/rest/server/TestPropertyStoreAccessor.java
@@ -22,13 +22,13 @@
import java.io.IOException;
import javax.ws.rs.core.Response;
-import org.I0Itec.zkclient.exception.ZkMarshallingError;
-import org.I0Itec.zkclient.serialize.ZkSerializer;
import org.apache.helix.AccessOption;
import org.apache.helix.PropertyPathBuilder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.manager.zk.ZkBaseDataAccessor;
import org.apache.helix.rest.server.util.JerseyUriRequestBuilder;
+import org.apache.helix.zookeeper.zkclient.exception.ZkMarshallingError;
+import org.apache.helix.zookeeper.zkclient.serialize.ZkSerializer;
import org.apache.http.HttpStatus;
import org.codehaus.jackson.JsonNode;
import org.junit.Assert;
diff --git a/helix-rest/src/test/java/org/apache/helix/rest/server/TestResourceAccessor.java b/helix-rest/src/test/java/org/apache/helix/rest/server/TestResourceAccessor.java
index f865674..6d672ed 100644
--- a/helix-rest/src/test/java/org/apache/helix/rest/server/TestResourceAccessor.java
+++ b/helix-rest/src/test/java/org/apache/helix/rest/server/TestResourceAccessor.java
@@ -40,7 +40,7 @@
import org.apache.helix.InstanceType;
import org.apache.helix.PropertyPathBuilder;
import org.apache.helix.TestHelper;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.controller.rebalancer.waged.WagedRebalancer;
import org.apache.helix.model.ClusterConfig;
import org.apache.helix.model.ExternalView;
diff --git a/helix-rest/src/test/java/org/apache/helix/rest/server/TestZooKeeperAccessor.java b/helix-rest/src/test/java/org/apache/helix/rest/server/TestZooKeeperAccessor.java
index 4d71d56..23337ba 100644
--- a/helix-rest/src/test/java/org/apache/helix/rest/server/TestZooKeeperAccessor.java
+++ b/helix-rest/src/test/java/org/apache/helix/rest/server/TestZooKeeperAccessor.java
@@ -27,11 +27,11 @@
import javax.ws.rs.core.Response;
-import org.I0Itec.zkclient.exception.ZkMarshallingError;
-import org.I0Itec.zkclient.serialize.ZkSerializer;
import org.apache.helix.AccessOption;
import org.apache.helix.manager.zk.ZkBaseDataAccessor;
import org.apache.helix.rest.server.util.JerseyUriRequestBuilder;
+import org.apache.helix.zookeeper.zkclient.exception.ZkMarshallingError;
+import org.apache.helix.zookeeper.zkclient.serialize.ZkSerializer;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
diff --git a/metrics-common/LICENSE b/metrics-common/LICENSE
new file mode 100644
index 0000000..d78ae52
--- /dev/null
+++ b/metrics-common/LICENSE
@@ -0,0 +1,270 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+
+For xstream:
+
+Copyright (c) 2003-2006, Joe Walnes
+Copyright (c) 2006-2009, 2011 XStream Committers
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this list of
+conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice, this list of
+conditions and the following disclaimer in the documentation and/or other materials provided
+with the distribution.
+
+3. Neither the name of XStream nor the names of its contributors may be used to endorse
+or promote products derived from this software without specific prior written
+permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
+for jline:
+
+Copyright (c) 2002-2006, Marc Prud'hommeaux <mwp1@cornell.edu>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or
+without modification, are permitted provided that the following
+conditions are met:
+
+Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with
+the distribution.
+
+Neither the name of JLine nor the names of its contributors
+may be used to endorse or promote products derived from this
+software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/metrics-common/NOTICE b/metrics-common/NOTICE
new file mode 100644
index 0000000..ff5a745
--- /dev/null
+++ b/metrics-common/NOTICE
@@ -0,0 +1,37 @@
+Apache Helix
+Copyright 2014 The Apache Software Foundation
+
+
+I. Included Software
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+Licensed under the Apache License 2.0.
+
+This product includes software developed at
+Codehaus (http://www.codehaus.org/).
+Licensed under the BSD License.
+
+This product includes software developed at
+jline (http://jline.sourceforge.net/).
+Licensed under the BSD License.
+
+This product includes software developed at
+restlet (http://www.restlet.org/about/legal).
+Licensed under the Apache License 2.0.
+
+This product includes software developed at
+Google (http://www.google.com/).
+Licensed under the Apache License 2.0.
+
+This product includes software developed at
+snakeyaml (http://www.snakeyaml.org/).
+Licensed under the Apache License 2.0.
+
+This product includes software developed at
+zkclient (https://github.com/sgroschupf/zkclient).
+Licensed under the Apache License 2.0.
+
+II. License Summary
+- Apache License 2.0
+- BSD License
\ No newline at end of file
diff --git a/metrics-common/metrics-common-0.9.2-SNAPSHOT.ivy b/metrics-common/metrics-common-0.9.2-SNAPSHOT.ivy
new file mode 100644
index 0000000..e84dd9a
--- /dev/null
+++ b/metrics-common/metrics-common-0.9.2-SNAPSHOT.ivy
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<ivy-module version="1.0">
+ <info organisation="org.apache.helix"
+ module="metrics-common"
+ revision="0.9.2-SNAPSHOT"
+ status="integration"
+ publication="20170128141623"
+ />
+ <configurations>
+ <conf name="default" visibility="public" description="runtime dependencies and master artifact can be used with this conf" extends="runtime,master"/>
+ <conf name="master" visibility="public" description="contains only the artifact published by this module itself, with no transitive dependencies"/>
+ <conf name="compile" visibility="public" description="this is the default scope, used if none is specified. Compile dependencies are available in all classpaths."/>
+ <conf name="provided" visibility="public" description="this is much like compile, but indicates you expect the JDK or a container to provide it. It is only available on the compilation classpath, and is not transitive."/>
+ <conf name="runtime" visibility="public" description="this scope indicates that the dependency is not required for compilation, but is for execution. It is in the runtime and test classpaths, but not the compile classpath." extends="compile"/>
+ <conf name="test" visibility="private" description="this scope indicates that the dependency is not required for normal use of the application, and is only available for the test compilation and execution phases."/>
+ <conf name="system" visibility="public" description="this scope is similar to provided except that you have to provide the JAR which contains it explicitly. The artifact is always available and is not looked up in a repository."/>
+ </configurations>
+ <publications>
+ <artifact name="metrics-common" type="jar" ext="jar" conf="master"/>
+ </publications>
+ <dependencies>
+ <dependency org="org.slf4j" name="slf4j-api" rev="1.7.25" force="true" conf="compile->compile(*),master(*);runtime->runtime(*)">
+ <artifact name="slf4j-api" ext="jar"/>
+ </dependency>
+ <dependency org="org.slf4j" name="slf4j-log4j12" rev="1.7.14" force="true" conf="compile->compile(*),master(*);runtime->runtime(*)">
+ <artifact name="slf4j-log4j12" ext="jar"/>
+ </dependency>
+ </dependencies>
+</ivy-module>
diff --git a/metrics-common/pom.xml b/metrics-common/pom.xml
new file mode 100644
index 0000000..79a5e1f
--- /dev/null
+++ b/metrics-common/pom.xml
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <groupId>org.apache.helix</groupId>
+ <artifactId>helix</artifactId>
+ <version>0.9.2-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>metrics-common</artifactId>
+ <packaging>bundle</packaging>
+ <name>Apache Helix :: Metrics Common</name>
+
+ <properties>
+ <osgi.import>
+ org.slf4j*;version="[1.6,2)",
+ *
+ </osgi.import>
+ <osgi.export>org.apache.helix*;version="${project.version};-noimport:=true</osgi.export>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>io.dropwizard.metrics</groupId>
+ <artifactId>metrics-core</artifactId>
+ <version>3.2.3</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>1.7.25</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>1.7.14</version>
+ </dependency>
+ <dependency>
+ <groupId>org.testng</groupId>
+ <artifactId>testng</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <resources>
+ <resource>
+ <directory>${basedir}</directory>
+ <includes>
+ <include>DISCLAIMER</include>
+ </includes>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <configuration>
+ <descriptors>
+ <descriptor>src/assemble/assembly.xml</descriptor>
+ </descriptors>
+ </configuration>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/metrics-common/src/assemble/assembly.xml b/metrics-common/src/assemble/assembly.xml
new file mode 100644
index 0000000..3c9eb4b
--- /dev/null
+++ b/metrics-common/src/assemble/assembly.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<assembly>
+ <id>pkg</id>
+ <formats>
+ <format>tar</format>
+ </formats>
+ <fileSets>
+ <fileSet>
+ <directory>target/metrics-common-pkg/bin</directory>
+ <outputDirectory>bin</outputDirectory>
+ <lineEnding>unix</lineEnding>
+ <fileMode>0755</fileMode>
+ <directoryMode>0755</directoryMode>
+ </fileSet>
+ <fileSet>
+ <directory>target/metrics-common-pkg/repo/</directory>
+ <outputDirectory>repo</outputDirectory>
+ <fileMode>0755</fileMode>
+ <directoryMode>0755</directoryMode>
+ <excludes>
+ <exclude>**/*.xml</exclude>
+ </excludes>
+ </fileSet>
+ <fileSet>
+ <directory>target/metrics-common-pkg/conf</directory>
+ <outputDirectory>conf</outputDirectory>
+ <lineEnding>unix</lineEnding>
+ <fileMode>0755</fileMode>
+ <directoryMode>0755</directoryMode>
+ </fileSet>
+ <fileSet>
+ <directory>${project.basedir}</directory>
+ <outputDirectory>/</outputDirectory>
+ <includes>
+ <include>LICENSE</include>
+ <include>NOTICE</include>
+ <include>DISCLAIMER</include>
+ </includes>
+ <fileMode>0755</fileMode>
+ </fileSet>
+ </fileSets>
+</assembly>
diff --git a/helix-core/src/main/java/org/apache/helix/monitoring/SensorNameProvider.java b/metrics-common/src/main/java/org/apache/helix/monitoring/SensorNameProvider.java
similarity index 100%
rename from helix-core/src/main/java/org/apache/helix/monitoring/SensorNameProvider.java
rename to metrics-common/src/main/java/org/apache/helix/monitoring/SensorNameProvider.java
diff --git a/helix-core/src/main/java/org/apache/helix/monitoring/mbeans/MBeanRegistrar.java b/metrics-common/src/main/java/org/apache/helix/monitoring/mbeans/MBeanRegistrar.java
similarity index 99%
rename from helix-core/src/main/java/org/apache/helix/monitoring/mbeans/MBeanRegistrar.java
rename to metrics-common/src/main/java/org/apache/helix/monitoring/mbeans/MBeanRegistrar.java
index 9cff11b..04ff496 100644
--- a/helix-core/src/main/java/org/apache/helix/monitoring/mbeans/MBeanRegistrar.java
+++ b/metrics-common/src/main/java/org/apache/helix/monitoring/mbeans/MBeanRegistrar.java
@@ -29,6 +29,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
public class MBeanRegistrar {
private static Logger LOG = LoggerFactory.getLogger(MBeanRegistrar.class);
diff --git a/metrics-common/src/main/java/org/apache/helix/monitoring/mbeans/MonitorDomainNames.java b/metrics-common/src/main/java/org/apache/helix/monitoring/mbeans/MonitorDomainNames.java
new file mode 100644
index 0000000..73bf057
--- /dev/null
+++ b/metrics-common/src/main/java/org/apache/helix/monitoring/mbeans/MonitorDomainNames.java
@@ -0,0 +1,32 @@
+package org.apache.helix.monitoring.mbeans;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * This enum defines all of domain names used with various Helix monitor mbeans.
+ */
+public enum MonitorDomainNames {
+ ClusterStatus,
+ HelixZkClient,
+ HelixThreadPoolExecutor,
+ HelixCallback,
+ RoutingTableProvider,
+ CLMParticipantReport
+}
diff --git a/metrics-common/src/main/java/org/apache/helix/monitoring/mbeans/dynamicMBeans/DynamicMBeanProvider.java b/metrics-common/src/main/java/org/apache/helix/monitoring/mbeans/dynamicMBeans/DynamicMBeanProvider.java
new file mode 100644
index 0000000..8174326
--- /dev/null
+++ b/metrics-common/src/main/java/org/apache/helix/monitoring/mbeans/dynamicMBeans/DynamicMBeanProvider.java
@@ -0,0 +1,260 @@
+package org.apache.helix.monitoring.mbeans.dynamicMBeans;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import javax.management.Attribute;
+import javax.management.AttributeList;
+import javax.management.AttributeNotFoundException;
+import javax.management.DynamicMBean;
+import javax.management.InvalidAttributeValueException;
+import javax.management.JMException;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanConstructorInfo;
+import javax.management.MBeanException;
+import javax.management.MBeanInfo;
+import javax.management.MBeanNotificationInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+
+import org.apache.helix.monitoring.SensorNameProvider;
+import org.apache.helix.monitoring.mbeans.MBeanRegistrar;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Dynamic MBean provider that reporting DynamicMetric attributes
+ */
+public abstract class DynamicMBeanProvider implements DynamicMBean, SensorNameProvider {
+ protected final Logger _logger = LoggerFactory.getLogger(getClass());
+ protected static final long DEFAULT_RESET_INTERVAL_MS = 60 * 60 * 1000; // Reset time every hour
+ private static final String HELIX_MONITOR_TIME_WINDOW_LENGTH_MS =
+ "helix.monitor.slidingTimeWindow.ms";
+
+ private static String SENSOR_NAME_TAG = "SensorName";
+ private static String DEFAULT_DESCRIPTION =
+ "Information on the management interface of the MBean";
+
+ // Attribute name to the DynamicMetric object mapping
+ private final Map<String, DynamicMetric> _attributeMap = new HashMap<>();
+ private ObjectName _objectName = null;
+ private MBeanInfo _mBeanInfo;
+
+ /**
+ * Instantiates a new Dynamic MBean provider.
+ * @param dynamicMetrics Dynamic Metrics that are exposed by this provider
+ * @param description the MBean description
+ * @param domain the MBean domain name
+ * @param keyValuePairs the MBean object name components
+ */
+ protected synchronized boolean doRegister(Collection<DynamicMetric<?, ?>> dynamicMetrics,
+ String description, String domain, String... keyValuePairs) throws JMException {
+ return doRegister(dynamicMetrics, description,
+ MBeanRegistrar.buildObjectName(domain, keyValuePairs));
+ }
+
+ /**
+ * Instantiates a new Dynamic MBean provider.
+ * @param dynamicMetrics Dynamic Metrics that are exposed by this provider
+ * @param description the MBean description
+ * @param objectName the proposed MBean ObjectName
+ */
+ protected synchronized boolean doRegister(Collection<DynamicMetric<?, ?>> dynamicMetrics,
+ String description, ObjectName objectName) throws JMException {
+ if (_objectName != null) {
+ _logger.debug("Mbean {} has already been registered. Ignore register request.",
+ objectName.getCanonicalName());
+ return false;
+ }
+ updateAttributtInfos(dynamicMetrics, description);
+ _objectName = MBeanRegistrar.register(this, objectName);
+ return true;
+ }
+
+ protected synchronized boolean doRegister(Collection<DynamicMetric<?, ?>> dynamicMetrics,
+ ObjectName objectName) throws JMException {
+ return doRegister(dynamicMetrics, null, objectName);
+ }
+
+ /**
+ * Update the Dynamic MBean provider with new metric list.
+ * @param description description of the MBean
+ * @param dynamicMetrics the DynamicMetrics
+ */
+ private void updateAttributtInfos(Collection<DynamicMetric<?, ?>> dynamicMetrics,
+ String description) {
+ _attributeMap.clear();
+
+ // get all attributes that can be emit by the dynamicMetrics.
+ List<MBeanAttributeInfo> attributeInfoList = new ArrayList<>();
+ if (dynamicMetrics != null) {
+ for (DynamicMetric dynamicMetric : dynamicMetrics) {
+ Iterator<MBeanAttributeInfo> iter = dynamicMetric.getAttributeInfos().iterator();
+ while (iter.hasNext()) {
+ MBeanAttributeInfo attributeInfo = iter.next();
+ // Info list to create MBean info
+ attributeInfoList.add(attributeInfo);
+ // Attribute mapping for getting attribute value when getAttribute() is called
+ _attributeMap.put(attributeInfo.getName(), dynamicMetric);
+ }
+ }
+ }
+
+ // SensorName
+ attributeInfoList.add(new MBeanAttributeInfo(SENSOR_NAME_TAG, String.class.getName(),
+ "The name of the metric sensor", true, false, false));
+
+ MBeanConstructorInfo constructorInfo = new MBeanConstructorInfo(
+ String.format("Default %s Constructor", getClass().getSimpleName()),
+ getClass().getConstructors()[0]);
+
+ MBeanAttributeInfo[] attributeInfos = new MBeanAttributeInfo[attributeInfoList.size()];
+ attributeInfos = attributeInfoList.toArray(attributeInfos);
+
+ if (description == null) {
+ description = DEFAULT_DESCRIPTION;
+ }
+
+ _mBeanInfo = new MBeanInfo(getClass().getName(), description, attributeInfos,
+ new MBeanConstructorInfo[]{constructorInfo}, new MBeanOperationInfo[0],
+ new MBeanNotificationInfo[0]);
+ }
+
+ /**
+ * Call doRegister() to finish registration MBean and the attributes.
+ */
+ public abstract DynamicMBeanProvider register() throws JMException;
+
+ /**
+ * Unregister the MBean and clean up object name record.
+ * Note that all the metric data is kept even after unregister.
+ */
+ public synchronized void unregister() {
+ MBeanRegistrar.unregister(_objectName);
+ _objectName = null;
+ }
+
+ @Override
+ public Object getAttribute(String attribute)
+ throws AttributeNotFoundException, MBeanException, ReflectionException {
+ if (SENSOR_NAME_TAG.equals(attribute)) {
+ return getSensorName();
+ }
+
+ if (!_attributeMap.containsKey(attribute)) {
+ return null;
+ }
+
+ return _attributeMap.get(attribute).getAttributeValue(attribute);
+ }
+
+ @Override
+ public AttributeList getAttributes(String[] attributes) {
+ AttributeList attributeList = new AttributeList();
+ for (String attributeName : attributes) {
+ try {
+ Object value = getAttribute(attributeName);
+ attributeList.add(new Attribute(attributeName, value));
+ } catch (AttributeNotFoundException | MBeanException | ReflectionException ex) {
+ _logger.error("Failed to get attribute: " + attributeName, ex);
+ }
+ }
+ return attributeList;
+ }
+
+ @Override
+ public MBeanInfo getMBeanInfo() {
+ return _mBeanInfo;
+ }
+
+ @Override
+ public void setAttribute(Attribute attribute)
+ throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException,
+ ReflectionException {
+ // All MBeans are readonly
+ return;
+ }
+
+ @Override
+ public AttributeList setAttributes(AttributeList attributes) {
+ // All MBeans are readonly
+ return null;
+ }
+
+ @Override
+ public Object invoke(String actionName, Object[] params, String[] signature)
+ throws MBeanException, ReflectionException {
+ // No operation supported
+ return null;
+ }
+
+ /**
+ * NOTE: This method is not thread-safe nor atomic.
+ * Increment the value of a given SimpleDynamicMetric by 1.
+ */
+ protected void incrementSimpleDynamicMetric(SimpleDynamicMetric<Long> metric) {
+ incrementSimpleDynamicMetric(metric, 1);
+ }
+
+ /**
+ * NOTE: This method is not thread-safe nor atomic.
+ * Increment the value of a given SimpleDynamicMetric with input value.
+ */
+ protected void incrementSimpleDynamicMetric(SimpleDynamicMetric<Long> metric, long value) {
+ metric.updateValue(metric.getValue() + value);
+ }
+
+ /**
+ * Return the interval length for the underlying reservoir used by the MBean metric configured
+ * in the system env variables. If not found, use default value.
+ */
+ protected Long getResetIntervalInMs() {
+ return getSystemPropertyAsLong(HELIX_MONITOR_TIME_WINDOW_LENGTH_MS, DEFAULT_RESET_INTERVAL_MS);
+ }
+
+ /**
+ * Get the value of system property
+ * @param propertyKey
+ * @param propertyDefaultValue
+ * @return
+ */
+ private long getSystemPropertyAsLong(String propertyKey, long propertyDefaultValue) {
+ String valueString = System.getProperty(propertyKey, "" + propertyDefaultValue);
+
+ try {
+ long value = Long.parseLong(valueString);
+ if (value > 0) {
+ return value;
+ }
+ } catch (NumberFormatException e) {
+ _logger.warn("Exception while parsing property: " + propertyKey + ", string: " + valueString
+ + ", using default value: " + propertyDefaultValue);
+ }
+
+ return propertyDefaultValue;
+ }
+}
diff --git a/helix-core/src/main/java/org/apache/helix/monitoring/mbeans/dynamicMBeans/DynamicMetric.java b/metrics-common/src/main/java/org/apache/helix/monitoring/mbeans/dynamicMBeans/DynamicMetric.java
similarity index 95%
rename from helix-core/src/main/java/org/apache/helix/monitoring/mbeans/dynamicMBeans/DynamicMetric.java
rename to metrics-common/src/main/java/org/apache/helix/monitoring/mbeans/dynamicMBeans/DynamicMetric.java
index 5ac4cbd..b1736c4 100644
--- a/helix-core/src/main/java/org/apache/helix/monitoring/mbeans/dynamicMBeans/DynamicMetric.java
+++ b/metrics-common/src/main/java/org/apache/helix/monitoring/mbeans/dynamicMBeans/DynamicMetric.java
@@ -25,7 +25,8 @@
import java.util.Set;
import javax.management.MBeanAttributeInfo;
-import org.apache.helix.HelixException;
+import org.apache.helix.monitoring.mbeans.exception.MetricException;
+
/**
* The abstract class for dynamic metrics that is used to emitting monitor data to DynamicMBean.
@@ -48,7 +49,7 @@
*/
public DynamicMetric(String metricName, O metricObject) {
if (metricName == null || metricObject == null) {
- throw new HelixException("Failed to construct metric due to missing argument.");
+ throw new MetricException("Failed to construct metric due to missing argument.");
}
_metricObject = metricObject;
_attributeInfoSet =
diff --git a/helix-core/src/main/java/org/apache/helix/monitoring/mbeans/dynamicMBeans/HistogramDynamicMetric.java b/metrics-common/src/main/java/org/apache/helix/monitoring/mbeans/dynamicMBeans/HistogramDynamicMetric.java
similarity index 99%
rename from helix-core/src/main/java/org/apache/helix/monitoring/mbeans/dynamicMBeans/HistogramDynamicMetric.java
rename to metrics-common/src/main/java/org/apache/helix/monitoring/mbeans/dynamicMBeans/HistogramDynamicMetric.java
index b683043..64f4c0b 100644
--- a/helix-core/src/main/java/org/apache/helix/monitoring/mbeans/dynamicMBeans/HistogramDynamicMetric.java
+++ b/metrics-common/src/main/java/org/apache/helix/monitoring/mbeans/dynamicMBeans/HistogramDynamicMetric.java
@@ -30,6 +30,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
/**
* The dynamic metric that accept Long monitor data and emits histogram information based on the input
*/
diff --git a/metrics-common/src/main/java/org/apache/helix/monitoring/mbeans/dynamicMBeans/SimpleDynamicMetric.java b/metrics-common/src/main/java/org/apache/helix/monitoring/mbeans/dynamicMBeans/SimpleDynamicMetric.java
new file mode 100644
index 0000000..1be6a21
--- /dev/null
+++ b/metrics-common/src/main/java/org/apache/helix/monitoring/mbeans/dynamicMBeans/SimpleDynamicMetric.java
@@ -0,0 +1,60 @@
+package org.apache.helix.monitoring.mbeans.dynamicMBeans;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * The dynamic metric that accept and emits same type of monitor data
+ *
+ * @param <T> the type of the metric value
+ */
+public class SimpleDynamicMetric<T> extends DynamicMetric<T, T> {
+ private final String _metricName;
+
+ /**
+ * Instantiates a new Simple dynamic metric.
+ *
+ * @param metricName the metric name
+ * @param metricObject the metric object
+ */
+ public SimpleDynamicMetric(String metricName, T metricObject) {
+ super(metricName, metricObject);
+ _metricName = metricName;
+ }
+
+ @Override
+ public T getAttributeValue(String attributeName) {
+ if (!attributeName.equals(_metricName)) {
+ return null;
+ }
+ return getMetricObject();
+ }
+
+ /**
+ * @return current metric value
+ */
+ public T getValue() {
+ return getMetricObject();
+ }
+
+ @Override
+ public void updateValue(T metricObject) {
+ setMetricObject(metricObject);
+ }
+}
diff --git a/metrics-common/src/main/java/org/apache/helix/monitoring/mbeans/exception/MetricException.java b/metrics-common/src/main/java/org/apache/helix/monitoring/mbeans/exception/MetricException.java
new file mode 100644
index 0000000..569893c
--- /dev/null
+++ b/metrics-common/src/main/java/org/apache/helix/monitoring/mbeans/exception/MetricException.java
@@ -0,0 +1,35 @@
+package org.apache.helix.monitoring.mbeans.exception;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+public class MetricException extends RuntimeException {
+
+ public MetricException(String message) {
+ super(message);
+ }
+
+ public MetricException(Throwable cause) {
+ super(cause);
+ }
+
+ public MetricException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/metrics-common/src/test/conf/testng.xml b/metrics-common/src/test/conf/testng.xml
new file mode 100644
index 0000000..125e51c
--- /dev/null
+++ b/metrics-common/src/test/conf/testng.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
+<suite name="Suite" parallel="false">
+ <test name="Test" preserve-order="true">
+ <packages>
+ <package name="org.apache.helix.metrics.common.*"/>
+ </packages>
+ </test>
+</suite>
diff --git a/metrics-common/src/test/resources/log4j.properties b/metrics-common/src/test/resources/log4j.properties
new file mode 100644
index 0000000..24b6d10
--- /dev/null
+++ b/metrics-common/src/test/resources/log4j.properties
@@ -0,0 +1,41 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# Set root logger level to DEBUG and its only appender to R.
+log4j.rootLogger=ERROR, C
+
+# A1 is set to be a ConsoleAppender.
+log4j.appender.C=org.apache.log4j.ConsoleAppender
+log4j.appender.C.layout=org.apache.log4j.PatternLayout
+log4j.appender.C.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
+
+log4j.appender.R=org.apache.log4j.RollingFileAppender
+log4j.appender.R.layout=org.apache.log4j.PatternLayout
+log4j.appender.R.layout.ConversionPattern=%5p [%C:%M] (%F:%L) - %m%n
+log4j.appender.R.File=target/ClusterManagerLogs/log.txt
+
+log4j.appender.STATUSDUMP=org.apache.log4j.RollingFileAppender
+log4j.appender.STATUSDUMP.layout=org.apache.log4j.SimpleLayout
+log4j.appender.STATUSDUMP.File=target/ClusterManagerLogs/statusUpdates.log
+
+log4j.logger.org.I0Itec=ERROR
+log4j.logger.org.apache=ERROR
+log4j.logger.com.noelios=ERROR
+log4j.logger.org.restlet=ERROR
+
+log4j.logger.org.apache.helix.monitoring.ZKPathDataDumpTask=ERROR,STATUSDUMP
diff --git a/pom.xml b/pom.xml
index 29308c1..c131ce8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -20,6 +20,12 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
+ <dependencies>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ </dependencies>
<parent>
<groupId>org.apache</groupId>
@@ -240,6 +246,9 @@
</developer>
</developers>
<modules>
+ <module>metrics-common</module>
+ <module>zookeeper-api</module>
+ <module>helix-common</module>
<module>helix-core</module>
<module>helix-admin-webapp</module>
<module>helix-rest</module>
@@ -619,7 +628,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
- <version>3.0.0-M3</version>
+ <version>2.18.1</version>
</plugin>
<plugin>
<groupId>org.apache.rat</groupId>
diff --git a/recipes/distributed-lock-manager/src/main/java/org/apache/helix/lockmanager/LockManagerDemo.java b/recipes/distributed-lock-manager/src/main/java/org/apache/helix/lockmanager/LockManagerDemo.java
index b6c54db..cc4c3d3 100644
--- a/recipes/distributed-lock-manager/src/main/java/org/apache/helix/lockmanager/LockManagerDemo.java
+++ b/recipes/distributed-lock-manager/src/main/java/org/apache/helix/lockmanager/LockManagerDemo.java
@@ -23,9 +23,6 @@
import java.util.Map;
import java.util.TreeSet;
-import org.I0Itec.zkclient.IDefaultNameSpace;
-import org.I0Itec.zkclient.ZkClient;
-import org.I0Itec.zkclient.ZkServer;
import org.apache.commons.io.FileUtils;
import org.apache.helix.HelixAdmin;
import org.apache.helix.HelixManager;
@@ -35,6 +32,10 @@
import org.apache.helix.model.IdealState.RebalanceMode;
import org.apache.helix.model.StateModelDefinition;
import org.apache.helix.tools.StateModelConfigGenerator;
+import org.apache.helix.zookeeper.zkclient.IDefaultNameSpace;
+import org.apache.helix.zookeeper.zkclient.ZkClient;
+import org.apache.helix.zookeeper.zkclient.ZkServer;
+
public class LockManagerDemo {
/**
diff --git a/recipes/rabbitmq-consumer-group/src/main/java/org/apache/helix/recipes/rabbitmq/Consumer.java b/recipes/rabbitmq-consumer-group/src/main/java/org/apache/helix/recipes/rabbitmq/Consumer.java
index 25b6027..508faca 100644
--- a/recipes/rabbitmq-consumer-group/src/main/java/org/apache/helix/recipes/rabbitmq/Consumer.java
+++ b/recipes/rabbitmq-consumer-group/src/main/java/org/apache/helix/recipes/rabbitmq/Consumer.java
@@ -26,7 +26,7 @@
import org.apache.helix.InstanceType;
import org.apache.helix.manager.zk.ZKHelixAdmin;
import org.apache.helix.manager.zk.ZNRecordSerializer;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.model.InstanceConfig;
import org.apache.helix.participant.StateMachineEngine;
diff --git a/recipes/rabbitmq-consumer-group/src/main/java/org/apache/helix/recipes/rabbitmq/SetupConsumerCluster.java b/recipes/rabbitmq-consumer-group/src/main/java/org/apache/helix/recipes/rabbitmq/SetupConsumerCluster.java
index b73aaa9..3d81929 100644
--- a/recipes/rabbitmq-consumer-group/src/main/java/org/apache/helix/recipes/rabbitmq/SetupConsumerCluster.java
+++ b/recipes/rabbitmq-consumer-group/src/main/java/org/apache/helix/recipes/rabbitmq/SetupConsumerCluster.java
@@ -21,7 +21,7 @@
import org.apache.helix.manager.zk.ZKHelixAdmin;
import org.apache.helix.manager.zk.ZNRecordSerializer;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.model.IdealState.RebalanceMode;
import org.apache.helix.model.StateModelDefinition;
import org.apache.helix.tools.StateModelConfigGenerator;
diff --git a/recipes/rsync-replicated-file-system/pom.xml b/recipes/rsync-replicated-file-system/pom.xml
index eb85b64..b98f9ed 100644
--- a/recipes/rsync-replicated-file-system/pom.xml
+++ b/recipes/rsync-replicated-file-system/pom.xml
@@ -88,11 +88,6 @@
<artifactId>commons-jci-fam</artifactId>
<version>1.0</version>
</dependency>
- <dependency>
- <groupId>com.101tec</groupId>
- <artifactId>zkclient</artifactId>
- <version>0.5</version>
- </dependency>
</dependencies>
<build>
<pluginManagement>
diff --git a/recipes/rsync-replicated-file-system/src/main/java/org/apache/helix/filestore/FileStore.java b/recipes/rsync-replicated-file-system/src/main/java/org/apache/helix/filestore/FileStore.java
index 6448411..8ec1a15 100644
--- a/recipes/rsync-replicated-file-system/src/main/java/org/apache/helix/filestore/FileStore.java
+++ b/recipes/rsync-replicated-file-system/src/main/java/org/apache/helix/filestore/FileStore.java
@@ -22,7 +22,7 @@
import org.apache.helix.HelixManager;
import org.apache.helix.HelixManagerFactory;
import org.apache.helix.InstanceType;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.participant.StateMachineEngine;
public class FileStore {
diff --git a/recipes/rsync-replicated-file-system/src/main/java/org/apache/helix/filestore/FileStoreStateModel.java b/recipes/rsync-replicated-file-system/src/main/java/org/apache/helix/filestore/FileStoreStateModel.java
index 49799db..bac9c25 100644
--- a/recipes/rsync-replicated-file-system/src/main/java/org/apache/helix/filestore/FileStoreStateModel.java
+++ b/recipes/rsync-replicated-file-system/src/main/java/org/apache/helix/filestore/FileStoreStateModel.java
@@ -19,17 +19,17 @@
* under the License.
*/
-import org.I0Itec.zkclient.DataUpdater;
import org.apache.helix.AccessOption;
import org.apache.helix.HelixManager;
import org.apache.helix.NotificationContext;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.model.InstanceConfig;
import org.apache.helix.model.Message;
import org.apache.helix.participant.statemachine.StateModel;
import org.apache.helix.participant.statemachine.StateModelInfo;
import org.apache.helix.participant.statemachine.Transition;
import org.apache.helix.store.zk.ZkHelixPropertyStore;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/recipes/rsync-replicated-file-system/src/main/java/org/apache/helix/filestore/IntegrationTest.java b/recipes/rsync-replicated-file-system/src/main/java/org/apache/helix/filestore/IntegrationTest.java
index 845afb8..bafa163 100644
--- a/recipes/rsync-replicated-file-system/src/main/java/org/apache/helix/filestore/IntegrationTest.java
+++ b/recipes/rsync-replicated-file-system/src/main/java/org/apache/helix/filestore/IntegrationTest.java
@@ -25,9 +25,6 @@
import java.util.HashMap;
import java.util.Map;
-import org.I0Itec.zkclient.IDefaultNameSpace;
-import org.I0Itec.zkclient.ZkClient;
-import org.I0Itec.zkclient.ZkServer;
import org.apache.commons.io.FileUtils;
import org.apache.helix.HelixDataAccessor;
import org.apache.helix.HelixManager;
@@ -37,12 +34,15 @@
import org.apache.helix.model.HelixConfigScope.ConfigScopeProperty;
import org.apache.helix.model.builder.HelixConfigScopeBuilder;
import org.apache.helix.tools.ClusterSetup;
+import org.apache.helix.zookeeper.zkclient.IDefaultNameSpace;
+import org.apache.helix.zookeeper.zkclient.ZkClient;
+import org.apache.helix.zookeeper.zkclient.ZkServer;
+
public class IntegrationTest {
public static void main(String[] args) throws InterruptedException {
ZkServer server = null;
- ;
try {
String baseDir = "/tmp/IntegrationTest/";
diff --git a/recipes/rsync-replicated-file-system/src/main/java/org/apache/helix/filestore/Replicator.java b/recipes/rsync-replicated-file-system/src/main/java/org/apache/helix/filestore/Replicator.java
index b4bf5af..0da5a65 100644
--- a/recipes/rsync-replicated-file-system/src/main/java/org/apache/helix/filestore/Replicator.java
+++ b/recipes/rsync-replicated-file-system/src/main/java/org/apache/helix/filestore/Replicator.java
@@ -23,7 +23,7 @@
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.helix.NotificationContext;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.model.ExternalView;
import org.apache.helix.model.InstanceConfig;
import org.apache.helix.spectator.RoutingTableProvider;
diff --git a/recipes/rsync-replicated-file-system/src/main/java/org/apache/helix/filestore/SetupCluster.java b/recipes/rsync-replicated-file-system/src/main/java/org/apache/helix/filestore/SetupCluster.java
index 5c756ce..42a6cf7 100644
--- a/recipes/rsync-replicated-file-system/src/main/java/org/apache/helix/filestore/SetupCluster.java
+++ b/recipes/rsync-replicated-file-system/src/main/java/org/apache/helix/filestore/SetupCluster.java
@@ -21,7 +21,7 @@
import org.apache.helix.manager.zk.ZKHelixAdmin;
import org.apache.helix.manager.zk.ZNRecordSerializer;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.model.IdealState.RebalanceMode;
import org.apache.helix.model.InstanceConfig;
import org.apache.helix.model.StateModelDefinition;
diff --git a/recipes/service-discovery/src/main/java/org/apache/helix/servicediscovery/ServiceDiscovery.java b/recipes/service-discovery/src/main/java/org/apache/helix/servicediscovery/ServiceDiscovery.java
index 670e563..c2e3a32 100644
--- a/recipes/service-discovery/src/main/java/org/apache/helix/servicediscovery/ServiceDiscovery.java
+++ b/recipes/service-discovery/src/main/java/org/apache/helix/servicediscovery/ServiceDiscovery.java
@@ -36,7 +36,7 @@
import org.apache.helix.NotificationContext;
import org.apache.helix.PropertyKey;
import org.apache.helix.PropertyKey.Builder;
-import org.apache.helix.ZNRecord;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
import org.apache.helix.manager.zk.ZKHelixManager;
import org.apache.helix.model.HelixConfigScope;
import org.apache.helix.model.HelixConfigScope.ConfigScopeProperty;
diff --git a/recipes/task-execution/src/main/java/org/apache/helix/taskexecution/TaskCluster.java b/recipes/task-execution/src/main/java/org/apache/helix/taskexecution/TaskCluster.java
index 064fc1a..55b7bf1 100644
--- a/recipes/task-execution/src/main/java/org/apache/helix/taskexecution/TaskCluster.java
+++ b/recipes/task-execution/src/main/java/org/apache/helix/taskexecution/TaskCluster.java
@@ -22,7 +22,7 @@
import org.apache.helix.ConfigAccessor;
import org.apache.helix.manager.zk.ZKHelixAdmin;
import org.apache.helix.manager.zk.ZNRecordSerializer;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.model.HelixConfigScope;
import org.apache.helix.model.HelixConfigScope.ConfigScopeProperty;
import org.apache.helix.model.IdealState.RebalanceMode;
diff --git a/recipes/task-execution/src/main/java/org/apache/helix/taskexecution/TaskExecutionDemo.java b/recipes/task-execution/src/main/java/org/apache/helix/taskexecution/TaskExecutionDemo.java
index 01716d7..04c5b70 100644
--- a/recipes/task-execution/src/main/java/org/apache/helix/taskexecution/TaskExecutionDemo.java
+++ b/recipes/task-execution/src/main/java/org/apache/helix/taskexecution/TaskExecutionDemo.java
@@ -24,13 +24,14 @@
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
-import org.I0Itec.zkclient.IDefaultNameSpace;
-import org.I0Itec.zkclient.ZkClient;
-import org.I0Itec.zkclient.ZkServer;
import org.apache.commons.io.FileUtils;
import org.apache.helix.HelixManager;
import org.apache.helix.controller.HelixControllerMain;
import org.apache.helix.taskexecution.Dag.Node;
+import org.apache.helix.zookeeper.zkclient.IDefaultNameSpace;
+import org.apache.helix.zookeeper.zkclient.ZkClient;
+import org.apache.helix.zookeeper.zkclient.ZkServer;
+
/**
* Demo for execution of task Dag using primitives provided by Helix. This demo sets up a Dag of
diff --git a/recipes/task-execution/src/main/java/org/apache/helix/taskexecution/Worker.java b/recipes/task-execution/src/main/java/org/apache/helix/taskexecution/Worker.java
index 4d54b23..dd9ebee 100644
--- a/recipes/task-execution/src/main/java/org/apache/helix/taskexecution/Worker.java
+++ b/recipes/task-execution/src/main/java/org/apache/helix/taskexecution/Worker.java
@@ -26,7 +26,7 @@
import org.apache.helix.InstanceType;
import org.apache.helix.manager.zk.ZKHelixAdmin;
import org.apache.helix.manager.zk.ZNRecordSerializer;
-import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
import org.apache.helix.model.InstanceConfig;
import org.apache.helix.participant.StateMachineEngine;
diff --git a/zookeeper-api/LICENSE b/zookeeper-api/LICENSE
new file mode 100644
index 0000000..d78ae52
--- /dev/null
+++ b/zookeeper-api/LICENSE
@@ -0,0 +1,270 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+
+For xstream:
+
+Copyright (c) 2003-2006, Joe Walnes
+Copyright (c) 2006-2009, 2011 XStream Committers
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this list of
+conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice, this list of
+conditions and the following disclaimer in the documentation and/or other materials provided
+with the distribution.
+
+3. Neither the name of XStream nor the names of its contributors may be used to endorse
+or promote products derived from this software without specific prior written
+permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
+for jline:
+
+Copyright (c) 2002-2006, Marc Prud'hommeaux <mwp1@cornell.edu>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or
+without modification, are permitted provided that the following
+conditions are met:
+
+Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with
+the distribution.
+
+Neither the name of JLine nor the names of its contributors
+may be used to endorse or promote products derived from this
+software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/zookeeper-api/NOTICE b/zookeeper-api/NOTICE
new file mode 100644
index 0000000..ff5a745
--- /dev/null
+++ b/zookeeper-api/NOTICE
@@ -0,0 +1,37 @@
+Apache Helix
+Copyright 2014 The Apache Software Foundation
+
+
+I. Included Software
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+Licensed under the Apache License 2.0.
+
+This product includes software developed at
+Codehaus (http://www.codehaus.org/).
+Licensed under the BSD License.
+
+This product includes software developed at
+jline (http://jline.sourceforge.net/).
+Licensed under the BSD License.
+
+This product includes software developed at
+restlet (http://www.restlet.org/about/legal).
+Licensed under the Apache License 2.0.
+
+This product includes software developed at
+Google (http://www.google.com/).
+Licensed under the Apache License 2.0.
+
+This product includes software developed at
+snakeyaml (http://www.snakeyaml.org/).
+Licensed under the Apache License 2.0.
+
+This product includes software developed at
+zkclient (https://github.com/sgroschupf/zkclient).
+Licensed under the Apache License 2.0.
+
+II. License Summary
+- Apache License 2.0
+- BSD License
\ No newline at end of file
diff --git a/zookeeper-api/pom.xml b/zookeeper-api/pom.xml
new file mode 100644
index 0000000..5ec1e56
--- /dev/null
+++ b/zookeeper-api/pom.xml
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <groupId>org.apache.helix</groupId>
+ <artifactId>helix</artifactId>
+ <version>0.9.2-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>zookeeper-api</artifactId>
+ <packaging>bundle</packaging>
+ <name>Apache Helix :: ZooKeeper API</name>
+
+ <properties>
+ <osgi.import>
+ org.slf4j*;version="[1.6,2)",
+ *
+ </osgi.import>
+ <osgi.export>org.apache.helix.zookeeper*;version="${project.version};-noimport:=true</osgi.export>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.helix</groupId>
+ <artifactId>metrics-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.zookeeper</groupId>
+ <artifactId>zookeeper</artifactId>
+ <version>3.4.13</version>
+ <exclusions>
+ <exclusion>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.jackson</groupId>
+ <artifactId>jackson-mapper-asl</artifactId>
+ <version>1.9.13</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ <version>1.14</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>1.7.25</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>1.7.14</version>
+ </dependency>
+ <dependency>
+ <groupId>org.testng</groupId>
+ <artifactId>testng</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <resources>
+ <resource>
+ <directory>${basedir}</directory>
+ <includes>
+ <include>DISCLAIMER</include>
+ </includes>
+ </resource>
+ </resources>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <configuration>
+ <descriptors>
+ <descriptor>src/assemble/assembly.xml</descriptor>
+ </descriptors>
+ </configuration>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/zookeeper-api/src/assemble/assembly.xml b/zookeeper-api/src/assemble/assembly.xml
new file mode 100644
index 0000000..61e06f5
--- /dev/null
+++ b/zookeeper-api/src/assemble/assembly.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<assembly>
+ <id>pkg</id>
+ <formats>
+ <format>tar</format>
+ </formats>
+ <fileSets>
+ <fileSet>
+ <directory>target/zookeeper-api-pkg/bin</directory>
+ <outputDirectory>bin</outputDirectory>
+ <lineEnding>unix</lineEnding>
+ <fileMode>0755</fileMode>
+ <directoryMode>0755</directoryMode>
+ </fileSet>
+ <fileSet>
+ <directory>target/zookeeper-api-pkg/repo/</directory>
+ <outputDirectory>repo</outputDirectory>
+ <fileMode>0755</fileMode>
+ <directoryMode>0755</directoryMode>
+ <excludes>
+ <exclude>**/*.xml</exclude>
+ </excludes>
+ </fileSet>
+ <fileSet>
+ <directory>target/zookeeper-api-pkg/conf</directory>
+ <outputDirectory>conf</outputDirectory>
+ <lineEnding>unix</lineEnding>
+ <fileMode>0755</fileMode>
+ <directoryMode>0755</directoryMode>
+ </fileSet>
+ <fileSet>
+ <directory>${project.basedir}</directory>
+ <outputDirectory>/</outputDirectory>
+ <includes>
+ <include>LICENSE</include>
+ <include>NOTICE</include>
+ <include>DISCLAIMER</include>
+ </includes>
+ <fileMode>0755</fileMode>
+ </fileSet>
+ </fileSets>
+</assembly>
diff --git a/zookeeper-api/src/main/config/log4j.properties b/zookeeper-api/src/main/config/log4j.properties
new file mode 100644
index 0000000..375c7ba
--- /dev/null
+++ b/zookeeper-api/src/main/config/log4j.properties
@@ -0,0 +1,32 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+# Set root logger level to DEBUG and its only appender to A1.
+log4j.rootLogger=WARN,A1
+
+# A1 is set to be a ConsoleAppender.
+log4j.appender.A1=org.apache.log4j.ConsoleAppender
+
+# A1 uses PatternLayout.
+log4j.appender.A1.layout=org.apache.log4j.PatternLayout
+log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
+
+log4j.logger.org.I0Itec=ERROR
+log4j.logger.org.apache.zookeeper=ERROR
+log4j.logger.org.apache.helix=INFO
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/api/client/HelixZkClient.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/api/client/HelixZkClient.java
new file mode 100644
index 0000000..bbb8a98
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/api/client/HelixZkClient.java
@@ -0,0 +1,26 @@
+package org.apache.helix.zookeeper.api.client;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * HelixZkClient interface that follows the supported API structure of RealmAwareZkClient.
+ */
+public interface HelixZkClient extends RealmAwareZkClient {
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/api/client/RealmAwareZkClient.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/api/client/RealmAwareZkClient.java
new file mode 100644
index 0000000..f2345f6
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/api/client/RealmAwareZkClient.java
@@ -0,0 +1,463 @@
+package org.apache.helix.zookeeper.api.client;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
+import org.apache.helix.zookeeper.zkclient.IZkChildListener;
+import org.apache.helix.zookeeper.zkclient.IZkDataListener;
+import org.apache.helix.zookeeper.zkclient.IZkStateListener;
+import org.apache.helix.zookeeper.zkclient.callback.ZkAsyncCallbacks;
+import org.apache.helix.zookeeper.zkclient.exception.ZkTimeoutException;
+import org.apache.helix.zookeeper.zkclient.serialize.BasicZkSerializer;
+import org.apache.helix.zookeeper.zkclient.serialize.PathBasedZkSerializer;
+import org.apache.helix.zookeeper.zkclient.serialize.SerializableSerializer;
+import org.apache.helix.zookeeper.zkclient.serialize.ZkSerializer;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.Op;
+import org.apache.zookeeper.OpResult;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.data.ACL;
+import org.apache.zookeeper.data.Stat;
+
+
+public interface RealmAwareZkClient {
+ int DEFAULT_OPERATION_TIMEOUT = Integer.MAX_VALUE;
+ int DEFAULT_CONNECTION_TIMEOUT = 60 * 1000;
+ int DEFAULT_SESSION_TIMEOUT = 30 * 1000;
+
+ // listener subscription
+ List<String> subscribeChildChanges(String path, IZkChildListener listener);
+
+ void unsubscribeChildChanges(String path, IZkChildListener listener);
+
+ void subscribeDataChanges(String path, IZkDataListener listener);
+
+ void unsubscribeDataChanges(String path, IZkDataListener listener);
+
+ /*
+ * This is for backwards compatibility.
+ *
+ * TODO: remove below default implementation when getting rid of I0Itec in the new zk client.
+ */
+ default void subscribeStateChanges(final IZkStateListener listener) {
+ subscribeStateChanges(new HelixZkClient.I0ItecIZkStateListenerHelixImpl(listener));
+ }
+
+ /*
+ * This is for backwards compatibility.
+ *
+ * TODO: remove below default implementation when getting rid of I0Itec in the new zk client.
+ */
+ default void unsubscribeStateChanges(IZkStateListener listener) {
+ unsubscribeStateChanges(new HelixZkClient.I0ItecIZkStateListenerHelixImpl(listener));
+ }
+
+ /**
+ * Subscribes state changes for a
+ * {@link org.apache.helix.zookeeper.zkclient.deprecated.IZkStateListener} listener.
+ * @deprecated
+ * This is deprecated. It is kept for backwards compatibility. Please use
+ * {@link #subscribeStateChanges(IZkStateListener)}.
+ * @param listener {@link org.apache.helix.zookeeper.zkclient.deprecated.IZkStateListener}
+ * listener
+ */
+ @Deprecated
+ void subscribeStateChanges(
+ final org.apache.helix.zookeeper.zkclient.deprecated.IZkStateListener listener);
+
+ /**
+ * Unsubscribes state changes for a
+ * {@link org.apache.helix.zookeeper.zkclient.deprecated.IZkStateListener} listener.
+ * @deprecated
+ * This is deprecated. It is kept for backwards compatibility. Please use
+ * {@link #unsubscribeStateChanges(IZkStateListener)}.
+ * @param listener {@link org.apache.helix.zookeeper.zkclient.deprecated.IZkStateListener}
+ * listener
+ */
+ @Deprecated
+ void unsubscribeStateChanges(
+ org.apache.helix.zookeeper.zkclient.deprecated.IZkStateListener listener);
+
+ void unsubscribeAll();
+
+ // data access
+ void createPersistent(String path);
+
+ void createPersistent(String path, boolean createParents);
+
+ void createPersistent(String path, boolean createParents, List<ACL> acl);
+
+ void createPersistent(String path, Object data);
+
+ void createPersistent(String path, Object data, List<ACL> acl);
+
+ String createPersistentSequential(String path, Object data);
+
+ String createPersistentSequential(String path, Object data, List<ACL> acl);
+
+ void createEphemeral(final String path);
+
+ void createEphemeral(final String path, final String sessionId);
+
+ void createEphemeral(final String path, final List<ACL> acl);
+
+ void createEphemeral(final String path, final List<ACL> acl, final String sessionId);
+
+ String create(final String path, Object data, final CreateMode mode);
+
+ String create(final String path, Object datat, final List<ACL> acl, final CreateMode mode);
+
+ void createEphemeral(final String path, final Object data);
+
+ void createEphemeral(final String path, final Object data, final String sessionId);
+
+ void createEphemeral(final String path, final Object data, final List<ACL> acl);
+
+ void createEphemeral(final String path, final Object data, final List<ACL> acl,
+ final String sessionId);
+
+ String createEphemeralSequential(final String path, final Object data);
+
+ String createEphemeralSequential(final String path, final Object data, final List<ACL> acl);
+
+ String createEphemeralSequential(final String path, final Object data, final String sessionId);
+
+ String createEphemeralSequential(final String path, final Object data, final List<ACL> acl,
+ final String sessionId);
+
+ List<String> getChildren(String path);
+
+ int countChildren(String path);
+
+ boolean exists(final String path);
+
+ Stat getStat(final String path);
+
+ boolean waitUntilExists(String path, TimeUnit timeUnit, long time);
+
+ void deleteRecursively(String path);
+
+ boolean delete(final String path);
+
+ <T extends Object> T readData(String path);
+
+ <T extends Object> T readData(String path, boolean returnNullIfPathNotExists);
+
+ <T extends Object> T readData(String path, Stat stat);
+
+ <T extends Object> T readData(final String path, final Stat stat, final boolean watch);
+
+ <T extends Object> T readDataAndStat(String path, Stat stat, boolean returnNullIfPathNotExists);
+
+ void writeData(String path, Object object);
+
+ <T extends Object> void updateDataSerialized(String path, DataUpdater<T> updater);
+
+ void writeData(final String path, Object datat, final int expectedVersion);
+
+ Stat writeDataReturnStat(final String path, Object datat, final int expectedVersion);
+
+ Stat writeDataGetStat(final String path, Object datat, final int expectedVersion);
+
+ void asyncCreate(final String path, Object datat, final CreateMode mode,
+ final ZkAsyncCallbacks.CreateCallbackHandler cb);
+
+ void asyncSetData(final String path, Object datat, final int version,
+ final ZkAsyncCallbacks.SetDataCallbackHandler cb);
+
+ void asyncGetData(final String path, final ZkAsyncCallbacks.GetDataCallbackHandler cb);
+
+ void asyncExists(final String path, final ZkAsyncCallbacks.ExistsCallbackHandler cb);
+
+ void asyncDelete(final String path, final ZkAsyncCallbacks.DeleteCallbackHandler cb);
+
+ void watchForData(final String path);
+
+ List<String> watchForChilds(final String path);
+
+ long getCreationTime(String path);
+
+ List<OpResult> multi(final Iterable<Op> ops);
+
+ // ZK state control
+ boolean waitUntilConnected(long time, TimeUnit timeUnit);
+
+ /**
+ * Waits for SyncConnected state and returns a valid session ID(non-zero). The implementation of
+ * this method should wait for SyncConnected state and ZK session to be established, and should
+ * guarantee the established session's ID is returned before keeper state changes.
+ *
+ * Please note: this default implementation may have race condition issue and return an unexpected
+ * session ID that is zero or another new session's ID. The default implementation is for backward
+ * compatibility purpose.
+ *
+ * @param timeout Max waiting time for connecting to ZK server.
+ * @param timeUnit Time unit for the timeout.
+ * @return A valid ZK session ID which is non-zero.
+ */
+ default long waitForEstablishedSession(long timeout, TimeUnit timeUnit) {
+ if (!waitUntilConnected(timeout, timeUnit)) {
+ throw new ZkTimeoutException(
+ "Failed to get established session because connecting to ZK server has timed out in "
+ + timeout + " " + timeUnit);
+ }
+ return getSessionId();
+ }
+
+ String getServers();
+
+ long getSessionId();
+
+ void close();
+
+ boolean isClosed();
+
+ // other
+ byte[] serialize(Object data, String path);
+
+ <T extends Object> T deserialize(byte[] data, String path);
+
+ void setZkSerializer(ZkSerializer zkSerializer);
+
+ void setZkSerializer(PathBasedZkSerializer zkSerializer);
+
+ PathBasedZkSerializer getZkSerializer();
+
+ /**
+ * A class that wraps a default implementation of
+ * {@link IZkStateListener}, which means this listener
+ * runs the methods of {@link IZkStateListener}.
+ * This is for backward compatibility and to avoid breaking the original implementation of
+ * {@link org.apache.helix.zookeeper.zkclient.deprecated.IZkStateListener}.
+ */
+ class I0ItecIZkStateListenerHelixImpl
+ implements org.apache.helix.zookeeper.zkclient.deprecated.IZkStateListener {
+ private IZkStateListener _listener;
+
+ I0ItecIZkStateListenerHelixImpl(IZkStateListener listener) {
+ _listener = listener;
+ }
+
+ @Override
+ public void handleStateChanged(Watcher.Event.KeeperState keeperState) throws Exception {
+ _listener.handleStateChanged(keeperState);
+ }
+
+ @Override
+ public void handleNewSession() throws Exception {
+ /*
+ * org.apache.helix.manager.zk.zookeeper.IZkStateListener does not have handleNewSession(),
+ * so null is passed into handleNewSession(sessionId).
+ */
+ _listener.handleNewSession(null);
+ }
+
+ @Override
+ public void handleSessionEstablishmentError(Throwable error) throws Exception {
+ _listener.handleSessionEstablishmentError(error);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof HelixZkClient.I0ItecIZkStateListenerHelixImpl)) {
+ return false;
+ }
+ if (_listener == null) {
+ return false;
+ }
+
+ HelixZkClient.I0ItecIZkStateListenerHelixImpl
+ defaultListener = (HelixZkClient.I0ItecIZkStateListenerHelixImpl) obj;
+
+ return _listener.equals(defaultListener._listener);
+ }
+
+ @Override
+ public int hashCode() {
+ /*
+ * The original listener's hashcode helps find the wrapped listener with the same original
+ * listener. This is helpful in unsubscribeStateChanges(listener).
+ */
+ return _listener.hashCode();
+ }
+ }
+
+ /**
+ * Configuration for creating a new ZkConnection.
+ */
+ class ZkConnectionConfig {
+ // Connection configs
+ private final String _zkServers;
+ private int _sessionTimeout = HelixZkClient.DEFAULT_SESSION_TIMEOUT;
+
+ public ZkConnectionConfig(String zkServers) {
+ _zkServers = zkServers;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof HelixZkClient.ZkConnectionConfig)) {
+ return false;
+ }
+ HelixZkClient.ZkConnectionConfig configObj = (HelixZkClient.ZkConnectionConfig) obj;
+ return (_zkServers == null && configObj._zkServers == null ||
+ _zkServers != null && _zkServers.equals(configObj._zkServers)) &&
+ _sessionTimeout == configObj._sessionTimeout;
+ }
+
+ @Override
+ public int hashCode() {
+ return _sessionTimeout * 31 + _zkServers.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return (_zkServers + "_" + _sessionTimeout).replaceAll("[\\W]", "_");
+ }
+
+ public HelixZkClient.ZkConnectionConfig setSessionTimeout(Integer sessionTimeout) {
+ this._sessionTimeout = sessionTimeout;
+ return this;
+ }
+
+ public String getZkServers() {
+ return _zkServers;
+ }
+
+ public int getSessionTimeout() {
+ return _sessionTimeout;
+ }
+ }
+
+ /**
+ * Configuration for creating a new RealmAwareZkClient with serializer and monitor.
+ */
+ class ZkClientConfig {
+ // For client to init the connection
+ private long _connectInitTimeout = HelixZkClient.DEFAULT_CONNECTION_TIMEOUT;
+
+ // Data access configs
+ private long _operationRetryTimeout = HelixZkClient.DEFAULT_OPERATION_TIMEOUT;
+
+ // Others
+ private PathBasedZkSerializer _zkSerializer;
+
+ // Monitoring
+ private String _monitorType;
+ private String _monitorKey;
+ private String _monitorInstanceName = null;
+ private boolean _monitorRootPathOnly = true;
+
+ public HelixZkClient.ZkClientConfig setZkSerializer(PathBasedZkSerializer zkSerializer) {
+ this._zkSerializer = zkSerializer;
+ return this;
+ }
+
+ public HelixZkClient.ZkClientConfig setZkSerializer(ZkSerializer zkSerializer) {
+ this._zkSerializer = new BasicZkSerializer(zkSerializer);
+ return this;
+ }
+
+ /**
+ * Used as part of the MBean ObjectName. This item is required for enabling monitoring.
+ *
+ * @param monitorType
+ */
+ public HelixZkClient.ZkClientConfig setMonitorType(String monitorType) {
+ this._monitorType = monitorType;
+ return this;
+ }
+
+ /**
+ * Used as part of the MBean ObjectName. This item is required for enabling monitoring.
+ *
+ * @param monitorKey
+ */
+ public HelixZkClient.ZkClientConfig setMonitorKey(String monitorKey) {
+ this._monitorKey = monitorKey;
+ return this;
+ }
+
+ /**
+ * Used as part of the MBean ObjectName. This item is optional.
+ *
+ * @param instanceName
+ */
+ public HelixZkClient.ZkClientConfig setMonitorInstanceName(String instanceName) {
+ this._monitorInstanceName = instanceName;
+ return this;
+ }
+
+ public HelixZkClient.ZkClientConfig setMonitorRootPathOnly(Boolean monitorRootPathOnly) {
+ this._monitorRootPathOnly = monitorRootPathOnly;
+ return this;
+ }
+
+ public HelixZkClient.ZkClientConfig setOperationRetryTimeout(Long operationRetryTimeout) {
+ this._operationRetryTimeout = operationRetryTimeout;
+ return this;
+ }
+
+ public HelixZkClient.ZkClientConfig setConnectInitTimeout(long _connectInitTimeout) {
+ this._connectInitTimeout = _connectInitTimeout;
+ return this;
+ }
+
+ public PathBasedZkSerializer getZkSerializer() {
+ if (_zkSerializer == null) {
+ _zkSerializer = new BasicZkSerializer(new SerializableSerializer());
+ }
+ return _zkSerializer;
+ }
+
+ public long getOperationRetryTimeout() {
+ return _operationRetryTimeout;
+ }
+
+ public String getMonitorType() {
+ return _monitorType;
+ }
+
+ public String getMonitorKey() {
+ return _monitorKey;
+ }
+
+ public String getMonitorInstanceName() {
+ return _monitorInstanceName;
+ }
+
+ public boolean isMonitorRootPathOnly() {
+ return _monitorRootPathOnly;
+ }
+
+ public long getConnectInitTimeout() {
+ return _connectInitTimeout;
+ }
+ }
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/api/factory/RealmAwareZkClientFactory.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/api/factory/RealmAwareZkClientFactory.java
new file mode 100644
index 0000000..9fbf259
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/api/factory/RealmAwareZkClientFactory.java
@@ -0,0 +1,23 @@
+package org.apache.helix.zookeeper.api.factory;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+public interface RealmAwareZkClientFactory {
+}
diff --git a/helix-core/src/main/java/org/apache/helix/ZNRecord.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/datamodel/ZNRecord.java
similarity index 97%
rename from helix-core/src/main/java/org/apache/helix/ZNRecord.java
rename to zookeeper-api/src/main/java/org/apache/helix/zookeeper/datamodel/ZNRecord.java
index bd9acbb..6070414 100644
--- a/helix-core/src/main/java/org/apache/helix/ZNRecord.java
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/datamodel/ZNRecord.java
@@ -1,4 +1,4 @@
-package org.apache.helix;
+package org.apache.helix.zookeeper.datamodel;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -24,9 +24,8 @@
import java.util.Map;
import java.util.TreeMap;
-import org.apache.helix.ZNRecordDelta.MergeOperation;
-import org.apache.helix.manager.zk.serializer.JacksonPayloadSerializer;
-import org.apache.helix.manager.zk.serializer.PayloadSerializer;
+import org.apache.helix.zookeeper.datamodel.serializer.JacksonPayloadSerializer;
+import org.apache.helix.zookeeper.datamodel.serializer.PayloadSerializer;
import org.codehaus.jackson.annotate.JsonCreator;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
@@ -36,6 +35,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
/**
* Generic Record Format to store data at a Node This can be used to store
* simpleFields mapFields listFields
@@ -540,11 +540,11 @@
* @param delta
*/
void merge(ZNRecordDelta delta) {
- if (delta.getMergeOperation() == MergeOperation.ADD) {
+ if (delta.getMergeOperation() == ZNRecordDelta.MergeOperation.ADD) {
merge(delta.getRecord());
- } else if (delta.getMergeOperation() == MergeOperation.SUBTRACT) {
+ } else if (delta.getMergeOperation() == ZNRecordDelta.MergeOperation.SUBTRACT) {
subtract(delta.getRecord());
- } else if (delta.getMergeOperation() == MergeOperation.UPDATE) {
+ } else if (delta.getMergeOperation() == ZNRecordDelta.MergeOperation.UPDATE) {
update(delta.getRecord());
}
}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/datamodel/ZNRecordAssembler.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/datamodel/ZNRecordAssembler.java
new file mode 100644
index 0000000..925fd17
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/datamodel/ZNRecordAssembler.java
@@ -0,0 +1,52 @@
+package org.apache.helix.zookeeper.datamodel;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+
+/**
+ * Constructs ZNRecords from collections of ZNRecords
+ */
+public class ZNRecordAssembler {
+ /**
+ * Merge a list of ZNRecords into a single ZNRecord
+ * @param records
+ * @return {@link ZNRecord}
+ */
+ public ZNRecord assemble(List<ZNRecord> records) {
+ ZNRecord assembledRecord = null;
+ if (records != null && records.size() > 0) {
+ for (ZNRecord record : records) {
+ if (record == null) {
+ continue;
+ }
+
+ if (assembledRecord == null) {
+ assembledRecord = new ZNRecord(record.getId());
+ }
+
+ assembledRecord.merge(record);
+ }
+ }
+ return assembledRecord;
+ }
+
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/datamodel/ZNRecordBucketizer.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/datamodel/ZNRecordBucketizer.java
new file mode 100644
index 0000000..107e12e
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/datamodel/ZNRecordBucketizer.java
@@ -0,0 +1,125 @@
+package org.apache.helix.zookeeper.datamodel;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Operations to divide a ZNRecord into specified buckets
+ */
+public class ZNRecordBucketizer {
+ private static Logger LOG = LoggerFactory.getLogger(ZNRecordBucketizer.class);
+ final int _bucketSize;
+
+ /**
+ * Instantiate a bucketizer with the number of buckets
+ * @param bucketSize
+ */
+ public ZNRecordBucketizer(int bucketSize) {
+ if (bucketSize <= 0) {
+ LOG.debug("bucketSize <= 0 (was " + bucketSize
+ + "). Set to 0 to use non-bucketized HelixProperty.");
+ bucketSize = 0;
+ }
+
+ _bucketSize = bucketSize;
+ }
+
+ /**
+ * Calculate bucketName in form of "resourceName_p{startPartition}-p{endPartition}
+ * @param partitionName
+ * @return the bucket name
+ */
+ public String getBucketName(String key) {
+ if (_bucketSize == 0) {
+ // no bucketize
+ return null;
+ }
+
+ int idx = key.lastIndexOf('_');
+ if (idx < 0) {
+ throw new IllegalArgumentException("Could NOT find partition# in " + key
+ + ". partitionName should be in format of resourceName_partition#");
+ }
+
+ try {
+ int partitionNb = Integer.parseInt(key.substring(idx + 1));
+ int bucketNb = partitionNb / _bucketSize;
+ int startPartition = bucketNb * _bucketSize;
+ int endPartition = bucketNb * _bucketSize + (_bucketSize - 1);
+ return key.substring(0, idx) + "_p" + startPartition + "-p" + endPartition;
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Could NOT parse partition# (" + key.substring(idx + 1)
+ + ") in " + key);
+ }
+ }
+
+ /**
+ * Bucketize a ZNRecord
+ * @param record
+ * @return A map of bucket names to bucketized records
+ */
+ public Map<String, ZNRecord> bucketize(ZNRecord record) {
+ Map<String, ZNRecord> map = new HashMap<String, ZNRecord>();
+ if (_bucketSize == 0) {
+ map.put(record.getId(), record);
+ return map;
+ }
+
+ // bucketize list field
+ for (String partitionName : record.getListFields().keySet()) {
+ String bucketName = getBucketName(partitionName);
+ if (bucketName != null) {
+ if (!map.containsKey(bucketName)) {
+ map.put(bucketName, new ZNRecord(bucketName));
+ }
+ ZNRecord bucketizedRecord = map.get(bucketName);
+ bucketizedRecord.setListField(partitionName, record.getListField(partitionName));
+ } else {
+ LOG.error("Can't bucketize " + partitionName + " in list field");
+ }
+ }
+
+ // bucketize map field
+ for (String partitionName : record.getMapFields().keySet()) {
+ String bucketName = getBucketName(partitionName);
+ if (bucketName != null) {
+ if (!map.containsKey(bucketName)) {
+ map.put(bucketName, new ZNRecord(bucketName));
+ }
+ ZNRecord bucketizedRecord = map.get(bucketName);
+ bucketizedRecord.setMapField(partitionName, record.getMapField(partitionName));
+ } else {
+ LOG.error("Can't bucketize " + partitionName + " in map field");
+ }
+ }
+
+ // copy all simple fields
+ for (ZNRecord bucketizedRecord : map.values()) {
+ bucketizedRecord.setSimpleFields(record.getSimpleFields());
+ }
+ return map;
+ }
+}
diff --git a/helix-core/src/main/java/org/apache/helix/ZNRecordDelta.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/datamodel/ZNRecordDelta.java
similarity index 97%
rename from helix-core/src/main/java/org/apache/helix/ZNRecordDelta.java
rename to zookeeper-api/src/main/java/org/apache/helix/zookeeper/datamodel/ZNRecordDelta.java
index 616e1f5..9ccf0a9 100644
--- a/helix-core/src/main/java/org/apache/helix/ZNRecordDelta.java
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/datamodel/ZNRecordDelta.java
@@ -1,4 +1,4 @@
-package org.apache.helix;
+package org.apache.helix.zookeeper.datamodel;
/*
* Licensed to the Apache Software Foundation (ASF) under one
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/datamodel/ZNRecordUpdater.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/datamodel/ZNRecordUpdater.java
new file mode 100644
index 0000000..27388fa
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/datamodel/ZNRecordUpdater.java
@@ -0,0 +1,47 @@
+package org.apache.helix.zookeeper.datamodel;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
+
+
+/**
+ * Class that specifies how a ZNRecord should be updated with another ZNRecord
+ */
+public class ZNRecordUpdater implements DataUpdater<ZNRecord> {
+ final ZNRecord _record;
+
+ /**
+ * Initialize with the record that will be updated
+ * @param record
+ */
+ public ZNRecordUpdater(ZNRecord record) {
+ _record = record;
+ }
+
+ @Override
+ public ZNRecord update(ZNRecord current) {
+ if (current != null) {
+ current.merge(_record);
+ return current;
+ }
+ return _record;
+ }
+}
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/serializer/JacksonPayloadSerializer.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/datamodel/serializer/JacksonPayloadSerializer.java
similarity index 94%
rename from helix-core/src/main/java/org/apache/helix/manager/zk/serializer/JacksonPayloadSerializer.java
rename to zookeeper-api/src/main/java/org/apache/helix/zookeeper/datamodel/serializer/JacksonPayloadSerializer.java
index 1cc8102..ee16fd1 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/serializer/JacksonPayloadSerializer.java
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/datamodel/serializer/JacksonPayloadSerializer.java
@@ -1,4 +1,4 @@
-package org.apache.helix.manager.zk.serializer;
+package org.apache.helix.zookeeper.datamodel.serializer;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -22,13 +22,14 @@
import java.io.ByteArrayInputStream;
import java.io.StringWriter;
-import org.apache.helix.HelixException;
+import org.apache.helix.zookeeper.exception.ZkClientException;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
/**
* Serializes and deserializes data of a generic type using Jackson
*/
@@ -52,7 +53,7 @@
mapper.writeValue(sw, data);
} catch (Exception e) {
logger.error("Exception during payload data serialization.", e);
- throw new HelixException(e);
+ throw new ZkClientException(e);
}
return sw.toString().getBytes();
}
@@ -78,5 +79,4 @@
return null;
}
}
-
}
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/serializer/PayloadSerializer.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/datamodel/serializer/PayloadSerializer.java
similarity index 95%
rename from helix-core/src/main/java/org/apache/helix/manager/zk/serializer/PayloadSerializer.java
rename to zookeeper-api/src/main/java/org/apache/helix/zookeeper/datamodel/serializer/PayloadSerializer.java
index a9531bd..54ccf71 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/serializer/PayloadSerializer.java
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/datamodel/serializer/PayloadSerializer.java
@@ -1,4 +1,4 @@
-package org.apache.helix.manager.zk.serializer;
+package org.apache.helix.zookeeper.datamodel.serializer;
/*
* Licensed to the Apache Software Foundation (ASF) under one
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/datamodel/serializer/ZNRecordJacksonSerializer.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/datamodel/serializer/ZNRecordJacksonSerializer.java
new file mode 100644
index 0000000..a30829a
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/datamodel/serializer/ZNRecordJacksonSerializer.java
@@ -0,0 +1,69 @@
+package org.apache.helix.zookeeper.datamodel.serializer;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.exception.ZkClientException;
+import org.apache.helix.zookeeper.zkclient.exception.ZkMarshallingError;
+import org.apache.helix.zookeeper.zkclient.serialize.ZkSerializer;
+import org.codehaus.jackson.map.ObjectMapper;
+
+
+/**
+ * ZNRecordJacksonSerializer serializes ZNRecord objects into a byte array using Jackson. Note that
+ * this serializer doesn't check for the size of the resulting binary.
+ */
+public class ZNRecordJacksonSerializer implements ZkSerializer {
+ private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
+
+ @Override
+ public byte[] serialize(Object record) throws ZkMarshallingError {
+ if (!(record instanceof ZNRecord)) {
+ // null is NOT an instance of any class
+ throw new ZkClientException("Input object is not of type ZNRecord (was " + record + ")");
+ }
+ ZNRecord znRecord = (ZNRecord) record;
+
+ try {
+ return OBJECT_MAPPER.writeValueAsBytes(znRecord);
+ } catch (IOException e) {
+ throw new ZkClientException(
+ String.format("Exception during serialization. ZNRecord id: %s", znRecord.getId()), e);
+ }
+ }
+
+ @Override
+ public Object deserialize(byte[] bytes) throws ZkMarshallingError {
+ if (bytes == null || bytes.length == 0) {
+ // reading a parent/null node
+ return null;
+ }
+
+ ZNRecord record;
+ try {
+ record = OBJECT_MAPPER.readValue(bytes, ZNRecord.class);
+ } catch (IOException e) {
+ throw new ZkClientException("Exception during deserialization!", e);
+ }
+ return record;
+ }
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/datamodel/serializer/ZNRecordSerializer.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/datamodel/serializer/ZNRecordSerializer.java
new file mode 100644
index 0000000..89850b0
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/datamodel/serializer/ZNRecordSerializer.java
@@ -0,0 +1,134 @@
+package org.apache.helix.zookeeper.datamodel.serializer;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.exception.ZkClientException;
+import org.apache.helix.zookeeper.util.GZipCompressionUtil;
+import org.apache.helix.zookeeper.zkclient.serialize.ZkSerializer;
+import org.codehaus.jackson.map.DeserializationConfig;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.map.SerializationConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class ZNRecordSerializer implements ZkSerializer {
+ private static Logger logger = LoggerFactory.getLogger(ZNRecordSerializer.class);
+
+ private static int getListFieldBound(ZNRecord record) {
+ int max = Integer.MAX_VALUE;
+ if (record.getSimpleFields().containsKey(ZNRecord.LIST_FIELD_BOUND)) {
+ String maxStr = record.getSimpleField(ZNRecord.LIST_FIELD_BOUND);
+ try {
+ max = Integer.parseInt(maxStr);
+ } catch (Exception e) {
+ logger.error("IllegalNumberFormat for list field bound: " + maxStr);
+ }
+ }
+ return max;
+ }
+
+ @Override
+ public byte[] serialize(Object data) {
+ if (!(data instanceof ZNRecord)) {
+ // null is NOT an instance of any class
+ logger.error("Input object must be of type ZNRecord but it is " + data
+ + ". Will not write to zk");
+ throw new ZkClientException("Input object is not of type ZNRecord (was " + data + ")");
+ }
+
+ ZNRecord record = (ZNRecord) data;
+
+ // apply retention policy
+ int max = getListFieldBound(record);
+ if (max < Integer.MAX_VALUE) {
+ Map<String, List<String>> listMap = record.getListFields();
+ for (String key : listMap.keySet()) {
+ List<String> list = listMap.get(key);
+ if (list.size() > max) {
+ listMap.put(key, list.subList(0, max));
+ }
+ }
+ }
+
+ // do serialization
+ ObjectMapper mapper = new ObjectMapper();
+ SerializationConfig serializationConfig = mapper.getSerializationConfig();
+ serializationConfig.set(SerializationConfig.Feature.INDENT_OUTPUT, true);
+ serializationConfig.set(SerializationConfig.Feature.AUTO_DETECT_FIELDS, true);
+ serializationConfig.set(SerializationConfig.Feature.CAN_OVERRIDE_ACCESS_MODIFIERS, true);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] serializedBytes;
+ try {
+ mapper.writeValue(baos, data);
+ serializedBytes = baos.toByteArray();
+ // apply compression if needed
+ if (record.getBooleanField("enableCompression", false) || serializedBytes.length > ZNRecord.SIZE_LIMIT) {
+ serializedBytes = GZipCompressionUtil.compress(serializedBytes);
+ }
+ } catch (Exception e) {
+ logger.error("Exception during data serialization. Will not write to zk. Data (first 1k): "
+ + new String(baos.toByteArray()).substring(0, 1024), e);
+ throw new ZkClientException(e);
+ }
+ if (serializedBytes.length > ZNRecord.SIZE_LIMIT) {
+ logger.error("Data size larger than 1M, ZNRecord.id: " + record.getId()
+ + ". Will not write to zk. Data (first 1k): "
+ + new String(serializedBytes).substring(0, 1024));
+ throw new ZkClientException("Data size larger than 1M, ZNRecord.id: " + record.getId());
+ }
+ return serializedBytes;
+ }
+
+ @Override
+ public Object deserialize(byte[] bytes) {
+ if (bytes == null || bytes.length == 0) {
+ // reading a parent/null node
+ return null;
+ }
+
+ ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+
+ ObjectMapper mapper = new ObjectMapper();
+ DeserializationConfig deserializationConfig = mapper.getDeserializationConfig();
+ deserializationConfig.set(DeserializationConfig.Feature.AUTO_DETECT_FIELDS, true);
+ deserializationConfig.set(DeserializationConfig.Feature.AUTO_DETECT_SETTERS, true);
+ deserializationConfig.set(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, true);
+ try {
+ //decompress the data if its already compressed
+ if (GZipCompressionUtil.isCompressed(bytes)) {
+ byte[] uncompressedBytes = GZipCompressionUtil.uncompress(bais);
+ bais = new ByteArrayInputStream(uncompressedBytes);
+ }
+ ZNRecord zn = mapper.readValue(bais, ZNRecord.class);
+
+ return zn;
+ } catch (Exception e) {
+ logger.error("Exception during deserialization of bytes: " + new String(bytes), e);
+ return null;
+ }
+ }
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/datamodel/serializer/ZNRecordStreamingSerializer.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/datamodel/serializer/ZNRecordStreamingSerializer.java
new file mode 100644
index 0000000..c5acdb0
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/datamodel/serializer/ZNRecordStreamingSerializer.java
@@ -0,0 +1,311 @@
+package org.apache.helix.zookeeper.datamodel.serializer;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.exception.ZkClientException;
+import org.apache.helix.zookeeper.util.GZipCompressionUtil;
+import org.apache.helix.zookeeper.zkclient.exception.ZkMarshallingError;
+import org.apache.helix.zookeeper.zkclient.serialize.ZkSerializer;
+import org.codehaus.jackson.JsonFactory;
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.JsonParser;
+import org.codehaus.jackson.JsonToken;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class ZNRecordStreamingSerializer implements ZkSerializer {
+ private static Logger LOG = LoggerFactory.getLogger(ZNRecordStreamingSerializer.class);
+
+ private static int getListFieldBound(ZNRecord record) {
+ int max = Integer.MAX_VALUE;
+ if (record.getSimpleFields().containsKey(ZNRecord.LIST_FIELD_BOUND)) {
+ String maxStr = record.getSimpleField(ZNRecord.LIST_FIELD_BOUND);
+ try {
+ max = Integer.parseInt(maxStr);
+ } catch (Exception e) {
+ LOG.error("IllegalNumberFormat for list field bound: " + maxStr);
+ }
+ }
+ return max;
+ }
+
+ @Override
+ public byte[] serialize(Object data) throws ZkMarshallingError {
+ if (!(data instanceof ZNRecord)) {
+ // null is NOT an instance of any class
+ LOG.error("Input object must be of type ZNRecord but it is " + data
+ + ". Will not write to zk");
+ throw new ZkClientException("Input object is not of type ZNRecord (was " + data + ")");
+ }
+
+ // apply retention policy on list field
+ ZNRecord record = (ZNRecord) data;
+ int max = getListFieldBound(record);
+ if (max < Integer.MAX_VALUE) {
+ Map<String, List<String>> listMap = record.getListFields();
+ for (String key : listMap.keySet()) {
+ List<String> list = listMap.get(key);
+ if (list.size() > max) {
+ listMap.put(key, list.subList(0, max));
+ }
+ }
+ }
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] serializedBytes = null;
+ try {
+ JsonFactory f = new JsonFactory();
+ JsonGenerator g = f.createJsonGenerator(baos);
+
+ g.writeStartObject();
+
+ // write id field
+ g.writeRaw("\n ");
+ g.writeStringField("id", record.getId());
+
+ // write simepleFields
+ g.writeRaw("\n ");
+ g.writeObjectFieldStart("simpleFields");
+ for (String key : record.getSimpleFields().keySet()) {
+ g.writeRaw("\n ");
+ g.writeStringField(key, record.getSimpleField(key));
+ }
+ g.writeRaw("\n ");
+ g.writeEndObject(); // for simpleFields
+
+ // write listFields
+ g.writeRaw("\n ");
+ g.writeObjectFieldStart("listFields");
+ for (String key : record.getListFields().keySet()) {
+ // g.writeStringField(key, record.getListField(key).toString());
+
+ // g.writeObjectFieldStart(key);
+ g.writeRaw("\n ");
+ g.writeArrayFieldStart(key);
+ List<String> list = record.getListField(key);
+ for (String listValue : list) {
+ g.writeString(listValue);
+ }
+ // g.writeEndObject();
+ g.writeEndArray();
+
+ }
+ g.writeRaw("\n ");
+ g.writeEndObject(); // for listFields
+
+ // write mapFields
+ g.writeRaw("\n ");
+ g.writeObjectFieldStart("mapFields");
+ for (String key : record.getMapFields().keySet()) {
+ // g.writeStringField(key, record.getMapField(key).toString());
+ g.writeRaw("\n ");
+ g.writeObjectFieldStart(key);
+ Map<String, String> map = record.getMapField(key);
+ for (String mapKey : map.keySet()) {
+ g.writeRaw("\n ");
+ g.writeStringField(mapKey, map.get(mapKey));
+ }
+ g.writeRaw("\n ");
+ g.writeEndObject();
+
+ }
+ g.writeRaw("\n ");
+ g.writeEndObject(); // for mapFields
+
+ byte[] rawPayload = record.getRawPayload();
+ if (rawPayload != null && rawPayload.length > 0) {
+ // write rawPayload
+ g.writeRaw("\n ");
+ g.writeStringField("rawPayload", new String(Base64.encodeBase64(rawPayload), "UTF-8"));
+ }
+
+ g.writeRaw("\n");
+ g.writeEndObject(); // for whole znrecord
+
+ // important: will force flushing of output, close underlying output
+ // stream
+ g.close();
+ serializedBytes = baos.toByteArray();
+ // apply compression if needed
+ if (record.getBooleanField("enableCompression", false) || serializedBytes.length > ZNRecord.SIZE_LIMIT) {
+ serializedBytes = GZipCompressionUtil.compress(serializedBytes);
+ }
+ } catch (Exception e) {
+ LOG.error("Exception during data serialization. Will not write to zk. Data (first 1k): "
+ + new String(baos.toByteArray()).substring(0, 1024), e);
+ throw new ZkClientException(e);
+ }
+ // check size
+ if (serializedBytes.length > ZNRecord.SIZE_LIMIT) {
+ LOG.error("Data size larger than 1M, ZNRecord.id: " + record.getId()
+ + ". Will not write to zk. Data (first 1k): "
+ + new String(serializedBytes).substring(0, 1024));
+ throw new ZkClientException("Data size larger than 1M, ZNRecord.id: " + record.getId());
+ }
+
+ return serializedBytes;
+ }
+
+ @Override
+ public Object deserialize(byte[] bytes) throws ZkMarshallingError {
+ if (bytes == null || bytes.length == 0) {
+ LOG.error("ZNode is empty.");
+ return null;
+ }
+
+ ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+
+ ZNRecord record = null;
+ String id = null;
+ Map<String, String> simpleFields = new HashMap<>();
+ Map<String, List<String>> listFields = new HashMap<>();
+ Map<String, Map<String, String>> mapFields = new HashMap<>();
+ byte[] rawPayload = null;
+
+ try {
+ // decompress the data if its already compressed
+ if (GZipCompressionUtil.isCompressed(bytes)) {
+ byte[] uncompressedBytes = GZipCompressionUtil.uncompress(bais);
+ bais = new ByteArrayInputStream(uncompressedBytes);
+ }
+ JsonFactory f = new JsonFactory();
+ JsonParser jp = f.createJsonParser(bais);
+
+ jp.nextToken(); // will return JsonToken.START_OBJECT (verify?)
+ while (jp.nextToken() != JsonToken.END_OBJECT) {
+ String fieldname = jp.getCurrentName();
+ jp.nextToken(); // move to value, or START_OBJECT/START_ARRAY
+ if ("id".equals(fieldname)) {
+ // contains an object
+ id = jp.getText();
+ } else if ("simpleFields".equals(fieldname)) {
+ while (jp.nextToken() != JsonToken.END_OBJECT) {
+ String key = jp.getCurrentName();
+ jp.nextToken(); // move to value
+ simpleFields.put(key, jp.getText());
+ }
+ } else if ("mapFields".equals(fieldname)) {
+ // user.setVerified(jp.getCurrentToken() == JsonToken.VALUE_TRUE);
+ while (jp.nextToken() != JsonToken.END_OBJECT) {
+ String key = jp.getCurrentName();
+ mapFields.put(key, new TreeMap<String, String>());
+ jp.nextToken(); // move to value
+
+ while (jp.nextToken() != JsonToken.END_OBJECT) {
+ String mapKey = jp.getCurrentName();
+ jp.nextToken(); // move to value
+ mapFields.get(key).put(mapKey, jp.getText());
+ }
+ }
+
+ } else if ("listFields".equals(fieldname)) {
+ // user.setUserImage(jp.getBinaryValue());
+ while (jp.nextToken() != JsonToken.END_OBJECT) {
+ String key = jp.getCurrentName();
+ listFields.put(key, new ArrayList<String>());
+ jp.nextToken(); // move to value
+ while (jp.nextToken() != JsonToken.END_ARRAY) {
+ listFields.get(key).add(jp.getText());
+ }
+
+ }
+
+ } else if ("rawPayload".equals(fieldname)) {
+ rawPayload = Base64.decodeBase64(jp.getText());
+ } else {
+ throw new IllegalStateException("Unrecognized field '" + fieldname + "'!");
+ }
+ }
+ jp.close(); // ensure resources get cleaned up timely and properly
+
+ if (id == null) {
+ throw new IllegalStateException("ZNRecord id field is required!");
+ }
+ record = new ZNRecord(id);
+ record.setSimpleFields(simpleFields);
+ record.setListFields(listFields);
+ record.setMapFields(mapFields);
+ record.setRawPayload(rawPayload);
+ } catch (Exception e) {
+ LOG.error("Exception during deserialization of bytes: " + new String(bytes), e);
+ }
+ return record;
+ }
+
+ public static void main(String[] args) {
+ ZNRecord record = new ZNRecord("record");
+ final int recordSize = 10;
+ for (int i = 0; i < recordSize; i++) {
+ record.setSimpleField("" + i, "" + i);
+ record.setListField("" + i, new ArrayList<String>());
+ for (int j = 0; j < recordSize; j++) {
+ record.getListField("" + i).add("" + j);
+ }
+
+ record.setMapField("" + i, new TreeMap<String, String>());
+ for (int j = 0; j < recordSize; j++) {
+ record.getMapField("" + i).put("" + j, "" + j);
+ }
+ }
+
+ ZNRecordStreamingSerializer serializer = new ZNRecordStreamingSerializer();
+ byte[] bytes = serializer.serialize(record);
+ System.out.println(new String(bytes));
+ ZNRecord record2 = (ZNRecord) serializer.deserialize(bytes);
+ System.out.println(record2);
+
+ long start = System.currentTimeMillis();
+ for (int i = 0; i < 100; i++) {
+ bytes = serializer.serialize(record);
+ // System.out.println(new String(bytes));
+ record2 = (ZNRecord) serializer.deserialize(bytes);
+ // System.out.println(record2);
+ }
+ long end = System.currentTimeMillis();
+ System.out.println("ZNRecordStreamingSerializer time used: " + (end - start));
+
+ ZNRecordSerializer serializer2 = new ZNRecordSerializer();
+ bytes = serializer2.serialize(record);
+ // System.out.println(new String(bytes));
+ record2 = (ZNRecord) serializer2.deserialize(bytes);
+ // System.out.println(record2);
+
+ start = System.currentTimeMillis();
+ for (int i = 0; i < 100; i++) {
+ bytes = serializer2.serialize(record);
+ // System.out.println(new String(bytes));
+ record2 = (ZNRecord) serializer2.deserialize(bytes);
+ // System.out.println(record2);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("ZNRecordSerializer time used: " + (end - start));
+
+ }
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/exception/ZkClientException.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/exception/ZkClientException.java
new file mode 100644
index 0000000..3a669f5
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/exception/ZkClientException.java
@@ -0,0 +1,38 @@
+package org.apache.helix.zookeeper.exception;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Exceptions for ZkClient-related failures.
+ */
+public class ZkClientException extends RuntimeException {
+
+ public ZkClientException(String message) {
+ super(message);
+ }
+
+ public ZkClientException(Throwable cause) {
+ super(cause);
+ }
+
+ public ZkClientException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/impl/client/FederatedZkClient.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/impl/client/FederatedZkClient.java
new file mode 100644
index 0000000..3925a6d
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/impl/client/FederatedZkClient.java
@@ -0,0 +1,363 @@
+package org.apache.helix.zookeeper.impl.client;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.helix.zookeeper.api.client.RealmAwareZkClient;
+import org.apache.helix.zookeeper.zkclient.DataUpdater;
+import org.apache.helix.zookeeper.zkclient.IZkChildListener;
+import org.apache.helix.zookeeper.zkclient.IZkDataListener;
+import org.apache.helix.zookeeper.zkclient.callback.ZkAsyncCallbacks;
+import org.apache.helix.zookeeper.zkclient.deprecated.IZkStateListener;
+import org.apache.helix.zookeeper.zkclient.serialize.PathBasedZkSerializer;
+import org.apache.helix.zookeeper.zkclient.serialize.ZkSerializer;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.Op;
+import org.apache.zookeeper.OpResult;
+import org.apache.zookeeper.data.ACL;
+import org.apache.zookeeper.data.Stat;
+
+
+public class FederatedZkClient implements RealmAwareZkClient {
+ @Override
+ public List<String> subscribeChildChanges(String path, IZkChildListener listener) {
+ return null;
+ }
+
+ @Override
+ public void unsubscribeChildChanges(String path, IZkChildListener listener) {
+
+ }
+
+ @Override
+ public void subscribeDataChanges(String path, IZkDataListener listener) {
+
+ }
+
+ @Override
+ public void unsubscribeDataChanges(String path, IZkDataListener listener) {
+
+ }
+
+ @Override
+ public void subscribeStateChanges(IZkStateListener listener) {
+
+ }
+
+ @Override
+ public void unsubscribeStateChanges(IZkStateListener listener) {
+
+ }
+
+ @Override
+ public void unsubscribeAll() {
+
+ }
+
+ @Override
+ public void createPersistent(String path) {
+
+ }
+
+ @Override
+ public void createPersistent(String path, boolean createParents) {
+
+ }
+
+ @Override
+ public void createPersistent(String path, boolean createParents, List<ACL> acl) {
+
+ }
+
+ @Override
+ public void createPersistent(String path, Object data) {
+
+ }
+
+ @Override
+ public void createPersistent(String path, Object data, List<ACL> acl) {
+
+ }
+
+ @Override
+ public String createPersistentSequential(String path, Object data) {
+ return null;
+ }
+
+ @Override
+ public String createPersistentSequential(String path, Object data, List<ACL> acl) {
+ return null;
+ }
+
+ @Override
+ public void createEphemeral(String path) {
+
+ }
+
+ @Override
+ public void createEphemeral(String path, String sessionId) {
+
+ }
+
+ @Override
+ public void createEphemeral(String path, List<ACL> acl) {
+
+ }
+
+ @Override
+ public void createEphemeral(String path, List<ACL> acl, String sessionId) {
+
+ }
+
+ @Override
+ public String create(String path, Object data, CreateMode mode) {
+ return null;
+ }
+
+ @Override
+ public String create(String path, Object datat, List<ACL> acl, CreateMode mode) {
+ return null;
+ }
+
+ @Override
+ public void createEphemeral(String path, Object data) {
+
+ }
+
+ @Override
+ public void createEphemeral(String path, Object data, String sessionId) {
+
+ }
+
+ @Override
+ public void createEphemeral(String path, Object data, List<ACL> acl) {
+
+ }
+
+ @Override
+ public void createEphemeral(String path, Object data, List<ACL> acl, String sessionId) {
+
+ }
+
+ @Override
+ public String createEphemeralSequential(String path, Object data) {
+ return null;
+ }
+
+ @Override
+ public String createEphemeralSequential(String path, Object data, List<ACL> acl) {
+ return null;
+ }
+
+ @Override
+ public String createEphemeralSequential(String path, Object data, String sessionId) {
+ return null;
+ }
+
+ @Override
+ public String createEphemeralSequential(String path, Object data, List<ACL> acl,
+ String sessionId) {
+ return null;
+ }
+
+ @Override
+ public List<String> getChildren(String path) {
+ return null;
+ }
+
+ @Override
+ public int countChildren(String path) {
+ return 0;
+ }
+
+ @Override
+ public boolean exists(String path) {
+ return false;
+ }
+
+ @Override
+ public Stat getStat(String path) {
+ return null;
+ }
+
+ @Override
+ public boolean waitUntilExists(String path, TimeUnit timeUnit, long time) {
+ return false;
+ }
+
+ @Override
+ public void deleteRecursively(String path) {
+
+ }
+
+ @Override
+ public boolean delete(String path) {
+ return false;
+ }
+
+ @Override
+ public <T> T readData(String path) {
+ return null;
+ }
+
+ @Override
+ public <T> T readData(String path, boolean returnNullIfPathNotExists) {
+ return null;
+ }
+
+ @Override
+ public <T> T readData(String path, Stat stat) {
+ return null;
+ }
+
+ @Override
+ public <T> T readData(String path, Stat stat, boolean watch) {
+ return null;
+ }
+
+ @Override
+ public <T> T readDataAndStat(String path, Stat stat, boolean returnNullIfPathNotExists) {
+ return null;
+ }
+
+ @Override
+ public void writeData(String path, Object object) {
+
+ }
+
+ @Override
+ public <T> void updateDataSerialized(String path, DataUpdater<T> updater) {
+
+ }
+
+ @Override
+ public void writeData(String path, Object datat, int expectedVersion) {
+
+ }
+
+ @Override
+ public Stat writeDataReturnStat(String path, Object datat, int expectedVersion) {
+ return null;
+ }
+
+ @Override
+ public Stat writeDataGetStat(String path, Object datat, int expectedVersion) {
+ return null;
+ }
+
+ @Override
+ public void asyncCreate(String path, Object datat, CreateMode mode,
+ ZkAsyncCallbacks.CreateCallbackHandler cb) {
+
+ }
+
+ @Override
+ public void asyncSetData(String path, Object datat, int version,
+ ZkAsyncCallbacks.SetDataCallbackHandler cb) {
+
+ }
+
+ @Override
+ public void asyncGetData(String path, ZkAsyncCallbacks.GetDataCallbackHandler cb) {
+
+ }
+
+ @Override
+ public void asyncExists(String path, ZkAsyncCallbacks.ExistsCallbackHandler cb) {
+
+ }
+
+ @Override
+ public void asyncDelete(String path, ZkAsyncCallbacks.DeleteCallbackHandler cb) {
+
+ }
+
+ @Override
+ public void watchForData(String path) {
+
+ }
+
+ @Override
+ public List<String> watchForChilds(String path) {
+ return null;
+ }
+
+ @Override
+ public long getCreationTime(String path) {
+ return 0;
+ }
+
+ @Override
+ public List<OpResult> multi(Iterable<Op> ops) {
+ return null;
+ }
+
+ @Override
+ public boolean waitUntilConnected(long time, TimeUnit timeUnit) {
+ return false;
+ }
+
+ @Override
+ public String getServers() {
+ return null;
+ }
+
+ @Override
+ public long getSessionId() {
+ return 0;
+ }
+
+ @Override
+ public void close() {
+
+ }
+
+ @Override
+ public boolean isClosed() {
+ return false;
+ }
+
+ @Override
+ public byte[] serialize(Object data, String path) {
+ return new byte[0];
+ }
+
+ @Override
+ public <T> T deserialize(byte[] data, String path) {
+ return null;
+ }
+
+ @Override
+ public void setZkSerializer(ZkSerializer zkSerializer) {
+
+ }
+
+ @Override
+ public void setZkSerializer(PathBasedZkSerializer zkSerializer) {
+
+ }
+
+ @Override
+ public PathBasedZkSerializer getZkSerializer() {
+ return null;
+ }
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/impl/client/SharedZkClient.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/impl/client/SharedZkClient.java
new file mode 100644
index 0000000..70d58a8
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/impl/client/SharedZkClient.java
@@ -0,0 +1,115 @@
+package org.apache.helix.zookeeper.impl.client;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.factory.ZkConnectionManager;
+import org.apache.helix.zookeeper.zkclient.IZkConnection;
+import org.apache.helix.zookeeper.zkclient.ZkConnection;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.data.ACL;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * NOTE: DO NOT USE THIS CLASS DIRECTLY. USE SharedZkClientFactory instead.
+ *
+ * HelixZkClient that uses shared ZkConnection.
+ * A SharedZkClient won't manipulate the shared ZkConnection directly.
+ */
+public class SharedZkClient extends ZkClient implements HelixZkClient {
+ private static Logger LOG = LoggerFactory.getLogger(SharedZkClient.class);
+ /*
+ * Since we cannot really disconnect the ZkConnection, we need a dummy ZkConnection placeholder.
+ * This is to ensure connection field is never null even the shared RealmAwareZkClient instance is closed so as to avoid NPE.
+ */
+ private final static ZkConnection IDLE_CONNECTION = new ZkConnection("Dummy_ZkServers");
+ private final OnCloseCallback _onCloseCallback;
+ private final ZkConnectionManager _connectionManager;
+
+ public interface OnCloseCallback {
+ /**
+ * Triggered after the RealmAwareZkClient is closed.
+ */
+ void onClose();
+ }
+
+ /**
+ * Construct a shared RealmAwareZkClient that uses a shared ZkConnection.
+ *
+ * @param connectionManager The manager of the shared ZkConnection.
+ * @param clientConfig ZkClientConfig details to create the shared RealmAwareZkClient.
+ * @param callback Clean up logic when the shared RealmAwareZkClient is closed.
+ */
+ public SharedZkClient(ZkConnectionManager connectionManager, ZkClientConfig clientConfig,
+ OnCloseCallback callback) {
+ super(connectionManager.getConnection(), 0, clientConfig.getOperationRetryTimeout(),
+ clientConfig.getZkSerializer(), clientConfig.getMonitorType(), clientConfig.getMonitorKey(),
+ clientConfig.getMonitorInstanceName(), clientConfig.isMonitorRootPathOnly());
+ _connectionManager = connectionManager;
+ // Register to the base dedicated RealmAwareZkClient
+ _connectionManager.registerWatcher(this);
+ _onCloseCallback = callback;
+ }
+
+ @Override
+ public void close() {
+ super.close();
+ if (isClosed()) {
+ // Note that if register is not done while constructing, these private fields may not be init yet.
+ if (_connectionManager != null) {
+ _connectionManager.unregisterWatcher(this);
+ }
+ if (_onCloseCallback != null) {
+ _onCloseCallback.onClose();
+ }
+ }
+ }
+
+ @Override
+ public IZkConnection getConnection() {
+ if (isClosed()) {
+ return IDLE_CONNECTION;
+ }
+ return super.getConnection();
+ }
+
+ /**
+ * Since ZkConnection session is shared in this RealmAwareZkClient, do not create ephemeral node using a SharedZKClient.
+ */
+ @Override
+ public String create(final String path, Object datat, final List<ACL> acl,
+ final CreateMode mode) {
+ if (mode.isEphemeral()) {
+ throw new UnsupportedOperationException(
+ "Create ephemeral nodes using a " + SharedZkClient.class.getSimpleName()
+ + " is not supported.");
+ }
+ return super.create(path, datat, acl, mode);
+ }
+
+ @Override
+ protected boolean isManagingZkConnection() {
+ return false;
+ }
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/impl/client/ZkClient.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/impl/client/ZkClient.java
new file mode 100644
index 0000000..619e1da
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/impl/client/ZkClient.java
@@ -0,0 +1,277 @@
+package org.apache.helix.zookeeper.impl.client;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.exception.ZkClientException;
+import org.apache.helix.zookeeper.zkclient.IZkConnection;
+import org.apache.helix.zookeeper.zkclient.ZkConnection;
+import org.apache.helix.zookeeper.zkclient.serialize.BasicZkSerializer;
+import org.apache.helix.zookeeper.zkclient.serialize.PathBasedZkSerializer;
+import org.apache.helix.zookeeper.zkclient.serialize.SerializableSerializer;
+import org.apache.helix.zookeeper.zkclient.serialize.ZkSerializer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * "Raw ZkClient".
+ *
+ * Raw ZkClient that wraps {@link org.apache.helix.zookeeper.zkclient.ZkClient},
+ * with additional constructors and builder.
+ *
+ * Note that, instead of directly constructing a raw RealmAwareZkClient, applications should always use
+ * HelixZkClientFactory to build shared or dedicated HelixZkClient instances.
+ * Only constructing a raw RealmAwareZkClient when advanced usage is required.
+ * For example, application need to access/manage ZkConnection directly.
+ *
+ * Both SharedZKClient and DedicatedZkClient are built based on the raw RealmAwareZkClient. As shown below.
+ * ----------------------------
+ * | |
+ * --------------------- |
+ * | | | *implements
+ * SharedZkClient DedicatedZkClient ----> HelixZkClient Interface
+ * | | |
+ * --------------------- |
+ * | |
+ * Raw RealmAwareZkClient (this class)--------
+ * |
+ * Native RealmAwareZkClient
+ *
+ * TODO Completely replace usage of the raw ZkClient within helix-core. Instead, using HelixZkClient. --JJ
+ */
+
+public class ZkClient extends org.apache.helix.zookeeper.zkclient.ZkClient implements HelixZkClient {
+ private static Logger LOG = LoggerFactory.getLogger(ZkClient.class);
+
+ public static final int DEFAULT_OPERATION_TIMEOUT = Integer.MAX_VALUE;
+ public static final int DEFAULT_CONNECTION_TIMEOUT = 60 * 1000;
+ public static final int DEFAULT_SESSION_TIMEOUT = 30 * 1000;
+
+ /**
+ *
+ * @param zkConnection
+ * The Zookeeper connection
+ * @param connectionTimeout
+ * The connection timeout in milli seconds
+ * @param zkSerializer
+ * The Zookeeper data serializer
+ * @param operationRetryTimeout
+ * Most operations are retried in cases like connection loss with the Zookeeper servers. During such failures, this
+ * <code>operationRetryTimeout</code> decides the maximum amount of time, in milli seconds, each
+ * operation is retried. A value lesser than 0 is considered as
+ * "retry forever until a connection has been reestablished".
+ * @param monitorType
+ * @param monitorKey
+ * @param monitorInstanceName
+ * These 3 inputs are used to name JMX monitor bean name for this RealmAwareZkClient.
+ * The JMX bean name will be: HelixZkClient.monitorType.monitorKey.monitorInstanceName.
+ * @param monitorRootPathOnly
+ * Should only stat of access to root path be reported to JMX bean or path-specific stat be reported too.
+ */
+ public ZkClient(IZkConnection zkConnection, int connectionTimeout, long operationRetryTimeout,
+ PathBasedZkSerializer zkSerializer,
+ String monitorType, String monitorKey, String monitorInstanceName,
+ boolean monitorRootPathOnly) {
+ super(zkConnection, connectionTimeout, operationRetryTimeout, zkSerializer, monitorType,
+ monitorKey, monitorInstanceName, monitorRootPathOnly);
+ }
+
+ public ZkClient(IZkConnection connection, int connectionTimeout,
+ PathBasedZkSerializer zkSerializer,
+ String monitorType, String monitorKey, long operationRetryTimeout) {
+ this(connection, connectionTimeout, operationRetryTimeout, zkSerializer, monitorType,
+ monitorKey, null, true);
+ }
+
+ public ZkClient(IZkConnection connection, int connectionTimeout,
+ PathBasedZkSerializer zkSerializer,
+ String monitorType, String monitorKey) {
+ this(connection, connectionTimeout, zkSerializer, monitorType, monitorKey,
+ DEFAULT_OPERATION_TIMEOUT);
+ }
+
+ public ZkClient(String zkServers, String monitorType, String monitorKey) {
+ this(new ZkConnection(zkServers, DEFAULT_SESSION_TIMEOUT), Integer.MAX_VALUE,
+ new BasicZkSerializer(new SerializableSerializer()), monitorType, monitorKey);
+ }
+
+ public ZkClient(String zkServers, int sessionTimeout, int connectionTimeout,
+ PathBasedZkSerializer zkSerializer,
+ String monitorType, String monitorKey) {
+ this(new ZkConnection(zkServers, sessionTimeout), connectionTimeout, zkSerializer, monitorType,
+ monitorKey);
+ }
+
+ public ZkClient(IZkConnection connection, int connectionTimeout,
+ PathBasedZkSerializer zkSerializer) {
+ this(connection, connectionTimeout, zkSerializer, null, null);
+ }
+
+ public ZkClient(IZkConnection connection, int connectionTimeout, ZkSerializer zkSerializer) {
+ this(connection, connectionTimeout, new BasicZkSerializer(zkSerializer));
+ }
+
+ public ZkClient(IZkConnection connection, int connectionTimeout) {
+ this(connection, connectionTimeout, new SerializableSerializer());
+ }
+
+ public ZkClient(IZkConnection connection) {
+ this(connection, Integer.MAX_VALUE, new SerializableSerializer());
+ }
+
+ public ZkClient(String zkServers, int sessionTimeout, int connectionTimeout,
+ ZkSerializer zkSerializer) {
+ this(new ZkConnection(zkServers, sessionTimeout), connectionTimeout, zkSerializer);
+ }
+
+ public ZkClient(String zkServers, int sessionTimeout, int connectionTimeout,
+ PathBasedZkSerializer zkSerializer) {
+ this(new ZkConnection(zkServers, sessionTimeout), connectionTimeout, zkSerializer);
+ }
+
+ public ZkClient(String zkServers, int sessionTimeout, int connectionTimeout) {
+ this(new ZkConnection(zkServers, sessionTimeout), connectionTimeout,
+ new SerializableSerializer());
+ }
+
+ public ZkClient(String zkServers, int connectionTimeout) {
+ this(new ZkConnection(zkServers, DEFAULT_SESSION_TIMEOUT), connectionTimeout,
+ new SerializableSerializer());
+ }
+
+ public ZkClient(String zkServers) {
+ this(zkServers, null, null);
+ }
+
+ public ZkClient(final String zkServers, final int sessionTimeout, final int connectionTimeout,
+ final ZkSerializer zkSerializer, final long operationRetryTimeout) {
+ this(new ZkConnection(zkServers, sessionTimeout), connectionTimeout, zkSerializer,
+ operationRetryTimeout);
+ }
+
+ public ZkClient(final IZkConnection zkConnection, final int connectionTimeout,
+ final ZkSerializer zkSerializer, final long operationRetryTimeout) {
+ this(zkConnection, connectionTimeout, operationRetryTimeout,
+ new BasicZkSerializer(zkSerializer), null, null, null, false);
+ }
+
+ public static class Builder {
+ IZkConnection _connection;
+ String _zkServer;
+
+ PathBasedZkSerializer _zkSerializer;
+
+ long _operationRetryTimeout = DEFAULT_OPERATION_TIMEOUT;
+ int _connectionTimeout = DEFAULT_CONNECTION_TIMEOUT;
+ int _sessionTimeout = DEFAULT_SESSION_TIMEOUT;
+
+ String _monitorType;
+ String _monitorKey;
+ String _monitorInstanceName = null;
+ boolean _monitorRootPathOnly = true;
+
+ public Builder setConnection(IZkConnection connection) {
+ this._connection = connection;
+ return this;
+ }
+
+ public Builder setConnectionTimeout(Integer connectionTimeout) {
+ this._connectionTimeout = connectionTimeout;
+ return this;
+ }
+
+ public Builder setZkSerializer(
+ PathBasedZkSerializer zkSerializer) {
+ this._zkSerializer = zkSerializer;
+ return this;
+ }
+
+ public Builder setZkSerializer(ZkSerializer zkSerializer) {
+ this._zkSerializer = new BasicZkSerializer(zkSerializer);
+ return this;
+ }
+
+ /**
+ * Used as part of the MBean ObjectName. This item is required for enabling monitoring.
+ * @param monitorType
+ */
+ public Builder setMonitorType(String monitorType) {
+ this._monitorType = monitorType;
+ return this;
+ }
+
+ /**
+ * Used as part of the MBean ObjectName. This item is required for enabling monitoring.
+ * @param monitorKey
+ */
+ public Builder setMonitorKey(String monitorKey) {
+ this._monitorKey = monitorKey;
+ return this;
+ }
+
+ /**
+ * Used as part of the MBean ObjectName. This item is optional.
+ * @param instanceName
+ */
+ public Builder setMonitorInstanceName(String instanceName) {
+ this._monitorInstanceName = instanceName;
+ return this;
+ }
+
+ public Builder setMonitorRootPathOnly(Boolean monitorRootPathOnly) {
+ this._monitorRootPathOnly = monitorRootPathOnly;
+ return this;
+ }
+
+ public Builder setZkServer(String zkServer) {
+ this._zkServer = zkServer;
+ return this;
+ }
+
+ public Builder setSessionTimeout(Integer sessionTimeout) {
+ this._sessionTimeout = sessionTimeout;
+ return this;
+ }
+
+ public Builder setOperationRetryTimeout(Long operationRetryTimeout) {
+ this._operationRetryTimeout = operationRetryTimeout;
+ return this;
+ }
+
+ public ZkClient build() {
+ if (_connection == null) {
+ if (_zkServer == null) {
+ throw new ZkClientException(
+ "Failed to build ZkClient since no connection or ZK server address is specified.");
+ } else {
+ _connection = new ZkConnection(_zkServer, _sessionTimeout);
+ }
+ }
+
+ if (_zkSerializer == null) {
+ _zkSerializer = new BasicZkSerializer(new SerializableSerializer());
+ }
+
+ return new ZkClient(_connection, _connectionTimeout, _operationRetryTimeout, _zkSerializer,
+ _monitorType, _monitorKey, _monitorInstanceName, _monitorRootPathOnly);
+ }
+ }
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/impl/factory/DedicatedZkClientFactory.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/impl/factory/DedicatedZkClientFactory.java
new file mode 100644
index 0000000..90ecf9b
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/impl/factory/DedicatedZkClientFactory.java
@@ -0,0 +1,57 @@
+package org.apache.helix.zookeeper.impl.factory;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
+
+
+/**
+ * Singleton factory that build dedicated clients using the raw ZkClient.
+ */
+public class DedicatedZkClientFactory extends HelixZkClientFactory {
+
+ protected DedicatedZkClientFactory() {
+ }
+
+ private static class SingletonHelper {
+ private static final DedicatedZkClientFactory INSTANCE = new DedicatedZkClientFactory();
+ }
+
+ public static DedicatedZkClientFactory getInstance() {
+ return SingletonHelper.INSTANCE;
+ }
+
+ /**
+ * Build a Dedicated ZkClient based on connection config and client config
+ *
+ * @param connectionConfig
+ * @param clientConfig
+ * @return
+ */
+ @Override
+ public HelixZkClient buildZkClient(HelixZkClient.ZkConnectionConfig connectionConfig,
+ HelixZkClient.ZkClientConfig clientConfig) {
+ return new ZkClient(createZkConnection(connectionConfig),
+ (int) clientConfig.getConnectInitTimeout(), clientConfig.getOperationRetryTimeout(),
+ clientConfig.getZkSerializer(), clientConfig.getMonitorType(), clientConfig.getMonitorKey(),
+ clientConfig.getMonitorInstanceName(), clientConfig.isMonitorRootPathOnly());
+ }
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/impl/factory/HelixZkClientFactory.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/impl/factory/HelixZkClientFactory.java
new file mode 100644
index 0000000..9e1ca6e
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/impl/factory/HelixZkClientFactory.java
@@ -0,0 +1,68 @@
+package org.apache.helix.zookeeper.impl.factory;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.exception.ZkClientException;
+import org.apache.helix.zookeeper.zkclient.IZkConnection;
+import org.apache.helix.zookeeper.zkclient.ZkConnection;
+
+
+/**
+ * Abstract class of the ZkClient factory.
+ */
+abstract class HelixZkClientFactory {
+
+ /**
+ * Build a ZkClient using specified connection config and client config
+ *
+ * @param connectionConfig
+ * @param clientConfig
+ * @return HelixZkClient
+ */
+ public abstract HelixZkClient buildZkClient(HelixZkClient.ZkConnectionConfig connectionConfig,
+ HelixZkClient.ZkClientConfig clientConfig);
+
+ /**
+ * Build a ZkClient using specified connection config and default client config
+ *
+ * @param connectionConfig
+ * @return HelixZkClient
+ */
+ public HelixZkClient buildZkClient(HelixZkClient.ZkConnectionConfig connectionConfig) {
+ return buildZkClient(connectionConfig, new HelixZkClient.ZkClientConfig());
+ }
+
+ /**
+ * Construct a new ZkConnection instance based on connection configuration.
+ * Note that the connection is not really made until someone calls zkConnection.connect().
+ * @param connectionConfig
+ * @return
+ */
+ protected IZkConnection createZkConnection(HelixZkClient.ZkConnectionConfig connectionConfig) {
+ if (connectionConfig.getZkServers() == null) {
+ throw new ZkClientException(
+ "Failed to build ZkClient since no connection or ZK server address is specified.");
+ } else {
+ return new ZkConnection(connectionConfig.getZkServers(),
+ connectionConfig.getSessionTimeout());
+ }
+ }
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/impl/factory/SharedZkClientFactory.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/impl/factory/SharedZkClientFactory.java
new file mode 100644
index 0000000..bf9d9a1
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/impl/factory/SharedZkClientFactory.java
@@ -0,0 +1,111 @@
+package org.apache.helix.zookeeper.impl.factory;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.HashMap;
+
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.exception.ZkClientException;
+import org.apache.helix.zookeeper.impl.client.SharedZkClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Singleton factory that build shared ZkClient which use a shared ZkConnection.
+ */
+public class SharedZkClientFactory extends HelixZkClientFactory {
+ private static Logger LOG = LoggerFactory.getLogger(SharedZkClientFactory.class);
+ // The connection pool to track all created connections.
+ private final HashMap<HelixZkClient.ZkConnectionConfig, ZkConnectionManager>
+ _connectionManagerPool = new HashMap<>();
+
+ protected SharedZkClientFactory() {
+ }
+
+ private static class SingletonHelper {
+ private static final SharedZkClientFactory INSTANCE = new SharedZkClientFactory();
+ }
+
+ public static SharedZkClientFactory getInstance() {
+ return SingletonHelper.INSTANCE;
+ }
+
+ /**
+ * Build a Shared ZkClient that uses sharing ZkConnection that is created based on the specified connection config.
+ *
+ * @param connectionConfig The connection configuration that is used to search for a shared connection. Or create new connection if necessary.
+ * @param clientConfig
+ * @return Shared ZkClient
+ */
+ @Override
+ public HelixZkClient buildZkClient(HelixZkClient.ZkConnectionConfig connectionConfig,
+ HelixZkClient.ZkClientConfig clientConfig) {
+ synchronized (_connectionManagerPool) {
+ final ZkConnectionManager zkConnectionManager =
+ getOrCreateZkConnectionManager(connectionConfig, clientConfig.getConnectInitTimeout());
+ if (zkConnectionManager == null) {
+ throw new ZkClientException("Failed to create a connection manager in the pool to share.");
+ }
+ LOG.info("Sharing ZkConnection {} to a new SharedZkClient.", connectionConfig.toString());
+ return new SharedZkClient(zkConnectionManager, clientConfig,
+ new SharedZkClient.OnCloseCallback() {
+ @Override
+ public void onClose() {
+ cleanupConnectionManager(zkConnectionManager);
+ }
+ });
+ }
+ }
+
+ private ZkConnectionManager getOrCreateZkConnectionManager(
+ HelixZkClient.ZkConnectionConfig connectionConfig, long connectInitTimeout) {
+ ZkConnectionManager connectionManager = _connectionManagerPool.get(connectionConfig);
+ if (connectionManager == null || connectionManager.isClosed()) {
+ connectionManager =
+ new ZkConnectionManager(createZkConnection(connectionConfig), connectInitTimeout,
+ connectionConfig.toString());
+ _connectionManagerPool.put(connectionConfig, connectionManager);
+ }
+ return connectionManager;
+ }
+
+ // Close the ZkConnectionManager if no other shared client is referring to it.
+ // Note the close operation of connection manager needs to be synchronized with the pool operation
+ // to avoid race condition.
+ private void cleanupConnectionManager(ZkConnectionManager zkConnectionManager) {
+ synchronized (_connectionManagerPool) {
+ zkConnectionManager.close(true);
+ }
+ }
+
+ // For testing purposes only
+ public int getActiveConnectionCount() {
+ int count = 0;
+ synchronized (_connectionManagerPool) {
+ for (ZkConnectionManager manager : _connectionManagerPool.values()) {
+ if (!manager.isClosed()) {
+ count++;
+ }
+ }
+ }
+ return count;
+ }
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/impl/factory/ZkConnectionManager.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/impl/factory/ZkConnectionManager.java
new file mode 100644
index 0000000..1413111
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/impl/factory/ZkConnectionManager.java
@@ -0,0 +1,145 @@
+package org.apache.helix.zookeeper.impl.factory;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.helix.zookeeper.api.client.HelixZkClient;
+import org.apache.helix.zookeeper.impl.client.SharedZkClient;
+import org.apache.helix.zookeeper.impl.client.ZkClient;
+import org.apache.helix.zookeeper.exception.ZkClientException;
+import org.apache.helix.zookeeper.zkclient.IZkConnection;
+import org.apache.helix.zookeeper.zkclient.serialize.BasicZkSerializer;
+import org.apache.helix.zookeeper.zkclient.serialize.SerializableSerializer;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * NOTE: DO NOT USE THIS CLASS DIRECTLY. Use ZkClientFactories instead.
+ *
+ * A ZkConnection manager that maintain connection status and allows additional watchers to be registered.
+ * It will forward events to those watchers.
+ *
+ * TODO Separate connection management logic from the raw ZkClient class.
+ * So this manager is a peer to the HelixZkClient. Connection Manager for maintaining the connection and
+ * HelixZkClient to handle user request.
+ * After this is done, Dedicated HelixZkClient hires one manager for it's connection.
+ * While multiple Shared ZkClients can use single connection manager if possible.
+ */
+public class ZkConnectionManager extends ZkClient {
+ private static Logger LOG = LoggerFactory.getLogger(ZkConnectionManager.class);
+ // Client type that is used in monitor, and metrics.
+ private final static String MONITOR_TYPE = "ZkConnectionManager";
+ private final String _monitorKey;
+ // Set of all registered watchers
+ protected final Set<Watcher> _sharedWatchers = new HashSet<>();
+
+ /**
+ * Construct and init a ZkConnection Manager.
+ *
+ * @param zkConnection
+ * @param connectionTimeout
+ */
+ protected ZkConnectionManager(IZkConnection zkConnection, long connectionTimeout,
+ String monitorKey) {
+ super(zkConnection, (int) connectionTimeout, HelixZkClient.DEFAULT_OPERATION_TIMEOUT,
+ new BasicZkSerializer(new SerializableSerializer()), MONITOR_TYPE, monitorKey, null, true);
+ _monitorKey = monitorKey;
+ LOG.info("ZkConnection {} was created for sharing.", _monitorKey);
+ }
+
+ /**
+ * Register event watcher.
+ *
+ * @param watcher
+ * @return true if the watcher is newly added. false if it is already in record.
+ */
+ public synchronized boolean registerWatcher(Watcher watcher) {
+ if (isClosed()) {
+ throw new ZkClientException("Cannot add watcher to a closed client.");
+ }
+ return _sharedWatchers.add(watcher);
+ }
+
+ /**
+ * Unregister the event watcher.
+ *
+ * @param watcher
+ * @return number of the remaining event watchers
+ */
+ public synchronized int unregisterWatcher(Watcher watcher) {
+ _sharedWatchers.remove(watcher);
+ return _sharedWatchers.size();
+ }
+
+ @Override
+ public void process(final WatchedEvent event) {
+ super.process(event);
+ forwardingEvent(event);
+ }
+
+ private synchronized void forwardingEvent(final WatchedEvent event) {
+ // note that process (then forwardingEvent) could be triggered during construction, when sharedWatchers is still null.
+ if (_sharedWatchers == null || _sharedWatchers.isEmpty()) {
+ return;
+ }
+ // forward event to all the watchers' event queue
+ for (final Watcher watcher : _sharedWatchers) {
+ watcher.process(event);
+ }
+ }
+
+ @Override
+ public void close() {
+ // Enforce closing, if any watcher exists, throw Exception.
+ close(false);
+ }
+
+ protected synchronized void close(boolean skipIfWatched) {
+ cleanupInactiveWatchers();
+ if (_sharedWatchers.size() > 0) {
+ if (skipIfWatched) {
+ LOG.debug("Skip closing ZkConnection due to existing watchers. Watcher count {}.",
+ _sharedWatchers.size());
+ return;
+ } else {
+ throw new ZkClientException(
+ "Cannot close the connection when there are still shared watchers listen on the event.");
+ }
+ }
+ super.close();
+ LOG.info("ZkConnection {} was closed.", _monitorKey);
+ }
+
+ protected void cleanupInactiveWatchers() {
+ Set<Watcher> closedWatchers = new HashSet<>();
+ for (Watcher watcher : _sharedWatchers) {
+ // TODO ideally, we shall have a ClosableWatcher interface so as to check accordingly. -- JJ
+ if (watcher instanceof SharedZkClient && ((SharedZkClient) watcher).isClosed()) {
+ closedWatchers.add(watcher);
+ }
+ }
+ _sharedWatchers.removeAll(closedWatchers);
+ }
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/util/GZipCompressionUtil.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/util/GZipCompressionUtil.java
new file mode 100644
index 0000000..a87ef37
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/util/GZipCompressionUtil.java
@@ -0,0 +1,74 @@
+package org.apache.helix.zookeeper.util;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+
+
+public class GZipCompressionUtil {
+ /**
+ * Compresses a byte array by applying GZIP compression
+ * @param buffer
+ * @return
+ * @throws IOException
+ */
+ public static byte[] compress(byte[] buffer) throws IOException {
+ ByteArrayOutputStream gzipByteArrayOutputStream = new ByteArrayOutputStream();
+ GZIPOutputStream gzipOutputStream = null;
+ gzipOutputStream = new GZIPOutputStream(gzipByteArrayOutputStream);
+ gzipOutputStream.write(buffer, 0, buffer.length);
+ gzipOutputStream.close();
+ byte[] compressedBytes = gzipByteArrayOutputStream.toByteArray();
+ return compressedBytes;
+ }
+
+ public static byte[] uncompress(ByteArrayInputStream bais) throws IOException {
+ GZIPInputStream gzipInputStream = new GZIPInputStream(bais);
+ byte[] buffer = new byte[1024];
+ int length;
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ while ((length = gzipInputStream.read(buffer)) != -1) {
+ baos.write(buffer, 0, length);
+ }
+ gzipInputStream.close();
+ baos.close();
+ byte[] uncompressedBytes = baos.toByteArray();
+ return uncompressedBytes;
+ }
+
+ /*
+ * Determines if a byte array is compressed. The java.util.zip GZip
+ * implementaiton does not expose the GZip header so it is difficult to determine
+ * if a string is compressed.
+ * @param bytes an array of bytes
+ * @return true if the array is compressed or false otherwise
+ */
+ public static boolean isCompressed(byte[] bytes) {
+ if ((bytes == null) || (bytes.length < 2)) {
+ return false;
+ } else {
+ return ((bytes[0] == (byte) (GZIPInputStream.GZIP_MAGIC)) && (bytes[1] == (byte) (GZIPInputStream.GZIP_MAGIC >> 8)));
+ }
+ }
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/DataUpdater.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/DataUpdater.java
new file mode 100644
index 0000000..db9a35b
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/DataUpdater.java
@@ -0,0 +1,34 @@
+/**
+ * Copyright 2010 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.zookeeper.zkclient;
+
+/**
+ * Updates the data of a znode. This is used together with {@link ZkClient#updateDataSerialized(String, DataUpdater)}.
+ *
+ * @param <T>
+ */
+public interface DataUpdater<T extends Object> {
+
+ /**
+ * Updates the current data of a znode.
+ *
+ * @param currentData
+ * The current contents.
+ * @return the new data that should be written back to ZooKeeper.
+ */
+ public T update(T currentData);
+
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/ExceptionUtil.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/ExceptionUtil.java
new file mode 100644
index 0000000..9b575d8
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/ExceptionUtil.java
@@ -0,0 +1,52 @@
+/**
+ * Copyright 2010 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.zookeeper.zkclient;
+
+import org.apache.helix.zookeeper.zkclient.exception.ZkInterruptedException;
+
+
+public class ExceptionUtil {
+
+ public static RuntimeException convertToRuntimeException(Throwable e) {
+ if (e instanceof RuntimeException) {
+ return (RuntimeException) e;
+ }
+ retainInterruptFlag(e);
+ return new RuntimeException(e);
+ }
+
+ /**
+ * This sets the interrupt flag if the catched exception was an {@link InterruptedException}. Catching such an
+ * exception always clears the interrupt flag.
+ *
+ * @param catchedException
+ * The catched exception.
+ */
+ public static void retainInterruptFlag(Throwable catchedException) {
+ if (catchedException instanceof InterruptedException) {
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ public static void rethrowInterruptedException(Throwable e) throws InterruptedException {
+ if (e instanceof InterruptedException) {
+ throw (InterruptedException) e;
+ }
+ if (e instanceof ZkInterruptedException) {
+ throw (ZkInterruptedException) e;
+ }
+ }
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/IDefaultNameSpace.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/IDefaultNameSpace.java
new file mode 100644
index 0000000..46a9461
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/IDefaultNameSpace.java
@@ -0,0 +1,27 @@
+/**
+ * Copyright 2010 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.zookeeper.zkclient;
+
+public interface IDefaultNameSpace {
+
+ /**
+ * Creates a set of default folder structure within a zookeeper .
+ *
+ * @param zkClient
+ * The zkclient.
+ */
+ public void createDefaultNameSpace(ZkClient zkClient);
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/IZkChildListener.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/IZkChildListener.java
new file mode 100644
index 0000000..351f305
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/IZkChildListener.java
@@ -0,0 +1,41 @@
+/**
+ * Copyright 2010 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.zookeeper.zkclient;
+
+import java.util.List;
+
+/**
+ * An {@link IZkChildListener} can be registered at a {@link ZkClient} for listening on zk child changes for a given
+ * path.
+ *
+ * Node: Also this listener re-subscribes it watch for the path on each zk event (zk watches are one-timers) is is not
+ * guaranteed that events on the path are missing (see http://zookeeper.wiki.sourceforge.net/ZooKeeperWatches). An
+ * implementation of this class should take that into account.
+ *
+ */
+public interface IZkChildListener {
+
+ /**
+ * Called when the children of the given path changed.
+ *
+ * @param parentPath
+ * The parent path
+ * @param currentChilds
+ * The children or null if the root node (parent path) was deleted.
+ * @throws Exception
+ */
+ public void handleChildChange(String parentPath, List<String> currentChilds) throws Exception;
+}
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
new file mode 100644
index 0000000..6370c95
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/IZkConnection.java
@@ -0,0 +1,60 @@
+/**
+ * Copyright 2010 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.zookeeper.zkclient;
+
+import java.util.List;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.Op;
+import org.apache.zookeeper.OpResult;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.ZooKeeper.States;
+import org.apache.zookeeper.data.ACL;
+import org.apache.zookeeper.data.Stat;
+
+public interface IZkConnection {
+
+ public void connect(Watcher watcher);
+
+ void close() throws InterruptedException;
+
+ public String create(String path, byte[] data, CreateMode mode) throws KeeperException, InterruptedException;
+
+ public String create(String path, byte[] data, List<ACL> acl, CreateMode mode) throws KeeperException, InterruptedException;
+
+ public void delete(String path) throws InterruptedException, KeeperException;
+
+ boolean exists(final String path, final boolean watch) throws KeeperException, InterruptedException;
+
+ List<String> getChildren(final String path, final boolean watch) throws KeeperException, InterruptedException;
+
+ public byte[] readData(String path, Stat stat, boolean watch) throws KeeperException, InterruptedException;
+
+ public void writeData(String path, byte[] data, int expectedVersion) throws KeeperException, InterruptedException;
+
+ public Stat writeDataReturnStat(String path, byte[] data, int expectedVersion) throws KeeperException, InterruptedException;
+
+ public States getZookeeperState();
+
+ public long getCreateTime(String path) throws KeeperException, InterruptedException;
+
+ public String getServers();
+
+ public List<OpResult> multi(Iterable<Op> ops) throws KeeperException, InterruptedException;
+
+ public void addAuthInfo(String scheme, byte[] auth);
+}
\ No newline at end of file
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/IZkDataListener.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/IZkDataListener.java
new file mode 100644
index 0000000..c7fb7dd
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/IZkDataListener.java
@@ -0,0 +1,30 @@
+/**
+ * Copyright 2010 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.zookeeper.zkclient;
+
+/**
+ * An {@link IZkDataListener} can be registered at a {@link ZkClient} for listening on zk data changes for a given path.
+ *
+ * Node: Also this listener re-subscribes it watch for the path on each zk event (zk watches are one-timers) is is not
+ * guaranteed that events on the path are missing (see http://zookeeper.wiki.sourceforge.net/ZooKeeperWatches). An
+ * implementation of this class should take that into account.
+ */
+public interface IZkDataListener {
+
+ public void handleDataChange(String dataPath, Object data) throws Exception;
+
+ public void handleDataDeleted(String dataPath) throws Exception;
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/IZkStateListener.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/IZkStateListener.java
new file mode 100644
index 0000000..5970e62
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/IZkStateListener.java
@@ -0,0 +1,61 @@
+package org.apache.helix.zookeeper.zkclient;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+
+
+public interface IZkStateListener {
+
+ /**
+ * Called when the zookeeper connection state has changed.
+ *
+ * @param state the new zookeeper state.
+ * @throws Exception if any error occurs.
+ */
+ void handleStateChanged(KeeperState state) throws Exception;
+
+ /**
+ * Called after the zookeeper session has expired and a new session has been created. The new
+ * session id has to be passed in as the parameter.
+ * And you would have to re-create any ephemeral nodes here. This is a session aware operation.
+ * The ephemeral nodes have to be created within the expected session id, which means passed-in
+ * session id has to be checked with current zookeeper's session id. If the passed-in session id
+ * does not match current zookeeper's session id, ephemeral nodes should not be created.
+ * Otherwise, session race condition may occur and the newly created ephemeral nodes may not be in
+ * the expected session.
+ *
+ * @param sessionId the new session's id. The ephemeral nodes are expected to be created in this
+ * session. If this session id is expired, ephemeral nodes should not be created.
+ * @throws Exception if any error occurs.
+ */
+ void handleNewSession(final String sessionId) throws Exception;
+
+ /**
+ * Called when a session cannot be re-established. This should be used to implement connection
+ * failure handling e.g. retry to connect or pass the error up
+ *
+ * @param error
+ * The error that prevents a session from being established
+ * @throws Exception
+ * On any error.
+ */
+ void handleSessionEstablishmentError(final Throwable error) throws Exception;
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/NetworkUtil.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/NetworkUtil.java
new file mode 100644
index 0000000..f31a130
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/NetworkUtil.java
@@ -0,0 +1,122 @@
+/**
+ * Copyright 2010 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.zookeeper.zkclient;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.Socket;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Set;
+
+public class NetworkUtil {
+
+ public final static String OVERWRITE_HOSTNAME_SYSTEM_PROPERTY = "zkclient.hostname.overwritten";
+
+ public static String[] getLocalHostNames() {
+ final Set<String> hostNames = new HashSet<String>();
+ // we add localhost to this set manually, because if the ip 127.0.0.1 is
+ // configured with more than one name in the /etc/hosts, only the first
+ // name
+ // is returned
+ hostNames.add("localhost");
+ try {
+ final Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
+ for (final Enumeration<NetworkInterface> ifaces = networkInterfaces; ifaces.hasMoreElements();) {
+ final NetworkInterface iface = ifaces.nextElement();
+ InetAddress ia = null;
+ for (final Enumeration<InetAddress> ips = iface.getInetAddresses(); ips.hasMoreElements();) {
+ ia = ips.nextElement();
+ hostNames.add(ia.getCanonicalHostName());
+ hostNames.add(ipToString(ia.getAddress()));
+ }
+ }
+ } catch (final SocketException e) {
+ throw new RuntimeException("unable to retrieve host names of localhost");
+ }
+ return hostNames.toArray(new String[hostNames.size()]);
+ }
+
+ private static String ipToString(final byte[] bytes) {
+ final StringBuffer addrStr = new StringBuffer();
+ for (int cnt = 0; cnt < bytes.length; cnt++) {
+ final int uByte = bytes[cnt] < 0 ? bytes[cnt] + 256 : bytes[cnt];
+ addrStr.append(uByte);
+ if (cnt < 3)
+ addrStr.append('.');
+ }
+ return addrStr.toString();
+ }
+
+ public static int hostNamesInList(final String serverList, final String[] hostNames) {
+ final String[] serverNames = serverList.split(",");
+ for (int i = 0; i < hostNames.length; i++) {
+ final String hostname = hostNames[i];
+ for (int j = 0; j < serverNames.length; j++) {
+ final String serverNameAndPort = serverNames[j];
+ final String serverName = serverNameAndPort.split(":")[0];
+ if (serverName.equalsIgnoreCase(hostname)) {
+ return j;
+ }
+ }
+ }
+ return -1;
+ }
+
+ public static boolean hostNameInArray(final String[] hostNames, final String hostName) {
+ for (final String name : hostNames) {
+ if (name.equalsIgnoreCase(hostName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static boolean isPortFree(int port) {
+ try {
+ Socket socket = new Socket("localhost", port);
+ socket.close();
+ return false;
+ } catch (ConnectException e) {
+ return true;
+ } catch (SocketException e) {
+ if (e.getMessage().equals("Connection reset by peer")) {
+ return true;
+ }
+ throw new RuntimeException(e);
+ } catch (UnknownHostException e) {
+ throw new RuntimeException(e);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static String getLocalhostName() {
+ String property = System.getProperty(OVERWRITE_HOSTNAME_SYSTEM_PROPERTY);
+ if (property != null && property.trim().length() > 0) {
+ return property;
+ }
+ try {
+ return InetAddress.getLocalHost().getHostName();
+ } catch (final UnknownHostException e) {
+ throw new RuntimeException("unable to retrieve localhost name");
+ }
+ }
+}
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
new file mode 100644
index 0000000..0507c3f
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/ZkClient.java
@@ -0,0 +1,2172 @@
+/**
+ * Copyright 2010 the original author or authors.
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.helix.zookeeper.zkclient;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.OptionalLong;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.TimeUnit;
+import javax.management.JMException;
+
+import org.apache.helix.zookeeper.datamodel.ZNRecord;
+import org.apache.helix.zookeeper.exception.ZkClientException;
+import org.apache.helix.zookeeper.zkclient.exception.ZkBadVersionException;
+import org.apache.helix.zookeeper.zkclient.exception.ZkException;
+import org.apache.helix.zookeeper.zkclient.exception.ZkInterruptedException;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNoNodeException;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNodeExistsException;
+import org.apache.helix.zookeeper.zkclient.exception.ZkTimeoutException;
+import org.apache.helix.zookeeper.zkclient.serialize.ZkSerializer;
+import org.apache.helix.zookeeper.zkclient.annotation.PreFetch;
+import org.apache.helix.zookeeper.zkclient.serialize.BasicZkSerializer;
+import org.apache.helix.zookeeper.zkclient.serialize.PathBasedZkSerializer;
+import org.apache.helix.zookeeper.zkclient.callback.ZkAsyncCallbacks;
+import org.apache.helix.zookeeper.zkclient.exception.ZkSessionMismatchedException;
+import org.apache.helix.zookeeper.zkclient.metric.ZkClientMonitor;
+import org.apache.helix.zookeeper.zkclient.util.ExponentialBackoffStrategy;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.KeeperException.ConnectionLossException;
+import org.apache.zookeeper.KeeperException.SessionExpiredException;
+import org.apache.zookeeper.Op;
+import org.apache.zookeeper.OpResult;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.Watcher.Event.EventType;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.zookeeper.ZooDefs;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.data.ACL;
+import org.apache.zookeeper.data.Stat;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * "Native ZkClient": not to be used directly.
+ *
+ * Abstracts the interaction with zookeeper and allows permanent (not just one time) watches on
+ * nodes in ZooKeeper.
+ * WARN: Do not use this class directly, use {@link org.apache.helix.zookeeper.impl.client.ZkClient} instead.
+ */
+public class ZkClient implements Watcher {
+ private static Logger LOG = LoggerFactory.getLogger(ZkClient.class);
+ private static long MAX_RECONNECT_INTERVAL_MS = 30000; // 30 seconds
+
+ private final IZkConnection _connection;
+ private final long _operationRetryTimeoutInMillis;
+ private final Map<String, Set<IZkChildListener>> _childListener = new ConcurrentHashMap<>();
+ private final ConcurrentHashMap<String, Set<IZkDataListenerEntry>> _dataListener =
+ new ConcurrentHashMap<>();
+ private final Set<IZkStateListener> _stateListener = new CopyOnWriteArraySet<>();
+ private KeeperState _currentState;
+ private final ZkLock _zkEventLock = new ZkLock();
+
+ // When a new zookeeper instance is created in reconnect, its session id is not yet valid before
+ // the zookeeper session is established(SyncConnected). To avoid session race condition in
+ // handling new session, the new session event is only fired after SyncConnected. Meanwhile,
+ // SyncConnected state is also received when re-opening the zk connection. So to avoid firing
+ // new session event more than once, this flag is used to check.
+ // It is set to false right after the new zookeeper instance is created in reconnect before the
+ // session is established. And set it to true once the new session event is fired the first time.
+ private boolean _isNewSessionEventFired;
+
+ private boolean _shutdownTriggered;
+ private ZkEventThread _eventThread;
+ // TODO PVo remove this later
+ private Thread _zookeeperEventThread;
+ private volatile boolean _closed;
+ private PathBasedZkSerializer _pathBasedZkSerializer;
+ private ZkClientMonitor _monitor;
+
+ private class IZkDataListenerEntry {
+ final IZkDataListener _dataListener;
+ final boolean _prefetchData;
+
+ public IZkDataListenerEntry(IZkDataListener dataListener, boolean prefetchData) {
+ _dataListener = dataListener;
+ _prefetchData = prefetchData;
+ }
+
+ public IZkDataListenerEntry(IZkDataListener dataListener) {
+ _dataListener = dataListener;
+ _prefetchData = false;
+ }
+
+ public IZkDataListener getDataListener() {
+ return _dataListener;
+ }
+
+ public boolean isPrefetchData() {
+ return _prefetchData;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof IZkDataListenerEntry)) {
+ return false;
+ }
+
+ IZkDataListenerEntry that = (IZkDataListenerEntry) o;
+
+ return _dataListener.equals(that._dataListener);
+ }
+
+ @Override
+ public int hashCode() {
+ return _dataListener.hashCode();
+ }
+ }
+
+ private class ZkPathStatRecord {
+ private final String _path;
+ private Stat _stat = null;
+ private boolean _checked = false;
+
+ public ZkPathStatRecord(String path) {
+ _path = path;
+ }
+
+ public boolean pathExists() {
+ return _stat != null;
+ }
+
+ public boolean pathChecked() {
+ return _checked;
+ }
+
+ /*
+ * Note this method is not thread safe.
+ */
+ public void recordPathStat(Stat stat, OptionalLong notificationTime) {
+ _checked = true;
+ _stat = stat;
+
+ if (_monitor != null && stat != null && notificationTime.isPresent()) {
+ long updateTime = Math.max(stat.getCtime(), stat.getMtime());
+ if (notificationTime.getAsLong() > updateTime) {
+ _monitor.recordDataPropagationLatency(_path, notificationTime.getAsLong() - updateTime);
+ } // else, the node was updated again after the notification. Propagation latency is
+ // unavailable.
+ }
+ }
+ }
+
+ protected ZkClient(IZkConnection zkConnection, int connectionTimeout, long operationRetryTimeout,
+ PathBasedZkSerializer zkSerializer, String monitorType, String monitorKey,
+ String monitorInstanceName, boolean monitorRootPathOnly) {
+ if (zkConnection == null) {
+ throw new NullPointerException("Zookeeper connection is null!");
+ }
+ _connection = zkConnection;
+ _pathBasedZkSerializer = zkSerializer;
+ _operationRetryTimeoutInMillis = operationRetryTimeout;
+ _isNewSessionEventFired = false;
+
+ connect(connectionTimeout, this);
+
+ // initiate monitor
+ try {
+ if (monitorKey != null && !monitorKey.isEmpty() && monitorType != null && !monitorType
+ .isEmpty()) {
+ _monitor =
+ new ZkClientMonitor(monitorType, monitorKey, monitorInstanceName, monitorRootPathOnly,
+ _eventThread);
+ _monitor.register();
+ } else {
+ LOG.info("ZkClient monitor key or type is not provided. Skip monitoring.");
+ }
+ } catch (JMException e) {
+ LOG.error("Error in creating ZkClientMonitor", e);
+ }
+ }
+
+ public List<String> subscribeChildChanges(String path, IZkChildListener listener) {
+ synchronized (_childListener) {
+ Set<IZkChildListener> listeners = _childListener.get(path);
+ if (listeners == null) {
+ listeners = new CopyOnWriteArraySet<>();
+ _childListener.put(path, listeners);
+ }
+ listeners.add(listener);
+ }
+ return watchForChilds(path);
+ }
+
+ public void unsubscribeChildChanges(String path, IZkChildListener childListener) {
+ synchronized (_childListener) {
+ final Set<IZkChildListener> listeners = _childListener.get(path);
+ if (listeners != null) {
+ listeners.remove(childListener);
+ }
+ }
+ }
+
+ /**
+ * Subscribe the path and the listener will handle data events of the path
+ * WARNING: if the path is created after deletion, users need to re-subscribe the path
+ * @param path The zookeeper path
+ * @param listener Instance of {@link IZkDataListener}
+ */
+ public void subscribeDataChanges(String path, IZkDataListener listener) {
+ Set<IZkDataListenerEntry> listenerEntries;
+ synchronized (_dataListener) {
+ listenerEntries = _dataListener.get(path);
+ if (listenerEntries == null) {
+ listenerEntries = new CopyOnWriteArraySet<>();
+ _dataListener.put(path, listenerEntries);
+ }
+
+ boolean prefetchEnabled = isPrefetchEnabled(listener);
+ IZkDataListenerEntry listenerEntry = new IZkDataListenerEntry(listener, prefetchEnabled);
+ listenerEntries.add(listenerEntry);
+ if (prefetchEnabled) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Subscribed data changes for " + path + ", listener: " + listener
+ + ", prefetch data: " + prefetchEnabled);
+ }
+ }
+ }
+ watchForData(path);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Subscribed data changes for " + path);
+ }
+ }
+
+ private boolean isPrefetchEnabled(IZkDataListener dataListener) {
+ PreFetch preFetch = dataListener.getClass().getAnnotation(PreFetch.class);
+ if (preFetch != null) {
+ return preFetch.enabled();
+ }
+
+ Method callbackMethod = IZkDataListener.class.getMethods()[0];
+ try {
+ Method method = dataListener.getClass()
+ .getMethod(callbackMethod.getName(), callbackMethod.getParameterTypes());
+ PreFetch preFetchInMethod = method.getAnnotation(PreFetch.class);
+ if (preFetchInMethod != null) {
+ return preFetchInMethod.enabled();
+ }
+ } catch (NoSuchMethodException e) {
+ LOG.warn("No method " + callbackMethod.getName() + " defined in listener " + dataListener
+ .getClass().getCanonicalName());
+ }
+
+ return true;
+ }
+
+ public void unsubscribeDataChanges(String path, IZkDataListener dataListener) {
+ synchronized (_dataListener) {
+ final Set<IZkDataListenerEntry> listeners = _dataListener.get(path);
+ if (listeners != null) {
+ IZkDataListenerEntry listenerEntry = new IZkDataListenerEntry(dataListener);
+ listeners.remove(listenerEntry);
+ }
+ if (listeners == null || listeners.isEmpty()) {
+ _dataListener.remove(path);
+ }
+ }
+ }
+
+ public void subscribeStateChanges(final IZkStateListener listener) {
+ synchronized (_stateListener) {
+ _stateListener.add(listener);
+ }
+ }
+
+ /**
+ * Subscribes state changes for a {@link IZkStateListener} listener.
+ *
+ * @deprecated
+ * This is deprecated. It is kept for backwards compatibility. Please use
+ * {@link #subscribeStateChanges(IZkStateListener)}.
+ *
+ * @param listener {@link IZkStateListener} listener
+ */
+ @Deprecated
+ public void subscribeStateChanges(
+ final org.apache.helix.zookeeper.zkclient.deprecated.IZkStateListener listener) {
+ subscribeStateChanges(new IZkStateListenerI0ItecImpl(listener));
+ }
+
+ public void unsubscribeStateChanges(IZkStateListener stateListener) {
+ synchronized (_stateListener) {
+ _stateListener.remove(stateListener);
+ }
+ }
+
+ /**
+ * Unsubscribes state changes for a {@link IZkStateListener} listener.
+ *
+ * @deprecated
+ * This is deprecated. It is kept for backwards compatibility. Please use
+ * {@link #unsubscribeStateChanges(IZkStateListener)}.
+ *
+ * @param stateListener {@link IZkStateListener} listener
+ */
+ @Deprecated
+ public void unsubscribeStateChanges(
+ org.apache.helix.zookeeper.zkclient.deprecated.IZkStateListener stateListener) {
+ unsubscribeStateChanges(new IZkStateListenerI0ItecImpl(stateListener));
+ }
+
+ public void unsubscribeAll() {
+ synchronized (_childListener) {
+ _childListener.clear();
+ }
+ synchronized (_dataListener) {
+ _dataListener.clear();
+ }
+ synchronized (_stateListener) {
+ _stateListener.clear();
+ }
+ }
+
+ // </listeners>
+
+ /**
+ * Create a persistent node.
+ * @param 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 void createPersistent(String path)
+ throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
+ createPersistent(path, false);
+ }
+
+ /**
+ * Create a persistent node and set its ACLs.
+ * @param path
+ * @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 createPersistent(String path, boolean createParents)
+ throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
+ createPersistent(path, createParents, ZooDefs.Ids.OPEN_ACL_UNSAFE);
+ }
+
+ /**
+ * Create a persistent node and set its ACLs.
+ * @param path
+ * @param acl
+ * List of ACL permissions to assign to the node
+ * @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 createPersistent(String path, boolean createParents, List<ACL> acl)
+ throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
+ try {
+ create(path, null, acl, CreateMode.PERSISTENT);
+ } catch (ZkNodeExistsException e) {
+ if (!createParents) {
+ throw e;
+ }
+ } catch (ZkNoNodeException e) {
+ if (!createParents) {
+ throw e;
+ }
+ String parentDir = path.substring(0, path.lastIndexOf('/'));
+ createPersistent(parentDir, createParents, acl);
+ createPersistent(path, createParents, acl);
+ }
+ }
+
+ /**
+ * Create a persistent node.
+ * @param path
+ * @param data
+ * @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 createPersistent(String path, Object data)
+ throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
+ create(path, data, CreateMode.PERSISTENT);
+ }
+
+ /**
+ * Create a persistent node.
+ * @param path
+ * @param data
+ * @param acl
+ * @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 createPersistent(String path, Object data, List<ACL> acl) {
+ create(path, data, acl, CreateMode.PERSISTENT);
+ }
+
+ /**
+ * Create a persistent, sequental node.
+ * @param path
+ * @param data
+ * @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 createPersistentSequential(String path, Object data)
+ throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
+ return create(path, data, CreateMode.PERSISTENT_SEQUENTIAL);
+ }
+
+ /**
+ * Create a persistent, sequential node and set its ACL.
+ * @param path
+ * @param acl
+ * @param data
+ * @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 createPersistentSequential(String path, Object data, List<ACL> acl)
+ throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
+ return create(path, data, acl, CreateMode.PERSISTENT_SEQUENTIAL);
+ }
+
+ /**
+ * Create an ephemeral node.
+ * @param 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 void createEphemeral(final String path)
+ throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
+ create(path, null, CreateMode.EPHEMERAL);
+ }
+
+ /**
+ * Creates an ephemeral node. This ephemeral node is created by the expected(passed-in) ZK session.
+ * If the expected session does not match the current ZK session, the node will not be created.
+ *
+ * @param path path of the node
+ * @param sessionId expected session id of the ZK connection. If the session id of current ZK
+ * connection does not match the expected session id, ephemeral creation will
+ * fail
+ * @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 createEphemeral(final String path, final String sessionId)
+ throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
+ createEphemeral(path, null, sessionId);
+ }
+
+ /**
+ * Create an ephemeral node and set its ACL.
+ * @param path
+ * @param acl
+ * @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 createEphemeral(final String path, final List<ACL> acl)
+ throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
+ create(path, null, acl, CreateMode.EPHEMERAL);
+ }
+
+ /**
+ * Creates an ephemeral node and set its ACL. This ephemeral node is created by the
+ * expected(passed-in) ZK session. If the expected session does not match the current ZK session,
+ * the node will not be created.
+ *
+ * @param path path of the ephemeral node
+ * @param acl a list of ACL for the ephemeral node.
+ * @param sessionId expected session id of the ZK connection. If the session id of current ZK
+ * connection does not match the expected session id, ephemeral creation will
+ * fail.
+ * @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 createEphemeral(final String path, final List<ACL> acl, final String sessionId)
+ throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
+ create(path, null, acl, CreateMode.EPHEMERAL, sessionId);
+ }
+
+ /**
+ * Create a node.
+ * @param path
+ * @param data
+ * @param mode
+ * @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)
+ throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
+ return create(path, data, ZooDefs.Ids.OPEN_ACL_UNSAFE, mode);
+ }
+
+ /**
+ * Create a node with ACL.
+ * @param path
+ * @param datat
+ * @param acl
+ * @param mode
+ * @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)
+ throws IllegalArgumentException, ZkException {
+ return create(path, datat, acl, mode, null);
+ }
+
+ /**
+ * Creates a node and returns the actual path of the created node.
+ *
+ * Given an expected non-null session id, if the node is successfully created, it is guaranteed to
+ * be created in the expected(passed-in) session.
+ *
+ * If the expected session is expired, which means the expected session does not match the current
+ * session of ZK connection, the node will not be created.
+ *
+ * @param path the path where you want the node to be created
+ * @param dataObject data of the node
+ * @param acl list of ACL for the node
+ * @param mode {@link CreateMode} of the node
+ * @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
+ * failed if the expected session id doesn't match current connected zk session.
+ * If the session id is null, it means the create operation is NOT session aware.
+ * @return path of the node created
+ * @throws IllegalArgumentException if called from anything else except the ZooKeeper event thread
+ * @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)
+ throws IllegalArgumentException, ZkException {
+ if (path == null) {
+ throw new NullPointerException("Path must not be null.");
+ }
+ if (acl == null || acl.size() == 0) {
+ throw new NullPointerException("Missing value for ACL");
+ }
+ long startT = System.currentTimeMillis();
+ try {
+ final byte[] dataBytes = dataObject == null ? null : serialize(dataObject, path);
+ checkDataSizeLimit(dataBytes);
+
+ final String actualPath = retryUntilConnected(() -> {
+ ZooKeeper zooKeeper = ((ZkConnection) getConnection()).getZookeeper();
+
+ /*
+ * 1. If operation is session aware, we have to check whether or not the
+ * passed-in(expected) session id matches actual session's id.
+ * If not, ephemeral node creation is failed. This validation is
+ * critical to guarantee the ephemeral node created by the expected ZK session.
+ *
+ * 2. Otherwise, the operation is NOT session aware.
+ * In this case, we will use the actual zookeeper session to create the node.
+ */
+ if (isSessionAwareOperation(expectedSessionId, mode)) {
+ acquireEventLock();
+ try {
+ final String actualSessionId = toHexSessionId(zooKeeper.getSessionId());
+ if (!actualSessionId.equals(expectedSessionId)) {
+ throw new ZkSessionMismatchedException(
+ "Failed to create ephemeral node! There is a session id mismatch. Expected: "
+ + expectedSessionId + ". Actual: " + actualSessionId);
+ }
+
+ /*
+ * Cache the zookeeper reference and make sure later zooKeeper.create() is being run
+ * under this zookeeper connection. This is to avoid locking zooKeeper.create() which
+ * may cause potential performance issue.
+ */
+ zooKeeper = ((ZkConnection) getConnection()).getZookeeper();
+ } finally {
+ getEventLock().unlock();
+ }
+ }
+
+ return zooKeeper.create(path, dataBytes, acl, mode);
+ });
+
+ record(path, dataBytes, startT, ZkClientMonitor.AccessType.WRITE);
+ return actualPath;
+ } catch (Exception e) {
+ recordFailure(path, ZkClientMonitor.AccessType.WRITE);
+ throw e;
+ } finally {
+ long endT = System.currentTimeMillis();
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("create, path: " + path + ", time: " + (endT - startT) + " ms");
+ }
+ }
+ }
+
+ /**
+ * Create an ephemeral node.
+ * @param path
+ * @param data
+ * @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 createEphemeral(final String path, final Object data)
+ throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
+ create(path, data, CreateMode.EPHEMERAL);
+ }
+
+ /**
+ * Creates an ephemeral node. Given an expected non-null session id, if the ephemeral
+ * node is successfully created, it is guaranteed to be in the expected(passed-in) session.
+ *
+ * If the expected session is expired, which means the expected session does not match the session
+ * of current ZK connection, the ephemeral node will not be created.
+ * If connection is timed out or interrupted, exception is thrown.
+ *
+ * @param path path of the ephemeral node being created
+ * @param data data of the ephemeral node being created
+ * @param sessionId 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
+ * failed if the expected session id doesn't match current connected zk session.
+ * If the session id is null, it means the operation is NOT session aware
+ * and the node will be created by current ZK session.
+ * @throws ZkInterruptedException if operation is interrupted, or a required reconnection gets
+ * interrupted
+ * @throws IllegalArgumentException if called from anything except the ZooKeeper event thread
+ * @throws ZkException if any ZooKeeper exception occurs
+ * @throws RuntimeException if any other exception occurs
+ */
+ 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 an ephemeral node.
+ * @param path
+ * @param data
+ * @param acl
+ * @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 createEphemeral(final String path, final Object data, final List<ACL> acl)
+ throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
+ create(path, data, acl, CreateMode.EPHEMERAL);
+ }
+
+ /**
+ * Creates an ephemeral node in an expected ZK session. Given an expected non-null session id,
+ * if the ephemeral node is successfully created, it is guaranteed to be in the expected session.
+ * If the expected session is expired, which means the expected session does not match the session
+ * of current ZK connection, the ephemeral node will not be created.
+ * If connection is timed out or interrupted, exception is thrown.
+ *
+ * @param path path of the ephemeral node being created
+ * @param data data of the ephemeral node being created
+ * @param acl list of ACL for the ephemeral node
+ * @param sessionId 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
+ * failed if the expected session id doesn't match current connected zk session.
+ * If the session id is null, it means the create operation is NOT session aware
+ * and the node will be created by current ZK session.
+ * @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 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 an ephemeral, sequential node.
+ * @param path
+ * @param data
+ * @return created 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 createEphemeralSequential(final String path, final Object data)
+ throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
+ return create(path, data, CreateMode.EPHEMERAL_SEQUENTIAL);
+ }
+
+ /**
+ * Creates an ephemeral, sequential node with ACL in an expected ZK session.
+ * Given an expected non-null session id, if the ephemeral node is successfully created,
+ * it is guaranteed to be in the expected session.
+ * If the expected session is expired, which means the expected session does not match the session
+ * of current ZK connection, the ephemeral node will not be created.
+ * If connection is timed out or interrupted, exception is thrown.
+ *
+ * @param path path of the node
+ * @param data data of the node
+ * @param acl list of ACL for the node
+ * @return created 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 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);
+ }
+
+ /**
+ * Creates an ephemeral, sequential node. Given an expected non-null session id,
+ * if the ephemeral node is successfully created, it is guaranteed to be in the expected session.
+ * If the expected session is expired, which means the expected session does not match the session
+ * of current ZK connection, the ephemeral node will not be created.
+ * If connection is timed out or interrupted, exception is thrown.
+ *
+ * @param path path of the node
+ * @param data data of the node
+ * @param sessionId 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
+ * failed if the expected session id doesn't match current connected zk session.
+ * If the session id is null, it means the create operation is NOT session aware
+ * and the node will be created by current ZK session.
+ * @return created 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 createEphemeralSequential(final String path, final Object data,
+ final String sessionId)
+ throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
+ return create(path, data, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL,
+ sessionId);
+ }
+
+ /**
+ * Create an ephemeral, sequential node with ACL.
+ * @param path
+ * @param data
+ * @param acl
+ * @return created 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 createEphemeralSequential(final String path, final Object data, final List<ACL> acl)
+ throws ZkInterruptedException, IllegalArgumentException, ZkException, RuntimeException {
+ return create(path, data, acl, CreateMode.EPHEMERAL_SEQUENTIAL);
+ }
+
+ @Override
+ public void process(WatchedEvent event) {
+ long notificationTime = System.currentTimeMillis();
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Received event: " + event);
+ }
+ _zookeeperEventThread = Thread.currentThread();
+
+ boolean stateChanged = event.getPath() == null;
+ boolean znodeChanged = event.getPath() != null;
+ boolean dataChanged =
+ event.getType() == EventType.NodeDataChanged || event.getType() == EventType.NodeDeleted
+ || event.getType() == EventType.NodeCreated
+ || event.getType() == EventType.NodeChildrenChanged;
+ if (event.getType() == EventType.NodeDeleted) {
+ LOG.debug("Path {} is deleted", event.getPath());
+ }
+
+ getEventLock().lock();
+ try {
+ // We might have to install child change event listener if a new node was created
+ if (getShutdownTrigger()) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("ignoring event '{" + event.getType() + " | " + event.getPath()
+ + "}' since shutdown triggered");
+ }
+ return;
+ }
+ if (stateChanged) {
+ processStateChanged(event);
+ }
+ if (dataChanged) {
+ processDataOrChildChange(event, notificationTime);
+ }
+ } finally {
+ if (stateChanged) {
+ getEventLock().getStateChangedCondition().signalAll();
+
+ // If the session expired we have to signal all conditions, because watches might have been
+ // removed and
+ // there is no guarantee that those
+ // conditions will be signaled at all after an Expired event
+ // TODO PVo write a test for this
+ if (event.getState() == KeeperState.Expired) {
+ getEventLock().getZNodeEventCondition().signalAll();
+ getEventLock().getDataChangedCondition().signalAll();
+ }
+ }
+ if (znodeChanged) {
+ getEventLock().getZNodeEventCondition().signalAll();
+ }
+ if (dataChanged) {
+ getEventLock().getDataChangedCondition().signalAll();
+ }
+ getEventLock().unlock();
+
+ // update state change counter.
+ recordStateChange(stateChanged, dataChanged);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Leaving process event");
+ }
+ }
+ }
+
+ private void fireAllEvents() {
+ //TODO: During handling new session, if the path is deleted, watcher leakage could still happen
+ for (Entry<String, Set<IZkChildListener>> entry : _childListener.entrySet()) {
+ fireChildChangedEvents(entry.getKey(), entry.getValue(), true);
+ }
+ for (Entry<String, Set<IZkDataListenerEntry>> entry : _dataListener.entrySet()) {
+ fireDataChangedEvents(entry.getKey(), entry.getValue(), OptionalLong.empty(), true);
+ }
+ }
+
+ public List<String> getChildren(String path) {
+ return getChildren(path, hasListeners(path));
+ }
+
+ protected List<String> getChildren(final String path, final boolean watch) {
+ long startT = System.currentTimeMillis();
+ try {
+ List<String> children = retryUntilConnected(new Callable<List<String>>() {
+ @Override
+ public List<String> call() throws Exception {
+ return getConnection().getChildren(path, watch);
+ }
+ });
+ record(path, null, startT, ZkClientMonitor.AccessType.READ);
+ return children;
+ } catch (ZkNoNodeException e) {
+ record(path, null, startT, ZkClientMonitor.AccessType.READ);
+ throw e;
+ } catch (Exception e) {
+ recordFailure(path, ZkClientMonitor.AccessType.READ);
+ throw e;
+ } finally {
+ long endT = System.currentTimeMillis();
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("getChildren, path: " + path + ", time: " + (endT - startT) + " ms");
+ }
+ }
+ }
+
+ /**
+ * Counts number of children for the given path.
+ * @param path
+ * @return number of children or 0 if path does not exist.
+ */
+ public int countChildren(String path) {
+ try {
+ return getChildren(path).size();
+ } catch (ZkNoNodeException e) {
+ return 0;
+ }
+ }
+
+ public boolean exists(final String path) {
+ return exists(path, hasListeners(path));
+ }
+
+ protected boolean exists(final String path, final boolean watch) {
+ long startT = System.currentTimeMillis();
+ try {
+ boolean exists = retryUntilConnected(new Callable<Boolean>() {
+ @Override
+ public Boolean call() throws Exception {
+ return getConnection().exists(path, watch);
+ }
+ });
+ record(path, null, startT, ZkClientMonitor.AccessType.READ);
+ return exists;
+ } catch (ZkNoNodeException e) {
+ record(path, null, startT, ZkClientMonitor.AccessType.READ);
+ throw e;
+ } catch (Exception e) {
+ recordFailure(path, ZkClientMonitor.AccessType.READ);
+ throw e;
+ } finally {
+ long endT = System.currentTimeMillis();
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("exists, path: " + path + ", time: " + (endT - startT) + " ms");
+ }
+ }
+ }
+
+ public Stat getStat(final String path) {
+ return getStat(path, false);
+ }
+
+ private Stat getStat(final String path, final boolean watch) {
+ long startT = System.currentTimeMillis();
+ try {
+ Stat stat = retryUntilConnected(
+ () -> ((ZkConnection) getConnection()).getZookeeper().exists(path, watch));
+ record(path, null, startT, ZkClientMonitor.AccessType.READ);
+ return stat;
+ } catch (ZkNoNodeException e) {
+ record(path, null, startT, ZkClientMonitor.AccessType.READ);
+ throw e;
+ } catch (Exception e) {
+ recordFailure(path, ZkClientMonitor.AccessType.READ);
+ throw e;
+ } finally {
+ long endT = System.currentTimeMillis();
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("exists, path: " + path + ", time: " + (endT - startT) + " ms");
+ }
+ }
+ }
+
+ protected void processStateChanged(WatchedEvent event) {
+ LOG.info("zookeeper state changed (" + event.getState() + ")");
+ setCurrentState(event.getState());
+ if (getShutdownTrigger()) {
+ return;
+ }
+
+ fireStateChangedEvent(event.getState());
+
+ if (!isManagingZkConnection()) {
+ return;
+ }
+
+ if (event.getState() == KeeperState.SyncConnected) {
+ if (!_isNewSessionEventFired && !"0".equals(getHexSessionId())) {
+ /*
+ * Before the new zookeeper instance is connected to the zookeeper service and its session
+ * is established, its session id is 0.
+ * New session event is not fired until the new zookeeper session receives the first
+ * SyncConnected state(the zookeeper session is established).
+ * Now the session id is available and non-zero, and we can fire new session events.
+ */
+ fireNewSessionEvents();
+ /*
+ * Set it true to avoid firing events again for the same session next time
+ * when SyncConnected events are received.
+ */
+ _isNewSessionEventFired = true;
+
+ /*
+ * With this first SyncConnected state, we just get connected to zookeeper service after
+ * reconnecting when the session expired. Because previous session expired, we also have to
+ * notify all listeners that something might have changed.
+ */
+ fireAllEvents();
+ }
+ } else if (event.getState() == KeeperState.Expired) {
+ reconnectOnExpiring();
+ }
+ }
+
+ private void reconnectOnExpiring() {
+ int retryCount = 0;
+ ExponentialBackoffStrategy retryStrategy =
+ new ExponentialBackoffStrategy(MAX_RECONNECT_INTERVAL_MS, true);
+
+ Exception reconnectException = new ZkException("Shutdown triggered.");
+ while (!isClosed()) {
+ try {
+ reconnect();
+ return;
+ } catch (ZkInterruptedException interrupt) {
+ reconnectException = interrupt;
+ break;
+ } catch (Exception e) {
+ reconnectException = e;
+ long waitInterval = retryStrategy.getNextWaitInterval(retryCount++);
+ LOG.warn("ZkClient reconnect on expiring failed. Will retry after {} ms", waitInterval, e);
+ try {
+ Thread.sleep(waitInterval);
+ } catch (InterruptedException ex) {
+ reconnectException = ex;
+ break;
+ }
+ }
+ }
+
+ LOG.info("Unable to re-establish connection. Notifying consumer of the following exception: ",
+ reconnectException);
+ fireSessionEstablishmentError(reconnectException);
+ }
+
+ private void reconnect() {
+ getEventLock().lock();
+ try {
+ ZkConnection connection = ((ZkConnection) getConnection());
+ connection.reconnect(this);
+ _isNewSessionEventFired = false;
+ } catch (InterruptedException e) {
+ throw new ZkInterruptedException(e);
+ } finally {
+ getEventLock().unlock();
+ }
+ }
+
+ private void fireNewSessionEvents() {
+ final String sessionId = getHexSessionId();
+ for (final IZkStateListener stateListener : _stateListener) {
+ _eventThread.send(new ZkEventThread.ZkEvent("New session event sent to " + stateListener, sessionId) {
+
+ @Override
+ public void run() throws Exception {
+ stateListener.handleNewSession(sessionId);
+ }
+ });
+ }
+ }
+
+ protected void fireStateChangedEvent(final KeeperState state) {
+ final String sessionId = getHexSessionId();
+ for (final IZkStateListener stateListener : _stateListener) {
+ final String description = "State changed to " + state + " sent to " + stateListener;
+ _eventThread.send(new ZkEventThread.ZkEvent(description, sessionId) {
+
+ @Override
+ public void run() throws Exception {
+ stateListener.handleStateChanged(state);
+ }
+ });
+ }
+ }
+
+ private void fireSessionEstablishmentError(final Throwable error) {
+ for (final IZkStateListener stateListener : _stateListener) {
+ _eventThread
+ .send(new ZkEventThread.ZkEvent("Session establishment error(" + error + ") sent to " + stateListener) {
+
+ @Override
+ public void run() throws Exception {
+ stateListener.handleSessionEstablishmentError(error);
+ }
+ });
+ }
+ }
+
+ private boolean hasListeners(String path) {
+ Set<IZkDataListenerEntry> dataListeners = _dataListener.get(path);
+ if (dataListeners != null && dataListeners.size() > 0) {
+ return true;
+ }
+ Set<IZkChildListener> childListeners = _childListener.get(path);
+ if (childListeners != null && childListeners.size() > 0) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Delete the path as well as all its children.
+ * This method is deprecated, please use {@link #deleteRecursively(String)}} instead
+ * @param path ZK path
+ * @return true if successfully deleted all children, and the given path, else false
+ */
+ @Deprecated
+ public boolean deleteRecursive(String path) {
+ try {
+ deleteRecursively(path);
+ return true;
+ } catch (ZkClientException e) {
+ LOG.error("Failed to recursively delete path " + path, e);
+ return false;
+ }
+ }
+
+ /**
+ * Delete the path as well as all its children.
+ * @param path
+ * @throws ZkClientException
+ */
+ public void deleteRecursively(String path) throws ZkClientException {
+ List<String> children;
+ try {
+ children = getChildren(path, false);
+ } catch (ZkNoNodeException e) {
+ // if the node to be deleted does not exist, treat it as success.
+ return;
+ }
+
+ for (String subPath : children) {
+ deleteRecursively(path + "/" + subPath);
+ }
+
+ // delete() function call will return true if successful, false if the path does not
+ // exist (in this context, it should be treated as successful), and throw exception
+ // if there is any other failure case.
+ try {
+ delete(path);
+ } catch (Exception e) {
+ LOG.error("Failed to delete " + path, e);
+ throw new ZkClientException("Failed to delete " + path, e);
+ }
+ }
+
+ private void processDataOrChildChange(WatchedEvent event, long notificationTime) {
+ final String path = event.getPath();
+ final boolean pathExists = event.getType() != EventType.NodeDeleted;
+
+ if (event.getType() == EventType.NodeChildrenChanged || event.getType() == EventType.NodeCreated
+ || event.getType() == EventType.NodeDeleted) {
+ Set<IZkChildListener> childListeners = _childListener.get(path);
+ if (childListeners != null && !childListeners.isEmpty()) {
+ // TODO recording child changed event propagation latency as well. Note this change will
+ // introduce additional ZK access.
+ fireChildChangedEvents(path, childListeners, pathExists);
+ }
+ }
+
+ if (event.getType() == EventType.NodeDataChanged || event.getType() == EventType.NodeDeleted
+ || event.getType() == EventType.NodeCreated) {
+ Set<IZkDataListenerEntry> listeners = _dataListener.get(path);
+ if (listeners != null && !listeners.isEmpty()) {
+ fireDataChangedEvents(event.getPath(), listeners, OptionalLong.of(notificationTime),
+ pathExists);
+ }
+ }
+ }
+
+ private void fireDataChangedEvents(final String path, Set<IZkDataListenerEntry> listeners,
+ final OptionalLong notificationTime, boolean pathExists) {
+ try {
+ final ZkPathStatRecord pathStatRecord = new ZkPathStatRecord(path);
+ // Trigger listener callbacks
+ for (final IZkDataListenerEntry listener : listeners) {
+ _eventThread.send(new ZkEventThread.ZkEvent(
+ "Data of " + path + " changed sent to " + listener.getDataListener()
+ + " prefetch data: " + listener.isPrefetchData()) {
+ @Override
+ public void run() throws Exception {
+ if (!pathStatRecord.pathChecked()) {
+ // getStat will re-install watcher only when the path exists
+ pathStatRecord.recordPathStat(getStat(path, pathExists), notificationTime);
+ }
+ if (!pathStatRecord.pathExists()) {
+ listener.getDataListener().handleDataDeleted(path);
+ } else {
+ Object data = null;
+ if (listener.isPrefetchData()) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Prefetch data for path: {}", path);
+ }
+ try {
+ // TODO: the data is redundantly read multiple times when multiple listeners exist
+ data = readData(path, null, true);
+ } catch (ZkNoNodeException e) {
+ LOG.warn("Prefetch data for path: {} failed.", path, e);
+ listener.getDataListener().handleDataDeleted(path);
+ return;
+ }
+ }
+ listener.getDataListener().handleDataChange(path, data);
+ }
+ }
+ });
+ }
+ } catch (Exception e) {
+ LOG.error("Failed to fire data changed event for path: {}", path, e);
+ }
+ }
+
+ private void fireChildChangedEvents(final String path, Set<IZkChildListener> childListeners, boolean pathExists) {
+ try {
+ final ZkPathStatRecord pathStatRecord = new ZkPathStatRecord(path);
+ for (final IZkChildListener listener : childListeners) {
+ _eventThread.send(new ZkEventThread.ZkEvent("Children of " + path + " changed sent to " + listener) {
+ @Override
+ public void run() throws Exception {
+ if (!pathStatRecord.pathChecked()) {
+ pathStatRecord.recordPathStat(getStat(path, hasListeners(path) && pathExists),
+ OptionalLong.empty());
+ }
+ List<String> children = null;
+ if (pathStatRecord.pathExists()) {
+ try {
+ children = getChildren(path);
+ } catch (ZkNoNodeException e) {
+ LOG.warn("Get children under path: {} failed.", path, e);
+ // Continue trigger the change handler
+ }
+ }
+ listener.handleChildChange(path, children);
+ }
+ });
+ }
+ } catch (Exception e) {
+ LOG.error("Failed to fire child changed event. Unable to getChildren.", e);
+ }
+ }
+
+ public boolean waitUntilExists(String path, TimeUnit timeUnit, long time)
+ throws ZkInterruptedException {
+ Date timeout = new Date(System.currentTimeMillis() + timeUnit.toMillis(time));
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Waiting until znode '" + path + "' becomes available.");
+ }
+ if (exists(path)) {
+ return true;
+ }
+ acquireEventLock();
+ try {
+ while (!exists(path, true)) {
+ boolean gotSignal = getEventLock().getZNodeEventCondition().awaitUntil(timeout);
+ if (!gotSignal) {
+ return false;
+ }
+ }
+ return true;
+ } catch (InterruptedException e) {
+ throw new ZkInterruptedException(e);
+ } finally {
+ getEventLock().unlock();
+ }
+ }
+
+ public IZkConnection getConnection() {
+ return _connection;
+ }
+
+ public long waitForEstablishedSession(long timeout, TimeUnit timeUnit) {
+ validateCurrentThread();
+
+ acquireEventLock();
+ try {
+ if (!waitForKeeperState(KeeperState.SyncConnected, timeout, timeUnit)) {
+ throw new ZkTimeoutException("Waiting to be connected to ZK server has timed out.");
+ }
+ // Reading session ID before unlocking event lock is critical to guarantee the established
+ // session's ID won't change.
+ return getSessionId();
+ } finally {
+ getEventLock().unlock();
+ }
+ }
+
+ public boolean waitUntilConnected(long time, TimeUnit timeUnit) throws ZkInterruptedException {
+ return waitForKeeperState(KeeperState.SyncConnected, time, timeUnit);
+ }
+
+ public boolean waitForKeeperState(KeeperState keeperState, long time, TimeUnit timeUnit)
+ throws ZkInterruptedException {
+ validateCurrentThread();
+ Date timeout = new Date(System.currentTimeMillis() + timeUnit.toMillis(time));
+
+ LOG.debug("Waiting for keeper state " + keeperState);
+ acquireEventLock();
+ try {
+ boolean stillWaiting = true;
+ while (_currentState != keeperState) {
+ if (!stillWaiting) {
+ return false;
+ }
+ stillWaiting = getEventLock().getStateChangedCondition().awaitUntil(timeout);
+ }
+ LOG.debug("State is " + (_currentState == null ? "CLOSED" : _currentState));
+ return true;
+ } catch (InterruptedException e) {
+ throw new ZkInterruptedException(e);
+ } finally {
+ getEventLock().unlock();
+ }
+ }
+
+ private void acquireEventLock() {
+ try {
+ getEventLock().lockInterruptibly();
+ } catch (InterruptedException e) {
+ throw new ZkInterruptedException(e);
+ }
+ }
+
+ /**
+ * @param <T>
+ * @param callable
+ * @return result of Callable
+ * @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 from invoking the Callable
+ */
+ public <T> T retryUntilConnected(final Callable<T> callable)
+ throws IllegalArgumentException, ZkException {
+ if (_zookeeperEventThread != null && Thread.currentThread() == _zookeeperEventThread) {
+ throw new IllegalArgumentException("Must not be done in the zookeeper event thread.");
+ }
+ final long operationStartTime = System.currentTimeMillis();
+ if (_monitor != null) {
+ _monitor.increaseOutstandingRequestGauge();
+ }
+ try {
+ while (true) {
+ // Because ConnectionLossException and SessionExpiredException are caught but not thrown,
+ // we don't know what causes retry. This is used to record which one of the two exceptions
+ // causes retry in ZkTimeoutException.
+ // This also helps the test testConnectionLossWhileCreateEphemeral.
+ KeeperException.Code retryCauseCode;
+
+ if (isClosed()) {
+ throw new IllegalStateException("ZkClient already closed!");
+ }
+ try {
+ final ZkConnection zkConnection = (ZkConnection) getConnection();
+ // Validate that the connection is not null before trigger callback
+ if (zkConnection == null || zkConnection.getZookeeper() == null) {
+ throw new IllegalStateException(
+ "ZkConnection is in invalid state! Please close this ZkClient and create new client.");
+ }
+ return callable.call();
+ } catch (ConnectionLossException e) {
+ retryCauseCode = e.code();
+ // we give the event thread some time to update the status to 'Disconnected'
+ Thread.yield();
+ waitForRetry();
+ } catch (SessionExpiredException e) {
+ retryCauseCode = e.code();
+ // we give the event thread some time to update the status to 'Expired'
+ Thread.yield();
+ waitForRetry();
+ } catch (ZkSessionMismatchedException e) {
+ throw e;
+ } catch (KeeperException e) {
+ throw ZkException.create(e);
+ } catch (InterruptedException e) {
+ throw new ZkInterruptedException(e);
+ } catch (Exception e) {
+ throw ExceptionUtil.convertToRuntimeException(e);
+ }
+ // before attempting a retry, check whether retry timeout has elapsed
+ if (System.currentTimeMillis() - operationStartTime > _operationRetryTimeoutInMillis) {
+ throw new ZkTimeoutException("Operation cannot be retried because of retry timeout ("
+ + _operationRetryTimeoutInMillis + " milli seconds). Retry was caused by "
+ + retryCauseCode);
+ }
+ }
+ } finally {
+ if (_monitor != null) {
+ _monitor.decreaseOutstandingRequestGauge();
+ }
+ }
+ }
+
+ private void waitForRetry() {
+ waitUntilConnected(_operationRetryTimeoutInMillis, TimeUnit.MILLISECONDS);
+ }
+
+ public void setCurrentState(KeeperState currentState) {
+ getEventLock().lock();
+ try {
+ _currentState = currentState;
+ } finally {
+ getEventLock().unlock();
+ }
+ }
+
+ /**
+ * Returns a mutex all zookeeper events are synchronized aginst. So in case you need to do
+ * something without getting
+ * any zookeeper event interruption synchronize against this mutex. Also all threads waiting on
+ * this mutex object
+ * will be notified on an event.
+ * @return the mutex.
+ */
+ public ZkLock getEventLock() {
+ return _zkEventLock;
+ }
+
+ /**
+ * Delete the given path. Path should not have any children or the deletion will fail.
+ * This function will throw exception if we fail to delete an existing path
+ * @param path
+ * @return true if path is successfully deleted, false if path does not exist
+ */
+ public boolean delete(final String path) {
+ long startT = System.currentTimeMillis();
+ boolean success;
+ try {
+ try {
+ retryUntilConnected(new Callable<Object>() {
+
+ @Override
+ public Object call() throws Exception {
+ getConnection().delete(path);
+ return null;
+ }
+ });
+ success = true;
+ } catch (ZkNoNodeException e) {
+ success = false;
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Failed to delete path " + path + ", znode does not exist!");
+ }
+ }
+ record(path, null, startT, ZkClientMonitor.AccessType.WRITE);
+ } catch (Exception e) {
+ recordFailure(path, ZkClientMonitor.AccessType.WRITE);
+ LOG.warn("Failed to delete path " + path + "! " + e);
+ throw e;
+ } finally {
+ long endT = System.currentTimeMillis();
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("delete, path: " + path + ", time: " + (endT - startT) + " ms");
+ }
+ }
+ return success;
+ }
+
+ public void setZkSerializer(ZkSerializer zkSerializer) {
+ _pathBasedZkSerializer = new BasicZkSerializer(zkSerializer);
+ }
+
+ public void setZkSerializer(PathBasedZkSerializer zkSerializer) {
+ _pathBasedZkSerializer = zkSerializer;
+ }
+
+ public PathBasedZkSerializer getZkSerializer() {
+ return _pathBasedZkSerializer;
+ }
+
+ public byte[] serialize(Object data, String path) {
+ return _pathBasedZkSerializer.serialize(data, path);
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T extends Object> T deserialize(byte[] data, String path) {
+ if (data == null) {
+ return null;
+ }
+ return (T) _pathBasedZkSerializer.deserialize(data, path);
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T extends Object> T readData(String path) {
+ return (T) readData(path, false);
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T extends Object> T readData(String path, boolean returnNullIfPathNotExists) {
+ T data = null;
+ try {
+ data = (T) readData(path, null);
+ } catch (ZkNoNodeException e) {
+ if (!returnNullIfPathNotExists) {
+ throw e;
+ }
+ }
+ return data;
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T extends Object> T readData(String path, Stat stat) {
+ return (T) readData(path, stat, hasListeners(path));
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T extends Object> T readData(final String path, final Stat stat, final boolean watch) {
+ long startT = System.currentTimeMillis();
+ byte[] data = null;
+ try {
+ data = retryUntilConnected(new Callable<byte[]>() {
+
+ @Override
+ public byte[] call() throws Exception {
+ return getConnection().readData(path, stat, watch);
+ }
+ });
+ record(path, data, startT, ZkClientMonitor.AccessType.READ);
+ return (T) deserialize(data, path);
+ } catch (ZkNoNodeException e) {
+ record(path, data, startT, ZkClientMonitor.AccessType.READ);
+ throw e;
+ } catch (Exception e) {
+ recordFailure(path, ZkClientMonitor.AccessType.READ);
+ throw e;
+ } finally {
+ long endT = System.currentTimeMillis();
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("getData, path: " + path + ", time: " + (endT - startT) + " ms");
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T extends Object> T readDataAndStat(String path, Stat stat,
+ boolean returnNullIfPathNotExists) {
+ T data = null;
+ try {
+ data = readData(path, stat);
+ } catch (ZkNoNodeException e) {
+ if (!returnNullIfPathNotExists) {
+ throw e;
+ }
+ }
+ return data;
+ }
+
+ public void writeData(String path, Object object) {
+ writeData(path, object, -1);
+ }
+
+ /**
+ * Updates data of an existing znode. The current content of the znode is passed to the
+ * {@link DataUpdater} that is
+ * passed into this method, which returns the new content. The new content is only written back to
+ * ZooKeeper if
+ * nobody has modified the given znode in between. If a concurrent change has been detected the
+ * new data of the
+ * znode is passed to the updater once again until the new contents can be successfully written
+ * back to ZooKeeper.
+ * @param <T>
+ * @param path
+ * The path of the znode.
+ * @param updater
+ * Updater that creates the new contents.
+ */
+ @SuppressWarnings("unchecked")
+ public <T extends Object> void updateDataSerialized(String path, DataUpdater<T> updater) {
+ Stat stat = new Stat();
+ boolean retry;
+ do {
+ retry = false;
+ try {
+ T oldData = (T) readData(path, stat);
+ T newData = updater.update(oldData);
+ writeData(path, newData, stat.getVersion());
+ } catch (ZkBadVersionException e) {
+ retry = true;
+ }
+ } while (retry);
+ }
+
+ public void writeData(final String path, Object datat, final int expectedVersion) {
+ writeDataReturnStat(path, datat, expectedVersion);
+ }
+
+ public Stat writeDataReturnStat(final String path, Object datat, final int expectedVersion) {
+ long startT = System.currentTimeMillis();
+ try {
+ final byte[] data = serialize(datat, path);
+ checkDataSizeLimit(data);
+ final Stat stat = (Stat) retryUntilConnected(new Callable<Object>() {
+ @Override
+ public Object call() throws Exception {
+ return getConnection().writeDataReturnStat(path, data, expectedVersion);
+ }
+ });
+ record(path, data, startT, ZkClientMonitor.AccessType.WRITE);
+ return stat;
+ } catch (Exception e) {
+ recordFailure(path, ZkClientMonitor.AccessType.WRITE);
+ throw e;
+ } finally {
+ long endT = System.currentTimeMillis();
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("setData, path: " + path + ", time: " + (endT - startT) + " ms");
+ }
+ }
+ }
+
+ public Stat writeDataGetStat(final String path, Object datat, final int expectedVersion) {
+ return writeDataReturnStat(path, datat, expectedVersion);
+ }
+
+ public void asyncCreate(final String path, Object datat, final CreateMode mode,
+ final ZkAsyncCallbacks.CreateCallbackHandler cb) {
+ final long startT = System.currentTimeMillis();
+ final byte[] data = (datat == null ? null : serialize(datat, path));
+ retryUntilConnected(new Callable<Object>() {
+ @Override
+ public Object call() throws Exception {
+ ((ZkConnection) getConnection()).getZookeeper()
+ .create(path, data, ZooDefs.Ids.OPEN_ACL_UNSAFE,
+ // Arrays.asList(DEFAULT_ACL),
+ mode, cb, new ZkAsyncCallbacks.ZkAsyncCallContext(_monitor, startT,
+ data == null ? 0 : data.length, false));
+ return null;
+ }
+ });
+ }
+
+ // Async Data Accessors
+ public void asyncSetData(final String path, Object datat, final int version,
+ final ZkAsyncCallbacks.SetDataCallbackHandler cb) {
+ final long startT = System.currentTimeMillis();
+ final byte[] data = serialize(datat, path);
+ retryUntilConnected(new Callable<Object>() {
+ @Override
+ public Object call() throws Exception {
+ ((ZkConnection) getConnection()).getZookeeper().setData(path, data, version, cb,
+ new ZkAsyncCallbacks.ZkAsyncCallContext(_monitor, startT,
+ data == null ? 0 : data.length, false));
+ return null;
+ }
+ });
+ }
+
+ public void asyncGetData(final String path, final ZkAsyncCallbacks.GetDataCallbackHandler cb) {
+ final long startT = System.currentTimeMillis();
+ retryUntilConnected(new Callable<Object>() {
+ @Override
+ public Object call() throws Exception {
+ ((ZkConnection) getConnection()).getZookeeper().getData(path, null, cb,
+ new ZkAsyncCallbacks.ZkAsyncCallContext(_monitor, startT, 0, true));
+ return null;
+ }
+ });
+ }
+
+ public void asyncExists(final String path, final ZkAsyncCallbacks.ExistsCallbackHandler cb) {
+ final long startT = System.currentTimeMillis();
+ retryUntilConnected(new Callable<Object>() {
+ @Override
+ public Object call() throws Exception {
+ ((ZkConnection) getConnection()).getZookeeper().exists(path, null, cb,
+ new ZkAsyncCallbacks.ZkAsyncCallContext(_monitor, startT, 0, true));
+ return null;
+ }
+ });
+ }
+
+ public void asyncDelete(final String path, final ZkAsyncCallbacks.DeleteCallbackHandler cb) {
+ final long startT = System.currentTimeMillis();
+ retryUntilConnected(new Callable<Object>() {
+ @Override
+ public Object call() throws Exception {
+ ((ZkConnection) getConnection()).getZookeeper().delete(path, -1, cb,
+ new ZkAsyncCallbacks.ZkAsyncCallContext(_monitor, startT, 0, false));
+ return null;
+ }
+ });
+ }
+
+ private void checkDataSizeLimit(byte[] data) {
+ if (data != null && data.length > ZNRecord.SIZE_LIMIT) {
+ LOG.error(
+ "Data size larger than 1M, will not write to zk. Data (first 1k): " + new String(data)
+ .substring(0, 1024));
+ throw new ZkClientException("Data size larger than 1M");
+ }
+ }
+
+ public void watchForData(final String path) {
+ retryUntilConnected(new Callable<Object>() {
+ @Override
+ public Object call() throws Exception {
+ getConnection().exists(path, true);
+ return null;
+ }
+ });
+ }
+
+ /**
+ * Installs a child watch for the given path.
+ * @param path
+ * @return the current children of the path or null if the zk node with the given path doesn't
+ * exist.
+ */
+ public List<String> watchForChilds(final String path) {
+ if (_zookeeperEventThread != null && Thread.currentThread() == _zookeeperEventThread) {
+ throw new IllegalArgumentException("Must not be done in the zookeeper event thread.");
+ }
+ return retryUntilConnected(new Callable<List<String>>() {
+ @Override
+ public List<String> call() throws Exception {
+ exists(path, true);
+ try {
+ return getChildren(path, true);
+ } catch (ZkNoNodeException e) {
+ // ignore, the "exists" watch will listen for the parent node to appear
+ }
+ return null;
+ }
+ });
+ }
+
+ /**
+ * Add authentication information to the connection. This will be used to identify the user and
+ * check access to
+ * nodes protected by ACLs
+ * @param scheme
+ * @param auth
+ */
+ public void addAuthInfo(final String scheme, final byte[] auth) {
+ retryUntilConnected(new Callable<Object>() {
+ @Override
+ public Object call() throws Exception {
+ getConnection().addAuthInfo(scheme, auth);
+ return null;
+ }
+ });
+ }
+
+ /**
+ * Connect to ZooKeeper.
+ * @param maxMsToWaitUntilConnected
+ * @param watcher
+ * @throws ZkInterruptedException
+ * if the connection timed out due to thread interruption
+ * @throws ZkTimeoutException
+ * if the connection timed out
+ * @throws IllegalStateException
+ * if the connection timed out due to thread interruption
+ */
+ public void connect(final long maxMsToWaitUntilConnected, Watcher watcher)
+ throws ZkInterruptedException, ZkTimeoutException, IllegalStateException {
+ if (isClosed()) {
+ throw new IllegalStateException("ZkClient already closed!");
+ }
+ boolean started = false;
+ acquireEventLock();
+ try {
+ setShutdownTrigger(false);
+
+ IZkConnection zkConnection = getConnection();
+ _eventThread = new ZkEventThread(zkConnection.getServers());
+ _eventThread.start();
+
+ if (isManagingZkConnection()) {
+ zkConnection.connect(watcher);
+ LOG.debug("Awaiting connection to Zookeeper server");
+ if (!waitUntilConnected(maxMsToWaitUntilConnected, TimeUnit.MILLISECONDS)) {
+ throw new ZkTimeoutException(
+ "Unable to connect to zookeeper server within timeout: " + maxMsToWaitUntilConnected);
+ }
+ } else {
+ // if the client is not managing connection, the input connection is supposed to connect.
+ if (isConnectionClosed()) {
+ throw new ZkClientException(
+ "Unable to connect to zookeeper server with the specified ZkConnection");
+ }
+ // TODO Refine the init state here. Here we pre-config it to be connected. This may not be
+ // the case, if the connection is connecting or recovering. -- JJ
+ // For shared client, the event notification will not be forwarded before wather add to the
+ // connection manager.
+ setCurrentState(KeeperState.SyncConnected);
+ }
+
+ started = true;
+ } finally {
+ getEventLock().unlock();
+
+ // we should close the zookeeper instance, otherwise it would keep
+ // on trying to connect
+ if (!started) {
+ close();
+ }
+ }
+ }
+
+ public long getCreationTime(String path) {
+ acquireEventLock();
+ try {
+ return getConnection().getCreateTime(path);
+ } catch (KeeperException e) {
+ throw ZkException.create(e);
+ } catch (InterruptedException e) {
+ throw new ZkInterruptedException(e);
+ } finally {
+ getEventLock().unlock();
+ }
+ }
+
+ public String getServers() {
+ return getConnection().getServers();
+ }
+
+ /**
+ * Close the client.
+ * @throws ZkInterruptedException
+ */
+ public void close() throws ZkInterruptedException {
+ if (LOG.isTraceEnabled()) {
+ StackTraceElement[] calls = Thread.currentThread().getStackTrace();
+ LOG.trace("closing a zkclient. callStack: " + Arrays.asList(calls));
+ }
+ getEventLock().lock();
+ IZkConnection connection = getConnection();
+ try {
+ if (connection == null || _closed) {
+ return;
+ }
+ setShutdownTrigger(true);
+ _eventThread.interrupt();
+ _eventThread.join(2000);
+ if (isManagingZkConnection()) {
+ LOG.info("Closing zkclient: " + ((ZkConnection) connection).getZookeeper());
+ connection.close();
+ }
+ _closed = true;
+
+ // send state change notification to unlock any wait
+ setCurrentState(null);
+ getEventLock().getStateChangedCondition().signalAll();
+ } catch (InterruptedException e) {
+ /**
+ * Workaround for HELIX-264: calling ZkClient#close() in its own eventThread context will
+ * throw ZkInterruptedException and skip ZkConnection#close()
+ */
+ if (connection != null) {
+ try {
+ /**
+ * ZkInterruptedException#construct() honors InterruptedException by calling
+ * Thread.currentThread().interrupt(); clear it first, so we can safely close the
+ * zk-connection
+ */
+ Thread.interrupted();
+ if (isManagingZkConnection()) {
+ connection.close();
+ }
+ /**
+ * restore interrupted status of current thread
+ */
+ Thread.currentThread().interrupt();
+ } catch (InterruptedException e1) {
+ throw new ZkInterruptedException(e1);
+ }
+ }
+ } finally {
+ getEventLock().unlock();
+ if (_monitor != null) {
+ _monitor.unregister();
+ }
+ LOG.info("Closed zkclient");
+ }
+ }
+
+ public boolean isClosed() {
+ try {
+ getEventLock().lock();
+ return _closed;
+ } finally {
+ getEventLock().unlock();
+ }
+ }
+
+ public boolean isConnectionClosed() {
+ IZkConnection connection = getConnection();
+ return (connection == null || connection.getZookeeperState() == null || !connection
+ .getZookeeperState().isAlive());
+ }
+
+ public void setShutdownTrigger(boolean triggerState) {
+ _shutdownTriggered = triggerState;
+ }
+
+ public boolean getShutdownTrigger() {
+ return _shutdownTriggered;
+ }
+
+ public int numberOfListeners() {
+ int listeners = 0;
+ for (Set<IZkChildListener> childListeners : _childListener.values()) {
+ listeners += childListeners.size();
+ }
+ for (Set<IZkDataListenerEntry> dataListeners : _dataListener.values()) {
+ listeners += dataListeners.size();
+ }
+ listeners += _stateListener.size();
+
+ return listeners;
+ }
+
+ public List<OpResult> multi(final Iterable<Op> ops) throws ZkException {
+ if (ops == null) {
+ throw new NullPointerException("ops must not be null.");
+ }
+
+ return retryUntilConnected(new Callable<List<OpResult>>() {
+
+ @Override
+ public List<OpResult> call() throws Exception {
+ return getConnection().multi(ops);
+ }
+ });
+ }
+
+ /**
+ * @return true if this ZkClient is managing the ZkConnection.
+ */
+ protected boolean isManagingZkConnection() {
+ return true;
+ }
+
+ public long getSessionId() {
+ ZkConnection zkConnection = ((ZkConnection) getConnection());
+ ZooKeeper zk = zkConnection.getZookeeper();
+ if (zk == null) {
+ throw new ZkClientException(
+ "ZooKeeper connection information is not available now. ZkClient might be disconnected.");
+ } else {
+ return zkConnection.getZookeeper().getSessionId();
+ }
+ }
+
+ /*
+ * Gets a session id in hexadecimal notation.
+ * Ex. 1000a5ceb930004 is returned.
+ */
+ private String getHexSessionId() {
+ return toHexSessionId(getSessionId());
+ }
+
+ /*
+ * Session aware operation needs below requirements:
+ * 1. the session id is NOT null or empty
+ * 2. create mode is EPHEMERAL or EPHEMERAL_SEQUENTIAL
+ */
+ private boolean isSessionAwareOperation(String expectedSessionId, CreateMode mode) {
+ return expectedSessionId != null && !expectedSessionId.isEmpty() && (
+ mode == CreateMode.EPHEMERAL || mode == CreateMode.EPHEMERAL_SEQUENTIAL);
+ }
+
+ // operations to update monitor's counters
+ private void record(String path, byte[] data, long startTimeMilliSec,
+ ZkClientMonitor.AccessType accessType) {
+ if (_monitor != null) {
+ int dataSize = (data != null) ? data.length : 0;
+ _monitor.record(path, dataSize, startTimeMilliSec, accessType);
+ }
+ }
+
+ private void recordFailure(String path, ZkClientMonitor.AccessType accessType) {
+ if (_monitor != null) {
+ _monitor.recordFailure(path, accessType);
+ }
+ }
+
+ private void recordStateChange(boolean stateChanged, boolean dataChanged) {
+ // update state change counter.
+ if (_monitor != null) {
+ if (stateChanged) {
+ _monitor.increaseStateChangeEventCounter();
+ }
+ if (dataChanged) {
+ _monitor.increaseDataChangeEventCounter();
+ }
+ }
+ }
+
+ /**
+ * Creates a {@link IZkStateListener} that wraps a default
+ * implementation of {@link org.apache.helix.zookeeper.zkclient.deprecated.IZkStateListener}, which means the returned
+ * listener runs the methods of {@link org.apache.helix.zookeeper.zkclient.deprecated.IZkStateListener}.
+ * This is for backward compatibility with {@link org.apache.helix.zookeeper.zkclient.deprecated.IZkStateListener}.
+ */
+ private static class IZkStateListenerI0ItecImpl implements IZkStateListener {
+ private org.apache.helix.zookeeper.zkclient.deprecated.IZkStateListener _listener;
+
+ IZkStateListenerI0ItecImpl(
+ org.apache.helix.zookeeper.zkclient.deprecated.IZkStateListener listener) {
+ _listener = listener;
+ }
+
+ @Override
+ public void handleStateChanged(KeeperState keeperState) throws Exception {
+ _listener.handleStateChanged(keeperState);
+ }
+
+ @Override
+ public void handleNewSession(final String sessionId) throws Exception {
+ /*
+ * org.I0Itec.zkclient.IZkStateListener does not have handleNewSession(sessionId),
+ * so just call handleNewSession() by default.
+ */
+ _listener.handleNewSession();
+ }
+
+ @Override
+ public void handleSessionEstablishmentError(Throwable error) throws Exception {
+ _listener.handleSessionEstablishmentError(error);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof IZkStateListenerI0ItecImpl)) {
+ return false;
+ }
+ if (_listener == null) {
+ return false;
+ }
+
+ IZkStateListenerI0ItecImpl defaultListener = (IZkStateListenerI0ItecImpl) obj;
+
+ return _listener.equals(defaultListener._listener);
+ }
+
+ @Override
+ public int hashCode() {
+ /*
+ * The original listener's hashcode helps find the wrapped listener with the same original
+ * listener. This is helpful in unsubscribeStateChanges(listener) when finding the listener
+ * to remove.
+ */
+ return _listener.hashCode();
+ }
+ }
+
+ private void validateCurrentThread() {
+ if (_zookeeperEventThread != null && Thread.currentThread() == _zookeeperEventThread) {
+ throw new IllegalArgumentException("Must not be done in the zookeeper event thread.");
+ }
+ }
+
+ /**
+ * Converts a session id in hexadecimal notation from a long type session id.
+ * Ex. 1000a5ceb930004 is returned.
+ *
+ * @return String representation of session id in hexadecimal notation.
+ */
+ private static String toHexSessionId(long sessionId) {
+ return Long.toHexString(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
new file mode 100644
index 0000000..21de122
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/ZkConnection.java
@@ -0,0 +1,187 @@
+/**
+ * Copyright 2010 the original author or authors.
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.helix.zookeeper.zkclient;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.apache.helix.zookeeper.zkclient.exception.ZkException;
+import org.apache.log4j.Logger;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.Op;
+import org.apache.zookeeper.OpResult;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.ZooKeeper.States;
+import org.apache.zookeeper.data.ACL;
+import org.apache.zookeeper.data.Stat;
+
+
+public class ZkConnection implements IZkConnection {
+ private static final Logger LOG = Logger.getLogger(ZkConnection.class);
+
+ /** It is recommended to use quite large sessions timeouts for ZooKeeper. */
+ private static final int DEFAULT_SESSION_TIMEOUT = 30000;
+
+ private ZooKeeper _zk = null;
+ private Lock _zookeeperLock = new ReentrantLock();
+
+ private final String _servers;
+ private final int _sessionTimeOut;
+
+ public ZkConnection(String zkServers) {
+ this(zkServers, DEFAULT_SESSION_TIMEOUT);
+ }
+
+ public ZkConnection(String zkServers, int sessionTimeOut) {
+ _servers = zkServers;
+ _sessionTimeOut = sessionTimeOut;
+ }
+
+ @Override
+ public void connect(Watcher watcher) {
+ _zookeeperLock.lock();
+ try {
+ if (_zk != null) {
+ throw new IllegalStateException("zk client has already been started");
+ }
+ try {
+ LOG.debug("Creating new ZookKeeper instance to connect to " + _servers + ".");
+ _zk = new ZooKeeper(_servers, _sessionTimeOut, watcher);
+ } catch (IOException e) {
+ throw new ZkException("Unable to connect to " + _servers, e);
+ }
+ } finally {
+ _zookeeperLock.unlock();
+ }
+ }
+
+ @Override
+ public void close() throws InterruptedException {
+ _zookeeperLock.lock();
+ try {
+ if (_zk != null) {
+ LOG.debug("Closing ZooKeeper connected to " + _servers);
+ _zk.close();
+ _zk = null;
+ }
+ } finally {
+ _zookeeperLock.unlock();
+ }
+ }
+
+ protected void reconnect(Watcher watcher) throws InterruptedException {
+ _zookeeperLock.lock();
+ try {
+ if (_zk == null) {
+ throw new IllegalStateException("zk client has not been connected or already been closed");
+ }
+ ZooKeeper prevZk = _zk;
+ try {
+ LOG.debug("Creating new ZookKeeper instance to reconnect to " + _servers + ".");
+ _zk = new ZooKeeper(_servers, _sessionTimeOut, watcher);
+ prevZk.close();
+ } catch (IOException e) {
+ throw new ZkException("Unable to connect to " + _servers, e);
+ }
+ } finally {
+ _zookeeperLock.unlock();
+ }
+ }
+
+ @Override
+ public String create(String path, byte[] data, CreateMode mode)
+ throws KeeperException, InterruptedException {
+ return _zk.create(path, data, Ids.OPEN_ACL_UNSAFE, mode);
+ }
+
+ @Override
+ public String create(String path, byte[] data, List<ACL> acl, CreateMode mode)
+ throws KeeperException, InterruptedException {
+ return _zk.create(path, data, acl, mode);
+ }
+
+ @Override
+ public void delete(String path) throws InterruptedException, KeeperException {
+ _zk.delete(path, -1);
+ }
+
+ @Override
+ public boolean exists(String path, boolean watch) throws KeeperException, InterruptedException {
+ return _zk.exists(path, watch) != null;
+ }
+
+ @Override
+ public List<String> getChildren(final String path, final boolean watch)
+ throws KeeperException, InterruptedException {
+ return _zk.getChildren(path, watch);
+ }
+
+ @Override
+ public byte[] readData(String path, Stat stat, boolean watch)
+ throws KeeperException, InterruptedException {
+ return _zk.getData(path, watch, stat);
+ }
+
+ public void writeData(String path, byte[] data) throws KeeperException, InterruptedException {
+ writeData(path, data, -1);
+ }
+
+ @Override
+ public void writeData(String path, byte[] data, int version)
+ throws KeeperException, InterruptedException {
+ _zk.setData(path, data, version);
+ }
+
+ @Override
+ public Stat writeDataReturnStat(String path, byte[] data, int version)
+ throws KeeperException, InterruptedException {
+ return _zk.setData(path, data, version);
+ }
+
+ @Override
+ public States getZookeeperState() {
+ return _zk != null ? _zk.getState() : null;
+ }
+
+ public ZooKeeper getZookeeper() {
+ return _zk;
+ }
+
+ @Override
+ public long getCreateTime(String path) throws KeeperException, InterruptedException {
+ Stat stat = _zk.exists(path, false);
+ if (stat != null) {
+ return stat.getCtime();
+ }
+ return -1;
+ }
+
+ @Override
+ public String getServers() {
+ return _servers;
+ }
+
+ @Override
+ public List<OpResult> multi(Iterable<Op> ops) throws KeeperException, InterruptedException {
+ return _zk.multi(ops);
+ }
+
+ @Override
+ public void addAuthInfo(String scheme, byte[] auth) {
+ _zk.addAuthInfo(scheme, auth);
+ }
+}
diff --git a/helix-core/src/main/java/org/apache/helix/manager/zk/zookeeper/ZkEventThread.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/ZkEventThread.java
similarity index 96%
rename from helix-core/src/main/java/org/apache/helix/manager/zk/zookeeper/ZkEventThread.java
rename to zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/ZkEventThread.java
index f720216..cc1ad74 100644
--- a/helix-core/src/main/java/org/apache/helix/manager/zk/zookeeper/ZkEventThread.java
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/ZkEventThread.java
@@ -8,16 +8,17 @@
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
-package org.apache.helix.manager.zk.zookeeper;
+package org.apache.helix.zookeeper.zkclient;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
-import org.I0Itec.zkclient.exception.ZkInterruptedException;
+import org.apache.helix.zookeeper.zkclient.exception.ZkInterruptedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
/**
* All listeners registered at the {@link ZkClient} will be notified from this event thread. This is to prevent
* dead-lock situations. The {@link ZkClient} pulls some information out of the {@link ZooKeeper} events to signal
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/ZkLock.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/ZkLock.java
new file mode 100644
index 0000000..6294c39
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/ZkLock.java
@@ -0,0 +1,56 @@
+/**
+ * Copyright 2010 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.zookeeper.zkclient;
+
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
+
+public class ZkLock extends ReentrantLock {
+
+ private static final long serialVersionUID = 1L;
+
+ private Condition _dataChangedCondition = newCondition();
+ private Condition _stateChangedCondition = newCondition();
+ private Condition _zNodeEventCondition = newCondition();
+
+ /**
+ * This condition will be signaled if a zookeeper event was processed and the event contains a data/child change.
+ *
+ * @return the condition.
+ */
+ public Condition getDataChangedCondition() {
+ return _dataChangedCondition;
+ }
+
+ /**
+ * This condition will be signaled if a zookeeper event was processed and the event contains a state change
+ * (connected, disconnected, session expired, etc ...).
+ *
+ * @return the condition.
+ */
+ public Condition getStateChangedCondition() {
+ return _stateChangedCondition;
+ }
+
+ /**
+ * This condition will be signaled if any znode related zookeeper event was received.
+ *
+ * @return the condition.
+ */
+ public Condition getZNodeEventCondition() {
+ return _zNodeEventCondition;
+ }
+}
\ No newline at end of file
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/ZkServer.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/ZkServer.java
new file mode 100644
index 0000000..2ba4d59
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/ZkServer.java
@@ -0,0 +1,175 @@
+/**
+ * Copyright 2010 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.zookeeper.zkclient;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.util.Arrays;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+
+import org.apache.helix.zookeeper.zkclient.exception.ZkException;
+import org.apache.helix.zookeeper.zkclient.exception.ZkInterruptedException;
+import org.apache.helix.zookeeper.zkclient.serialize.BasicZkSerializer;
+import org.apache.helix.zookeeper.zkclient.serialize.SerializableSerializer;
+import org.apache.log4j.Logger;
+import org.apache.zookeeper.server.NIOServerCnxnFactory;
+import org.apache.zookeeper.server.ZooKeeperServer;
+
+public class ZkServer {
+
+ private final static Logger LOG = Logger.getLogger(ZkServer.class);
+
+ public static final int DEFAULT_PORT = 2181;
+ public static final int DEFAULT_TICK_TIME = 5000;
+ public static final int DEFAULT_MIN_SESSION_TIMEOUT = 2 * DEFAULT_TICK_TIME;
+
+ private String _dataDir;
+ private String _logDir;
+
+ private IDefaultNameSpace _defaultNameSpace;
+
+ private ZooKeeperServer _zk;
+ private NIOServerCnxnFactory _nioFactory;
+ private ZkClient _zkClient;
+ private int _port;
+ private int _tickTime;
+ private int _minSessionTimeout;
+
+ public ZkServer(String dataDir, String logDir, IDefaultNameSpace defaultNameSpace) {
+ this(dataDir, logDir, defaultNameSpace, DEFAULT_PORT);
+ }
+
+ public ZkServer(String dataDir, String logDir, IDefaultNameSpace defaultNameSpace, int port) {
+ this(dataDir, logDir, defaultNameSpace, port, DEFAULT_TICK_TIME);
+ }
+
+ public ZkServer(String dataDir, String logDir, IDefaultNameSpace defaultNameSpace, int port, int tickTime) {
+ this(dataDir, logDir, defaultNameSpace, port, tickTime, DEFAULT_MIN_SESSION_TIMEOUT);
+ }
+
+ public ZkServer(String dataDir, String logDir, IDefaultNameSpace defaultNameSpace, int port, int tickTime, int minSessionTimeout) {
+ _dataDir = dataDir;
+ _logDir = logDir;
+ _defaultNameSpace = defaultNameSpace;
+ _port = port;
+ _tickTime = tickTime;
+ _minSessionTimeout = minSessionTimeout;
+ }
+
+ public int getPort() {
+ return _port;
+ }
+
+ @PostConstruct
+ public void start() {
+ final String[] localHostNames = NetworkUtil.getLocalHostNames();
+ String names = "";
+ for (int i = 0; i < localHostNames.length; i++) {
+ final String name = localHostNames[i];
+ names += " " + name;
+ if (i + 1 != localHostNames.length) {
+ names += ",";
+ }
+ }
+ LOG.info("Starting ZkServer on: [" + names + "] port " + _port + "...");
+ startZooKeeperServer();
+ _zkClient = new ZkClient(new ZkConnection("localhost:" + _port), 10000, -1, new BasicZkSerializer(new SerializableSerializer()), null, null, null, false);
+ _defaultNameSpace.createDefaultNameSpace(_zkClient);
+ }
+
+ private void startZooKeeperServer() {
+ final String[] localhostHostNames = NetworkUtil.getLocalHostNames();
+ final String servers = "localhost:" + _port;
+ // check if this server needs to start a _client server.
+ int pos = -1;
+ LOG.debug("check if hostNames " + servers + " is in list: " + Arrays.asList(localhostHostNames));
+ if ((pos = NetworkUtil.hostNamesInList(servers, localhostHostNames)) != -1) {
+ // yes this server needs to start a zookeeper server
+ final String[] hosts = servers.split(",");
+ final String[] hostSplitted = hosts[pos].split(":");
+ int port = _port;
+ if (hostSplitted.length > 1) {
+ port = Integer.parseInt(hostSplitted[1]);
+ }
+ // check if this machine is already something running..
+ if (NetworkUtil.isPortFree(port)) {
+ final File dataDir = new File(_dataDir);
+ final File dataLogDir = new File(_logDir);
+ dataDir.mkdirs();
+ dataLogDir.mkdirs();
+
+ if (hosts.length > 1) {
+ // multiple zk servers
+ LOG.info("Start distributed zookeeper server...");
+ throw new IllegalArgumentException("Unable to start distributed zookeeper server");
+ }
+ // single zk server
+ LOG.info("Start single zookeeper server...");
+ LOG.info("data dir: " + dataDir.getAbsolutePath());
+ LOG.info("data log dir: " + dataLogDir.getAbsolutePath());
+ startSingleZkServer(_tickTime, dataDir, dataLogDir, port);
+ } else {
+ throw new IllegalStateException("Zookeeper port " + port + " was already in use. Running in single machine mode?");
+ }
+ }
+ }
+
+ private void startSingleZkServer(final int tickTime, final File dataDir, final File dataLogDir, final int port) {
+ try {
+ _zk = new ZooKeeperServer(dataDir, dataLogDir, tickTime);
+ _zk.setMinSessionTimeout(_minSessionTimeout);
+ _nioFactory = new NIOServerCnxnFactory();
+ int maxClientConnections = 0; // 0 means unlimited
+ _nioFactory.configure(new InetSocketAddress(port), maxClientConnections);
+ _nioFactory.startup(_zk);
+ } catch (IOException e) {
+ throw new ZkException("Unable to start single ZooKeeper server.", e);
+ } catch (InterruptedException e) {
+ throw new ZkInterruptedException(e);
+ }
+ }
+
+ @PreDestroy
+ public void shutdown() {
+ LOG.info("Shutting down ZkServer...");
+ try {
+ _zkClient.close();
+ } catch (ZkException e) {
+ LOG.warn("Error on closing zkclient: " + e.getClass().getName());
+ }
+ if (_nioFactory != null) {
+ _nioFactory.shutdown();
+ try {
+ _nioFactory.join();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ _nioFactory = null;
+ }
+ if (_zk != null) {
+ _zk.shutdown();
+ _zk = null;
+ }
+ LOG.info("Shutting down ZkServer...done");
+ }
+
+ public ZkClient getZkClient() {
+ return _zkClient;
+ }
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/annotation/PreFetch.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/annotation/PreFetch.java
new file mode 100644
index 0000000..f32081d
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/annotation/PreFetch.java
@@ -0,0 +1,29 @@
+package org.apache.helix.zookeeper.zkclient.annotation;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface PreFetch {
+ boolean enabled() default true;
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/callback/ZkAsyncCallbacks.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/callback/ZkAsyncCallbacks.java
new file mode 100644
index 0000000..04c4058
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/callback/ZkAsyncCallbacks.java
@@ -0,0 +1,193 @@
+package org.apache.helix.zookeeper.zkclient.callback;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.helix.zookeeper.zkclient.metric.ZkClientMonitor;
+import org.apache.zookeeper.AsyncCallback.DataCallback;
+import org.apache.zookeeper.AsyncCallback.StatCallback;
+import org.apache.zookeeper.AsyncCallback.StringCallback;
+import org.apache.zookeeper.AsyncCallback.VoidCallback;
+import org.apache.zookeeper.KeeperException.Code;
+import org.apache.zookeeper.data.Stat;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class ZkAsyncCallbacks {
+ private static Logger LOG = LoggerFactory.getLogger(ZkAsyncCallbacks.class);
+
+ public static class GetDataCallbackHandler extends DefaultCallback implements DataCallback {
+ public byte[] _data;
+ public Stat _stat;
+
+ @Override
+ public void handle() {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public void processResult(int rc, String path, Object ctx, byte[] data, Stat stat) {
+ if (rc == 0) {
+ _data = data;
+ _stat = stat;
+ // update ctx with data size
+ if (_data != null && ctx != null && ctx instanceof ZkAsyncCallContext) {
+ ZkAsyncCallContext zkCtx = (ZkAsyncCallContext) ctx;
+ zkCtx._bytes = _data.length;
+ }
+ }
+ callback(rc, path, ctx);
+ }
+ }
+
+ public static class SetDataCallbackHandler extends DefaultCallback implements StatCallback {
+ Stat _stat;
+
+ @Override
+ public void handle() {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public void processResult(int rc, String path, Object ctx, Stat stat) {
+ if (rc == 0) {
+ _stat = stat;
+ }
+ callback(rc, path, ctx);
+ }
+
+ public Stat getStat() {
+ return _stat;
+ }
+ }
+
+ public static class ExistsCallbackHandler extends DefaultCallback implements StatCallback {
+ public Stat _stat;
+
+ @Override
+ public void handle() {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public void processResult(int rc, String path, Object ctx, Stat stat) {
+ if (rc == 0) {
+ _stat = stat;
+ }
+ callback(rc, path, ctx);
+ }
+ }
+
+ public static class CreateCallbackHandler extends DefaultCallback implements StringCallback {
+ @Override
+ public void processResult(int rc, String path, Object ctx, String name) {
+ callback(rc, path, ctx);
+ }
+
+ @Override
+ public void handle() {
+ // TODO Auto-generated method stub
+ }
+ }
+
+ public static class DeleteCallbackHandler extends DefaultCallback implements VoidCallback {
+ @Override
+ public void processResult(int rc, String path, Object ctx) {
+ callback(rc, path, ctx);
+ }
+
+ @Override
+ public void handle() {
+ // TODO Auto-generated method stub
+ }
+ }
+
+ /**
+ * Default callback for zookeeper async api
+ */
+ public static abstract class DefaultCallback {
+ AtomicBoolean _lock = new AtomicBoolean(false);
+ int _rc = -1;
+
+ public void callback(int rc, String path, Object ctx) {
+ if (rc != 0 && LOG.isDebugEnabled()) {
+ LOG.debug(this + ", rc:" + Code.get(rc) + ", path: " + path);
+ }
+
+ if (ctx != null && ctx instanceof ZkAsyncCallContext) {
+ ZkAsyncCallContext zkCtx = (ZkAsyncCallContext) ctx;
+ if (zkCtx._monitor != null) {
+ if (zkCtx._isRead) {
+ zkCtx._monitor.record(path, zkCtx._bytes, zkCtx._startTimeMilliSec,
+ ZkClientMonitor.AccessType.READ);
+ } else {
+ zkCtx._monitor.record(path, zkCtx._bytes, zkCtx._startTimeMilliSec,
+ ZkClientMonitor.AccessType.WRITE);
+ }
+ }
+ }
+
+ _rc = rc;
+ handle();
+
+ synchronized (_lock) {
+ _lock.set(true);
+ _lock.notify();
+ }
+ }
+
+ public boolean waitForSuccess() {
+ try {
+ synchronized (_lock) {
+ while (!_lock.get()) {
+ _lock.wait();
+ }
+ }
+ } catch (InterruptedException e) {
+ LOG.error("Interrupted waiting for success", e);
+ }
+ return true;
+ }
+
+ public int getRc() {
+ return _rc;
+ }
+
+ abstract public void handle();
+ }
+
+ public static class ZkAsyncCallContext {
+ private long _startTimeMilliSec;
+ private int _bytes;
+ private ZkClientMonitor _monitor;
+ private boolean _isRead;
+
+ public ZkAsyncCallContext(final ZkClientMonitor monitor, long startTimeMilliSec, int bytes,
+ boolean isRead) {
+ _monitor = monitor;
+ _startTimeMilliSec = startTimeMilliSec;
+ _bytes = bytes;
+ _isRead = isRead;
+ }
+ }
+
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/deprecated/IZkStateListener.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/deprecated/IZkStateListener.java
new file mode 100644
index 0000000..1955fd3
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/deprecated/IZkStateListener.java
@@ -0,0 +1,53 @@
+/**
+ * Copyright 2010 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.zookeeper.zkclient.deprecated;
+
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+
+@Deprecated
+public interface IZkStateListener {
+
+ /**
+ * Called when the zookeeper connection state has changed.
+ *
+ * @param state
+ * The new state.
+ * @throws Exception
+ * On any error.
+ */
+ public void handleStateChanged(KeeperState state) throws Exception;
+
+ /**
+ * Called after the zookeeper session has expired and a new session has been created. You would have to re-create
+ * any ephemeral nodes here.
+ *
+ * @throws Exception
+ * On any error.
+ */
+ public void handleNewSession() throws Exception;
+
+ /**
+ * Called when a session cannot be re-established. This should be used to implement connection
+ * failure handling e.g. retry to connect or pass the error up
+ *
+ * @param error
+ * The error that prevents a session from being established
+ * @throws Exception
+ * On any error.
+ */
+ public void handleSessionEstablishmentError(final Throwable error) throws Exception;
+
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/exception/ZkBadVersionException.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/exception/ZkBadVersionException.java
new file mode 100644
index 0000000..a85fddd
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/exception/ZkBadVersionException.java
@@ -0,0 +1,39 @@
+/**
+ * Copyright 2010 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.zookeeper.zkclient.exception;
+
+import org.apache.zookeeper.KeeperException;
+
+public class ZkBadVersionException extends ZkException {
+
+ private static final long serialVersionUID = 1L;
+
+ public ZkBadVersionException() {
+ super();
+ }
+
+ public ZkBadVersionException(KeeperException cause) {
+ super(cause);
+ }
+
+ public ZkBadVersionException(String message, KeeperException cause) {
+ super(message, cause);
+ }
+
+ public ZkBadVersionException(String message) {
+ super(message);
+ }
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/exception/ZkException.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/exception/ZkException.java
new file mode 100644
index 0000000..f610449
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/exception/ZkException.java
@@ -0,0 +1,71 @@
+/**
+ * Copyright 2010 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.zookeeper.zkclient.exception;
+
+import org.apache.zookeeper.KeeperException;
+
+public class ZkException extends RuntimeException {
+
+ private static final long serialVersionUID = 1L;
+
+ public ZkException() {
+ super();
+ }
+
+ public ZkException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ZkException(String message) {
+ super(message);
+ }
+
+ public ZkException(Throwable cause) {
+ super(cause);
+ }
+
+ public static ZkException create(KeeperException e) {
+ switch (e.code()) {
+ // case DATAINCONSISTENCY:
+ // return new DataInconsistencyException();
+ // case CONNECTIONLOSS:
+ // return new ConnectionLossException();
+ case NONODE:
+ return new ZkNoNodeException(e);
+ // case NOAUTH:
+ // return new ZkNoAuthException();
+ case BADVERSION:
+ return new ZkBadVersionException(e);
+ // case NOCHILDRENFOREPHEMERALS:
+ // return new NoChildrenForEphemeralsException();
+ case NODEEXISTS:
+ return new ZkNodeExistsException(e);
+ // case INVALIDACL:
+ // return new ZkInvalidACLException();
+ // case AUTHFAILED:
+ // return new AuthFailedException();
+ // case NOTEMPTY:
+ // return new NotEmptyException();
+ // case SESSIONEXPIRED:
+ // return new SessionExpiredException();
+ // case INVALIDCALLBACK:
+ // return new InvalidCallbackException();
+
+ default:
+ return new ZkException(e);
+ }
+ }
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/exception/ZkInterruptedException.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/exception/ZkInterruptedException.java
new file mode 100644
index 0000000..64a9407
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/exception/ZkInterruptedException.java
@@ -0,0 +1,26 @@
+/**
+ * Copyright 2010 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.zookeeper.zkclient.exception;
+
+public class ZkInterruptedException extends ZkException {
+
+ private static final long serialVersionUID = 1L;
+
+ public ZkInterruptedException(InterruptedException e) {
+ super(e);
+ Thread.currentThread().interrupt();
+ }
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/exception/ZkMarshallingError.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/exception/ZkMarshallingError.java
new file mode 100644
index 0000000..3e1518b
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/exception/ZkMarshallingError.java
@@ -0,0 +1,37 @@
+/**
+ * Copyright 2010 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.zookeeper.zkclient.exception;
+
+public class ZkMarshallingError extends ZkException {
+
+ private static final long serialVersionUID = 1L;
+
+ public ZkMarshallingError() {
+ super();
+ }
+
+ public ZkMarshallingError(Throwable cause) {
+ super(cause);
+ }
+
+ public ZkMarshallingError(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ZkMarshallingError(String message) {
+ super(message);
+ }
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/exception/ZkNoNodeException.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/exception/ZkNoNodeException.java
new file mode 100644
index 0000000..f7b7bae
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/exception/ZkNoNodeException.java
@@ -0,0 +1,39 @@
+/**
+ * Copyright 2010 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.zookeeper.zkclient.exception;
+
+import org.apache.zookeeper.KeeperException;
+
+public class ZkNoNodeException extends ZkException {
+
+ private static final long serialVersionUID = 1L;
+
+ public ZkNoNodeException() {
+ super();
+ }
+
+ public ZkNoNodeException(KeeperException cause) {
+ super(cause);
+ }
+
+ public ZkNoNodeException(String message, KeeperException cause) {
+ super(message, cause);
+ }
+
+ public ZkNoNodeException(String message) {
+ super(message);
+ }
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/exception/ZkNodeExistsException.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/exception/ZkNodeExistsException.java
new file mode 100644
index 0000000..9624a12
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/exception/ZkNodeExistsException.java
@@ -0,0 +1,39 @@
+/**
+ * Copyright 2010 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.zookeeper.zkclient.exception;
+
+import org.apache.zookeeper.KeeperException;
+
+public class ZkNodeExistsException extends ZkException {
+
+ private static final long serialVersionUID = 1L;
+
+ public ZkNodeExistsException() {
+ super();
+ }
+
+ public ZkNodeExistsException(KeeperException cause) {
+ super(cause);
+ }
+
+ public ZkNodeExistsException(String message, KeeperException cause) {
+ super(message, cause);
+ }
+
+ public ZkNodeExistsException(String message) {
+ super(message);
+ }
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/exception/ZkSessionMismatchedException.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/exception/ZkSessionMismatchedException.java
new file mode 100644
index 0000000..88b17c0
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/exception/ZkSessionMismatchedException.java
@@ -0,0 +1,33 @@
+package org.apache.helix.zookeeper.zkclient.exception;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Exception thrown when an action is taken by an expected zk session which
+ * does not match the actual zk session.
+ */
+public class ZkSessionMismatchedException extends ZkException {
+
+ private static final long serialVersionUID = 1L;
+
+ public ZkSessionMismatchedException(String message) {
+ super(message);
+ }
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/exception/ZkTimeoutException.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/exception/ZkTimeoutException.java
new file mode 100644
index 0000000..738ad08
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/exception/ZkTimeoutException.java
@@ -0,0 +1,37 @@
+/**
+ * Copyright 2010 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.zookeeper.zkclient.exception;
+
+public class ZkTimeoutException extends ZkException {
+
+ private static final long serialVersionUID = 1L;
+
+ public ZkTimeoutException() {
+ super();
+ }
+
+ public ZkTimeoutException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ZkTimeoutException(String message) {
+ super(message);
+ }
+
+ public ZkTimeoutException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/metric/ZkClientMonitor.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/metric/ZkClientMonitor.java
new file mode 100644
index 0000000..9b0ec34
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/metric/ZkClientMonitor.java
@@ -0,0 +1,252 @@
+package org.apache.helix.zookeeper.zkclient.metric;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import javax.management.JMException;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+
+import org.apache.helix.monitoring.mbeans.MBeanRegistrar;
+import org.apache.helix.monitoring.mbeans.MonitorDomainNames;
+import org.apache.helix.monitoring.mbeans.dynamicMBeans.DynamicMBeanProvider;
+import org.apache.helix.monitoring.mbeans.dynamicMBeans.DynamicMetric;
+import org.apache.helix.monitoring.mbeans.dynamicMBeans.SimpleDynamicMetric;
+import org.apache.helix.monitoring.mbeans.exception.MetricException;
+import org.apache.helix.zookeeper.zkclient.ZkEventThread;
+
+
+public class ZkClientMonitor extends DynamicMBeanProvider {
+ public static final String MONITOR_TYPE = "Type";
+ public static final String MONITOR_KEY = "Key";
+ protected static final String MBEAN_DESCRIPTION = "Helix Zookeeper Client Monitor";
+
+ public enum AccessType {
+ READ, WRITE
+ }
+
+ private String _sensorName;
+ private String _monitorType;
+ private String _monitorKey;
+ private String _monitorInstanceName;
+ private boolean _monitorRootOnly;
+
+ private SimpleDynamicMetric<Long> _stateChangeEventCounter;
+ private SimpleDynamicMetric<Long> _dataChangeEventCounter;
+ private SimpleDynamicMetric<Long> _outstandingRequestGauge;
+
+ private ZkThreadMetric _zkEventThreadMetric;
+
+ private Map<ZkClientPathMonitor.PredefinedPath, ZkClientPathMonitor> _zkClientPathMonitorMap =
+ new ConcurrentHashMap<>();
+
+ public ZkClientMonitor(String monitorType, String monitorKey, String monitorInstanceName,
+ boolean monitorRootOnly, ZkEventThread zkEventThread) {
+ if (monitorKey == null || monitorKey.isEmpty() || monitorType == null || monitorType
+ .isEmpty()) {
+ throw new MetricException("Cannot create ZkClientMonitor without monitor key and type.");
+ }
+
+ _sensorName =
+ String.format("%s.%s.%s", MonitorDomainNames.HelixZkClient.name(), monitorType, monitorKey);
+ _monitorType = monitorType;
+ _monitorKey = monitorKey;
+ _monitorInstanceName = monitorInstanceName;
+ _monitorRootOnly = monitorRootOnly;
+
+ _stateChangeEventCounter = new SimpleDynamicMetric("StateChangeEventCounter", 0l);
+ _dataChangeEventCounter = new SimpleDynamicMetric("DataChangeEventCounter", 0l);
+ _outstandingRequestGauge = new SimpleDynamicMetric("OutstandingRequestGauge", 0l);
+ if (zkEventThread != null) {
+ _zkEventThreadMetric = new ZkThreadMetric(zkEventThread);
+ }
+ }
+
+ public static ObjectName getObjectName(String monitorType, String monitorKey,
+ String monitorInstanceName) throws MalformedObjectNameException {
+ return MBeanRegistrar
+ .buildObjectName(MonitorDomainNames.HelixZkClient.name(), MONITOR_TYPE, monitorType,
+ MONITOR_KEY,
+ (monitorKey + (monitorInstanceName == null ? "" : "." + monitorInstanceName)));
+ }
+
+ @Override
+ public DynamicMBeanProvider register() throws JMException {
+ List<DynamicMetric<?, ?>> attributeList = new ArrayList<>();
+ attributeList.add(_dataChangeEventCounter);
+ attributeList.add(_outstandingRequestGauge);
+ attributeList.add(_stateChangeEventCounter);
+ if (_zkEventThreadMetric != null) {
+ attributeList.add(_zkEventThreadMetric);
+ }
+ doRegister(attributeList, MBEAN_DESCRIPTION,
+ getObjectName(_monitorType, _monitorKey, _monitorInstanceName));
+ for (ZkClientPathMonitor.PredefinedPath path : ZkClientPathMonitor.PredefinedPath.values()) {
+ // If monitor root path only, check if the current path is Root.
+ // Otherwise, add monitors for every path.
+ if (!_monitorRootOnly || path.equals(ZkClientPathMonitor.PredefinedPath.Root)) {
+ _zkClientPathMonitorMap.put(path,
+ new ZkClientPathMonitor(path, _monitorType, _monitorKey, _monitorInstanceName)
+ .register());
+ }
+ }
+ return this;
+ }
+
+ /**
+ * After unregistered, the MBean can't be registered again, a new monitor has be to created.
+ */
+ public void unregister() {
+ super.unregister();
+ for (ZkClientPathMonitor zkClientPathMonitor : _zkClientPathMonitorMap.values()) {
+ zkClientPathMonitor.unregister();
+ }
+ }
+
+ @Override
+ public String getSensorName() {
+ return _sensorName;
+ }
+
+ public void increaseStateChangeEventCounter() {
+ synchronized (_stateChangeEventCounter) {
+ _stateChangeEventCounter.updateValue(_stateChangeEventCounter.getValue() + 1);
+ }
+ }
+
+ public void increaseDataChangeEventCounter() {
+ synchronized (_dataChangeEventCounter) {
+ _dataChangeEventCounter.updateValue(_dataChangeEventCounter.getValue() + 1);
+ }
+ }
+
+ public void increaseOutstandingRequestGauge() {
+ synchronized (_outstandingRequestGauge) {
+ _outstandingRequestGauge.updateValue(_outstandingRequestGauge.getValue() + 1);
+ }
+ }
+
+ public void decreaseOutstandingRequestGauge() {
+ synchronized (_outstandingRequestGauge) {
+ _outstandingRequestGauge.updateValue(_outstandingRequestGauge.getValue() - 1);
+ }
+ }
+
+ public void recordDataPropagationLatency(String path, long latencyMilliSec) {
+ if (null == path) {
+ return;
+ }
+ Arrays.stream(ZkClientPathMonitor.PredefinedPath.values())
+ .filter(predefinedPath -> predefinedPath.match(path))
+ .forEach(predefinedPath -> {
+ ZkClientPathMonitor zkClientPathMonitor = _zkClientPathMonitorMap.get(predefinedPath);
+ if (zkClientPathMonitor != null) {
+ zkClientPathMonitor.recordDataPropagationLatency(latencyMilliSec);
+ }
+ });
+ }
+
+ private void record(String path, int bytes, long latencyMilliSec, boolean isFailure,
+ boolean isRead) {
+ if (null == path) {
+ return;
+ }
+ Arrays.stream(ZkClientPathMonitor.PredefinedPath.values())
+ .filter(predefinedPath -> predefinedPath.match(path))
+ .forEach(predefinedPath -> {
+ ZkClientPathMonitor zkClientPathMonitor = _zkClientPathMonitorMap.get(predefinedPath);
+ if (zkClientPathMonitor != null) {
+ zkClientPathMonitor.record(bytes, latencyMilliSec, isFailure, isRead);
+ }
+ });
+ }
+
+ public void record(String path, int dataSize, long startTimeMilliSec, AccessType accessType) {
+ switch (accessType) {
+ case READ:
+ record(path, dataSize, System.currentTimeMillis() - startTimeMilliSec, false, true);
+ return;
+ case WRITE:
+ record(path, dataSize, System.currentTimeMillis() - startTimeMilliSec, false, false);
+ return;
+ default:
+ return;
+ }
+ }
+
+ public void recordFailure(String path, AccessType accessType) {
+ switch (accessType) {
+ case READ:
+ record(path, 0, 0, true, true);
+ return;
+ case WRITE:
+ record(path, 0, 0, true, false);
+ return;
+ default:
+ return;
+ }
+ }
+
+ class ZkThreadMetric extends DynamicMetric<ZkEventThread, ZkEventThread> {
+ public ZkThreadMetric(ZkEventThread eventThread) {
+ super("ZkEventThead", eventThread);
+ }
+
+ @Override
+ protected Set<MBeanAttributeInfo> generateAttributeInfos(String metricName,
+ ZkEventThread eventThread) {
+ Set<MBeanAttributeInfo> attributeInfoSet = new HashSet<>();
+ attributeInfoSet.add(new MBeanAttributeInfo("PendingCallbackGauge", Long.TYPE.getName(),
+ DEFAULT_ATTRIBUTE_DESCRIPTION, true, false, false));
+ attributeInfoSet.add(new MBeanAttributeInfo("TotalCallbackCounter", Long.TYPE.getName(),
+ DEFAULT_ATTRIBUTE_DESCRIPTION, true, false, false));
+ attributeInfoSet.add(
+ new MBeanAttributeInfo("TotalCallbackHandledCounter", Long.TYPE.getName(),
+ DEFAULT_ATTRIBUTE_DESCRIPTION, true, false, false));
+ return attributeInfoSet;
+ }
+
+ @Override
+ public Object getAttributeValue(String attributeName) {
+ switch (attributeName) {
+ case "PendingCallbackGauge":
+ return getMetricObject().getPendingEventsCount();
+ case "TotalCallbackCounter":
+ return getMetricObject().getTotalEventCount();
+ case "TotalCallbackHandledCounter":
+ return getMetricObject().getTotalHandledEventCount();
+ default:
+ throw new MetricException("Unknown attribute name: " + attributeName);
+ }
+ }
+
+ @Override
+ public void updateValue(ZkEventThread newEventThread) {
+ setMetricObject(newEventThread);
+ }
+ }
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/metric/ZkClientPathMonitor.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/metric/ZkClientPathMonitor.java
new file mode 100644
index 0000000..35f7943
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/metric/ZkClientPathMonitor.java
@@ -0,0 +1,248 @@
+package org.apache.helix.zookeeper.zkclient.metric;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import javax.management.JMException;
+import javax.management.ObjectName;
+
+import com.codahale.metrics.Histogram;
+import com.codahale.metrics.SlidingTimeWindowArrayReservoir;
+import org.apache.helix.monitoring.mbeans.MonitorDomainNames;
+import org.apache.helix.monitoring.mbeans.dynamicMBeans.DynamicMBeanProvider;
+import org.apache.helix.monitoring.mbeans.dynamicMBeans.DynamicMetric;
+import org.apache.helix.monitoring.mbeans.dynamicMBeans.HistogramDynamicMetric;
+import org.apache.helix.monitoring.mbeans.dynamicMBeans.SimpleDynamicMetric;
+
+
+public class ZkClientPathMonitor extends DynamicMBeanProvider {
+ public static final String MONITOR_PATH = "PATH";
+ private final String _sensorName;
+ private final String _type;
+ private final String _key;
+ private final String _instanceName;
+ private final PredefinedPath _path;
+
+ public enum PredefinedPath {
+ IdealStates(".*/IDEALSTATES/.*"),
+ Instances(".*/INSTANCES/.*"),
+ Configs(".*/CONFIGS/.*"),
+ Controller(".*/CONTROLLER/.*"),
+ ExternalView(".*/EXTERNALVIEW/.*"),
+ LiveInstances(".*/LIVEINSTANCES/.*"),
+ PropertyStore(".*/PROPERTYSTORE/.*"),
+ CurrentStates(".*/CURRENTSTATES/.*"),
+ Messages(".*/MESSAGES/.*"),
+ Root(".*");
+
+ private final String _matchString;
+
+ PredefinedPath(String matchString) {
+ _matchString = matchString;
+ }
+
+ public boolean match(String path) {
+ return path.matches(this._matchString);
+ }
+ }
+
+ public enum PredefinedMetricDomains {
+ WriteTotalLatencyCounter,
+ ReadTotalLatencyCounter,
+ WriteFailureCounter,
+ ReadFailureCounter,
+ WriteBytesCounter,
+ ReadBytesCounter,
+ WriteCounter,
+ ReadCounter,
+ ReadLatencyGauge,
+ WriteLatencyGauge,
+ ReadBytesGauge,
+ WriteBytesGauge,
+ /*
+ * The latency between a ZK data change happening on the server side and the client side.
+ */
+ DataPropagationLatencyGauge,
+ /**
+ * @deprecated
+ * This domain name has a typo. Keep it in case its historical metric data is being used.
+ */
+ @Deprecated
+ DataPropagationLatencyGuage
+ }
+
+ private SimpleDynamicMetric<Long> _readCounter;
+ private SimpleDynamicMetric<Long> _writeCounter;
+ private SimpleDynamicMetric<Long> _readBytesCounter;
+ private SimpleDynamicMetric<Long> _writeBytesCounter;
+ private SimpleDynamicMetric<Long> _readFailureCounter;
+ private SimpleDynamicMetric<Long> _writeFailureCounter;
+ private SimpleDynamicMetric<Long> _readTotalLatencyCounter;
+ private SimpleDynamicMetric<Long> _writeTotalLatencyCounter;
+
+ private HistogramDynamicMetric _readLatencyGauge;
+ private HistogramDynamicMetric _writeLatencyGauge;
+ private HistogramDynamicMetric _readBytesGauge;
+ private HistogramDynamicMetric _writeBytesGauge;
+ private HistogramDynamicMetric _dataPropagationLatencyGauge;
+
+ /**
+ * @deprecated
+ * Keep it for backward-compatibility purpose.
+ */
+ @Deprecated
+ private HistogramDynamicMetric _dataPropagationLatencyGuage;
+
+ @Override
+ public String getSensorName() {
+ return _sensorName;
+ }
+
+ public ZkClientPathMonitor(PredefinedPath path, String monitorType, String monitorKey,
+ String monitorInstanceName) {
+ _type = monitorType;
+ _key = monitorKey;
+ _instanceName = monitorInstanceName;
+ _path = path;
+ _sensorName = String
+ .format("%s.%s.%s.%s", MonitorDomainNames.HelixZkClient.name(), monitorType, monitorKey,
+ path.name());
+
+ _writeTotalLatencyCounter =
+ new SimpleDynamicMetric(PredefinedMetricDomains.WriteTotalLatencyCounter.name(), 0l);
+ _readTotalLatencyCounter =
+ new SimpleDynamicMetric(PredefinedMetricDomains.ReadTotalLatencyCounter.name(), 0l);
+ _writeFailureCounter =
+ new SimpleDynamicMetric(PredefinedMetricDomains.WriteFailureCounter.name(), 0l);
+ _readFailureCounter =
+ new SimpleDynamicMetric(PredefinedMetricDomains.ReadFailureCounter.name(), 0l);
+ _writeBytesCounter =
+ new SimpleDynamicMetric(PredefinedMetricDomains.WriteBytesCounter.name(), 0l);
+ _readBytesCounter =
+ new SimpleDynamicMetric(PredefinedMetricDomains.ReadBytesCounter.name(), 0l);
+ _writeCounter = new SimpleDynamicMetric(PredefinedMetricDomains.WriteCounter.name(), 0l);
+ _readCounter = new SimpleDynamicMetric(PredefinedMetricDomains.ReadCounter.name(), 0l);
+
+ _readLatencyGauge = new HistogramDynamicMetric(PredefinedMetricDomains.ReadLatencyGauge.name(),
+ new Histogram(
+ new SlidingTimeWindowArrayReservoir(getResetIntervalInMs(), TimeUnit.MILLISECONDS)));
+ _writeLatencyGauge =
+ new HistogramDynamicMetric(PredefinedMetricDomains.WriteLatencyGauge.name(), new Histogram(
+ new SlidingTimeWindowArrayReservoir(getResetIntervalInMs(), TimeUnit.MILLISECONDS)));
+ _readBytesGauge = new HistogramDynamicMetric(PredefinedMetricDomains.ReadBytesGauge.name(),
+ new Histogram(
+ new SlidingTimeWindowArrayReservoir(getResetIntervalInMs(), TimeUnit.MILLISECONDS)));
+ _writeBytesGauge = new HistogramDynamicMetric(PredefinedMetricDomains.WriteBytesGauge.name(),
+ new Histogram(
+ new SlidingTimeWindowArrayReservoir(getResetIntervalInMs(), TimeUnit.MILLISECONDS)));
+ _dataPropagationLatencyGauge =
+ new HistogramDynamicMetric(PredefinedMetricDomains.DataPropagationLatencyGauge.name(),
+ new Histogram(new SlidingTimeWindowArrayReservoir(getResetIntervalInMs(),
+ TimeUnit.MILLISECONDS)));
+
+ // This is deprecated and keep it for backward-compatibility purpose.
+ _dataPropagationLatencyGuage =
+ new HistogramDynamicMetric(PredefinedMetricDomains.DataPropagationLatencyGuage.name(),
+ new Histogram(new SlidingTimeWindowArrayReservoir(getResetIntervalInMs(),
+ TimeUnit.MILLISECONDS)));
+ }
+
+ public ZkClientPathMonitor register() throws JMException {
+ List<DynamicMetric<?, ?>> attributeList = new ArrayList<>();
+ attributeList.add(_readCounter);
+ attributeList.add(_writeCounter);
+ attributeList.add(_readBytesCounter);
+ attributeList.add(_writeBytesCounter);
+ attributeList.add(_readFailureCounter);
+ attributeList.add(_writeFailureCounter);
+ attributeList.add(_readTotalLatencyCounter);
+ attributeList.add(_writeTotalLatencyCounter);
+ attributeList.add(_readLatencyGauge);
+ attributeList.add(_writeLatencyGauge);
+ attributeList.add(_readBytesGauge);
+ attributeList.add(_writeBytesGauge);
+ attributeList.add(_dataPropagationLatencyGauge);
+ // This is deprecated and keep it for backward-compatibility purpose.
+ attributeList.add(_dataPropagationLatencyGuage);
+
+ ObjectName objectName = new ObjectName(String
+ .format("%s,%s=%s", ZkClientMonitor.getObjectName(_type, _key, _instanceName).toString(),
+ MONITOR_PATH, _path.name()));
+ doRegister(attributeList, ZkClientMonitor.MBEAN_DESCRIPTION, objectName);
+
+ return this;
+ }
+
+ protected synchronized void record(int bytes, long latencyMilliSec, boolean isFailure,
+ boolean isRead) {
+ if (isFailure) {
+ increaseFailureCounter(isRead);
+ } else {
+ increaseCounter(isRead);
+ increaseTotalLatency(isRead, latencyMilliSec);
+ if (bytes > 0) {
+ increaseBytesCounter(isRead, bytes);
+ }
+ }
+ }
+
+ public void recordDataPropagationLatency(long latency) {
+ _dataPropagationLatencyGauge.updateValue(latency);
+ _dataPropagationLatencyGuage.updateValue(latency);
+ }
+
+ private void increaseFailureCounter(boolean isRead) {
+ if (isRead) {
+ _readFailureCounter.updateValue(_readFailureCounter.getValue() + 1);
+ } else {
+ _writeFailureCounter.updateValue(_writeFailureCounter.getValue() + 1);
+ }
+ }
+
+ private void increaseCounter(boolean isRead) {
+ if (isRead) {
+ _readCounter.updateValue(_readCounter.getValue() + 1);
+ } else {
+ _writeCounter.updateValue(_writeCounter.getValue() + 1);
+ }
+ }
+
+ private void increaseBytesCounter(boolean isRead, int bytes) {
+ if (isRead) {
+ _readBytesCounter.updateValue(_readBytesCounter.getValue() + bytes);
+ _readBytesGauge.updateValue((long) bytes);
+ } else {
+ _writeBytesCounter.updateValue(_writeBytesCounter.getValue() + bytes);
+ _writeBytesGauge.updateValue((long) bytes);
+ }
+ }
+
+ private void increaseTotalLatency(boolean isRead, long latencyDelta) {
+ if (isRead) {
+ _readTotalLatencyCounter.updateValue(_readTotalLatencyCounter.getValue() + latencyDelta);
+ _readLatencyGauge.updateValue(latencyDelta);
+ } else {
+ _writeTotalLatencyCounter.updateValue(_writeTotalLatencyCounter.getValue() + latencyDelta);
+ _writeLatencyGauge.updateValue(latencyDelta);
+ }
+ }
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/serialize/BasicZkSerializer.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/serialize/BasicZkSerializer.java
new file mode 100644
index 0000000..dc8d003
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/serialize/BasicZkSerializer.java
@@ -0,0 +1,41 @@
+package org.apache.helix.zookeeper.zkclient.serialize;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Basic path based serializer which ignores the path and delegates
+ * serialization into a regular {@link ZkSerializer}
+ */
+public class BasicZkSerializer implements PathBasedZkSerializer {
+ private final ZkSerializer _delegate;
+
+ public BasicZkSerializer(ZkSerializer delegate) {
+ _delegate = delegate;
+ }
+
+ public byte[] serialize(Object data, String path) {
+ return _delegate.serialize(data);
+ }
+
+ @Override
+ public Object deserialize(byte[] bytes, String path) {
+ return _delegate.deserialize(bytes);
+ }
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/serialize/BytesPushThroughSerializer.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/serialize/BytesPushThroughSerializer.java
new file mode 100644
index 0000000..f566483
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/serialize/BytesPushThroughSerializer.java
@@ -0,0 +1,36 @@
+/**
+ * Copyright 2010 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.zookeeper.zkclient.serialize;
+
+import org.apache.helix.zookeeper.zkclient.exception.ZkMarshallingError;
+
+
+/**
+ * A {@link ZkSerializer} which simply passes byte arrays to zk and back.
+ */
+public class BytesPushThroughSerializer implements ZkSerializer {
+
+ @Override
+ public Object deserialize(byte[] bytes) throws ZkMarshallingError {
+ return bytes;
+ }
+
+ @Override
+ public byte[] serialize(Object bytes) throws ZkMarshallingError {
+ return (byte[]) bytes;
+ }
+
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/serialize/PathBasedZkSerializer.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/serialize/PathBasedZkSerializer.java
new file mode 100644
index 0000000..93d4b61
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/serialize/PathBasedZkSerializer.java
@@ -0,0 +1,45 @@
+package org.apache.helix.zookeeper.zkclient.serialize;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.helix.zookeeper.zkclient.exception.ZkMarshallingError;
+
+
+public interface PathBasedZkSerializer {
+
+ /**
+ * Serialize data differently according to different paths
+ * @param data
+ * @param path
+ * @return
+ * @throws ZkMarshallingError
+ */
+ public byte[] serialize(Object data, String path) throws ZkMarshallingError;
+
+ /**
+ * Deserialize data differently according to different paths
+ * @param bytes
+ * @param path
+ * @return
+ * @throws ZkMarshallingError
+ */
+ public Object deserialize(byte[] bytes, String path) throws ZkMarshallingError;
+
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/serialize/SerializableSerializer.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/serialize/SerializableSerializer.java
new file mode 100644
index 0000000..65a5983
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/serialize/SerializableSerializer.java
@@ -0,0 +1,55 @@
+/**
+ * Copyright 2010 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.zookeeper.zkclient.serialize;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import org.apache.helix.zookeeper.zkclient.exception.ZkMarshallingError;
+
+
+public class SerializableSerializer implements ZkSerializer {
+
+ @Override
+ public Object deserialize(byte[] bytes) throws ZkMarshallingError {
+ try {
+ ObjectInputStream inputStream = new TcclAwareObjectIputStream(new ByteArrayInputStream(bytes));
+ Object object = inputStream.readObject();
+ return object;
+ } catch (ClassNotFoundException e) {
+ throw new ZkMarshallingError("Unable to find object class.", e);
+ } catch (IOException e) {
+ throw new ZkMarshallingError(e);
+ }
+ }
+
+ @Override
+ public byte[] serialize(Object serializable) throws ZkMarshallingError {
+ try {
+ ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream();
+ ObjectOutputStream stream = new ObjectOutputStream(byteArrayOS);
+ stream.writeObject(serializable);
+ stream.close();
+ return byteArrayOS.toByteArray();
+ } catch (IOException e) {
+ throw new ZkMarshallingError(e);
+ }
+ }
+
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/serialize/TcclAwareObjectIputStream.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/serialize/TcclAwareObjectIputStream.java
new file mode 100644
index 0000000..8fb21e3
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/serialize/TcclAwareObjectIputStream.java
@@ -0,0 +1,82 @@
+/**
+ * Copyright 2010 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.zookeeper.zkclient.serialize;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectStreamClass;
+import java.lang.reflect.Proxy;
+
+/**
+ * An ObjectInputStream that is aware of the TCCL.
+ */
+public class TcclAwareObjectIputStream extends ObjectInputStream {
+
+ public TcclAwareObjectIputStream(InputStream in) throws IOException {
+ super(in);
+ }
+
+ /**
+ * Load the local class equivalent of the specified stream class
+ * description.
+ * Uses the current class {@link ClassLoader} and falls back to the {@link Thread} context {@link ClassLoader}.
+ */
+ protected Class resolveClass(ObjectStreamClass classDesc) throws IOException, ClassNotFoundException {
+ try {
+ return getClass().getClassLoader().loadClass(classDesc.getName());
+ } catch (ClassNotFoundException ex) {
+ ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+ if (tccl != null) {
+ return tccl.loadClass(classDesc.getName());
+ } else {
+ throw ex;
+ }
+ }
+ }
+
+ /**
+ * Returns a proxy class that implements the interfaces named in a proxy
+ * class descriptor; subclasses may implement this method to read custom
+ * data from the stream along with the descriptors for dynamic proxy
+ * classes, allowing them to use an alternate loading mechanism for the
+ * interfaces and the proxy class.
+ *
+ * For each interface uses the current class {@link ClassLoader} and falls back to the {@link Thread} context {@link ClassLoader}.
+ */
+ protected Class resolveProxyClass(String[] interfaces) throws IOException, ClassNotFoundException {
+ ClassLoader cl = getClass().getClassLoader();
+ Class[] cinterfaces = new Class[interfaces.length];
+
+ for (int i = 0; i < interfaces.length; i++) {
+ try {
+ cinterfaces[i] = cl.loadClass(interfaces[i]);
+ } catch (ClassNotFoundException ex) {
+ ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+ if (tccl != null) {
+ return tccl.loadClass(interfaces[i]);
+ } else {
+ throw ex;
+ }
+ }
+ }
+ try {
+ return Proxy.getProxyClass(cinterfaces[0].getClassLoader(), cinterfaces);
+ } catch (IllegalArgumentException e) {
+ throw new ClassNotFoundException(null, e);
+ }
+ }
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/serialize/ZkSerializer.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/serialize/ZkSerializer.java
new file mode 100644
index 0000000..e9f065e
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/serialize/ZkSerializer.java
@@ -0,0 +1,33 @@
+/**
+ * Copyright 2010 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.helix.zookeeper.zkclient.serialize;
+
+import org.apache.helix.zookeeper.zkclient.exception.ZkMarshallingError;
+
+
+/**
+ * Zookeeper is able to store data in form of byte arrays. This interface is a bridge between those byte-array format
+ * and higher level objects.
+ *
+ * @see BytesPushThroughSerializer
+ * @see SerializableSerializer
+ */
+public interface ZkSerializer {
+
+ public byte[] serialize(Object data) throws ZkMarshallingError;
+
+ public Object deserialize(byte[] bytes) throws ZkMarshallingError;
+}
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/util/ExponentialBackoffStrategy.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/util/ExponentialBackoffStrategy.java
new file mode 100644
index 0000000..c6c6cc8
--- /dev/null
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/util/ExponentialBackoffStrategy.java
@@ -0,0 +1,53 @@
+package org.apache.helix.zookeeper.zkclient.util;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Random;
+
+
+public class ExponentialBackoffStrategy {
+ private final long INIT_RETRY_INTERVAL = 500;
+ private final long _maxRetryInterval;
+ private final boolean _addJitter;
+ private final Random _ran;
+
+ public ExponentialBackoffStrategy(long maxRetryInterval, boolean addJitter) {
+ _maxRetryInterval = maxRetryInterval;
+ _addJitter = addJitter;
+ _ran = new Random(System.currentTimeMillis());
+ }
+
+ public long getNextWaitInterval(int numberOfTriesFailed) {
+ double exponentialMultiplier = Math.pow(2.0, numberOfTriesFailed - 1);
+ double result = exponentialMultiplier * INIT_RETRY_INTERVAL;
+
+ if (_maxRetryInterval > 0 && result > _maxRetryInterval) {
+ result = _maxRetryInterval;
+ }
+
+ if (_addJitter) {
+ // Adding jitter so the real result would be 75% to 100% of the original result.
+ // Don't directly add jitter here, since it may exceed the max retry interval setup
+ result = result * (0.75 + _ran.nextDouble() % 0.25);
+ }
+
+ return (long) result;
+ }
+}
diff --git a/zookeeper-api/src/test/conf/testng.xml b/zookeeper-api/src/test/conf/testng.xml
new file mode 100644
index 0000000..6c78c76a4
--- /dev/null
+++ b/zookeeper-api/src/test/conf/testng.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
+<suite name="Suite" parallel="false">
+ <test name="Test" preserve-order="true">
+ <packages>
+ <package name="org.apache.helix.zookeeper.api.*"/>
+ </packages>
+ </test>
+</suite>
diff --git a/zookeeper-api/src/test/resources/log4j.properties b/zookeeper-api/src/test/resources/log4j.properties
new file mode 100644
index 0000000..24b6d10
--- /dev/null
+++ b/zookeeper-api/src/test/resources/log4j.properties
@@ -0,0 +1,41 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# Set root logger level to DEBUG and its only appender to R.
+log4j.rootLogger=ERROR, C
+
+# A1 is set to be a ConsoleAppender.
+log4j.appender.C=org.apache.log4j.ConsoleAppender
+log4j.appender.C.layout=org.apache.log4j.PatternLayout
+log4j.appender.C.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
+
+log4j.appender.R=org.apache.log4j.RollingFileAppender
+log4j.appender.R.layout=org.apache.log4j.PatternLayout
+log4j.appender.R.layout.ConversionPattern=%5p [%C:%M] (%F:%L) - %m%n
+log4j.appender.R.File=target/ClusterManagerLogs/log.txt
+
+log4j.appender.STATUSDUMP=org.apache.log4j.RollingFileAppender
+log4j.appender.STATUSDUMP.layout=org.apache.log4j.SimpleLayout
+log4j.appender.STATUSDUMP.File=target/ClusterManagerLogs/statusUpdates.log
+
+log4j.logger.org.I0Itec=ERROR
+log4j.logger.org.apache=ERROR
+log4j.logger.com.noelios=ERROR
+log4j.logger.org.restlet=ERROR
+
+log4j.logger.org.apache.helix.monitoring.ZKPathDataDumpTask=ERROR,STATUSDUMP
diff --git a/zookeeper-api/zookeeper-api-0.9.2-SNAPSHOT.ivy b/zookeeper-api/zookeeper-api-0.9.2-SNAPSHOT.ivy
new file mode 100644
index 0000000..19a9ed8
--- /dev/null
+++ b/zookeeper-api/zookeeper-api-0.9.2-SNAPSHOT.ivy
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<ivy-module version="1.0">
+ <info organisation="org.apache.helix"
+ module="zookeeper-api"
+ revision="0.9.2-SNAPSHOT"
+ status="integration"
+ publication="20170128141623"
+ />
+ <configurations>
+ <conf name="default" visibility="public" description="runtime dependencies and master artifact can be used with this conf" extends="runtime,master"/>
+ <conf name="master" visibility="public" description="contains only the artifact published by this module itself, with no transitive dependencies"/>
+ <conf name="compile" visibility="public" description="this is the default scope, used if none is specified. Compile dependencies are available in all classpaths."/>
+ <conf name="provided" visibility="public" description="this is much like compile, but indicates you expect the JDK or a container to provide it. It is only available on the compilation classpath, and is not transitive."/>
+ <conf name="runtime" visibility="public" description="this scope indicates that the dependency is not required for compilation, but is for execution. It is in the runtime and test classpaths, but not the compile classpath." extends="compile"/>
+ <conf name="test" visibility="private" description="this scope indicates that the dependency is not required for normal use of the application, and is only available for the test compilation and execution phases."/>
+ <conf name="system" visibility="public" description="this scope is similar to provided except that you have to provide the JAR which contains it explicitly. The artifact is always available and is not looked up in a repository."/>
+ </configurations>
+ <publications>
+ <artifact name="zookeeper-api" type="jar" ext="jar" conf="master"/>
+ </publications>
+ <dependencies>
+ <dependency org="org.slf4j" name="slf4j-api" rev="1.7.25" force="true" conf="compile->compile(*),master(*);runtime->runtime(*)">
+ <artifact name="slf4j-api" ext="jar"/>
+ </dependency>
+ <dependency org="org.slf4j" name="slf4j-log4j12" rev="1.7.14" force="true" conf="compile->compile(*),master(*);runtime->runtime(*)">
+ <artifact name="slf4j-log4j12" ext="jar"/>
+ </dependency>
+ <dependency org="org.codehaus.jackson" name="jackson-core-asl" rev="1.8.5" force="true" conf="compile->compile(*),master(*);runtime->runtime(*)"/>
+ <dependency org="org.codehaus.jackson" name="jackson-mapper-asl" rev="1.8.5" force="true" conf="compile->compile(*),master(*);runtime->runtime(*)"/>
+ <dependency org="commons-cli" name="commons-cli" rev="1.2" force="true" conf="compile->compile(*),master(*);runtime->runtime(*)"/>
+ </dependencies>
+</ivy-module>