SOLR-11629: Add new CloudSolrClient.Builder ctors

CloudSolrClient.Builder can be pointed at a Solr cluster in two ways: a
ZK connection string, or one or more Solr base URLs.  One of these two
values must be provided to create a working CloudSolrClient.

Since these values are required, this commit introduces two new ctors,
one for each means of CloudSolrClient setup.  It deprecates the existing
no-arg CloudSolrClient ctor.

Together, these changes make it clearer to our users that these options
are required (and mutually exclusive).
This commit is contained in:
Jason Gerlowski 2018-03-10 09:30:57 -05:00
parent 2eeed51cdf
commit 971bd26df6
25 changed files with 248 additions and 146 deletions

View File

@ -295,6 +295,8 @@ Optimizations
Other Changes
----------------------
* SOLR-11629: Add more intuitive CloudSolrClient.Builder constructors (Varun Thacker, Jason Gerlowski)
* SOLR-11575: Improve ref-guide solrj snippets via mock 'print()' method (Jason Gerlowski via hossman)
* SOLR-11757: In tests, fix race condition on SolrException.ignoreException.

View File

@ -21,6 +21,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.Callable;
@ -83,9 +84,7 @@ public class AnalyticsShardRequestManager {
*/
public void sendRequests(String collection, String zkHost) throws IOException {
this.replicaUrls = new ArrayList<>();
this.cloudSolrClient = new Builder()
.withZkHost(zkHost)
.build();
this.cloudSolrClient = new Builder(Collections.singletonList(zkHost), Optional.empty()).build();
try {
this.cloudSolrClient.connect();
pickShards(collection);

View File

@ -38,6 +38,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
@ -56,7 +57,6 @@ import org.apache.solr.client.solrj.impl.CloudSolrClient;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.impl.HttpSolrClient.Builder;
import org.apache.solr.client.solrj.impl.SolrClientCloudManager;
import org.apache.solr.client.solrj.impl.ZkClientClusterStateProvider;
import org.apache.solr.client.solrj.request.CoreAdminRequest.WaitForState;
import org.apache.solr.client.solrj.cloud.autoscaling.TriggerEventType;
import org.apache.solr.cloud.overseer.OverseerAction;
@ -614,9 +614,7 @@ public class ZkController {
if (cloudManager != null) {
return cloudManager;
}
cloudSolrClient = new CloudSolrClient.Builder()
.withClusterStateProvider(new ZkClientClusterStateProvider(zkStateReader))
.build();
cloudSolrClient = new CloudSolrClient.Builder(Collections.singletonList(zkServerAddress), Optional.empty()).build();
cloudManager = new SolrClientCloudManager(new ZkDistributedQueueFactory(zkClient), cloudSolrClient);
}
return cloudManager;

View File

@ -32,6 +32,7 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
@ -90,7 +91,7 @@ public class SolrSnapshotsTool implements Closeable {
private final CloudSolrClient solrClient;
public SolrSnapshotsTool(String solrZkEnsemble) {
solrClient = (new CloudSolrClient.Builder()).withZkHost(solrZkEnsemble).build();
solrClient = new CloudSolrClient.Builder(Collections.singletonList(solrZkEnsemble), Optional.empty()).build();
}
@Override

View File

@ -20,9 +20,11 @@ import java.io.Closeable;
import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
@ -90,8 +92,7 @@ class CdcrReplicatorManager implements CdcrStateManager.CdcrStateObserver {
String zkHost = params.get(CdcrParams.ZK_HOST_PARAM);
String targetCollection = params.get(CdcrParams.TARGET_COLLECTION_PARAM);
CloudSolrClient client = new Builder()
.withZkHost(zkHost)
CloudSolrClient client = new Builder(Collections.singletonList(zkHost), Optional.empty())
.sendUpdatesOnlyToShardLeaders()
.build();
client.setDefaultCollection(targetCollection);

View File

@ -18,9 +18,11 @@ package org.apache.solr.handler.admin;
import java.lang.invoke.MethodHandles;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import org.apache.solr.api.Api;
import org.apache.solr.api.ApiBag;
@ -123,8 +125,7 @@ public class AutoscalingHistoryHandler extends RequestHandlerBase implements Per
}
}
}
try (CloudSolrClient cloudSolrClient = new CloudSolrClient.Builder()
.withZkHost(coreContainer.getZkController().getZkServerAddress())
try (CloudSolrClient cloudSolrClient = new CloudSolrClient.Builder(Collections.singletonList(coreContainer.getZkController().getZkServerAddress()), Optional.empty())
.withHttpClient(coreContainer.getUpdateShardHandler().getHttpClient())
.build()) {
QueryResponse qr = cloudSolrClient.query(collection, params);

View File

@ -16,8 +16,18 @@
*/
package org.apache.solr.handler.sql;
import com.google.common.collect.ImmutableMap;
import org.apache.calcite.rel.type.*;
import java.io.IOException;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.rel.type.RelDataTypeImpl;
import org.apache.calcite.rel.type.RelDataTypeSystem;
import org.apache.calcite.rel.type.RelProtoDataType;
import org.apache.calcite.schema.Table;
import org.apache.calcite.schema.impl.AbstractSchema;
import org.apache.calcite.sql.type.SqlTypeFactoryImpl;
@ -30,10 +40,7 @@ import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.common.luke.FieldFlag;
import java.io.IOException;
import java.util.EnumSet;
import java.util.Map;
import java.util.Properties;
import com.google.common.collect.ImmutableMap;
class SolrSchema extends AbstractSchema {
final Properties properties;
@ -46,7 +53,7 @@ class SolrSchema extends AbstractSchema {
@Override
protected Map<String, Table> getTableMap() {
String zk = this.properties.getProperty("zk");
try(CloudSolrClient cloudSolrClient = new CloudSolrClient.Builder().withZkHost(zk).build()) {
try(CloudSolrClient cloudSolrClient = new CloudSolrClient.Builder(Collections.singletonList(zk), Optional.empty()).build()) {
cloudSolrClient.connect();
ZkStateReader zkStateReader = cloudSolrClient.getZkStateReader();
ClusterState clusterState = zkStateReader.getClusterState();
@ -70,7 +77,7 @@ class SolrSchema extends AbstractSchema {
private Map<String, LukeResponse.FieldInfo> getFieldInfo(String collection) {
String zk = this.properties.getProperty("zk");
try(CloudSolrClient cloudSolrClient = new CloudSolrClient.Builder().withZkHost(zk).build()) {
try(CloudSolrClient cloudSolrClient = new CloudSolrClient.Builder(Collections.singletonList(zk), Optional.empty()).build()) {
cloudSolrClient.connect();
LukeRequest lukeRequest = new LukeRequest();
lukeRequest.setNumTerms(0);

View File

@ -16,12 +16,7 @@
*/
package org.apache.solr.util;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.apache.solr.common.SolrException.ErrorCode.FORBIDDEN;
import static org.apache.solr.common.SolrException.ErrorCode.UNAUTHORIZED;
import static org.apache.solr.common.params.CommonParams.DISTRIB;
import static org.apache.solr.common.params.CommonParams.NAME;
import javax.net.ssl.SSLPeerUnverifiedException;
import java.io.Console;
import java.io.File;
import java.io.FileNotFoundException;
@ -45,6 +40,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedHashMap;
@ -62,8 +58,6 @@ import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import javax.net.ssl.SSLPeerUnverifiedException;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.HelpFormatter;
@ -131,6 +125,12 @@ import org.noggit.ObjectBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.apache.solr.common.SolrException.ErrorCode.FORBIDDEN;
import static org.apache.solr.common.SolrException.ErrorCode.UNAUTHORIZED;
import static org.apache.solr.common.params.CommonParams.DISTRIB;
import static org.apache.solr.common.params.CommonParams.NAME;
/**
* Command-line utility for working with Solr.
*/
@ -206,7 +206,7 @@ public class SolrCLI {
String zkHost = cli.getOptionValue("zkHost", ZK_HOST);
log.debug("Connecting to Solr cluster: " + zkHost);
try (CloudSolrClient cloudSolrClient = new CloudSolrClient.Builder().withZkHost(zkHost).build()) {
try (CloudSolrClient cloudSolrClient = new CloudSolrClient.Builder(Collections.singletonList(zkHost), Optional.empty()).build()) {
String collection = cli.getOptionValue("collection");
if (collection != null)
@ -1375,7 +1375,7 @@ public class SolrCLI {
if (zkHost == null)
throw new IllegalStateException("Must provide either the '-solrUrl' or '-zkHost' parameters!");
try (CloudSolrClient cloudSolrClient = new CloudSolrClient.Builder().withZkHost(zkHost).build()) {
try (CloudSolrClient cloudSolrClient = new CloudSolrClient.Builder(Collections.singletonList(zkHost), Optional.empty()).build()) {
cloudSolrClient.connect();
Set<String> liveNodes = cloudSolrClient.getZkStateReader().getClusterState().getLiveNodes();
if (liveNodes.isEmpty())
@ -1501,7 +1501,7 @@ public class SolrCLI {
"create_collection can only be used when running in SolrCloud mode.\n");
}
try (CloudSolrClient cloudSolrClient = new CloudSolrClient.Builder().withZkHost(zkHost).build()) {
try (CloudSolrClient cloudSolrClient = new CloudSolrClient.Builder(Collections.singletonList(zkHost), Optional.empty()).build()) {
echoIfVerbose("\nConnecting to ZooKeeper at " + zkHost+" ...", cli);
cloudSolrClient.connect();
runCloudTool(cloudSolrClient, cli);
@ -2380,7 +2380,7 @@ public class SolrCLI {
protected void deleteCollection(CommandLine cli) throws Exception {
String zkHost = getZkHost(cli);
try (CloudSolrClient cloudSolrClient = new CloudSolrClient.Builder().withZkHost(zkHost).build()) {
try (CloudSolrClient cloudSolrClient = new CloudSolrClient.Builder(Collections.singletonList(zkHost), Optional.empty()).build()) {
echoIfVerbose("Connecting to ZooKeeper at " + zkHost, cli);
cloudSolrClient.connect();
deleteCollection(cloudSolrClient, cli);
@ -2984,8 +2984,7 @@ public class SolrCLI {
protected void waitToSeeLiveNodes(int maxWaitSecs, String zkHost, int numNodes) {
CloudSolrClient cloudClient = null;
try {
cloudClient = new CloudSolrClient.Builder()
.withZkHost(zkHost)
cloudClient = new CloudSolrClient.Builder(Collections.singletonList(zkHost), Optional.empty())
.build();
cloudClient.connect();
Set<String> liveNodes = cloudClient.getZkStateReader().getClusterState().getLiveNodes();

View File

@ -22,10 +22,12 @@ import java.lang.invoke.MethodHandles;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@ -101,8 +103,7 @@ public class HttpPartitionTest extends AbstractFullDistribZkTestBase {
*/
@Override
protected CloudSolrClient createCloudClient(String defaultCollection) {
CloudSolrClient client = new CloudSolrClient.Builder()
.withZkHost(zkServer.getZkAddress())
CloudSolrClient client = new CloudSolrClient.Builder(Collections.singletonList(zkServer.getZkAddress()), Optional.empty())
.sendDirectUpdatesToAnyShardReplica()
.withConnectionTimeout(30000)
.withSocketTimeout(60000)

View File

@ -23,6 +23,7 @@ import static org.mockito.Mockito.when;
import com.codahale.metrics.Snapshot;
import com.codahale.metrics.Timer;
import java.io.File;
import java.io.IOException;
import java.lang.invoke.MethodHandles;
@ -34,6 +35,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@ -46,7 +48,6 @@ import org.apache.solr.client.solrj.cloud.DistributedQueue;
import org.apache.solr.client.solrj.cloud.autoscaling.SolrCloudManager;
import org.apache.solr.client.solrj.impl.CloudSolrClient;
import org.apache.solr.client.solrj.impl.SolrClientCloudManager;
import org.apache.solr.client.solrj.impl.ZkClientClusterStateProvider;
import org.apache.solr.cloud.overseer.NodeMutator;
import org.apache.solr.cloud.overseer.OverseerAction;
import org.apache.solr.cloud.overseer.ZkWriteCommand;
@ -687,7 +688,7 @@ public class OverseerTest extends SolrTestCaseJ4 {
updateShardHandlers.add(updateShardHandler);
HttpShardHandlerFactory httpShardHandlerFactory = new HttpShardHandlerFactory();
httpShardHandlerFactorys.add(httpShardHandlerFactory);
MockZkController mockZkController = createMockZkController(zkClient, reader);
MockZkController mockZkController = createMockZkController(server.getZkAddress(), zkClient, reader);
Overseer overseer = new Overseer(httpShardHandlerFactory.getShardHandler(), updateShardHandler, "/admin/cores", reader, mockZkController,
new CloudConfig.CloudConfigBuilder("127.0.0.1", 8983, "").build());
overseers.add(overseer);
@ -1313,7 +1314,7 @@ public class OverseerTest extends SolrTestCaseJ4 {
HttpShardHandlerFactory httpShardHandlerFactory = new HttpShardHandlerFactory();
httpShardHandlerFactorys.add(httpShardHandlerFactory);
MockZkController zkController = createMockZkController(zkClient, reader);
MockZkController zkController = createMockZkController(address, zkClient, reader);
Overseer overseer = new Overseer(httpShardHandlerFactory.getShardHandler(), updateShardHandler, "/admin/cores", reader, zkController,
new CloudConfig.CloudConfigBuilder("127.0.0.1", 8983, "").build());
@ -1325,7 +1326,7 @@ public class OverseerTest extends SolrTestCaseJ4 {
return zkClient;
}
private MockZkController createMockZkController(SolrZkClient zkClient, ZkStateReader reader) {
private MockZkController createMockZkController(String zkAddress, SolrZkClient zkClient, ZkStateReader reader) {
CoreContainer mockAlwaysUpCoreContainer = mock(CoreContainer.class,
Mockito.withSettings().defaultAnswer(Mockito.CALLS_REAL_METHODS));
when(mockAlwaysUpCoreContainer.isShutDown()).thenReturn(Boolean.FALSE); // Allow retry on session expiry
@ -1335,15 +1336,13 @@ public class OverseerTest extends SolrTestCaseJ4 {
when(zkController.getCoreContainer()).thenReturn(mockAlwaysUpCoreContainer);
when(zkController.getZkClient()).thenReturn(zkClient);
when(zkController.getZkStateReader()).thenReturn(reader);
doReturn(getCloudDataProvider(zkClient,reader))
doReturn(getCloudDataProvider(zkAddress, zkClient,reader))
.when(zkController).getSolrCloudManager();
return zkController;
}
private SolrCloudManager getCloudDataProvider(SolrZkClient zkClient, ZkStateReader reader) {
CloudSolrClient client = new CloudSolrClient.Builder()
.withClusterStateProvider(new ZkClientClusterStateProvider(reader))
.build();
private SolrCloudManager getCloudDataProvider(String zkAddress, SolrZkClient zkClient, ZkStateReader reader) {
CloudSolrClient client = new CloudSolrClient.Builder(Collections.singletonList(zkAddress), Optional.empty()).build();
solrClients.add(client);
return new SolrClientCloudManager(new ZkDistributedQueueFactory(zkClient), client);
}

View File

@ -43,7 +43,9 @@ import org.junit.BeforeClass;
import org.junit.Test;
import java.lang.invoke.MethodHandles;
import java.util.Collections;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import org.slf4j.Logger;
@ -179,8 +181,7 @@ public class TestSolrCloudWithDelegationTokens extends SolrTestCaseJ4 {
.withKerberosDelegationToken(token)
.withResponseParser(client.getParser())
.build();
else delegationTokenClient = new CloudSolrClient.Builder()
.withZkHost((miniCluster.getZkServer().getZkAddress()))
else delegationTokenClient = new CloudSolrClient.Builder(Collections.singletonList(miniCluster.getZkServer().getZkAddress()), Optional.empty())
.withLBHttpSolrClientBuilder(new LBHttpSolrClient.Builder()
.withResponseParser(client.getParser())
.withHttpSolrClientBuilder(

View File

@ -16,7 +16,9 @@
*/
package org.apache.solr.security.hadoop;
import java.util.Collections;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import org.apache.hadoop.security.authentication.client.PseudoAuthenticator;
@ -167,8 +169,7 @@ public class TestDelegationWithHadoopAuth extends SolrCloudTestCase {
.withKerberosDelegationToken(token)
.withResponseParser(client.getParser())
.build();
else delegationTokenClient = new CloudSolrClient.Builder()
.withZkHost((cluster.getZkServer().getZkAddress()))
else delegationTokenClient = new CloudSolrClient.Builder(Collections.singletonList(cluster.getZkServer().getZkAddress()), Optional.empty())
.withLBHttpSolrClientBuilder(new LBHttpSolrClient.Builder()
.withResponseParser(client.getParser())
.withHttpSolrClientBuilder(

View File

@ -30,6 +30,7 @@ import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@ -1356,6 +1357,35 @@ public class CloudSolrClient extends SolrClient {
protected boolean directUpdatesToLeadersOnly = false;
protected boolean parallelUpdates = true;
protected ClusterStateProvider stateProvider;
/**
* @deprecated use other constructors instead. This constructor will be changing visibility in an upcoming release.
*/
@Deprecated
public Builder() {}
/**
* Provide a series of Solr URLs to be used when configuring {@link CloudSolrClient} instances.
* The solr client will use these urls to understand the cluster topology, which solr nodes are active etc.
*
* Provided Solr URLs are expected to point to the root Solr path ("http://hostname:8983/solr"); it should not
* include any collections, cores, or other path components.
*/
public Builder(List<String> solrUrls) {
this.solrUrls = solrUrls;
}
/**
* Provide a series of ZK hosts which will be used when configuring {@link CloudSolrClient} instances.
*
* @param zkHosts a List of at least one ZooKeeper host and port
* @param zkChroot the path to the root ZooKeeper node containing Solr data. May be empty if Solr-data is located
* at the ZooKeeper root
*/
public Builder(List<String> zkHosts, Optional<String> zkChroot) {
this.zkHosts = zkHosts;
if (zkChroot.isPresent()) this.zkChroot = zkChroot.get();
}
/**
* Provide a ZooKeeper client endpoint to be used when configuring {@link CloudSolrClient} instances.
@ -1365,7 +1395,10 @@ public class CloudSolrClient extends SolrClient {
* @param zkHost
* The client endpoint of the ZooKeeper quorum containing the cloud
* state.
*
* @deprecated use Zk-host constructor instead
*/
@Deprecated
public Builder withZkHost(String zkHost) {
this.zkHosts.add(zkHost);
return this;
@ -1379,7 +1412,10 @@ public class CloudSolrClient extends SolrClient {
*
* Provided Solr URL is expected to point to the root Solr path ("http://hostname:8983/solr"); it should not
* include any collections, cores, or other path components.
*
* @deprecated use Solr-URL constructor instead
*/
@Deprecated
public Builder withSolrUrl(String solrUrl) {
this.solrUrls.add(solrUrl);
return this;
@ -1392,7 +1428,10 @@ public class CloudSolrClient extends SolrClient {
*
* Provided Solr URLs are expected to point to the root Solr path ("http://hostname:8983/solr"); they should not
* include any collections, cores, or other path components.
*
* @deprecated use Solr URL constructors instead
*/
@Deprecated
public Builder withSolrUrl(Collection<String> solrUrls) {
this.solrUrls.addAll(solrUrls);
return this;
@ -1416,7 +1455,10 @@ public class CloudSolrClient extends SolrClient {
* each host in the ZooKeeper ensemble. Note that with certain
* Collection types like HashSet, the order of hosts in the final
* connect string may not be in the same order you added them.
*
* @deprecated use Zk-host constructor instead
*/
@Deprecated
public Builder withZkHost(Collection<String> zkHosts) {
this.zkHosts.addAll(zkHosts);
return this;
@ -1424,7 +1466,10 @@ public class CloudSolrClient extends SolrClient {
/**
* Provides a ZooKeeper chroot for the builder to use when creating clients.
*
* @deprecated use Zk-host constructor instead
*/
@Deprecated
public Builder withZkChroot(String zkChroot) {
this.zkChroot = zkChroot;
return this;
@ -1477,6 +1522,14 @@ public class CloudSolrClient extends SolrClient {
return this;
}
/**
* Expert feature where you want to implement a custom cluster discovery mechanism of the solr nodes as part of the
* cluster.
*
* @deprecated since this is an expert feature we don't want to expose this to regular users. To use this feature
* extend CloudSolrClient.Builder and pass your custom ClusterStateProvider
*/
@Deprecated
public Builder withClusterStateProvider(ClusterStateProvider stateProvider) {
this.stateProvider = stateProvider;
return this;

View File

@ -20,7 +20,10 @@ import java.io.IOException;
import java.io.Serializable;
import java.lang.invoke.MethodHandles;
import java.util.Map;
import java.util.Optional;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.apache.http.client.HttpClient;
import org.apache.solr.client.solrj.SolrClient;
@ -54,8 +57,9 @@ public class SolrClientCache implements Serializable {
if (solrClients.containsKey(zkHost)) {
client = (CloudSolrClient) solrClients.get(zkHost);
} else {
CloudSolrClient.Builder builder = new CloudSolrClient.Builder()
.withZkHost(zkHost);
final List<String> hosts = new ArrayList<String>();
hosts.add(zkHost);
CloudSolrClient.Builder builder = new CloudSolrClient.Builder(hosts, Optional.empty());
if (httpClient != null) {
builder = builder.withHttpClient(httpClient);
}

View File

@ -23,6 +23,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Map.Entry;
import java.util.stream.Collectors;
@ -323,9 +324,9 @@ public class FacetStream extends TupleStream implements Expressible {
if(cache != null) {
cloudSolrClient = cache.getCloudSolrClient(zkHost);
} else {
cloudSolrClient = new Builder()
.withZkHost(zkHost)
.build();
final List<String> hosts = new ArrayList<>();
hosts.add(zkHost);
cloudSolrClient = new Builder(hosts, Optional.empty()).build();
}
FieldComparator[] adjustedSorts = adjustSorts(buckets, bucketSorts);

View File

@ -25,6 +25,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Random;
import java.util.stream.Collectors;
@ -175,7 +176,9 @@ public class RandomStream extends TupleStream implements Expressible {
if(cache != null) {
cloudSolrClient = cache.getCloudSolrClient(zkHost);
} else {
cloudSolrClient = (new CloudSolrClient.Builder()).withZkHost(zkHost).build();
final List<String> hosts = new ArrayList<>();
hosts.add(zkHost);
cloudSolrClient = new CloudSolrClient.Builder(hosts, Optional.empty()).build();
}
ModifiableSolrParams params = getParams(this.props);

View File

@ -25,6 +25,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Map.Entry;
import java.util.stream.Collectors;
@ -273,12 +274,12 @@ public class TimeSeriesStream extends TupleStream implements Expressible {
}
public void open() throws IOException {
if(cache != null) {
if (cache != null) {
cloudSolrClient = cache.getCloudSolrClient(zkHost);
} else {
cloudSolrClient = new Builder()
.withZkHost(zkHost)
.build();
final List<String> hosts = new ArrayList<>();
hosts.add(zkHost);
cloudSolrClient = new Builder(hosts, Optional.empty()).build();
}
String json = getJsonFacetString(field, metrics, start, end, gap);

View File

@ -26,6 +26,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;
@ -294,8 +295,9 @@ public class TopicStream extends CloudSolrStream implements Expressible {
if(streamContext.getSolrClientCache() != null) {
cloudSolrClient = streamContext.getSolrClientCache().getCloudSolrClient(zkHost);
} else {
cloudSolrClient = new Builder()
.withZkHost(zkHost)
final List<String> hosts = new ArrayList<String>();
hosts.add(zkHost);
cloudSolrClient = new Builder(hosts, Optional.empty())
.build();
this.cloudSolrClient.connect();
}

View File

@ -23,6 +23,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.CloudSolrClient;
@ -261,9 +262,9 @@ public class UpdateStream extends TupleStream implements Expressible {
if(this.cache != null) {
this.cloudSolrClient = this.cache.getCloudSolrClient(zkHost);
} else {
this.cloudSolrClient = new Builder()
.withZkHost(zkHost)
.build();
final List<String> hosts = new ArrayList<>();
hosts.add(zkHost);
this.cloudSolrClient = new Builder(hosts, Optional.empty()).build();
this.cloudSolrClient.connect();
}
}

View File

@ -19,6 +19,9 @@ package org.apache.solr.client.solrj.impl;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import org.apache.lucene.util.LuceneTestCase;
import org.apache.solr.client.solrj.impl.CloudSolrClient.Builder;
@ -38,9 +41,7 @@ public class CloudSolrClientBuilderTest extends LuceneTestCase {
@Test
public void testSingleZkHostSpecified() throws IOException {
try(CloudSolrClient createdClient = new Builder()
.withZkHost(ANY_ZK_HOST)
.withZkChroot(ANY_CHROOT)
try(CloudSolrClient createdClient = new Builder(Collections.singletonList(ANY_ZK_HOST), Optional.of(ANY_CHROOT))
.build()) {
final String clientZkHost = createdClient.getZkHost();
@ -50,10 +51,9 @@ public class CloudSolrClientBuilderTest extends LuceneTestCase {
@Test
public void testSeveralZkHostsSpecifiedSingly() throws IOException {
try (CloudSolrClient createdClient = new Builder()
.withZkHost(ANY_ZK_HOST)
.withZkHost(ANY_OTHER_ZK_HOST)
.withZkChroot(ANY_CHROOT)
final List<String> zkHostList = new ArrayList<>();
zkHostList.add(ANY_ZK_HOST); zkHostList.add(ANY_OTHER_ZK_HOST);
try (CloudSolrClient createdClient = new Builder(zkHostList, Optional.of(ANY_CHROOT))
.build()) {
final String clientZkHost = createdClient.getZkHost();
@ -67,10 +67,7 @@ public class CloudSolrClientBuilderTest extends LuceneTestCase {
final ArrayList<String> zkHosts = new ArrayList<String>();
zkHosts.add(ANY_ZK_HOST);
zkHosts.add(ANY_OTHER_ZK_HOST);
try(CloudSolrClient createdClient = new Builder()
.withZkHost(zkHosts)
.withZkChroot(ANY_CHROOT)
.build()) {
try(CloudSolrClient createdClient = new Builder(zkHosts, Optional.of(ANY_CHROOT)).build()) {
final String clientZkHost = createdClient.getZkHost();
assertTrue(clientZkHost.contains(ANY_ZK_HOST));
@ -80,29 +77,21 @@ public class CloudSolrClientBuilderTest extends LuceneTestCase {
@Test
public void testByDefaultConfiguresClientToSendUpdatesOnlyToShardLeaders() throws IOException {
try(CloudSolrClient createdClient = new Builder()
.withZkHost(ANY_ZK_HOST)
.withZkChroot(ANY_CHROOT)
.build()) {
try(CloudSolrClient createdClient = new Builder(Collections.singletonList(ANY_ZK_HOST), Optional.of(ANY_CHROOT)).build()) {
assertTrue(createdClient.isUpdatesToLeaders() == true);
}
}
@Test
public void testIsDirectUpdatesToLeadersOnlyDefault() throws IOException {
try(CloudSolrClient createdClient = new Builder()
.withZkHost(ANY_ZK_HOST)
.withZkChroot(ANY_CHROOT)
.build()) {
try(CloudSolrClient createdClient = new Builder(Collections.singletonList(ANY_ZK_HOST), Optional.of(ANY_CHROOT)).build()) {
assertFalse(createdClient.isDirectUpdatesToLeadersOnly());
}
}
@Test
public void test0Timeouts() throws IOException {
try(CloudSolrClient createdClient = new Builder()
.withZkHost(ANY_ZK_HOST)
.withZkChroot(ANY_CHROOT)
try(CloudSolrClient createdClient = new Builder(Collections.singletonList(ANY_ZK_HOST), Optional.empty())
.withSocketTimeout(0)
.withConnectionTimeout(0)
.build()) {

View File

@ -80,10 +80,8 @@ public class CloudSolrClientCacheTest extends SolrTestCaseJ4 {
LBHttpSolrClient mockLbclient = getMockLbHttpSolrClient(responses);
AtomicInteger lbhttpRequestCount = new AtomicInteger();
try (CloudSolrClient cloudClient = new CloudSolrClient.Builder()
try (CloudSolrClient cloudClient = new CloudSolrClientBuilder(getStateProvider(livenodes, refs))
.withLBHttpSolrClient(mockLbclient)
.withClusterStateProvider(getStateProvider(livenodes, refs))
.build()) {
livenodes.addAll(ImmutableSet.of("192.168.1.108:7574_solr", "192.168.1.108:8983_solr"));
ClusterState cs = ClusterState.load(1, coll1State.getBytes(UTF_8),

View File

@ -16,14 +16,16 @@
*/
package org.apache.solr.client.solrj.impl;
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util.TestUtil;
import org.junit.Test;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Optional;
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util.TestUtil;
import org.junit.Test;
public class CloudSolrClientMultiConstructorTest extends LuceneTestCase {
@ -35,7 +37,7 @@ public class CloudSolrClientMultiConstructorTest extends LuceneTestCase {
Collection<String> hosts;
@Test
public void testWithChroot() throws IOException {
public void testZkConnectionStringSetterWithValidChroot() throws IOException {
boolean setOrList = random().nextBoolean();
int numOfZKServers = TestUtil.nextInt(random(), 1, 5);
boolean withChroot = random().nextBoolean();
@ -70,13 +72,39 @@ public class CloudSolrClientMultiConstructorTest extends LuceneTestCase {
try (CloudSolrClient client = (new CloudSolrClient.Builder()).withZkHost(hosts).withZkChroot(clientChroot).build()) {
assertEquals(sb.toString(), client.getZkHost());
}
}
@Test
public void testZkConnectionStringConstructorWithValidChroot() throws IOException {
int numOfZKServers = TestUtil.nextInt(random(), 1, 5);
boolean withChroot = random().nextBoolean();
final String chroot = "/mychroot";
StringBuilder sb = new StringBuilder();
List<String> hosts = new ArrayList<>();
for (int i=0; i<numOfZKServers; i++) {
String ZKString = "host" + i + ":2181";
hosts.add(ZKString);
sb.append(ZKString);
if (i<numOfZKServers -1) sb.append(",");
}
if (withChroot) {
sb.append(chroot);
}
final Optional<String> chrootOption = withChroot == false ? Optional.empty() : Optional.of(chroot);
try (CloudSolrClient client = new CloudSolrClient.Builder(hosts, chrootOption).build()) {
assertEquals(sb.toString(), client.getZkHost());
}
}
@Test(expected = IllegalArgumentException.class)
public void testBadChroot() {
hosts = new ArrayList<>();
hosts.add("host1:2181");
(new CloudSolrClient.Builder()).withZkHost(hosts).withZkChroot("foo").build();
final List<String> zkHosts = new ArrayList<>();
zkHosts.add("host1:2181");
new CloudSolrClient.Builder(zkHosts, Optional.of("foo")).build();
}
}

View File

@ -22,11 +22,13 @@ import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeoutException;
@ -104,8 +106,9 @@ public class CloudSolrClientTest extends SolrCloudTestCase {
AbstractDistribZkTestBase.waitForRecoveriesToFinish(COLLECTION, cluster.getSolrClient().getZkStateReader(),
false, true, TIMEOUT);
httpBasedCloudSolrClient = new CloudSolrClient.Builder().withSolrUrl(
cluster.getJettySolrRunner(0).getBaseUrl().toString()).build();
final List<String> solrUrls = new ArrayList<>();
solrUrls.add(cluster.getJettySolrRunner(0).getBaseUrl().toString());
httpBasedCloudSolrClient = new CloudSolrClient.Builder(solrUrls).build();
}
@AfterClass
@ -269,8 +272,8 @@ public class CloudSolrClientTest extends SolrCloudTestCase {
assertEquals(0, docs.getNumFound());
// Test Multi-Threaded routed updates for UpdateRequest
try (CloudSolrClient threadedClient = new CloudSolrClientBuilder()
.withZkHost(cluster.getZkServer().getZkAddress())
try (CloudSolrClient threadedClient = new CloudSolrClientBuilder
(Collections.singletonList(cluster.getZkServer().getZkAddress()), Optional.empty())
.withParallelUpdates(true)
.build()) {
threadedClient.setDefaultCollection(COLLECTION);
@ -789,8 +792,8 @@ public class CloudSolrClientTest extends SolrCloudTestCase {
final String old_leader_core_node_name = slice.getLeader().getName();
// NOTE: creating our own CloudSolrClient whose settings we can muck with...
try (CloudSolrClient stale_client = new CloudSolrClientBuilder()
.withZkHost(cluster.getZkServer().getZkAddress())
try (CloudSolrClient stale_client = new CloudSolrClientBuilder
(Collections.singletonList(cluster.getZkServer().getZkAddress()), Optional.empty())
.sendDirectUpdatesToAnyShardReplica()
.withParallelUpdates(true)
.build()) {

View File

@ -55,6 +55,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
@ -66,6 +67,7 @@ import com.carrotsearch.randomizedtesting.TraceFormatting;
import com.carrotsearch.randomizedtesting.annotations.ThreadLeakFilters;
import com.carrotsearch.randomizedtesting.annotations.ThreadLeakLingering;
import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule;
import org.apache.commons.io.FileUtils;
import org.apache.http.client.HttpClient;
import org.apache.lucene.analysis.MockAnalyzer;
@ -79,7 +81,9 @@ import org.apache.lucene.util.QuickPatchThreadsFilter;
import org.apache.lucene.util.TestUtil;
import org.apache.solr.client.solrj.ResponseParser;
import org.apache.solr.client.solrj.embedded.JettyConfig;
import org.apache.solr.client.solrj.embedded.JettySolrRunner;
import org.apache.solr.client.solrj.impl.CloudSolrClient;
import org.apache.solr.client.solrj.impl.ClusterStateProvider;
import org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrClient;
import org.apache.solr.client.solrj.impl.HttpClientUtil;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
@ -2234,22 +2238,43 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
* some internal settings.
*/
public static class CloudSolrClientBuilder extends CloudSolrClient.Builder {
public CloudSolrClientBuilder() {
public CloudSolrClientBuilder(List<String> zkHosts, Optional<String> zkChroot) {
super(zkHosts, zkChroot);
randomizeCloudSolrClient();
}
public CloudSolrClientBuilder(ClusterStateProvider stateProvider) {
this.stateProvider = stateProvider;
randomizeCloudSolrClient();
}
public CloudSolrClientBuilder(MiniSolrCloudCluster cluster) {
if (random().nextBoolean()) {
this.zkHosts.add(cluster.getZkServer().getZkAddress());
} else {
populateSolrUrls(cluster);
}
randomizeCloudSolrClient();
}
private void populateSolrUrls(MiniSolrCloudCluster cluster) {
if (random().nextBoolean()) {
final List<JettySolrRunner> solrNodes = cluster.getJettySolrRunners();
for (JettySolrRunner node : solrNodes) {
this.solrUrls.add(node.getBaseUrl().toString());
}
} else {
this.solrUrls.add(cluster.getRandomJetty(random()).getBaseUrl().toString());
}
}
private void randomizeCloudSolrClient() {
this.directUpdatesToLeadersOnly = random().nextBoolean();
this.shardLeadersOnly = random().nextBoolean();
this.parallelUpdates = random().nextBoolean();
}
/** Randomly chooses the cluster state provider -- either ZK based or HTTP. */
public CloudSolrClient.Builder withCluster(MiniSolrCloudCluster cluster) {
if (random().nextBoolean()) {
return withZkHost(cluster.getZkServer().getZkAddress());
} else {
return withSolrUrl(cluster.getRandomJetty(random()).getBaseUrl().toString());
}
}
}
/**
@ -2258,9 +2283,7 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
* {@link org.apache.solr.client.solrj.impl.CloudSolrClient.Builder} class directly
*/
public static CloudSolrClient getCloudSolrClient(String zkHost) {
return new CloudSolrClientBuilder()
.withZkHost(zkHost)
.build();
return new CloudSolrClientBuilder(Collections.singletonList(zkHost), Optional.empty()).build();
}
/**
@ -2269,9 +2292,7 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
* {@link org.apache.solr.client.solrj.impl.CloudSolrClient.Builder} class directly
*/
public static CloudSolrClient getCloudSolrClient(MiniSolrCloudCluster cluster) {
return new CloudSolrClientBuilder()
.withCluster(cluster)
.build();
return new CloudSolrClientBuilder(cluster).build();
}
/**
@ -2280,8 +2301,7 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
* {@link org.apache.solr.client.solrj.impl.CloudSolrClient.Builder} class directly
*/
public static CloudSolrClient getCloudSolrClient(String zkHost, HttpClient httpClient) {
return new CloudSolrClientBuilder()
.withZkHost(zkHost)
return new CloudSolrClientBuilder(Collections.singletonList(zkHost), Optional.empty())
.withHttpClient(httpClient)
.build();
}
@ -2293,19 +2313,17 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
*/
public static CloudSolrClient getCloudSolrClient(String zkHost, boolean shardLeadersOnly) {
if (shardLeadersOnly) {
return new CloudSolrClientBuilder()
.withZkHost(zkHost)
return new CloudSolrClientBuilder(Collections.singletonList(zkHost), Optional.empty())
.sendUpdatesOnlyToShardLeaders()
.build();
}
return new CloudSolrClientBuilder()
.withZkHost(zkHost)
return new CloudSolrClientBuilder(Collections.singletonList(zkHost), Optional.empty())
.sendUpdatesToAllReplicasInShard()
.build();
}
public static CloudSolrClientBuilder newCloudSolrClient(String zkHost) {
return (CloudSolrClientBuilder) new CloudSolrClientBuilder().withZkHost(zkHost);
return (CloudSolrClientBuilder) new CloudSolrClientBuilder(Collections.singletonList(zkHost), Optional.empty());
}
/**
@ -2315,14 +2333,12 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
*/
public static CloudSolrClient getCloudSolrClient(String zkHost, boolean shardLeadersOnly, int socketTimeoutMillis) {
if (shardLeadersOnly) {
return new CloudSolrClientBuilder()
.withZkHost(zkHost)
return new CloudSolrClientBuilder(Collections.singletonList(zkHost), Optional.empty())
.sendUpdatesOnlyToShardLeaders()
.withSocketTimeout(socketTimeoutMillis)
.build();
}
return new CloudSolrClientBuilder()
.withZkHost(zkHost)
return new CloudSolrClientBuilder(Collections.singletonList(zkHost), Optional.empty())
.sendUpdatesToAllReplicasInShard()
.withSocketTimeout(socketTimeoutMillis)
.build();
@ -2335,15 +2351,13 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
*/
public static CloudSolrClient getCloudSolrClient(String zkHost, boolean shardLeadersOnly, int connectionTimeoutMillis, int socketTimeoutMillis) {
if (shardLeadersOnly) {
return new CloudSolrClientBuilder()
.withZkHost(zkHost)
return new CloudSolrClientBuilder(Collections.singletonList(zkHost), Optional.empty())
.sendUpdatesOnlyToShardLeaders()
.withConnectionTimeout(connectionTimeoutMillis)
.withSocketTimeout(socketTimeoutMillis)
.build();
}
return new CloudSolrClientBuilder()
.withZkHost(zkHost)
return new CloudSolrClientBuilder(Collections.singletonList(zkHost), Optional.empty())
.sendUpdatesToAllReplicasInShard()
.withConnectionTimeout(connectionTimeoutMillis)
.withSocketTimeout(socketTimeoutMillis)
@ -2359,14 +2373,12 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
*/
public static CloudSolrClient getCloudSolrClient(String zkHost, boolean shardLeadersOnly, HttpClient httpClient) {
if (shardLeadersOnly) {
return new CloudSolrClientBuilder()
.withZkHost(zkHost)
return new CloudSolrClientBuilder(Collections.singletonList(zkHost), Optional.empty())
.withHttpClient(httpClient)
.sendUpdatesOnlyToShardLeaders()
.build();
}
return new CloudSolrClientBuilder()
.withZkHost(zkHost)
return new CloudSolrClientBuilder(Collections.singletonList(zkHost), Optional.empty())
.withHttpClient(httpClient)
.sendUpdatesToAllReplicasInShard()
.build();
@ -2380,16 +2392,14 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
public static CloudSolrClient getCloudSolrClient(String zkHost, boolean shardLeadersOnly, HttpClient httpClient,
int connectionTimeoutMillis, int socketTimeoutMillis) {
if (shardLeadersOnly) {
return new CloudSolrClientBuilder()
.withZkHost(zkHost)
return new CloudSolrClientBuilder(Collections.singletonList(zkHost), Optional.empty())
.withHttpClient(httpClient)
.sendUpdatesOnlyToShardLeaders()
.withConnectionTimeout(connectionTimeoutMillis)
.withSocketTimeout(socketTimeoutMillis)
.build();
}
return new CloudSolrClientBuilder()
.withZkHost(zkHost)
return new CloudSolrClientBuilder(Collections.singletonList(zkHost), Optional.empty())
.withHttpClient(httpClient)
.sendUpdatesToAllReplicasInShard()
.withConnectionTimeout(connectionTimeoutMillis)

View File

@ -498,8 +498,7 @@ public class MiniSolrCloudCluster {
}
protected CloudSolrClient buildSolrClient() {
return new Builder()
.withZkHost(getZkServer().getZkAddress())
return new Builder(Collections.singletonList(getZkServer().getZkAddress()), Optional.empty())
.build();
}