You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by no...@apache.org on 2016/04/07 22:29:55 UTC

[23/50] [abbrv] lucene-solr:apiv2: SOLR-4509: Move to non deprecated HttpClient impl classes to remove stale connection check on every request and move connection lifecycle management towards the client.

SOLR-4509: Move to non deprecated HttpClient impl classes to remove stale connection check on every request and move connection lifecycle management towards the client.


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/ce172acb
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/ce172acb
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/ce172acb

Branch: refs/heads/apiv2
Commit: ce172acb8fec6c3bbb18837a4d640da6c5aad649
Parents: 3f217ab
Author: markrmiller <ma...@apache.org>
Authored: Fri Apr 1 12:21:59 2016 -0400
Committer: markrmiller <ma...@apache.org>
Committed: Fri Apr 1 12:21:59 2016 -0400

----------------------------------------------------------------------
 solr/CHANGES.txt                                |  28 +-
 .../client/solrj/embedded/JettySolrRunner.java  |  25 +-
 .../org/apache/solr/core/BlobRepository.java    |   3 +-
 .../org/apache/solr/core/CoreContainer.java     |  78 ++--
 .../org/apache/solr/handler/IndexFetcher.java   |  44 +-
 .../apache/solr/handler/ReplicationHandler.java |  23 +-
 .../component/HttpShardHandlerFactory.java      |  45 +-
 .../component/IterativeMergeStrategy.java       |   3 -
 .../solr/security/AuthenticationPlugin.java     |   3 -
 .../solr/security/HttpClientBuilderPlugin.java  |  37 ++
 .../security/HttpClientInterceptorPlugin.java   |  30 --
 .../apache/solr/security/KerberosPlugin.java    |  17 +-
 .../solr/security/PKIAuthenticationPlugin.java  |  45 +-
 .../org/apache/solr/servlet/HttpSolrCall.java   |   3 +-
 .../apache/solr/update/UpdateShardHandler.java  |  57 +--
 .../src/java/org/apache/solr/util/SolrCLI.java  |  23 +-
 solr/core/src/test-files/log4j.properties       |   4 +-
 .../org/apache/solr/TestDistributedSearch.java  |  12 +-
 .../solr/client/solrj/ConnectionReuseTest.java  | 195 +++++----
 .../solrj/embedded/TestJettySolrRunner.java     |  12 +-
 .../solr/cloud/BaseCdcrDistributedZkTest.java   |   9 +-
 .../solr/cloud/BasicDistributedZkTest.java      |  29 +-
 .../cloud/ChaosMonkeyNothingIsSafeTest.java     |   8 +-
 .../cloud/CollectionsAPIDistributedZkTest.java  |  12 +-
 .../apache/solr/cloud/HttpPartitionTest.java    |  10 +-
 .../cloud/LeaderFailoverAfterPartitionTest.java |   9 +-
 .../org/apache/solr/cloud/SSLMigrationTest.java |   2 +-
 .../org/apache/solr/cloud/ShardSplitTest.java   |   1 -
 .../solr/cloud/TestAuthenticationFramework.java |  52 +--
 .../solr/cloud/TestCloudDeleteByQuery.java      |  12 +-
 .../cloud/TestMiniSolrCloudClusterBase.java     |   2 +-
 .../cloud/TestRandomRequestDistribution.java    | 104 ++---
 .../cloud/TestSolrCloudWithKerberosAlt.java     |  13 +-
 .../cloud/TestTolerantUpdateProcessorCloud.java |  17 +-
 .../TestTolerantUpdateProcessorRandomCloud.java |  58 ++-
 .../org/apache/solr/cloud/ZkControllerTest.java |   9 +-
 .../solr/cloud/overseer/ZkStateReaderTest.java  |   5 +-
 .../solr/core/OpenCloseCoreStressTest.java      |   2 -
 .../org/apache/solr/core/TestCoreContainer.java |   1 -
 .../solr/handler/TestReplicationHandler.java    |   2 -
 .../handler/TestReplicationHandlerBackup.java   |   2 -
 .../apache/solr/handler/TestRestoreCore.java    |   2 -
 .../DistributedQueryElevationComponentTest.java |   1 +
 .../solr/search/AnalyticsMergeStrategyTest.java |   2 +
 .../solr/search/stats/TestDistribIDF.java       |  82 ++--
 .../solr/security/BasicAuthIntegrationTest.java |  41 +-
 .../PKIAuthenticationIntegrationTest.java       |   2 -
 .../security/TestAuthorizationFramework.java    |   3 +-
 .../org/apache/solr/update/AutoCommitTest.java  |   2 +-
 solr/server/etc/jetty-http.xml                  |   2 +-
 solr/server/etc/jetty-https.xml                 |   2 +-
 solr/server/etc/jetty.xml                       |   2 +-
 .../solr/client/solrj/impl/CloudSolrClient.java |   8 +
 .../solrj/impl/ConcurrentUpdateSolrClient.java  |  20 +-
 .../client/solrj/impl/HttpClientConfigurer.java | 100 -----
 .../solr/client/solrj/impl/HttpClientUtil.java  | 438 ++++++++++---------
 .../solr/client/solrj/impl/HttpSolrClient.java  | 122 +++---
 .../solrj/impl/Krb5HttpClientBuilder.java       | 192 ++++++++
 .../solrj/impl/Krb5HttpClientConfigurer.java    | 153 -------
 .../client/solrj/impl/LBHttpSolrClient.java     |  33 +-
 .../solrj/impl/SolrHttpClientBuilder.java       |  91 ++++
 .../impl/SolrHttpClientContextBuilder.java      |  96 ++++
 solr/solrj/src/test-files/log4j.properties      |   2 +
 .../client/solrj/SolrExampleBinaryTest.java     |   2 -
 .../solr/client/solrj/SolrExampleXMLTest.java   |   2 -
 .../solr/client/solrj/SolrExceptionTest.java    |   9 +-
 .../client/solrj/SolrSchemalessExampleTest.java |   7 +-
 .../solr/client/solrj/TestLBHttpSolrClient.java |  15 +-
 .../client/solrj/embedded/JettyWebappTest.java  |   3 +-
 .../solrj/embedded/SolrExampleJettyTest.java    |   3 +-
 .../solrj/impl/BasicHttpSolrClientTest.java     |  87 ++--
 .../client/solrj/impl/CloudSolrClientTest.java  |  10 +-
 .../solrj/impl/ExternalHttpClientTest.java      |  75 ----
 .../client/solrj/impl/HttpClientUtilTest.java   | 162 -------
 .../client/solrj/impl/LBHttpSolrClientTest.java |  17 +-
 .../solr/client/solrj/request/SchemaTest.java   |   9 +-
 .../solr/BaseDistributedSearchTestCase.java     |   7 -
 .../java/org/apache/solr/SolrJettyTestBase.java |  18 +-
 .../java/org/apache/solr/SolrTestCaseJ4.java    |   7 +-
 .../cloud/AbstractFullDistribZkTestBase.java    |   4 -
 .../org/apache/solr/util/RestTestHarness.java   |   4 +-
 .../org/apache/solr/util/SSLTestConfig.java     |  79 +++-
 82 files changed, 1504 insertions(+), 1458 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/CHANGES.txt
----------------------------------------------------------------------
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 326beec..5ab52b2 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -17,7 +17,33 @@ servlet container in the directory named "example".
 See the Quick Start guide at http://lucene.apache.org/solr/quickstart.html
 
 ==================  7.0.0 ==================
-(No Changes)
+
+Upgrading from Solr 5.x
+----------------------
+
+* HttpClientInterceptorPlugin is now HttpClientBuilderPlugin and must work with a 
+  SolrHttpClientBuilder rather than an HttpClientConfigurer.
+  
+* HttpClientUtil now allows configuring HttpClient instances via SolrHttpClientBuilder
+  rather than an HttpClientConfigurer.
+
+* SolrClient implementations now use their own internal configuration for socket timeouts,
+  connect timeouts, and allowing redirects rather than what is set as the default when
+  building the HttpClient instance. Use the appropriate setters on the SolrClient instance.
+  
+* HttpSolrClient#setAllowCompression has been removed and compression must be enabled as
+  a constructor param. 
+  
+* HttpSolrClient#setDefaultMaxConnectionsPerHost and
+  HttpSolrClient#setMaxTotalConnections have been removed. These now default very
+  high and can only be changed via param when creating an HttpClient instance.
+  
+Optimizations
+----------------------
+
+* SOLR-4509: Move to non deprecated HttpClient impl classes to remove stale connection 
+  check on every request and move connection lifecycle management towards the client.
+  (Ryan Zezeski, Mark Miller, Shawn Heisey, Steve Davids)
 
 ==================  6.1.0 ==================
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/java/org/apache/solr/client/solrj/embedded/JettySolrRunner.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/client/solrj/embedded/JettySolrRunner.java b/solr/core/src/java/org/apache/solr/client/solrj/embedded/JettySolrRunner.java
index 88ea567..871fe4c 100644
--- a/solr/core/src/java/org/apache/solr/client/solrj/embedded/JettySolrRunner.java
+++ b/solr/core/src/java/org/apache/solr/client/solrj/embedded/JettySolrRunner.java
@@ -35,7 +35,6 @@ import java.util.LinkedList;
 import java.util.Map;
 import java.util.Properties;
 import java.util.Random;
-import java.util.SortedMap;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicLong;
 
@@ -44,7 +43,6 @@ import org.apache.solr.servlet.SolrDispatchFilter;
 import org.eclipse.jetty.server.Connector;
 import org.eclipse.jetty.server.HttpConfiguration;
 import org.eclipse.jetty.server.HttpConnectionFactory;
-import org.eclipse.jetty.server.LowResourceMonitor;
 import org.eclipse.jetty.server.SecureRequestCustomizer;
 import org.eclipse.jetty.server.Server;
 import org.eclipse.jetty.server.ServerConnector;
