You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@solr.apache.org by st...@apache.org on 2023/08/16 18:38:01 UTC
[solr] branch branch_9x updated: Refactor ZkCmdExecutor, move all ensureExists methods to ZkMaintenanceUtils (#1840)
This is an automated email from the ASF dual-hosted git repository.
stillalex pushed a commit to branch branch_9x
in repository https://gitbox.apache.org/repos/asf/solr.git
The following commit(s) were added to refs/heads/branch_9x by this push:
new 32cea463eb1 Refactor ZkCmdExecutor, move all ensureExists methods to ZkMaintenanceUtils (#1840)
32cea463eb1 is described below
commit 32cea463eb1fb3a112c94752472d31ef2681129f
Author: Alex D <st...@apache.org>
AuthorDate: Wed Aug 16 11:34:39 2023 -0700
Refactor ZkCmdExecutor, move all ensureExists methods to ZkMaintenanceUtils (#1840)
(cherry picked from commit c3aef6e8551bd757605fc308c4b19d9c784cfe68)
---
.../java/org/apache/solr/cloud/DistributedMap.java | 5 +-
.../java/org/apache/solr/cloud/LeaderElector.java | 11 +--
.../apache/solr/cloud/OverseerElectionContext.java | 5 +-
.../solr/cloud/ShardLeaderElectionContextBase.java | 4 +-
.../java/org/apache/solr/cloud/ZkController.java | 17 ++--
.../org/apache/solr/cloud/ZkDistributedQueue.java | 6 +-
.../handler/admin/api/CreateCollectionAPI.java | 11 ++-
.../solr/schema/ManagedIndexSchemaFactory.java | 5 +-
.../org/apache/solr/cloud/ZkSolrClientTest.java | 10 +--
.../apache/solr/common/cloud/ZkCmdExecutor.java | 60 --------------
.../solr/common/cloud/ZkMaintenanceUtils.java | 94 ++++++++++++++++++----
11 files changed, 108 insertions(+), 120 deletions(-)
diff --git a/solr/core/src/java/org/apache/solr/cloud/DistributedMap.java b/solr/core/src/java/org/apache/solr/cloud/DistributedMap.java
index ece2589310a..323c378f71d 100644
--- a/solr/core/src/java/org/apache/solr/cloud/DistributedMap.java
+++ b/solr/core/src/java/org/apache/solr/cloud/DistributedMap.java
@@ -22,7 +22,7 @@ import java.util.List;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrException.ErrorCode;
import org.apache.solr.common.cloud.SolrZkClient;
-import org.apache.solr.common.cloud.ZkCmdExecutor;
+import org.apache.solr.common.cloud.ZkMaintenanceUtils;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.KeeperException.NodeExistsException;
@@ -42,9 +42,8 @@ public class DistributedMap {
public DistributedMap(SolrZkClient zookeeper, String dir) {
this.dir = dir;
- ZkCmdExecutor cmdExecutor = new ZkCmdExecutor(zookeeper.getZkClientTimeout());
try {
- cmdExecutor.ensureExists(dir, zookeeper);
+ ZkMaintenanceUtils.ensureExists(dir, zookeeper);
} catch (KeeperException e) {
throw new SolrException(ErrorCode.SERVER_ERROR, e);
} catch (InterruptedException e) {
diff --git a/solr/core/src/java/org/apache/solr/cloud/LeaderElector.java b/solr/core/src/java/org/apache/solr/cloud/LeaderElector.java
index 650d21f8ef5..44d0a2000be 100644
--- a/solr/core/src/java/org/apache/solr/cloud/LeaderElector.java
+++ b/solr/core/src/java/org/apache/solr/cloud/LeaderElector.java
@@ -29,7 +29,7 @@ import org.apache.solr.cloud.ZkController.ContextKey;
import org.apache.solr.common.AlreadyClosedException;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.cloud.SolrZkClient;
-import org.apache.solr.common.cloud.ZkCmdExecutor;
+import org.apache.solr.common.cloud.ZkMaintenanceUtils;
import org.apache.solr.common.cloud.ZooKeeperException;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
@@ -62,8 +62,6 @@ public class LeaderElector {
protected SolrZkClient zkClient;
- private ZkCmdExecutor zkCmdExecutor;
-
private volatile ElectionContext context;
private ElectionWatcher watcher;
@@ -73,13 +71,11 @@ public class LeaderElector {
public LeaderElector(SolrZkClient zkClient) {
this.zkClient = zkClient;
- zkCmdExecutor = new ZkCmdExecutor(zkClient.getZkClientTimeout());
}
public LeaderElector(
SolrZkClient zkClient, ContextKey key, Map<ContextKey, ElectionContext> electionContexts) {
this.zkClient = zkClient;
- zkCmdExecutor = new ZkCmdExecutor(zkClient.getZkClientTimeout());
this.electionContexts = electionContexts;
this.contextKey = key;
}
@@ -367,10 +363,11 @@ public class LeaderElector {
public void setup(final ElectionContext context) throws InterruptedException, KeeperException {
String electZKPath = context.electionPath + LeaderElector.ELECTION_NODE;
if (context instanceof OverseerElectionContext) {
- zkCmdExecutor.ensureExists(electZKPath, zkClient);
+ ZkMaintenanceUtils.ensureExists(electZKPath, zkClient);
} else {
// we use 2 param so that replica won't create /collection/{collection} if it doesn't exist
- zkCmdExecutor.ensureExists(electZKPath, (byte[]) null, CreateMode.PERSISTENT, zkClient, 2);
+ ZkMaintenanceUtils.ensureExists(
+ electZKPath, (byte[]) null, CreateMode.PERSISTENT, zkClient, 2);
}
this.context = context;
diff --git a/solr/core/src/java/org/apache/solr/cloud/OverseerElectionContext.java b/solr/core/src/java/org/apache/solr/cloud/OverseerElectionContext.java
index 2d2669af2ce..8eb8a6d1386 100644
--- a/solr/core/src/java/org/apache/solr/cloud/OverseerElectionContext.java
+++ b/solr/core/src/java/org/apache/solr/cloud/OverseerElectionContext.java
@@ -23,7 +23,7 @@ import java.lang.invoke.MethodHandles;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrException.ErrorCode;
import org.apache.solr.common.cloud.SolrZkClient;
-import org.apache.solr.common.cloud.ZkCmdExecutor;
+import org.apache.solr.common.cloud.ZkMaintenanceUtils;
import org.apache.solr.common.cloud.ZkNodeProps;
import org.apache.solr.common.util.Utils;
import org.apache.zookeeper.CreateMode;
@@ -43,8 +43,7 @@ final class OverseerElectionContext extends ElectionContext {
this.overseer = overseer;
this.zkClient = zkClient;
try {
- new ZkCmdExecutor(zkClient.getZkClientTimeout())
- .ensureExists(Overseer.OVERSEER_ELECT, zkClient);
+ ZkMaintenanceUtils.ensureExists(Overseer.OVERSEER_ELECT, zkClient);
} catch (KeeperException e) {
throw new SolrException(ErrorCode.SERVER_ERROR, e);
} catch (InterruptedException e) {
diff --git a/solr/core/src/java/org/apache/solr/cloud/ShardLeaderElectionContextBase.java b/solr/core/src/java/org/apache/solr/cloud/ShardLeaderElectionContextBase.java
index 64ff0b3d5d4..de9cf4a24d7 100644
--- a/solr/core/src/java/org/apache/solr/cloud/ShardLeaderElectionContextBase.java
+++ b/solr/core/src/java/org/apache/solr/cloud/ShardLeaderElectionContextBase.java
@@ -28,7 +28,6 @@ import org.apache.solr.common.cloud.PerReplicaStates;
import org.apache.solr.common.cloud.PerReplicaStatesOps;
import org.apache.solr.common.cloud.Replica;
import org.apache.solr.common.cloud.SolrZkClient;
-import org.apache.solr.common.cloud.ZkCmdExecutor;
import org.apache.solr.common.cloud.ZkMaintenanceUtils;
import org.apache.solr.common.cloud.ZkNodeProps;
import org.apache.solr.common.cloud.ZkStateReader;
@@ -80,11 +79,10 @@ class ShardLeaderElectionContextBase extends ElectionContext {
this.collection = collection;
String parent = ZkMaintenanceUtils.getZkParent(leaderPath);
- ZkCmdExecutor zcmd = new ZkCmdExecutor(30000);
// only if /collections/{collection} exists already do we succeed in creating this path
log.info("make sure parent is created {}", parent);
try {
- zcmd.ensureExists(parent, (byte[]) null, CreateMode.PERSISTENT, zkClient, 2);
+ ZkMaintenanceUtils.ensureExists(parent, (byte[]) null, CreateMode.PERSISTENT, zkClient, 2);
} catch (KeeperException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
diff --git a/solr/core/src/java/org/apache/solr/cloud/ZkController.java b/solr/core/src/java/org/apache/solr/cloud/ZkController.java
index e22d85be88f..20e23a624d9 100644
--- a/solr/core/src/java/org/apache/solr/cloud/ZkController.java
+++ b/solr/core/src/java/org/apache/solr/cloud/ZkController.java
@@ -88,10 +88,10 @@ import org.apache.solr.common.cloud.Slice;
import org.apache.solr.common.cloud.SolrZkClient;
import org.apache.solr.common.cloud.ZkACLProvider;
import org.apache.solr.common.cloud.ZkClientConnectionStrategy;
-import org.apache.solr.common.cloud.ZkCmdExecutor;
import org.apache.solr.common.cloud.ZkCoreNodeProps;
import org.apache.solr.common.cloud.ZkCredentialsInjector;
import org.apache.solr.common.cloud.ZkCredentialsProvider;
+import org.apache.solr.common.cloud.ZkMaintenanceUtils;
import org.apache.solr.common.cloud.ZkNodeProps;
import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.common.cloud.ZooKeeperException;
@@ -923,20 +923,19 @@ public class ZkController implements Closeable {
*/
public static void createClusterZkNodes(SolrZkClient zkClient)
throws KeeperException, InterruptedException, IOException {
- ZkCmdExecutor cmdExecutor = new ZkCmdExecutor(zkClient.getZkClientTimeout());
- cmdExecutor.ensureExists(ZkStateReader.LIVE_NODES_ZKNODE, zkClient);
- cmdExecutor.ensureExists(ZkStateReader.NODE_ROLES, zkClient);
+ ZkMaintenanceUtils.ensureExists(ZkStateReader.LIVE_NODES_ZKNODE, zkClient);
+ ZkMaintenanceUtils.ensureExists(ZkStateReader.NODE_ROLES, zkClient);
for (NodeRoles.Role role : NodeRoles.Role.values()) {
- cmdExecutor.ensureExists(NodeRoles.getZNodeForRole(role), zkClient);
+ ZkMaintenanceUtils.ensureExists(NodeRoles.getZNodeForRole(role), zkClient);
for (String mode : role.supportedModes()) {
- cmdExecutor.ensureExists(NodeRoles.getZNodeForRoleMode(role, mode), zkClient);
+ ZkMaintenanceUtils.ensureExists(NodeRoles.getZNodeForRoleMode(role, mode), zkClient);
}
}
- cmdExecutor.ensureExists(ZkStateReader.COLLECTIONS_ZKNODE, zkClient);
- cmdExecutor.ensureExists(ZkStateReader.ALIASES, zkClient);
+ ZkMaintenanceUtils.ensureExists(ZkStateReader.COLLECTIONS_ZKNODE, zkClient);
+ ZkMaintenanceUtils.ensureExists(ZkStateReader.ALIASES, zkClient);
byte[] emptyJson = "{}".getBytes(StandardCharsets.UTF_8);
- cmdExecutor.ensureExists(ZkStateReader.SOLR_SECURITY_CONF_PATH, emptyJson, zkClient);
+ ZkMaintenanceUtils.ensureExists(ZkStateReader.SOLR_SECURITY_CONF_PATH, emptyJson, zkClient);
repairSecurityJson(zkClient);
}
diff --git a/solr/core/src/java/org/apache/solr/cloud/ZkDistributedQueue.java b/solr/core/src/java/org/apache/solr/cloud/ZkDistributedQueue.java
index 39a1de01feb..57db14740c5 100644
--- a/solr/core/src/java/org/apache/solr/cloud/ZkDistributedQueue.java
+++ b/solr/core/src/java/org/apache/solr/cloud/ZkDistributedQueue.java
@@ -37,7 +37,7 @@ import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrException.ErrorCode;
import org.apache.solr.common.cloud.ConnectionManager.IsClosed;
import org.apache.solr.common.cloud.SolrZkClient;
-import org.apache.solr.common.cloud.ZkCmdExecutor;
+import org.apache.solr.common.cloud.ZkMaintenanceUtils;
import org.apache.solr.common.util.Pair;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
@@ -134,10 +134,8 @@ public class ZkDistributedQueue implements DistributedQueue {
IsClosed higherLevelIsClosed) {
this.dir = dir;
- ZkCmdExecutor cmdExecutor =
- new ZkCmdExecutor(zookeeper.getZkClientTimeout(), higherLevelIsClosed);
try {
- cmdExecutor.ensureExists(dir, zookeeper);
+ ZkMaintenanceUtils.ensureExists(dir, zookeeper);
} catch (KeeperException e) {
throw new SolrException(ErrorCode.SERVER_ERROR, e);
} catch (InterruptedException e) {
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/CreateCollectionAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/CreateCollectionAPI.java
index 1ff34e69ff7..52555417645 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/api/CreateCollectionAPI.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/api/CreateCollectionAPI.java
@@ -67,7 +67,7 @@ import org.apache.solr.client.solrj.util.SolrIdentifierValidator;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.cloud.ClusterProperties;
import org.apache.solr.common.cloud.SolrZkClient;
-import org.apache.solr.common.cloud.ZkCmdExecutor;
+import org.apache.solr.common.cloud.ZkMaintenanceUtils;
import org.apache.solr.common.cloud.ZkNodeProps;
import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.common.params.CollectionAdminParams;
@@ -265,9 +265,8 @@ public class CreateCollectionAPI extends AdminAPIBase {
private static void createSysConfigSet(CoreContainer coreContainer)
throws KeeperException, InterruptedException {
SolrZkClient zk = coreContainer.getZkController().getZkStateReader().getZkClient();
- ZkCmdExecutor cmdExecutor = new ZkCmdExecutor(zk.getZkClientTimeout());
- cmdExecutor.ensureExists(ZkStateReader.CONFIGS_ZKNODE, zk);
- cmdExecutor.ensureExists(
+ ZkMaintenanceUtils.ensureExists(ZkStateReader.CONFIGS_ZKNODE, zk);
+ ZkMaintenanceUtils.ensureExists(
ZkStateReader.CONFIGS_ZKNODE + "/" + CollectionAdminParams.SYSTEM_COLL, zk);
try {
@@ -280,7 +279,7 @@ public class CreateCollectionAPI extends AdminAPIBase {
data = inputStream.readAllBytes();
}
assert data != null && data.length > 0;
- cmdExecutor.ensureExists(path, data, CreateMode.PERSISTENT, zk);
+ ZkMaintenanceUtils.ensureExists(path, data, CreateMode.PERSISTENT, zk);
path =
ZkStateReader.CONFIGS_ZKNODE
+ "/"
@@ -292,7 +291,7 @@ public class CreateCollectionAPI extends AdminAPIBase {
data = inputStream.readAllBytes();
}
assert data != null && data.length > 0;
- cmdExecutor.ensureExists(path, data, CreateMode.PERSISTENT, zk);
+ ZkMaintenanceUtils.ensureExists(path, data, CreateMode.PERSISTENT, zk);
} catch (IOException e) {
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, e);
}
diff --git a/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchemaFactory.java b/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchemaFactory.java
index 9008b3e443e..73187383bd8 100644
--- a/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchemaFactory.java
+++ b/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchemaFactory.java
@@ -32,7 +32,7 @@ import org.apache.solr.cloud.ZkSolrResourceLoader;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrException.ErrorCode;
import org.apache.solr.common.cloud.SolrZkClient;
-import org.apache.solr.common.cloud.ZkCmdExecutor;
+import org.apache.solr.common.cloud.ZkMaintenanceUtils;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.IOUtils;
import org.apache.solr.common.util.NamedList;
@@ -485,12 +485,11 @@ public class ManagedIndexSchemaFactory extends IndexSchemaFactory implements Sol
// Rename the non-managed schema znode in ZooKeeper
final String nonManagedSchemaPath = zkLoader.getConfigSetZkPath() + "/" + resourceName;
try {
- ZkCmdExecutor zkCmdExecutor = new ZkCmdExecutor(zkClient.getZkClientTimeout());
if (zkController.pathExists(nonManagedSchemaPath)) {
// First, copy the non-managed schema znode content to the upgraded schema znode
byte[] bytes = zkController.getZkClient().getData(nonManagedSchemaPath, null, null, true);
final String upgradedSchemaPath = nonManagedSchemaPath + UPGRADED_SCHEMA_EXTENSION;
- zkCmdExecutor.ensureExists(upgradedSchemaPath, zkController.getZkClient());
+ ZkMaintenanceUtils.ensureExists(upgradedSchemaPath, zkController.getZkClient());
zkController.getZkClient().setData(upgradedSchemaPath, bytes, true);
// Then delete the non-managed schema znode
if (zkController.getZkClient().exists(nonManagedSchemaPath, true)) {
diff --git a/solr/core/src/test/org/apache/solr/cloud/ZkSolrClientTest.java b/solr/core/src/test/org/apache/solr/cloud/ZkSolrClientTest.java
index a9ed66f70ff..4503c862d50 100644
--- a/solr/core/src/test/org/apache/solr/cloud/ZkSolrClientTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/ZkSolrClientTest.java
@@ -30,6 +30,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.common.cloud.SolrZkClient;
import org.apache.solr.common.cloud.ZkCmdExecutor;
+import org.apache.solr.common.cloud.ZkMaintenanceUtils;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.Op;
@@ -394,12 +395,11 @@ public class ZkSolrClientTest extends SolrTestCaseJ4 {
zkClient.clean("/");
- ZkCmdExecutor zkCmdExecutor = new ZkCmdExecutor(30000);
expectThrows(
KeeperException.NoNodeException.class,
"We should not be able to create this path",
() ->
- zkCmdExecutor.ensureExists(
+ ZkMaintenanceUtils.ensureExists(
"/collection/collection/leader",
(byte[]) null,
CreateMode.PERSISTENT,
@@ -412,7 +412,7 @@ public class ZkSolrClientTest extends SolrTestCaseJ4 {
KeeperException.NoNodeException.class,
"We should not be able to create this path",
() ->
- zkCmdExecutor.ensureExists(
+ ZkMaintenanceUtils.ensureExists(
"/collections/collection/leader",
(byte[]) null,
CreateMode.PERSISTENT,
@@ -421,7 +421,7 @@ public class ZkSolrClientTest extends SolrTestCaseJ4 {
zkClient.makePath("/collection/collection", true);
byte[] bytes = new byte[10];
- zkCmdExecutor.ensureExists(
+ ZkMaintenanceUtils.ensureExists(
"/collection/collection", bytes, CreateMode.PERSISTENT, zkClient, 2);
byte[] returnedBytes = zkClient.getData("/collection/collection", null, null, true);
@@ -430,7 +430,7 @@ public class ZkSolrClientTest extends SolrTestCaseJ4 {
zkClient.makePath("/collection/collection/leader", true);
- zkCmdExecutor.ensureExists(
+ ZkMaintenanceUtils.ensureExists(
"/collection/collection/leader", (byte[]) null, CreateMode.PERSISTENT, zkClient, 2);
}
}
diff --git a/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkCmdExecutor.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkCmdExecutor.java
index 06134f1fbae..01924b3c044 100644
--- a/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkCmdExecutor.java
+++ b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkCmdExecutor.java
@@ -19,9 +19,7 @@ package org.apache.solr.common.cloud;
import java.lang.invoke.MethodHandles;
import org.apache.solr.common.AlreadyClosedException;
import org.apache.solr.common.cloud.ConnectionManager.IsClosed;
-import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.KeeperException.NodeExistsException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -94,64 +92,6 @@ public class ZkCmdExecutor {
return isClosed != null && isClosed.isClosed();
}
- /**
- * Create a persistent znode with no data if it does not already exist
- *
- * @see #ensureExists(String, byte[], CreateMode, SolrZkClient, int)
- */
- public void ensureExists(String path, final SolrZkClient zkClient)
- throws KeeperException, InterruptedException {
- ensureExists(path, null, CreateMode.PERSISTENT, zkClient, 0);
- }
-
- /**
- * Create a persistent znode with the given data if it does not already exist
- *
- * @see #ensureExists(String, byte[], CreateMode, SolrZkClient, int)
- */
- public void ensureExists(String path, final byte[] data, final SolrZkClient zkClient)
- throws KeeperException, InterruptedException {
- ensureExists(path, data, CreateMode.PERSISTENT, zkClient, 0);
- }
-
- /**
- * Create a znode with the given mode and data if it does not already exist
- *
- * @see #ensureExists(String, byte[], CreateMode, SolrZkClient, int)
- */
- public void ensureExists(
- String path, final byte[] data, CreateMode createMode, final SolrZkClient zkClient)
- throws KeeperException, InterruptedException {
- ensureExists(path, data, createMode, zkClient, 0);
- }
-
- /**
- * Create a node if it does not exist
- *
- * @param path the path at which to create the znode
- * @param data the optional data to set on the znode
- * @param createMode the mode with which to create the znode
- * @param zkClient the client to use to check and create
- * @param skipPathParts how many path elements to skip
- */
- public void ensureExists(
- final String path,
- final byte[] data,
- CreateMode createMode,
- final SolrZkClient zkClient,
- int skipPathParts)
- throws KeeperException, InterruptedException {
-
- if (zkClient.exists(path, true)) {
- return;
- }
- try {
- zkClient.makePath(path, data, createMode, null, true, true, skipPathParts);
- } catch (NodeExistsException ignored) {
- // it's okay if another beats us creating the node
- }
- }
-
/**
* Performs a retry delay if this is not the first attempt
*
diff --git a/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkMaintenanceUtils.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkMaintenanceUtils.java
index 7ade32ebf3d..34d770c7a12 100644
--- a/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkMaintenanceUtils.java
+++ b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkMaintenanceUtils.java
@@ -37,6 +37,7 @@ import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.common.util.StrUtils;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.KeeperException.NodeExistsException;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -589,28 +590,87 @@ public class ZkMaintenanceUtils {
int lastDot = filePath.lastIndexOf('.');
return lastDot >= 0 && USE_FORBIDDEN_FILE_TYPES.contains(filePath.substring(lastDot + 1));
}
-}
-class ZkCopier implements ZkMaintenanceUtils.ZkVisitor {
+ /**
+ * Create a persistent znode with no data if it does not already exist
+ *
+ * @see #ensureExists(String, byte[], CreateMode, SolrZkClient, int)
+ */
+ public static void ensureExists(String path, final SolrZkClient zkClient)
+ throws KeeperException, InterruptedException {
+ ensureExists(path, null, CreateMode.PERSISTENT, zkClient, 0);
+ }
+
+ /**
+ * Create a persistent znode with the given data if it does not already exist
+ *
+ * @see #ensureExists(String, byte[], CreateMode, SolrZkClient, int)
+ */
+ public static void ensureExists(String path, final byte[] data, final SolrZkClient zkClient)
+ throws KeeperException, InterruptedException {
+ ensureExists(path, data, CreateMode.PERSISTENT, zkClient, 0);
+ }
+
+ /**
+ * Create a znode with the given mode and data if it does not already exist
+ *
+ * @see #ensureExists(String, byte[], CreateMode, SolrZkClient, int)
+ */
+ public static void ensureExists(
+ String path, final byte[] data, CreateMode createMode, final SolrZkClient zkClient)
+ throws KeeperException, InterruptedException {
+ ensureExists(path, data, createMode, zkClient, 0);
+ }
- String source;
- String dest;
- SolrZkClient zkClient;
+ /**
+ * Create a node if it does not exist
+ *
+ * @param path the path at which to create the znode
+ * @param data the optional data to set on the znode
+ * @param createMode the mode with which to create the znode
+ * @param zkClient the client to use to check and create
+ * @param skipPathParts how many path elements to skip
+ */
+ public static void ensureExists(
+ final String path,
+ final byte[] data,
+ CreateMode createMode,
+ final SolrZkClient zkClient,
+ int skipPathParts)
+ throws KeeperException, InterruptedException {
- ZkCopier(SolrZkClient zkClient, String source, String dest) {
- this.source = source;
- this.dest = dest;
- if (dest.endsWith("/")) {
- this.dest = dest.substring(0, dest.length() - 1);
+ if (zkClient.exists(path, true)) {
+ return;
+ }
+ try {
+ zkClient.makePath(path, data, createMode, null, true, true, skipPathParts);
+ } catch (NodeExistsException ignored) {
+ // it's okay if another beats us creating the node
}
- this.zkClient = zkClient;
}
- @Override
- public void visit(String path) throws InterruptedException, KeeperException {
- String finalDestination = dest;
- if (path.equals(source) == false) finalDestination += "/" + path.substring(source.length() + 1);
- zkClient.makePath(finalDestination, false, true);
- zkClient.setData(finalDestination, zkClient.getData(path, null, null, true), true);
+ static class ZkCopier implements ZkMaintenanceUtils.ZkVisitor {
+
+ String source;
+ String dest;
+ SolrZkClient zkClient;
+
+ ZkCopier(SolrZkClient zkClient, String source, String dest) {
+ this.source = source;
+ this.dest = dest;
+ if (dest.endsWith("/")) {
+ this.dest = dest.substring(0, dest.length() - 1);
+ }
+ this.zkClient = zkClient;
+ }
+
+ @Override
+ public void visit(String path) throws InterruptedException, KeeperException {
+ String finalDestination = dest;
+ if (path.equals(source) == false)
+ finalDestination += "/" + path.substring(source.length() + 1);
+ zkClient.makePath(finalDestination, false, true);
+ zkClient.setData(finalDestination, zkClient.getData(path, null, null, true), true);
+ }
}
}