You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@helix.apache.org by jx...@apache.org on 2020/04/23 20:02:47 UTC
[helix] 12/20: Fixed lock path generation
This is an automated email from the ASF dual-hosted git repository.
jxue pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/helix.git
commit bd0109534b5a331a0527c985f111e9580a87645e
Author: Molly Gao <mg...@mgao-ld1.linkedin.biz>
AuthorDate: Thu Feb 6 15:46:12 2020 -0800
Fixed lock path generation
---
.../java/org/apache/helix/lock/HelixLockScope.java | 160 +++++++++++++++++++++
.../apache/helix/lock/ZKHelixNonblockingLock.java | 10 +-
.../helix/lock/TestZKHelixNonblockingLock.java | 30 ++--
3 files changed, 179 insertions(+), 21 deletions(-)
diff --git a/helix-lock/src/main/java/org/apache/helix/lock/HelixLockScope.java b/helix-lock/src/main/java/org/apache/helix/lock/HelixLockScope.java
new file mode 100644
index 0000000..9fc12fc
--- /dev/null
+++ b/helix-lock/src/main/java/org/apache/helix/lock/HelixLockScope.java
@@ -0,0 +1,160 @@
+/*
+ * 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.
+ */
+
+package org.apache.helix.lock;
+
+import java.util.List;
+
+import org.apache.helix.util.StringTemplate;
+
+
+/**
+ * Defines the various scopes of Helix locks, and how they are represented on Zookeeper
+ */
+public class HelixLockScope {
+
+ /**
+ * Define various properties of Helix lock, and associate them with the number of arguments required for getting znode path
+ */
+ public enum LockScopeProperty {
+
+ PARTICIPANT(1, 0),
+
+ RESOURCE(2, 1),
+
+ PARTITION(3, 2);
+
+ final int _zkPathArgNum;
+ final int _argumentPos;
+
+ private LockScopeProperty(int zkPathArgNum, int argumentPos) {
+ _zkPathArgNum = zkPathArgNum;
+ _argumentPos = argumentPos;
+ }
+
+ /**
+ * Get the number of template arguments required to generate a full path
+ * @return number of template arguments in the path
+ */
+ public int getZkPathArgNum() {
+ return _zkPathArgNum;
+ }
+
+ /**
+ * Get the position of this argument from the input that used to generate the scope
+ * @return the number of position of value for this property in the list of keys input
+ */
+ public int getArgumentPos() {
+ return _argumentPos;
+ }
+ }
+
+ /**
+ * string templates to generate znode path
+ */
+ private static final StringTemplate template = new StringTemplate();
+
+ static {
+ template.addEntry(HelixLockScope.LockScopeProperty.PARTICIPANT, 1, "/{participantName}");
+ template.addEntry(HelixLockScope.LockScopeProperty.RESOURCE, 2,
+ "/{participantName}/{resourceName}");
+ template.addEntry(HelixLockScope.LockScopeProperty.PARTITION, 3,
+ "/{participantName}/{resourceName}/{partitionName}");
+ }
+
+ private final HelixLockScope.LockScopeProperty _type;
+ private final String _participantName;
+ private final String _resourceName;
+ private final String _partitionName;
+
+ private final String _zkPath;
+
+ /**
+ * Initialize with a type of scope and unique identifiers
+ * @param type the scope
+ * @param zkPathKeys keys identifying a ZNode location
+ */
+ public HelixLockScope(HelixLockScope.LockScopeProperty type, List<String> zkPathKeys) {
+
+ if (zkPathKeys.size() != type.getZkPathArgNum()) {
+ throw new IllegalArgumentException(
+ type + " requires " + type.getZkPathArgNum() + " arguments to get znode, but was: "
+ + zkPathKeys);
+ }
+
+ _type = type;
+
+ //Initialize the name fields for various scope
+ _participantName = zkPathKeys.get(LockScopeProperty.PARTICIPANT.getArgumentPos());
+
+ if (type.getZkPathArgNum() >= LockScopeProperty.RESOURCE.getZkPathArgNum()) {
+ _resourceName = zkPathKeys.get(LockScopeProperty.RESOURCE.getArgumentPos());
+ } else {
+ _resourceName = null;
+ }
+
+ if (type.getZkPathArgNum() >= LockScopeProperty.PARTITION.getZkPathArgNum()) {
+ _partitionName = zkPathKeys.get(LockScopeProperty.PARTITION.getArgumentPos());
+ } else {
+ _partitionName = null;
+ }
+
+ _zkPath = template.instantiate(type, zkPathKeys.toArray(new String[0]));
+ }
+
+ /**
+ * Get the scope
+ * @return the type of scope
+ */
+ public HelixLockScope.LockScopeProperty getType() {
+ return _type;
+ }
+
+ /**
+ * Get the participant name if it exists
+ * @return the participant name
+ */
+ public String getParticipantName() {
+ return _participantName;
+ }
+
+ /**
+ * Get the resource name if it exists
+ * @return the resource name
+ */
+ public String getResourceName() {
+ return _resourceName;
+ }
+
+ /**
+ * Get the partition name if it exists
+ * @return the partition name
+ */
+ public String getPartitionName() {
+ return _partitionName;
+ }
+
+ /**
+ * Get the path to the corresponding ZNode
+ * @return a Zookeeper path
+ */
+ public String getZkPath() {
+ return _zkPath;
+ }
+}
diff --git a/helix-lock/src/main/java/org/apache/helix/lock/ZKHelixNonblockingLock.java b/helix-lock/src/main/java/org/apache/helix/lock/ZKHelixNonblockingLock.java
index 0424177..0573228 100644
--- a/helix-lock/src/main/java/org/apache/helix/lock/ZKHelixNonblockingLock.java
+++ b/helix-lock/src/main/java/org/apache/helix/lock/ZKHelixNonblockingLock.java
@@ -28,6 +28,8 @@ import org.I0Itec.zkclient.exception.ZkNoNodeException;
import org.apache.helix.AccessOption;
import org.apache.helix.BaseDataAccessor;
import org.apache.helix.HelixException;
+import org.apache.helix.PropertyPathBuilder;
+import org.apache.helix.PropertyType;
import org.apache.helix.ZNRecord;
import org.apache.helix.api.exceptions.HelixMetaDataAccessException;
import org.apache.helix.manager.zk.ZkBaseDataAccessor;
@@ -48,8 +50,7 @@ public class ZKHelixNonblockingLock implements HelixLock {
private static final Logger LOG = Logger.getLogger(ZKHelixNonblockingLock.class);
- private static final String LOCK_ROOT = "LOCKS";
- private static final String PATH_DELIMITER = "/";
+ private static final String LOCK_ROOT = "/LOCK";
private final String _lockPath;
private final String _userId;
private final long _timeout;
@@ -65,10 +66,9 @@ public class ZKHelixNonblockingLock implements HelixLock {
* @param lockMsg the reason for having this lock
* @param userId a universal unique userId for lock owner identity
*/
- public ZKHelixNonblockingLock(String clusterName, HelixConfigScope scope, String zkAddress,
+ public ZKHelixNonblockingLock(String clusterName, HelixLockScope scope, String zkAddress,
Long timeout, String lockMsg, String userId) {
- this(PATH_DELIMITER + String.join(PATH_DELIMITER, clusterName, LOCK_ROOT, scope.getZkPath()), zkAddress, timeout, lockMsg,
- userId);
+ this("/" + clusterName + LOCK_ROOT + scope.getZkPath(), zkAddress, timeout, lockMsg, userId);
}
/**
diff --git a/helix-lock/src/test/java/org/apache/helix/lock/TestZKHelixNonblockingLock.java b/helix-lock/src/test/java/org/apache/helix/lock/TestZKHelixNonblockingLock.java
index 29f84ae..96a15b3 100644
--- a/helix-lock/src/test/java/org/apache/helix/lock/TestZKHelixNonblockingLock.java
+++ b/helix-lock/src/test/java/org/apache/helix/lock/TestZKHelixNonblockingLock.java
@@ -26,17 +26,12 @@ import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Callable;
-import org.apache.helix.AccessOption;
import org.apache.helix.PropertyPathBuilder;
+import org.apache.helix.PropertyType;
import org.apache.helix.TestHelper;
import org.apache.helix.ZNRecord;
import org.apache.helix.ZkUnitTestBase;
-import org.apache.helix.manager.zk.TestWtCacheAsyncOpMultiThread;
-import org.apache.helix.manager.zk.ZKHelixDataAccessor;
-import org.apache.helix.manager.zk.ZkCacheBaseDataAccessor;
-import org.apache.helix.model.HelixConfigScope;
-import org.apache.helix.model.HelixConfigScope.ConfigScopeProperty;
-import org.apache.helix.model.builder.HelixConfigScopeBuilder;
+import org.apache.helix.common.ZkTestBase;
import org.apache.zookeeper.CreateMode;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
@@ -44,16 +39,15 @@ import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
-public class TestZKHelixNonblockingLock extends ZkUnitTestBase {
+public class TestZKHelixNonblockingLock extends ZkTestBase {
- private final String _className = TestHelper.getTestClassName();
- private final String _methodName = TestHelper.getTestMethodName();
- private final String _clusterName = _className + "_" + _methodName;
+ private final String _clusterName = TestHelper.getTestClassName();
+ private final String _lockRoot = "/LOCK";
private final String _lockMessage = "Test";
private String _lockPath;
private ZKHelixNonblockingLock _lock;
private String _userId;
- private HelixConfigScope _participantScope;
+ private HelixLockScope _participantScope;
@BeforeClass
public void beforeClass() throws Exception {
@@ -63,10 +57,14 @@ public class TestZKHelixNonblockingLock extends ZkUnitTestBase {
TestHelper.setupCluster(_clusterName, ZK_ADDR, 12918, "localhost", "TestDB", 1, 10, 5, 3,
"MasterSlave", true);
_userId = UUID.randomUUID().toString();
- _participantScope =
- new HelixConfigScopeBuilder(ConfigScopeProperty.PARTICIPANT).forCluster(_clusterName)
- .forParticipant("localhost_12918").build();
- _lockPath = "/" + _clusterName + '/' + "LOCKS" + '/' + _participantScope.getZkPath();
+
+ List<String> pathKeys = new ArrayList<>();
+ pathKeys.add("participant_name");
+ pathKeys.add("resource_name");
+ pathKeys.add("partition_name");
+
+ _participantScope = new HelixLockScope(HelixLockScope.LockScopeProperty.PARTITION, pathKeys);
+ _lockPath = "/" + _clusterName + _lockRoot + _participantScope.getZkPath();
_lock = new ZKHelixNonblockingLock(_clusterName, _participantScope, ZK_ADDR, Long.MAX_VALUE,
_lockMessage, _userId);
}