This is an automated email from the ASF dual-hosted git repository.
houston pushed a commit to branch branch_9x
in repository https://gitbox.apache.org/repos/asf/solr.git
The following commit(s) were added to refs/heads/branch_9x by this push:
new 9cdf021874a SOLR-17098: Only use ZK ACLs for default ZK Host
9cdf021874a is described below
commit 9cdf021874a0957f67f140e7431f92e8aeb07eda
Author: Houston Putman <[email protected]>
AuthorDate: Tue Dec 5 14:35:25 2023 -0500
SOLR-17098: Only use ZK ACLs for default ZK Host
(cherry picked from commit e2bf1f434aad873fbb24c21d46ac00e888806d98)
---
solr/CHANGES.txt | 3 +
.../java/org/apache/solr/core/CoreContainer.java | 1 +
.../pages/stream-decorator-reference.adoc | 1 +
.../query-guide/pages/stream-source-reference.adoc | 3 +
.../solr/client/solrj/io/SolrClientCache.java | 45 +++++++++++--
.../solr/client/solrj/io/SolrClientCacheTest.java | 77 ++++++++++++++++++++++
.../solrj/impl/ZkClientClusterStateProvider.java | 11 +++-
.../org/apache/solr/common/cloud/SolrZkClient.java | 24 +++++--
.../apache/solr/common/cloud/ZkStateReader.java | 15 ++++-
.../client/solrj/impl/CloudHttp2SolrClient.java | 10 ++-
.../client/solrj/impl/CloudLegacySolrClient.java | 10 ++-
.../client/solrj/impl/ClusterStateProvider.java | 6 +-
solr/solrj/src/test-files/solrj/solr/solr.xml | 3 +
.../apache/solr/cloud/MiniSolrCloudCluster.java | 1 +
14 files changed, 190 insertions(+), 20 deletions(-)
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 3af76fde3b2..9879ab1c322 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -89,6 +89,9 @@ Bug Fixes
* SOLR-17060: CoreContainer#create may deadlock with concurrent requests for
metrics (Alex Deparvu, David Smiley)
+* SOLR-17098: ZK Credentials and ACLs are no longer sent to all ZK Servers
when using Streaming Expressions.
+ They will only be used when sent to the default ZK Host. (Houston Putman,
Jan Høydahl, David Smiley, Gus Heck, Qing Xu)
+
Dependency Upgrades
---------------------
* SOLR-17012: Update Apache Hadoop to 3.3.6 and Apache Curator to 5.5.0 (Kevin
Risden)
diff --git a/solr/core/src/java/org/apache/solr/core/CoreContainer.java
b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
index 2fa5e70fed6..52bcdd5a676 100644
--- a/solr/core/src/java/org/apache/solr/core/CoreContainer.java
+++ b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
@@ -831,6 +831,7 @@ public class CoreContainer {
zkSys.initZooKeeper(this, cfg.getCloudConfig());
if (isZooKeeperAware()) {
+ solrClientCache.setDefaultZKHost(getZkController().getZkServerAddress());
// initialize ZkClient metrics
zkSys.getZkMetricsProducer().initializeMetrics(solrMetricsContext,
"zkClient");
pkiAuthenticationSecurityBuilder =
diff --git
a/solr/solr-ref-guide/modules/query-guide/pages/stream-decorator-reference.adoc
b/solr/solr-ref-guide/modules/query-guide/pages/stream-decorator-reference.adoc
index 1c2d8afccdf..d5e25ba98fa 100644
---
a/solr/solr-ref-guide/modules/query-guide/pages/stream-decorator-reference.adoc
+++
b/solr/solr-ref-guide/modules/query-guide/pages/stream-decorator-reference.adoc
@@ -1187,6 +1187,7 @@ Worker collections can be empty collections that exist
only to execute streaming
* `StreamExpression`: Expression to send to the worker collection.
* `workers`: Number of workers in the worker collection to send the expression
to.
* `zkHost`: (Optional) The ZooKeeper connect string where the worker
collection resides.
+Zookeeper Credentials and ACLs will only be included if the same ZkHost is
used as the Solr instance that you are connecting to (the `chroot` can be
different).
* `sort`: The sort criteria for ordering tuples returned by the worker nodes.
=== parallel Syntax
diff --git
a/solr/solr-ref-guide/modules/query-guide/pages/stream-source-reference.adoc
b/solr/solr-ref-guide/modules/query-guide/pages/stream-source-reference.adoc
index 39352261a2f..a4213776f6b 100644
--- a/solr/solr-ref-guide/modules/query-guide/pages/stream-source-reference.adoc
+++ b/solr/solr-ref-guide/modules/query-guide/pages/stream-source-reference.adoc
@@ -36,6 +36,7 @@ To read more about the `/export` handler requirements review
the section xref:ex
* `fl`: (Mandatory) The list of fields to return.
* `sort`: (Mandatory) The sort criteria.
* `zkHost`: Only needs to be defined if the collection being searched is found
in a different zkHost than the local stream handler.
+Zookeeper Credentials and ACLs will only be included if the same ZkHost is
used as the Solr instance that you are connecting to (the `chroot` can be
different).
* `qt`: Specifies the query type, or request handler, to use.
Set this to `/export` to work with large result sets.
The default is `/select`.
@@ -484,6 +485,7 @@ When used in parallel mode the partitionKeys parameter must
be provided.
* `fl`: (Mandatory) The list of fields to return.
* `sort`: (Mandatory) The sort criteria.
* `zkHost`: Only needs to be defined if the collection being searched is found
in a different zkHost than the local stream handler.
+Zookeeper Credentials and ACLs will only be included if the same ZkHost is
used as the Solr instance that you are connecting to (the `chroot` can be
different).
* `partitionKeys`: Comma delimited list of keys to partition the search
results by.
To be used with the parallel function for parallelizing operations across
worker nodes.
See the xref:stream-decorator-reference.adoc#parallel[parallel] function for
details.
@@ -648,6 +650,7 @@ The checkpoints will be saved under this id.
If not set, it defaults to the highest version in the index.
Setting to 0 will process all records that match query in the index.
* `zkHost`: (Optional) Only needs to be defined if the collection being
searched is found in a different zkHost than the local stream handler.
+Zookeeper Credentials and ACLs will only be included if the same ZkHost is
used as the Solr instance that you are connecting to (the `chroot` can be
different).
=== topic Syntax
diff --git
a/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/SolrClientCache.java
b/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/SolrClientCache.java
index e56d1a55c13..915d9fbafc7 100644
---
a/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/SolrClientCache.java
+++
b/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/SolrClientCache.java
@@ -25,6 +25,7 @@ import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
import org.apache.http.client.HttpClient;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.impl.CloudHttp2SolrClient;
@@ -57,6 +58,7 @@ public class SolrClientCache implements Closeable {
private final HttpClient apacheHttpClient;
private final Http2SolrClient http2SolrClient;
private final AtomicBoolean isClosed = new AtomicBoolean(false);
+ private final AtomicReference<String> defaultZkHost = new
AtomicReference<>();
public SolrClientCache() {
this.apacheHttpClient = null;
@@ -74,40 +76,71 @@ public class SolrClientCache implements Closeable {
this.http2SolrClient = http2SolrClient;
}
+ public void setDefaultZKHost(String zkHost) {
+ if (zkHost != null) {
+ zkHost = zkHost.split("/")[0];
+ if (!zkHost.isEmpty()) {
+ defaultZkHost.set(zkHost);
+ } else {
+ defaultZkHost.set(null);
+ }
+ }
+ }
+
public synchronized CloudSolrClient getCloudSolrClient(String zkHost) {
ensureOpen();
Objects.requireNonNull(zkHost, "ZooKeeper host cannot be null!");
if (solrClients.containsKey(zkHost)) {
return (CloudSolrClient) solrClients.get(zkHost);
}
+ // Can only use ZK ACLs if there is a default ZK Host, and the given ZK
host contains that
+ // default.
+ // Basically the ZK ACLs are assumed to be only used for the default ZK
host,
+ // thus we should only provide the ACLs to that Zookeeper instance.
+ String zkHostNoChroot = zkHost.split("/")[0];
+ boolean canUseACLs =
+
Optional.ofNullable(defaultZkHost.get()).map(zkHostNoChroot::equals).orElse(false);
final CloudSolrClient client;
if (apacheHttpClient != null) {
- client = newCloudLegacySolrClient(zkHost, apacheHttpClient);
+ client = newCloudLegacySolrClient(zkHost, apacheHttpClient, canUseACLs);
} else {
- client = newCloudHttp2SolrClient(zkHost, http2SolrClient);
+ client = newCloudHttp2SolrClient(zkHost, http2SolrClient, canUseACLs);
}
solrClients.put(zkHost, client);
return client;
}
@Deprecated
- private static CloudSolrClient newCloudLegacySolrClient(String zkHost,
HttpClient httpClient) {
+ private static CloudSolrClient newCloudLegacySolrClient(
+ String zkHost, HttpClient httpClient, boolean canUseACLs) {
final List<String> hosts = List.of(zkHost);
var builder = new CloudLegacySolrClient.Builder(hosts, Optional.empty());
+ builder.canUseZkACLs(canUseACLs);
adjustTimeouts(builder, httpClient);
var client = builder.build();
- client.connect();
+ try {
+ client.connect();
+ } catch (Exception e) {
+ IOUtils.closeQuietly(client);
+ throw e;
+ }
return client;
}
private static CloudHttp2SolrClient newCloudHttp2SolrClient(
- String zkHost, Http2SolrClient http2SolrClient) {
+ String zkHost, Http2SolrClient http2SolrClient, boolean canUseACLs) {
final List<String> hosts = List.of(zkHost);
var builder = new CloudHttp2SolrClient.Builder(hosts, Optional.empty());
+ builder.canUseZkACLs(canUseACLs);
// using internal builder to ensure the internal client gets closed
builder =
builder.withInternalClientBuilder(newHttp2SolrClientBuilder(null,
http2SolrClient));
var client = builder.build();
- client.connect();
+ try {
+ client.connect();
+ } catch (Exception e) {
+ IOUtils.closeQuietly(client);
+ throw e;
+ }
return client;
}
diff --git
a/solr/solrj-streaming/src/test/org/apache/solr/client/solrj/io/SolrClientCacheTest.java
b/solr/solrj-streaming/src/test/org/apache/solr/client/solrj/io/SolrClientCacheTest.java
new file mode 100644
index 00000000000..1f7ee0cffbf
--- /dev/null
+++
b/solr/solrj-streaming/src/test/org/apache/solr/client/solrj/io/SolrClientCacheTest.java
@@ -0,0 +1,77 @@
+/*
+ * 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.client.solrj.io;
+
+import java.util.Map;
+import org.apache.solr.cloud.SolrCloudTestCase;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.cloud.DigestZkACLProvider;
+import org.apache.solr.common.cloud.DigestZkCredentialsProvider;
+import org.apache.solr.common.cloud.SolrZkClient;
+import org.apache.solr.common.cloud.VMParamsZkCredentialsInjector;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class SolrClientCacheTest extends SolrCloudTestCase {
+
+ private static final Map<String, String> sysProps =
+ Map.of(
+ SolrZkClient.ZK_CREDENTIALS_INJECTOR_CLASS_NAME_VM_PARAM_NAME,
+ VMParamsZkCredentialsInjector.class.getName(),
+ SolrZkClient.ZK_CRED_PROVIDER_CLASS_NAME_VM_PARAM_NAME,
+ DigestZkCredentialsProvider.class.getName(),
+ SolrZkClient.ZK_ACL_PROVIDER_CLASS_NAME_VM_PARAM_NAME,
+ DigestZkACLProvider.class.getName(),
+ VMParamsZkCredentialsInjector.DEFAULT_DIGEST_USERNAME_VM_PARAM_NAME,
"admin-user",
+ VMParamsZkCredentialsInjector.DEFAULT_DIGEST_PASSWORD_VM_PARAM_NAME,
"pass",
+
VMParamsZkCredentialsInjector.DEFAULT_DIGEST_READONLY_USERNAME_VM_PARAM_NAME,
"read-user",
+
VMParamsZkCredentialsInjector.DEFAULT_DIGEST_READONLY_PASSWORD_VM_PARAM_NAME,
"pass");
+
+ @BeforeClass
+ public static void before() throws Exception {
+ sysProps.forEach(System::setProperty);
+ configureCluster(1)
+ .formatZkServer(true)
+ .addConfig("config",
getFile("solrj/solr/configsets/streaming/conf").toPath())
+ .configure();
+ }
+
+ @AfterClass
+ public static void after() {
+ sysProps.keySet().forEach(System::clearProperty);
+ }
+
+ @Test
+ public void testZkACLsNotUsedWithDifferentZkHost() {
+ try (SolrClientCache cache = new SolrClientCache()) {
+ // This ZK Host is fake, thus the ZK ACLs should not be used
+ cache.setDefaultZKHost("test:2181");
+ expectThrows(
+ SolrException.class, () ->
cache.getCloudSolrClient(zkClient().getZkServerAddress()));
+ }
+ }
+
+ @Test
+ public void testZkACLsUsedWithDifferentChroot() {
+ try (SolrClientCache cache = new SolrClientCache()) {
+ // The same ZK Host is used, so the ZK ACLs should still be applied
+ cache.setDefaultZKHost(zkClient().getZkServerAddress() +
"/random/chroot");
+ cache.getCloudSolrClient(zkClient().getZkServerAddress());
+ }
+ }
+}
diff --git
a/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/ZkClientClusterStateProvider.java
b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/ZkClientClusterStateProvider.java
index 075c1e4d3de..36c5891da1e 100644
---
a/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/ZkClientClusterStateProvider.java
+++
b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/ZkClientClusterStateProvider.java
@@ -48,6 +48,7 @@ public class ZkClientClusterStateProvider
volatile ZkStateReader zkStateReader;
private boolean closeZkStateReader = true;
private final String zkHost;
+ private final boolean canUseZkACLs;
private int zkConnectTimeout =
SolrZkClientTimeout.DEFAULT_ZK_CONNECT_TIMEOUT;
private int zkClientTimeout = SolrZkClientTimeout.DEFAULT_ZK_CLIENT_TIMEOUT;
@@ -65,14 +66,22 @@ public class ZkClientClusterStateProvider
this.zkStateReader = zkStateReader;
this.closeZkStateReader = false;
this.zkHost = null;
+ this.canUseZkACLs = true;
}
public ZkClientClusterStateProvider(Collection<String> zkHosts, String
chroot) {
+ this(zkHosts, chroot, true);
+ }
+
+ public ZkClientClusterStateProvider(
+ Collection<String> zkHosts, String chroot, boolean canUseZkACLs) {
zkHost = buildZkHostString(zkHosts, chroot);
+ this.canUseZkACLs = canUseZkACLs;
}
public ZkClientClusterStateProvider(String zkHost) {
this.zkHost = zkHost;
+ this.canUseZkACLs = true;
}
/**
@@ -212,7 +221,7 @@ public class ZkClientClusterStateProvider
if (zkStateReader == null) {
ZkStateReader zk = null;
try {
- zk = new ZkStateReader(zkHost, zkClientTimeout, zkConnectTimeout);
+ zk = new ZkStateReader(zkHost, zkClientTimeout, zkConnectTimeout,
canUseZkACLs);
zk.createClusterStateWatchersAndUpdate();
log.info("Cluster at {} ready", zkHost);
zkStateReader = zk;
diff --git
a/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/SolrZkClient.java
b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/SolrZkClient.java
index ddbd70d375f..4ae9d16f123 100644
---
a/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/SolrZkClient.java
+++
b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/SolrZkClient.java
@@ -118,7 +118,8 @@ public class SolrZkClient implements Closeable {
builder.zkACLProvider,
builder.higherLevelIsClosed,
builder.compressor,
- builder.solrClassLoader);
+ builder.solrClassLoader,
+ builder.useDefaultCredsAndACLs);
}
private SolrZkClient(
@@ -131,7 +132,8 @@ public class SolrZkClient implements Closeable {
ZkACLProvider zkACLProvider,
IsClosed higherLevelIsClosed,
Compressor compressor,
- SolrClassLoader solrClassLoader) {
+ SolrClassLoader solrClassLoader,
+ boolean useDefaultCredsAndACLs) {
if (zkServerAddress == null) {
// only tests should create one without server address
@@ -148,9 +150,14 @@ public class SolrZkClient implements Closeable {
this.solrClassLoader = solrClassLoader;
if (!strat.hasZkCredentialsToAddAutomatically()) {
- zkCredentialsInjector = createZkCredentialsInjector();
+ zkCredentialsInjector =
+ useDefaultCredsAndACLs
+ ? createZkCredentialsInjector()
+ : new DefaultZkCredentialsInjector();
ZkCredentialsProvider zkCredentialsToAddAutomatically =
- createZkCredentialsToAddAutomatically();
+ useDefaultCredsAndACLs
+ ? createZkCredentialsToAddAutomatically()
+ : new DefaultZkCredentialsProvider();
strat.setZkCredentialsToAddAutomatically(zkCredentialsToAddAutomatically);
}
@@ -210,7 +217,8 @@ public class SolrZkClient implements Closeable {
}
assert ObjectReleaseTracker.track(this);
if (zkACLProvider == null) {
- this.zkACLProvider = createZkACLProvider();
+ this.zkACLProvider =
+ useDefaultCredsAndACLs ? createZkACLProvider() : new
DefaultZkACLProvider();
} else {
this.zkACLProvider = zkACLProvider;
}
@@ -1134,6 +1142,7 @@ public class SolrZkClient implements Closeable {
public ZkACLProvider zkACLProvider;
public IsClosed higherLevelIsClosed;
public SolrClassLoader solrClassLoader;
+ public boolean useDefaultCredsAndACLs = true;
public Compressor compressor;
@@ -1199,6 +1208,11 @@ public class SolrZkClient implements Closeable {
return this;
}
+ public Builder withUseDefaultCredsAndACLs(boolean useDefaultCredsAndACLs) {
+ this.useDefaultCredsAndACLs = useDefaultCredsAndACLs;
+ return this;
+ }
+
public SolrZkClient build() {
return new SolrZkClient(this);
}
diff --git
a/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkStateReader.java
b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkStateReader.java
index d6904d5bfcd..faaa44bed94 100644
---
a/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkStateReader.java
+++
b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/ZkStateReader.java
@@ -403,11 +403,20 @@ public class ZkStateReader implements SolrCloseable {
}
public ZkStateReader(String zkServerAddress, int zkClientTimeout, int
zkClientConnectTimeout) {
- this.zkClient =
+ this(zkServerAddress, zkClientTimeout, zkClientConnectTimeout, true);
+ }
+
+ public ZkStateReader(
+ String zkServerAddress,
+ int zkClientTimeout,
+ int zkClientConnectTimeout,
+ boolean canUseZkACLs) {
+ SolrZkClient.Builder builder =
new SolrZkClient.Builder()
.withUrl(zkServerAddress)
.withTimeout(zkClientTimeout, TimeUnit.MILLISECONDS)
.withConnTimeOut(zkClientConnectTimeout, TimeUnit.MILLISECONDS)
+ .withUseDefaultCredsAndACLs(canUseZkACLs)
.withReconnectListener(
() -> {
// on reconnect, reload cloud info
@@ -423,8 +432,8 @@ public class ZkStateReader implements SolrCloseable {
log.error("Interrupted", e);
throw new ZooKeeperException(ErrorCode.SERVER_ERROR,
"Interrupted", e);
}
- })
- .build();
+ });
+ this.zkClient = builder.build();
this.closeClient = true;
this.securityNodeWatcher = null;
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 7fea327d005..1af1110e5fd 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
@@ -138,6 +138,7 @@ public class CloudHttp2SolrClient extends CloudSolrClient {
private int parallelCacheRefreshesLocks = 3;
private int zkConnectTimeout =
SolrZkClientTimeout.DEFAULT_ZK_CONNECT_TIMEOUT;
private int zkClientTimeout =
SolrZkClientTimeout.DEFAULT_ZK_CLIENT_TIMEOUT;
+ private boolean canUseZkACLs = true;
/**
* Provide a series of Solr URLs to be used when configuring {@link
CloudHttp2SolrClient}
@@ -189,6 +190,12 @@ public class CloudHttp2SolrClient extends CloudSolrClient {
if (zkChroot.isPresent()) this.zkChroot = zkChroot.get();
}
+ /** Whether or not to use the default ZK ACLs when building a ZK Client. */
+ public Builder canUseZkACLs(boolean canUseZkACLs) {
+ this.canUseZkACLs = canUseZkACLs;
+ return this;
+ }
+
/**
* Tells {@link Builder} that created clients should be configured such
that {@link
* CloudSolrClient#isUpdatesToLeaders} returns <code>true</code>.
@@ -406,7 +413,8 @@ public class CloudHttp2SolrClient extends CloudSolrClient {
throw new IllegalArgumentException(
"Both zkHost(s) & solrUrl(s) have been specified. Only specify
one.");
} else if (!zkHosts.isEmpty()) {
- stateProvider =
ClusterStateProvider.newZkClusterStateProvider(zkHosts, zkChroot);
+ stateProvider =
+ ClusterStateProvider.newZkClusterStateProvider(zkHosts,
zkChroot, canUseZkACLs);
if (stateProvider instanceof SolrZkClientTimeoutAware) {
var timeoutAware = (SolrZkClientTimeoutAware) stateProvider;
timeoutAware.setZkClientTimeout(zkClientTimeout);
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 3547c652293..e1f3840cfbd 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
@@ -172,6 +172,7 @@ public class CloudLegacySolrClient extends CloudSolrClient {
protected ClusterStateProvider stateProvider;
private int zkConnectTimeout =
SolrZkClientTimeout.DEFAULT_ZK_CONNECT_TIMEOUT;
private int zkClientTimeout =
SolrZkClientTimeout.DEFAULT_ZK_CLIENT_TIMEOUT;
+ private boolean canUseZkACLs = true;
/** Constructor for use by subclasses. This constructor was public prior
to version 9.0 */
protected Builder() {}
@@ -231,6 +232,12 @@ public class CloudLegacySolrClient extends CloudSolrClient
{
if (zkChroot.isPresent()) this.zkChroot = zkChroot.get();
}
+ /** Whether or not to use the default ZK ACLs when building a ZK Client. */
+ public Builder canUseZkACLs(boolean canUseZkACLs) {
+ this.canUseZkACLs = canUseZkACLs;
+ return this;
+ }
+
/** Provides a {@link HttpClient} for the builder to use when creating
clients. */
public Builder withLBHttpSolrClientBuilder(LBHttpSolrClient.Builder
lbHttpSolrClientBuilder) {
this.lbClientBuilder = lbHttpSolrClientBuilder;
@@ -371,7 +378,8 @@ public class CloudLegacySolrClient extends CloudSolrClient {
throw new IllegalArgumentException(
"Both zkHost(s) & solrUrl(s) have been specified. Only specify
one.");
} else if (!zkHosts.isEmpty()) {
- this.stateProvider =
ClusterStateProvider.newZkClusterStateProvider(zkHosts, zkChroot);
+ this.stateProvider =
+ ClusterStateProvider.newZkClusterStateProvider(zkHosts,
zkChroot, canUseZkACLs);
if (stateProvider instanceof SolrZkClientTimeoutAware) {
var timeoutAware = (SolrZkClientTimeoutAware) stateProvider;
timeoutAware.setZkClientTimeout(zkClientTimeout);
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 9673f08e48d..e6b7f2097a4 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
@@ -31,14 +31,14 @@ import org.apache.solr.common.params.CollectionAdminParams;
public interface ClusterStateProvider extends SolrCloseable {
static ClusterStateProvider newZkClusterStateProvider(
- Collection<String> zkHosts, String zkChroot) {
+ Collection<String> zkHosts, String zkChroot, boolean canUseZkACLs) {
// 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);
+ .getConstructor(Collection.class, String.class, Boolean.TYPE);
+ return constructor.newInstance(zkHosts, zkChroot, canUseZkACLs);
} catch (InvocationTargetException e) {
if (e.getCause() instanceof RuntimeException) {
throw (RuntimeException) e.getCause();
diff --git a/solr/solrj/src/test-files/solrj/solr/solr.xml
b/solr/solrj/src/test-files/solrj/solr/solr.xml
index 76d992170f1..528240ae8c7 100644
--- a/solr/solrj/src/test-files/solrj/solr/solr.xml
+++ b/solr/solrj/src/test-files/solrj/solr/solr.xml
@@ -42,6 +42,9 @@
<int name="leaderVoteWait">0</int>
<int
name="distribUpdateConnTimeout">${distribUpdateConnTimeout:45000}</int>
<int name="distribUpdateSoTimeout">${distribUpdateSoTimeout:340000}</int>
+ <str
name="zkCredentialsProvider">${zkCredentialsProvider:org.apache.solr.common.cloud.DefaultZkCredentialsProvider}</str>
+ <str
name="zkACLProvider">${zkACLProvider:org.apache.solr.common.cloud.DefaultZkACLProvider}</str>
+ <str
name="zkCredentialsInjector">${zkCredentialsInjector:org.apache.solr.common.cloud.DefaultZkCredentialsInjector}</str>
</solrcloud>
</solr>
diff --git
a/solr/test-framework/src/java/org/apache/solr/cloud/MiniSolrCloudCluster.java
b/solr/test-framework/src/java/org/apache/solr/cloud/MiniSolrCloudCluster.java
index 95cc12ae34a..6995df5dddd 100644
---
a/solr/test-framework/src/java/org/apache/solr/cloud/MiniSolrCloudCluster.java
+++
b/solr/test-framework/src/java/org/apache/solr/cloud/MiniSolrCloudCluster.java
@@ -130,6 +130,7 @@ public class MiniSolrCloudCluster {
+ " <int name=\"leaderVoteWait\">${leaderVoteWait:10000}</int>\n"
+ " <int
name=\"distribUpdateConnTimeout\">${distribUpdateConnTimeout:45000}</int>\n"
+ " <int
name=\"distribUpdateSoTimeout\">${distribUpdateSoTimeout:340000}</int>\n"
+ + " <str
name=\"zkCredentialsInjector\">${zkCredentialsInjector:org.apache.solr.common.cloud.DefaultZkCredentialsInjector}</str>
\n"
+ " <str
name=\"zkCredentialsProvider\">${zkCredentialsProvider:org.apache.solr.common.cloud.DefaultZkCredentialsProvider}</str>
\n"
+ " <str
name=\"zkACLProvider\">${zkACLProvider:org.apache.solr.common.cloud.DefaultZkACLProvider}</str>
\n"
+ " <str
name=\"pkiHandlerPrivateKeyPath\">${pkiHandlerPrivateKeyPath:"