You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@solr.apache.org by ds...@apache.org on 2022/08/25 21:59:58 UTC
[solr] branch main updated: SOLR-15342: Separate out a SolrJ-Zookeeper module (#943)
This is an automated email from the ASF dual-hosted git repository.
dsmiley pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr.git
The following commit(s) were added to refs/heads/main by this push:
new 88bc36ae9e9 SOLR-15342: Separate out a SolrJ-Zookeeper module (#943)
88bc36ae9e9 is described below
commit 88bc36ae9e916bafca8863c25b8bb5bb8185d89f
Author: Haythem <ha...@yahoo.fr>
AuthorDate: Thu Aug 25 23:59:52 2022 +0200
SOLR-15342: Separate out a SolrJ-Zookeeper module (#943)
• CloudSolrClient builders use reflection to instantiate ZkClientClusterStateProvider when needed
• CollectionAdminParams constants
• CollectionStateProps constants
• SliceStateProps constants
• ReplicaStateProps constants
• SolrJ streaming expressions: don’t depend on ZK anymore
• javadocs: temporarily unlink to solrj modules due to split package issue
• PerReplicaStates.fetch -> PerReplicaStatesFetcher
• ZkStateReader.getCollectionPath -> DocCollection.getCollectionPath
Co-authored-by: Haythem Khiri <hk...@salesforce.com>
Co-authored-by: David Smiley <ds...@apache.org>
Co-authored-by: Christine Poerschke <cp...@apache.org>
---
gradle/documentation/markdown.gradle | 2 +-
gradle/documentation/render-javadoc.gradle | 36 ++++++--
gradle/ide/eclipse/dot.classpath.xsl | 1 +
gradle/maven/defaults-maven.gradle | 1 +
gradle/solr/packaging.gradle | 1 +
settings.gradle | 1 +
solr/CHANGES.txt | 3 +
solr/core/build.gradle | 1 +
.../solr/cloud/DistributedClusterStateUpdater.java | 14 +--
.../apache/solr/cloud/OverseerTaskProcessor.java | 2 +-
.../solr/cloud/RefreshCollectionMessage.java | 3 +-
.../solr/cloud/ShardLeaderElectionContextBase.java | 3 +-
.../java/org/apache/solr/cloud/ZkController.java | 3 +-
.../solr/cloud/api/collections/AddReplicaCmd.java | 3 +-
.../api/collections/CollectionHandlingUtils.java | 15 ++--
.../cloud/api/collections/CreateCollectionCmd.java | 15 ++--
.../cloud/api/collections/DeleteCollectionCmd.java | 2 +-
.../api/collections/ReindexCollectionCmd.java | 4 +-
.../solr/cloud/api/collections/RestoreCmd.java | 6 +-
.../solr/cloud/overseer/ClusterStateMutator.java | 6 +-
.../solr/cloud/overseer/CollectionMutator.java | 14 +--
.../apache/solr/cloud/overseer/NodeMutator.java | 3 +-
.../apache/solr/cloud/overseer/ReplicaMutator.java | 11 ++-
.../apache/solr/cloud/overseer/SliceMutator.java | 14 +--
.../apache/solr/cloud/overseer/ZkStateWriter.java | 8 +-
.../apache/solr/filestore/DistribPackageStore.java | 5 +-
.../solr/handler/admin/CollectionsHandler.java | 10 ++-
.../org/apache/solr/handler/admin/SplitOp.java | 8 +-
.../solr/handler/admin/ZookeeperInfoHandler.java | 8 +-
.../org/apache/solr/logging/MDCLoggingContext.java | 10 +++
.../apache/solr/cloud/ClusterStateMockUtil.java | 5 +-
.../solr/cloud/CollectionStateZnodeTest.java | 7 +-
.../solr/cloud/FullSolrCloudDistribCmdsTest.java | 3 +-
.../org/apache/solr/cloud/ReplaceNodeTest.java | 6 +-
.../org/apache/solr/cloud/ZkControllerTest.java | 3 +-
.../api/collections/CustomCollectionTest.java | 2 +-
.../solr/cloud/overseer/ZkStateReaderTest.java | 5 +-
.../solr/cloud/overseer/ZkStateWriterTest.java | 4 +-
.../handler/admin/V2CollectionsAPIMappingTest.java | 3 +-
.../stream/AnalyticsShardRequestManager.java | 4 +-
solr/modules/hadoop-auth/build.gradle | 1 +
solr/modules/hdfs/build.gradle | 1 +
solr/modules/sql/build.gradle | 1 +
.../org/apache/solr/handler/sql/SolrSchema.java | 5 +-
.../modules/deployment-guide/pages/solrj.adoc | 5 ++
.../pages/zookeeper-access-control.adoc | 6 +-
.../upgrade-notes/pages/solr-upgrade-notes.adoc | 6 ++
solr/solrj-zookeeper/build.gradle | 57 ++++++++++++
.../client/solrj/cloud/AlreadyExistsException.java | 0
.../client/solrj/cloud/BadVersionException.java | 0
.../client/solrj/cloud/DelegatingCloudManager.java | 0
.../client/solrj/cloud/DistribStateManager.java | 4 +
.../solr/client/solrj/cloud/DistributedQueue.java | 0
.../solrj/cloud/DistributedQueueFactory.java | 0
.../solr/client/solrj/cloud/NodeStateProvider.java | 0
.../solr/client/solrj/cloud/NotEmptyException.java | 0
.../solr/client/solrj/cloud/SolrCloudManager.java | 0
.../solr/client/solrj/cloud/VersionedData.java | 0
.../client/solrj/impl/SolrClientCloudManager.java | 0
.../solrj/impl/SolrClientNodeStateProvider.java | 16 +++-
.../solrj/impl/ZkClientClusterStateProvider.java | 49 ++++++++++
.../client/solrj/impl/ZkDistribStateManager.java | 22 ++++-
.../org/apache/solr/common/LazySolrCluster.java | 3 +-
.../java/org/apache/solr/common/SimpleZkMap.java | 0
.../apache/solr/common/cloud/BeforeReconnect.java | 0
.../common/cloud/CloudCollectionsListener.java | 0
.../solr/common/cloud/ClusterProperties.java | 0
.../common/cloud/ClusterPropertiesListener.java | 0
.../solr/common/cloud/CollectionProperties.java | 0
.../solr/common/cloud/CollectionPropsWatcher.java | 0
.../solr/common/cloud/CollectionStateWatcher.java | 0
.../solr/common/cloud/ConnectionManager.java | 0
.../common/cloud/DefaultConnectionStrategy.java | 0
.../solr/common/cloud/DefaultZkACLProvider.java | 0
.../common/cloud/DefaultZkCredentialsProvider.java | 0
.../solr/common/cloud/DocCollectionWatcher.java | 0
.../solr/common/cloud/LiveNodesListener.java | 0
.../solr/common/cloud/LiveNodesPredicate.java | 0
.../solr/common/cloud/NodesSysPropsCacher.java | 3 +-
.../org/apache/solr/common/cloud/OnReconnect.java | 0
.../solr/common/cloud/PerReplicaStatesFetcher.java | 53 +++++++++++
.../solr/common/cloud/PerReplicaStatesOps.java | 2 +-
.../solr/common/cloud/SaslZkACLProvider.java | 0
.../common/cloud/SecurityAwareZkACLProvider.java | 0
.../org/apache/solr/common/cloud/SolrZkClient.java | 0
.../VMParamsAllAndReadonlyDigestZkACLProvider.java | 0
...eSetCredentialsDigestZkCredentialsProvider.java | 0
.../apache/solr/common/cloud/ZkACLProvider.java | 0
.../common/cloud/ZkClientConnectionStrategy.java | 0
.../apache/solr/common/cloud/ZkCmdExecutor.java | 0
.../solr/common/cloud/ZkCredentialsProvider.java | 0
.../apache/solr/common/cloud/ZkDynamicConfig.java | 0
.../solr/common/cloud/ZkMaintenanceUtils.java | 0
.../org/apache/solr/common/cloud/ZkOperation.java | 0
.../apache/solr/common/cloud/ZkStateReader.java | 22 ++---
.../solr/common/cloud/ZooKeeperException.java | 0
.../solr/common/cloud/rule/ImplicitSnitch.java | 0
.../solr/common/cloud/rule/RemoteCallback.java | 0
.../org/apache/solr/common/cloud/rule/Snitch.java | 0
.../solr/common/cloud/rule/SnitchContext.java | 0
.../solr/common/cloud/rule/package-info.java | 0
.../apache/solr/common/cloud/SolrZkClientTest.java | 0
.../solr/common/cloud/TestPerReplicaStates.java | 12 +--
.../solr/common/cloud/TestZkConfigSetService.java | 0
.../solr/common/cloud/TestZkMaintenanceUtils.java | 0
solr/solrj/build.gradle | 23 ++---
.../solrj/impl/BaseHttpClusterStateProvider.java | 3 +-
.../client/solrj/impl/CloudHttp2SolrClient.java | 6 +-
.../client/solrj/impl/CloudLegacySolrClient.java | 5 +-
.../solr/client/solrj/impl/CloudSolrClient.java | 100 ++-------------------
.../client/solrj/impl/ClusterStateProvider.java | 22 +++++
.../client/solrj/io/sql/DatabaseMetaDataImpl.java | 9 +-
.../solr/client/solrj/io/sql/StatementImpl.java | 5 +-
.../client/solrj/io/stream/CloudSolrStream.java | 38 ++++----
.../client/solrj/io/stream/DeepRandomStream.java | 49 ----------
.../solrj/io/stream/FeaturesSelectionStream.java | 10 +--
.../client/solrj/io/stream/TextLogitStream.java | 9 +-
.../solr/client/solrj/io/stream/TopicStream.java | 22 ++---
.../solr/client/solrj/io/stream/TupleStream.java | 6 +-
.../solrj/request/CollectionAdminRequest.java | 59 ++++++------
.../client/solrj/request/CoreAdminRequest.java | 8 +-
.../routing/NodePreferenceRulesComparator.java | 14 +--
.../RequestReplicaListTransformerGenerator.java | 16 ++--
.../java/org/apache/solr/common/cloud/Aliases.java | 9 +-
.../org/apache/solr/common/cloud/ClusterState.java | 68 ++++----------
.../common/cloud/CollectionStatePredicate.java | 6 +-
.../apache/solr/common/cloud/DocCollection.java | 69 ++++++++------
.../org/apache/solr/common/cloud/DocRouter.java | 5 +-
.../{ZkACLProvider.java => NodesSysProps.java} | 11 +--
.../apache/solr/common/cloud/PerReplicaStates.java | 35 +-------
.../java/org/apache/solr/common/cloud/Replica.java | 80 ++++++++++-------
.../java/org/apache/solr/common/cloud/Slice.java | 37 ++++----
.../apache/solr/common/cloud/ZkCoreNodeProps.java | 14 +--
.../solr/common/params/CollectionAdminParams.java | 16 ++++
.../java/org/apache/solr/common/util/Utils.java | 61 +------------
.../client/solrj/impl/CloudSolrClientTest.java | 12 +--
.../client/solrj/impl/HttpClusterStateSSLTest.java | 3 +-
.../cloud/PerReplicaStatesIntegrationTest.java | 43 +++++----
.../common/cloud/TestDocCollectionWatcher.java | 3 +-
solr/test-framework/build.gradle | 1 +
.../apache/solr/common/cloud/ClusterStateUtil.java | 0
141 files changed, 728 insertions(+), 672 deletions(-)
diff --git a/gradle/documentation/markdown.gradle b/gradle/documentation/markdown.gradle
index 7112362d146..29d23d87c75 100644
--- a/gradle/documentation/markdown.gradle
+++ b/gradle/documentation/markdown.gradle
@@ -142,7 +142,7 @@ class MarkdownTemplateTask extends DefaultTask {
binding.put('projectList', project.providers.provider{
def projects = productProject.subprojects.findAll{ it.tasks.findByName('renderSiteJavadoc')?.enabled }
.sort(false, Comparator.comparing{ (it.name != 'core') as Boolean }
- .thenComparing(Comparator.comparing{ (it.name != 'solrj') as Boolean })
+ .thenComparing(Comparator.comparing{ (! it.name.startsWith('solrj')) as Boolean })
.thenComparing(Comparator.comparing{ (it.name == 'test-framework') as Boolean })
.thenComparing(Comparator.comparing{ it.path }));
return projects.collect{ project ->
diff --git a/gradle/documentation/render-javadoc.gradle b/gradle/documentation/render-javadoc.gradle
index cda667424e8..fc564b8b9be 100644
--- a/gradle/documentation/render-javadoc.gradle
+++ b/gradle/documentation/render-javadoc.gradle
@@ -108,7 +108,7 @@ configure(project(":solr").allprojects) {
configure(project(":solr:modules:analysis-extras")) {
project.tasks.withType(RenderJavadocTask) {
- // TODO: clean up split packages
+ // TODO: clean up split packages SOLR-15604
javadocMissingIgnore = [
"org.apache.solr.schema",
"org.apache.solr.update.processor"
@@ -118,7 +118,7 @@ configure(project(":solr:modules:analysis-extras")) {
configure(project(":solr:modules:analytics")) {
project.tasks.withType(RenderJavadocTask) {
- // TODO: clean up split packages
+ // TODO: clean up split packages SOLR-15604
javadocMissingIgnore = [
"org.apache.solr.handler",
"org.apache.solr.handler.component",
@@ -129,25 +129,38 @@ configure(project(":solr:modules:analytics")) {
configure(project(":solr:modules:langid")) {
project.tasks.withType(RenderJavadocTask) {
- // TODO: clean up split packages
+ // TODO: clean up split packages SOLR-15604
javadocMissingIgnore = ["org.apache.solr.update.processor"]
}
}
configure(project(":solr:solrj")) {
project.tasks.withType(RenderJavadocTask) {
- // TODO: clean up split packages
+ // TODO: clean up split packages SOLR-15604
javadocMissingIgnore = ["org.apache.solr.client.solrj.embedded"]
}
}
+configure(project(":solr:solrj-zookeeper")) {
+ project.tasks.withType(RenderJavadocTask) {
+ // TODO: clean up split packages SOLR-15604
+ javadocMissingIgnore = [
+ "org.apache.solr.common",
+ "org.apache.solr.common.cloud",
+ "org.apache.solr.client.solrj.impl",
+ "org.apache.solr.client.solrj.cloud"
+ ]
+ }
+}
+
configure(project(":solr:test-framework")) {
project.tasks.withType(RenderJavadocTask) {
- // TODO: clean up split packages
+ // TODO: clean up split packages SOLR-15604 or don't because it's test stuff
javadocMissingIgnore = [
"org.apache.solr",
"org.apache.solr.analysis",
"org.apache.solr.cloud",
+ "org.apache.solr.common.cloud",
"org.apache.solr.core",
"org.apache.solr.handler",
"org.apache.solr.handler.component",
@@ -253,10 +266,14 @@ class RenderJavadocTask extends DefaultTask {
private Set findRenderTasksInDependencies() {
Set found = []
def collectDeps
- collectDeps = { task -> task.taskDependencies.getDependencies(task).findAll{ it.name == this.name && it.enabled && !found.contains(it) }.each{
- found << it
- collectDeps(it)
- }}
+ collectDeps = { task ->
+ task.taskDependencies.getDependencies(task)
+ .findAll{ it.name == this.name && it.enabled && !found.contains(it) }
+ .each{
+ found << it
+ collectDeps(it)
+ }
+ }
collectDeps(this)
return found
}
@@ -325,6 +342,7 @@ class RenderJavadocTask extends DefaultTask {
// lucene-test-framework was first, or broken links to things like LuceneTestCase if lucene-core was first)
if (project.path != ':solr:test-framework') { //
findRenderTasksInDependencies()
+ .findAll({it.project.path != ':solr:solrj' && it.project.path != ':solr:solrj-zookeeper'}) // split packages
.sort(false, Comparator.comparing { (it.project.name != 'core') as Boolean }.thenComparing(Comparator.comparing { it.path }))
.each { otherTask ->
def otherProject = otherTask.project
diff --git a/gradle/ide/eclipse/dot.classpath.xsl b/gradle/ide/eclipse/dot.classpath.xsl
index 8d48c5d9acd..e0b606836be 100644
--- a/gradle/ide/eclipse/dot.classpath.xsl
+++ b/gradle/ide/eclipse/dot.classpath.xsl
@@ -37,6 +37,7 @@
<xsl:sort select="string(starts-with(text(), 'lucene/'))" order="descending" lang="en"/>
<xsl:sort select="string(starts-with(text(), 'solr/core/'))" order="descending" lang="en"/>
<xsl:sort select="string(starts-with(text(), 'solr/solrj/'))" order="descending" lang="en"/>
+ <xsl:sort select="string(starts-with(text(), 'solr/solrj-zookeeper/'))" order="descending" lang="en"/>
<xsl:sort select="string(starts-with(text(), 'solr/test-framework/'))" order="descending" lang="en"/>
<xsl:sort select="string(starts-with(text(), 'solr/'))" order="descending" lang="en"/>
<!-- all others in one group above are sorted by path name: -->
diff --git a/gradle/maven/defaults-maven.gradle b/gradle/maven/defaults-maven.gradle
index 647e28cd7c1..5eb45919c0f 100644
--- a/gradle/maven/defaults-maven.gradle
+++ b/gradle/maven/defaults-maven.gradle
@@ -26,6 +26,7 @@ configure(rootProject) {
published = [
":solr:core",
":solr:solrj",
+ ":solr:solrj-zookeeper",
":solr:prometheus-exporter",
":solr:test-framework",
] + project(":solr:modules").getChildProjects().values().path
diff --git a/gradle/solr/packaging.gradle b/gradle/solr/packaging.gradle
index cce602fc29c..dec16950f98 100644
--- a/gradle/solr/packaging.gradle
+++ b/gradle/solr/packaging.gradle
@@ -58,6 +58,7 @@ configure(allprojects.findAll {project -> project.path.startsWith(":solr:modules
dependencies {
solrPlatformLibs project(":solr:core")
solrPlatformLibs project(":solr:solrj")
+ solrPlatformLibs project(":solr:solrj-zookeeper")
// libExt has logging libs, which we don't want. Lets users decide what they want.
solrPlatformLibs project(path: ":solr:server", configuration: 'libExt')
}
diff --git a/settings.gradle b/settings.gradle
index a93e882d128..83476e73ad9 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -27,6 +27,7 @@ rootProject.name = "solr-root"
includeBuild("dev-tools/solr-missing-doclet")
include "solr:solrj"
+include "solr:solrj-zookeeper"
include "solr:core"
include "solr:server"
include "solr:modules:analysis-extras"
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 3923ecc4892..f51145b8cce 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -156,6 +156,9 @@ Other Changes
* SOLR-16339: Refined "no servers hosting shard" SolrException wording. (Christine Poerschke)
+* SOLR-15342: SolrJ: Split ZooKeeper based dependencies off to a solr-solrj-zookeeper module /
+ dependency. (David Smiley, Haythem Khiri)
+
Build
---------------------
* SOLR-16204: Change Lucene dependency to Lucene 9.1.0 (Elia Porciani via Alessandro Benedetti)
diff --git a/solr/core/build.gradle b/solr/core/build.gradle
index adea2e71297..999214376e8 100644
--- a/solr/core/build.gradle
+++ b/solr/core/build.gradle
@@ -55,6 +55,7 @@ dependencies {
api 'org.slf4j:slf4j-api'
api project(':solr:solrj')
+ api project(':solr:solrj-zookeeper')
api 'io.dropwizard.metrics:metrics-core'
implementation ('io.dropwizard.metrics:metrics-graphite', {
diff --git a/solr/core/src/java/org/apache/solr/cloud/DistributedClusterStateUpdater.java b/solr/core/src/java/org/apache/solr/cloud/DistributedClusterStateUpdater.java
index b3209d21ddc..ca745b55ff6 100644
--- a/solr/core/src/java/org/apache/solr/cloud/DistributedClusterStateUpdater.java
+++ b/solr/core/src/java/org/apache/solr/cloud/DistributedClusterStateUpdater.java
@@ -38,6 +38,7 @@ import java.util.List;
import java.util.Optional;
import java.util.Set;
import org.apache.solr.client.solrj.cloud.SolrCloudManager;
+import org.apache.solr.client.solrj.impl.ZkClientClusterStateProvider;
import org.apache.solr.cloud.api.collections.CollectionHandlingUtils;
import org.apache.solr.cloud.overseer.ClusterStateMutator;
import org.apache.solr.cloud.overseer.CollectionMutator;
@@ -51,6 +52,7 @@ import org.apache.solr.common.SolrException;
import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.cloud.DocCollection;
import org.apache.solr.common.cloud.PerReplicaStates;
+import org.apache.solr.common.cloud.PerReplicaStatesFetcher;
import org.apache.solr.common.cloud.PerReplicaStatesOps;
import org.apache.solr.common.cloud.SolrZkClient;
import org.apache.solr.common.cloud.ZkNodeProps;
@@ -478,7 +480,7 @@ public class DistributedClusterStateUpdater {
firstAttempt = false;
// The parent node of the per replica state nodes happens to be the node of state.json.
- String prsParentNode = ZkStateReader.getCollectionPath(updater.getCollectionName());
+ String prsParentNode = DocCollection.getCollectionPath(updater.getCollectionName());
for (PerReplicaStatesOps prso : allStatesOps) {
prso.persist(prsParentNode, zkStateReader.getZkClient());
@@ -504,7 +506,7 @@ public class DistributedClusterStateUpdater {
// Fetch the per replica states updates done previously or skip fetching if we already
// have them
fetchedPerReplicaStates =
- PerReplicaStates.fetch(
+ PerReplicaStatesFetcher.fetch(
docCollection.getZNode(), zkStateReader.getZkClient(), fetchedPerReplicaStates);
// Transpose the per replica states into the cluster state
updatedState =
@@ -545,7 +547,7 @@ public class DistributedClusterStateUpdater {
// call will fail if the underlying cluster state update cannot be done, and that's a
// desirable thing).
throw new KeeperException.BadVersionException(
- ZkStateReader.getCollectionPath(updater.getCollectionName()));
+ DocCollection.getCollectionPath(updater.getCollectionName()));
}
/**
@@ -572,7 +574,7 @@ public class DistributedClusterStateUpdater {
*/
private void doStateDotJsonCasUpdate(ClusterState updatedState)
throws KeeperException, InterruptedException {
- String jsonPath = ZkStateReader.getCollectionPath(updater.getCollectionName());
+ String jsonPath = DocCollection.getCollectionPath(updater.getCollectionName());
// Collection delete
if (!updatedState.hasCollection(updater.getCollectionName())) {
@@ -619,7 +621,7 @@ public class DistributedClusterStateUpdater {
* fresh data is ok, a second attempt will be made)
*/
private ClusterState fetchStateForCollection() throws KeeperException, InterruptedException {
- String collectionStatePath = ZkStateReader.getCollectionPath(updater.getCollectionName());
+ String collectionStatePath = DocCollection.getCollectionPath(updater.getCollectionName());
Stat stat = new Stat();
byte[] data = zkStateReader.getZkClient().getData(collectionStatePath, null, stat, true);
@@ -627,7 +629,7 @@ public class DistributedClusterStateUpdater {
// old ZK location.
// TODO in Solr 10 remove that factory method
ClusterState clusterState =
- ClusterState.createFromJsonSupportingLegacyConfigName(
+ ZkClientClusterStateProvider.createFromJsonSupportingLegacyConfigName(
stat.getVersion(),
data,
Collections.emptySet(),
diff --git a/solr/core/src/java/org/apache/solr/cloud/OverseerTaskProcessor.java b/solr/core/src/java/org/apache/solr/cloud/OverseerTaskProcessor.java
index 443bcc728aa..9e9ac2be2dc 100644
--- a/solr/core/src/java/org/apache/solr/cloud/OverseerTaskProcessor.java
+++ b/solr/core/src/java/org/apache/solr/cloud/OverseerTaskProcessor.java
@@ -158,7 +158,7 @@ public class OverseerTaskProcessor implements Runnable, Closeable {
this.runningZKTasks = ConcurrentHashMap.newKeySet();
this.runningTasks = ConcurrentHashMap.newKeySet();
this.completedTasks = new ConcurrentHashMap<>();
- thisNode = Utils.getMDCNode();
+ thisNode = MDCLoggingContext.getNodeName();
overseerTaskProcessorMetricsContext = solrMetricsContext.getChildContext(this);
overseerTaskProcessorMetricsContext.gauge(
diff --git a/solr/core/src/java/org/apache/solr/cloud/RefreshCollectionMessage.java b/solr/core/src/java/org/apache/solr/cloud/RefreshCollectionMessage.java
index 573bf3bda8f..f9fca3cbddc 100644
--- a/solr/core/src/java/org/apache/solr/cloud/RefreshCollectionMessage.java
+++ b/solr/core/src/java/org/apache/solr/cloud/RefreshCollectionMessage.java
@@ -19,7 +19,6 @@ package org.apache.solr.cloud;
import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.cloud.DocCollection;
-import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.zookeeper.data.Stat;
/** Refresh the Cluster State for a given collection */
@@ -35,7 +34,7 @@ public class RefreshCollectionMessage implements Overseer.Message {
overseer
.getZkStateReader()
.getZkClient()
- .exists(ZkStateReader.getCollectionPath(collection), null, true);
+ .exists(DocCollection.getCollectionPath(collection), null, true);
if (stat == null) {
// collection does not exist
return clusterState.copyWith(collection, null);
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 210c576a425..b2ae127eb2a 100644
--- a/solr/core/src/java/org/apache/solr/cloud/ShardLeaderElectionContextBase.java
+++ b/solr/core/src/java/org/apache/solr/cloud/ShardLeaderElectionContextBase.java
@@ -25,6 +25,7 @@ import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrException.ErrorCode;
import org.apache.solr.common.cloud.DocCollection;
import org.apache.solr.common.cloud.PerReplicaStates;
+import org.apache.solr.common.cloud.PerReplicaStatesFetcher;
import org.apache.solr.common.cloud.PerReplicaStatesOps;
import org.apache.solr.common.cloud.Replica;
import org.apache.solr.common.cloud.SolrZkClient;
@@ -238,7 +239,7 @@ class ShardLeaderElectionContextBase extends ElectionContext {
}
} else {
PerReplicaStates prs =
- PerReplicaStates.fetch(coll.getZNode(), zkClient, coll.getPerReplicaStates());
+ PerReplicaStatesFetcher.fetch(coll.getZNode(), zkClient, coll.getPerReplicaStates());
PerReplicaStatesOps.flipLeader(
zkStateReader
.getClusterState()
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 7f0eeab34d3..b5da642e428 100644
--- a/solr/core/src/java/org/apache/solr/cloud/ZkController.java
+++ b/solr/core/src/java/org/apache/solr/cloud/ZkController.java
@@ -83,6 +83,7 @@ import org.apache.solr.common.cloud.LiveNodesListener;
import org.apache.solr.common.cloud.NodesSysPropsCacher;
import org.apache.solr.common.cloud.OnReconnect;
import org.apache.solr.common.cloud.PerReplicaStates;
+import org.apache.solr.common.cloud.PerReplicaStatesFetcher;
import org.apache.solr.common.cloud.PerReplicaStatesOps;
import org.apache.solr.common.cloud.Replica;
import org.apache.solr.common.cloud.Replica.Type;
@@ -1784,7 +1785,7 @@ public class ZkController implements Closeable {
log.debug("bypassed overseer for message : {}", Utils.toJSONString(m));
}
PerReplicaStates perReplicaStates =
- PerReplicaStates.fetch(coll.getZNode(), zkClient, coll.getPerReplicaStates());
+ PerReplicaStatesFetcher.fetch(coll.getZNode(), zkClient, coll.getPerReplicaStates());
PerReplicaStatesOps.flipState(coreNodeName, state, perReplicaStates)
.persist(coll.getZNode(), zkClient);
}
diff --git a/solr/core/src/java/org/apache/solr/cloud/api/collections/AddReplicaCmd.java b/solr/core/src/java/org/apache/solr/cloud/api/collections/AddReplicaCmd.java
index 93477c8cd44..1df96cd2986 100644
--- a/solr/core/src/java/org/apache/solr/cloud/api/collections/AddReplicaCmd.java
+++ b/solr/core/src/java/org/apache/solr/cloud/api/collections/AddReplicaCmd.java
@@ -254,7 +254,6 @@ public class AddReplicaCmd implements CollApiCmds.CollectionApiCommand {
boolean skipCreateReplicaInClusterState,
CreateReplica createReplica)
throws InterruptedException, KeeperException {
- ZkStateReader zkStateReader = ccc.getZkStateReader();
if (!skipCreateReplicaInClusterState) {
ZkNodeProps props =
new ZkNodeProps(
@@ -271,7 +270,7 @@ public class AddReplicaCmd implements CollApiCmds.CollectionApiCommand {
ZkStateReader.NODE_NAME_PROP,
createReplica.node,
ZkStateReader.BASE_URL_PROP,
- zkStateReader.getBaseUrlForNodeName(createReplica.node),
+ ccc.getZkStateReader().getBaseUrlForNodeName(createReplica.node),
ZkStateReader.REPLICA_TYPE,
createReplica.replicaType.name());
if (createReplica.coreNodeName != null) {
diff --git a/solr/core/src/java/org/apache/solr/cloud/api/collections/CollectionHandlingUtils.java b/solr/core/src/java/org/apache/solr/cloud/api/collections/CollectionHandlingUtils.java
index 41a2a7e4f71..76f077387a5 100644
--- a/solr/core/src/java/org/apache/solr/cloud/api/collections/CollectionHandlingUtils.java
+++ b/solr/core/src/java/org/apache/solr/cloud/api/collections/CollectionHandlingUtils.java
@@ -49,6 +49,7 @@ import org.apache.solr.cloud.overseer.OverseerAction;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.cloud.DocCollection;
+import org.apache.solr.common.cloud.DocCollection.CollectionStateProps;
import org.apache.solr.common.cloud.DocRouter;
import org.apache.solr.common.cloud.Replica;
import org.apache.solr.common.cloud.Slice;
@@ -91,8 +92,6 @@ public class CollectionHandlingUtils {
public static final String CREATE_NODE_SET_EMPTY = "EMPTY";
public static final String CREATE_NODE_SET = CollectionAdminParams.CREATE_NODE_SET_PARAM;
- public static final String ROUTER = "router";
-
public static final String SHARDS_PROP = "shards";
public static final String REQUESTID = "requestid";
@@ -109,17 +108,17 @@ public class CollectionHandlingUtils {
public static final Map<String, Object> COLLECTION_PROPS_AND_DEFAULTS =
Collections.unmodifiableMap(
Utils.makeMap(
- ROUTER,
+ CollectionStateProps.DOC_ROUTER,
DocRouter.DEFAULT_NAME,
- ZkStateReader.REPLICATION_FACTOR,
+ CollectionStateProps.REPLICATION_FACTOR,
"1",
- ZkStateReader.NRT_REPLICAS,
+ CollectionStateProps.NRT_REPLICAS,
"1",
- ZkStateReader.TLOG_REPLICAS,
+ CollectionStateProps.TLOG_REPLICAS,
"0",
- DocCollection.PER_REPLICA_STATE,
+ CollectionStateProps.PER_REPLICA_STATE,
null,
- ZkStateReader.PULL_REPLICAS,
+ CollectionStateProps.PULL_REPLICAS,
"0"));
public static final Random RANDOM;
diff --git a/solr/core/src/java/org/apache/solr/cloud/api/collections/CreateCollectionCmd.java b/solr/core/src/java/org/apache/solr/cloud/api/collections/CreateCollectionCmd.java
index 6663cd3876b..2a748fa9d30 100644
--- a/solr/core/src/java/org/apache/solr/cloud/api/collections/CreateCollectionCmd.java
+++ b/solr/core/src/java/org/apache/solr/cloud/api/collections/CreateCollectionCmd.java
@@ -62,9 +62,11 @@ import org.apache.solr.common.SolrException.ErrorCode;
import org.apache.solr.common.cloud.Aliases;
import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.cloud.DocCollection;
+import org.apache.solr.common.cloud.DocCollection.CollectionStateProps;
import org.apache.solr.common.cloud.DocRouter;
import org.apache.solr.common.cloud.ImplicitDocRouter;
import org.apache.solr.common.cloud.PerReplicaStates;
+import org.apache.solr.common.cloud.PerReplicaStatesFetcher;
import org.apache.solr.common.cloud.Replica;
import org.apache.solr.common.cloud.ReplicaPosition;
import org.apache.solr.common.cloud.ZkNodeProps;
@@ -107,7 +109,7 @@ public class CreateCollectionCmd implements CollApiCmds.CollectionApiCommand {
final boolean waitForFinalState = message.getBool(WAIT_FOR_FINAL_STATE, false);
final String alias = message.getStr(ALIAS, collectionName);
log.info("Create collection {}", collectionName);
- final boolean isPRS = message.getBool(DocCollection.PER_REPLICA_STATE, false);
+ final boolean isPRS = message.getBool(CollectionStateProps.PER_REPLICA_STATE, false);
if (clusterState.hasCollection(collectionName)) {
throw new SolrException(
SolrException.ErrorCode.BAD_REQUEST, "collection already exists: " + collectionName);
@@ -134,7 +136,7 @@ public class CreateCollectionCmd implements CollApiCmds.CollectionApiCommand {
List<String> shardNames = populateShardNames(message, router);
checkReplicaTypes(message);
DocCollection newColl = null;
- final String collectionPath = ZkStateReader.getCollectionPath(collectionName);
+ final String collectionPath = DocCollection.getCollectionPath(collectionName);
try {
@@ -333,7 +335,7 @@ public class CreateCollectionCmd implements CollApiCmds.CollectionApiCommand {
new SliceMutator(ccc.getSolrCloudManager()).addReplica(clusterState, props);
byte[] data = Utils.toJSON(Collections.singletonMap(collectionName, command.collection));
// log.info("collection updated : {}", new String(data, StandardCharsets.UTF_8));
- ccc.getZkStateReader().getZkClient().setData(collectionPath, data, true);
+ zkStateReader.getZkClient().setData(collectionPath, data, true);
clusterState = clusterState.copyWith(collectionName, command.collection);
newColl = command.collection;
} else {
@@ -426,11 +428,14 @@ public class CreateCollectionCmd implements CollApiCmds.CollectionApiCommand {
TimeUnit.SECONDS,
ccc.getSolrCloudManager().getTimeSource()); // could be a big cluster
PerReplicaStates prs =
- PerReplicaStates.fetch(collectionPath, ccc.getZkStateReader().getZkClient(), null);
+ PerReplicaStatesFetcher.fetch(
+ collectionPath, ccc.getZkStateReader().getZkClient(), null);
while (!timeout.hasTimedOut()) {
if (prs.allActive()) break;
Thread.sleep(100);
- prs = PerReplicaStates.fetch(collectionPath, ccc.getZkStateReader().getZkClient(), null);
+ prs =
+ PerReplicaStatesFetcher.fetch(
+ collectionPath, ccc.getZkStateReader().getZkClient(), null);
}
if (prs.allActive()) {
// we have successfully found all replicas to be ACTIVE
diff --git a/solr/core/src/java/org/apache/solr/cloud/api/collections/DeleteCollectionCmd.java b/solr/core/src/java/org/apache/solr/cloud/api/collections/DeleteCollectionCmd.java
index d906b53458d..d1eeb1497c3 100644
--- a/solr/core/src/java/org/apache/solr/cloud/api/collections/DeleteCollectionCmd.java
+++ b/solr/core/src/java/org/apache/solr/cloud/api/collections/DeleteCollectionCmd.java
@@ -209,7 +209,7 @@ public class DeleteCollectionCmd implements CollApiCmds.CollectionApiCommand {
} finally {
try {
- String collectionPath = ZkStateReader.getCollectionPathRoot(collection);
+ String collectionPath = DocCollection.getCollectionPathRoot(collection);
if (zkStateReader.getZkClient().exists(collectionPath, true)) {
if (removeCounterNode) {
zkStateReader.getZkClient().clean(collectionPath);
diff --git a/solr/core/src/java/org/apache/solr/cloud/api/collections/ReindexCollectionCmd.java b/solr/core/src/java/org/apache/solr/cloud/api/collections/ReindexCollectionCmd.java
index 868e2398ecc..663a0480574 100644
--- a/solr/core/src/java/org/apache/solr/cloud/api/collections/ReindexCollectionCmd.java
+++ b/solr/core/src/java/org/apache/solr/cloud/api/collections/ReindexCollectionCmd.java
@@ -617,7 +617,7 @@ public class ReindexCollectionCmd implements CollApiCmds.CollectionApiCommand {
String path = ZkStateReader.COLLECTIONS_ZKNODE + "/" + collection + REINDEXING_STATE_PATH;
DistribStateManager stateManager = ccc.getSolrCloudManager().getDistribStateManager();
if (props == null) { // retrieve existing props, if any
- props = Utils.getJson(stateManager, path);
+ props = stateManager.getJson(path);
}
Map<String, Object> copyProps = new HashMap<>(props);
copyProps.put("state", state.toLower());
@@ -642,7 +642,7 @@ public class ReindexCollectionCmd implements CollApiCmds.CollectionApiCommand {
DistribStateManager stateManager, String collection) throws Exception {
String path = ZkStateReader.COLLECTIONS_ZKNODE + "/" + collection + REINDEXING_STATE_PATH;
// make it modifiable
- return new TreeMap<>(Utils.getJson(stateManager, path));
+ return new TreeMap<>(stateManager.getJson(path));
}
private long getNumberOfDocs(String collection) {
diff --git a/solr/core/src/java/org/apache/solr/cloud/api/collections/RestoreCmd.java b/solr/core/src/java/org/apache/solr/cloud/api/collections/RestoreCmd.java
index f0a38f039b3..770768c76e2 100644
--- a/solr/core/src/java/org/apache/solr/cloud/api/collections/RestoreCmd.java
+++ b/solr/core/src/java/org/apache/solr/cloud/api/collections/RestoreCmd.java
@@ -56,6 +56,7 @@ import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrException.ErrorCode;
import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.cloud.DocCollection;
+import org.apache.solr.common.cloud.DocCollection.CollectionStateProps;
import org.apache.solr.common.cloud.ImplicitDocRouter;
import org.apache.solr.common.cloud.Replica;
import org.apache.solr.common.cloud.ReplicaPosition;
@@ -361,9 +362,10 @@ public class RestoreCmd implements CollApiCmds.CollectionApiCommand {
// router.*
@SuppressWarnings({"unchecked"})
Map<String, Object> routerProps =
- (Map<String, Object>) backupCollectionState.getProperties().get(DocCollection.DOC_ROUTER);
+ (Map<String, Object>)
+ backupCollectionState.getProperties().get(CollectionStateProps.DOC_ROUTER);
for (Map.Entry<String, Object> pair : routerProps.entrySet()) {
- propMap.put(DocCollection.DOC_ROUTER + "." + pair.getKey(), pair.getValue());
+ propMap.put(CollectionStateProps.DOC_ROUTER + "." + pair.getKey(), pair.getValue());
}
Set<String> sliceNames = backupCollectionState.getActiveSlicesMap().keySet();
diff --git a/solr/core/src/java/org/apache/solr/cloud/overseer/ClusterStateMutator.java b/solr/core/src/java/org/apache/solr/cloud/overseer/ClusterStateMutator.java
index b2ba75d9de4..f979d47a9af 100644
--- a/solr/core/src/java/org/apache/solr/cloud/overseer/ClusterStateMutator.java
+++ b/solr/core/src/java/org/apache/solr/cloud/overseer/ClusterStateMutator.java
@@ -31,10 +31,12 @@ import org.apache.solr.cloud.api.collections.CollectionHandlingUtils;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.cloud.DocCollection;
+import org.apache.solr.common.cloud.DocCollection.CollectionStateProps;
import org.apache.solr.common.cloud.DocRouter;
import org.apache.solr.common.cloud.ImplicitDocRouter;
import org.apache.solr.common.cloud.Replica;
import org.apache.solr.common.cloud.Slice;
+import org.apache.solr.common.cloud.Slice.SliceStateProps;
import org.apache.solr.common.cloud.ZkNodeProps;
import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.common.params.CollectionAdminParams;
@@ -93,7 +95,7 @@ public class ClusterStateMutator {
String sliceName = shardNames.get(i);
Map<String, Object> sliceProps = new LinkedHashMap<>(1);
- sliceProps.put(Slice.RANGE, ranges == null ? null : ranges.get(i));
+ sliceProps.put(SliceStateProps.RANGE, ranges == null ? null : ranges.get(i));
slices.put(sliceName, new Slice(sliceName, null, sliceProps, cName));
}
@@ -109,7 +111,7 @@ public class ClusterStateMutator {
}
if (val != null) collectionProps.put(e.getKey(), val);
}
- collectionProps.put(DocCollection.DOC_ROUTER, routerSpec);
+ collectionProps.put(CollectionStateProps.DOC_ROUTER, routerSpec);
if (message.getStr("fromApi") == null) {
collectionProps.put("autoCreated", "true");
diff --git a/solr/core/src/java/org/apache/solr/cloud/overseer/CollectionMutator.java b/solr/core/src/java/org/apache/solr/cloud/overseer/CollectionMutator.java
index 7bb5168f32b..1a6e1c9f583 100644
--- a/solr/core/src/java/org/apache/solr/cloud/overseer/CollectionMutator.java
+++ b/solr/core/src/java/org/apache/solr/cloud/overseer/CollectionMutator.java
@@ -32,10 +32,12 @@ import org.apache.solr.client.solrj.cloud.SolrCloudManager;
import org.apache.solr.client.solrj.request.CollectionAdminRequest;
import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.cloud.DocCollection;
-import org.apache.solr.common.cloud.PerReplicaStates;
+import org.apache.solr.common.cloud.DocCollection.CollectionStateProps;
+import org.apache.solr.common.cloud.PerReplicaStatesFetcher;
import org.apache.solr.common.cloud.PerReplicaStatesOps;
import org.apache.solr.common.cloud.Replica;
import org.apache.solr.common.cloud.Slice;
+import org.apache.solr.common.cloud.Slice.SliceStateProps;
import org.apache.solr.common.cloud.SolrZkClient;
import org.apache.solr.common.cloud.ZkNodeProps;
import org.apache.solr.common.cloud.ZkStateReader;
@@ -69,10 +71,10 @@ public class CollectionMutator {
String shardParent = message.getStr(ZkStateReader.SHARD_PARENT_PROP);
String shardParentZkSession = message.getStr("shard_parent_zk_session");
String shardParentNode = message.getStr("shard_parent_node");
- sliceProps.put(Slice.RANGE, shardRange);
+ sliceProps.put(SliceStateProps.RANGE, shardRange);
sliceProps.put(ZkStateReader.STATE_PROP, shardState);
if (shardParent != null) {
- sliceProps.put(Slice.PARENT, shardParent);
+ sliceProps.put(SliceStateProps.PARENT, shardParent);
}
if (shardParentZkSession != null) {
sliceProps.put("shard_parent_zk_session", shardParentZkSession);
@@ -116,8 +118,8 @@ public class CollectionMutator {
boolean hasAnyOps = false;
PerReplicaStatesOps replicaOps = null;
for (String prop : CollectionAdminRequest.MODIFIABLE_COLLECTION_PROPERTIES) {
- if (prop.equals(DocCollection.PER_REPLICA_STATE)) {
- String val = message.getStr(DocCollection.PER_REPLICA_STATE);
+ if (prop.equals(CollectionStateProps.PER_REPLICA_STATE)) {
+ String val = message.getStr(CollectionStateProps.PER_REPLICA_STATE);
if (val == null) continue;
boolean enable = Boolean.parseBoolean(val);
if (enable == coll.isPerReplicaState()) {
@@ -127,7 +129,7 @@ public class CollectionMutator {
}
replicaOps =
PerReplicaStatesOps.modifyCollection(
- coll, enable, PerReplicaStates.fetch(coll.getZNode(), zkClient, null));
+ coll, enable, PerReplicaStatesFetcher.fetch(coll.getZNode(), zkClient, null));
}
if (message.containsKey(prop)) {
diff --git a/solr/core/src/java/org/apache/solr/cloud/overseer/NodeMutator.java b/solr/core/src/java/org/apache/solr/cloud/overseer/NodeMutator.java
index 0830569dd2a..acd58a5e242 100644
--- a/solr/core/src/java/org/apache/solr/cloud/overseer/NodeMutator.java
+++ b/solr/core/src/java/org/apache/solr/cloud/overseer/NodeMutator.java
@@ -28,6 +28,7 @@ import org.apache.solr.client.solrj.cloud.SolrCloudManager;
import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.cloud.DocCollection;
import org.apache.solr.common.cloud.PerReplicaStates;
+import org.apache.solr.common.cloud.PerReplicaStatesFetcher;
import org.apache.solr.common.cloud.PerReplicaStatesOps;
import org.apache.solr.common.cloud.Replica;
import org.apache.solr.common.cloud.Slice;
@@ -121,7 +122,7 @@ public class NodeMutator {
PerReplicaStates prs =
client == null
? docCollection.getPerReplicaStates()
- : PerReplicaStates.fetch(
+ : PerReplicaStatesFetcher.fetch(
docCollection.getZNode(), client, docCollection.getPerReplicaStates());
return Optional.of(
diff --git a/solr/core/src/java/org/apache/solr/cloud/overseer/ReplicaMutator.java b/solr/core/src/java/org/apache/solr/cloud/overseer/ReplicaMutator.java
index 7055573e365..def546db285 100644
--- a/solr/core/src/java/org/apache/solr/cloud/overseer/ReplicaMutator.java
+++ b/solr/core/src/java/org/apache/solr/cloud/overseer/ReplicaMutator.java
@@ -44,9 +44,11 @@ import org.apache.solr.common.SolrException;
import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.cloud.DocCollection;
import org.apache.solr.common.cloud.PerReplicaStates;
+import org.apache.solr.common.cloud.PerReplicaStatesFetcher;
import org.apache.solr.common.cloud.PerReplicaStatesOps;
import org.apache.solr.common.cloud.Replica;
import org.apache.solr.common.cloud.Slice;
+import org.apache.solr.common.cloud.Slice.SliceStateProps;
import org.apache.solr.common.cloud.SolrZkClient;
import org.apache.solr.common.cloud.ZkNodeProps;
import org.apache.solr.common.cloud.ZkStateReader;
@@ -433,9 +435,9 @@ public class ReplicaMutator {
} else {
replicas = new HashMap<>(1);
sliceProps = new HashMap<>();
- sliceProps.put(Slice.RANGE, shardRange);
+ sliceProps.put(SliceStateProps.RANGE, shardRange);
sliceProps.put(ZkStateReader.STATE_PROP, shardState);
- sliceProps.put(Slice.PARENT, shardParent);
+ sliceProps.put(SliceStateProps.PARENT, shardParent);
}
replicas.put(replica.getName(), replica);
slice = new Slice(sliceName, replicas, sliceProps, collectionName);
@@ -444,7 +446,8 @@ public class ReplicaMutator {
log.debug("Collection is now: {}", newCollection);
if (collection != null && collection.isPerReplicaState()) {
PerReplicaStates prs =
- PerReplicaStates.fetch(collection.getZNode(), zkClient, collection.getPerReplicaStates());
+ PerReplicaStatesFetcher.fetch(
+ collection.getZNode(), zkClient, collection.getPerReplicaStates());
return new ZkWriteCommand(
collectionName,
newCollection,
@@ -523,7 +526,7 @@ public class ReplicaMutator {
// hurray, all sub shard replicas are active
log.info(
"Shard: {} - All replicas across all fellow sub-shards are now ACTIVE.", sliceName);
- String parentSliceName = (String) sliceProps.remove(Slice.PARENT);
+ String parentSliceName = (String) sliceProps.remove(SliceStateProps.PARENT);
// now lets see if the parent leader is still the same or else there's a chance of data
// loss see SOLR-9438 for details
String shardParentZkSession = (String) sliceProps.remove("shard_parent_zk_session");
diff --git a/solr/core/src/java/org/apache/solr/cloud/overseer/SliceMutator.java b/solr/core/src/java/org/apache/solr/cloud/overseer/SliceMutator.java
index adbdfe7f087..ed26494cf4e 100644
--- a/solr/core/src/java/org/apache/solr/cloud/overseer/SliceMutator.java
+++ b/solr/core/src/java/org/apache/solr/cloud/overseer/SliceMutator.java
@@ -31,10 +31,12 @@ import org.apache.solr.cloud.api.collections.Assign;
import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.cloud.DocCollection;
import org.apache.solr.common.cloud.PerReplicaStates;
+import org.apache.solr.common.cloud.PerReplicaStatesFetcher;
import org.apache.solr.common.cloud.PerReplicaStatesOps;
import org.apache.solr.common.cloud.Replica;
import org.apache.solr.common.cloud.RoutingRule;
import org.apache.solr.common.cloud.Slice;
+import org.apache.solr.common.cloud.Slice.SliceStateProps;
import org.apache.solr.common.cloud.SolrZkClient;
import org.apache.solr.common.cloud.ZkCoreNodeProps;
import org.apache.solr.common.cloud.ZkNodeProps;
@@ -109,7 +111,8 @@ public class SliceMutator {
if (collection.isPerReplicaState()) {
PerReplicaStates prs =
- PerReplicaStates.fetch(collection.getZNode(), zkClient, collection.getPerReplicaStates());
+ PerReplicaStatesFetcher.fetch(
+ collection.getZNode(), zkClient, collection.getPerReplicaStates());
return new ZkWriteCommand(
coll,
updateReplica(collection, sl, replica.getName(), replica),
@@ -147,7 +150,8 @@ public class SliceMutator {
if (coll.isPerReplicaState()) {
PerReplicaStatesOps replicaOps =
PerReplicaStatesOps.deleteReplica(
- cnn, PerReplicaStates.fetch(coll.getZNode(), zkClient, coll.getPerReplicaStates()));
+ cnn,
+ PerReplicaStatesFetcher.fetch(coll.getZNode(), zkClient, coll.getPerReplicaStates()));
return new ZkWriteCommand(collection, coll.copyWithSlices(newSlices), replicaOps, true);
} else {
return new ZkWriteCommand(collection, coll.copyWithSlices(newSlices));
@@ -190,11 +194,11 @@ public class SliceMutator {
}
Map<String, Object> newSliceProps = slice.shallowCopy();
- newSliceProps.put(Slice.REPLICAS, newReplicas);
+ newSliceProps.put(SliceStateProps.REPLICAS, newReplicas);
slice = new Slice(slice.getName(), newReplicas, slice.getProperties(), collectionName);
if (coll.isPerReplicaState()) {
PerReplicaStates prs =
- PerReplicaStates.fetch(coll.getZNode(), zkClient, coll.getPerReplicaStates());
+ PerReplicaStatesFetcher.fetch(coll.getZNode(), zkClient, coll.getPerReplicaStates());
return new ZkWriteCommand(
collectionName,
CollectionMutator.updateSlice(collectionName, coll, slice),
@@ -230,7 +234,7 @@ public class SliceMutator {
Map<String, Object> props = slice.shallowCopy();
if (Slice.State.getState(message.getStr(key)) == Slice.State.ACTIVE) {
- props.remove(Slice.PARENT);
+ props.remove(SliceStateProps.PARENT);
props.remove("shard_parent_node");
props.remove("shard_parent_zk_session");
}
diff --git a/solr/core/src/java/org/apache/solr/cloud/overseer/ZkStateWriter.java b/solr/core/src/java/org/apache/solr/cloud/overseer/ZkStateWriter.java
index e1bef0eb436..2908382e1c1 100644
--- a/solr/core/src/java/org/apache/solr/cloud/overseer/ZkStateWriter.java
+++ b/solr/core/src/java/org/apache/solr/cloud/overseer/ZkStateWriter.java
@@ -28,7 +28,7 @@ import org.apache.solr.cloud.Overseer;
import org.apache.solr.cloud.Stats;
import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.cloud.DocCollection;
-import org.apache.solr.common.cloud.PerReplicaStates;
+import org.apache.solr.common.cloud.PerReplicaStatesFetcher;
import org.apache.solr.common.cloud.PerReplicaStatesOps;
import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.common.util.Utils;
@@ -223,7 +223,7 @@ public class ZkStateWriter {
if (!updates.isEmpty()) {
for (Map.Entry<String, ZkWriteCommand> entry : updates.entrySet()) {
String name = entry.getKey();
- String path = ZkStateReader.getCollectionPath(name);
+ String path = DocCollection.getCollectionPath(name);
ZkWriteCommand cmd = entry.getValue();
DocCollection c = cmd.collection;
@@ -234,7 +234,7 @@ public class ZkStateWriter {
clusterState.copyWith(
name,
cmd.collection.copyWith(
- PerReplicaStates.fetch(
+ PerReplicaStatesFetcher.fetch(
cmd.collection.getZNode(), reader.getZkClient(), null)));
}
@@ -279,7 +279,7 @@ public class ZkStateWriter {
clusterState.copyWith(
name,
currentCollState.copyWith(
- PerReplicaStates.fetch(
+ PerReplicaStatesFetcher.fetch(
currentCollState.getZNode(), reader.getZkClient(), null)));
}
}
diff --git a/solr/core/src/java/org/apache/solr/filestore/DistribPackageStore.java b/solr/core/src/java/org/apache/solr/filestore/DistribPackageStore.java
index fca382f2227..ef63850ac6b 100644
--- a/solr/core/src/java/org/apache/solr/filestore/DistribPackageStore.java
+++ b/solr/core/src/java/org/apache/solr/filestore/DistribPackageStore.java
@@ -50,7 +50,6 @@ import org.apache.lucene.util.IOUtils;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.annotation.SolrThreadUnsafe;
import org.apache.solr.common.cloud.SolrZkClient;
-import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.util.Utils;
import org.apache.solr.core.CoreContainer;
@@ -218,10 +217,10 @@ public class DistribPackageStore implements PackageStore {
boolean fetchFromAnyNode() {
ArrayList<String> l = coreContainer.getPackageStoreAPI().shuffledNodes();
- ZkStateReader stateReader = coreContainer.getZkController().getZkStateReader();
for (String liveNode : l) {
try {
- String baseurl = stateReader.getBaseUrlForNodeName(liveNode);
+ String baseurl =
+ coreContainer.getZkController().getZkStateReader().getBaseUrlForNodeName(liveNode);
String url = baseurl.replace("/solr", "/api");
String reqUrl = url + "/node/files" + path + "?meta=true&wt=javabin&omitHeader=true";
boolean nodeHasBlob = false;
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java
index 72a5751abce..becfff21dd3 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java
@@ -33,8 +33,6 @@ import static org.apache.solr.cloud.api.collections.CollectionHandlingUtils.SHAR
import static org.apache.solr.cloud.api.collections.CollectionHandlingUtils.SHARD_UNIQUE;
import static org.apache.solr.cloud.api.collections.RoutedAlias.CREATE_COLLECTION_PREFIX;
import static org.apache.solr.common.SolrException.ErrorCode.BAD_REQUEST;
-import static org.apache.solr.common.cloud.DocCollection.DOC_ROUTER;
-import static org.apache.solr.common.cloud.DocCollection.PER_REPLICA_STATE;
import static org.apache.solr.common.cloud.ZkStateReader.COLLECTION_PROP;
import static org.apache.solr.common.cloud.ZkStateReader.NRT_REPLICAS;
import static org.apache.solr.common.cloud.ZkStateReader.PROPERTY_PROP;
@@ -50,6 +48,7 @@ import static org.apache.solr.common.params.CollectionAdminParams.COLLECTION;
import static org.apache.solr.common.params.CollectionAdminParams.COLL_CONF;
import static org.apache.solr.common.params.CollectionAdminParams.COUNT_PROP;
import static org.apache.solr.common.params.CollectionAdminParams.FOLLOW_ALIASES;
+import static org.apache.solr.common.params.CollectionAdminParams.PER_REPLICA_STATE;
import static org.apache.solr.common.params.CollectionAdminParams.PROPERTY_NAME;
import static org.apache.solr.common.params.CollectionAdminParams.PROPERTY_PREFIX;
import static org.apache.solr.common.params.CollectionAdminParams.PROPERTY_VALUE;
@@ -167,6 +166,7 @@ import org.apache.solr.common.cloud.ClusterProperties;
import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.cloud.CollectionProperties;
import org.apache.solr.common.cloud.DocCollection;
+import org.apache.solr.common.cloud.DocCollection.CollectionStateProps;
import org.apache.solr.common.cloud.ImplicitDocRouter;
import org.apache.solr.common.cloud.Replica;
import org.apache.solr.common.cloud.Replica.State;
@@ -941,7 +941,11 @@ public class CollectionsHandler extends RequestHandlerBase implements Permission
.resolveSimpleAlias(extCollectionName)
: extCollectionName;
if (!ImplicitDocRouter.NAME.equals(
- ((Map<?, ?>) clusterState.getCollection(collectionName).get(DOC_ROUTER)).get(NAME)))
+ ((Map<?, ?>)
+ clusterState
+ .getCollection(collectionName)
+ .get(CollectionStateProps.DOC_ROUTER))
+ .get(NAME)))
throw new SolrException(
ErrorCode.BAD_REQUEST, "shards can be added only to 'implicit' collections");
copy(
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/SplitOp.java b/solr/core/src/java/org/apache/solr/handler/admin/SplitOp.java
index c751f5d2544..2e3481bc966 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/SplitOp.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/SplitOp.java
@@ -17,7 +17,6 @@
package org.apache.solr.handler.admin;
-import static org.apache.solr.common.cloud.DocCollection.DOC_ROUTER;
import static org.apache.solr.common.params.CommonParams.PATH;
import static org.apache.solr.common.params.CoreAdminParams.GET_RANGES;
@@ -40,6 +39,7 @@ import org.apache.solr.common.SolrException;
import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.cloud.CompositeIdRouter;
import org.apache.solr.common.cloud.DocCollection;
+import org.apache.solr.common.cloud.DocCollection.CollectionStateProps;
import org.apache.solr.common.cloud.DocRouter;
import org.apache.solr.common.cloud.Slice;
import org.apache.solr.common.params.CommonAdminParams;
@@ -136,7 +136,8 @@ class SplitOp implements CoreAdminHandler.CoreAdminOp {
DocRouter.Range currentRange = slice.getRange();
ranges = currentRange != null ? router.partitionRange(partitions, currentRange) : null;
}
- Object routerObj = collection.get(DOC_ROUTER); // for back-compat with Solr 4.4
+ Object routerObj =
+ collection.get(CollectionStateProps.DOC_ROUTER); // for back-compat with Solr 4.4
if (routerObj instanceof Map) {
Map<?, ?> routerProps = (Map<?, ?>) routerObj;
routeFieldName = (String) routerProps.get("field");
@@ -249,7 +250,8 @@ class SplitOp implements CoreAdminHandler.CoreAdminOp {
collection.getRouter() != null ? collection.getRouter() : DocRouter.DEFAULT;
DocRouter.Range currentRange = slice.getRange();
- Object routerObj = collection.get(DOC_ROUTER); // for back-compat with Solr 4.4
+ Object routerObj =
+ collection.get(CollectionStateProps.DOC_ROUTER); // for back-compat with Solr 4.4
if (routerObj instanceof Map) {
Map<?, ?> routerProps = (Map<?, ?>) routerObj;
routeFieldName = (String) routerProps.get("field");
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/ZookeeperInfoHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/ZookeeperInfoHandler.java
index 479f9b4115c..3191b83ba82 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/ZookeeperInfoHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/ZookeeperInfoHandler.java
@@ -47,9 +47,10 @@ import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrException.ErrorCode;
import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.cloud.DocCollection;
+import org.apache.solr.common.cloud.DocCollection.CollectionStateProps;
import org.apache.solr.common.cloud.OnReconnect;
import org.apache.solr.common.cloud.Replica;
-import org.apache.solr.common.cloud.Slice;
+import org.apache.solr.common.cloud.Slice.SliceStateProps;
import org.apache.solr.common.cloud.SolrZkClient;
import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.common.params.MapSolrParams;
@@ -190,11 +191,12 @@ public final class ZookeeperInfoHandler extends RequestHandlerBase {
boolean hasDownedShard = false; // means one or more shards is down
boolean replicaInRecovery = false;
- Map<String, Object> shards = (Map<String, Object>) collectionState.get(DocCollection.SHARDS);
+ Map<String, Object> shards =
+ (Map<String, Object>) collectionState.get(CollectionStateProps.SHARDS);
for (Object o : shards.values()) {
boolean hasActive = false;
Map<String, Object> shard = (Map<String, Object>) o;
- Map<String, Object> replicas = (Map<String, Object>) shard.get(Slice.REPLICAS);
+ Map<String, Object> replicas = (Map<String, Object>) shard.get(SliceStateProps.REPLICAS);
for (Object value : replicas.values()) {
Map<String, Object> replicaState = (Map<String, Object>) value;
Replica.State coreState =
diff --git a/solr/core/src/java/org/apache/solr/logging/MDCLoggingContext.java b/solr/core/src/java/org/apache/solr/logging/MDCLoggingContext.java
index ea6194dadb2..92c13b4178f 100644
--- a/solr/core/src/java/org/apache/solr/logging/MDCLoggingContext.java
+++ b/solr/core/src/java/org/apache/solr/logging/MDCLoggingContext.java
@@ -108,6 +108,16 @@ public class MDCLoggingContext {
}
}
+ public static String getNodeName() {
+ String s = MDC.get(NODE_NAME_PROP);
+ if (s == null) return null;
+ if (s.startsWith("n:")) {
+ return s.substring(2);
+ } else {
+ return null;
+ }
+ }
+
/** Sets multiple information from the params. REMEMBER TO CALL {@link #clear()} in a finally! */
public static void setCore(SolrCore core) {
CoreContainer coreContainer = core == null ? null : core.getCoreContainer();
diff --git a/solr/core/src/test/org/apache/solr/cloud/ClusterStateMockUtil.java b/solr/core/src/test/org/apache/solr/cloud/ClusterStateMockUtil.java
index 3145737bf80..674fe60b8a6 100644
--- a/solr/core/src/test/org/apache/solr/cloud/ClusterStateMockUtil.java
+++ b/solr/core/src/test/org/apache/solr/cloud/ClusterStateMockUtil.java
@@ -29,6 +29,7 @@ import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.cloud.DocCollection;
import org.apache.solr.common.cloud.DocRouter;
import org.apache.solr.common.cloud.Replica;
+import org.apache.solr.common.cloud.Replica.ReplicaStateProps;
import org.apache.solr.common.cloud.Slice;
import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.common.util.Utils;
@@ -169,13 +170,13 @@ public class ClusterStateMockUtil {
boolean leaderFound = false;
for (Map.Entry<String, Replica> entry : replicas.entrySet()) {
Replica value = entry.getValue();
- if ("true".equals(value.get(Slice.LEADER))) {
+ if ("true".equals(value.get(ReplicaStateProps.LEADER))) {
leaderFound = true;
break;
}
}
if (!leaderFound && !m.group(1).equals("p")) {
- replicaPropMap.put(Slice.LEADER, "true");
+ replicaPropMap.put(ReplicaStateProps.LEADER, "true");
}
replica = new Replica(replicaName, replicaPropMap, collName, sliceName);
replicas.put(replica.getName(), replica);
diff --git a/solr/core/src/test/org/apache/solr/cloud/CollectionStateZnodeTest.java b/solr/core/src/test/org/apache/solr/cloud/CollectionStateZnodeTest.java
index 3ff63d93d76..0c43b93ea80 100644
--- a/solr/core/src/test/org/apache/solr/cloud/CollectionStateZnodeTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/CollectionStateZnodeTest.java
@@ -18,7 +18,6 @@ package org.apache.solr.cloud;
import org.apache.solr.client.solrj.request.CollectionAdminRequest;
import org.apache.solr.common.cloud.DocCollection;
-import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.zookeeper.data.Stat;
import org.junit.After;
import org.junit.BeforeClass;
@@ -51,10 +50,10 @@ public class CollectionStateZnodeTest extends SolrCloudTestCase {
(n, c) -> DocCollection.isFullyActive(n, c, 2, 2));
assertTrue(
"Collection path does not exist",
- zkClient().exists(ZkStateReader.getCollectionPath(collectionName), true));
+ zkClient().exists(DocCollection.getCollectionPath(collectionName), true));
Stat stat = new Stat();
- zkClient().getData(ZkStateReader.getCollectionPath(collectionName), null, stat, true);
+ zkClient().getData(DocCollection.getCollectionPath(collectionName), null, stat, true);
DocCollection c = getCollectionState(collectionName);
@@ -69,6 +68,6 @@ public class CollectionStateZnodeTest extends SolrCloudTestCase {
assertFalse(
"collection state should not exist",
- zkClient().exists(ZkStateReader.getCollectionPath(collectionName), true));
+ zkClient().exists(DocCollection.getCollectionPath(collectionName), true));
}
}
diff --git a/solr/core/src/test/org/apache/solr/cloud/FullSolrCloudDistribCmdsTest.java b/solr/core/src/test/org/apache/solr/cloud/FullSolrCloudDistribCmdsTest.java
index 546ea4fbbcd..d8d3d8869fa 100644
--- a/solr/core/src/test/org/apache/solr/cloud/FullSolrCloudDistribCmdsTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/FullSolrCloudDistribCmdsTest.java
@@ -45,6 +45,7 @@ import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.cloud.CollectionStatePredicate;
import org.apache.solr.common.cloud.DocCollection;
import org.apache.solr.common.cloud.Replica;
+import org.apache.solr.common.cloud.Replica.ReplicaStateProps;
import org.apache.solr.common.cloud.Slice;
import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.common.params.SolrParams;
@@ -425,7 +426,7 @@ public class FullSolrCloudDistribCmdsTest extends SolrCloudTestCase {
// No point in this test if these aren't true...
assertNotNull(
"Sanity check: leaderProps isn't a leader?: " + leaderProps.toString(),
- leaderProps.getStr(Slice.LEADER));
+ leaderProps.getStr(ReplicaStateProps.LEADER));
assertTrue(
"Sanity check: leaderProps isn't using the proxy port?: " + leaderProps,
leaderProps.getCoreUrl().contains("" + proxy.getListenPort()));
diff --git a/solr/core/src/test/org/apache/solr/cloud/ReplaceNodeTest.java b/solr/core/src/test/org/apache/solr/cloud/ReplaceNodeTest.java
index 8c5faa71272..1bfa9aadee0 100644
--- a/solr/core/src/test/org/apache/solr/cloud/ReplaceNodeTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/ReplaceNodeTest.java
@@ -115,9 +115,9 @@ public class ReplaceNodeTest extends SolrCloudTestCase {
log.info("excluded_node : {} ", emptyNode);
createReplaceNodeRequest(nodeToBeDecommissioned, emptyNode, null)
.processAndWait("000", cloudClient, 15);
+ ZkStateReader zkStateReader = ZkStateReader.from(cloudClient);
try (HttpSolrClient coreclient =
- getHttpSolrClient(
- ZkStateReader.from(cloudClient).getBaseUrlForNodeName(nodeToBeDecommissioned))) {
+ getHttpSolrClient(zkStateReader.getBaseUrlForNodeName(nodeToBeDecommissioned))) {
CoreAdminResponse status = CoreAdminRequest.getStatus(null, coreclient);
assertEquals(0, status.getCoreStatus().size());
}
@@ -139,7 +139,7 @@ public class ReplaceNodeTest extends SolrCloudTestCase {
replaceNodeRequest.processAndWait("001", cloudClient, 10);
try (HttpSolrClient coreclient =
- getHttpSolrClient(ZkStateReader.from(cloudClient).getBaseUrlForNodeName(emptyNode))) {
+ getHttpSolrClient(zkStateReader.getBaseUrlForNodeName(emptyNode))) {
CoreAdminResponse status = CoreAdminRequest.getStatus(null, coreclient);
assertEquals(
"Expecting no cores but found some: " + status.getCoreStatus(),
diff --git a/solr/core/src/test/org/apache/solr/cloud/ZkControllerTest.java b/solr/core/src/test/org/apache/solr/cloud/ZkControllerTest.java
index b675541e15b..78cc987b76e 100644
--- a/solr/core/src/test/org/apache/solr/cloud/ZkControllerTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/ZkControllerTest.java
@@ -31,6 +31,7 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.common.cloud.ClusterProperties;
+import org.apache.solr.common.cloud.DocCollection;
import org.apache.solr.common.cloud.SolrZkClient;
import org.apache.solr.common.cloud.ZkNodeProps;
import org.apache.solr.common.cloud.ZkStateReader;
@@ -257,7 +258,7 @@ public class ZkControllerTest extends SolrTestCaseJ4 {
zkController
.getZkClient()
.makePath(
- ZkStateReader.getCollectionPathRoot(collectionName),
+ DocCollection.getCollectionPathRoot(collectionName),
new byte[0],
CreateMode.PERSISTENT,
true);
diff --git a/solr/core/src/test/org/apache/solr/cloud/api/collections/CustomCollectionTest.java b/solr/core/src/test/org/apache/solr/cloud/api/collections/CustomCollectionTest.java
index ccab98767ed..1c1644394ee 100644
--- a/solr/core/src/test/org/apache/solr/cloud/api/collections/CustomCollectionTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/api/collections/CustomCollectionTest.java
@@ -16,7 +16,7 @@
*/
package org.apache.solr.cloud.api.collections;
-import static org.apache.solr.common.cloud.DocCollection.DOC_ROUTER;
+import static org.apache.solr.common.cloud.DocCollection.CollectionStateProps.DOC_ROUTER;
import static org.apache.solr.common.cloud.ZkStateReader.REPLICATION_FACTOR;
import static org.apache.solr.common.params.ShardParams._ROUTE_;
diff --git a/solr/core/src/test/org/apache/solr/cloud/overseer/ZkStateReaderTest.java b/solr/core/src/test/org/apache/solr/cloud/overseer/ZkStateReaderTest.java
index 4d7e8b67cc8..73093e41f3f 100644
--- a/solr/core/src/test/org/apache/solr/cloud/overseer/ZkStateReaderTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/overseer/ZkStateReaderTest.java
@@ -41,6 +41,7 @@ import org.apache.solr.common.cloud.DocCollection;
import org.apache.solr.common.cloud.DocCollectionWatcher;
import org.apache.solr.common.cloud.DocRouter;
import org.apache.solr.common.cloud.PerReplicaStates;
+import org.apache.solr.common.cloud.PerReplicaStatesFetcher;
import org.apache.solr.common.cloud.PerReplicaStatesOps;
import org.apache.solr.common.cloud.Replica;
import org.apache.solr.common.cloud.SolrZkClient;
@@ -259,7 +260,7 @@ public class ZkStateReaderTest extends SolrTestCaseJ4 {
DocCollection collection = ref.get();
PerReplicaStates prs =
- PerReplicaStates.fetch(
+ PerReplicaStatesFetcher.fetch(
collection.getZNode(), fixture.zkClient, collection.getPerReplicaStates());
PerReplicaStatesOps.addReplica("r1", Replica.State.DOWN, false, prs)
.persist(collection.getZNode(), fixture.zkClient);
@@ -318,7 +319,7 @@ public class ZkStateReaderTest extends SolrTestCaseJ4 {
// re-add PRS
collection = ref.get();
prs =
- PerReplicaStates.fetch(
+ PerReplicaStatesFetcher.fetch(
collection.getZNode(), fixture.zkClient, collection.getPerReplicaStates());
PerReplicaStatesOps.addReplica("r1", Replica.State.DOWN, false, prs)
.persist(collection.getZNode(), fixture.zkClient);
diff --git a/solr/core/src/test/org/apache/solr/cloud/overseer/ZkStateWriterTest.java b/solr/core/src/test/org/apache/solr/cloud/overseer/ZkStateWriterTest.java
index 2d4b39f7d02..ca7577ab3f9 100644
--- a/solr/core/src/test/org/apache/solr/cloud/overseer/ZkStateWriterTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/overseer/ZkStateWriterTest.java
@@ -212,8 +212,8 @@ public class ZkStateWriterTest extends SolrTestCaseJ4 {
int c2Version = state.getCollection("c2").getZNodeVersion();
// Simulate an external modification to /collections/c2/state.json
- byte[] data = zkClient.getData(ZkStateReader.getCollectionPath("c2"), null, null, true);
- zkClient.setData(ZkStateReader.getCollectionPath("c2"), data, true);
+ byte[] data = zkClient.getData(DocCollection.getCollectionPath("c2"), null, null, true);
+ zkClient.setData(DocCollection.getCollectionPath("c2"), data, true);
// get the most up-to-date state
reader.forceUpdateCollection("c2");
diff --git a/solr/core/src/test/org/apache/solr/handler/admin/V2CollectionsAPIMappingTest.java b/solr/core/src/test/org/apache/solr/handler/admin/V2CollectionsAPIMappingTest.java
index 7b1dafdafa7..bf0b2db17cb 100644
--- a/solr/core/src/test/org/apache/solr/handler/admin/V2CollectionsAPIMappingTest.java
+++ b/solr/core/src/test/org/apache/solr/handler/admin/V2CollectionsAPIMappingTest.java
@@ -22,7 +22,6 @@ import java.util.Locale;
import org.apache.solr.client.solrj.request.CollectionAdminRequest;
import org.apache.solr.cloud.api.collections.CategoryRoutedAlias;
import org.apache.solr.cloud.api.collections.RoutedAlias;
-import org.apache.solr.common.cloud.DocCollection;
import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.common.params.CollectionAdminParams;
import org.apache.solr.common.params.CollectionParams;
@@ -111,7 +110,7 @@ public class V2CollectionsAPIMappingTest extends V2ApiMappingTest<CollectionsHan
assertEquals("bar2", v1Params.get("property.foo2"));
assertEquals("requestTrackingId", v1Params.get(CommonAdminParams.ASYNC));
assertEquals(false, v1Params.getPrimitiveBool(CommonAdminParams.WAIT_FOR_FINAL_STATE));
- assertEquals(false, v1Params.getPrimitiveBool(DocCollection.PER_REPLICA_STATE));
+ assertEquals(false, v1Params.getPrimitiveBool(CollectionAdminParams.PER_REPLICA_STATE));
assertEquals(1, v1Params.getPrimitiveInt(CollectionAdminParams.NUM_SHARDS));
}
diff --git a/solr/modules/analytics/src/java/org/apache/solr/analytics/stream/AnalyticsShardRequestManager.java b/solr/modules/analytics/src/java/org/apache/solr/analytics/stream/AnalyticsShardRequestManager.java
index fb3045414c2..977a2fef7ca 100644
--- a/solr/modules/analytics/src/java/org/apache/solr/analytics/stream/AnalyticsShardRequestManager.java
+++ b/solr/modules/analytics/src/java/org/apache/solr/analytics/stream/AnalyticsShardRequestManager.java
@@ -41,7 +41,6 @@ import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.cloud.Replica;
import org.apache.solr.common.cloud.Slice;
import org.apache.solr.common.cloud.ZkCoreNodeProps;
-import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.params.SolrParams;
@@ -104,8 +103,7 @@ public class AnalyticsShardRequestManager {
protected void pickShards(String collection) throws IOException {
try {
- ZkStateReader zkStateReader = ZkStateReader.from(cloudSolrClient);
- ClusterState clusterState = zkStateReader.getClusterState();
+ ClusterState clusterState = cloudSolrClient.getClusterState();
Set<String> liveNodes = clusterState.getLiveNodes();
Slice[] slices = clusterState.getCollection(collection).getActiveSlicesArr();
diff --git a/solr/modules/hadoop-auth/build.gradle b/solr/modules/hadoop-auth/build.gradle
index a0672bf772f..e96e512aa79 100644
--- a/solr/modules/hadoop-auth/build.gradle
+++ b/solr/modules/hadoop-auth/build.gradle
@@ -32,6 +32,7 @@ dependencies {
implementation project(':solr:core')
implementation project(':solr:solrj')
+ implementation project(':solr:solrj-zookeeper')
implementation 'org.slf4j:slf4j-api'
diff --git a/solr/modules/hdfs/build.gradle b/solr/modules/hdfs/build.gradle
index 607ccc95c7e..29467b7d27b 100644
--- a/solr/modules/hdfs/build.gradle
+++ b/solr/modules/hdfs/build.gradle
@@ -39,6 +39,7 @@ dependencies {
implementation 'commons-cli:commons-cli'
testImplementation project(':solr:test-framework')
+ testImplementation project(':solr:solrj-zookeeper')
testImplementation 'org.apache.lucene:lucene-test-framework'
testImplementation 'com.carrotsearch.randomizedtesting:randomizedtesting-runner'
testImplementation 'junit:junit'
diff --git a/solr/modules/sql/build.gradle b/solr/modules/sql/build.gradle
index fe23cccd969..7b0bc20c253 100644
--- a/solr/modules/sql/build.gradle
+++ b/solr/modules/sql/build.gradle
@@ -22,6 +22,7 @@ description = 'SQL Module'
dependencies {
implementation project(':solr:core')
implementation project(':solr:solrj')
+ implementation project(':solr:solrj-zookeeper')
implementation 'org.slf4j:slf4j-api'
diff --git a/solr/modules/sql/src/java/org/apache/solr/handler/sql/SolrSchema.java b/solr/modules/sql/src/java/org/apache/solr/handler/sql/SolrSchema.java
index 9bdac755cae..02a02fe672d 100644
--- a/solr/modules/sql/src/java/org/apache/solr/handler/sql/SolrSchema.java
+++ b/solr/modules/sql/src/java/org/apache/solr/handler/sql/SolrSchema.java
@@ -87,8 +87,7 @@ class SolrSchema extends AbstractSchema implements Closeable {
protected Map<String, Table> getTableMap() {
String zk = this.properties.getProperty("zk");
CloudSolrClient cloudSolrClient = solrClientCache.getCloudSolrClient(zk);
- ZkStateReader zkStateReader = ZkStateReader.from(cloudSolrClient);
- ClusterState clusterState = zkStateReader.getClusterState();
+ ClusterState clusterState = cloudSolrClient.getClusterState();
final ImmutableMap.Builder<String, Table> builder = ImmutableMap.builder();
@@ -97,7 +96,7 @@ class SolrSchema extends AbstractSchema implements Closeable {
builder.put(collection, new SolrTable(this, collection));
}
- Aliases aliases = zkStateReader.getAliases();
+ Aliases aliases = ZkStateReader.from(cloudSolrClient).getAliases();
for (String alias : aliases.getCollectionAliasListMap().keySet()) {
// don't create duplicate entries
if (!collections.contains(alias)) {
diff --git a/solr/solr-ref-guide/modules/deployment-guide/pages/solrj.adoc b/solr/solr-ref-guide/modules/deployment-guide/pages/solrj.adoc
index 8f2ba8a9ce2..d8e11837f0c 100644
--- a/solr/solr-ref-guide/modules/deployment-guide/pages/solrj.adoc
+++ b/solr/solr-ref-guide/modules/deployment-guide/pages/solrj.adoc
@@ -54,6 +54,8 @@ For projects built with Gradle, place the following in your `build.gradle`:
compile group: 'org.apache.solr', name: 'solr-solrj', version: '{solr-full-version}'
----
+If you want to use `CloudSolrClient` _and_ have it talk directly to ZooKeeper, you will need to add a dependency on the `solr-solrj-zookeeper` artifact.
+
=== Adding SolrJ to the Classpath Manually
If you are not using one of the above build system, it's still easy to add SolrJ to your build.
@@ -155,6 +157,9 @@ include::example$UsingSolrJRefGuideExamplesTest.java[tag=solrj-cloudsolrclient-z
include::example$UsingSolrJRefGuideExamplesTest.java[tag=solrj-cloudsolrclient-zookeeperroot]
----
+Additionally, you will need to depend on the `solr-solrj-zookeeper` artifact or else you will get a `ClassNotFoundException`.
+
+The ZooKeeper based connection is the most reliable and performant means for CloudSolrClient to work. On the other hand, it means exposing ZooKeeper more broadly than to Solr nodes, which is a security risk. It also adds more JAR dependencies.
==== Timeouts
All `SolrClient` implementations allow users to specify the connection and read timeouts for communicating with Solr.
diff --git a/solr/solr-ref-guide/modules/deployment-guide/pages/zookeeper-access-control.adoc b/solr/solr-ref-guide/modules/deployment-guide/pages/zookeeper-access-control.adoc
index 4125e4b1d96..8aee24c4a8d 100644
--- a/solr/solr-ref-guide/modules/deployment-guide/pages/zookeeper-access-control.adoc
+++ b/solr/solr-ref-guide/modules/deployment-guide/pages/zookeeper-access-control.adoc
@@ -65,13 +65,13 @@ The credentials are used to get permission to perform operations in ZooKeeper.
. Control which ACLs Solr will add to znodes (ZooKeeper files/folders) it creates in ZooKeeper.
. Control it "from the outside", so that you do not have to modify and/or recompile Solr code to turn this on.
-Solr nodes, clients, and tools (e.g., ZkCLI) always use a java class called {solr-javadocs}/solrj/org/apache/solr/common/cloud/SolrZkClient.html[`SolrZkClient`] to deal with their ZooKeeper stuff.
+Solr nodes, clients, and tools (e.g., ZkCLI) always use a java class called {solr-javadocs}/solrj-zookeeper/org/apache/solr/common/cloud/SolrZkClient.html[`SolrZkClient`] to deal with their ZooKeeper stuff.
The implementation of the solution described here is all about changing `SolrZkClient`.
If you use `SolrZkClient` in your application, the descriptions below will be true for your application too.
=== Controlling Credentials
-You control which credentials provider will be used by configuring the `zkCredentialsProvider` property in the `<solrcloud>` section of xref:configuration-guide:configuring-solr-xml.adoc[`solr.xml`] to the name of a class (on the classpath) implementing the {solr-javadocs}/solrj/org/apache/solr/common/cloud/ZkCredentialsProvider.html[`ZkCredentialsProvider`] interface.
+You control which credentials provider will be used by configuring the `zkCredentialsProvider` property in the `<solrcloud>` section of xref:configuration-guide:configuring-solr-xml.adoc[`solr.xml`] to the name of a class (on the classpath) implementing the {solr-javadocs}/solrj-zookeeper/org/apache/solr/common/cloud/ZkCredentialsProvider.html[`ZkCredentialsProvider`] interface.
`solr.xml` defines the `zkCredentialsProvider` such that it will take on the value of the same-named `zkCredentialsProvider` system property if it is defined (in `solr.in.sh/.cmd` - see <<ZooKeeper ACLs in Solr Scripts,below>>), or if not, default to the `DefaultZkCredentialsProvider` implementation.
@@ -91,7 +91,7 @@ This set of credentials will be added to the list of credentials returned by `ge
=== Controlling ACLs
-You control which ACLs will be added by configuring `zkACLProvider` property in the `<solrcloud>` section of xref:configuration-guide:configuring-solr-xml.adoc[`solr.xml`] to the name of a class (on the classpath) implementing the {solr-javadocs}/solrj/org/apache/solr/common/cloud/ZkACLProvider.html[`ZkACLProvider`] interface.
+You control which ACLs will be added by configuring `zkACLProvider` property in the `<solrcloud>` section of xref:configuration-guide:configuring-solr-xml.adoc[`solr.xml`] to the name of a class (on the classpath) implementing the {solr-javadocs}/solrj-zookeeper/org/apache/solr/common/cloud/ZkACLProvider.html[`ZkACLProvider`] interface.
`solr.xml` defines the `zkACLProvider` such that it will take on the value of the same-named `zkACLProvider` system property if it is defined (in `solr.in.sh/.cmd` - see <<ZooKeeper ACLs in Solr Scripts,below>>), or if not, default to the `DefaultZkACLProvider` implementation.
diff --git a/solr/solr-ref-guide/modules/upgrade-notes/pages/solr-upgrade-notes.adoc b/solr/solr-ref-guide/modules/upgrade-notes/pages/solr-upgrade-notes.adoc
index 1a562844628..8fc722e5eec 100644
--- a/solr/solr-ref-guide/modules/upgrade-notes/pages/solr-upgrade-notes.adoc
+++ b/solr/solr-ref-guide/modules/upgrade-notes/pages/solr-upgrade-notes.adoc
@@ -34,6 +34,12 @@ that may affect your existing implementation.
Detailed steps for upgrading a Solr cluster are in the section xref:deployment-guide:upgrading-a-solr-cluster.adoc[].
+== Upgrading to 9.1
+
+SolrJ is beginning to be split up. If you use ZooKeeper coordinates to create a `CloudSolrClient`, you will need to add a dependency on `solrj-zookeeper`.
+Instead, consider migrating to use of specifying a list of Solr URLs in the client's builder.
+Not only does this reduce dependencies, but it improves security by being able to limit ZooKeeper access.
+
== Upgrading to 9.0 from 8.x Releases
The upgrade from 8.x to Solr 9.0 introduces several *major* changes that you should be aware of before upgrading.
diff --git a/solr/solrj-zookeeper/build.gradle b/solr/solrj-zookeeper/build.gradle
new file mode 100644
index 00000000000..21d23a809cc
--- /dev/null
+++ b/solr/solrj-zookeeper/build.gradle
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+apply plugin: 'java-library'
+
+description = 'Solrj-ZooKeeper - SolrJ requiring ZooKeeper'
+
+dependencies {
+ // Spotbugs Annotations are only needed for old findbugs
+ // annotation usage like in Zookeeper during compilation time.
+ // It is not included in the release so exclude from checks.
+ compileOnly 'com.github.spotbugs:spotbugs-annotations'
+ permitUnusedDeclared 'com.github.spotbugs:spotbugs-annotations'
+ // Exclude these from jar validation and license checks.
+ configurations.jarValidation {
+ exclude group: "com.github.spotbugs", module: "spotbugs-annotations"
+ }
+
+ implementation project(':solr:solrj')
+
+ // declare dependencies we use even though already declared by solrj-core
+ implementation 'org.slf4j:slf4j-api'
+ implementation 'org.apache.httpcomponents:httpclient'
+ implementation 'org.apache.httpcomponents:httpcore'
+
+ implementation('org.apache.zookeeper:zookeeper', {
+ exclude group: "org.apache.yetus", module: "audience-annotations"
+ exclude group: "log4j", module: "log4j"
+ exclude group: "org.slf4j", module: "slf4j-log4j12"
+ })
+ implementation ('org.apache.zookeeper:zookeeper-jute') {
+ exclude group: 'org.apache.yetus', module: 'audience-annotations'
+ }
+
+ testImplementation project(':solr:test-framework')
+ testImplementation project(':solr:core')
+
+ testImplementation 'junit:junit'
+ testImplementation 'commons-io:commons-io'
+ testImplementation 'com.google.guava:guava'
+
+ permitTestUsedUndeclared project(':solr:solrj-zookeeper') // duh!
+}
\ No newline at end of file
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/cloud/AlreadyExistsException.java b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/cloud/AlreadyExistsException.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/client/solrj/cloud/AlreadyExistsException.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/cloud/AlreadyExistsException.java
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/cloud/BadVersionException.java b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/cloud/BadVersionException.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/client/solrj/cloud/BadVersionException.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/cloud/BadVersionException.java
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/cloud/DelegatingCloudManager.java b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/cloud/DelegatingCloudManager.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/client/solrj/cloud/DelegatingCloudManager.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/cloud/DelegatingCloudManager.java
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/cloud/DistribStateManager.java b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/cloud/DistribStateManager.java
similarity index 97%
rename from solr/solrj/src/java/org/apache/solr/client/solrj/cloud/DistribStateManager.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/cloud/DistribStateManager.java
index 25543892fcd..e664e38355a 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/cloud/DistribStateManager.java
+++ b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/cloud/DistribStateManager.java
@@ -22,6 +22,7 @@ import java.util.Collections;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
import java.util.NoSuchElementException;
import org.apache.solr.common.SolrCloseable;
import org.apache.solr.common.cloud.PerReplicaStates;
@@ -52,6 +53,9 @@ public interface DistribStateManager extends SolrCloseable {
return getData(path, null);
}
+ Map<String, Object> getJson(String path)
+ throws InterruptedException, IOException, KeeperException;
+
// state mutators
void makePath(String path)
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/cloud/DistributedQueue.java b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/cloud/DistributedQueue.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/client/solrj/cloud/DistributedQueue.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/cloud/DistributedQueue.java
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/cloud/DistributedQueueFactory.java b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/cloud/DistributedQueueFactory.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/client/solrj/cloud/DistributedQueueFactory.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/cloud/DistributedQueueFactory.java
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/cloud/NodeStateProvider.java b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/cloud/NodeStateProvider.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/client/solrj/cloud/NodeStateProvider.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/cloud/NodeStateProvider.java
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/cloud/NotEmptyException.java b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/cloud/NotEmptyException.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/client/solrj/cloud/NotEmptyException.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/cloud/NotEmptyException.java
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/cloud/SolrCloudManager.java b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/cloud/SolrCloudManager.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/client/solrj/cloud/SolrCloudManager.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/cloud/SolrCloudManager.java
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/cloud/VersionedData.java b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/cloud/VersionedData.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/client/solrj/cloud/VersionedData.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/cloud/VersionedData.java
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/SolrClientCloudManager.java b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/SolrClientCloudManager.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/client/solrj/impl/SolrClientCloudManager.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/SolrClientCloudManager.java
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/SolrClientNodeStateProvider.java b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/SolrClientNodeStateProvider.java
similarity index 97%
rename from solr/solrj/src/java/org/apache/solr/client/solrj/impl/SolrClientNodeStateProvider.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/SolrClientNodeStateProvider.java
index 4c26154742c..4d59091db54 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/SolrClientNodeStateProvider.java
+++ b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/SolrClientNodeStateProvider.java
@@ -345,9 +345,21 @@ public class SolrClientNodeStateProvider implements NodeStateProvider, MapWriter
}
@Override
+ @SuppressWarnings({"unchecked"})
public Map<?, ?> getZkJson(String path) throws KeeperException, InterruptedException {
- return Utils.getJson(
- zkClientClusterStateProvider.getZkStateReader().getZkClient(), path, true);
+ try {
+ byte[] bytes =
+ zkClientClusterStateProvider
+ .getZkStateReader()
+ .getZkClient()
+ .getData(path, null, null, true);
+ if (bytes != null && bytes.length > 0) {
+ return (Map<String, Object>) Utils.fromJSON(bytes);
+ }
+ } catch (KeeperException.NoNodeException e) {
+ return emptyMap();
+ }
+ return emptyMap();
}
/**
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ZkClientClusterStateProvider.java b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/ZkClientClusterStateProvider.java
similarity index 79%
rename from solr/solrj/src/java/org/apache/solr/client/solrj/impl/ZkClientClusterStateProvider.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/ZkClientClusterStateProvider.java
index 184796e61b4..cfb0911a142 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ZkClientClusterStateProvider.java
+++ b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/ZkClientClusterStateProvider.java
@@ -27,9 +27,14 @@ import java.util.Set;
import org.apache.solr.common.AlreadyClosedException;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.cloud.ClusterState;
+import org.apache.solr.common.cloud.DocCollection;
+import org.apache.solr.common.cloud.SolrZkClient;
+import org.apache.solr.common.cloud.ZkNodeProps;
import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.common.cloud.ZooKeeperException;
+import org.apache.solr.common.util.Utils;
import org.apache.zookeeper.KeeperException;
+import org.noggit.JSONWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -67,6 +72,50 @@ public class ZkClientClusterStateProvider implements ClusterStateProvider {
this.zkHost = zkHost;
}
+ /**
+ * Create a ClusterState from Json. This method supports legacy configName location
+ *
+ * @param bytes a byte array of a Json representation of a mapping from collection name to the
+ * Json representation of a {@link DocCollection} as written by {@link
+ * ClusterState#write(JSONWriter)}. It can represent one or more collections.
+ * @param liveNodes list of live nodes
+ * @param coll collection name
+ * @param zkClient ZK client
+ * @return the ClusterState
+ */
+ @SuppressWarnings({"unchecked"})
+ @Deprecated
+ public static ClusterState createFromJsonSupportingLegacyConfigName(
+ int version, byte[] bytes, Set<String> liveNodes, String coll, SolrZkClient zkClient) {
+ if (bytes == null || bytes.length == 0) {
+ return new ClusterState(liveNodes, Collections.emptyMap());
+ }
+ Map<String, Object> stateMap = (Map<String, Object>) Utils.fromJSON(bytes);
+ Map<String, Object> props = (Map<String, Object>) stateMap.get(coll);
+ if (props != null) {
+ if (!props.containsKey(ZkStateReader.CONFIGNAME_PROP)) {
+ try {
+ // read configName from collections/collection node
+ String path = ZkStateReader.COLLECTIONS_ZKNODE + "/" + coll;
+ byte[] data = zkClient.getData(path, null, null, true);
+ if (data != null && data.length > 0) {
+ ZkNodeProps configProp = ZkNodeProps.load(data);
+ String configName = configProp.getStr(ZkStateReader.CONFIGNAME_PROP);
+ if (configName != null) {
+ props.put(ZkStateReader.CONFIGNAME_PROP, configName);
+ stateMap.put(coll, props);
+ } else {
+ log.warn("configName is null, not found on {}", path);
+ }
+ }
+ } catch (KeeperException | InterruptedException e) {
+ // do nothing
+ }
+ }
+ }
+ return ClusterState.createFromCollectionMap(version, stateMap, liveNodes);
+ }
+
@Override
public ClusterState.CollectionRef getState(String collection) {
ClusterState clusterState = getZkStateReader().getClusterState();
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ZkDistribStateManager.java b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/ZkDistribStateManager.java
similarity index 90%
rename from solr/solrj/src/java/org/apache/solr/client/solrj/impl/ZkDistribStateManager.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/ZkDistribStateManager.java
index e055ee5f6cb..4e050d22572 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ZkDistribStateManager.java
+++ b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/ZkDistribStateManager.java
@@ -18,7 +18,9 @@
package org.apache.solr.client.solrj.impl;
import java.io.IOException;
+import java.util.Collections;
import java.util.List;
+import java.util.Map;
import java.util.NoSuchElementException;
import org.apache.solr.client.solrj.cloud.AlreadyExistsException;
import org.apache.solr.client.solrj.cloud.BadVersionException;
@@ -27,7 +29,9 @@ import org.apache.solr.client.solrj.cloud.NotEmptyException;
import org.apache.solr.client.solrj.cloud.VersionedData;
import org.apache.solr.common.AlreadyClosedException;
import org.apache.solr.common.cloud.PerReplicaStates;
+import org.apache.solr.common.cloud.PerReplicaStatesFetcher;
import org.apache.solr.common.cloud.SolrZkClient;
+import org.apache.solr.common.util.Utils;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.Op;
@@ -44,6 +48,22 @@ public class ZkDistribStateManager implements DistribStateManager {
this.zkClient = zkClient;
}
+ @SuppressWarnings({"unchecked"})
+ @Override
+ public Map<String, Object> getJson(String path)
+ throws InterruptedException, IOException, KeeperException {
+ VersionedData data;
+ try {
+ data = getData(path);
+ } catch (KeeperException.NoNodeException | NoSuchElementException e) {
+ return Collections.emptyMap();
+ }
+ if (data == null || data.getData() == null || data.getData().length == 0) {
+ return Collections.emptyMap();
+ }
+ return (Map<String, Object>) Utils.fromJSON(data.getData());
+ }
+
@Override
public boolean hasData(String path) throws IOException, KeeperException, InterruptedException {
try {
@@ -196,6 +216,6 @@ public class ZkDistribStateManager implements DistribStateManager {
@Override
public PerReplicaStates getReplicaStates(String path)
throws KeeperException, InterruptedException {
- return PerReplicaStates.fetch(path, zkClient, null);
+ return PerReplicaStatesFetcher.fetch(path, zkClient, null);
}
}
diff --git a/solr/solrj/src/java/org/apache/solr/common/LazySolrCluster.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/LazySolrCluster.java
similarity index 98%
rename from solr/solrj/src/java/org/apache/solr/common/LazySolrCluster.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/LazySolrCluster.java
index cd42888587f..295018a3372 100644
--- a/solr/solrj/src/java/org/apache/solr/common/LazySolrCluster.java
+++ b/solr/solrj-zookeeper/src/java/org/apache/solr/common/LazySolrCluster.java
@@ -18,7 +18,6 @@
package org.apache.solr.common;
import static org.apache.solr.common.cloud.ZkStateReader.URL_SCHEME;
-import static org.apache.solr.common.cloud.ZkStateReader.getCollectionPathRoot;
import java.util.HashMap;
import java.util.HashSet;
@@ -266,7 +265,7 @@ public class LazySolrCluster implements SolrCluster {
byte[] d =
zkStateReader
.getZkClient()
- .getData(getCollectionPathRoot(coll.getName()), null, null, true);
+ .getData(DocCollection.getCollectionPathRoot(coll.getName()), null, null, true);
if (d == null || d.length == 0) return null;
Map<?, ?> m = (Map<?, ?>) Utils.fromJSON(d);
confName = (String) m.get("configName");
diff --git a/solr/solrj/src/java/org/apache/solr/common/SimpleZkMap.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/SimpleZkMap.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/common/SimpleZkMap.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/SimpleZkMap.java
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/BeforeReconnect.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/BeforeReconnect.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/BeforeReconnect.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/BeforeReconnect.java
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/CloudCollectionsListener.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/CloudCollectionsListener.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/CloudCollectionsListener.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/CloudCollectionsListener.java
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterProperties.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ClusterProperties.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/ClusterProperties.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ClusterProperties.java
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterPropertiesListener.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ClusterPropertiesListener.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/ClusterPropertiesListener.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ClusterPropertiesListener.java
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/CollectionProperties.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/CollectionProperties.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/CollectionProperties.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/CollectionProperties.java
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/CollectionPropsWatcher.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/CollectionPropsWatcher.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/CollectionPropsWatcher.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/CollectionPropsWatcher.java
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/CollectionStateWatcher.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/CollectionStateWatcher.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/CollectionStateWatcher.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/CollectionStateWatcher.java
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/ConnectionManager.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ConnectionManager.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/ConnectionManager.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ConnectionManager.java
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/DefaultConnectionStrategy.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/DefaultConnectionStrategy.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/DefaultConnectionStrategy.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/DefaultConnectionStrategy.java
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/DefaultZkACLProvider.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/DefaultZkACLProvider.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/DefaultZkACLProvider.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/DefaultZkACLProvider.java
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/DefaultZkCredentialsProvider.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/DefaultZkCredentialsProvider.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/DefaultZkCredentialsProvider.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/DefaultZkCredentialsProvider.java
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/DocCollectionWatcher.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/DocCollectionWatcher.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/DocCollectionWatcher.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/DocCollectionWatcher.java
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/LiveNodesListener.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/LiveNodesListener.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/LiveNodesListener.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/LiveNodesListener.java
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/LiveNodesPredicate.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/LiveNodesPredicate.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/LiveNodesPredicate.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/LiveNodesPredicate.java
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/NodesSysPropsCacher.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/NodesSysPropsCacher.java
similarity index 97%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/NodesSysPropsCacher.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/NodesSysPropsCacher.java
index 6224eefb74b..df9a7c5dbde 100644
--- a/solr/solrj/src/java/org/apache/solr/common/cloud/NodesSysPropsCacher.java
+++ b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/NodesSysPropsCacher.java
@@ -31,7 +31,7 @@ import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.params.ModifiableSolrParams;
/** Fetch lazily and cache a node's system properties */
-public class NodesSysPropsCacher implements AutoCloseable {
+public class NodesSysPropsCacher implements NodesSysProps, AutoCloseable {
private volatile boolean isClosed = false;
private final Map<String, Map<String, Object>> nodeVsTagsCache = new ConcurrentHashMap<>();
private ZkStateReader zkStateReader;
@@ -52,6 +52,7 @@ public class NodesSysPropsCacher implements AutoCloseable {
});
}
+ @Override
public Map<String, Object> getSysProps(String nodeName, Collection<String> tags) {
Map<String, Object> cached =
nodeVsTagsCache.computeIfAbsent(nodeName, s -> new LinkedHashMap<>());
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/OnReconnect.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/OnReconnect.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/OnReconnect.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/OnReconnect.java
diff --git a/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/PerReplicaStatesFetcher.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/PerReplicaStatesFetcher.java
new file mode 100644
index 00000000000..c9bf7d7f087
--- /dev/null
+++ b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/PerReplicaStatesFetcher.java
@@ -0,0 +1,53 @@
+/*
+ * 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.solr.common.cloud;
+
+import java.util.Collections;
+import java.util.List;
+import org.apache.solr.common.SolrException;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.data.Stat;
+
+public class PerReplicaStatesFetcher {
+ /**
+ * Fetch the latest {@link PerReplicaStates} . It fetches data after checking the {@link
+ * Stat#getCversion()} of state.json. If this is not modified, the same object is returned
+ */
+ public static PerReplicaStates fetch(
+ String path, SolrZkClient zkClient, PerReplicaStates current) {
+ try {
+ if (current != null) {
+ Stat stat = zkClient.exists(current.path, null, true);
+ if (stat == null) return new PerReplicaStates(path, -1, Collections.emptyList());
+ if (current.cversion == stat.getCversion()) return current; // not modifiedZkStateReaderTest
+ }
+ Stat stat = new Stat();
+ List<String> children = zkClient.getChildren(path, null, stat, true);
+ return new PerReplicaStates(path, stat.getCversion(), Collections.unmodifiableList(children));
+ } catch (KeeperException e) {
+ throw new SolrException(
+ SolrException.ErrorCode.SERVER_ERROR, "Error fetching per-replica states", e);
+ } catch (InterruptedException e) {
+ SolrZkClient.checkInterrupted(e);
+ throw new SolrException(
+ SolrException.ErrorCode.SERVER_ERROR,
+ "Thread interrupted when loading per-replica states from " + path,
+ e);
+ }
+ }
+}
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/PerReplicaStatesOps.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/PerReplicaStatesOps.java
similarity index 99%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/PerReplicaStatesOps.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/PerReplicaStatesOps.java
index 708199561cb..7c5688230d4 100644
--- a/solr/solrj/src/java/org/apache/solr/common/cloud/PerReplicaStatesOps.java
+++ b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/PerReplicaStatesOps.java
@@ -97,7 +97,7 @@ public class PerReplicaStatesOps {
if (log.isInfoEnabled()) {
log.info("Stale state for {}, attempt: {}. retrying...", znode, i);
}
- operations = refresh(PerReplicaStates.fetch(znode, zkClient, null));
+ operations = refresh(PerReplicaStatesFetcher.fetch(znode, zkClient, null));
}
}
}
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/SaslZkACLProvider.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/SaslZkACLProvider.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/SaslZkACLProvider.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/SaslZkACLProvider.java
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/SecurityAwareZkACLProvider.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/SecurityAwareZkACLProvider.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/SecurityAwareZkACLProvider.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/SecurityAwareZkACLProvider.java
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/SolrZkClient.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/SolrZkClient.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/SolrZkClient.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/SolrZkClient.java
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/VMParamsAllAndReadonlyDigestZkACLProvider.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/VMParamsAllAndReadonlyDigestZkACLProvider.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/VMParamsAllAndReadonlyDigestZkACLProvider.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/VMParamsAllAndReadonlyDigestZkACLProvider.java
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/VMParamsSingleSetCredentialsDigestZkCredentialsProvider.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/VMParamsSingleSetCredentialsDigestZkCredentialsProvider.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/VMParamsSingleSetCredentialsDigestZkCredentialsProvider.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/VMParamsSingleSetCredentialsDigestZkCredentialsProvider.java
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/ZkACLProvider.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkACLProvider.java
similarity index 100%
copy from solr/solrj/src/java/org/apache/solr/common/cloud/ZkACLProvider.java
copy to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkACLProvider.java
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/ZkClientConnectionStrategy.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkClientConnectionStrategy.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/ZkClientConnectionStrategy.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkClientConnectionStrategy.java
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/ZkCmdExecutor.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkCmdExecutor.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/ZkCmdExecutor.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkCmdExecutor.java
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/ZkCredentialsProvider.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkCredentialsProvider.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/ZkCredentialsProvider.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkCredentialsProvider.java
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/ZkDynamicConfig.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkDynamicConfig.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/ZkDynamicConfig.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkDynamicConfig.java
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/ZkMaintenanceUtils.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkMaintenanceUtils.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/ZkMaintenanceUtils.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkMaintenanceUtils.java
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/ZkOperation.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkOperation.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/ZkOperation.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkOperation.java
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkStateReader.java
similarity index 99%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkStateReader.java
index 353500581c2..2d0165ae96b 100644
--- a/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java
+++ b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkStateReader.java
@@ -232,7 +232,7 @@ public class ZkStateReader implements SolrCloseable {
var provider = (ZkClientClusterStateProvider) solrClient.getClusterStateProvider();
return provider.getZkStateReader();
} catch (ClassCastException e) {
- throw new IllegalArgumentException("client has no Zk stateReader", e);
+ throw new IllegalArgumentException("client must be ZK based", e);
}
}
@@ -814,7 +814,7 @@ public class ZkStateReader implements SolrCloseable {
if (cachedDocCollection != null) {
Stat freshStats = null;
try {
- freshStats = zkClient.exists(getCollectionPath(collName), null, true);
+ freshStats = zkClient.exists(DocCollection.getCollectionPath(collName), null, true);
} catch (Exception e) {
}
if (freshStats != null
@@ -1256,7 +1256,7 @@ public class ZkStateReader implements SolrCloseable {
* @param cacheForMillis The minimum number of milliseconds to maintain a cache for the specified
* collection's properties. Setting a {@code CollectionPropsWatcher} will override this value
* and retain the cache for the life of the watcher. A lack of changes in zookeeper may allow
- * the caching to remain for a greater duration up to the cycle time of {@link CacheCleaner}.
+ * the caching to remain for a greater duration up to the cycle time of {@code CacheCleaner}.
* Passing zero for this value will explicitly remove the cached copy if and only if it is due
* to expire and no watch exists. Any positive value will extend the expiration time if
* required.
@@ -1404,7 +1404,7 @@ public class ZkStateReader implements SolrCloseable {
StateWatcher(String coll) {
this.coll = coll;
- collectionPath = getCollectionPath(coll);
+ collectionPath = DocCollection.getCollectionPath(coll);
}
@Override
@@ -1682,13 +1682,13 @@ public class ZkStateReader implements SolrCloseable {
private DocCollection fetchCollectionState(String coll, Watcher watcher)
throws KeeperException, InterruptedException {
- String collectionPath = getCollectionPath(coll);
+ String collectionPath = DocCollection.getCollectionPath(coll);
while (true) {
ClusterState.initReplicaStateProvider(
() -> {
try {
PerReplicaStates replicaStates =
- PerReplicaStates.fetch(collectionPath, zkClient, null);
+ PerReplicaStatesFetcher.fetch(collectionPath, zkClient, null);
log.debug(
"per-replica-state ver: {} fetched for initializing {} ",
replicaStates.cversion,
@@ -1707,7 +1707,7 @@ public class ZkStateReader implements SolrCloseable {
// old ZK location.
// TODO in Solr 10 remove that factory method
ClusterState state =
- ClusterState.createFromJsonSupportingLegacyConfigName(
+ ZkClientClusterStateProvider.createFromJsonSupportingLegacyConfigName(
stat.getVersion(), data, Collections.emptySet(), coll, zkClient);
ClusterState.CollectionRef collectionRef = state.getCollectionStates().get(coll);
@@ -1729,12 +1729,14 @@ public class ZkStateReader implements SolrCloseable {
}
}
+ @Deprecated // see DocCollection
public static String getCollectionPathRoot(String coll) {
- return COLLECTIONS_ZKNODE + "/" + coll;
+ return DocCollection.getCollectionPathRoot(coll);
}
+ @Deprecated // see DocCollection
public static String getCollectionPath(String coll) {
- return getCollectionPathRoot(coll) + "/state.json";
+ return DocCollection.getCollectionPath(coll);
}
/**
@@ -1861,7 +1863,7 @@ public class ZkStateReader implements SolrCloseable {
private DocCollection updatePerReplicaState(DocCollection c) {
if (c == null || !c.isPerReplicaState()) return c;
PerReplicaStates current = c.getPerReplicaStates();
- PerReplicaStates newPrs = PerReplicaStates.fetch(c.getZNode(), zkClient, current);
+ PerReplicaStates newPrs = PerReplicaStatesFetcher.fetch(c.getZNode(), zkClient, current);
if (newPrs != current) {
if (log.isDebugEnabled()) {
log.debug("update for a fresh per-replica-state {}", c.getName());
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/ZooKeeperException.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZooKeeperException.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/ZooKeeperException.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZooKeeperException.java
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/rule/ImplicitSnitch.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/rule/ImplicitSnitch.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/rule/ImplicitSnitch.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/rule/ImplicitSnitch.java
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/rule/RemoteCallback.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/rule/RemoteCallback.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/rule/RemoteCallback.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/rule/RemoteCallback.java
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/rule/Snitch.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/rule/Snitch.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/rule/Snitch.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/rule/Snitch.java
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/rule/SnitchContext.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/rule/SnitchContext.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/rule/SnitchContext.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/rule/SnitchContext.java
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/rule/package-info.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/rule/package-info.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/rule/package-info.java
rename to solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/rule/package-info.java
diff --git a/solr/solrj/src/test/org/apache/solr/common/cloud/SolrZkClientTest.java b/solr/solrj-zookeeper/src/test/org/apache/solr/common/cloud/SolrZkClientTest.java
similarity index 100%
rename from solr/solrj/src/test/org/apache/solr/common/cloud/SolrZkClientTest.java
rename to solr/solrj-zookeeper/src/test/org/apache/solr/common/cloud/SolrZkClientTest.java
diff --git a/solr/solrj/src/test/org/apache/solr/common/cloud/TestPerReplicaStates.java b/solr/solrj-zookeeper/src/test/org/apache/solr/common/cloud/TestPerReplicaStates.java
similarity index 91%
rename from solr/solrj/src/test/org/apache/solr/common/cloud/TestPerReplicaStates.java
rename to solr/solrj-zookeeper/src/test/org/apache/solr/common/cloud/TestPerReplicaStates.java
index 387714ff03c..99edf56cd69 100644
--- a/solr/solrj/src/test/org/apache/solr/common/cloud/TestPerReplicaStates.java
+++ b/solr/solrj-zookeeper/src/test/org/apache/solr/common/cloud/TestPerReplicaStates.java
@@ -95,7 +95,7 @@ public class TestPerReplicaStates extends SolrCloudTestCase {
}
ZkStateReader zkStateReader = cluster.getZkStateReader();
- PerReplicaStates rs = PerReplicaStates.fetch(root, zkStateReader.getZkClient(), null);
+ PerReplicaStates rs = PerReplicaStatesFetcher.fetch(root, zkStateReader.getZkClient(), null);
assertEquals(3, rs.states.size());
assertTrue(rs.cversion >= 5);
@@ -103,7 +103,7 @@ public class TestPerReplicaStates extends SolrCloudTestCase {
assertEquals(1, ops.get().size());
assertEquals(PerReplicaStates.Operation.Type.ADD, ops.ops.get(0).typ);
ops.persist(root, cluster.getZkClient());
- rs = PerReplicaStates.fetch(root, zkStateReader.getZkClient(), null);
+ rs = PerReplicaStatesFetcher.fetch(root, zkStateReader.getZkClient(), null);
assertEquals(4, rs.states.size());
assertTrue(rs.cversion >= 6);
assertEquals(6, cluster.getZkClient().getChildren(root, null, true).size());
@@ -115,7 +115,7 @@ public class TestPerReplicaStates extends SolrCloudTestCase {
assertEquals(PerReplicaStates.Operation.Type.DELETE, ops.ops.get(2).typ);
assertEquals(PerReplicaStates.Operation.Type.DELETE, ops.ops.get(3).typ);
ops.persist(root, cluster.getZkClient());
- rs = PerReplicaStates.fetch(root, zkStateReader.getZkClient(), null);
+ rs = PerReplicaStatesFetcher.fetch(root, zkStateReader.getZkClient(), null);
assertEquals(4, rs.states.size());
assertEquals(3, rs.states.get("R1").version);
@@ -123,7 +123,7 @@ public class TestPerReplicaStates extends SolrCloudTestCase {
assertEquals(1, ops.ops.size());
ops.persist(root, cluster.getZkClient());
- rs = PerReplicaStates.fetch(root, zkStateReader.getZkClient(), null);
+ rs = PerReplicaStatesFetcher.fetch(root, zkStateReader.getZkClient(), null);
assertEquals(3, rs.states.size());
ops = PerReplicaStatesOps.flipLeader(Set.of("R4", "R3", "R1"), "R4", rs);
@@ -131,11 +131,11 @@ public class TestPerReplicaStates extends SolrCloudTestCase {
assertEquals(PerReplicaStates.Operation.Type.ADD, ops.ops.get(0).typ);
assertEquals(PerReplicaStates.Operation.Type.DELETE, ops.ops.get(1).typ);
ops.persist(root, cluster.getZkClient());
- rs = PerReplicaStates.fetch(root, zkStateReader.getZkClient(), null);
+ rs = PerReplicaStatesFetcher.fetch(root, zkStateReader.getZkClient(), null);
ops = PerReplicaStatesOps.flipLeader(Set.of("R4", "R3", "R1"), "R3", rs);
assertEquals(4, ops.ops.size());
ops.persist(root, cluster.getZkClient());
- rs = PerReplicaStates.fetch(root, zkStateReader.getZkClient(), null);
+ rs = PerReplicaStatesFetcher.fetch(root, zkStateReader.getZkClient(), null);
assertTrue(rs.get("R3").isLeader);
}
}
diff --git a/solr/solrj/src/test/org/apache/solr/common/cloud/TestZkConfigSetService.java b/solr/solrj-zookeeper/src/test/org/apache/solr/common/cloud/TestZkConfigSetService.java
similarity index 100%
rename from solr/solrj/src/test/org/apache/solr/common/cloud/TestZkConfigSetService.java
rename to solr/solrj-zookeeper/src/test/org/apache/solr/common/cloud/TestZkConfigSetService.java
diff --git a/solr/solrj/src/test/org/apache/solr/common/cloud/TestZkMaintenanceUtils.java b/solr/solrj-zookeeper/src/test/org/apache/solr/common/cloud/TestZkMaintenanceUtils.java
similarity index 100%
rename from solr/solrj/src/test/org/apache/solr/common/cloud/TestZkMaintenanceUtils.java
rename to solr/solrj-zookeeper/src/test/org/apache/solr/common/cloud/TestZkMaintenanceUtils.java
diff --git a/solr/solrj/build.gradle b/solr/solrj/build.gradle
index 1621fa6b78c..36d4035c84f 100644
--- a/solr/solrj/build.gradle
+++ b/solr/solrj/build.gradle
@@ -21,15 +21,6 @@ apply plugin: 'java-library'
description = 'Solrj - Solr Java Client'
dependencies {
- // Spotbugs Annotations are only needed for old findbugs
- // annotation usage like in Zookeeper during compilation time.
- // It is not included in the release so exclude from checks.
- compileOnly 'com.github.spotbugs:spotbugs-annotations'
- permitUnusedDeclared 'com.github.spotbugs:spotbugs-annotations'
- // Exclude these from jar validation and license checks.
- configurations.jarValidation {
- exclude group: "com.github.spotbugs", module: "spotbugs-annotations"
- }
implementation 'org.slf4j:slf4j-api'
runtimeOnly 'org.slf4j:jcl-over-slf4j'
@@ -50,20 +41,16 @@ dependencies {
implementation 'org.apache.httpcomponents:httpclient'
implementation 'org.apache.httpcomponents:httpcore'
- implementation('org.apache.zookeeper:zookeeper', {
- exclude group: "org.apache.yetus", module: "audience-annotations"
- exclude group: "log4j", module: "log4j"
- exclude group: "org.slf4j", module: "slf4j-log4j12"
- })
- implementation ('org.apache.zookeeper:zookeeper-jute') {
- exclude group: 'org.apache.yetus', module: 'audience-annotations'
- }
-
testImplementation project(':solr:test-framework')
testImplementation project(':solr:core')
testImplementation project(':solr:solrj')
testRuntimeOnly project(':solr:modules:sql')
+ // ideally ZK centric tests move to solrj-zookeeper but sometimes we depend on ZK here anyway
+ testImplementation project(':solr:solrj-zookeeper')
+ testImplementation 'org.apache.zookeeper:zookeeper'
+ permitTestUnusedDeclared 'org.apache.zookeeper:zookeeper'
+
testImplementation 'org.apache.lucene:lucene-analysis-common'
testImplementation 'org.apache.lucene:lucene-core'
testImplementation 'org.apache.lucene:lucene-test-framework'
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/BaseHttpClusterStateProvider.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/BaseHttpClusterStateProvider.java
index be08057d271..875f21a8ade 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/BaseHttpClusterStateProvider.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/BaseHttpClusterStateProvider.java
@@ -35,7 +35,6 @@ import org.apache.solr.client.solrj.request.QueryRequest;
import org.apache.solr.client.solrj.response.CollectionAdminResponse;
import org.apache.solr.common.cloud.Aliases;
import org.apache.solr.common.cloud.ClusterState;
-import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap;
@@ -339,7 +338,7 @@ public abstract class BaseHttpClusterStateProvider implements ClusterStateProvid
@Override
public Object getClusterProperty(String propertyName) {
- if (propertyName.equals(ZkStateReader.URL_SCHEME)) {
+ if (propertyName.equals(ClusterState.URL_SCHEME)) {
return this.urlScheme;
}
return getClusterProperties().get(propertyName);
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudHttp2SolrClient.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudHttp2SolrClient.java
index acc9f76615e..376dc29d96e 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudHttp2SolrClient.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudHttp2SolrClient.java
@@ -68,7 +68,8 @@ public class CloudHttp2SolrClient extends CloudSolrClient {
"Both zkHost(s) & solrUrl(s) have been specified. Only specify one.");
}
if (builder.zkHosts != null) {
- this.stateProvider = new ZkClientClusterStateProvider(builder.zkHosts, builder.zkChroot);
+ this.stateProvider =
+ ClusterStateProvider.newZkClusterStateProvider(builder.zkHosts, builder.zkChroot);
} else if (builder.solrUrls != null && !builder.solrUrls.isEmpty()) {
try {
this.stateProvider = new Http2ClusterStateProvider(builder.solrUrls, builder.httpClient);
@@ -250,7 +251,8 @@ public class CloudHttp2SolrClient extends CloudSolrClient {
public CloudHttp2SolrClient build() {
if (stateProvider == null) {
if (!zkHosts.isEmpty()) {
- stateProvider = new ZkClientClusterStateProvider(zkHosts, zkChroot);
+ stateProvider =
+ ClusterStateProvider.newZkClusterStateProvider(zkHosts, Builder.this.zkChroot);
} else if (!this.solrUrls.isEmpty()) {
try {
stateProvider = new Http2ClusterStateProvider(solrUrls, httpClient);
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudLegacySolrClient.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudLegacySolrClient.java
index 8d237f12ecc..9a65997729a 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudLegacySolrClient.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudLegacySolrClient.java
@@ -66,7 +66,8 @@ public class CloudLegacySolrClient extends CloudSolrClient {
"Both zkHost(s) & solrUrl(s) have been specified. Only specify one.");
}
if (builder.zkHosts != null) {
- this.stateProvider = new ZkClientClusterStateProvider(builder.zkHosts, builder.zkChroot);
+ this.stateProvider =
+ ClusterStateProvider.newZkClusterStateProvider(builder.zkHosts, builder.zkChroot);
} else if (builder.solrUrls != null && !builder.solrUrls.isEmpty()) {
try {
this.stateProvider = new HttpClusterStateProvider(builder.solrUrls, builder.httpClient);
@@ -324,7 +325,7 @@ public class CloudLegacySolrClient extends CloudSolrClient {
public CloudLegacySolrClient build() {
if (stateProvider == null) {
if (!zkHosts.isEmpty()) {
- stateProvider = new ZkClientClusterStateProvider(zkHosts, zkChroot);
+ this.stateProvider = ClusterStateProvider.newZkClusterStateProvider(zkHosts, zkChroot);
} else if (!this.solrUrls.isEmpty()) {
try {
stateProvider = new HttpClusterStateProvider(solrUrls, httpClient);
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java
index 7794818e89c..23901407774 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java
@@ -46,7 +46,6 @@ import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
-import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import org.apache.solr.client.solrj.ResponseParser;
@@ -66,16 +65,12 @@ import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.ToleratedUpdateError;
import org.apache.solr.common.cloud.ClusterState;
-import org.apache.solr.common.cloud.CollectionStatePredicate;
-import org.apache.solr.common.cloud.CollectionStateWatcher;
import org.apache.solr.common.cloud.DocCollection;
-import org.apache.solr.common.cloud.DocCollectionWatcher;
import org.apache.solr.common.cloud.DocRouter;
import org.apache.solr.common.cloud.ImplicitDocRouter;
import org.apache.solr.common.cloud.Replica;
import org.apache.solr.common.cloud.Slice;
import org.apache.solr.common.cloud.ZkCoreNodeProps;
-import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.params.ShardParams;
import org.apache.solr.common.params.SolrParams;
@@ -159,7 +154,10 @@ public abstract class CloudSolrClient extends SolrClient {
/**
* Provide a series of ZK hosts which will be used when configuring {@link CloudSolrClient}
- * instances.
+ * instances. This requires a dependency on {@code solr-solrj-zookeeper} which transitively
+ * depends on more JARs. The ZooKeeper based connection is the most reliable and performant
+ * means for CloudSolrClient to work. On the other hand, it means exposing ZooKeeper more
+ * broadly than to Solr nodes, which is a security risk.
*
* <p>Usage example when Solr stores data at the ZooKeeper root ('/'):
*
@@ -388,94 +386,6 @@ public abstract class CloudSolrClient extends SolrClient {
throw new TimeoutException("Timed out waiting for cluster");
}
- private ZkClientClusterStateProvider assertZKStateProvider() {
- if (getClusterStateProvider() instanceof ZkClientClusterStateProvider) {
- return (ZkClientClusterStateProvider) getClusterStateProvider();
- }
- throw new IllegalArgumentException("This client does not use ZK");
- }
-
- /**
- * Block until a CollectionStatePredicate returns true, or the wait times out
- *
- * <p>Note that the predicate may be called again even after it has returned true, so implementors
- * should avoid changing state within the predicate call itself.
- *
- * <p>This implementation utilizes {@link CollectionStateWatcher} internally. Callers that don't
- * care about liveNodes are encouraged to use a {@link DocCollection} {@link Predicate} instead
- *
- * @see #waitForState(String, long, TimeUnit, Predicate)
- * @see #registerCollectionStateWatcher
- * @param collection the collection to watch
- * @param wait how long to wait
- * @param unit the units of the wait parameter
- * @param predicate a {@link CollectionStatePredicate} to check the collection state
- * @throws InterruptedException on interrupt
- * @throws TimeoutException on timeout
- */
- public void waitForState(
- String collection, long wait, TimeUnit unit, CollectionStatePredicate predicate)
- throws InterruptedException, TimeoutException {
- getClusterStateProvider().connect();
- assertZKStateProvider().zkStateReader.waitForState(collection, wait, unit, predicate);
- }
- /**
- * Block until a Predicate returns true, or the wait times out
- *
- * <p>Note that the predicate may be called again even after it has returned true, so implementors
- * should avoid changing state within the predicate call itself.
- *
- * @see #registerDocCollectionWatcher
- * @param collection the collection to watch
- * @param wait how long to wait
- * @param unit the units of the wait parameter
- * @param predicate a {@link Predicate} to test against the {@link DocCollection}
- * @throws InterruptedException on interrupt
- * @throws TimeoutException on timeout
- */
- public void waitForState(
- String collection, long wait, TimeUnit unit, Predicate<DocCollection> predicate)
- throws InterruptedException, TimeoutException {
- getClusterStateProvider().connect();
- assertZKStateProvider().zkStateReader.waitForState(collection, wait, unit, predicate);
- }
-
- /**
- * Register a CollectionStateWatcher to be called when the cluster state for a collection changes
- * <em>or</em> the set of live nodes changes.
- *
- * <p>The Watcher will automatically be removed when it's <code>onStateChanged</code> returns
- * <code>true</code>
- *
- * <p>This implementation utilizes {@link ZkStateReader#registerCollectionStateWatcher}
- * internally. Callers that don't care about liveNodes are encouraged to use a {@link
- * DocCollectionWatcher} instead
- *
- * @see #registerDocCollectionWatcher(String, DocCollectionWatcher)
- * @see ZkStateReader#registerCollectionStateWatcher
- * @param collection the collection to watch
- * @param watcher a watcher that will be called when the state changes
- */
- public void registerCollectionStateWatcher(String collection, CollectionStateWatcher watcher) {
- getClusterStateProvider().connect();
- assertZKStateProvider().zkStateReader.registerCollectionStateWatcher(collection, watcher);
- }
-
- /**
- * Register a DocCollectionWatcher to be called when the cluster state for a collection changes.
- *
- * <p>The Watcher will automatically be removed when it's <code>onStateChanged</code> returns
- * <code>true</code>
- *
- * @see ZkStateReader#registerDocCollectionWatcher
- * @param collection the collection to watch
- * @param watcher a watcher that will be called when the state changes
- */
- public void registerDocCollectionWatcher(String collection, DocCollectionWatcher watcher) {
- getClusterStateProvider().connect();
- assertZKStateProvider().zkStateReader.registerDocCollectionWatcher(collection, watcher);
- }
-
@SuppressWarnings({"unchecked"})
private NamedList<Object> directUpdate(AbstractUpdateRequest request, String collection)
throws SolrServerException {
@@ -1156,7 +1066,7 @@ public abstract class CloudSolrClient extends SolrClient {
requestRLTGenerator.getReplicaListTransformer(reqParams);
final ClusterStateProvider provider = getClusterStateProvider();
- final String urlScheme = provider.getClusterProperty(ZkStateReader.URL_SCHEME, "http");
+ final String urlScheme = provider.getClusterProperty(ClusterState.URL_SCHEME, "http");
final Set<String> liveNodes = provider.getLiveNodes();
final List<String> theUrlList = new ArrayList<>(); // we populate this as follows...
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ClusterStateProvider.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ClusterStateProvider.java
index 7c7aa2f9899..9673f08e48d 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ClusterStateProvider.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ClusterStateProvider.java
@@ -17,6 +17,8 @@
package org.apache.solr.client.solrj.impl;
import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -28,6 +30,26 @@ import org.apache.solr.common.params.CollectionAdminParams;
/** Provides cluster state from some source */
public interface ClusterStateProvider extends SolrCloseable {
+ static ClusterStateProvider newZkClusterStateProvider(
+ Collection<String> zkHosts, String zkChroot) {
+ // instantiate via reflection so that we don't depend on ZK
+ try {
+ var constructor =
+ Class.forName("org.apache.solr.client.solrj.impl.ZkClientClusterStateProvider")
+ .asSubclass(ClusterStateProvider.class)
+ .getConstructor(Collection.class, String.class);
+ return constructor.newInstance(zkHosts, zkChroot);
+ } catch (InvocationTargetException e) {
+ if (e.getCause() instanceof RuntimeException) {
+ throw (RuntimeException) e.getCause();
+ } else {
+ throw new RuntimeException(e.getCause());
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e.toString(), e);
+ }
+ }
+
/**
* Obtain the state of the collection (cluster status).
*
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/sql/DatabaseMetaDataImpl.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/sql/DatabaseMetaDataImpl.java
index 5c1623285e3..d5b71d57219 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/sql/DatabaseMetaDataImpl.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/sql/DatabaseMetaDataImpl.java
@@ -30,8 +30,9 @@ import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.CloudSolrClient;
import org.apache.solr.client.solrj.impl.HttpSolrClient.Builder;
import org.apache.solr.client.solrj.response.QueryResponse;
-import org.apache.solr.common.cloud.ZkStateReader;
+import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.util.SimpleOrderedMap;
+import org.apache.solr.common.util.Utils;
class DatabaseMetaDataImpl implements DatabaseMetaData {
private final ConnectionImpl connection;
@@ -116,9 +117,13 @@ class DatabaseMetaDataImpl implements DatabaseMetaData {
CloudSolrClient cloudSolrClient = this.connection.getClient();
Set<String> liveNodes = cloudSolrClient.getClusterState().getLiveNodes();
SolrClient solrClient = null;
+ String urlScheme =
+ cloudSolrClient
+ .getClusterStateProvider()
+ .getClusterProperty(ClusterState.URL_SCHEME, "http");
for (String node : liveNodes) {
try {
- String nodeURL = ZkStateReader.from(cloudSolrClient).getBaseUrlForNodeName(node);
+ String nodeURL = Utils.getBaseUrlForNodeName(node, urlScheme);
solrClient = new Builder(nodeURL).build();
QueryResponse rsp = solrClient.query(sysQuery);
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/sql/StatementImpl.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/sql/StatementImpl.java
index 7d78830d5c2..c2a6259576a 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/sql/StatementImpl.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/sql/StatementImpl.java
@@ -32,7 +32,6 @@ import org.apache.solr.client.solrj.io.stream.SolrStream;
import org.apache.solr.common.cloud.Replica;
import org.apache.solr.common.cloud.Slice;
import org.apache.solr.common.cloud.ZkCoreNodeProps;
-import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.params.ModifiableSolrParams;
@@ -76,9 +75,9 @@ class StatementImpl implements Statement {
protected SolrStream constructStream(String sql) throws IOException {
try {
- ZkStateReader zkStateReader = ZkStateReader.from(this.connection.getClient());
Slice[] slices =
- CloudSolrStream.getSlices(this.connection.getCollection(), zkStateReader, true);
+ CloudSolrStream.getSlices(
+ this.connection.getCollection(), this.connection.getClient(), true);
List<Replica> shuffler = new ArrayList<>();
for (Slice slice : slices) {
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/CloudSolrStream.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/CloudSolrStream.java
index a29bb84298e..c2bcca77539 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/CloudSolrStream.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/CloudSolrStream.java
@@ -50,10 +50,8 @@ import org.apache.solr.client.solrj.io.stream.expr.StreamExpression;
import org.apache.solr.client.solrj.io.stream.expr.StreamExpressionNamedParameter;
import org.apache.solr.client.solrj.io.stream.expr.StreamExpressionValue;
import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
-import org.apache.solr.common.cloud.Aliases;
import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.cloud.Slice;
-import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.ExecutorUtil;
@@ -347,35 +345,31 @@ public class CloudSolrStream extends TupleStream implements Expressible {
}
public static Slice[] getSlices(
- String collectionName, ZkStateReader zkStateReader, boolean checkAlias) throws IOException {
- ClusterState clusterState = zkStateReader.getClusterState();
-
- // check for alias or collection
+ String collectionName, CloudSolrClient cloudSolrClient, boolean checkAlias)
+ throws IOException {
- List<String> allCollections = new ArrayList<>();
- String[] collectionNames = collectionName.split(",");
- Aliases aliases = checkAlias ? zkStateReader.getAliases() : null;
+ Stream<String> allCollections = Arrays.stream(collectionName.split(","));
- for (String col : collectionNames) {
- List<String> collections =
- (aliases != null)
- ? aliases.resolveAliases(col) // if not an alias, returns collectionName
- : Collections.singletonList(collectionName);
- allCollections.addAll(collections);
+ // check for alias or collection
+ if (checkAlias) {
+ // if not an alias, returns collectionName
+ allCollections =
+ allCollections.flatMap(
+ col -> cloudSolrClient.getClusterStateProvider().resolveAlias(col).stream());
}
// Lookup all actives slices for these collections
- List<Slice> slices =
- allCollections.stream()
+ ClusterState clusterState = cloudSolrClient.getClusterState();
+ Slice[] slices =
+ allCollections
.map(c -> clusterState.getCollectionOrNull(c, true))
.filter(Objects::nonNull)
.flatMap(docCol -> Arrays.stream(docCol.getActiveSlicesArr()))
- .collect(Collectors.toList());
- if (!slices.isEmpty()) {
- return slices.toArray(new Slice[0]);
+ .toArray(Slice[]::new);
+ if (slices.length == 0) {
+ throw new IOException("Slices not found for " + collectionName);
}
-
- throw new IOException("Slices not found for " + collectionName);
+ return slices;
}
protected void constructStreams() throws IOException {
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/DeepRandomStream.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/DeepRandomStream.java
index d8b32955e95..c17efa9a18a 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/DeepRandomStream.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/DeepRandomStream.java
@@ -22,7 +22,6 @@ import static org.apache.solr.common.params.CommonParams.SORT;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
@@ -47,10 +46,6 @@ import org.apache.solr.client.solrj.io.stream.expr.StreamExpression;
import org.apache.solr.client.solrj.io.stream.expr.StreamExpressionNamedParameter;
import org.apache.solr.client.solrj.io.stream.expr.StreamExpressionValue;
import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
-import org.apache.solr.common.cloud.ClusterState;
-import org.apache.solr.common.cloud.DocCollection;
-import org.apache.solr.common.cloud.Slice;
-import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.ExecutorUtil;
@@ -282,50 +277,6 @@ public class DeepRandomStream extends TupleStream implements Expressible {
return solrStreams;
}
- public static Slice[] getSlices(
- String collectionName, ZkStateReader zkStateReader, boolean checkAlias) throws IOException {
- ClusterState clusterState = zkStateReader.getClusterState();
-
- Map<String, DocCollection> collectionsMap = clusterState.getCollectionsMap();
-
- // TODO we should probably split collection by comma to query more than one
- // which is something already supported in other parts of Solr
-
- // check for alias or collection
-
- List<String> allCollections = new ArrayList<>();
- String[] collectionNames = collectionName.split(",");
- for (String col : collectionNames) {
- List<String> collections =
- checkAlias
- ? zkStateReader
- .getAliases()
- .resolveAliases(col) // if not an alias, returns collectionName
- : Collections.singletonList(collectionName);
- allCollections.addAll(collections);
- }
-
- // Lookup all actives slices for these collections
- List<Slice> slices =
- allCollections.stream()
- .map(collectionsMap::get)
- .filter(Objects::nonNull)
- .flatMap(docCol -> Arrays.stream(docCol.getActiveSlicesArr()))
- .collect(Collectors.toList());
- if (!slices.isEmpty()) {
- return slices.toArray(new Slice[slices.size()]);
- }
-
- // Check collection case insensitive
- for (Entry<String, DocCollection> entry : collectionsMap.entrySet()) {
- if (entry.getKey().equalsIgnoreCase(collectionName)) {
- return entry.getValue().getActiveSlicesArr();
- }
- }
-
- throw new IOException("Slices not found for " + collectionName);
- }
-
protected void constructStreams() throws IOException {
try {
ModifiableSolrParams mParams = new ModifiableSolrParams(params);
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/FeaturesSelectionStream.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/FeaturesSelectionStream.java
index 52df95f56aa..b9009075b62 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/FeaturesSelectionStream.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/FeaturesSelectionStream.java
@@ -51,11 +51,9 @@ import org.apache.solr.client.solrj.io.stream.expr.StreamExpressionValue;
import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
import org.apache.solr.client.solrj.request.QueryRequest;
import org.apache.solr.client.solrj.response.QueryResponse;
-import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.cloud.Replica;
import org.apache.solr.common.cloud.Slice;
import org.apache.solr.common.cloud.ZkCoreNodeProps;
-import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.util.ExecutorUtil;
import org.apache.solr.common.util.NamedList;
@@ -280,12 +278,8 @@ public class FeaturesSelectionStream extends TupleStream implements Expressible
private List<String> getShardUrls() throws IOException {
try {
- ZkStateReader zkStateReader = ZkStateReader.from(cloudSolrClient);
-
- Slice[] slices = CloudSolrStream.getSlices(this.collection, zkStateReader, false);
-
- ClusterState clusterState = zkStateReader.getClusterState();
- Set<String> liveNodes = clusterState.getLiveNodes();
+ Slice[] slices = CloudSolrStream.getSlices(this.collection, cloudSolrClient, false);
+ Set<String> liveNodes = cloudSolrClient.getClusterState().getLiveNodes();
List<String> baseUrls = new ArrayList<>();
for (Slice slice : slices) {
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/TextLogitStream.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/TextLogitStream.java
index b3c98da81b4..7e02fc76059 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/TextLogitStream.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/TextLogitStream.java
@@ -52,11 +52,9 @@ import org.apache.solr.client.solrj.io.stream.expr.StreamExpressionValue;
import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
import org.apache.solr.client.solrj.request.QueryRequest;
import org.apache.solr.client.solrj.response.QueryResponse;
-import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.cloud.Replica;
import org.apache.solr.common.cloud.Slice;
import org.apache.solr.common.cloud.ZkCoreNodeProps;
-import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.util.ExecutorUtil;
import org.apache.solr.common.util.NamedList;
@@ -383,12 +381,9 @@ public class TextLogitStream extends TupleStream implements Expressible {
protected List<String> getShardUrls() throws IOException {
try {
- ZkStateReader zkStateReader = ZkStateReader.from(cloudSolrClient);
+ Slice[] slices = CloudSolrStream.getSlices(this.collection, cloudSolrClient, false);
- Slice[] slices = CloudSolrStream.getSlices(this.collection, zkStateReader, false);
-
- ClusterState clusterState = zkStateReader.getClusterState();
- Set<String> liveNodes = clusterState.getLiveNodes();
+ Set<String> liveNodes = cloudSolrClient.getClusterState().getLiveNodes();
List<String> baseUrls = new ArrayList<>();
for (Slice slice : slices) {
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/TopicStream.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/TopicStream.java
index c7b270d024f..48b7ab6cf68 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/TopicStream.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/TopicStream.java
@@ -54,11 +54,9 @@ import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
import org.apache.solr.client.solrj.request.UpdateRequest;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrInputDocument;
-import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.cloud.Replica;
import org.apache.solr.common.cloud.Slice;
import org.apache.solr.common.cloud.ZkCoreNodeProps;
-import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.ExecutorUtil;
@@ -420,12 +418,8 @@ public class TopicStream extends CloudSolrStream implements Expressible {
private void getCheckpoints() throws IOException {
this.checkpoints = new HashMap<>();
- ZkStateReader zkStateReader = ZkStateReader.from(cloudSolrClient);
-
- Slice[] slices = CloudSolrStream.getSlices(this.collection, zkStateReader, false);
-
- ClusterState clusterState = zkStateReader.getClusterState();
- Set<String> liveNodes = clusterState.getLiveNodes();
+ Slice[] slices = CloudSolrStream.getSlices(this.collection, cloudSolrClient, false);
+ Set<String> liveNodes = cloudSolrClient.getClusterState().getLiveNodes();
for (Slice slice : slices) {
String sliceName = slice.getName();
@@ -501,11 +495,9 @@ public class TopicStream extends CloudSolrStream implements Expressible {
}
private void getPersistedCheckpoints() throws IOException {
- ZkStateReader zkStateReader = ZkStateReader.from(cloudSolrClient);
- Slice[] slices = CloudSolrStream.getSlices(checkpointCollection, zkStateReader, false);
+ Slice[] slices = CloudSolrStream.getSlices(checkpointCollection, cloudSolrClient, false);
- ClusterState clusterState = zkStateReader.getClusterState();
- Set<String> liveNodes = clusterState.getLiveNodes();
+ Set<String> liveNodes = cloudSolrClient.getClusterState().getLiveNodes();
OUTER:
for (Slice slice : slices) {
@@ -536,8 +528,7 @@ public class TopicStream extends CloudSolrStream implements Expressible {
protected void constructStreams() throws IOException {
try {
- ZkStateReader zkStateReader = ZkStateReader.from(cloudSolrClient);
- Slice[] slices = CloudSolrStream.getSlices(this.collection, zkStateReader, false);
+ Slice[] slices = CloudSolrStream.getSlices(this.collection, cloudSolrClient, false);
ModifiableSolrParams mParams = new ModifiableSolrParams(params);
mParams.set(DISTRIB, "false"); // We are the aggregator.
@@ -550,8 +541,7 @@ public class TopicStream extends CloudSolrStream implements Expressible {
Random random = new Random();
- ClusterState clusterState = zkStateReader.getClusterState();
- Set<String> liveNodes = clusterState.getLiveNodes();
+ Set<String> liveNodes = cloudSolrClient.getClusterState().getLiveNodes();
for (Slice slice : slices) {
ModifiableSolrParams localParams = new ModifiableSolrParams(mParams);
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/TupleStream.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/TupleStream.java
index b3fe795a004..1b0495589d6 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/TupleStream.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/TupleStream.java
@@ -41,7 +41,6 @@ import org.apache.solr.common.MapWriter;
import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.cloud.Replica;
import org.apache.solr.common.cloud.Slice;
-import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.params.SolrParams;
@@ -149,9 +148,8 @@ public abstract class TupleStream implements Closeable, Serializable, MapWriter
}
CloudSolrClient cloudSolrClient = solrClientCache.getCloudSolrClient(zkHost);
- ZkStateReader zkStateReader = ZkStateReader.from(cloudSolrClient);
- ClusterState clusterState = zkStateReader.getClusterState();
- Slice[] slices = CloudSolrStream.getSlices(collection, zkStateReader, true);
+ ClusterState clusterState = cloudSolrClient.getClusterStateProvider().getClusterState();
+ Slice[] slices = CloudSolrStream.getSlices(collection, cloudSolrClient, true);
Set<String> liveNodes = clusterState.getLiveNodes();
RequestReplicaListTransformerGenerator requestReplicaListTransformerGenerator;
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/request/CollectionAdminRequest.java b/solr/solrj/src/java/org/apache/solr/client/solrj/request/CollectionAdminRequest.java
index 7f142474faf..e24ba660f62 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/request/CollectionAdminRequest.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/request/CollectionAdminRequest.java
@@ -16,14 +16,7 @@
*/
package org.apache.solr.client.solrj.request;
-import static org.apache.solr.common.cloud.DocCollection.PER_REPLICA_STATE;
-import static org.apache.solr.common.cloud.ZkStateReader.NRT_REPLICAS;
-import static org.apache.solr.common.cloud.ZkStateReader.PULL_REPLICAS;
-import static org.apache.solr.common.cloud.ZkStateReader.READ_ONLY;
-import static org.apache.solr.common.cloud.ZkStateReader.REPLICATION_FACTOR;
-import static org.apache.solr.common.cloud.ZkStateReader.TLOG_REPLICAS;
import static org.apache.solr.common.params.CollectionAdminParams.ALIAS;
-import static org.apache.solr.common.params.CollectionAdminParams.COLL_CONF;
import static org.apache.solr.common.params.CollectionAdminParams.COUNT_PROP;
import static org.apache.solr.common.params.CollectionAdminParams.CREATE_NODE_SET_PARAM;
import static org.apache.solr.common.params.CollectionAdminParams.CREATE_NODE_SET_SHUFFLE_PARAM;
@@ -56,7 +49,6 @@ import org.apache.solr.common.SolrException;
import org.apache.solr.common.StringUtils;
import org.apache.solr.common.cloud.ImplicitDocRouter;
import org.apache.solr.common.cloud.Replica;
-import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.common.params.CollectionAdminParams;
import org.apache.solr.common.params.CollectionParams;
import org.apache.solr.common.params.CollectionParams.CollectionAction;
@@ -78,11 +70,15 @@ public abstract class CollectionAdminRequest<T extends CollectionAdminResponse>
/** The set of modifiable collection properties */
public static final java.util.List<String> MODIFIABLE_COLLECTION_PROPERTIES =
- Arrays.asList(REPLICATION_FACTOR, COLL_CONF, PER_REPLICA_STATE, READ_ONLY);
+ Arrays.asList(
+ CollectionAdminParams.REPLICATION_FACTOR,
+ CollectionAdminParams.COLL_CONF,
+ CollectionAdminParams.PER_REPLICA_STATE,
+ CollectionAdminParams.READ_ONLY);
protected final CollectionAction action;
- public static String PROPERTY_PREFIX = "property.";
+ @Deprecated public static String PROPERTY_PREFIX = CollectionAdminParams.PROPERTY_PREFIX;
public CollectionAdminRequest(CollectionAction action) {
this("/admin/collections", action);
@@ -684,7 +680,7 @@ public abstract class CollectionAdminRequest<T extends CollectionAdminResponse>
if (configName != null) params.set("collection.configName", configName);
if (createNodeSet != null) params.set(CREATE_NODE_SET_PARAM, createNodeSet);
if (numShards != null) {
- params.set(ZkStateReader.NUM_SHARDS_PROP, numShards);
+ params.set(CollectionAdminParams.NUM_SHARDS, numShards);
}
if (routerName != null) params.set("router.name", routerName);
if (shards != null) params.set("shards", shards);
@@ -692,19 +688,19 @@ public abstract class CollectionAdminRequest<T extends CollectionAdminResponse>
params.set("router.field", routerField);
}
if (nrtReplicas != null) {
- params.set(ZkStateReader.NRT_REPLICAS, nrtReplicas);
+ params.set(CollectionAdminParams.NRT_REPLICAS, nrtReplicas);
}
if (properties != null) {
addProperties(params, properties);
}
if (pullReplicas != null) {
- params.set(ZkStateReader.PULL_REPLICAS, pullReplicas);
+ params.set(CollectionAdminParams.PULL_REPLICAS, pullReplicas);
}
if (tlogReplicas != null) {
- params.set(ZkStateReader.TLOG_REPLICAS, tlogReplicas);
+ params.set(CollectionAdminParams.TLOG_REPLICAS, tlogReplicas);
}
if (Boolean.TRUE.equals(perReplicaState)) {
- params.set(PER_REPLICA_STATE, perReplicaState);
+ params.set(CollectionAdminParams.PER_REPLICA_STATE, perReplicaState);
}
params.setNonNull(ALIAS, alias);
return params;
@@ -919,6 +915,9 @@ public abstract class CollectionAdminRequest<T extends CollectionAdminResponse>
}
public static class ReindexCollection extends AsyncCollectionSpecificAdminRequest {
+ // not moving to CollectionAdminParams because there is COLL_CONF there already; confusing
+ private static final String CONFIGNAME_PARAM = "configName";
+
String target;
String query;
String fields;
@@ -985,7 +984,7 @@ public abstract class CollectionAdminRequest<T extends CollectionAdminResponse>
ModifiableSolrParams params = (ModifiableSolrParams) super.getParams();
params.setNonNull("target", target);
params.setNonNull("cmd", cmd);
- params.setNonNull(ZkStateReader.CONFIGNAME_PROP, configName);
+ params.setNonNull(CONFIGNAME_PARAM, configName);
params.setNonNull(CommonParams.Q, query);
params.setNonNull(CommonParams.FL, fields);
params.setNonNull("removeSource", removeSource);
@@ -1360,16 +1359,16 @@ public abstract class CollectionAdminRequest<T extends CollectionAdminResponse>
"Cannot set both replicationFactor and nrtReplicas as they mean the same thing");
}
if (replicationFactor != null) {
- params.set(ZkStateReader.REPLICATION_FACTOR, replicationFactor);
+ params.set(CollectionAdminParams.REPLICATION_FACTOR, replicationFactor);
}
if (nrtReplicas != null) {
- params.set(ZkStateReader.NRT_REPLICAS, nrtReplicas);
+ params.set(CollectionAdminParams.NRT_REPLICAS, nrtReplicas);
}
if (pullReplicas != null) {
- params.set(ZkStateReader.PULL_REPLICAS, pullReplicas);
+ params.set(CollectionAdminParams.PULL_REPLICAS, pullReplicas);
}
if (tlogReplicas != null) {
- params.set(ZkStateReader.TLOG_REPLICAS, tlogReplicas);
+ params.set(CollectionAdminParams.TLOG_REPLICAS, tlogReplicas);
}
if (properties != null) {
addProperties(params, properties);
@@ -2339,6 +2338,8 @@ public abstract class CollectionAdminRequest<T extends CollectionAdminResponse>
// ADDREPLICA request
public static class AddReplica extends AsyncCollectionAdminRequest {
+ private static final String REPLICA_TYPE_PARAM = "type";
+
protected String collection;
protected String shard;
protected String node;
@@ -2501,19 +2502,19 @@ public abstract class CollectionAdminRequest<T extends CollectionAdminResponse>
params.add(CoreAdminParams.NAME, coreName);
}
if (type != null) {
- params.add(ZkStateReader.REPLICA_TYPE, type.name());
+ params.add(REPLICA_TYPE_PARAM, type.name());
}
if (properties != null) {
addProperties(params, properties);
}
if (nrtReplicas != null) {
- params.add(NRT_REPLICAS, String.valueOf(nrtReplicas));
+ params.add(CollectionAdminParams.NRT_REPLICAS, String.valueOf(nrtReplicas));
}
if (tlogReplicas != null) {
- params.add(TLOG_REPLICAS, String.valueOf(tlogReplicas));
+ params.add(CollectionAdminParams.TLOG_REPLICAS, String.valueOf(tlogReplicas));
}
if (pullReplicas != null) {
- params.add(PULL_REPLICAS, String.valueOf(pullReplicas));
+ params.add(CollectionAdminParams.PULL_REPLICAS, String.valueOf(pullReplicas));
}
if (createNodeSet != null) {
params.add(CREATE_NODE_SET_PARAM, createNodeSet);
@@ -2591,10 +2592,10 @@ public abstract class CollectionAdminRequest<T extends CollectionAdminResponse>
// AsyncCollectionSpecificAdminRequest uses 'name' rather than 'collection'
// TODO - deal with this inconsistency
params.remove(CoreAdminParams.NAME);
- params.set(ZkStateReader.COLLECTION_PROP, this.collection);
+ params.set(CollectionAdminParams.COLLECTION, this.collection);
- if (this.replica != null) params.set(ZkStateReader.REPLICA_PROP, this.replica);
- if (this.shard != null) params.set(ZkStateReader.SHARD_ID_PROP, this.shard);
+ if (this.replica != null) params.set(CollectionAdminParams.REPLICA, this.replica);
+ if (this.shard != null) params.set(CollectionAdminParams.SHARD, this.shard);
if (onlyIfDown != null) {
params.set("onlyIfDown", onlyIfDown);
@@ -3220,8 +3221,8 @@ public abstract class CollectionAdminRequest<T extends CollectionAdminResponse>
// DELETEREPLICAPROP request
public static class DeleteReplicaProp extends AsyncShardSpecificAdminRequest {
- private String replica;
- private String propertyName;
+ private final String replica;
+ private final String propertyName;
private DeleteReplicaProp(
String collection, String shard, String replica, String propertyName) {
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/request/CoreAdminRequest.java b/solr/solrj/src/java/org/apache/solr/client/solrj/request/CoreAdminRequest.java
index 492c6e79ab1..ea2ff9a634d 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/request/CoreAdminRequest.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/request/CoreAdminRequest.java
@@ -25,7 +25,7 @@ import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.response.CoreAdminResponse;
import org.apache.solr.client.solrj.util.SolrIdentifierValidator;
import org.apache.solr.common.cloud.Replica;
-import org.apache.solr.common.cloud.ZkStateReader;
+import org.apache.solr.common.params.CollectionAdminParams;
import org.apache.solr.common.params.CoreAdminParams;
import org.apache.solr.common.params.CoreAdminParams.CoreAdminAction;
import org.apache.solr.common.params.ModifiableSolrParams;
@@ -223,7 +223,7 @@ public class CoreAdminRequest extends SolrRequest<CoreAdminResponse> {
params.set(CoreAdminParams.COLLECTION, collection);
}
if (numShards != null) {
- params.set(ZkStateReader.NUM_SHARDS_PROP, numShards);
+ params.set(CollectionAdminParams.NUM_SHARDS, numShards);
}
if (shardId != null) {
params.set(CoreAdminParams.SHARD, shardId);
@@ -326,7 +326,7 @@ public class CoreAdminRequest extends SolrRequest<CoreAdminResponse> {
}
if (state != null) {
- params.set(ZkStateReader.STATE_PROP, state.toString());
+ params.set("state", state.toString());
}
if (checkLive != null) {
@@ -426,7 +426,7 @@ public class CoreAdminRequest extends SolrRequest<CoreAdminResponse> {
ModifiableSolrParams params = new ModifiableSolrParams();
params.set(CoreAdminParams.ACTION, action.toString());
params.set(CoreAdminParams.CORE, core);
- params.set(ZkStateReader.STATE_PROP, state);
+ params.set("state", state);
return params;
}
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/routing/NodePreferenceRulesComparator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/routing/NodePreferenceRulesComparator.java
index 0ceb5141eec..f53f1003795 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/routing/NodePreferenceRulesComparator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/routing/NodePreferenceRulesComparator.java
@@ -23,7 +23,7 @@ import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.apache.solr.common.StringUtils;
-import org.apache.solr.common.cloud.NodesSysPropsCacher;
+import org.apache.solr.common.cloud.NodesSysProps;
import org.apache.solr.common.cloud.Replica;
import org.apache.solr.common.params.ShardParams;
import org.apache.solr.common.params.SolrParams;
@@ -40,7 +40,7 @@ import org.apache.solr.common.params.SolrParams;
*/
public class NodePreferenceRulesComparator implements Comparator<Object> {
- private final NodesSysPropsCacher sysPropsCache;
+ private final NodesSysProps sysProps;
private final String nodeName;
private final List<PreferenceRule> sortRules;
private final List<PreferenceRule> preferenceRules;
@@ -60,10 +60,10 @@ public class NodePreferenceRulesComparator implements Comparator<Object> {
final SolrParams requestParams,
final String nodeName,
final String localHostAddress,
- final NodesSysPropsCacher sysPropsCache,
+ final NodesSysProps sysProps,
final ReplicaListTransformerFactory defaultRltFactory,
final ReplicaListTransformerFactory stableRltFactory) {
- this.sysPropsCache = sysPropsCache;
+ this.sysProps = sysProps;
this.preferenceRules = preferenceRules;
this.nodeName = nodeName;
this.localHostAddress = localHostAddress;
@@ -137,7 +137,7 @@ public class NodePreferenceRulesComparator implements Comparator<Object> {
rhs = hasLeaderStatus(right, preferenceRule.value);
break;
case ShardParams.SHARDS_PREFERENCE_NODE_WITH_SAME_SYSPROP:
- if (sysPropsCache == null) {
+ if (sysProps == null) {
throw new IllegalArgumentException(
"Unable to get the NodesSysPropsCacher on sorting replicas by preference:"
+ preferenceRule.value);
@@ -169,8 +169,8 @@ public class NodePreferenceRulesComparator implements Comparator<Object> {
Collection<String> tags = Collections.singletonList(metricTag);
String otherNodeName = ((Replica) o).getNodeName();
- Map<String, Object> currentNodeMetric = sysPropsCache.getSysProps(nodeName, tags);
- Map<String, Object> otherNodeMetric = sysPropsCache.getSysProps(otherNodeName, tags);
+ Map<String, Object> currentNodeMetric = sysProps.getSysProps(nodeName, tags);
+ Map<String, Object> otherNodeMetric = sysProps.getSysProps(otherNodeName, tags);
return currentNodeMetric.equals(otherNodeMetric);
}
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/routing/RequestReplicaListTransformerGenerator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/routing/RequestReplicaListTransformerGenerator.java
index d7eb93ba245..748d13f4b5d 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/routing/RequestReplicaListTransformerGenerator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/routing/RequestReplicaListTransformerGenerator.java
@@ -24,7 +24,7 @@ import java.util.Objects;
import java.util.Random;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrException.ErrorCode;
-import org.apache.solr.common.cloud.NodesSysPropsCacher;
+import org.apache.solr.common.cloud.NodesSysProps;
import org.apache.solr.common.params.ShardParams;
import org.apache.solr.common.params.SolrParams;
import org.slf4j.Logger;
@@ -45,7 +45,7 @@ public class RequestReplicaListTransformerGenerator {
private final String defaultShardPreferences;
private final String nodeName;
private final String localHostAddress;
- private final NodesSysPropsCacher sysPropsCacher;
+ private final NodesSysProps sysProps;
public RequestReplicaListTransformerGenerator() {
this(null);
@@ -65,8 +65,8 @@ public class RequestReplicaListTransformerGenerator {
String defaultShardPreferences,
String nodeName,
String localHostAddress,
- NodesSysPropsCacher sysPropsCacher) {
- this(null, null, defaultShardPreferences, nodeName, localHostAddress, sysPropsCacher);
+ NodesSysProps sysProps) {
+ this(null, null, defaultShardPreferences, nodeName, localHostAddress, sysProps);
}
public RequestReplicaListTransformerGenerator(
@@ -75,14 +75,14 @@ public class RequestReplicaListTransformerGenerator {
String defaultShardPreferences,
String nodeName,
String localHostAddress,
- NodesSysPropsCacher sysPropsCacher) {
+ NodesSysProps sysProps) {
this.defaultRltFactory = Objects.requireNonNullElse(defaultRltFactory, RANDOM_RLTF);
this.stableRltFactory =
Objects.requireNonNullElseGet(stableRltFactory, AffinityReplicaListTransformerFactory::new);
this.defaultShardPreferences = Objects.requireNonNullElse(defaultShardPreferences, "");
this.nodeName = nodeName;
this.localHostAddress = localHostAddress;
- this.sysPropsCacher = sysPropsCacher;
+ this.sysProps = sysProps;
}
public ReplicaListTransformer getReplicaListTransformer(final SolrParams requestParams) {
@@ -99,7 +99,7 @@ public class RequestReplicaListTransformerGenerator {
String defaultShardPreferences,
String nodeName,
String localHostAddress,
- NodesSysPropsCacher sysPropsCacher) {
+ NodesSysProps sysProps) {
defaultShardPreferences =
Objects.requireNonNullElse(defaultShardPreferences, this.defaultShardPreferences);
final String shardsPreferenceSpec =
@@ -115,7 +115,7 @@ public class RequestReplicaListTransformerGenerator {
localHostAddress != null
? localHostAddress
: this.localHostAddress, // could still be null
- sysPropsCacher != null ? sysPropsCacher : this.sysPropsCacher, // could still be null
+ sysProps != null ? sysProps : this.sysProps, // could still be null
defaultRltFactory,
stableRltFactory);
ReplicaListTransformer baseReplicaListTransformer =
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/Aliases.java b/solr/solrj/src/java/org/apache/solr/common/cloud/Aliases.java
index 35679e4b6aa..dc80635c4c7 100644
--- a/solr/solrj/src/java/org/apache/solr/common/cloud/Aliases.java
+++ b/solr/solrj/src/java/org/apache/solr/common/cloud/Aliases.java
@@ -25,7 +25,6 @@ import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.function.BiConsumer;
-import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.params.CollectionAdminParams;
@@ -311,7 +310,7 @@ public class Aliases {
* based on the parameters.
*
* <p>Note that the state in zookeeper is unaffected by this method and the change must still be
- * persisted via {@link
+ * persisted via {@code
* ZkStateReader.AliasesManager#applyModificationAndExportToZk(UnaryOperator)}
*
* @param alias the alias to update, must not be null
@@ -352,7 +351,7 @@ public class Aliases {
* lists. Renaming routed aliases is not supported.
*
* <p>Note that the state in zookeeper is unaffected by this method and the change must still be
- * persisted via {@link
+ * persisted via {@code
* ZkStateReader.AliasesManager#applyModificationAndExportToZk(UnaryOperator)}
*
* @param before previous alias name, must not be null
@@ -422,7 +421,7 @@ public class Aliases {
* instance with the same data as the current one but with a modification based on the parameters.
*
* <p>Note that the state in zookeeper is unaffected by this method and the change must still be
- * persisted via {@link
+ * persisted via {@code
* ZkStateReader.AliasesManager#applyModificationAndExportToZk(UnaryOperator)}
*
* @param alias the alias to update
@@ -442,7 +441,7 @@ public class Aliases {
* parameters.
*
* <p>Note that the state in zookeeper is unaffected by this method and the change must still be
- * persisted via {@link
+ * persisted via {@code
* ZkStateReader.AliasesManager#applyModificationAndExportToZk(UnaryOperator)}
*
* @param alias the alias to update
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java b/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java
index 24afd246c6c..d54446afa0d 100644
--- a/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java
+++ b/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java
@@ -32,19 +32,24 @@ import java.util.function.Supplier;
import java.util.stream.Collectors;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrException.ErrorCode;
+import org.apache.solr.common.cloud.DocCollection.CollectionStateProps;
+import org.apache.solr.common.cloud.Replica.ReplicaStateProps;
import org.apache.solr.common.util.Utils;
-import org.apache.zookeeper.KeeperException;
import org.noggit.JSONWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- * Immutable state of the cloud. Normally you can get the state by using {@link
+ * Immutable state of the cloud. Normally you can get the state by using {@code
* ZkStateReader#getClusterState()}.
*
* @lucene.experimental
*/
public class ClusterState implements JSONWriter.Writable {
+
+ /** Cluster Prop that is http or https. */
+ public static final String URL_SCHEME = "urlScheme";
+
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private final Map<String, CollectionRef> collectionStates, immutableCollectionStates;
@@ -182,8 +187,8 @@ public class ClusterState implements JSONWriter.Writable {
for (Slice slice : coll.getSlices()) {
for (Replica replica : slice.getReplicas()) {
// TODO: for really large clusters, we could 'index' on this
- String rnodeName = replica.getStr(ZkStateReader.NODE_NAME_PROP);
- String rcore = replica.getStr(ZkStateReader.CORE_NAME_PROP);
+ String rnodeName = replica.getStr(ReplicaStateProps.NODE_NAME);
+ String rcore = replica.getStr(ReplicaStateProps.CORE_NAME);
if (nodeName.equals(rnodeName) && coreName.equals(rcore)) {
return slice.getName();
}
@@ -226,50 +231,6 @@ public class ClusterState implements JSONWriter.Writable {
return createFromCollectionMap(version, stateMap, liveNodes);
}
- /**
- * Create a ClusterState from Json. This method supports legacy configName location
- *
- * @param bytes a byte array of a Json representation of a mapping from collection name to the
- * Json representation of a {@link DocCollection} as written by {@link #write(JSONWriter)}. It
- * can represent one or more collections.
- * @param liveNodes list of live nodes
- * @param coll collection name
- * @param zkClient ZK client
- * @return the ClusterState
- */
- @SuppressWarnings({"unchecked"})
- @Deprecated
- public static ClusterState createFromJsonSupportingLegacyConfigName(
- int version, byte[] bytes, Set<String> liveNodes, String coll, SolrZkClient zkClient) {
- if (bytes == null || bytes.length == 0) {
- return new ClusterState(liveNodes, Collections.emptyMap());
- }
- Map<String, Object> stateMap = (Map<String, Object>) Utils.fromJSON(bytes);
- Map<String, Object> props = (Map<String, Object>) stateMap.get(coll);
- if (props != null) {
- if (!props.containsKey(ZkStateReader.CONFIGNAME_PROP)) {
- try {
- // read configName from collections/collection node
- String path = ZkStateReader.COLLECTIONS_ZKNODE + "/" + coll;
- byte[] data = zkClient.getData(path, null, null, true);
- if (data != null && data.length > 0) {
- ZkNodeProps configProp = ZkNodeProps.load(data);
- String configName = configProp.getStr(ZkStateReader.CONFIGNAME_PROP);
- if (configName != null) {
- props.put(ZkStateReader.CONFIGNAME_PROP, configName);
- stateMap.put(coll, props);
- } else {
- log.warn("configName is null, not found on {}", path);
- }
- }
- } catch (KeeperException | InterruptedException e) {
- // do nothing
- }
- }
- }
- return createFromCollectionMap(version, stateMap, liveNodes);
- }
-
public static ClusterState createFromCollectionMap(
int version, Map<String, Object> stateMap, Set<String> liveNodes) {
Map<String, CollectionRef> collections = new LinkedHashMap<>(stateMap.size());
@@ -290,7 +251,7 @@ public class ClusterState implements JSONWriter.Writable {
Map<String, Object> props;
Map<String, Slice> slices;
- if (Boolean.parseBoolean(String.valueOf(objs.get(DocCollection.PER_REPLICA_STATE)))) {
+ if (Boolean.parseBoolean(String.valueOf(objs.get(CollectionStateProps.PER_REPLICA_STATE)))) {
if (log.isDebugEnabled()) {
log.debug("a collection {} has per-replica state", name);
}
@@ -299,7 +260,7 @@ public class ClusterState implements JSONWriter.Writable {
if (rsp instanceof StatesProvider) ((StatesProvider) rsp).isPerReplicaState = true;
}
@SuppressWarnings({"unchecked"})
- Map<String, Object> sliceObjs = (Map<String, Object>) objs.get(DocCollection.SHARDS);
+ Map<String, Object> sliceObjs = (Map<String, Object>) objs.get(CollectionStateProps.SHARDS);
if (sliceObjs == null) {
// legacy format from 4.0... there was no separate "shards" level to contain the collection
// shards.
@@ -308,10 +269,10 @@ public class ClusterState implements JSONWriter.Writable {
} else {
slices = Slice.loadAllFromMap(name, sliceObjs);
props = new HashMap<>(objs);
- objs.remove(DocCollection.SHARDS);
+ objs.remove(CollectionStateProps.SHARDS);
}
- Object routerObj = props.get(DocCollection.DOC_ROUTER);
+ Object routerObj = props.get(CollectionStateProps.DOC_ROUTER);
DocRouter router;
if (routerObj == null) {
router = DocRouter.DEFAULT;
@@ -400,7 +361,8 @@ public class ClusterState implements JSONWriter.Writable {
consumer.accept(collection);
}
} catch (SolrException e) {
- if (e.getCause() instanceof KeeperException.NoNodeException) {
+ if (e.getCause() != null
+ && e.getCause().getClass().getName().endsWith("NoNodeException")) {
// don't do anything. This collection does not exist
} else {
throw e;
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/CollectionStatePredicate.java b/solr/solrj/src/java/org/apache/solr/common/cloud/CollectionStatePredicate.java
index fe5a672ae88..af0ba278c0f 100644
--- a/solr/solrj/src/java/org/apache/solr/common/cloud/CollectionStatePredicate.java
+++ b/solr/solrj/src/java/org/apache/solr/common/cloud/CollectionStatePredicate.java
@@ -18,14 +18,12 @@
package org.apache.solr.common.cloud;
import java.util.Set;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Predicate;
/**
* Interface to determine if a set of liveNodes and a collection's state matches some expecatations.
*
- * @see ZkStateReader#waitForState(String, long, TimeUnit, CollectionStatePredicate)
- * @see ZkStateReader#waitForState(String, long, TimeUnit, Predicate)
+ * @see "ZkStateReader#waitForState(String, long, TimeUnit, CollectionStatePredicate)"
+ * @see "ZkStateReader#waitForState(String, long, TimeUnit, Predicate)"
*/
public interface CollectionStatePredicate {
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/DocCollection.java b/solr/solrj/src/java/org/apache/solr/common/cloud/DocCollection.java
index ce30eceac37..fa1a8f415c2 100644
--- a/solr/solrj/src/java/org/apache/solr/common/cloud/DocCollection.java
+++ b/solr/solrj/src/java/org/apache/solr/common/cloud/DocCollection.java
@@ -16,12 +16,6 @@
*/
package org.apache.solr.common.cloud;
-import static org.apache.solr.common.cloud.ZkStateReader.CONFIGNAME_PROP;
-import static org.apache.solr.common.cloud.ZkStateReader.NRT_REPLICAS;
-import static org.apache.solr.common.cloud.ZkStateReader.PULL_REPLICAS;
-import static org.apache.solr.common.cloud.ZkStateReader.READ_ONLY;
-import static org.apache.solr.common.cloud.ZkStateReader.REPLICATION_FACTOR;
-import static org.apache.solr.common.cloud.ZkStateReader.TLOG_REPLICAS;
import static org.apache.solr.common.util.Utils.toJSONString;
import java.lang.invoke.MethodHandles;
@@ -37,6 +31,7 @@ import java.util.Objects;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BiPredicate;
+import org.apache.solr.common.cloud.Replica.ReplicaStateProps;
import org.noggit.JSONWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -45,11 +40,9 @@ import org.slf4j.LoggerFactory;
* Models a Collection in zookeeper (but that Java name is obviously taken, hence "DocCollection")
*/
public class DocCollection extends ZkNodeProps implements Iterable<Slice> {
- private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
- public static final String DOC_ROUTER = "router";
- public static final String SHARDS = "shards";
- public static final String PER_REPLICA_STATE = "perReplicaState";
+ public static final String COLLECTIONS_ZKNODE = "/collections";
+ private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private final int znodeVersion;
@@ -96,20 +89,21 @@ public class DocCollection extends ZkNodeProps implements Iterable<Slice> {
// overwrites
this.znodeVersion = zkVersion == -1 ? Integer.MAX_VALUE : zkVersion;
this.name = name;
- this.configName = (String) props.get(CONFIGNAME_PROP);
+ this.configName = (String) props.get(CollectionStateProps.CONFIGNAME);
this.slices = slices;
this.activeSlices = new HashMap<>();
this.nodeNameLeaderReplicas = new HashMap<>();
this.nodeNameReplicas = new HashMap<>();
- this.replicationFactor = (Integer) verifyProp(props, REPLICATION_FACTOR);
- this.numNrtReplicas = (Integer) verifyProp(props, NRT_REPLICAS, 0);
- this.numTlogReplicas = (Integer) verifyProp(props, TLOG_REPLICAS, 0);
- this.numPullReplicas = (Integer) verifyProp(props, PULL_REPLICAS, 0);
- this.perReplicaState = (Boolean) verifyProp(props, PER_REPLICA_STATE, Boolean.FALSE);
+ this.replicationFactor = (Integer) verifyProp(props, CollectionStateProps.REPLICATION_FACTOR);
+ this.numNrtReplicas = (Integer) verifyProp(props, CollectionStateProps.NRT_REPLICAS, 0);
+ this.numTlogReplicas = (Integer) verifyProp(props, CollectionStateProps.TLOG_REPLICAS, 0);
+ this.numPullReplicas = (Integer) verifyProp(props, CollectionStateProps.PULL_REPLICAS, 0);
+ this.perReplicaState =
+ (Boolean) verifyProp(props, CollectionStateProps.PER_REPLICA_STATE, Boolean.FALSE);
ClusterState.getReplicaStatesProvider()
.get()
.ifPresent(it -> perReplicaStates = it.getStates());
- Boolean readOnly = (Boolean) verifyProp(props, READ_ONLY);
+ Boolean readOnly = (Boolean) verifyProp(props, CollectionStateProps.READ_ONLY);
this.readOnly = readOnly == null ? Boolean.FALSE : readOnly;
Iterator<Map.Entry<String, Slice>> iter = slices.entrySet().iterator();
@@ -128,10 +122,18 @@ public class DocCollection extends ZkNodeProps implements Iterable<Slice> {
}
this.activeSlicesArr = activeSlices.values().toArray(new Slice[activeSlices.size()]);
this.router = router;
- this.znode = ZkStateReader.getCollectionPath(name);
+ this.znode = getCollectionPath(name);
assert name != null && slices != null;
}
+ public static String getCollectionPath(String coll) {
+ return getCollectionPathRoot(coll) + "/state.json";
+ }
+
+ public static String getCollectionPathRoot(String coll) {
+ return COLLECTIONS_ZKNODE + "/" + coll;
+ }
+
/**
* Update our state with a state of a {@link Replica} Used to create a new Collection State when
* only a replica is updated
@@ -171,7 +173,7 @@ public class DocCollection extends ZkNodeProps implements Iterable<Slice> {
}
replicas.add(replica);
- if (replica.getStr(Slice.LEADER) != null) {
+ if (replica.getStr(ReplicaStateProps.LEADER) != null) {
List<Replica> leaderReplicas = nodeNameLeaderReplicas.get(replica.getNodeName());
if (leaderReplicas == null) {
leaderReplicas = new ArrayList<>();
@@ -189,13 +191,13 @@ public class DocCollection extends ZkNodeProps implements Iterable<Slice> {
Object o = props.get(propName);
if (o == null) return def;
switch (propName) {
- case REPLICATION_FACTOR:
- case NRT_REPLICAS:
- case PULL_REPLICAS:
- case TLOG_REPLICAS:
+ case CollectionStateProps.REPLICATION_FACTOR:
+ case CollectionStateProps.NRT_REPLICAS:
+ case CollectionStateProps.PULL_REPLICAS:
+ case CollectionStateProps.TLOG_REPLICAS:
return Integer.parseInt(o.toString());
- case PER_REPLICA_STATE:
- case READ_ONLY:
+ case CollectionStateProps.PER_REPLICA_STATE:
+ case CollectionStateProps.READ_ONLY:
return Boolean.parseBoolean(o.toString());
case "snitch":
default:
@@ -312,7 +314,7 @@ public class DocCollection extends ZkNodeProps implements Iterable<Slice> {
return "DocCollection("
+ name
+ "/"
- + znode
+ + getZNode()
+ "/"
+ znodeVersion
+ " "
@@ -325,7 +327,7 @@ public class DocCollection extends ZkNodeProps implements Iterable<Slice> {
public void write(JSONWriter jsonWriter) {
LinkedHashMap<String, Object> all = new LinkedHashMap<>(slices.size() + 1);
all.putAll(propMap);
- all.put(SHARDS, slices);
+ all.put(CollectionStateProps.SHARDS, slices);
jsonWriter.write(all);
}
@@ -473,4 +475,17 @@ public class DocCollection extends ZkNodeProps implements Iterable<Slice> {
if (type == Replica.Type.TLOG) result = numTlogReplicas;
return result == null ? def : result;
}
+
+ /** JSON properties related to a collection's state. */
+ public interface CollectionStateProps {
+ String NRT_REPLICAS = "nrtReplicas";
+ String PULL_REPLICAS = "pullReplicas";
+ String TLOG_REPLICAS = "tlogReplicas";
+ String REPLICATION_FACTOR = "replicationFactor";
+ String READ_ONLY = "readOnly";
+ String CONFIGNAME = "configName";
+ String DOC_ROUTER = "router";
+ String SHARDS = "shards";
+ String PER_REPLICA_STATE = "perReplicaState";
+ }
}
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/DocRouter.java b/solr/solrj/src/java/org/apache/solr/common/cloud/DocRouter.java
index 5b27eb5109e..77487753df5 100644
--- a/solr/solrj/src/java/org/apache/solr/common/cloud/DocRouter.java
+++ b/solr/solrj/src/java/org/apache/solr/common/cloud/DocRouter.java
@@ -16,8 +16,6 @@
*/
package org.apache.solr.common.cloud;
-import static org.apache.solr.common.cloud.DocCollection.DOC_ROUTER;
-
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -29,6 +27,7 @@ import java.util.Map;
import org.apache.solr.cluster.api.HashRange;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrInputDocument;
+import org.apache.solr.common.cloud.DocCollection.CollectionStateProps;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.StrUtils;
import org.noggit.JSONWriter;
@@ -52,7 +51,7 @@ public abstract class DocRouter {
public String getRouteField(DocCollection coll) {
if (coll == null) return null;
@SuppressWarnings({"rawtypes"})
- Map m = (Map) coll.get(DOC_ROUTER);
+ Map m = (Map) coll.get(CollectionStateProps.DOC_ROUTER);
if (m == null) return null;
return (String) m.get("field");
}
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/ZkACLProvider.java b/solr/solrj/src/java/org/apache/solr/common/cloud/NodesSysProps.java
similarity index 79%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/ZkACLProvider.java
rename to solr/solrj/src/java/org/apache/solr/common/cloud/NodesSysProps.java
index 4b3ad36ed42..8433a186776 100644
--- a/solr/solrj/src/java/org/apache/solr/common/cloud/ZkACLProvider.java
+++ b/solr/solrj/src/java/org/apache/solr/common/cloud/NodesSysProps.java
@@ -14,12 +14,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.solr.common.cloud;
-import java.util.List;
-import org.apache.zookeeper.data.ACL;
+package org.apache.solr.common.cloud;
-public interface ZkACLProvider {
+import java.util.Collection;
+import java.util.Map;
- List<ACL> getACLsToAdd(String zNodePath);
+/** Fetch a node's system properties. It should be cached. */
+public interface NodesSysProps {
+ Map<String, Object> getSysProps(String node, Collection<String> tags);
}
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/PerReplicaStates.java b/solr/solrj/src/java/org/apache/solr/common/cloud/PerReplicaStates.java
index f05d79042ce..f756ea1883f 100644
--- a/solr/solrj/src/java/org/apache/solr/common/cloud/PerReplicaStates.java
+++ b/solr/solrj/src/java/org/apache/solr/common/cloud/PerReplicaStates.java
@@ -33,13 +33,11 @@ import java.util.Set;
import java.util.function.BiConsumer;
import org.apache.solr.cluster.api.SimpleMap;
import org.apache.solr.common.MapWriter;
-import org.apache.solr.common.SolrException;
import org.apache.solr.common.annotation.JsonProperty;
+import org.apache.solr.common.cloud.Replica.ReplicaStateProps;
import org.apache.solr.common.util.ReflectMapWriter;
import org.apache.solr.common.util.StrUtils;
import org.apache.solr.common.util.WrappedSimpleMap;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -119,33 +117,6 @@ public class PerReplicaStates implements ReflectMapWriter {
return result;
}
- /**
- * Fetch the latest {@link PerReplicaStates} . It fetches data after checking the {@link
- * Stat#getCversion()} of state.json. If this is not modified, the same object is returned
- */
- public static PerReplicaStates fetch(
- String path, SolrZkClient zkClient, PerReplicaStates current) {
- try {
- if (current != null) {
- Stat stat = zkClient.exists(current.path, null, true);
- if (stat == null) return new PerReplicaStates(path, -1, Collections.emptyList());
- if (current.cversion == stat.getCversion()) return current; // not modifiedZkStateReaderTest
- }
- Stat stat = new Stat();
- List<String> children = zkClient.getChildren(path, null, stat, true);
- return new PerReplicaStates(path, stat.getCversion(), Collections.unmodifiableList(children));
- } catch (KeeperException e) {
- throw new SolrException(
- SolrException.ErrorCode.SERVER_ERROR, "Error fetching per-replica states", e);
- } catch (InterruptedException e) {
- SolrZkClient.checkInterrupted(e);
- throw new SolrException(
- SolrException.ErrorCode.SERVER_ERROR,
- "Thread interrupted when loading per-replica states from " + path,
- e);
- }
- }
-
public static String getReplicaName(String s) {
int idx = s.indexOf(SEPARATOR);
if (idx > 0) {
@@ -262,8 +233,8 @@ public class PerReplicaStates implements ReflectMapWriter {
public void writeMap(EntryWriter ew) throws IOException {
ew.put(NAME, replica);
ew.put(VERSION, version);
- ew.put(ZkStateReader.STATE_PROP, state.toString());
- if (isLeader) ew.put(Slice.LEADER, isLeader);
+ ew.put(ReplicaStateProps.STATE, state.toString());
+ if (isLeader) ew.put(ReplicaStateProps.LEADER, isLeader);
ew.putIfNotNull("duplicate", duplicate);
}
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/Replica.java b/solr/solrj/src/java/org/apache/solr/common/cloud/Replica.java
index 0b6c0689c63..0b05b9bdf69 100644
--- a/solr/solrj/src/java/org/apache/solr/common/cloud/Replica.java
+++ b/solr/solrj/src/java/org/apache/solr/common/cloud/Replica.java
@@ -18,7 +18,6 @@ package org.apache.solr.common.cloud;
import static org.apache.solr.common.ConditionalMapWriter.NON_NULL_VAL;
import static org.apache.solr.common.ConditionalMapWriter.dedupeKeyPredicate;
-import static org.apache.solr.common.cloud.ZkStateReader.BASE_URL_PROP;
import java.io.IOException;
import java.lang.invoke.MethodHandles;
@@ -38,6 +37,7 @@ import org.slf4j.LoggerFactory;
public class Replica extends ZkNodeProps implements MapWriter {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
/**
* The replica's state. In general, if the node the replica is hosted on is not under {@code
* /live_nodes} in ZK, the replica's state should be discarded.
@@ -142,15 +142,14 @@ public class Replica extends ZkNodeProps implements MapWriter {
this.collection = collection;
this.shard = shard;
this.name = name;
- this.node = (String) propMap.get(ZkStateReader.NODE_NAME_PROP);
- this.core = (String) propMap.get(ZkStateReader.CORE_NAME_PROP);
- this.type = Type.get((String) propMap.get(ZkStateReader.REPLICA_TYPE));
+ this.node = (String) propMap.get(ReplicaStateProps.NODE_NAME);
+ this.core = (String) propMap.get(ReplicaStateProps.CORE_NAME);
+ this.type = Type.get((String) propMap.get(ReplicaStateProps.TYPE));
readPrs();
// default to ACTIVE
this.state =
State.getState(
- String.valueOf(
- propMap.getOrDefault(ZkStateReader.STATE_PROP, State.ACTIVE.toString())));
+ String.valueOf(propMap.getOrDefault(ReplicaStateProps.STATE, State.ACTIVE.toString())));
validate();
}
@@ -199,11 +198,10 @@ public class Replica extends ZkNodeProps implements MapWriter {
this.propMap.putAll(details);
readPrs();
type =
- Replica.Type.valueOf(
- String.valueOf(propMap.getOrDefault(ZkStateReader.REPLICA_TYPE, "NRT")));
+ Replica.Type.valueOf(String.valueOf(propMap.getOrDefault(ReplicaStateProps.TYPE, "NRT")));
if (state == null)
state =
- State.getState(String.valueOf(propMap.getOrDefault(ZkStateReader.STATE_PROP, "active")));
+ State.getState(String.valueOf(propMap.getOrDefault(ReplicaStateProps.STATE, "active")));
validate();
}
@@ -216,9 +214,9 @@ public class Replica extends ZkNodeProps implements MapWriter {
replicaState = it.getStates().get(name);
if (replicaState != null) {
propMap.put(
- ZkStateReader.STATE_PROP,
+ ReplicaStateProps.STATE,
replicaState.state.toString().toLowerCase(Locale.ROOT));
- if (replicaState.isLeader) propMap.put(Slice.LEADER, "true");
+ if (replicaState.isLeader) propMap.put(ReplicaStateProps.LEADER, "true");
}
});
}
@@ -232,17 +230,17 @@ public class Replica extends ZkNodeProps implements MapWriter {
Objects.requireNonNull(this.state, "'state' must not be null");
Objects.requireNonNull(this.node, "'node' must not be null");
- String baseUrl = (String) propMap.get(BASE_URL_PROP);
+ String baseUrl = (String) propMap.get(ReplicaStateProps.BASE_URL);
Objects.requireNonNull(baseUrl, "'base_url' must not be null");
// make sure all declared props are in the propMap
- propMap.put(ZkStateReader.COLLECTION_PROP, collection);
- propMap.put(ZkStateReader.SHARD_ID_PROP, shard);
- propMap.put(ZkStateReader.CORE_NODE_NAME_PROP, name);
- propMap.put(ZkStateReader.NODE_NAME_PROP, node);
- propMap.put(ZkStateReader.CORE_NAME_PROP, core);
- propMap.put(ZkStateReader.REPLICA_TYPE, type.toString());
- propMap.put(ZkStateReader.STATE_PROP, state.toString());
+ propMap.put(ReplicaStateProps.COLLECTION, collection);
+ propMap.put(ReplicaStateProps.SHARD_ID, shard);
+ propMap.put(ReplicaStateProps.CORE_NODE_NAME, name);
+ propMap.put(ReplicaStateProps.NODE_NAME, node);
+ propMap.put(ReplicaStateProps.CORE_NAME, core);
+ propMap.put(ReplicaStateProps.TYPE, type.toString());
+ propMap.put(ReplicaStateProps.STATE, state.toString());
}
public String getCollection() {
@@ -284,7 +282,7 @@ public class Replica extends ZkNodeProps implements MapWriter {
}
public String getBaseUrl() {
- return getStr(BASE_URL_PROP);
+ return getStr(ReplicaStateProps.BASE_URL);
}
/** SolrCore name. */
@@ -304,7 +302,7 @@ public class Replica extends ZkNodeProps implements MapWriter {
public void setState(State state) {
this.state = state;
- propMap.put(ZkStateReader.STATE_PROP, this.state.toString());
+ propMap.put(ReplicaStateProps.STATE, this.state.toString());
}
public boolean isActive(Set<String> liveNodes) {
@@ -316,7 +314,7 @@ public class Replica extends ZkNodeProps implements MapWriter {
}
public boolean isLeader() {
- return getBool(ZkStateReader.LEADER_PROP, false);
+ return getBool(ReplicaStateProps.LEADER, false);
}
public Object get(String key, Object defValue) {
@@ -330,8 +328,8 @@ public class Replica extends ZkNodeProps implements MapWriter {
public String getProperty(String propertyName) {
final String propertyKey;
- if (!propertyName.startsWith(ZkStateReader.PROPERTY_PROP_PREFIX)) {
- propertyKey = ZkStateReader.PROPERTY_PROP_PREFIX + propertyName;
+ if (!propertyName.startsWith(ReplicaStateProps.PROPERTY_PREFIX)) {
+ propertyKey = ReplicaStateProps.PROPERTY_PREFIX + propertyName;
} else {
propertyKey = propertyName;
}
@@ -343,11 +341,11 @@ public class Replica extends ZkNodeProps implements MapWriter {
log.debug("A replica is updated with new state : {}", state);
Map<String, Object> props = new LinkedHashMap<>(propMap);
if (state == null) {
- props.put(ZkStateReader.STATE_PROP, State.DOWN.toString());
- props.remove(Slice.LEADER);
+ props.put(ReplicaStateProps.STATE, State.DOWN.toString());
+ props.remove(ReplicaStateProps.LEADER);
} else {
- props.put(ZkStateReader.STATE_PROP, state.state.toString());
- if (state.isLeader) props.put(Slice.LEADER, "true");
+ props.put(ReplicaStateProps.STATE, state.state.toString());
+ if (state.isLeader) props.put(ReplicaStateProps.LEADER, "true");
}
Replica r = new Replica(name, props, collection, shard);
r.replicaState = state;
@@ -392,12 +390,12 @@ public class Replica extends ZkNodeProps implements MapWriter {
}
writer
- .put(ZkStateReader.CORE_NAME_PROP, core, p)
- .put(ZkStateReader.SHARD_ID_PROP, shard, p)
- .put(ZkStateReader.COLLECTION_PROP, collection, p)
- .put(ZkStateReader.NODE_NAME_PROP, node, p)
- .put(ZkStateReader.REPLICA_TYPE, type.toString(), p)
- .put(ZkStateReader.STATE_PROP, state.toString(), p);
+ .put(ReplicaStateProps.CORE_NAME, core, p)
+ .put(ReplicaStateProps.SHARD_ID, shard, p)
+ .put(ReplicaStateProps.COLLECTION, collection, p)
+ .put(ReplicaStateProps.NODE_NAME, node, p)
+ .put(ReplicaStateProps.TYPE, type.toString(), p)
+ .put(ReplicaStateProps.STATE, state.toString(), p);
};
}
@@ -415,4 +413,18 @@ public class Replica extends ZkNodeProps implements MapWriter {
+ ':'
+ Utils.toJSONString(propMap); // small enough, keep it on one line (i.e. no indent)
}
+
+ /** JSON properties related to a replica's state. */
+ public interface ReplicaStateProps {
+ String COLLECTION = "collection";
+ String SHARD_ID = "shard";
+ String LEADER = "leader";
+ String STATE = "state";
+ String CORE_NAME = "core";
+ String CORE_NODE_NAME = "core_node_name";
+ String TYPE = "type";
+ String NODE_NAME = "node_name";
+ String BASE_URL = "base_url";
+ String PROPERTY_PREFIX = "property.";
+ }
}
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/Slice.java b/solr/solrj/src/java/org/apache/solr/common/cloud/Slice.java
index af3c4c07862..55f4c708637 100644
--- a/solr/solrj/src/java/org/apache/solr/common/cloud/Slice.java
+++ b/solr/solrj/src/java/org/apache/solr/common/cloud/Slice.java
@@ -127,13 +127,6 @@ public class Slice extends ZkNodeProps implements Iterable<Replica> {
}
}
- public static final String REPLICAS = "replicas";
- public static final String RANGE = "range";
- // FUTURE: do we want to record the leader as a slice property in the JSON (as opposed to isLeader
- // as a replica property?)
- public static final String LEADER = "leader";
- public static final String PARENT = "parent";
-
private final String name;
private final DocRouter.Range range;
// FUTURE: optional per-slice override of the collection replicationFactor
@@ -157,12 +150,12 @@ public class Slice extends ZkNodeProps implements Iterable<Replica> {
this.name = name;
this.collection = collection;
- Object rangeObj = propMap.get(RANGE);
- if (propMap.get(ZkStateReader.STATE_PROP) != null) {
- this.state = State.getState((String) propMap.get(ZkStateReader.STATE_PROP));
+ Object rangeObj = propMap.get(SliceStateProps.RANGE);
+ if (propMap.get(SliceStateProps.STATE_PROP) != null) {
+ this.state = State.getState((String) propMap.get(SliceStateProps.STATE_PROP));
} else {
this.state = State.ACTIVE; // Default to ACTIVE
- propMap.put(ZkStateReader.STATE_PROP, state.toString());
+ propMap.put(SliceStateProps.STATE_PROP, state.toString());
}
DocRouter.Range tmpRange = null;
if (rangeObj instanceof DocRouter.Range) {
@@ -177,8 +170,8 @@ public class Slice extends ZkNodeProps implements Iterable<Replica> {
* debugging. this isn't an error condition for custom sharding. if (range == null) {
* System.out.println("###### NO RANGE for " + name + " props=" + props); }
*/
- if (propMap.containsKey(PARENT) && propMap.get(PARENT) != null)
- this.parent = (String) propMap.get(PARENT);
+ if (propMap.containsKey(SliceStateProps.PARENT) && propMap.get(SliceStateProps.PARENT) != null)
+ this.parent = (String) propMap.get(SliceStateProps.PARENT);
else this.parent = null;
replicationFactor = null; // future
@@ -188,8 +181,9 @@ public class Slice extends ZkNodeProps implements Iterable<Replica> {
this.replicas =
replicas != null
? replicas
- : makeReplicas(collection, name, (Map<String, Object>) propMap.get(REPLICAS));
- propMap.put(REPLICAS, this.replicas);
+ : makeReplicas(
+ collection, name, (Map<String, Object>) propMap.get(SliceStateProps.REPLICAS));
+ propMap.put(SliceStateProps.REPLICAS, this.replicas);
Map<String, Object> rules = (Map<String, Object>) propMap.get("routingRules");
if (rules != null) {
@@ -310,4 +304,17 @@ public class Slice extends ZkNodeProps implements Iterable<Replica> {
public void write(JSONWriter jsonWriter) {
jsonWriter.write(propMap);
}
+
+ /** JSON properties related to a slice's state. */
+ public interface SliceStateProps {
+
+ String STATE_PROP = "state";
+ String REPLICAS = "replicas";
+ String RANGE = "range";
+ // FUTURE: do we want to record the leader as a slice property in the JSON (as opposed to
+ // isLeader
+ // as a replica property?)
+ String LEADER = "leader";
+ String PARENT = "parent";
+ }
}
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/ZkCoreNodeProps.java b/solr/solrj/src/java/org/apache/solr/common/cloud/ZkCoreNodeProps.java
index 25919d8e2d8..5e789efb7eb 100644
--- a/solr/solrj/src/java/org/apache/solr/common/cloud/ZkCoreNodeProps.java
+++ b/solr/solrj/src/java/org/apache/solr/common/cloud/ZkCoreNodeProps.java
@@ -17,8 +17,10 @@
package org.apache.solr.common.cloud;
import java.util.Objects;
+import org.apache.solr.common.cloud.Replica.ReplicaStateProps;
public class ZkCoreNodeProps {
+
private final ZkNodeProps nodeProps;
public ZkCoreNodeProps(ZkNodeProps nodeProps) {
@@ -30,11 +32,11 @@ public class ZkCoreNodeProps {
}
public String getNodeName() {
- return nodeProps.getStr(ZkStateReader.NODE_NAME_PROP);
+ return nodeProps.getStr(ReplicaStateProps.NODE_NAME);
}
public String getState() {
- return nodeProps.getStr(ZkStateReader.STATE_PROP);
+ return nodeProps.getStr(ReplicaStateProps.STATE);
}
public String getBaseUrl() {
@@ -42,13 +44,13 @@ public class ZkCoreNodeProps {
}
public String getCoreName() {
- return nodeProps.getStr(ZkStateReader.CORE_NAME_PROP);
+ return nodeProps.getStr(ReplicaStateProps.CORE_NAME);
}
private static String getBaseUrl(ZkNodeProps nodeProps) {
// if storing baseUrl in ZK is enabled and it's stored, just use what's stored, i.e. no
// self-healing here
- String baseUrl = nodeProps.getStr(ZkStateReader.BASE_URL_PROP);
+ String baseUrl = nodeProps.getStr(ReplicaStateProps.BASE_URL);
if (baseUrl == null) {
throw new IllegalStateException("base_url not set in: " + nodeProps);
}
@@ -58,7 +60,7 @@ public class ZkCoreNodeProps {
public static String getCoreUrl(ZkNodeProps nodeProps) {
String baseUrl = getBaseUrl(nodeProps);
return baseUrl != null
- ? getCoreUrl(baseUrl, nodeProps.getStr(ZkStateReader.CORE_NAME_PROP))
+ ? getCoreUrl(baseUrl, nodeProps.getStr(ReplicaStateProps.CORE_NAME))
: null;
}
@@ -82,6 +84,6 @@ public class ZkCoreNodeProps {
}
public boolean isLeader() {
- return nodeProps.containsKey(ZkStateReader.LEADER_PROP);
+ return nodeProps.containsKey(ReplicaStateProps.LEADER);
}
}
diff --git a/solr/solrj/src/java/org/apache/solr/common/params/CollectionAdminParams.java b/solr/solrj/src/java/org/apache/solr/common/params/CollectionAdminParams.java
index ecddc96fe01..eb143f3153a 100644
--- a/solr/solrj/src/java/org/apache/solr/common/params/CollectionAdminParams.java
+++ b/solr/solrj/src/java/org/apache/solr/common/params/CollectionAdminParams.java
@@ -18,6 +18,7 @@ package org.apache.solr.common.params;
import java.util.Arrays;
import java.util.Collection;
+import org.apache.solr.common.cloud.DocCollection.CollectionStateProps;
public interface CollectionAdminParams {
@@ -42,6 +43,12 @@ public interface CollectionAdminParams {
/** The number of shards to create a particular collection with. */
String NUM_SHARDS = "numShards";
+ String NRT_REPLICAS = "nrtReplicas";
+ String PULL_REPLICAS = "pullReplicas";
+ String TLOG_REPLICAS = "tlogReplicas";
+
+ String REPLICATION_FACTOR = "replicationFactor";
+
/**
* A parameter which specifies if the provided list of Solr nodes (via {@linkplain
* #CREATE_NODE_SET_PARAM}) should be shuffled before being used.
@@ -106,6 +113,15 @@ public interface CollectionAdminParams {
*/
String SKIP_NODE_ASSIGNMENT = "skipNodeAssignment";
+ String REPLICA = "replica";
+
+ /** To identify a specific shard. */
+ String SHARD = "shard";
+
+ String READ_ONLY = "readOnly";
+
/** Prefix for arbitrary collection or replica properties. */
String PROPERTY_PREFIX = "property.";
+
+ String PER_REPLICA_STATE = CollectionStateProps.PER_REPLICA_STATE;
}
diff --git a/solr/solrj/src/java/org/apache/solr/common/util/Utils.java b/solr/solrj/src/java/org/apache/solr/common/util/Utils.java
index bc3d30c1919..1ddac204b51 100644
--- a/solr/solrj/src/java/org/apache/solr/common/util/Utils.java
+++ b/solr/solrj/src/java/org/apache/solr/common/util/Utils.java
@@ -20,6 +20,7 @@ import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Collections.singletonList;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
+import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -48,7 +49,6 @@ import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;
@@ -66,8 +66,6 @@ import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.util.EntityUtils;
-import org.apache.solr.client.solrj.cloud.DistribStateManager;
-import org.apache.solr.client.solrj.cloud.VersionedData;
import org.apache.solr.client.solrj.impl.BinaryRequestWriter;
import org.apache.solr.common.IteratorWriter;
import org.apache.solr.common.LinkedHashMapWriter;
@@ -76,19 +74,13 @@ import org.apache.solr.common.MapWriterMap;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SpecProvider;
import org.apache.solr.common.annotation.JsonProperty;
-import org.apache.solr.common.cloud.SolrZkClient;
-import org.apache.solr.common.cloud.ZkOperation;
-import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.common.params.CommonParams;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.server.ByteBufferInputStream;
import org.noggit.CharArr;
import org.noggit.JSONParser;
import org.noggit.JSONWriter;
import org.noggit.ObjectBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.slf4j.MDC;
public class Utils {
@@ -180,7 +172,7 @@ public class Utils {
try (final JavaBinCodec jbc = new JavaBinCodec()) {
BinaryRequestWriter.BAOS baos = new BinaryRequestWriter.BAOS();
jbc.marshal(o, baos);
- return new ByteBufferInputStream(ByteBuffer.wrap(baos.getbuf(), 0, baos.size()));
+ return new ByteArrayInputStream(baos.getbuf(), 0, baos.size());
}
}
@@ -677,45 +669,6 @@ public class Utils {
while (is.read() != -1) {}
}
- @SuppressWarnings({"unchecked"})
- public static Map<String, Object> getJson(DistribStateManager distribStateManager, String path)
- throws InterruptedException, IOException, KeeperException {
- VersionedData data = null;
- try {
- data = distribStateManager.getData(path);
- } catch (KeeperException.NoNodeException | NoSuchElementException e) {
- return Collections.emptyMap();
- }
- if (data == null || data.getData() == null || data.getData().length == 0)
- return Collections.emptyMap();
- return (Map<String, Object>) Utils.fromJSON(data.getData());
- }
-
- /**
- * Assumes data in ZooKeeper is a JSON string, deserializes it and returns as a Map
- *
- * @param zkClient the zookeeper client
- * @param path the path to the znode being read
- * @param retryOnConnLoss whether to retry the operation automatically on connection loss, see
- * {@link org.apache.solr.common.cloud.ZkCmdExecutor#retryOperation(ZkOperation)}
- * @return a Map if the node exists and contains valid JSON or an empty map if znode does not
- * exist or has a null data
- */
- @SuppressWarnings({"unchecked"})
- public static Map<String, Object> getJson(
- SolrZkClient zkClient, String path, boolean retryOnConnLoss)
- throws KeeperException, InterruptedException {
- try {
- byte[] bytes = zkClient.getData(path, null, null, retryOnConnLoss);
- if (bytes != null && bytes.length > 0) {
- return (Map<String, Object>) Utils.fromJSON(bytes);
- }
- } catch (KeeperException.NoNodeException e) {
- return Collections.emptyMap();
- }
- return Collections.emptyMap();
- }
-
public static final Pattern ARRAY_ELEMENT_INDEX = Pattern.compile("(\\S*?)\\[([-]?\\d+)\\]");
public static SpecProvider getSpec(final String name) {
@@ -827,16 +780,6 @@ public class Utils {
return unit.convert(timeSource.getTimeNs() - NANOSECONDS.convert(start, unit), NANOSECONDS);
}
- public static String getMDCNode() {
- String s = MDC.get(ZkStateReader.NODE_NAME_PROP);
- if (s == null) return null;
- if (s.startsWith("n:")) {
- return s.substring(2);
- } else {
- return null;
- }
- }
-
public static <T> T handleExp(Logger logger, T def, Callable<T> c) {
try {
return c.call();
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudSolrClientTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudSolrClientTest.java
index 8813480e1bf..f13a542b9e0 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudSolrClientTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudSolrClientTest.java
@@ -62,6 +62,7 @@ import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.cloud.DocCollection;
import org.apache.solr.common.cloud.DocRouter;
import org.apache.solr.common.cloud.PerReplicaStates;
+import org.apache.solr.common.cloud.PerReplicaStatesFetcher;
import org.apache.solr.common.cloud.Replica;
import org.apache.solr.common.cloud.Slice;
import org.apache.solr.common.cloud.ZkStateReader;
@@ -1155,7 +1156,7 @@ public class CloudSolrClientTest extends SolrCloudTestCase {
.process(cluster.getSolrClient());
String testCollection = "perReplicaState_test";
- String collectionPath = ZkStateReader.getCollectionPath(testCollection);
+ String collectionPath = DocCollection.getCollectionPath(testCollection);
int liveNodes = cluster.getJettySolrRunners().size();
CollectionAdminRequest.createCollection(testCollection, "conf", 2, 2)
@@ -1168,7 +1169,8 @@ public class CloudSolrClientTest extends SolrCloudTestCase {
DocCollection c = cluster.getZkStateReader().getCollection(testCollection);
c.forEachReplica((s, replica) -> assertNotNull(replica.getReplicaState()));
- PerReplicaStates prs = PerReplicaStates.fetch(collectionPath, cluster.getZkClient(), null);
+ PerReplicaStates prs =
+ PerReplicaStatesFetcher.fetch(collectionPath, cluster.getZkClient(), null);
assertEquals(4, prs.states.size());
JettySolrRunner jsr = null;
@@ -1178,12 +1180,12 @@ public class CloudSolrClientTest extends SolrCloudTestCase {
// Now let's do an add replica
CollectionAdminRequest.addReplicaToShard(testCollection, "shard1")
.process(cluster.getSolrClient());
- prs = PerReplicaStates.fetch(collectionPath, cluster.getZkClient(), null);
+ prs = PerReplicaStatesFetcher.fetch(collectionPath, cluster.getZkClient(), null);
assertEquals(5, prs.states.size());
// create a collection with PRS and v2 API
testCollection = "perReplicaState_testv2";
- collectionPath = ZkStateReader.getCollectionPath(testCollection);
+ collectionPath = DocCollection.getCollectionPath(testCollection);
new V2Request.Builder("/collections")
.withMethod(POST)
@@ -1194,7 +1196,7 @@ public class CloudSolrClientTest extends SolrCloudTestCase {
cluster.waitForActiveCollection(testCollection, 2, 4);
c = cluster.getZkStateReader().getCollection(testCollection);
c.forEachReplica((s, replica) -> assertNotNull(replica.getReplicaState()));
- prs = PerReplicaStates.fetch(collectionPath, cluster.getZkClient(), null);
+ prs = PerReplicaStatesFetcher.fetch(collectionPath, cluster.getZkClient(), null);
assertEquals(4, prs.states.size());
} finally {
if (jsr != null) {
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/HttpClusterStateSSLTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/HttpClusterStateSSLTest.java
index 1cff762641d..93e959d96b2 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/HttpClusterStateSSLTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/HttpClusterStateSSLTest.java
@@ -26,7 +26,6 @@ import org.apache.solr.cloud.SolrCloudTestCase;
import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.cloud.DocCollection;
import org.apache.solr.common.cloud.Replica;
-import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.common.util.Utils;
import org.apache.solr.util.RandomizeSSL;
import org.junit.BeforeClass;
@@ -69,7 +68,7 @@ public class HttpClusterStateSSLTest extends SolrCloudTestCase {
byte[] stateJsonBytes =
cluster
.getZkClient()
- .getData(ZkStateReader.getCollectionPath(collectionId), null, null, true);
+ .getData(DocCollection.getCollectionPath(collectionId), null, null, true);
assertNotNull(stateJsonBytes);
Map<String, Object> replicasMap =
(Map<String, Object>)
diff --git a/solr/solrj/src/test/org/apache/solr/common/cloud/PerReplicaStatesIntegrationTest.java b/solr/solrj/src/test/org/apache/solr/common/cloud/PerReplicaStatesIntegrationTest.java
index 393a10c77c2..8a4c36a92ee 100644
--- a/solr/solrj/src/test/org/apache/solr/common/cloud/PerReplicaStatesIntegrationTest.java
+++ b/solr/solrj/src/test/org/apache/solr/common/cloud/PerReplicaStatesIntegrationTest.java
@@ -18,7 +18,7 @@
package org.apache.solr.common.cloud;
import static org.apache.solr.client.solrj.SolrRequest.METHOD.POST;
-import static org.apache.solr.common.cloud.DocCollection.PER_REPLICA_STATE;
+import static org.apache.solr.common.params.CollectionAdminParams.PER_REPLICA_STATE;
import java.lang.invoke.MethodHandles;
import java.util.Collections;
@@ -70,16 +70,16 @@ public class PerReplicaStatesIntegrationTest extends SolrCloudTestCase {
DocCollection c = cluster.getZkStateReader().getCollection(testCollection);
c.forEachReplica((s, replica) -> assertNotNull(replica.getReplicaState()));
PerReplicaStates prs =
- PerReplicaStates.fetch(
- ZkStateReader.getCollectionPath(testCollection), cluster.getZkClient(), null);
+ PerReplicaStatesFetcher.fetch(
+ DocCollection.getCollectionPath(testCollection), cluster.getZkClient(), null);
assertEquals(4, prs.states.size());
JettySolrRunner jsr = cluster.startJettySolrRunner();
// Now let's do an add replica
CollectionAdminRequest.addReplicaToShard(testCollection, "shard1")
.process(cluster.getSolrClient());
prs =
- PerReplicaStates.fetch(
- ZkStateReader.getCollectionPath(testCollection), cluster.getZkClient(), null);
+ PerReplicaStatesFetcher.fetch(
+ DocCollection.getCollectionPath(testCollection), cluster.getZkClient(), null);
assertEquals(5, prs.states.size());
testCollection = "perReplicaState_testv2";
@@ -93,8 +93,8 @@ public class PerReplicaStatesIntegrationTest extends SolrCloudTestCase {
c = cluster.getZkStateReader().getCollection(testCollection);
c.forEachReplica((s, replica) -> assertNotNull(replica.getReplicaState()));
prs =
- PerReplicaStates.fetch(
- ZkStateReader.getCollectionPath(testCollection), cluster.getZkClient(), null);
+ PerReplicaStatesFetcher.fetch(
+ DocCollection.getCollectionPath(testCollection), cluster.getZkClient(), null);
assertEquals(4, prs.states.size());
} finally {
cluster.shutdown();
@@ -123,9 +123,10 @@ public class PerReplicaStatesIntegrationTest extends SolrCloudTestCase {
DocCollection c = cluster.getZkStateReader().getCollection(testCollection);
c.forEachReplica((s, replica) -> assertNotNull(replica.getReplicaState()));
- String collectionPath = ZkStateReader.getCollectionPath(testCollection);
+ String collectionPath = DocCollection.getCollectionPath(testCollection);
PerReplicaStates prs =
- PerReplicaStates.fetch(collectionPath, SolrCloudTestCase.cluster.getZkClient(), null);
+ PerReplicaStatesFetcher.fetch(
+ collectionPath, SolrCloudTestCase.cluster.getZkClient(), null);
assertEquals(1, prs.states.size());
JettySolrRunner jsr = cluster.startJettySolrRunner();
@@ -135,7 +136,9 @@ public class PerReplicaStatesIntegrationTest extends SolrCloudTestCase {
CollectionAdminRequest.addReplicaToShard(testCollection, "shard1")
.process(cluster.getSolrClient());
cluster.waitForActiveCollection(testCollection, 1, 2);
- prs = PerReplicaStates.fetch(collectionPath, SolrCloudTestCase.cluster.getZkClient(), null);
+ prs =
+ PerReplicaStatesFetcher.fetch(
+ collectionPath, SolrCloudTestCase.cluster.getZkClient(), null);
assertEquals(2, prs.states.size());
c = cluster.getZkStateReader().getCollection(testCollection);
prs.states.forEachEntry((s, state) -> assertEquals(Replica.State.ACTIVE, state.state));
@@ -160,12 +163,16 @@ public class PerReplicaStatesIntegrationTest extends SolrCloudTestCase {
if (log.isInfoEnabled()) {
log.info("after down node, state.json v: {}", c.getZNodeVersion());
}
- prs = PerReplicaStates.fetch(collectionPath, SolrCloudTestCase.cluster.getZkClient(), null);
+ prs =
+ PerReplicaStatesFetcher.fetch(
+ collectionPath, SolrCloudTestCase.cluster.getZkClient(), null);
PerReplicaStates.State st = prs.get(replicaName);
assertNotEquals(Replica.State.ACTIVE, st.state);
jsr.start();
cluster.waitForActiveCollection(testCollection, 1, 2);
- prs = PerReplicaStates.fetch(collectionPath, SolrCloudTestCase.cluster.getZkClient(), null);
+ prs =
+ PerReplicaStatesFetcher.fetch(
+ collectionPath, SolrCloudTestCase.cluster.getZkClient(), null);
prs.states.forEachEntry((s, state) -> assertEquals(Replica.State.ACTIVE, state.state));
}
@@ -197,8 +204,8 @@ public class PerReplicaStatesIntegrationTest extends SolrCloudTestCase {
PerReplicaStates prs1 =
original =
- PerReplicaStates.fetch(
- ZkStateReader.getCollectionPath(COLL), cluster.getZkClient(), null);
+ PerReplicaStatesFetcher.fetch(
+ DocCollection.getCollectionPath(COLL), cluster.getZkClient(), null);
log.info("prs1 : {}", prs1);
CollectionAdminRequest.modifyCollection(
@@ -224,8 +231,8 @@ public class PerReplicaStatesIntegrationTest extends SolrCloudTestCase {
(liveNodes, collectionState) -> {
AtomicBoolean anyFail = new AtomicBoolean(false);
PerReplicaStates prs2 =
- PerReplicaStates.fetch(
- ZkStateReader.getCollectionPath(COLL), cluster.getZkClient(), null);
+ PerReplicaStatesFetcher.fetch(
+ DocCollection.getCollectionPath(COLL), cluster.getZkClient(), null);
prs2.states.forEachEntry(
(r, newState) -> {
if (newState.getDuplicate() != null) anyFail.set(true);
@@ -237,8 +244,8 @@ public class PerReplicaStatesIntegrationTest extends SolrCloudTestCase {
System.out.println("prs1 : " + original);
System.out.println(
"prs2 : "
- + PerReplicaStates.fetch(
- ZkStateReader.getCollectionPath(COLL), cluster.getZkClient(), null));
+ + PerReplicaStatesFetcher.fetch(
+ DocCollection.getCollectionPath(COLL), cluster.getZkClient(), null));
cluster.shutdown();
}
}
diff --git a/solr/solrj/src/test/org/apache/solr/common/cloud/TestDocCollectionWatcher.java b/solr/solrj/src/test/org/apache/solr/common/cloud/TestDocCollectionWatcher.java
index b15cc36266b..03b4959df93 100644
--- a/solr/solrj/src/test/org/apache/solr/common/cloud/TestDocCollectionWatcher.java
+++ b/solr/solrj/src/test/org/apache/solr/common/cloud/TestDocCollectionWatcher.java
@@ -281,7 +281,8 @@ public class TestDocCollectionWatcher extends SolrCloudTestCase {
expectThrows(
TimeoutException.class,
() -> {
- client.waitForState("no-such-collection", 10, TimeUnit.MILLISECONDS, (c) -> (false));
+ ZkStateReader.from(client)
+ .waitForState("no-such-collection", 10, TimeUnit.MILLISECONDS, (c) -> (false));
});
waitFor(
diff --git a/solr/test-framework/build.gradle b/solr/test-framework/build.gradle
index 014024b3f5b..c9d5294ce8a 100644
--- a/solr/test-framework/build.gradle
+++ b/solr/test-framework/build.gradle
@@ -32,6 +32,7 @@ dependencies {
api project(':solr:core')
api project(':solr:solrj')
+ implementation project(':solr:solrj-zookeeper')
api 'org.apache.lucene:lucene-test-framework'
implementation 'org.apache.lucene:lucene-core'
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterStateUtil.java b/solr/test-framework/src/java/org/apache/solr/common/cloud/ClusterStateUtil.java
similarity index 100%
rename from solr/solrj/src/java/org/apache/solr/common/cloud/ClusterStateUtil.java
rename to solr/test-framework/src/java/org/apache/solr/common/cloud/ClusterStateUtil.java