lucene-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ans...@apache.org
Subject [1/3] lucene-solr:master: SOLR-8097: Implement builder pattern design for constructing SolrJ clients and deprecate direct construction of clients
Date Thu, 07 Apr 2016 23:25:00 GMT
Repository: lucene-solr
Updated Branches:
  refs/heads/master 1848477bd -> b02b026b7


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b02b026b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrClient.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrClient.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrClient.java
index 18038c2..9b0cf8d 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrClient.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrClient.java
@@ -30,7 +30,6 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Locale;
 import java.util.Set;
-import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Future;
 
@@ -41,7 +40,6 @@ import org.apache.http.HttpResponse;
 import org.apache.http.HttpStatus;
 import org.apache.http.NameValuePair;
 import org.apache.http.client.HttpClient;
-import org.apache.http.client.config.RequestConfig.Builder;
 import org.apache.http.client.entity.UrlEncodedFormEntity;
 import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
 import org.apache.http.client.methods.HttpGet;
@@ -55,7 +53,6 @@ import org.apache.http.entity.InputStreamEntity;
 import org.apache.http.entity.mime.FormBodyPart;
 import org.apache.http.entity.mime.HttpMultipartMode;
 import org.apache.http.entity.mime.MultipartEntity;
-import org.apache.http.entity.mime.MultipartEntityBuilder;
 import org.apache.http.entity.mime.content.InputStreamBody;
 import org.apache.http.entity.mime.content.StringBody;
 import org.apache.http.message.BasicHeader;