@@ -71,6 +69,10 @@ public class JettySolrRunner {
 
   private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
+  private static final int THREAD_POOL_MAX_THREADS = 10000;
+  // NOTE: needs to be larger than SolrHttpClient.threadPoolSweeperMaxIdleTime
+  private static final int THREAD_POOL_MAX_IDLE_TIME_MS = 120000;
+  
   Server server;
 
   FilterHolder dispatchFilter;
@@ -161,8 +163,8 @@ public class JettySolrRunner {
   private void init(int port) {
 
     QueuedThreadPool qtp = new QueuedThreadPool();
-    qtp.setMaxThreads(10000);
-    qtp.setIdleTimeout((int) TimeUnit.SECONDS.toMillis(5));
+    qtp.setMaxThreads(THREAD_POOL_MAX_THREADS);
+    qtp.setIdleTimeout(THREAD_POOL_MAX_IDLE_TIME_MS);
     qtp.setStopTimeout((int) TimeUnit.MINUTES.toMillis(1));
     server = new Server(qtp);
     server.manage(qtp);
@@ -179,7 +181,7 @@ public class JettySolrRunner {
       // talking to that server, but for the purposes of testing that should 
       // be good enough
       final SslContextFactory sslcontext = SSLConfig.createContextFactory(config.sslConfig);
-
+      
       ServerConnector connector;
       if (sslcontext != null) {
         HttpConfiguration configuration = new HttpConfiguration();
@@ -192,21 +194,18 @@ public class JettySolrRunner {
       }
 
       connector.setReuseAddress(true);
-      connector.setSoLingerTime(0);
+      connector.setSoLingerTime(-1);
       connector.setPort(port);
       connector.setHost("127.0.0.1");
-
-      // Enable Low Resources Management
-      LowResourceMonitor lowResources = new LowResourceMonitor(server);
-      lowResources.setLowResourcesIdleTimeout(1500);
-      lowResources.setMaxConnections(10000);
-      server.addBean(lowResources);
-
+      connector.setIdleTimeout(THREAD_POOL_MAX_IDLE_TIME_MS);
+      
       server.setConnectors(new Connector[] {connector});
       server.setSessionIdManager(new HashSessionIdManager(new Random()));
     } else {
       ServerConnector connector = new ServerConnector(server, new HttpConnectionFactory());
       connector.setPort(port);
+      connector.setSoLingerTime(-1);
+      connector.setIdleTimeout(THREAD_POOL_MAX_IDLE_TIME_MS);
       server.setConnectors(new Connector[] {connector});
     }
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/java/org/apache/solr/core/BlobRepository.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/core/BlobRepository.java b/solr/core/src/java/org/apache/solr/core/BlobRepository.java
index 6739826..09461f0 100644
--- a/solr/core/src/java/org/apache/solr/core/BlobRepository.java
+++ b/solr/core/src/java/org/apache/solr/core/BlobRepository.java
@@ -38,6 +38,7 @@ import java.util.zip.ZipInputStream;
 import org.apache.http.HttpResponse;
 import org.apache.http.client.HttpClient;
 import org.apache.http.client.methods.HttpGet;
+import org.apache.solr.client.solrj.impl.HttpClientUtil;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.cloud.ClusterState;
 import org.apache.solr.common.cloud.DocCollection;
@@ -116,7 +117,7 @@ public class BlobRepository {
         HttpGet httpGet = new HttpGet(url);
         ByteBuffer b;
         try {
-          HttpResponse entity = httpClient.execute(httpGet);
+          HttpResponse entity = httpClient.execute(httpGet, HttpClientUtil.createNewHttpClientRequestContext());
           int statusCode = entity.getStatusLine().getStatusCode();
           if (statusCode != 200) {
             throw new SolrException(SolrException.ErrorCode.NOT_FOUND, "no such blob or version available: " + key);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/java/org/apache/solr/core/CoreContainer.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/core/CoreContainer.java b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
index c140fb4..4d57ad1d 100644
--- a/solr/core/src/java/org/apache/solr/core/CoreContainer.java
+++ b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
@@ -16,6 +16,17 @@
  */
 package org.apache.solr.core;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.Collections.EMPTY_MAP;
+import static org.apache.solr.common.params.CommonParams.AUTHC_PATH;
+import static org.apache.solr.common.params.CommonParams.AUTHZ_PATH;
+import static org.apache.solr.common.params.CommonParams.COLLECTIONS_HANDLER_PATH;
+import static org.apache.solr.common.params.CommonParams.CONFIGSETS_HANDLER_PATH;
+import static org.apache.solr.common.params.CommonParams.CORES_HANDLER_PATH;
+import static org.apache.solr.common.params.CommonParams.INFO_HANDLER_PATH;
+import static org.apache.solr.common.params.CommonParams.ZK_PATH;
+import static org.apache.solr.security.AuthenticationPlugin.AUTHENTICATION_PLUGIN_PROP;
+
 import java.io.IOException;
 import java.lang.invoke.MethodHandles;
 import java.nio.file.Path;
@@ -32,10 +43,14 @@ import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Future;
 
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-import org.apache.solr.client.solrj.impl.HttpClientConfigurer;
+import org.apache.http.auth.AuthSchemeProvider;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.config.Lookup;
 import org.apache.solr.client.solrj.impl.HttpClientUtil;
+import org.apache.solr.client.solrj.impl.SolrHttpClientBuilder;
+import org.apache.solr.client.solrj.impl.SolrHttpClientContextBuilder;
+import org.apache.solr.client.solrj.impl.SolrHttpClientContextBuilder.AuthSchemeRegistryProvider;
+import org.apache.solr.client.solrj.impl.SolrHttpClientContextBuilder.CredentialsProviderProvider;
 import org.apache.solr.client.solrj.util.SolrIdentifierValidator;
 import org.apache.solr.cloud.Overseer;
 import org.apache.solr.cloud.ZkController;
@@ -52,14 +67,13 @@ import org.apache.solr.handler.admin.CoreAdminHandler;
 import org.apache.solr.handler.admin.InfoHandler;
 import org.apache.solr.handler.admin.SecurityConfHandler;
 import org.apache.solr.handler.admin.ZookeeperInfoHandler;
-import org.apache.solr.handler.component.HttpShardHandlerFactory;
 import org.apache.solr.handler.component.ShardHandlerFactory;
 import org.apache.solr.logging.LogWatcher;
 import org.apache.solr.logging.MDCLoggingContext;
 import org.apache.solr.request.SolrRequestHandler;
 import org.apache.solr.security.AuthenticationPlugin;
 import org.apache.solr.security.AuthorizationPlugin;
-import org.apache.solr.security.HttpClientInterceptorPlugin;
+import org.apache.solr.security.HttpClientBuilderPlugin;
 import org.apache.solr.security.PKIAuthenticationPlugin;
 import org.apache.solr.security.SecurityPluginHolder;
 import org.apache.solr.update.SolrCoreState;
@@ -69,16 +83,8 @@ import org.apache.zookeeper.KeeperException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import static com.google.common.base.Preconditions.checkNotNull;
-import static java.util.Collections.EMPTY_MAP;
-import static org.apache.solr.common.params.CommonParams.AUTHC_PATH;
-import static org.apache.solr.common.params.CommonParams.AUTHZ_PATH;
-import static org.apache.solr.common.params.CommonParams.COLLECTIONS_HANDLER_PATH;
-import static org.apache.solr.common.params.CommonParams.CONFIGSETS_HANDLER_PATH;
-import static org.apache.solr.common.params.CommonParams.CORES_HANDLER_PATH;
-import static org.apache.solr.common.params.CommonParams.INFO_HANDLER_PATH;
-import static org.apache.solr.common.params.CommonParams.ZK_PATH;
-import static org.apache.solr.security.AuthenticationPlugin.AUTHENTICATION_PLUGIN_PROP;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
 
 
 /**
@@ -291,7 +297,7 @@ public class CoreContainer {
     }
     if (authenticationPlugin != null) {
       authenticationPlugin.plugin.init(authenticationConfig);
-      addHttpConfigurer(authenticationPlugin.plugin);
+      setupHttpClientForAuthPlugin(authenticationPlugin.plugin);
     }
     this.authenticationPlugin = authenticationPlugin;
     try {
@@ -300,26 +306,44 @@ public class CoreContainer {
 
   }
 
-  private void addHttpConfigurer(Object authcPlugin) {
-    if (authcPlugin instanceof HttpClientInterceptorPlugin) {
-      // Setup HttpClient to use the plugin's configurer for internode communication
-      HttpClientConfigurer configurer = ((HttpClientInterceptorPlugin) authcPlugin).getClientConfigurer();
-      HttpClientUtil.setConfigurer(configurer);
-
+  private void setupHttpClientForAuthPlugin(Object authcPlugin) {
+    if (authcPlugin instanceof HttpClientBuilderPlugin) {
+      // Setup HttpClient for internode communication
+      SolrHttpClientBuilder builder = ((HttpClientBuilderPlugin) authcPlugin).getHttpClientBuilder(HttpClientUtil.getHttpClientBuilder());
+      
       // The default http client of the core container's shardHandlerFactory has already been created and
       // configured using the default httpclient configurer. We need to reconfigure it using the plugin's
       // http client configurer to set it up for internode communication.
-      log.info("Reconfiguring the shard handler factory and update shard handler.");
-      if (getShardHandlerFactory() instanceof HttpShardHandlerFactory) {
-        ((HttpShardHandlerFactory) getShardHandlerFactory()).reconfigureHttpClient(configurer);
+      log.info("Reconfiguring HttpClient settings.");
+
+      SolrHttpClientContextBuilder httpClientBuilder = new SolrHttpClientContextBuilder();
+      if (builder.getCredentialsProviderProvider() != null) {
+        httpClientBuilder.setDefaultCredentialsProvider(new CredentialsProviderProvider() {
+          
+          @Override
+          public CredentialsProvider getCredentialsProvider() {
+            return builder.getCredentialsProviderProvider().getCredentialsProvider();
+          }
+        });
       }
-      getUpdateShardHandler().reconfigureHttpClient(configurer);
+      if (builder.getAuthSchemeRegistryProvider() != null) {
+        httpClientBuilder.setAuthSchemeRegistryProvider(new AuthSchemeRegistryProvider() {
+          
+          @Override
+          public Lookup<AuthSchemeProvider> getAuthSchemeRegistry() {
+            return builder.getAuthSchemeRegistryProvider().getAuthSchemeRegistry();
+          }
+        });
+      }
+
+      HttpClientUtil.setHttpClientRequestContextBuilder(httpClientBuilder);
+
     } else {
       if (pkiAuthenticationPlugin != null) {
         //this happened due to an authc plugin reload. no need to register the pkiAuthc plugin again
         if(pkiAuthenticationPlugin.isInterceptorRegistered()) return;
         log.info("PKIAuthenticationPlugin is managing internode requests");
-        addHttpConfigurer(pkiAuthenticationPlugin);
+        setupHttpClientForAuthPlugin(pkiAuthenticationPlugin);
         pkiAuthenticationPlugin.setInterceptorRegistered();
       }
     }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/java/org/apache/solr/handler/IndexFetcher.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/IndexFetcher.java b/solr/core/src/java/org/apache/solr/handler/IndexFetcher.java
index 39c4158..7f38acd 100644
--- a/solr/core/src/java/org/apache/solr/handler/IndexFetcher.java
+++ b/solr/core/src/java/org/apache/solr/handler/IndexFetcher.java
@@ -172,15 +172,17 @@ public class IndexFetcher {
 
   private final HttpClient myHttpClient;
 
-  private static HttpClient createHttpClient(SolrCore core, String connTimeout, String readTimeout, String httpBasicAuthUser, String httpBasicAuthPassword, boolean useCompression) {
+  private Integer connTimeout;
+
+  private Integer soTimeout;
+
+  private static HttpClient createHttpClient(SolrCore core, String httpBasicAuthUser, String httpBasicAuthPassword, boolean useCompression) {
     final ModifiableSolrParams httpClientParams = new ModifiableSolrParams();
-    httpClientParams.set(HttpClientUtil.PROP_CONNECTION_TIMEOUT, connTimeout != null ? connTimeout : "5000");
-    httpClientParams.set(HttpClientUtil.PROP_SO_TIMEOUT, readTimeout != null ? readTimeout : "20000");
     httpClientParams.set(HttpClientUtil.PROP_BASIC_AUTH_USER, httpBasicAuthUser);
     httpClientParams.set(HttpClientUtil.PROP_BASIC_AUTH_PASS, httpBasicAuthPassword);
     httpClientParams.set(HttpClientUtil.PROP_ALLOW_COMPRESSION, useCompression);
 
-    return HttpClientUtil.createClient(httpClientParams, core.getCoreDescriptor().getCoreContainer().getUpdateShardHandler().getConnectionManager());
+    return HttpClientUtil.createClient(httpClientParams, core.getCoreDescriptor().getCoreContainer().getUpdateShardHandler().getConnectionManager(), true);
   }
 
   public IndexFetcher(final NamedList initArgs, final ReplicationHandler handler, final SolrCore sc) {
@@ -199,11 +201,22 @@ public class IndexFetcher {
     String compress = (String) initArgs.get(COMPRESSION);
     useInternalCompression = INTERNAL.equals(compress);
     useExternalCompression = EXTERNAL.equals(compress);
-    String connTimeout = (String) initArgs.get(HttpClientUtil.PROP_CONNECTION_TIMEOUT);
-    String readTimeout = (String) initArgs.get(HttpClientUtil.PROP_SO_TIMEOUT);
+    connTimeout = getParameter(initArgs, HttpClientUtil.PROP_CONNECTION_TIMEOUT, 30000, null);
+    soTimeout = getParameter(initArgs, HttpClientUtil.PROP_SO_TIMEOUT, 120000, null);
+
     String httpBasicAuthUser = (String) initArgs.get(HttpClientUtil.PROP_BASIC_AUTH_USER);
     String httpBasicAuthPassword = (String) initArgs.get(HttpClientUtil.PROP_BASIC_AUTH_PASS);
-    myHttpClient = createHttpClient(solrCore, connTimeout, readTimeout, httpBasicAuthUser, httpBasicAuthPassword, useExternalCompression);
+    myHttpClient = createHttpClient(solrCore, httpBasicAuthUser, httpBasicAuthPassword, useExternalCompression);
+  }
+  
+  protected <T> T getParameter(NamedList initArgs, String configKey, T defaultValue, StringBuilder sb) {
+    T toReturn = defaultValue;
+    if (initArgs != null) {
+      T temp = (T) initArgs.get(configKey);
+      toReturn = (temp != null) ? temp : defaultValue;
+    }
+    if(sb!=null && toReturn != null) sb.append(configKey).append(" : ").append(toReturn).append(",");
+    return toReturn;
   }
 
   /**
@@ -219,8 +232,8 @@ public class IndexFetcher {
 
     // TODO modify to use shardhandler
     try (HttpSolrClient client = new HttpSolrClient(masterUrl, myHttpClient)) {
-      client.setSoTimeout(60000);
-      client.setConnectionTimeout(15000);
+      client.setSoTimeout(soTimeout);
+      client.setConnectionTimeout(connTimeout);
 
       return client.request(req);
     } catch (SolrServerException e) {
@@ -241,8 +254,8 @@ public class IndexFetcher {
 
     // TODO modify to use shardhandler
     try (HttpSolrClient client = new HttpSolrClient(masterUrl, myHttpClient)) {
-      client.setSoTimeout(60000);
-      client.setConnectionTimeout(15000);
+      client.setSoTimeout(soTimeout);
+      client.setConnectionTimeout(connTimeout);
       NamedList response = client.request(req);
 
       List<Map<String, Object>> files = (List<Map<String,Object>>) response.get(CMD_GET_FILE_LIST);
@@ -1607,8 +1620,8 @@ public class IndexFetcher {
 
       // TODO use shardhandler
       try (HttpSolrClient client = new HttpSolrClient(masterUrl, myHttpClient, null)) {
-        client.setSoTimeout(60000);
-        client.setConnectionTimeout(15000);
+        client.setSoTimeout(soTimeout);
+        client.setConnectionTimeout(connTimeout);
         QueryRequest req = new QueryRequest(params);
         response = client.request(req);
         is = (InputStream) response.get("stream");
@@ -1716,8 +1729,8 @@ public class IndexFetcher {
 
     // TODO use shardhandler
     try (HttpSolrClient client = new HttpSolrClient(masterUrl, myHttpClient)) {
-      client.setSoTimeout(60000);
-      client.setConnectionTimeout(15000);
+      client.setSoTimeout(soTimeout);
+      client.setConnectionTimeout(connTimeout);
       QueryRequest request = new QueryRequest(params);
       return client.request(request);
     }
@@ -1725,6 +1738,7 @@ public class IndexFetcher {
 
   public void destroy() {
     abortFetch();
+    HttpClientUtil.close(myHttpClient);
   }
 
   String getMasterUrl() {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java b/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
index b8c9692..267ab3d 100644
--- a/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
@@ -387,8 +387,15 @@ public class ReplicationHandler extends RequestHandlerBase implements SolrCoreAw
       return currentIndexFetcher.fetchLatestIndex(forceReplication);
     } catch (Exception e) {
       SolrException.log(LOG, "Index fetch failed ", e);
+      if (currentIndexFetcher != pollingIndexFetcher) {
+        currentIndexFetcher.destroy();
+      }
     } finally {
       if (pollingIndexFetcher != null) {
+       if( currentIndexFetcher != pollingIndexFetcher) {
+         currentIndexFetcher.destroy();
+       }
+        
         currentIndexFetcher = pollingIndexFetcher;
       }
       indexFetchLock.unlock();
@@ -1243,20 +1250,18 @@ public class ReplicationHandler extends RequestHandlerBase implements SolrCoreAw
     core.addCloseHook(new CloseHook() {
       @Override
       public void preClose(SolrCore core) {
-        try {
-          if (executorService != null) executorService.shutdown(); // we don't wait for shutdown - this can deadlock core reload
-        } finally {
-            if (pollingIndexFetcher != null) {
-              pollingIndexFetcher.destroy();
-            }
+        if (executorService != null) executorService.shutdown(); // we don't wait for shutdown - this can deadlock core reload
+      }
+
+      @Override
+      public void postClose(SolrCore core) {
+        if (pollingIndexFetcher != null) {
+          pollingIndexFetcher.destroy();
         }
         if (currentIndexFetcher != null && currentIndexFetcher != pollingIndexFetcher) {
           currentIndexFetcher.destroy();
         }
       }
-
-      @Override
-      public void postClose(SolrCore core) {}
     });
 
     core.addCloseHook(new CloseHook() {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java b/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java
index d2800d7..0412838 100644
--- a/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java
+++ b/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java
@@ -15,12 +15,11 @@
  * limitations under the License.
  */
 package org.apache.solr.handler.component;
+
 import org.apache.commons.lang.StringUtils;
 import org.apache.http.client.HttpClient;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
+import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.solr.client.solrj.SolrServerException;
-import org.apache.solr.client.solrj.impl.HttpClientConfigurer;
 import org.apache.solr.client.solrj.impl.HttpClientUtil;
 import org.apache.solr.client.solrj.impl.LBHttpSolrClient;
 import org.apache.solr.client.solrj.request.QueryRequest;
@@ -67,7 +66,7 @@ public class HttpShardHandlerFactory extends ShardHandlerFactory implements org.
       new DefaultSolrThreadFactory("httpShardExecutor")
   );
 
-  protected HttpClient defaultClient;
+  protected CloseableHttpClient defaultClient;
   private LBHttpSolrClient loadbalancer;
   //default values:
   int soTimeout = UpdateShardHandlerConfig.DEFAULT_DISTRIBUPDATESOTIMEOUT;
@@ -79,7 +78,6 @@ public class HttpShardHandlerFactory extends ShardHandlerFactory implements org.
   int keepAliveTime = 5;
   int queueSize = -1;
   boolean accessPolicy = false;
-  boolean useRetries = false;
 
   private String scheme = null;
 
@@ -140,7 +138,6 @@ public class HttpShardHandlerFactory extends ShardHandlerFactory implements org.
     this.keepAliveTime = getParameter(args, MAX_THREAD_IDLE_TIME, keepAliveTime,sb);
     this.queueSize = getParameter(args, INIT_SIZE_OF_QUEUE, queueSize,sb);
     this.accessPolicy = getParameter(args, INIT_FAIRNESS_POLICY, accessPolicy,sb);
-    this.useRetries = getParameter(args, USE_RETRIES, useRetries,sb);
     log.info("created with {}",sb);
     
     // magic sysprop to make tests reproducible: set by SolrTestCaseJ4.
@@ -165,13 +162,6 @@ public class HttpShardHandlerFactory extends ShardHandlerFactory implements org.
 
     this.defaultClient = HttpClientUtil.createClient(clientParams);
     
-    // must come after createClient
-    if (useRetries) {
-      // our default retry handler will never retry on IOException if the request has been sent already,
-      // but for these read only requests we can use the standard DefaultHttpRequestRetryHandler rules
-      ((DefaultHttpClient) this.defaultClient).setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler());
-    }
-    
     this.loadbalancer = createLoadbalancer(defaultClient);
   }
   
@@ -179,30 +169,18 @@ public class HttpShardHandlerFactory extends ShardHandlerFactory implements org.
     ModifiableSolrParams clientParams = new ModifiableSolrParams();
     clientParams.set(HttpClientUtil.PROP_MAX_CONNECTIONS_PER_HOST, maxConnectionsPerHost);
     clientParams.set(HttpClientUtil.PROP_MAX_CONNECTIONS, maxConnections);
-    clientParams.set(HttpClientUtil.PROP_SO_TIMEOUT, soTimeout);
-    clientParams.set(HttpClientUtil.PROP_CONNECTION_TIMEOUT, connectionTimeout);
-    if (!useRetries) {
-      clientParams.set(HttpClientUtil.PROP_USE_RETRY, false);
-    }
     return clientParams;
   }
 
-  /**
-   * For an already created internal httpclient, this can be used to configure it 
-   * again. Useful for authentication plugins.
-   * @param configurer an HttpClientConfigurer instance
-   */
-  public void reconfigureHttpClient(HttpClientConfigurer configurer) {
-    log.info("Reconfiguring the default client with: " + configurer);
-    configurer.configure((DefaultHttpClient)this.defaultClient, getClientParams());
-  }
-
   protected ThreadPoolExecutor getThreadPoolExecutor(){
     return this.commExecutor;
   }
 
   protected LBHttpSolrClient createLoadbalancer(HttpClient httpClient){
-    return new LBHttpSolrClient(httpClient);
+    LBHttpSolrClient client = new LBHttpSolrClient(httpClient);
+    client.setConnectionTimeout(connectionTimeout);
+    client.setSoTimeout(soTimeout);
+    return client;
   }
 
   protected <T> T getParameter(NamedList initArgs, String configKey, T defaultValue, StringBuilder sb) {
@@ -222,14 +200,13 @@ public class HttpShardHandlerFactory extends ShardHandlerFactory implements org.
       ExecutorUtil.shutdownAndAwaitTermination(commExecutor);
     } finally {
       try {
-        if (defaultClient != null) {
-          defaultClient.getConnectionManager().shutdown();
-        }
-      } finally {
-        
         if (loadbalancer != null) {
           loadbalancer.close();
         }
+      } finally { 
+        if (defaultClient != null) {
+          HttpClientUtil.close(defaultClient);
+        }
       }
     }
   }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/java/org/apache/solr/handler/component/IterativeMergeStrategy.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/component/IterativeMergeStrategy.java b/solr/core/src/java/org/apache/solr/handler/component/IterativeMergeStrategy.java
index a8f6ca9..83677e4 100644
--- a/solr/core/src/java/org/apache/solr/handler/component/IterativeMergeStrategy.java
+++ b/solr/core/src/java/org/apache/solr/handler/component/IterativeMergeStrategy.java
@@ -20,13 +20,10 @@ import java.lang.invoke.MethodHandles;
 import java.util.concurrent.Callable;
 import java.util.concurrent.Future;
 import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
 import java.util.List;
 import java.util.ArrayList;
 
-import org.apache.lucene.util.NamedThreadFactory;
 import org.apache.solr.client.solrj.SolrRequest;
-import org.apache.solr.client.solrj.impl.HttpClientConfigurer;
 import org.apache.solr.client.solrj.impl.HttpClientUtil;
 import org.apache.solr.client.solrj.impl.HttpSolrClient;
 import org.apache.solr.client.solrj.request.QueryRequest;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/java/org/apache/solr/security/AuthenticationPlugin.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/security/AuthenticationPlugin.java b/solr/core/src/java/org/apache/solr/security/AuthenticationPlugin.java
index 5229633..47daec1 100644
--- a/solr/core/src/java/org/apache/solr/security/AuthenticationPlugin.java
+++ b/solr/core/src/java/org/apache/solr/security/AuthenticationPlugin.java
@@ -22,15 +22,12 @@ import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequestWrapper;
-import javax.servlet.http.HttpServletResponse;
 import java.io.Closeable;
 import java.io.IOException;
-import java.nio.file.attribute.UserPrincipal;
 import java.security.Principal;
 import java.util.Map;
 
 import org.apache.http.auth.BasicUserPrincipal;
-import org.apache.solr.client.solrj.impl.HttpClientConfigurer;
 
 /**
  * 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/java/org/apache/solr/security/HttpClientBuilderPlugin.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/security/HttpClientBuilderPlugin.java b/solr/core/src/java/org/apache/solr/security/HttpClientBuilderPlugin.java
new file mode 100644
index 0000000..8b7e80b
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/security/HttpClientBuilderPlugin.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.solr.security;
+
+import org.apache.solr.client.solrj.impl.SolrHttpClientBuilder;
+
+/**
+ * Plugin interface for configuring internal HttpClients. This
+ * relies on the internal HttpClient implementation and is subject to
+ * change.
+ * 
+ * @lucene.experimental
+ */
+public interface HttpClientBuilderPlugin {
+  /**
+   *
+   * @return Returns an instance of a SolrHttpClientBuilder to be used for configuring the
+   * HttpClients for use with SolrJ clients.
+   *
+   * @lucene.experimental
+   */
+  public SolrHttpClientBuilder getHttpClientBuilder(SolrHttpClientBuilder builder);
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/java/org/apache/solr/security/HttpClientInterceptorPlugin.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/security/HttpClientInterceptorPlugin.java b/solr/core/src/java/org/apache/solr/security/HttpClientInterceptorPlugin.java
deleted file mode 100644
index d7598df..0000000
--- a/solr/core/src/java/org/apache/solr/security/HttpClientInterceptorPlugin.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.solr.security;
-
-import org.apache.solr.client.solrj.impl.HttpClientConfigurer;
-
-public interface HttpClientInterceptorPlugin {
-  /**
-   *
-   * @return Returns an instance of a HttpClientConfigurer to be used for configuring the
-   * httpclients for use with SolrJ clients.
-   *
-   * @lucene.experimental
-   */
-  public HttpClientConfigurer getClientConfigurer();
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/java/org/apache/solr/security/KerberosPlugin.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/security/KerberosPlugin.java b/solr/core/src/java/org/apache/solr/security/KerberosPlugin.java
index ad7f29b..2ef7fb8 100644
--- a/solr/core/src/java/org/apache/solr/security/KerberosPlugin.java
+++ b/solr/core/src/java/org/apache/solr/security/KerberosPlugin.java
@@ -30,6 +30,7 @@ import javax.servlet.Filter;
 import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
 import javax.servlet.FilterRegistration;
+import javax.servlet.FilterRegistration.Dynamic;
 import javax.servlet.RequestDispatcher;
 import javax.servlet.Servlet;
 import javax.servlet.ServletContext;
@@ -39,23 +40,22 @@ import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 import javax.servlet.SessionCookieConfig;
 import javax.servlet.SessionTrackingMode;
-import javax.servlet.FilterRegistration.Dynamic;
 import javax.servlet.descriptor.JspConfigDescriptor;
 
 import org.apache.commons.collections.iterators.IteratorEnumeration;
-import org.apache.solr.client.solrj.impl.HttpClientConfigurer;
-import org.apache.solr.client.solrj.impl.Krb5HttpClientConfigurer;
-import org.apache.solr.cloud.ZkController;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.solr.client.solrj.impl.Krb5HttpClientBuilder;
+import org.apache.solr.client.solrj.impl.SolrHttpClientBuilder;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.SolrException.ErrorCode;
 import org.apache.solr.core.CoreContainer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class KerberosPlugin extends AuthenticationPlugin implements HttpClientInterceptorPlugin {
+public class KerberosPlugin extends AuthenticationPlugin implements HttpClientBuilderPlugin {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
-  HttpClientConfigurer kerberosConfigurer = new Krb5HttpClientConfigurer();
+  Krb5HttpClientBuilder kerberosBuilder = new Krb5HttpClientBuilder();
   Filter kerberosFilter = new KerberosFilter();
   
   public static final String NAME_RULES_PARAM = "solr.kerberos.name.rules";
@@ -145,12 +145,13 @@ public class KerberosPlugin extends AuthenticationPlugin implements HttpClientIn
   }
 
   @Override
-  public HttpClientConfigurer getClientConfigurer() {
-    return kerberosConfigurer;
+  public SolrHttpClientBuilder getHttpClientBuilder(SolrHttpClientBuilder builder) {
+    return kerberosBuilder.getBuilder(builder);
   }
 
   public void close() {
     kerberosFilter.destroy();
+    kerberosBuilder.close();
   }
 
   protected static ServletContext noContext = new ServletContext() {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/java/org/apache/solr/security/PKIAuthenticationPlugin.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/security/PKIAuthenticationPlugin.java b/solr/core/src/java/org/apache/solr/security/PKIAuthenticationPlugin.java
index 3c65af2..26b29fe 100644
--- a/solr/core/src/java/org/apache/solr/security/PKIAuthenticationPlugin.java
+++ b/solr/core/src/java/org/apache/solr/security/PKIAuthenticationPlugin.java
@@ -16,11 +16,8 @@
  */
 package org.apache.solr.security;
 
-import javax.servlet.FilterChain;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletRequestWrapper;
+import static java.nio.charset.StandardCharsets.UTF_8;
+
 import java.io.IOException;
 import java.lang.invoke.MethodHandles;
 import java.nio.ByteBuffer;
@@ -30,17 +27,22 @@ import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
+import javax.servlet.FilterChain;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+
 import org.apache.http.HttpException;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpRequestInterceptor;
 import org.apache.http.HttpResponse;
 import org.apache.http.auth.BasicUserPrincipal;
 import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.DefaultHttpClient;
 import org.apache.http.protocol.HttpContext;
 import org.apache.http.util.EntityUtils;
-import org.apache.solr.client.solrj.impl.HttpClientConfigurer;
-import org.apache.solr.common.params.SolrParams;
+import org.apache.solr.client.solrj.impl.HttpClientUtil;
+import org.apache.solr.client.solrj.impl.SolrHttpClientBuilder;
 import org.apache.solr.common.util.Base64;
 import org.apache.solr.common.util.ExecutorUtil;
 import org.apache.solr.common.util.StrUtils;
@@ -56,17 +58,15 @@ import org.apache.solr.util.CryptoKeys;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import static java.nio.charset.StandardCharsets.UTF_8;
-
 
-public class PKIAuthenticationPlugin extends AuthenticationPlugin implements HttpClientInterceptorPlugin {
+public class PKIAuthenticationPlugin extends AuthenticationPlugin implements HttpClientBuilderPlugin {
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
   private final Map<String, PublicKey> keyCache = new ConcurrentHashMap<>();
   private final CryptoKeys.RSAKeyPair keyPair = new CryptoKeys.RSAKeyPair();
   private final CoreContainer cores;
   private final int MAX_VALIDITY = Integer.parseInt(System.getProperty("pkiauth.ttl", "5000"));
   private final String myNodeName;
-
+  private final HttpHeaderClientInterceptor interceptor = new HttpHeaderClientInterceptor();
   private boolean interceptorRegistered = false;
 
   public void setInterceptorRegistered(){
@@ -197,7 +197,7 @@ public class PKIAuthenticationPlugin extends AuthenticationPlugin implements Htt
     try {
       String uri = url + PATH + "?wt=json&omitHeader=true";
       log.debug("Fetching fresh public key from : {}",uri);
-      HttpResponse rsp = cores.getUpdateShardHandler().getHttpClient().execute(new HttpGet(uri));
+      HttpResponse rsp = cores.getUpdateShardHandler().getHttpClient().execute(new HttpGet(uri), HttpClientUtil.createNewHttpClientRequestContext());
       byte[] bytes = EntityUtils.toByteArray(rsp.getEntity());
       Map m = (Map) Utils.fromJSON(bytes);
       String key = (String) m.get("key");
@@ -217,11 +217,10 @@ public class PKIAuthenticationPlugin extends AuthenticationPlugin implements Htt
 
   }
 
-  private HttpHeaderClientConfigurer clientConfigurer = new HttpHeaderClientConfigurer();
-
   @Override
-  public HttpClientConfigurer getClientConfigurer() {
-    return clientConfigurer;
+  public SolrHttpClientBuilder getHttpClientBuilder(SolrHttpClientBuilder builder) {
+    HttpClientUtil.addRequestInterceptor(interceptor);
+    return builder;
   }
 
   public SolrRequestHandler getRequestHandler() {
@@ -242,13 +241,9 @@ public class PKIAuthenticationPlugin extends AuthenticationPlugin implements Htt
     return req.getUserPrincipal() != SU;
   }
 
-  private class HttpHeaderClientConfigurer extends HttpClientConfigurer implements
-      HttpRequestInterceptor {
+  private class HttpHeaderClientInterceptor implements HttpRequestInterceptor {
 
-    @Override
-    public void configure(DefaultHttpClient httpClient, SolrParams config) {
-      super.configure(httpClient, config);
-      httpClient.addRequestInterceptor(this);
+    public HttpHeaderClientInterceptor() {
     }
 
     @Override
@@ -299,12 +294,12 @@ public class PKIAuthenticationPlugin extends AuthenticationPlugin implements Htt
 
   boolean disabled() {
     return cores.getAuthenticationPlugin() == null ||
-        cores.getAuthenticationPlugin() instanceof HttpClientInterceptorPlugin;
+        cores.getAuthenticationPlugin() instanceof HttpClientBuilderPlugin;
   }
 
   @Override
   public void close() throws IOException {
-
+    HttpClientUtil.removeRequestInterceptor(interceptor);
   }
 
   public String getPublicKey() {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java b/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java
index 63cfb7c..4687154 100644
--- a/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java
+++ b/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java
@@ -58,6 +58,7 @@ import org.apache.http.client.methods.HttpPut;
 import org.apache.http.client.methods.HttpRequestBase;
 import org.apache.http.entity.InputStreamEntity;
 import org.apache.solr.client.solrj.impl.CloudSolrClient;
+import org.apache.solr.client.solrj.impl.HttpClientUtil;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.SolrException.ErrorCode;
 import org.apache.solr.common.cloud.Aliases;
@@ -557,7 +558,7 @@ public class HttpSolrCall {
         method.removeHeaders(CONTENT_LENGTH_HEADER);
       }
 
-      final HttpResponse response = solrDispatchFilter.httpClient.execute(method);
+      final HttpResponse response = solrDispatchFilter.httpClient.execute(method, HttpClientUtil.createNewHttpClientRequestContext());
       int httpStatus = response.getStatusLine().getStatusCode();
       httpEntity = response.getEntity();
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java b/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java
index a44b8f8..4fe869c 100644
--- a/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java
+++ b/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java
@@ -16,27 +16,21 @@
  */
 package org.apache.solr.update;
 
+import java.lang.invoke.MethodHandles;
+import java.util.concurrent.ExecutorService;
+
 import org.apache.http.client.HttpClient;
-import org.apache.http.conn.ClientConnectionManager;
 import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.impl.conn.PoolingClientConnectionManager;
-import org.apache.http.impl.conn.SchemeRegistryFactory;
-import org.apache.solr.client.solrj.impl.HttpClientConfigurer;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
 import org.apache.solr.client.solrj.impl.HttpClientUtil;
 import org.apache.solr.cloud.RecoveryStrategy;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.params.ModifiableSolrParams;
 import org.apache.solr.common.util.ExecutorUtil;
-import org.apache.solr.common.util.IOUtils;
 import org.apache.solr.common.util.SolrjNamedThreadFactory;
-import org.apache.solr.core.NodeConfig;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.lang.invoke.MethodHandles;
-import java.util.concurrent.ExecutorService;
-
 public class UpdateShardHandler {
   
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@@ -54,53 +48,25 @@ public class UpdateShardHandler {
   private ExecutorService recoveryExecutor = ExecutorUtil.newMDCAwareCachedThreadPool(
       new SolrjNamedThreadFactory("recoveryExecutor"));
   
-  private PoolingClientConnectionManager clientConnectionManager;
-  
   private final CloseableHttpClient client;
 
-  private final UpdateShardHandlerConfig cfg;
+  private final PoolingHttpClientConnectionManager clientConnectionManager;
 
   public UpdateShardHandler(UpdateShardHandlerConfig cfg) {
-    this.cfg = cfg;
-    clientConnectionManager = new PoolingClientConnectionManager(SchemeRegistryFactory.createSystemDefault());
+    clientConnectionManager = new PoolingHttpClientConnectionManager(HttpClientUtil.getSchemaRegisteryProvider().getSchemaRegistry());
     if (cfg != null ) {
       clientConnectionManager.setMaxTotal(cfg.getMaxUpdateConnections());
       clientConnectionManager.setDefaultMaxPerRoute(cfg.getMaxUpdateConnectionsPerHost());
     }
 
-    ModifiableSolrParams clientParams = getClientParams();
+    ModifiableSolrParams clientParams = new ModifiableSolrParams();
     log.info("Creating UpdateShardHandler HTTP client with params: {}", clientParams);
     client = HttpClientUtil.createClient(clientParams, clientConnectionManager);
   }
-
-  protected ModifiableSolrParams getClientParams() {
-    ModifiableSolrParams clientParams = new ModifiableSolrParams();
-    if (cfg != null) {
-      clientParams.set(HttpClientUtil.PROP_SO_TIMEOUT,
-          cfg.getDistributedSocketTimeout());
-      clientParams.set(HttpClientUtil.PROP_CONNECTION_TIMEOUT,
-          cfg.getDistributedConnectionTimeout());
-    }
-    // in the update case, we want to do retries, and to use
-    // the default Solr retry handler that createClient will 
-    // give us
-    clientParams.set(HttpClientUtil.PROP_USE_RETRY, true);
-    return clientParams;
-  }
-  
   
   public HttpClient getHttpClient() {
     return client;
   }
-
-  public void reconfigureHttpClient(HttpClientConfigurer configurer) {
-    log.info("Reconfiguring the default client with: " + configurer);
-    configurer.configure((DefaultHttpClient)client, getClientParams());
-  }
-
-  public ClientConnectionManager getConnectionManager() {
-    return clientConnectionManager;
-  }
   
   /**
    * This method returns an executor that is not meant for disk IO and that will
@@ -112,6 +78,11 @@ public class UpdateShardHandler {
     return updateExecutor;
   }
   
+
+  public PoolingHttpClientConnectionManager getConnectionManager() {
+    return clientConnectionManager;
+  }
+
   /**
    * In general, RecoveryStrategy threads do not do disk IO, but they open and close SolrCores
    * in async threads, amoung other things, and can trigger disk IO, so we use this alternate 
@@ -131,8 +102,8 @@ public class UpdateShardHandler {
     } catch (Exception e) {
       SolrException.log(log, e);
     } finally {
-      IOUtils.closeQuietly(client);
-      clientConnectionManager.shutdown();
+      HttpClientUtil.close(client);
+      clientConnectionManager.close();
     }
   }
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/java/org/apache/solr/util/SolrCLI.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/util/SolrCLI.java b/solr/core/src/java/org/apache/solr/util/SolrCLI.java
index 19aa52a..ae11118 100644
--- a/solr/core/src/java/org/apache/solr/util/SolrCLI.java
+++ b/solr/core/src/java/org/apache/solr/util/SolrCLI.java
@@ -16,6 +16,8 @@
  */
 package org.apache.solr.util;
 
+import static org.apache.solr.common.params.CommonParams.NAME;
+
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -35,7 +37,6 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.Enumeration;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Locale;
@@ -79,9 +80,9 @@ 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.HttpClientConfigurer;
 import org.apache.solr.client.solrj.impl.HttpClientUtil;
 import org.apache.solr.client.solrj.impl.HttpSolrClient;
+import org.apache.solr.client.solrj.impl.SolrHttpClientBuilder;
 import org.apache.solr.client.solrj.request.ContentStreamUpdateRequest;
 import org.apache.solr.client.solrj.response.QueryResponse;
 import org.apache.solr.common.SolrException;
@@ -101,8 +102,6 @@ import org.noggit.ObjectBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import static org.apache.solr.common.params.CommonParams.NAME;
-
 /**
  * Command-line utility for working with Solr.
  */
@@ -275,15 +274,15 @@ public class SolrCLI {
       exit(0);
     }
 
-    String configurerClassName = System.getProperty("solr.authentication.httpclient.configurer");
-    if (configurerClassName!=null) {
+    String builderClassName = System.getProperty("solr.authentication.httpclient.builder");
+    if (builderClassName!=null) {
       try {
-        Class c = Class.forName(configurerClassName);
-        HttpClientConfigurer configurer = (HttpClientConfigurer)c.newInstance();
-        HttpClientUtil.setConfigurer(configurer);
-        log.info("Set HttpClientConfigurer from: "+configurerClassName);
+        Class c = Class.forName(builderClassName);
+        SolrHttpClientBuilder builder = (SolrHttpClientBuilder)c.newInstance();
+        HttpClientUtil.setHttpClientBuilder(builder);
+        log.info("Set HttpClientConfigurer from: "+builderClassName);
       } catch (Exception ex) {
-        throw new RuntimeException("Error during loading of configurer '"+configurerClassName+"'.", ex);
+        throw new RuntimeException("Error during loading of configurer '"+builderClassName+"'.", ex);
       }
     }
 
@@ -651,7 +650,7 @@ public class SolrCLI {
     // ensure we're requesting JSON back from Solr
     HttpGet httpGet = new HttpGet(new URIBuilder(getUrl).setParameter(CommonParams.WT, CommonParams.JSON).build());
     // make the request and get back a parsed JSON object
-    Map<String,Object> json = httpClient.execute(httpGet, new SolrResponseHandler());
+    Map<String,Object> json = httpClient.execute(httpGet, new SolrResponseHandler(), HttpClientUtil.createNewHttpClientRequestContext());
     // check the response JSON from Solr to see if it is an error
     Long statusCode = asLong("/responseHeader/status", json);
     if (statusCode == -1) {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/test-files/log4j.properties
----------------------------------------------------------------------
diff --git a/solr/core/src/test-files/log4j.properties b/solr/core/src/test-files/log4j.properties
index e056163..2697203 100644
--- a/solr/core/src/test-files/log4j.properties
+++ b/solr/core/src/test-files/log4j.properties
@@ -29,8 +29,8 @@ log4j.logger.org.apache.solr.hadoop=INFO
 #log4j.logger.org.apache.solr.common.cloud.ClusterStateUtil=DEBUG
 #log4j.logger.org.apache.solr.cloud.OverseerAutoReplicaFailoverThread=DEBUG
 
-#log4j.logger.org.apache.http.impl.conn.PoolingClientConnectionManager=DEBUG
+#log4j.logger.org.apache.http.impl.conn.PoolingHttpClientConnectionManager=DEBUG
 #log4j.logger.org.apache.http.impl.conn.BasicClientConnectionManager=DEBUG
 #log4j.logger.org.apache.http=DEBUG
 #log4j.logger.org.apache.solr.client.solrj.impl.SolrHttpRequestRetryHandler=DEBUG
-#log4j.logger.org.eclipse.jetty.server=DEBUG
+#log4j.logger.org.eclipse.jetty=DEBUG

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/test/org/apache/solr/TestDistributedSearch.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/TestDistributedSearch.java b/solr/core/src/test/org/apache/solr/TestDistributedSearch.java
index dbc48dd..a25498a 100644
--- a/solr/core/src/test/org/apache/solr/TestDistributedSearch.java
+++ b/solr/core/src/test/org/apache/solr/TestDistributedSearch.java
@@ -55,6 +55,7 @@ import org.apache.solr.handler.component.TrackingShardHandlerFactory;
 import org.apache.solr.handler.component.TrackingShardHandlerFactory.RequestTrackingQueue;
 import org.apache.solr.handler.component.TrackingShardHandlerFactory.ShardRequestAndParams;
 import org.apache.solr.response.SolrQueryResponse;
+import org.junit.BeforeClass;
 import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -89,6 +90,15 @@ public class TestDistributedSearch extends BaseDistributedSearchTestCase {
     return "solr-trackingshardhandler.xml";
   }
 
+  @BeforeClass
+  public static void beforeClass() {
+    // we shutdown a jetty and start it and try to use
+    // the same http client pretty fast - this lowered setting makes sure
+    // we validate the connection before use on the restarted
+    // server so that we don't use a bad one
+    System.setProperty("validateAfterInactivity", "200");
+  }
+  
   @Test
   public void test() throws Exception {
     QueryResponse rsp = null;
@@ -988,7 +998,7 @@ public class TestDistributedSearch extends BaseDistributedSearchTestCase {
 
       // restart the jettys
       for (JettySolrRunner downJetty : downJettys) {
-        downJetty.start();
+        ChaosMonkey.start(downJetty);
       }
     }
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/test/org/apache/solr/client/solrj/ConnectionReuseTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/client/solrj/ConnectionReuseTest.java b/solr/core/src/test/org/apache/solr/client/solrj/ConnectionReuseTest.java
index 0ec9876..0d78975 100644
--- a/solr/core/src/test/org/apache/solr/client/solrj/ConnectionReuseTest.java
+++ b/solr/core/src/test/org/apache/solr/client/solrj/ConnectionReuseTest.java
@@ -18,24 +18,25 @@ package org.apache.solr.client.solrj;
 
 import java.io.IOException;
 import java.net.URL;
+import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import org.apache.http.client.methods.Configurable;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.HttpClientConnection;
 import org.apache.http.HttpConnectionMetrics;
 import org.apache.http.HttpException;
 import org.apache.http.HttpHost;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpVersion;
 import org.apache.http.client.HttpClient;
-import org.apache.http.conn.ClientConnectionRequest;
 import org.apache.http.conn.ConnectionPoolTimeoutException;
-import org.apache.http.conn.ManagedClientConnection;
+import org.apache.http.conn.ConnectionRequest;
 import org.apache.http.conn.routing.HttpRoute;
-import org.apache.http.impl.conn.PoolingClientConnectionManager;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
 import org.apache.http.message.BasicHttpRequest;
-import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.HttpProtocolParams;
-import org.apache.http.protocol.BasicHttpContext;
 import org.apache.solr.SolrTestCaseJ4.SuppressSSL;
 import org.apache.solr.client.solrj.impl.CloudSolrClient;
 import org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrClient;
@@ -51,7 +52,7 @@ import org.junit.Test;
 public class ConnectionReuseTest extends AbstractFullDistribZkTestBase {
   
   private AtomicInteger id = new AtomicInteger();
-  
+  private HttpClientContext context = HttpClientContext.create();
   @BeforeClass
   public static void beforeConnectionReuseTest() {
     if (true) TestInjection.failUpdateRequests = "true:100";
@@ -74,114 +75,122 @@ public class ConnectionReuseTest extends AbstractFullDistribZkTestBase {
   
   @Test
   public void test() throws Exception {
+
     URL url = new URL(((HttpSolrClient) clients.get(0)).getBaseURL());
-    
-    SolrClient client;
-    HttpClient httpClient = HttpClientUtil.createClient(null);
-    int rndClient = random().nextInt(3);
-    if (rndClient == 0) {
-      client = new ConcurrentUpdateSolrClient(url.toString(), httpClient, 6, 1); // currently only testing with 1 thread
-    } else if (rndClient == 1)  {
-      client = new HttpSolrClient(url.toString(), httpClient);
-    } else if (rndClient == 2) {
-      client = new CloudSolrClient(zkServer.getZkAddress(), random().nextBoolean(), httpClient);
-      ((CloudSolrClient) client).setParallelUpdates(random().nextBoolean());
-      ((CloudSolrClient) client).setDefaultCollection(DEFAULT_COLLECTION);
-      ((CloudSolrClient) client).getLbClient().setConnectionTimeout(30000);
-      ((CloudSolrClient) client).getLbClient().setSoTimeout(60000);
-    } else {
-      throw new RuntimeException("impossible");
-    }
-    
-    PoolingClientConnectionManager cm = (PoolingClientConnectionManager) httpClient.getConnectionManager();
-
-    HttpHost target = new HttpHost(url.getHost(), url.getPort(), isSSLMode() ? "https" : "http");
-    HttpRoute route = new HttpRoute(target);
-    
-    ClientConnectionRequest mConn = getClientConnectionRequest(httpClient, route);
-   
-    ManagedClientConnection conn1 = getConn(mConn);
-    headerRequest(target, route, conn1);
-    conn1.releaseConnection();
-    cm.releaseConnection(conn1, -1, TimeUnit.MILLISECONDS);
-    
-    int queueBreaks = 0;
-    int cnt1 = atLeast(3);
-    int cnt2 = atLeast(30);
-    for (int j = 0; j < cnt1; j++) {
-      for (int i = 0; i < cnt2; i++) {
-        boolean done = false;
-        AddUpdateCommand c = new AddUpdateCommand(null);
-        c.solrDoc = sdoc("id", id.incrementAndGet());
-        try {
-          client.add(c.solrDoc);
-        } catch (Exception e) {
-          e.printStackTrace();
+    PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
+    SolrClient client = null;
+    CloseableHttpClient httpClient = HttpClientUtil.createClient(null, cm);
+    try {
+      int rndClient = random().nextInt(3);
+      if (rndClient == 0) {
+        client = new ConcurrentUpdateSolrClient(url.toString(), httpClient, 6, 1); // currently only testing with 1
+                                                                                   // thread
+      } else if (rndClient == 1) {
+        client = new HttpSolrClient(url.toString(), httpClient);
+      } else if (rndClient == 2) {
+        client = new CloudSolrClient(zkServer.getZkAddress(), random().nextBoolean(), httpClient);
+        ((CloudSolrClient) client).setParallelUpdates(random().nextBoolean());
+        ((CloudSolrClient) client).setDefaultCollection(DEFAULT_COLLECTION);
+        ((CloudSolrClient) client).getLbClient().setConnectionTimeout(30000);
+        ((CloudSolrClient) client).getLbClient().setSoTimeout(60000);
+      } else {
+        throw new RuntimeException("impossible");
+      }
+
+      HttpHost target = new HttpHost(url.getHost(), url.getPort(), isSSLMode() ? "https" : "http");
+      HttpRoute route = new HttpRoute(target);
+
+      ConnectionRequest mConn = getClientConnectionRequest(httpClient, route, cm);
+
+      HttpClientConnection conn1 = getConn(mConn);
+      headerRequest(target, route, conn1, cm);
+
+      cm.releaseConnection(conn1, null, -1, TimeUnit.MILLISECONDS);
+
+      int queueBreaks = 0;
+      int cnt1 = atLeast(3);
+      int cnt2 = atLeast(30);
+      for (int j = 0; j < cnt1; j++) {
+        for (int i = 0; i < cnt2; i++) {
+          boolean done = false;
+          AddUpdateCommand c = new AddUpdateCommand(null);
+          c.solrDoc = sdoc("id", id.incrementAndGet());
+          try {
+            client.add(c.solrDoc);
+          } catch (Exception e) {
+            e.printStackTrace();
+          }
+          if (!done && i > 0 && i < cnt2 - 1 && client instanceof ConcurrentUpdateSolrClient
+              && random().nextInt(10) > 8) {
+            queueBreaks++;
+            done = true;
+            Thread.sleep(350); // wait past streaming client poll time of 250ms
+          }
         }
-        if (!done && i > 0 && i < cnt2 - 1 && client instanceof ConcurrentUpdateSolrClient && random().nextInt(10) > 8) {
-          queueBreaks++;
-          done = true;
-          Thread.sleep(350); // wait past streaming client poll time of 250ms
+        if (client instanceof ConcurrentUpdateSolrClient) {
+          ((ConcurrentUpdateSolrClient) client).blockUntilFinished();
         }
       }
+
+      route = new HttpRoute(new HttpHost(url.getHost(), url.getPort(), isSSLMode() ? "https" : "http"));
+
+      mConn = cm.requestConnection(route, null);
+
+      HttpClientConnection conn2 = getConn(mConn);
+
+      HttpConnectionMetrics metrics = conn2.getMetrics();
+      headerRequest(target, route, conn2, cm);
+
+      cm.releaseConnection(conn2, null, -1, TimeUnit.MILLISECONDS);
+
+      assertNotNull("No connection metrics found - is the connection getting aborted? server closing the connection? "
+          + client.getClass().getSimpleName(), metrics);
+
+      // we try and make sure the connection we get has handled all of the requests in this test
       if (client instanceof ConcurrentUpdateSolrClient) {
-        ((ConcurrentUpdateSolrClient) client).blockUntilFinished();
+        // we can't fully control queue polling breaking up requests - allow a bit of leeway
+        int exp = cnt1 + queueBreaks + 2;
+        assertTrue(
+            "We expected all communication via streaming client to use one connection! expected=" + exp + " got="
+                + metrics.getRequestCount(),
+            Math.max(exp, metrics.getRequestCount()) - Math.min(exp, metrics.getRequestCount()) < 3);
+      } else {
+        assertTrue("We expected all communication to use one connection! " + client.getClass().getSimpleName() + " "
+            + metrics.getRequestCount(),
+            cnt1 * cnt2 + 2 <= metrics.getRequestCount());
       }
-    }
 
-    route = new HttpRoute(new HttpHost(url.getHost(), url.getPort(), isSSLMode() ? "https" : "http"));
-
-    mConn = cm.requestConnection(route, null);
-   
-    ManagedClientConnection conn2 = getConn(mConn);
-
-    HttpConnectionMetrics metrics = conn2.getMetrics();
-    headerRequest(target, route, conn2);
-    conn2.releaseConnection();
-    cm.releaseConnection(conn2, -1, TimeUnit.MILLISECONDS);
-
-    
-    assertNotNull("No connection metrics found - is the connection getting aborted? server closing the connection? " + client.getClass().getSimpleName(), metrics);
-    
-    // we try and make sure the connection we get has handled all of the requests in this test
-    if (client instanceof ConcurrentUpdateSolrClient) {
-      // we can't fully control queue polling breaking up requests - allow a bit of leeway
-      int exp = cnt1 + queueBreaks + 2;
-      assertTrue(
-          "We expected all communication via streaming client to use one connection! expected=" + exp + " got="
-              + metrics.getRequestCount(),
-          Math.max(exp, metrics.getRequestCount()) - Math.min(exp, metrics.getRequestCount()) < 3);
-    } else {
-      assertTrue("We expected all communication to use one connection! " + client.getClass().getSimpleName(),
-          cnt1 * cnt2 + 2 <= metrics.getRequestCount());
+    } finally {
+      client.close();
+      HttpClientUtil.close(httpClient);
     }
-    
-    client.close();
   }
 
-  public ManagedClientConnection getConn(ClientConnectionRequest mConn)
-      throws InterruptedException, ConnectionPoolTimeoutException {
-    ManagedClientConnection conn = mConn.getConnection(30, TimeUnit.SECONDS);
-    conn.setIdleDuration(-1, TimeUnit.MILLISECONDS);
-    conn.markReusable();
+  public HttpClientConnection getConn(ConnectionRequest mConn)
+      throws InterruptedException, ConnectionPoolTimeoutException, ExecutionException {
+    HttpClientConnection conn = mConn.get(30, TimeUnit.SECONDS);
+
     return conn;
   }
 
-  public void headerRequest(HttpHost target, HttpRoute route, ManagedClientConnection conn)
+  public void headerRequest(HttpHost target, HttpRoute route, HttpClientConnection conn, PoolingHttpClientConnectionManager cm)
       throws IOException, HttpException {
     HttpRequest req = new BasicHttpRequest("OPTIONS", "*", HttpVersion.HTTP_1_1);
 
     req.addHeader("Host", target.getHostName());
-    BasicHttpParams p = new BasicHttpParams();
-    HttpProtocolParams.setVersion(p, HttpVersion.HTTP_1_1);
-    if (!conn.isOpen()) conn.open(route, new BasicHttpContext(null), p);
+    if (!conn.isOpen()) {
+      // establish connection based on its route info
+      cm.connect(conn, route, 1000, context);
+      // and mark it as route complete
+      cm.routeComplete(conn, route, context);
+    }
     conn.sendRequestHeader(req);
     conn.flush();
     conn.receiveResponseHeader();
   }
 
-  public ClientConnectionRequest getClientConnectionRequest(HttpClient httpClient, HttpRoute route) {
-    ClientConnectionRequest mConn = ((PoolingClientConnectionManager) httpClient.getConnectionManager()).requestConnection(route, null);
+  public ConnectionRequest getClientConnectionRequest(HttpClient httpClient, HttpRoute route, PoolingHttpClientConnectionManager cm) {
+    ConnectionRequest mConn = cm.requestConnection(route, null);
     return mConn;
   }
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/test/org/apache/solr/client/solrj/embedded/TestJettySolrRunner.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/client/solrj/embedded/TestJettySolrRunner.java b/solr/core/src/test/org/apache/solr/client/solrj/embedded/TestJettySolrRunner.java
index 17facec..dc8896d 100644
--- a/solr/core/src/test/org/apache/solr/client/solrj/embedded/TestJettySolrRunner.java
+++ b/solr/core/src/test/org/apache/solr/client/solrj/embedded/TestJettySolrRunner.java
@@ -53,13 +53,13 @@ public class TestJettySolrRunner extends SolrTestCaseJ4 {
     try {
       runner.start();
 
-      SolrClient client = new HttpSolrClient(runner.getBaseUrl().toString());
+      try (SolrClient client = new HttpSolrClient(runner.getBaseUrl().toString())) {
+        CoreAdminRequest.Create createReq = new CoreAdminRequest.Create();
+        createReq.setCoreName("newcore");
+        createReq.setConfigSet("minimal");
 
-      CoreAdminRequest.Create createReq = new CoreAdminRequest.Create();
-      createReq.setCoreName("newcore");
-      createReq.setConfigSet("minimal");
-
-      client.request(createReq);
+        client.request(createReq);
+      }
 
       assertTrue(Files.exists(coresDir.resolve("newcore").resolve("core.properties")));
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/test/org/apache/solr/cloud/BaseCdcrDistributedZkTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/BaseCdcrDistributedZkTest.java b/solr/core/src/test/org/apache/solr/cloud/BaseCdcrDistributedZkTest.java
index fe94309..ca4f912 100644
--- a/solr/core/src/test/org/apache/solr/cloud/BaseCdcrDistributedZkTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/BaseCdcrDistributedZkTest.java
@@ -168,6 +168,11 @@ public class BaseCdcrDistributedZkTest extends AbstractDistribZkTestBase {
 
   @After
   public void baseAfter() throws Exception {
+    for (List<CloudJettyRunner> runners : cloudJettys.values()) {
+      for (CloudJettyRunner runner : runners) {
+        runner.client.close();
+      }
+    }
     destroyServers();
   }
 
@@ -175,8 +180,6 @@ public class BaseCdcrDistributedZkTest extends AbstractDistribZkTestBase {
     CloudSolrClient server = new CloudSolrClient(zkServer.getZkAddress(), random().nextBoolean());
     server.setParallelUpdates(random().nextBoolean());
     if (defaultCollection != null) server.setDefaultCollection(defaultCollection);
-    server.getLbClient().getHttpClient().getParams()
-        .setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 30000);
     return server;
   }
 
@@ -747,8 +750,6 @@ public class BaseCdcrDistributedZkTest extends AbstractDistribZkTestBase {
       // setup the server...
       HttpSolrClient s = new HttpSolrClient(baseUrl);
       s.setConnectionTimeout(DEFAULT_CONNECTION_TIMEOUT);
-      s.setDefaultMaxConnectionsPerHost(100);
-      s.setMaxTotalConnections(100);
       return s;
     } catch (Exception ex) {
       throw new RuntimeException(ex);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/test/org/apache/solr/cloud/BasicDistributedZkTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/BasicDistributedZkTest.java b/solr/core/src/test/org/apache/solr/cloud/BasicDistributedZkTest.java
index 8222e91..6eee7db 100644
--- a/solr/core/src/test/org/apache/solr/cloud/BasicDistributedZkTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/BasicDistributedZkTest.java
@@ -404,17 +404,18 @@ public class BasicDistributedZkTest extends AbstractFullDistribZkTestBase {
     for (Slice slice : dColl.getActiveSlices()) {
       long sliceDocCount = -1;
       for (Replica rep : slice.getReplicas()) {
-        HttpSolrClient one = new HttpSolrClient(rep.getCoreUrl());
-        SolrQuery query = new SolrQuery("*:*");
-        query.setDistrib(false);
-        QueryResponse resp = one.query(query);
-        long hits = resp.getResults().getNumFound();
-        if (sliceDocCount == -1) {
-          sliceDocCount = hits;
-          docTotal += hits; 
-        } else {
-          if (hits != sliceDocCount) {
-            return -1;
+        try (HttpSolrClient one = new HttpSolrClient(rep.getCoreUrl())) {
+          SolrQuery query = new SolrQuery("*:*");
+          query.setDistrib(false);
+          QueryResponse resp = one.query(query);
+          long hits = resp.getResults().getNumFound();
+          if (sliceDocCount == -1) {
+            sliceDocCount = hits;
+            docTotal += hits;
+          } else {
+            if (hits != sliceDocCount) {
+              return -1;
+            }
           }
         }
       }
@@ -963,7 +964,7 @@ public class BasicDistributedZkTest extends AbstractFullDistribZkTestBase {
       @Override
       public Object call() {
         try (HttpSolrClient client = new HttpSolrClient(baseUrl)) {
-          client.setConnectionTimeout(15000);
+          // client.setConnectionTimeout(15000);
           Create createCmd = new Create();
           createCmd.setRoles("none");
           createCmd.setCoreName(collection + num);
@@ -1124,9 +1125,7 @@ public class BasicDistributedZkTest extends AbstractFullDistribZkTestBase {
     try {
       // setup the server...
       HttpSolrClient client = new HttpSolrClient(baseUrl + "/" + collection);
-      client.setSoTimeout(120000);
-      client.setDefaultMaxConnectionsPerHost(100);
-      client.setMaxTotalConnections(100);
+
       return client;
     }
     catch (Exception ex) {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java b/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java
index 7dceada..3ddf99d 100644
--- a/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java
@@ -70,6 +70,8 @@ public class ChaosMonkeyNothingIsSafeTest extends AbstractFullDistribZkTestBase
   
   protected static final String[] fieldNames = new String[]{"f_i", "f_f", "f_d", "f_l", "f_dt"};
   protected static final RandVal[] randVals = new RandVal[]{rint, rfloat, rdouble, rlong, rdate};
+
+  private int clientSoTimeout;
   
   public String[] getFieldNames() {
     return fieldNames;
@@ -109,6 +111,7 @@ public class ChaosMonkeyNothingIsSafeTest extends AbstractFullDistribZkTestBase
 
   @Test
   public void test() throws Exception {
+    cloudClient.setSoTimeout(clientSoTimeout);
     boolean testSuccessful = false;
     try {
       handle.clear();
@@ -293,8 +296,7 @@ public class ChaosMonkeyNothingIsSafeTest extends AbstractFullDistribZkTestBase
       setName("FullThrottleStopableIndexingThread");
       setDaemon(true);
       this.clients = clients;
-      HttpClientUtil.setConnectionTimeout(httpClient, clientConnectionTimeout);
-      HttpClientUtil.setSoTimeout(httpClient, clientSoTimeout);
+
       cusc = new ConcurrentUpdateSolrClient(
           ((HttpSolrClient) clients.get(0)).getBaseURL(), httpClient, 8,
           2) {
@@ -303,6 +305,8 @@ public class ChaosMonkeyNothingIsSafeTest extends AbstractFullDistribZkTestBase
           log.warn("cusc error", ex);
         }
       };
+      cusc.setConnectionTimeout(10000);
+      cusc.setSoTimeout(clientSoTimeout);
     }
     
     @Override

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIDistributedZkTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIDistributedZkTest.java b/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIDistributedZkTest.java
index 641dadf..5c80f2d 100644
--- a/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIDistributedZkTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIDistributedZkTest.java
@@ -97,6 +97,7 @@ public class CollectionsAPIDistributedZkTest extends AbstractFullDistribZkTestBa
   @BeforeClass
   public static void beforeCollectionsAPIDistributedZkTest() {
     TestInjection.randomDelayInCoreCreation = "true:20";
+    System.setProperty("validateAfterInactivity", "200");
   }
   
   @Override
@@ -1196,11 +1197,12 @@ public class CollectionsAPIDistributedZkTest extends AbstractFullDistribZkTestBa
           null, client, props);
       assertNotNull(newReplica);
 
-      HttpSolrClient coreclient = new HttpSolrClient(newReplica.getStr(ZkStateReader.BASE_URL_PROP));
-      CoreAdminResponse status = CoreAdminRequest.getStatus(newReplica.getStr("core"), coreclient);
-      NamedList<Object> coreStatus = status.getCoreStatus(newReplica.getStr("core"));
-      String instanceDirStr = (String) coreStatus.get("instanceDir");
-      assertEquals(Paths.get(instanceDirStr).toString(), instancePathStr);
+      try (HttpSolrClient coreclient = new HttpSolrClient(newReplica.getStr(ZkStateReader.BASE_URL_PROP))) {
+        CoreAdminResponse status = CoreAdminRequest.getStatus(newReplica.getStr("core"), coreclient);
+        NamedList<Object> coreStatus = status.getCoreStatus(newReplica.getStr("core"));
+        String instanceDirStr = (String) coreStatus.get("instanceDir");
+        assertEquals(Paths.get(instanceDirStr).toString(), instancePathStr);
+      }
 
       //Test to make sure we can't create another replica with an existing core_name of that collection
       String coreName = newReplica.getStr(CORE_NAME_PROP);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/test/org/apache/solr/cloud/HttpPartitionTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/HttpPartitionTest.java b/solr/core/src/test/org/apache/solr/cloud/HttpPartitionTest.java
index f1960aa..9dcbb8c 100644
--- a/solr/core/src/test/org/apache/solr/cloud/HttpPartitionTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/HttpPartitionTest.java
@@ -253,12 +253,14 @@ public class HttpPartitionTest extends AbstractFullDistribZkTestBase {
 
     // Check that doc 3 is on the leader but not on the notLeaders
     Replica leader = cloudClient.getZkStateReader().getLeaderRetry(testCollectionName, "shard1", 10000);
-    HttpSolrClient leaderSolr = getHttpSolrClient(leader, testCollectionName);
-    assertDocExists(leaderSolr, testCollectionName, "3");
+    try (HttpSolrClient leaderSolr = getHttpSolrClient(leader, testCollectionName)) {
+      assertDocExists(leaderSolr, testCollectionName, "3");
+    }
 
     for (Replica notLeader : notLeaders) {
-      HttpSolrClient notLeaderSolr = getHttpSolrClient(notLeader, testCollectionName);
-      assertDocNotExists(notLeaderSolr, testCollectionName, "3");
+      try (HttpSolrClient notLeaderSolr = getHttpSolrClient(notLeader, testCollectionName)) {
+        assertDocNotExists(notLeaderSolr, testCollectionName, "3");
+      }
     }
 
     // Retry sending doc 3

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/test/org/apache/solr/cloud/LeaderFailoverAfterPartitionTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/LeaderFailoverAfterPartitionTest.java b/solr/core/src/test/org/apache/solr/cloud/LeaderFailoverAfterPartitionTest.java
index 0436d5e..9f1abde 100644
--- a/solr/core/src/test/org/apache/solr/cloud/LeaderFailoverAfterPartitionTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/LeaderFailoverAfterPartitionTest.java
@@ -21,12 +21,14 @@ import org.apache.solr.SolrTestCaseJ4.SuppressSSL;
 import org.apache.solr.client.solrj.embedded.JettySolrRunner;
 import org.apache.solr.client.solrj.impl.HttpSolrClient;
 import org.apache.solr.client.solrj.request.CollectionAdminRequest;
+import org.apache.solr.common.SolrInputDocument;
 import org.apache.solr.common.cloud.Replica;
 import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.lang.invoke.MethodHandles;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -170,9 +172,10 @@ public class LeaderFailoverAfterPartitionTest extends HttpPartitionTest {
             printClusterStateInfo(testCollectionName),
         participatingReplicas.size() >= 2);
 
-    
-    sendDoc(6);
-
+    SolrInputDocument doc = new SolrInputDocument();
+    doc.addField(id, String.valueOf(6));
+    doc.addField("a_t", "hello" + 6);
+    sendDocsWithRetry(Collections.singletonList(doc), 1, 3, 1);
 
     Set<String> replicasToCheck = new HashSet<>();
     for (Replica stillUp : participatingReplicas)

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/test/org/apache/solr/cloud/SSLMigrationTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/SSLMigrationTest.java b/solr/core/src/test/org/apache/solr/cloud/SSLMigrationTest.java
index a0bb08f..c1b500c 100644
--- a/solr/core/src/test/org/apache/solr/cloud/SSLMigrationTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/SSLMigrationTest.java
@@ -70,7 +70,7 @@ public class SSLMigrationTest extends AbstractFullDistribZkTestBase {
       runner.stop();
     }
     
-    HttpClientUtil.setConfigurer(sslConfig.getHttpClientConfigurer());
+    HttpClientUtil.setHttpClientBuilder(sslConfig.getHttpClientBuilder());
     for(int i = 0; i < this.jettys.size(); i++) {
       JettySolrRunner runner = jettys.get(i);
       JettyConfig config = JettyConfig.builder()

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/test/org/apache/solr/cloud/ShardSplitTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/ShardSplitTest.java b/solr/core/src/test/org/apache/solr/cloud/ShardSplitTest.java
index 6d4b9cc..c691cf0 100644
--- a/solr/core/src/test/org/apache/solr/cloud/ShardSplitTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/ShardSplitTest.java
@@ -604,7 +604,6 @@ public class ShardSplitTest extends BasicDistributedZkTest {
   @Override
   protected CloudSolrClient createCloudClient(String defaultCollection) {
     CloudSolrClient client = super.createCloudClient(defaultCollection);
-    client.getLbClient().getHttpClient().getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 5 * 60 * 1000);
     return client;
   }
 }