@@ -160,20 +157,34 @@ public class HttpSolrClient extends SolrClient {
    *          The URL of the Solr server. For example, "
    *          <code>http://localhost:8983/solr/</code>" if you are using the
    *          standard distribution Solr webapp on your local machine.
+   * @deprecated use {@link Builder} instead.
    */
+  @Deprecated
   public HttpSolrClient(String baseURL) {
     this(baseURL, null, new BinaryResponseParser());
   }
   
+  /**
+   * @deprecated use {@link Builder} instead.
+   */
+  @Deprecated
   public HttpSolrClient(String baseURL, HttpClient client) {
     this(baseURL, client, new BinaryResponseParser());
   }
   
-  
+  /**
+   * @deprecated use {@link Builder} instead.
+   */
+  @Deprecated
   public HttpSolrClient(String baseURL, HttpClient client, ResponseParser parser) {
     this(baseURL, client, parser, false);
   }
   
+  /**
+   * @deprecated use {@link Builder} instead.  This will soon be a 'protected'
+   * method, and will only be available for use in implementing subclasses.
+   */
+  @Deprecated
   public HttpSolrClient(String baseURL, HttpClient client, ResponseParser parser, boolean allowCompression) {
     this.baseUrl = baseURL;
     if (baseUrl.endsWith("/")) {
@@ -479,7 +490,7 @@ public class HttpSolrClient extends SolrClient {
   protected NamedList<Object> executeMethod(HttpRequestBase method, final ResponseParser processor) throws SolrServerException {
     method.addHeader("User-Agent", AGENT);
  
-    Builder requestConfigBuilder = HttpClientUtil.createDefaultRequestConfigBuilder();
+    org.apache.http.client.config.RequestConfig.Builder requestConfigBuilder = HttpClientUtil.createDefaultRequestConfigBuilder();
     if (soTimeout != null) {
       requestConfigBuilder.setSocketTimeout(soTimeout);
     }
@@ -732,4 +743,60 @@ public class HttpSolrClient extends SolrClient {
       super(code, "Error from server at " + remoteHost + ": " + msg, th);
     }
   }
+  
+  /**
+   * Constructs {@link HttpSolrClient} instances from provided configuration.
+   */
+  public static class Builder {
+    private String baseSolrUrl;
+    private HttpClient httpClient;
+    private ResponseParser responseParser;
+    private boolean compression;
+    
+    /**
+     * Create a Builder object, based on the provided Solr URL.
+     * 
+     * By default, compression is not enabled in created HttpSolrClient objects.
+     * 
+     * @param baseSolrUrl the base URL of the Solr server that will be targeted by any created clients.
+     */
+    public Builder(String baseSolrUrl) {
+      this.baseSolrUrl = baseSolrUrl;
+      this.responseParser = new BinaryResponseParser();
+    }
+    
+    /**
+     * Provides a {@link HttpClient} for the builder to use when creating clients.
+     */
+    public Builder withHttpClient(HttpClient httpClient) {
+      this.httpClient = httpClient;
+      return this;
+    }
+    
+    /**
+     * Provides a {@link ResponseParser} for created clients to use when handling requests.
+     */
+    public Builder withResponseParser(ResponseParser responseParser) {
+      this.responseParser = responseParser;
+      return this;
+    }
+    
+    /**
+     * Chooses whether created {@link HttpSolrClient}s use compression by default.
+     */
+    public Builder allowCompression(boolean compression) {
+      this.compression = compression;
+      return this;
+    }
+    
+    /**
+     * Create a {@link HttpSolrClient} based on provided configuration.
+     */
+    public HttpSolrClient build() {
+      if (baseSolrUrl == null) {
+        throw new IllegalArgumentException("Cannot create HttpSolrClient without a valid baseSolrUrl!");
+      }
+      return new HttpSolrClient(baseSolrUrl, httpClient, responseParser, compression);
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b02b026b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBHttpSolrClient.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBHttpSolrClient.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBHttpSolrClient.java
index fabb933..eaf593e 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBHttpSolrClient.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBHttpSolrClient.java
@@ -16,30 +16,44 @@
  */
 package org.apache.solr.client.solrj.impl;
 
+import java.io.IOException;
+import java.lang.ref.WeakReference;
+import java.net.ConnectException;
+import java.net.MalformedURLException;
+import java.net.SocketException;
+import java.net.SocketTimeoutException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
 import org.apache.http.client.HttpClient;
-import org.apache.solr.client.solrj.*;
+import org.apache.solr.client.solrj.ResponseParser;
+import org.apache.solr.client.solrj.SolrClient;
+import org.apache.solr.client.solrj.SolrQuery;
+import org.apache.solr.client.solrj.SolrRequest;
+import org.apache.solr.client.solrj.SolrServerException;
 import org.apache.solr.client.solrj.request.IsUpdateRequest;
 import org.apache.solr.client.solrj.request.RequestWriter;
 import org.apache.solr.client.solrj.response.QueryResponse;
+import org.apache.solr.common.SolrException;
 import org.apache.solr.common.params.CommonParams;
 import org.apache.solr.common.params.ModifiableSolrParams;
 import org.apache.solr.common.params.SolrParams;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.common.util.SolrjNamedThreadFactory;
-import org.apache.solr.common.SolrException;
 import org.slf4j.MDC;
 
-import java.io.IOException;
-import java.lang.ref.WeakReference;
-import java.net.ConnectException;
-import java.net.MalformedURLException;
-import java.net.SocketException;
-import java.net.SocketTimeoutException;
-import java.net.URL;
-import java.util.concurrent.*;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.*;
-
 /**
  * LBHttpSolrClient or "LoadBalanced HttpSolrClient" is a load balancing wrapper around
  * {@link HttpSolrClient}. This is useful when you
@@ -209,19 +223,31 @@ public class LBHttpSolrClient extends SolrClient {
     }
   }
 
+  /**
+   * @deprecated use {@link Builder} instead.
+   */
+  @Deprecated
   public LBHttpSolrClient(String... solrServerUrls) throws MalformedURLException {
     this(null, solrServerUrls);
   }
   
-  /** The provided httpClient should use a multi-threaded connection manager */ 
+  /**
+   * The provided httpClient should use a multi-threaded connection manager
+   * @deprecated use {@link Builder} instead.
+   */ 
+  @Deprecated
   public LBHttpSolrClient(HttpClient httpClient, String... solrServerUrl) {
     this(httpClient, new BinaryResponseParser(), solrServerUrl);
   }
 
-  /** The provided httpClient should use a multi-threaded connection manager */  
+  /**
+   * The provided httpClient should use a multi-threaded connection manager
+   * @deprecated use {@link Builder} instead.  This will soon be a protected
+   * method and will only be available for use in implementing subclasses.
+   */
+  @Deprecated
   public LBHttpSolrClient(HttpClient httpClient, ResponseParser parser, String... solrServerUrl) {
     clientIsInternal = (httpClient == null);
-    this.parser = parser;
     if (httpClient == null) {
       ModifiableSolrParams params = new ModifiableSolrParams();
       if (solrServerUrl.length > 1) {
@@ -234,6 +260,9 @@ public class LBHttpSolrClient extends SolrClient {
     } else {
       this.httpClient = httpClient;
     }
+    
+    this.parser = parser;
+    
     for (String s : solrServerUrl) {
       ServerWrapper wrapper = new ServerWrapper(makeSolrClient(s));
       aliveServers.put(wrapper.getKey(), wrapper);
@@ -263,7 +292,10 @@ public class LBHttpSolrClient extends SolrClient {
   }
 
   protected HttpSolrClient makeSolrClient(String server) {
-    HttpSolrClient client = new HttpSolrClient(server, httpClient, parser);
+    HttpSolrClient client = new HttpSolrClient.Builder(server)
+        .withHttpClient(httpClient)
+        .withResponseParser(parser)
+        .build();
     if (connectionTimeout != null) {
       client.setConnectionTimeout(connectionTimeout);
     }
@@ -746,4 +778,64 @@ public class LBHttpSolrClient extends SolrClient {
   private static final int CHECK_INTERVAL = 60 * 1000; //1 minute between checks
   private static final int NONSTANDARD_PING_LIMIT = 5;  // number of times we'll ping dead servers not in the server list
 
+  /**
+   * Constructs {@link LBHttpSolrClient} instances from provided configuration.
+   */
+  public static class Builder {
+    private final List<String> baseSolrUrls;
+    private HttpClient httpClient;
+    private ResponseParser responseParser;
+    
+    public Builder() {
+      this.baseSolrUrls = new ArrayList<String>();
+      this.responseParser = new BinaryResponseParser();
+    }
+    
+    /**
+     * Provide a Solr endpoint to be used when configuring {@link LBHttpSolrClient} instances.
+     * 
+     * Method may be called multiple times.  All provided values will be used.
+     */
+    public Builder withBaseSolrUrl(String baseSolrUrl) {
+      this.baseSolrUrls.add(baseSolrUrl);
+      return this;
+    }
+    
+    /**
+     * Provide Solr endpoints to be used when configuring {@link LBHttpSolrClient} instances.
+     * 
+     * Method may be called multiple times.  All provided values will be used.
+     */
+    public Builder withBaseSolrUrls(String... solrUrls) {
+      for (String baseSolrUrl : solrUrls) {
+        this.baseSolrUrls.add(baseSolrUrl);
+      }
+      return this;
+    }
+    
+    
+    /**
+     * Provides a {@link HttpClient} for the builder to use when creating clients.
+     */
+    public Builder withHttpClient(HttpClient httpClient) {
+      this.httpClient = httpClient;
+      return this;
+    }
+    
+    /**
+     * Provides a {@link ResponseParser} for created clients to use when handling requests.
+     */
+    public Builder withResponseParser(ResponseParser responseParser) {
+      this.responseParser = responseParser;
+      return this;
+    }
+    
+    /**
+     * Create a {@link HttpSolrClient} based on provided configuration.
+     */
+    public LBHttpSolrClient build() {
+      final String[] baseUrlArray = new String[baseSolrUrls.size()];
+      return new LBHttpSolrClient(httpClient, responseParser, baseSolrUrls.toArray(baseUrlArray));
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b02b026b/solr/solrj/src/java/org/apache/solr/client/solrj/io/SolrClientCache.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/SolrClientCache.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/SolrClientCache.java
index e544c10..cd992a4 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/SolrClientCache.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/SolrClientCache.java
@@ -21,7 +21,7 @@ import java.io.Serializable;
 import java.lang.invoke.MethodHandles;
 import java.util.Map;
 import java.util.HashMap;
-import java.util.Iterator;
+
 import org.apache.solr.client.solrj.SolrClient;
 import org.apache.solr.client.solrj.impl.CloudSolrClient;
 import org.apache.solr.client.solrj.impl.HttpSolrClient;
@@ -44,7 +44,9 @@ public class SolrClientCache implements Serializable {
     if (solrClients.containsKey(zkHost)) {
       client = (CloudSolrClient) solrClients.get(zkHost);
     } else {
-      client = new CloudSolrClient(zkHost);
+      client = new CloudSolrClient.Builder()
+          .withZkHost(zkHost)
+          .build();
       client.connect();
       solrClients.put(zkHost, client);
     }
@@ -57,7 +59,8 @@ public class SolrClientCache implements Serializable {
     if (solrClients.containsKey(host)) {
       client = (HttpSolrClient) solrClients.get(host);
     } else {
-      client = new HttpSolrClient(host);
+      client = new HttpSolrClient.Builder(host)
+          .build();
       solrClients.put(host, client);
     }
     return client;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b02b026b/solr/solrj/src/java/org/apache/solr/client/solrj/io/sql/DatabaseMetaDataImpl.java
----------------------------------------------------------------------
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 d316c83..53f5c8d 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
@@ -29,7 +29,7 @@ import org.apache.solr.client.solrj.SolrClient;
 import org.apache.solr.client.solrj.SolrQuery;
 import org.apache.solr.client.solrj.SolrServerException;
 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.response.QueryResponse;
 import org.apache.solr.common.util.SimpleOrderedMap;
 
@@ -119,7 +119,7 @@ class DatabaseMetaDataImpl implements DatabaseMetaData {
     for (String node : liveNodes) {
       try {
         String nodeURL = cloudSolrClient.getZkStateReader().getBaseUrlForNodeName(node);
-        solrClient = new HttpSolrClient(nodeURL);
+        solrClient = new Builder(nodeURL).build();
 
         QueryResponse rsp = solrClient.query(sysQuery);
         return String.valueOf(((SimpleOrderedMap) rsp.getResponse().get("lucene")).get("solr-spec-version"));

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b02b026b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/CloudSolrStream.java
----------------------------------------------------------------------
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 07e6cb1..c9c7b22 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
@@ -34,6 +34,7 @@ import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Future;
 
 import org.apache.solr.client.solrj.impl.CloudSolrClient;
+import org.apache.solr.client.solrj.impl.CloudSolrClient.Builder;
 import org.apache.solr.client.solrj.io.SolrClientCache;
 import org.apache.solr.client.solrj.io.Tuple;
 import org.apache.solr.client.solrj.io.comp.ComparatorOrder;
@@ -236,7 +237,9 @@ public class CloudSolrStream extends TupleStream implements Expressible {
     if(this.cache != null) {
       this.cloudSolrClient = this.cache.getCloudSolrClient(zkHost);
     } else {
-      this.cloudSolrClient = new CloudSolrClient(zkHost);
+      this.cloudSolrClient = new Builder()
+          .withZkHost(zkHost)
+          .build();
       this.cloudSolrClient.connect();
     }
     constructStreams();
@@ -476,4 +479,4 @@ public class CloudSolrStream extends TupleStream implements Expressible {
       }
     }
   }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b02b026b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/FacetStream.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/FacetStream.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/FacetStream.java
index e4ae04c..3474257 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/FacetStream.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/FacetStream.java
@@ -19,7 +19,6 @@ package org.apache.solr.client.solrj.io.stream;
 import java.io.IOException;
 import java.util.HashMap;
 import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
@@ -27,6 +26,7 @@ import java.util.Collections;
 import java.util.Map.Entry;
 
 import org.apache.solr.client.solrj.impl.CloudSolrClient;
+import org.apache.solr.client.solrj.impl.CloudSolrClient.Builder;
 import org.apache.solr.client.solrj.io.SolrClientCache;
 import org.apache.solr.client.solrj.io.Tuple;
 import org.apache.solr.client.solrj.io.comp.ComparatorOrder;
@@ -281,7 +281,9 @@ public class FacetStream extends TupleStream implements Expressible  {
     if(cache != null) {
       cloudSolrClient = cache.getCloudSolrClient(zkHost);
     } else {
-      cloudSolrClient = new CloudSolrClient(zkHost);
+      cloudSolrClient = new Builder()
+          .withZkHost(zkHost)
+          .build();
     }
 
     FieldComparator[] adjustedSorts = adjustSorts(buckets, bucketSorts);
@@ -479,4 +481,4 @@ public class FacetStream extends TupleStream implements Expressible  {
       return bucketSorts[0];
     }
   }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b02b026b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/SolrStream.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/SolrStream.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/SolrStream.java
index 1c149cc..7ff8a4e 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/SolrStream.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/SolrStream.java
@@ -86,7 +86,7 @@ public class SolrStream extends TupleStream {
 
 
     if(cache == null) {
-      client = new HttpSolrClient(baseUrl);
+      client = new HttpSolrClient.Builder(baseUrl).build();
     } else {
       client = cache.getHttpSolrClient(baseUrl);
     }
@@ -230,4 +230,4 @@ public class SolrStream extends TupleStream {
 
     return fields;
   }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b02b026b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/StatsStream.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/StatsStream.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/StatsStream.java
index 478bc56..6ef49ea 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/StatsStream.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/StatsStream.java
@@ -25,6 +25,7 @@ import java.util.Map;
 import java.util.Map.Entry;
 
 import org.apache.solr.client.solrj.impl.CloudSolrClient;
+import org.apache.solr.client.solrj.impl.CloudSolrClient.Builder;
 import org.apache.solr.client.solrj.io.SolrClientCache;
 import org.apache.solr.client.solrj.io.Tuple;
 import org.apache.solr.client.solrj.io.comp.StreamComparator;
@@ -162,7 +163,9 @@ public class StatsStream extends TupleStream implements Expressible  {
     if(cache != null) {
       cloudSolrClient = cache.getCloudSolrClient(zkHost);
     } else {
-      cloudSolrClient = new CloudSolrClient(zkHost);
+      cloudSolrClient = new Builder()
+          .withZkHost(zkHost)
+          .build();
     }
 
     ModifiableSolrParams params = getParams(this.props);
@@ -290,4 +293,4 @@ public class StatsStream extends TupleStream implements Expressible  {
       map.put(stat+"("+field+")", val);
     }
   }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b02b026b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/TopicStream.java
----------------------------------------------------------------------
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 a52e8f9..e3434fc 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
@@ -33,7 +33,7 @@ import java.util.TreeSet;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Future;
 
-import org.apache.solr.client.solrj.impl.CloudSolrClient;
+import org.apache.solr.client.solrj.impl.CloudSolrClient.Builder;
 import org.apache.solr.client.solrj.impl.HttpSolrClient;
 import org.apache.solr.client.solrj.io.Tuple;
 import org.apache.solr.client.solrj.io.comp.ComparatorOrder;
@@ -218,7 +218,9 @@ public class TopicStream extends CloudSolrStream implements Expressible  {
     if(cache != null) {
       cloudSolrClient = cache.getCloudSolrClient(zkHost);
     } else {
-      cloudSolrClient = new CloudSolrClient(zkHost);
+      cloudSolrClient = new Builder()
+          .withZkHost(zkHost)
+          .build();
       this.cloudSolrClient.connect();
     }
 
@@ -474,4 +476,4 @@ public class TopicStream extends CloudSolrStream implements Expressible  {
       throw new IOException(e);
     }
   }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b02b026b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/UpdateStream.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/UpdateStream.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/UpdateStream.java
index 67e52e6..9ddd381 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/UpdateStream.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/UpdateStream.java
@@ -26,6 +26,7 @@ import java.util.Map;
 
 import org.apache.solr.client.solrj.SolrServerException;
 import org.apache.solr.client.solrj.impl.CloudSolrClient;
+import org.apache.solr.client.solrj.impl.CloudSolrClient.Builder;
 import org.apache.solr.client.solrj.io.SolrClientCache;
 import org.apache.solr.client.solrj.io.Tuple;
 import org.apache.solr.client.solrj.io.comp.StreamComparator;
@@ -219,7 +220,9 @@ public class UpdateStream extends TupleStream implements Expressible {
     if(this.cache != null) {
       this.cloudSolrClient = this.cache.getCloudSolrClient(zkHost);
     } else {
-      this.cloudSolrClient = new CloudSolrClient(zkHost);
+      this.cloudSolrClient = new Builder()
+          .withZkHost(zkHost)
+          .build();
       this.cloudSolrClient.connect();
     }
   }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b02b026b/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleBinaryTest.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleBinaryTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleBinaryTest.java
index 1d70cd9..dc53517 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleBinaryTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleBinaryTest.java
@@ -40,7 +40,7 @@ public class SolrExampleBinaryTest extends SolrExampleTests {
     try {
       // setup the server...
       String url = jetty.getBaseUrl().toString() + "/collection1";
-      HttpSolrClient client = new HttpSolrClient( url );
+      HttpSolrClient client = getHttpSolrClient(url);
       client.setConnectionTimeout(DEFAULT_CONNECTION_TIMEOUT);
       client.setUseMultiPartPost(random().nextBoolean());
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b02b026b/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTests.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTests.java b/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTests.java
index 6547bc1..1dd074e 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTests.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTests.java
@@ -220,7 +220,7 @@ abstract public class SolrExampleTests extends SolrExampleTestsBase
     if (jetty != null) {
       // check system wide system handler + "/admin/info/system"
       String url = jetty.getBaseUrl().toString();
-      try (HttpSolrClient adminClient = new HttpSolrClient(url)) {
+      try (HttpSolrClient adminClient = getHttpSolrClient(url)) {
         SolrQuery q = new SolrQuery();
         q.set("qt", "/admin/info/system");
         QueryResponse rsp = adminClient.query(q);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b02b026b/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleXMLTest.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleXMLTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleXMLTest.java
index 338e449..92ab1ec 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleXMLTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleXMLTest.java
@@ -37,7 +37,7 @@ public class SolrExampleXMLTest extends SolrExampleTests {
   public SolrClient createNewSolrClient() {
     try {
       String url = jetty.getBaseUrl().toString() + "/collection1";
-      HttpSolrClient client = new HttpSolrClient(url);
+      HttpSolrClient client = getHttpSolrClient(url);
       client.setUseMultiPartPost(random().nextBoolean());
       client.setConnectionTimeout(DEFAULT_CONNECTION_TIMEOUT);
       client.setParser(new XMLResponseParser());

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b02b026b/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExceptionTest.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExceptionTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExceptionTest.java
index 9fbaffb..6b92213 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExceptionTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExceptionTest.java
@@ -16,6 +16,8 @@
  */
 package org.apache.solr.client.solrj;
 
+import static org.apache.solr.SolrTestCaseJ4.getHttpSolrClient;
+
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.lucene.util.LuceneTestCase;
 import org.apache.solr.client.solrj.impl.HttpClientUtil;
@@ -38,7 +40,7 @@ public class SolrExceptionTest extends LuceneTestCase {
       // switched to a local address to avoid going out on the net, ns lookup issues, etc.
       // set a 1ms timeout to let the connection fail faster.
       httpClient = HttpClientUtil.createClient(null);
-      try (HttpSolrClient client = new HttpSolrClient("http://[ff01::114]:11235/solr/", httpClient)) {
+      try (HttpSolrClient client = getHttpSolrClient("http://[ff01::114]:11235/solr/", httpClient)) {
         client.setConnectionTimeout(1);
         SolrQuery query = new SolrQuery("test123");
         client.query(query);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b02b026b/solr/solrj/src/test/org/apache/solr/client/solrj/SolrSchemalessExampleTest.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/SolrSchemalessExampleTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/SolrSchemalessExampleTest.java
index 317d4cd..443e59e 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/SolrSchemalessExampleTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/SolrSchemalessExampleTest.java
@@ -134,7 +134,7 @@ public class SolrSchemalessExampleTest extends SolrExampleTestsBase {
     try {
       // setup the server...
       String url = jetty.getBaseUrl().toString() + "/collection1";
-      HttpSolrClient client = new HttpSolrClient(url);
+      HttpSolrClient client = getHttpSolrClient(url);
       client.setConnectionTimeout(DEFAULT_CONNECTION_TIMEOUT);
       client.setUseMultiPartPost(random().nextBoolean());
       

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b02b026b/solr/solrj/src/test/org/apache/solr/client/solrj/TestLBHttpSolrClient.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/TestLBHttpSolrClient.java b/solr/solrj/src/test/org/apache/solr/client/solrj/TestLBHttpSolrClient.java
index 70cd77d..64e90c3 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/TestLBHttpSolrClient.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/TestLBHttpSolrClient.java
@@ -109,7 +109,7 @@ public class TestLBHttpSolrClient extends SolrTestCaseJ4 {
       docs.add(doc);
     }
     SolrResponseBase resp;
-    try (HttpSolrClient client = new HttpSolrClient(solrInstance.getUrl(), httpClient)) {
+    try (HttpSolrClient client = getHttpSolrClient(solrInstance.getUrl(), httpClient)) {
       resp = client.add(docs);
       assertEquals(0, resp.getStatus());
       resp = client.commit();
@@ -133,7 +133,7 @@ public class TestLBHttpSolrClient extends SolrTestCaseJ4 {
     for (int i = 0; i < solr.length; i++) {
       s[i] = solr[i].getUrl();
     }
-    LBHttpSolrClient client = new LBHttpSolrClient(httpClient, s);
+    LBHttpSolrClient client = getLBHttpSolrClient(httpClient, s);
     client.setAliveCheckInterval(500);
     SolrQuery solrQuery = new SolrQuery("*:*");
     Set<String> names = new HashSet<>();
@@ -171,7 +171,7 @@ public class TestLBHttpSolrClient extends SolrTestCaseJ4 {
   }
 
   public void testTwoServers() throws Exception {
-    LBHttpSolrClient client = new LBHttpSolrClient(httpClient, solr[0].getUrl(), solr[1].getUrl());
+    LBHttpSolrClient client = getLBHttpSolrClient(httpClient, solr[0].getUrl(), solr[1].getUrl());
     client.setAliveCheckInterval(500);
     SolrQuery solrQuery = new SolrQuery("*:*");
     QueryResponse resp = null;
@@ -206,7 +206,7 @@ public class TestLBHttpSolrClient extends SolrTestCaseJ4 {
 
     CloseableHttpClient myHttpClient = HttpClientUtil.createClient(null);
     try {
-      LBHttpSolrClient client = new LBHttpSolrClient(myHttpClient, s);
+      LBHttpSolrClient client = getLBHttpSolrClient(myHttpClient, s);
       client.setConnectionTimeout(250);
       client.setSoTimeout(250);
       client.setAliveCheckInterval(500);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b02b026b/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleJettyTest.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleJettyTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleJettyTest.java
index d8347ce..a8832e7 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleJettyTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleJettyTest.java
@@ -55,7 +55,7 @@ public class SolrExampleJettyTest extends SolrExampleTests {
     try {
       // setup the server...
       String url = "http" + (isSSLMode() ? "s" : "") +  "://127.0.0.1/?core=xxx";
-      HttpSolrClient client = new HttpSolrClient(url);
+      HttpSolrClient client = getHttpSolrClient(url);
       Assert.fail("HttpSolrServer should not allow a path with a parameter: " + client.getBaseURL());
     }
     catch( Exception ex ) {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b02b026b/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleStreamingTest.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleStreamingTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleStreamingTest.java
index c3fa784..093238d 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleStreamingTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleStreamingTest.java
@@ -80,14 +80,8 @@ public class SolrExampleStreamingTest extends SolrExampleTests {
   public void testWaitOptions() throws Exception {
     // SOLR-3903
     final List<Throwable> failures = new ArrayList<>();
-    try (ConcurrentUpdateSolrClient concurrentClient = new ConcurrentUpdateSolrClient
-      (jetty.getBaseUrl().toString() + "/collection1", 2, 2) {
-        @Override
-        public void handleError(Throwable ex) {
-          failures.add(ex);
-        }
-      }) {
-
+    final String serverUrl = jetty.getBaseUrl().toString() + "/collection1";
+    try (ConcurrentUpdateSolrClient concurrentClient = new FailureRecordingConcurrentUpdateSolrClient(serverUrl, 2, 2)) {
       int docId = 42;
       for (UpdateRequest.ACTION action : EnumSet.allOf(UpdateRequest.ACTION.class)) {
         for (boolean waitSearch : Arrays.asList(true, false)) {
@@ -110,5 +104,18 @@ public class SolrExampleStreamingTest extends SolrExampleTests {
                    null, failures.get(0));
     }
   }
+  
+  class FailureRecordingConcurrentUpdateSolrClient extends ConcurrentUpdateSolrClient {
+    private final List<Throwable> failures = new ArrayList<>();
+    
+    public FailureRecordingConcurrentUpdateSolrClient(String serverUrl, int queueSize, int numThreads) {
+      super(serverUrl, null, queueSize, numThreads, null, false);
+    }
+    
+    @Override
+    public void handleError(Throwable ex) {
+      failures.add(ex);
+    }
+  }
 
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b02b026b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/BasicHttpSolrClientTest.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/BasicHttpSolrClientTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/BasicHttpSolrClientTest.java
index ad20e95..11d2784 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/BasicHttpSolrClientTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/BasicHttpSolrClientTest.java
@@ -16,6 +16,10 @@
  */
 package org.apache.solr.client.solrj.impl;
 
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.invoke.MethodHandles;
@@ -31,11 +35,6 @@ import java.util.Map;
 import java.util.Set;
 import java.util.TreeSet;
 
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
 import org.apache.http.Header;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpException;
@@ -209,7 +208,7 @@ public class BasicHttpSolrClientTest extends SolrJettyTestBase {
   public void testTimeout() throws Exception {
 
     SolrQuery q = new SolrQuery("*:*");
-    try (HttpSolrClient client = new HttpSolrClient(jetty.getBaseUrl().toString() + "/slow/foo")) {
+    try(HttpSolrClient client = getHttpSolrClient(jetty.getBaseUrl().toString() + "/slow/foo")) {
       client.setSoTimeout(2000);
       client.query(q, METHOD.GET);
       fail("No exception thrown.");
@@ -229,7 +228,7 @@ public class BasicHttpSolrClientTest extends SolrJettyTestBase {
     assertEquals(status + " didn't generate an UNKNOWN error code, someone modified the list of valid ErrorCode's w/o changing this test to work a different way",
         ErrorCode.UNKNOWN, ErrorCode.getErrorCode(status));
 
-    try ( HttpSolrClient client = new HttpSolrClient(jetty.getBaseUrl().toString() + "/debug/foo")) {
+    try (HttpSolrClient client = getHttpSolrClient(jetty.getBaseUrl().toString() + "/debug/foo")) {
       DebugServlet.setErrorCode(status);
       try {
         SolrQuery q = new SolrQuery("foo");
@@ -246,7 +245,7 @@ public class BasicHttpSolrClientTest extends SolrJettyTestBase {
   @Test
   public void testQuery() throws Exception {
     DebugServlet.clear();
-    try (HttpSolrClient client = new HttpSolrClient(jetty.getBaseUrl().toString() + "/debug/foo")) {
+    try (HttpSolrClient client = getHttpSolrClient(jetty.getBaseUrl().toString() + "/debug/foo")) {
       SolrQuery q = new SolrQuery("foo");
       q.setParam("a", "\u1234");
       try {
@@ -370,7 +369,7 @@ public class BasicHttpSolrClientTest extends SolrJettyTestBase {
   @Test
   public void testDelete() throws Exception {
     DebugServlet.clear();
-    try (HttpSolrClient client = new HttpSolrClient(jetty.getBaseUrl().toString() + "/debug/foo")) {
+    try (HttpSolrClient client = getHttpSolrClient(jetty.getBaseUrl().toString() + "/debug/foo")) {
       try {
         client.deleteById("id");
       } catch (ParseException ignored) {}
@@ -411,7 +410,7 @@ public class BasicHttpSolrClientTest extends SolrJettyTestBase {
   @Test
   public void testGetById() throws Exception {
     DebugServlet.clear();
-    try (HttpSolrClient client = new HttpSolrClient(jetty.getBaseUrl().toString() + "/debug/foo")) {
+    try (HttpSolrClient client = getHttpSolrClient(jetty.getBaseUrl().toString() + "/debug/foo")) {
       Collection<String> ids = Collections.singletonList("a");
       try {
         client.getById("a");
@@ -434,7 +433,7 @@ public class BasicHttpSolrClientTest extends SolrJettyTestBase {
   @Test
   public void testUpdate() throws Exception {
     DebugServlet.clear();
-    try (HttpSolrClient client = new HttpSolrClient(jetty.getBaseUrl().toString() + "/debug/foo")) {
+    try (HttpSolrClient client = getHttpSolrClient(jetty.getBaseUrl().toString() + "/debug/foo")) {
       UpdateRequest req = new UpdateRequest();
       req.add(new SolrInputDocument());
       req.setParam("a", "\u1234");
@@ -498,7 +497,8 @@ public class BasicHttpSolrClientTest extends SolrJettyTestBase {
   
   @Test
   public void testRedirect() throws Exception {
-    try (HttpSolrClient client = new HttpSolrClient(jetty.getBaseUrl().toString() + "/redirect/foo")) {
+    final String clientUrl = jetty.getBaseUrl().toString() + "/redirect/foo";
+    try (HttpSolrClient client = getHttpSolrClient(clientUrl)) {
       SolrQuery q = new SolrQuery("*:*");
       // default = false
       try {
@@ -527,7 +527,8 @@ public class BasicHttpSolrClientTest extends SolrJettyTestBase {
   public void testCompression() throws Exception {
     SolrQuery q = new SolrQuery("*:*");
     
-    try (HttpSolrClient client = new HttpSolrClient(jetty.getBaseUrl().toString() + "/debug/foo")) {
+    final String clientUrl = jetty.getBaseUrl().toString() + "/debug/foo";
+    try (HttpSolrClient client = getHttpSolrClient(clientUrl)) {
       // verify request header gets set
       DebugServlet.clear();
       try {
@@ -536,14 +537,14 @@ public class BasicHttpSolrClientTest extends SolrJettyTestBase {
       assertNull(DebugServlet.headers.toString(), DebugServlet.headers.get("Accept-Encoding")); 
     }
     
-    try (HttpSolrClient client = new HttpSolrClient(jetty.getBaseUrl().toString() + "/debug/foo", null, null, true)) {
+    try (HttpSolrClient client = getHttpSolrClient(clientUrl, null, null, true)) {
       try {
         client.query(q);
       } catch (ParseException ignored) {}
       assertNotNull(DebugServlet.headers.get("Accept-Encoding"));
     }
     
-    try (HttpSolrClient client = new HttpSolrClient(jetty.getBaseUrl().toString() + "/debug/foo", null, null, false)) {
+    try (HttpSolrClient client = getHttpSolrClient(clientUrl, null, null, false)) {
       try {
         client.query(q);
       } catch (ParseException ignored) {}
@@ -577,7 +578,7 @@ public class BasicHttpSolrClientTest extends SolrJettyTestBase {
     }
     
     // verify compressed response can be handled
-    try (HttpSolrClient client = new HttpSolrClient(jetty.getBaseUrl().toString() + "/collection1")) {
+    try (HttpSolrClient client = getHttpSolrClient(jetty.getBaseUrl().toString() + "/collection1")) {
       q = new SolrQuery("foo");
       QueryResponse response = client.query(q);
       assertEquals(0, response.getStatus());
@@ -587,7 +588,7 @@ public class BasicHttpSolrClientTest extends SolrJettyTestBase {
   @Test
   public void testCollectionParameters() throws IOException, SolrServerException {
 
-    try (HttpSolrClient client = new HttpSolrClient(jetty.getBaseUrl().toString())) {
+    try (HttpSolrClient client = getHttpSolrClient(jetty.getBaseUrl().toString())) {
       SolrInputDocument doc = new SolrInputDocument();
       doc.addField("id", "collection");
       client.add("collection1", doc);
@@ -596,7 +597,8 @@ public class BasicHttpSolrClientTest extends SolrJettyTestBase {
       assertEquals(1, client.query("collection1", new SolrQuery("id:collection")).getResults().getNumFound());
     }
 
-    try (HttpSolrClient client = new HttpSolrClient(jetty.getBaseUrl().toString() + "/collection1")) {
+    final String collection1Url = jetty.getBaseUrl().toString() + "/collection1";
+    try (HttpSolrClient client = getHttpSolrClient(collection1Url)) {
       assertEquals(1, client.query(new SolrQuery("id:collection")).getResults().getNumFound());
     }
 
@@ -606,7 +608,7 @@ public class BasicHttpSolrClientTest extends SolrJettyTestBase {
   public void testGetRawStream() throws SolrServerException, IOException{
     CloseableHttpClient client = HttpClientUtil.createClient(null);
     try {
-      HttpSolrClient solrClient = new HttpSolrClient(jetty.getBaseUrl().toString() + "/collection1",
+      HttpSolrClient solrClient = getHttpSolrClient(jetty.getBaseUrl().toString() + "/collection1",
           client, null);
       QueryRequest req = new QueryRequest();
       NamedList response = solrClient.request(req);
@@ -693,8 +695,8 @@ public class BasicHttpSolrClientTest extends SolrJettyTestBase {
     HttpClientUtil.addRequestInterceptor(changeRequestInterceptor);
     HttpClientUtil.addRequestInterceptor(cookieSettingRequestInterceptor);    
 
-    try(HttpSolrClient server = new HttpSolrClient(jetty.getBaseUrl().toString() +
-        "/debug/foo")) {
+    final String clientUrl = jetty.getBaseUrl().toString() + "/debug/foo";
+    try(HttpSolrClient server = getHttpSolrClient(clientUrl)) {
 
       SolrQuery q = new SolrQuery("foo");
       q.setParam("a", "\u1234");
@@ -765,7 +767,8 @@ public class BasicHttpSolrClientTest extends SolrJettyTestBase {
   @Test
   public void testQueryString() throws Exception {
 
-    try (HttpSolrClient client = new HttpSolrClient(jetty.getBaseUrl().toString() + "/debug/foo")) {
+    final String clientUrl = jetty.getBaseUrl().toString() + "/debug/foo";
+    try(HttpSolrClient client = getHttpSolrClient(clientUrl)) {
       // test without request query params
       DebugServlet.clear();
       client.setQueryParams(setOf("serverOnly"));

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b02b026b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudSolrClientBuilderTest.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudSolrClientBuilderTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudSolrClientBuilderTest.java
new file mode 100644
index 0000000..57692c7
--- /dev/null
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudSolrClientBuilderTest.java
@@ -0,0 +1,90 @@
+package org.apache.solr.client.solrj.impl;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+import org.apache.lucene.util.LuceneTestCase;
+import org.apache.solr.client.solrj.impl.CloudSolrClient.Builder;
+import org.junit.Test;
+
+/*
+ * 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.
+ */
+
+public class CloudSolrClientBuilderTest extends LuceneTestCase {
+  private static final String ANY_CHROOT = "/ANY_CHROOT";
+  private static final String ANY_ZK_HOST = "ANY_ZK_HOST";
+  private static final String ANY_OTHER_ZK_HOST = "ANY_OTHER_ZK_HOST";
+
+  @Test(expected = IllegalArgumentException.class)
+  public void testNoZkHostSpecified() {
+    new Builder()
+      .withZkChroot(ANY_CHROOT)
+      .build();
+  }
+  
+  @Test
+  public void testSingleZkHostSpecified() throws IOException {
+    try(CloudSolrClient createdClient = new Builder()
+        .withZkHost(ANY_ZK_HOST)
+        .withZkChroot(ANY_CHROOT)
+        .build()) {
+      final String clientZkHost = createdClient.getZkHost();
+    
+      assertTrue(clientZkHost.contains(ANY_ZK_HOST));
+    }
+  }
+  
+  @Test
+  public void testSeveralZkHostsSpecifiedSingly() throws IOException {
+    try (CloudSolrClient createdClient = new Builder()
+        .withZkHost(ANY_ZK_HOST)
+        .withZkHost(ANY_OTHER_ZK_HOST)
+        .withZkChroot(ANY_CHROOT)
+        .build()) {
+      final String clientZkHost = createdClient.getZkHost();
+    
+      assertTrue(clientZkHost.contains(ANY_ZK_HOST));
+      assertTrue(clientZkHost.contains(ANY_OTHER_ZK_HOST));
+    }
+  }
+  
+  @Test
+  public void testSeveralZkHostsSpecifiedTogether() throws IOException {
+    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()) {
+      final String clientZkHost = createdClient.getZkHost();
+    
+      assertTrue(clientZkHost.contains(ANY_ZK_HOST));
+      assertTrue(clientZkHost.contains(ANY_OTHER_ZK_HOST));
+    }
+  }
+  
+  @Test
+  public void testByDefaultConfiguresClientToSendUpdatesOnlyToShardLeaders() throws IOException {
+    try(CloudSolrClient createdClient = new Builder()
+        .withZkHost(ANY_ZK_HOST)
+        .withZkChroot(ANY_CHROOT)
+        .build()) {
+      assertTrue(createdClient.isUpdatesToLeaders() == true);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b02b026b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudSolrClientTest.java
----------------------------------------------------------------------
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 8c50e8e..5864389 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
@@ -225,7 +225,7 @@ public class CloudSolrClientTest extends AbstractFullDistribZkTestBase {
       params.add("q", "id:" + id);
       params.add("distrib", "false");
       QueryRequest queryRequest = new QueryRequest(params);
-      try (HttpSolrClient solrClient = new HttpSolrClient(url)) {
+      try (HttpSolrClient solrClient = getHttpSolrClient(url)) {
         QueryResponse queryResponse = queryRequest.process(solrClient);
         SolrDocumentList docList = queryResponse.getResults();
         assertTrue(docList.getNumFound() == 1);
@@ -247,7 +247,7 @@ public class CloudSolrClientTest extends AbstractFullDistribZkTestBase {
     assertTrue(docs.getNumFound() == 0);
     
     // Test Multi-Threaded routed updates for UpdateRequest
-    try (CloudSolrClient threadedClient = new CloudSolrClient(zkServer.getZkAddress())) {
+    try (CloudSolrClient threadedClient = getCloudSolrClient(zkServer.getZkAddress())) {
       threadedClient.setParallelUpdates(true);
       threadedClient.setDefaultCollection(collectionName);
       response = threadedClient.request(request);
@@ -266,7 +266,7 @@ public class CloudSolrClientTest extends AbstractFullDistribZkTestBase {
         params.add("q", "id:" + id);
         params.add("distrib", "false");
         QueryRequest queryRequest = new QueryRequest(params);
-        try (HttpSolrClient solrClient = new HttpSolrClient(url)) {
+        try (HttpSolrClient solrClient = getHttpSolrClient(url)) {
           QueryResponse queryResponse = queryRequest.process(solrClient);
           SolrDocumentList docList = queryResponse.getResults();
           assertTrue(docList.getNumFound() == 1);
@@ -480,7 +480,7 @@ public class CloudSolrClientTest extends AbstractFullDistribZkTestBase {
       SolrServerException, IOException {
 
     NamedList<Object> resp;
-    try (HttpSolrClient client = new HttpSolrClient(baseUrl + "/"+ collectionName)) {
+    try (HttpSolrClient client = getHttpSolrClient(baseUrl + "/"+ collectionName)) {
       client.setConnectionTimeout(15000);
       client.setSoTimeout(60000);
       ModifiableSolrParams params = new ModifiableSolrParams();
@@ -552,7 +552,8 @@ public class CloudSolrClientTest extends AbstractFullDistribZkTestBase {
       SolrQuery q = new SolrQuery().setQuery("*:*");
       HttpSolrClient.RemoteSolrException sse = null;
 
-      try (HttpSolrClient solrClient = new HttpSolrClient(r.getStr(ZkStateReader.BASE_URL_PROP) + "/"+collectionName)) {
+      final String url = r.getStr(ZkStateReader.BASE_URL_PROP) + "/" +collectionName;
+      try (HttpSolrClient solrClient = getHttpSolrClient(url)) {
 
         log.info("should work query, result {}", solrClient.query(q));
         //no problem
@@ -588,7 +589,9 @@ public class CloudSolrClientTest extends AbstractFullDistribZkTestBase {
       log.info("the node which does not serve this collection{} ",theNode);
       assertNotNull(theNode);
 
-      try (SolrClient solrClient = new HttpSolrClient(theNode + "/"+collectionName)) {
+      
+      final String solrClientUrl = theNode + "/" + collectionName;
+      try (SolrClient solrClient = getHttpSolrClient(solrClientUrl)) {
 
         q.setParam(CloudSolrClient.STATE_VERSION, collectionName + ":" + (coll.getZNodeVersion()-1));
         try {
@@ -605,7 +608,7 @@ public class CloudSolrClientTest extends AbstractFullDistribZkTestBase {
   }
 
   public void testShutdown() throws IOException {
-    try (CloudSolrClient client = new CloudSolrClient("[ff01::114]:33332")) {
+    try (CloudSolrClient client = getCloudSolrClient("[ff01::114]:33332")) {
       client.setZkConnectTimeout(100);
       client.connect();
       fail("Expected exception");
@@ -622,7 +625,7 @@ public class CloudSolrClientTest extends AbstractFullDistribZkTestBase {
     exception.expect(SolrException.class);
     exception.expectMessage("cluster not found/not ready");
 
-    try (CloudSolrClient client = new CloudSolrClient(zkServer.getZkAddress() + "/xyz/foo")) {
+    try (CloudSolrClient client = getCloudSolrClient(zkServer.getZkAddress() + "/xyz/foo")) {
       client.setDefaultCollection(DEFAULT_COLLECTION);
       client.setZkClientTimeout(1000 * 60);
       client.connect();
@@ -632,7 +635,7 @@ public class CloudSolrClientTest extends AbstractFullDistribZkTestBase {
 
   public void customHttpClientTest() throws IOException {
     CloseableHttpClient client = HttpClientUtil.createClient(null);
-    try (CloudSolrClient solrClient = new CloudSolrClient(zkServer.getZkAddress(), client)) {
+    try (CloudSolrClient solrClient = getCloudSolrClient(zkServer.getZkAddress(), client)) {
 
       assertTrue(solrClient.getLbClient().getHttpClient() == client);
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b02b026b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ConcurrentUpdateSolrClientBuilderTest.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ConcurrentUpdateSolrClientBuilderTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ConcurrentUpdateSolrClientBuilderTest.java
new file mode 100644
index 0000000..3389b7f
--- /dev/null
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ConcurrentUpdateSolrClientBuilderTest.java
@@ -0,0 +1,33 @@
+package org.apache.solr.client.solrj.impl;
+
+import org.apache.lucene.util.LuceneTestCase;
+import org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrClient.Builder;
+import org.junit.Test;
+
+/*
+ * 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.
+ */
+
+/**
+ * Unit tests for {@link Builder}.
+ */
+public class ConcurrentUpdateSolrClientBuilderTest extends LuceneTestCase {
+
+  @Test(expected = IllegalArgumentException.class)
+  public void testRejectsMissingBaseSolrUrl() {
+    new Builder(null).build();
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b02b026b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ConcurrentUpdateSolrClientTest.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ConcurrentUpdateSolrClientTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ConcurrentUpdateSolrClientTest.java
index bd5e6a2..5e2baeb 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ConcurrentUpdateSolrClientTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ConcurrentUpdateSolrClientTest.java
@@ -147,17 +147,8 @@ public class ConcurrentUpdateSolrClientTest extends SolrJettyTestBase {
     final StringBuilder errors = new StringBuilder();     
     
     @SuppressWarnings("serial")
-    ConcurrentUpdateSolrClient concurrentClient = new ConcurrentUpdateSolrClient(serverUrl, cussQueueSize, cussThreadCount) {
-      @Override
-      public void handleError(Throwable ex) {
-        errorCounter.incrementAndGet();
-        errors.append(" "+ex);
-      }
-      @Override
-      public void onSuccess(HttpResponse resp) {
-        successCounter.incrementAndGet();
-      }
-    };
+    ConcurrentUpdateSolrClient concurrentClient = new OutcomeCountingConcurrentUpdateSolrClient(serverUrl, cussQueueSize,
+        cussThreadCount, successCounter, errorCounter, errors);
     
     concurrentClient.setPollQueueTime(0);
     
@@ -224,4 +215,28 @@ public class ConcurrentUpdateSolrClientTest extends SolrJettyTestBase {
       }      
     }    
   }
+  
+  class OutcomeCountingConcurrentUpdateSolrClient extends ConcurrentUpdateSolrClient {
+    private final AtomicInteger successCounter;
+    private final AtomicInteger failureCounter;
+    private final StringBuilder errors;
+    public OutcomeCountingConcurrentUpdateSolrClient(String serverUrl, int queueSize, int threadCount,
+        AtomicInteger successCounter, AtomicInteger failureCounter, StringBuilder errors) {
+      super(serverUrl, null, queueSize, threadCount, null, false);
+      
+      this.successCounter = successCounter;
+      this.failureCounter = failureCounter;
+      this.errors = errors;
+    }
+    
+    @Override
+    public void handleError(Throwable ex) {
+      failureCounter.incrementAndGet();
+      errors.append(" "+ex);
+    }
+    @Override
+    public void onSuccess(HttpResponse resp) {
+      successCounter.incrementAndGet();
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b02b026b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/HttpSolrClientBuilderTest.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/HttpSolrClientBuilderTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/HttpSolrClientBuilderTest.java
new file mode 100644
index 0000000..da56576
--- /dev/null
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/HttpSolrClientBuilderTest.java
@@ -0,0 +1,76 @@
+package org.apache.solr.client.solrj.impl;
+
+import java.io.IOException;
+
+import org.apache.http.client.HttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.lucene.util.LuceneTestCase;
+import org.apache.solr.client.solrj.ResponseParser;
+import org.apache.solr.client.solrj.impl.HttpSolrClient.Builder;
+import org.junit.Test;
+
+/*
+ * 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.
+ */
+
+/**
+ * Unit tests for {@link Builder}.
+ */
+public class HttpSolrClientBuilderTest extends LuceneTestCase {
+  private static final String ANY_BASE_SOLR_URL = "ANY_BASE_SOLR_URL";
+  private static final HttpClient ANY_HTTP_CLIENT = HttpClientBuilder.create().build();
+  private static final ResponseParser ANY_RESPONSE_PARSER = new NoOpResponseParser();
+  
+  @Test(expected = IllegalArgumentException.class)
+  public void testBaseSolrUrlIsRequired() {
+    new Builder(null)
+        .build();
+  }
+
+  @Test
+  public void testProvidesBaseSolrUrlToClient() throws IOException {
+    try (HttpSolrClient createdClient = new HttpSolrClient.Builder(ANY_BASE_SOLR_URL).build()) {
+      assertTrue(createdClient.getBaseURL().equals(ANY_BASE_SOLR_URL));
+    }
+  }
+  
+  @Test
+  public void testProvidesHttpClientToClient() throws IOException {
+    try(HttpSolrClient createdClient = new Builder(ANY_BASE_SOLR_URL)
+        .withHttpClient(ANY_HTTP_CLIENT)
+        .build()) {
+      assertTrue(createdClient.getHttpClient().equals(ANY_HTTP_CLIENT));
+    }
+  }
+  
+  @Test
+  public void testProvidesResponseParserToClient() throws IOException {
+    try(HttpSolrClient createdClient = new Builder(ANY_BASE_SOLR_URL)
+        .withResponseParser(ANY_RESPONSE_PARSER)
+        .build()) {
+      assertTrue(createdClient.getParser().equals(ANY_RESPONSE_PARSER));
+    }
+  }
+  
+  @Test
+  public void testDefaultsToBinaryResponseParserWhenNoneProvided() throws IOException {
+    try(HttpSolrClient createdClient = new Builder(ANY_BASE_SOLR_URL)
+        .build()) {
+      final ResponseParser usedParser = createdClient.getParser();
+      assertTrue(usedParser instanceof BinaryResponseParser);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b02b026b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/LBHttpSolrClientBuilderTest.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/LBHttpSolrClientBuilderTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/LBHttpSolrClientBuilderTest.java
new file mode 100644
index 0000000..6a02da5
--- /dev/null
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/LBHttpSolrClientBuilderTest.java
@@ -0,0 +1,65 @@
+package org.apache.solr.client.solrj.impl;
+
+import org.apache.http.client.HttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.lucene.util.LuceneTestCase;
+import org.apache.solr.client.solrj.impl.LBHttpSolrClient.Builder;
+import org.apache.solr.client.solrj.ResponseParser;
+import org.junit.Test;
+
+/*
+ * 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.
+ */
+
+/**
+ * Unit tests for {@link Builder}.
+ */
+public class LBHttpSolrClientBuilderTest extends LuceneTestCase {
+  private static final String ANY_BASE_SOLR_URL = "ANY_BASE_SOLR_URL";
+  private static final HttpClient ANY_HTTP_CLIENT = HttpClientBuilder.create().build();
+  private static final ResponseParser ANY_RESPONSE_PARSER = new NoOpResponseParser();
+
+  @Test
+  public void providesHttpClientToClient() {
+    try(LBHttpSolrClient createdClient = new Builder()
+        .withBaseSolrUrl(ANY_BASE_SOLR_URL)
+        .withHttpClient(ANY_HTTP_CLIENT)
+        .build()) {
+      assertTrue(createdClient.getHttpClient().equals(ANY_HTTP_CLIENT));
+    }
+  }
+  
+  @Test
+  public void providesResponseParserToClient() {
+    try(LBHttpSolrClient createdClient = new Builder()
+        .withBaseSolrUrl(ANY_BASE_SOLR_URL)
+        .withResponseParser(ANY_RESPONSE_PARSER)
+        .build()) {
+      assertTrue(createdClient.getParser().equals(ANY_RESPONSE_PARSER));
+    }
+  }
+  
+  @Test
+  public void testDefaultsToBinaryResponseParserWhenNoneProvided() {
+    try(LBHttpSolrClient createdClient = new Builder()
+        .withBaseSolrUrl(ANY_BASE_SOLR_URL)
+        .build()) {
+      final ResponseParser usedParser = createdClient.getParser();
+    
+      assertTrue(usedParser instanceof BinaryResponseParser);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b02b026b/solr/test-framework/src/java/org/apache/solr/BaseDistributedSearchTestCase.java
----------------------------------------------------------------------
diff --git a/solr/test-framework/src/java/org/apache/solr/BaseDistributedSearchTestCase.java b/solr/test-framework/src/java/org/apache/solr/BaseDistributedSearchTestCase.java
index 4ae46f8..8c6eb60 100644
--- a/solr/test-framework/src/java/org/apache/solr/BaseDistributedSearchTestCase.java
+++ b/solr/test-framework/src/java/org/apache/solr/BaseDistributedSearchTestCase.java
@@ -439,7 +439,7 @@ public abstract class BaseDistributedSearchTestCase extends SolrTestCaseJ4 {
   protected SolrClient createNewSolrClient(int port) {
     try {
       // setup the client...
-      HttpSolrClient client = new HttpSolrClient(buildUrl(port) + "/" + DEFAULT_TEST_CORENAME);
+      HttpSolrClient client = getHttpSolrClient(buildUrl(port) + "/" + DEFAULT_TEST_CORENAME);
       return client;
     }
     catch (Exception ex) {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b02b026b/solr/test-framework/src/java/org/apache/solr/SolrJettyTestBase.java
----------------------------------------------------------------------
diff --git a/solr/test-framework/src/java/org/apache/solr/SolrJettyTestBase.java b/solr/test-framework/src/java/org/apache/solr/SolrJettyTestBase.java
index 5924593..0badec1 100644
--- a/solr/test-framework/src/java/org/apache/solr/SolrJettyTestBase.java
+++ b/solr/test-framework/src/java/org/apache/solr/SolrJettyTestBase.java
@@ -154,7 +154,7 @@ abstract public class SolrJettyTestBase extends SolrTestCaseJ4
       try {
         // setup the client...
         String url = jetty.getBaseUrl().toString() + "/" + "collection1";
-        HttpSolrClient client = new HttpSolrClient( url );
+        HttpSolrClient client = getHttpSolrClient(url);
         client.setConnectionTimeout(DEFAULT_CONNECTION_TIMEOUT);
         return client;
       }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b02b026b/solr/test-framework/src/java/org/apache/solr/SolrTestCaseHS.java
----------------------------------------------------------------------
diff --git a/solr/test-framework/src/java/org/apache/solr/SolrTestCaseHS.java b/solr/test-framework/src/java/org/apache/solr/SolrTestCaseHS.java
index 4aed135..118c194 100644
--- a/solr/test-framework/src/java/org/apache/solr/SolrTestCaseHS.java
+++ b/solr/test-framework/src/java/org/apache/solr/SolrTestCaseHS.java
@@ -16,15 +16,31 @@
  */
 package org.apache.solr;
 
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.lang.invoke.MethodHandles;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Random;
+import java.util.Set;
+
 import com.google.common.base.Charsets;
 import org.apache.commons.io.FileUtils;
 import org.apache.lucene.util.IOUtils;
-import org.apache.lucene.util.LuceneTestCase;
 import org.apache.solr.client.solrj.SolrClient;
 import org.apache.solr.client.solrj.SolrServerException;
 import org.apache.solr.client.solrj.embedded.JettyConfig;
 import org.apache.solr.client.solrj.embedded.JettySolrRunner;
-import org.apache.solr.client.solrj.impl.HttpSolrClient;
 import org.apache.solr.client.solrj.impl.NoOpResponseParser;
 import org.apache.solr.client.solrj.request.QueryRequest;
 import org.apache.solr.client.solrj.request.UpdateRequest;
@@ -43,24 +59,6 @@ import org.noggit.ObjectBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.File;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-import java.lang.invoke.MethodHandles;
-import java.nio.file.Files;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Random;
-import java.util.Set;
-
 
 @SolrTestCaseJ4.SuppressSSL
 //@LuceneTestCase.SuppressCodecs({"Lucene3x","Lucene40","Lucene41","Lucene42","Lucene45","Appending","Asserting"})
@@ -418,7 +416,7 @@ public class SolrTestCaseHS extends SolrTestCaseJ4 {
 
     public SolrClient getSolrJ() {
       if (solrj == null) {
-        solrj = new HttpSolrClient(getCollectionURL());
+        solrj = getHttpSolrClient(getCollectionURL());
       }
       return solrj;
     }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b02b026b/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
----------------------------------------------------------------------
diff --git a/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java b/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
index 6b28eb8..28e5879 100644
--- a/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
+++ b/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
@@ -31,6 +31,7 @@ import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 import java.lang.invoke.MethodHandles;
+import java.net.MalformedURLException;
 import java.net.URL;
 import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
@@ -56,6 +57,7 @@ import com.carrotsearch.randomizedtesting.annotations.ThreadLeakFilters;
 import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule;
 import org.apache.commons.codec.Charsets;
 import org.apache.commons.io.FileUtils;
+import org.apache.http.client.HttpClient;
 import org.apache.lucene.analysis.MockAnalyzer;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.index.IndexWriterConfig;
@@ -66,7 +68,13 @@ import org.apache.lucene.util.LuceneTestCase.SuppressSysoutChecks;
 import org.apache.lucene.util.QuickPatchThreadsFilter;
 import org.apache.lucene.util.TestUtil;
 import org.apache.solr.client.solrj.embedded.JettyConfig;
+import org.apache.solr.client.solrj.impl.CloudSolrClient;
+import org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrClient;
 import org.apache.solr.client.solrj.impl.HttpClientUtil;
+import org.apache.solr.client.solrj.impl.HttpSolrClient;
+import org.apache.solr.client.solrj.impl.HttpSolrClient.Builder;
+import org.apache.solr.client.solrj.impl.LBHttpSolrClient;
+import org.apache.solr.client.solrj.ResponseParser;
 import org.apache.solr.client.solrj.util.ClientUtils;
 import org.apache.solr.cloud.IpTables;
 import org.apache.solr.common.SolrDocument;
@@ -2037,6 +2045,140 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
   public static Object skewed(Object likely, Object unlikely) {
     return (0 == TestUtil.nextInt(random(), 0, 9)) ? unlikely : likely;
   }
+  
+  public static CloudSolrClient getCloudSolrClient(String zkHost) {
+    if (random().nextBoolean()) {
+      return new CloudSolrClient(zkHost);
+    }
+    return new CloudSolrClient.Builder()
+        .withZkHost(zkHost)
+        .build();
+  }
+  
+  public static CloudSolrClient getCloudSolrClient(String zkHost, HttpClient httpClient) {
+    if (random().nextBoolean()) {
+      return new CloudSolrClient(zkHost, httpClient);
+    }
+    return new CloudSolrClient.Builder()
+        .withZkHost(zkHost)
+        .withHttpClient(httpClient)
+        .build();
+  }
+  
+  public static CloudSolrClient getCloudSolrClient(String zkHost, boolean shardLeadersOnly) {
+    if (random().nextBoolean()) {
+      return new CloudSolrClient(zkHost, shardLeadersOnly);
+    }
+    
+    if (shardLeadersOnly) {
+      return new CloudSolrClient.Builder()
+          .withZkHost(zkHost)
+          .sendUpdatesOnlyToShardLeaders()
+          .build();
+    }
+    return new CloudSolrClient.Builder()
+        .withZkHost(zkHost)
+        .sendUpdatesToAllReplicasInShard()
+        .build();
+  }
+  
+  public static CloudSolrClient getCloudSolrClient(String zkHost, boolean shardLeadersOnly, HttpClient httpClient) {
+    if (random().nextBoolean()) {
+      return new CloudSolrClient(zkHost, shardLeadersOnly, httpClient);
+    }
+    
+    if (shardLeadersOnly) {
+      return new CloudSolrClient.Builder()
+          .withZkHost(zkHost)
+          .withHttpClient(httpClient)
+          .sendUpdatesOnlyToShardLeaders()
+          .build();
+    }
+    return new CloudSolrClient.Builder()
+        .withZkHost(zkHost)
+        .withHttpClient(httpClient)
+        .sendUpdatesToAllReplicasInShard()
+        .build();
+  }
+  
+  public static ConcurrentUpdateSolrClient getConcurrentUpdateSolrClient(String baseSolrUrl, int queueSize, int threadCount) {
+    if (random().nextBoolean()) {
+      return new ConcurrentUpdateSolrClient(baseSolrUrl, queueSize, threadCount);
+    }
+    return new ConcurrentUpdateSolrClient.Builder(baseSolrUrl)
+        .withQueueSize(queueSize)
+        .withThreadCount(threadCount)
+        .build();
+  }
+  
+  public static ConcurrentUpdateSolrClient getConcurrentUpdateSolrClient(String baseSolrUrl, HttpClient httpClient, int queueSize, int threadCount) {
+    if (random().nextBoolean()) {
+      return new ConcurrentUpdateSolrClient(baseSolrUrl, httpClient, queueSize, threadCount);
+    }
+    return new ConcurrentUpdateSolrClient.Builder(baseSolrUrl)
+        .withHttpClient(httpClient)
+        .withQueueSize(queueSize)
+        .withThreadCount(threadCount)
+        .build();
+  }
+  
+  public static LBHttpSolrClient getLBHttpSolrClient(HttpClient client, String... solrUrls) {
+    if (random().nextBoolean()) {
+      return new LBHttpSolrClient(client, solrUrls);
+    }
+    
+    return new LBHttpSolrClient.Builder()
+        .withHttpClient(client)
+        .withBaseSolrUrls(solrUrls)
+        .build();
+  }
+  
+  public static LBHttpSolrClient getLBHttpSolrClient(String... solrUrls) throws MalformedURLException {
+    if (random().nextBoolean()) {
+      return new LBHttpSolrClient(solrUrls);
+    }
+    return new LBHttpSolrClient.Builder()
+        .withBaseSolrUrls(solrUrls)
+        .build();
+  }
+  
+  public static HttpSolrClient getHttpSolrClient(String url, HttpClient httpClient, ResponseParser responseParser, boolean compression) {
+    if(random().nextBoolean()) {
+      return new HttpSolrClient(url, httpClient, responseParser, compression);
+    }
+    return new Builder(url)
+        .withHttpClient(httpClient)
+        .withResponseParser(responseParser)
+        .allowCompression(compression)
+        .build();
+  }
+  
+  public static HttpSolrClient getHttpSolrClient(String url, HttpClient httpClient, ResponseParser responseParser) {
+    if(random().nextBoolean()) {
+      return new HttpSolrClient(url, httpClient, responseParser);
+    }
+    return new Builder(url)
+        .withHttpClient(httpClient)
+        .withResponseParser(responseParser)
+        .build();
+  }
+  
+  public static HttpSolrClient getHttpSolrClient(String url, HttpClient httpClient) {
+    if(random().nextBoolean()) {
+      return new HttpSolrClient(url, httpClient);
+    }
+    return new Builder(url)
+        .withHttpClient(httpClient)
+        .build();
+  }
+
+  public static HttpSolrClient getHttpSolrClient(String url) {
+    if(random().nextBoolean()) {
+      return new HttpSolrClient(url);
+    }
+    return new Builder(url)
+        .build();
+  }
 
   /** 
    * Returns a randomly generated Date in the appropriate Solr external (input) format 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b02b026b/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java
----------------------------------------------------------------------
diff --git a/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java b/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java
index 090dfe8..a4a4172 100644
--- a/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java
+++ b/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java
@@ -16,11 +16,6 @@
  */
 package org.apache.solr.cloud;
 
-import static org.apache.solr.cloud.OverseerCollectionMessageHandler.CREATE_NODE_SET;
-import static org.apache.solr.cloud.OverseerCollectionMessageHandler.NUM_SLICES;
-import static org.apache.solr.cloud.OverseerCollectionMessageHandler.SHARDS_PROP;
-import static org.apache.solr.common.util.Utils.makeMap;
-
 import java.io.File;
 import java.io.IOException;
 import java.lang.invoke.MethodHandles;
@@ -90,6 +85,11 @@ import org.noggit.JSONWriter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import static org.apache.solr.cloud.OverseerCollectionMessageHandler.CREATE_NODE_SET;
+import static org.apache.solr.cloud.OverseerCollectionMessageHandler.NUM_SLICES;
+import static org.apache.solr.cloud.OverseerCollectionMessageHandler.SHARDS_PROP;
+import static org.apache.solr.common.util.Utils.makeMap;
+
 /**
  * TODO: we should still test this works as a custom update chain as well as
  * what we test now - the default update chain
@@ -272,7 +272,7 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes
   }
   
   protected CloudSolrClient createCloudClient(String defaultCollection) {
-    CloudSolrClient client = new CloudSolrClient(zkServer.getZkAddress(), random().nextBoolean());
+    CloudSolrClient client = getCloudSolrClient(zkServer.getZkAddress(), random().nextBoolean());
     client.setParallelUpdates(random().nextBoolean());
     if (defaultCollection != null) client.setDefaultCollection(defaultCollection);
     client.getLbClient().setConnectionTimeout(30000);
@@ -1626,7 +1626,7 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes
       // setup the server...
       String baseUrl = buildUrl(port);
       String url = baseUrl + (baseUrl.endsWith("/") ? "" : "/") + DEFAULT_COLLECTION;
-      HttpSolrClient client = new HttpSolrClient(url);
+      HttpSolrClient client = getHttpSolrClient(url);
       client.setConnectionTimeout(DEFAULT_CONNECTION_TIMEOUT);
       client.setSoTimeout(60000);
       return client;
@@ -1638,7 +1638,7 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes
   protected SolrClient createNewSolrClient(String collection, String baseUrl) {
     try {
       // setup the server...
-      HttpSolrClient client = new HttpSolrClient(baseUrl + "/" + collection);
+      HttpSolrClient client = getHttpSolrClient(baseUrl + "/" + collection);
       client.setConnectionTimeout(DEFAULT_CONNECTION_TIMEOUT);
       return client;
     }
@@ -1722,7 +1722,7 @@ public abstract class AbstractFullDistribZkTestBase extends AbstractDistribZkTes
       if (commonCloudSolrClient == null) {
         boolean updatesToLeaders = random().nextBoolean();
         boolean parallelUpdates = random().nextBoolean();
-        commonCloudSolrClient = new CloudSolrClient(zkServer.getZkAddress(),
+        commonCloudSolrClient = getCloudSolrClient(zkServer.getZkAddress(),
                 updatesToLeaders);
         commonCloudSolrClient.getLbClient().setConnectionTimeout(5000);
         commonCloudSolrClient.getLbClient().setSoTimeout(120000);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/b02b026b/solr/test-framework/src/java/org/apache/solr/cloud/MiniSolrCloudCluster.java
----------------------------------------------------------------------
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 118f7be..d23b37c 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
@@ -42,6 +42,7 @@ import org.apache.solr.client.solrj.embedded.JettyConfig;
 import org.apache.solr.client.solrj.embedded.JettySolrRunner;
 import org.apache.solr.client.solrj.embedded.SSLConfig;
 import org.apache.solr.client.solrj.impl.CloudSolrClient;
+import org.apache.solr.client.solrj.impl.CloudSolrClient.Builder;
 import org.apache.solr.client.solrj.request.QueryRequest;
 import org.apache.solr.common.cloud.SolrZkClient;
 import org.apache.solr.common.cloud.ZkConfigManager;
@@ -445,7 +446,9 @@ public class MiniSolrCloudCluster {
   }
   
   protected CloudSolrClient buildSolrClient() {
-    return new CloudSolrClient(getZkServer().getZkAddress());
+    return new Builder()
+        .withZkHost(getZkServer().getZkAddress())
+        .build();
   }
 
   private static String getHostContextSuitableForServletContext(String ctx) {


Mime
View raw message