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:54 UTC

[22/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.

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/test/org/apache/solr/cloud/TestAuthenticationFramework.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/TestAuthenticationFramework.java b/solr/core/src/test/org/apache/solr/cloud/TestAuthenticationFramework.java
index b9c7264..4ee983b 100644
--- a/solr/core/src/test/org/apache/solr/cloud/TestAuthenticationFramework.java
+++ b/solr/core/src/test/org/apache/solr/cloud/TestAuthenticationFramework.java
@@ -16,26 +16,26 @@
  */
 package org.apache.solr.cloud;
 
+import java.io.IOException;
+import java.lang.invoke.MethodHandles;
+import java.util.Map;
+
 import javax.servlet.FilterChain;
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.lang.invoke.MethodHandles;
-import java.util.Map;
-import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule;
+
 import org.apache.http.HttpException;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpRequestInterceptor;
-import org.apache.http.impl.client.DefaultHttpClient;
 import org.apache.http.protocol.HttpContext;
 import org.apache.lucene.util.LuceneTestCase;
 import org.apache.lucene.util.LuceneTestCase.SuppressSysoutChecks;
-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.security.AuthenticationPlugin;
-import org.apache.solr.security.HttpClientInterceptorPlugin;
+import org.apache.solr.security.HttpClientBuilderPlugin;
 import org.apache.solr.util.RevertDefaultThreadHandlerRule;
 import org.junit.ClassRule;
 import org.junit.Rule;
@@ -45,6 +45,8 @@ import org.junit.rules.TestRule;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule;
+
 /**
  * Test of the MiniSolrCloudCluster functionality with authentication enabled.
  */
@@ -114,10 +116,10 @@ public class TestAuthenticationFramework extends TestMiniSolrCloudCluster {
     super.tearDown();
   }
   
-  public static class MockAuthenticationPlugin extends AuthenticationPlugin implements HttpClientInterceptorPlugin {
+  public static class MockAuthenticationPlugin extends AuthenticationPlugin implements HttpClientBuilderPlugin {
     public static String expectedUsername;
     public static String expectedPassword;
-
+    private HttpRequestInterceptor interceptor;
     @Override
     public void init(Map<String,Object> pluginConfig) {}
 
@@ -141,25 +143,23 @@ public class TestAuthenticationFramework extends TestMiniSolrCloudCluster {
     }
 
     @Override
-    public HttpClientConfigurer getClientConfigurer() {
-      return new MockClientConfigurer();
+    public SolrHttpClientBuilder getHttpClientBuilder(SolrHttpClientBuilder httpClientBuilder) {
+      interceptor = new HttpRequestInterceptor() {
+        @Override
+        public void process(HttpRequest req, HttpContext rsp) throws HttpException, IOException {
+          req.addHeader("username", requestUsername);
+          req.addHeader("password", requestPassword);
+        }
+      };
+
+      HttpClientUtil.addRequestInterceptor(interceptor);
+      return httpClientBuilder;
     }
 
     @Override
-    public void close() {}
-    
-    private static class MockClientConfigurer extends HttpClientConfigurer {
-      @Override
-      public void configure(DefaultHttpClient httpClient, SolrParams config) {
-        super.configure(httpClient, config);
-        httpClient.addRequestInterceptor(new HttpRequestInterceptor() {
-          @Override
-          public void process(HttpRequest req, HttpContext rsp) throws HttpException, IOException {
-            req.addHeader("username", requestUsername);
-            req.addHeader("password", requestPassword);
-          }
-        });
-      }
+    public void close() {
+      HttpClientUtil.removeRequestInterceptor(interceptor);
     }
+    
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/test/org/apache/solr/cloud/TestCloudDeleteByQuery.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/TestCloudDeleteByQuery.java b/solr/core/src/test/org/apache/solr/cloud/TestCloudDeleteByQuery.java
index 2781896..26db949 100644
--- a/solr/core/src/test/org/apache/solr/cloud/TestCloudDeleteByQuery.java
+++ b/solr/core/src/test/org/apache/solr/cloud/TestCloudDeleteByQuery.java
@@ -48,7 +48,7 @@ import org.apache.solr.common.cloud.ZkStateReader;
 import org.apache.solr.common.params.ModifiableSolrParams;
 import org.apache.solr.common.params.SolrParams;
 import org.apache.solr.common.util.SimpleOrderedMap;
-
+import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
 
@@ -89,6 +89,16 @@ public class TestCloudDeleteByQuery extends SolrCloudTestCase {
   /** id field doc routing prefix for shard2 */
   private static final String S_TWO_PRE = "XYZ!";
   
+  @AfterClass
+  private static void afterClass() throws Exception {
+    CLOUD_CLIENT.close();
+    S_ONE_LEADER_CLIENT.close();
+    S_TWO_LEADER_CLIENT.close();
+    S_ONE_NON_LEADER_CLIENT.close();
+    S_TWO_NON_LEADER_CLIENT.close();
+    NO_COLLECTION_CLIENT.close();
+  }
+  
   @BeforeClass
   private static void createMiniSolrCloudCluster() throws Exception {
     

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/test/org/apache/solr/cloud/TestMiniSolrCloudClusterBase.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/TestMiniSolrCloudClusterBase.java b/solr/core/src/test/org/apache/solr/cloud/TestMiniSolrCloudClusterBase.java
index 1828561..33fa43b 100644
--- a/solr/core/src/test/org/apache/solr/cloud/TestMiniSolrCloudClusterBase.java
+++ b/solr/core/src/test/org/apache/solr/cloud/TestMiniSolrCloudClusterBase.java
@@ -63,7 +63,7 @@ public class TestMiniSolrCloudClusterBase extends LuceneTestCase {
     NUM_SHARDS = 2;
     REPLICATION_FACTOR = 2;
   }
-
+  
   @Rule
   public TestRule solrTestRules = RuleChain
       .outerRule(new SystemPropertiesRestoreRule());

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/test/org/apache/solr/cloud/TestRandomRequestDistribution.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/TestRandomRequestDistribution.java b/solr/core/src/test/org/apache/solr/cloud/TestRandomRequestDistribution.java
index 256774d..d0c2da4 100644
--- a/solr/core/src/test/org/apache/solr/cloud/TestRandomRequestDistribution.java
+++ b/solr/core/src/test/org/apache/solr/cloud/TestRandomRequestDistribution.java
@@ -96,13 +96,14 @@ public class TestRandomRequestDistribution extends AbstractFullDistribZkTestBase
     assertEquals(1, replicas.size());
     String baseUrl = replicas.iterator().next().getStr(ZkStateReader.BASE_URL_PROP);
     if (!baseUrl.endsWith("/")) baseUrl += "/";
-    HttpSolrClient client = new HttpSolrClient(baseUrl + "a1x2");
-    client.setSoTimeout(5000);
-    client.setConnectionTimeout(2000);
+    try (HttpSolrClient client = new HttpSolrClient(baseUrl + "a1x2")) {
+      client.setSoTimeout(5000);
+      client.setConnectionTimeout(2000);
 
-    log.info("Making requests to " + baseUrl + "a1x2");
-    for (int i=0; i < 10; i++)  {
-      client.query(new SolrQuery("*:*"));
+      log.info("Making requests to " + baseUrl + "a1x2");
+      for (int i = 0; i < 10; i++) {
+        client.query(new SolrQuery("*:*"));
+      }
     }
 
     Map<String, Integer> shardVsCount = new HashMap<>();
@@ -173,58 +174,59 @@ public class TestRandomRequestDistribution extends AbstractFullDistribZkTestBase
     if (!baseUrl.endsWith("/")) baseUrl += "/";
     String path = baseUrl + "football";
     log.info("Firing queries against path=" + path);
-    HttpSolrClient client = new HttpSolrClient(path);
-    client.setSoTimeout(5000);
-    client.setConnectionTimeout(2000);
-
-    SolrCore leaderCore = null;
-    for (JettySolrRunner jetty : jettys) {
-      CoreContainer container = jetty.getCoreContainer();
-      for (SolrCore core : container.getCores()) {
-        if (core.getName().equals(leader.getStr(ZkStateReader.CORE_NAME_PROP))) {
-          leaderCore = core;
-          break;
+    try (HttpSolrClient client = new HttpSolrClient(path)) {
+      client.setSoTimeout(5000);
+      client.setConnectionTimeout(2000);
+
+      SolrCore leaderCore = null;
+      for (JettySolrRunner jetty : jettys) {
+        CoreContainer container = jetty.getCoreContainer();
+        for (SolrCore core : container.getCores()) {
+          if (core.getName().equals(leader.getStr(ZkStateReader.CORE_NAME_PROP))) {
+            leaderCore = core;
+            break;
+          }
         }
       }
-    }
-    assertNotNull(leaderCore);
-
-    //All queries should be served by the active replica
-    //To make sure that's true we keep querying the down replica
-    //If queries are getting processed by the down replica then the cluster state hasn't updated for that replica locally
-    //So we keep trying till it has updated and then verify if ALL queries go to the active reploca
-    long count = 0;
-    while (true) {
-      count++;
-      client.query(new SolrQuery("*:*"));
-
-      SolrRequestHandler select = leaderCore.getRequestHandler("");
-      long c = (long) select.getStatistics().get("requests");
-
-      if (c == 1) {
-        break;  //cluster state has got update locally
-      } else {
-        Thread.sleep(100);
-      }
+      assertNotNull(leaderCore);
+
+      // All queries should be served by the active replica
+      // To make sure that's true we keep querying the down replica
+      // If queries are getting processed by the down replica then the cluster state hasn't updated for that replica
+      // locally
+      // So we keep trying till it has updated and then verify if ALL queries go to the active reploca
+      long count = 0;
+      while (true) {
+        count++;
+        client.query(new SolrQuery("*:*"));
+
+        SolrRequestHandler select = leaderCore.getRequestHandler("");
+        long c = (long) select.getStatistics().get("requests");
 
-      if (count > 10000) {
-        fail("After 10k queries we still see all requests being processed by the down replica");
+        if (c == 1) {
+          break; // cluster state has got update locally
+        } else {
+          Thread.sleep(100);
+        }
+
+        if (count > 10000) {
+          fail("After 10k queries we still see all requests being processed by the down replica");
+        }
       }
-    }
 
-    //Now we fire a few additional queries and make sure ALL of them
-    //are served by the active replica
-    int moreQueries = TestUtil.nextInt(random(), 4, 10);
-    count = 1; //Since 1 query has already hit the leader
-    for (int i=0; i<moreQueries; i++) {
-      client.query(new SolrQuery("*:*"));
-      count++;
+      // Now we fire a few additional queries and make sure ALL of them
+      // are served by the active replica
+      int moreQueries = TestUtil.nextInt(random(), 4, 10);
+      count = 1; // Since 1 query has already hit the leader
+      for (int i = 0; i < moreQueries; i++) {
+        client.query(new SolrQuery("*:*"));
+        count++;
 
-      SolrRequestHandler select = leaderCore.getRequestHandler("");
-      long c = (long) select.getStatistics().get("requests");
+        SolrRequestHandler select = leaderCore.getRequestHandler("");
+        long c = (long) select.getStatistics().get("requests");
 
-      assertEquals("Query wasn't served by leader", count, c);
+        assertEquals("Query wasn't served by leader", count, c);
+      }
     }
-
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/test/org/apache/solr/cloud/TestSolrCloudWithKerberosAlt.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/TestSolrCloudWithKerberosAlt.java b/solr/core/src/test/org/apache/solr/cloud/TestSolrCloudWithKerberosAlt.java
index f4dc97d..1e2b242 100644
--- a/solr/core/src/test/org/apache/solr/cloud/TestSolrCloudWithKerberosAlt.java
+++ b/solr/core/src/test/org/apache/solr/cloud/TestSolrCloudWithKerberosAlt.java
@@ -16,15 +16,12 @@
  */
 package org.apache.solr.cloud;
 
-import javax.security.auth.login.Configuration;
-
 import java.io.File;
 import java.util.List;
 import java.util.Locale;
 import java.util.Properties;
 
-import com.carrotsearch.randomizedtesting.annotations.ThreadLeakFilters;
-import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule;
+import javax.security.auth.login.Configuration;
 
 import org.apache.commons.io.FileUtils;
 import org.apache.hadoop.minikdc.MiniKdc;
@@ -36,8 +33,6 @@ import org.apache.solr.client.solrj.SolrQuery;
 import org.apache.solr.client.solrj.embedded.JettyConfig;
 import org.apache.solr.client.solrj.embedded.JettySolrRunner;
 import org.apache.solr.client.solrj.impl.CloudSolrClient;
-import org.apache.solr.client.solrj.impl.HttpClientUtil;
-import org.apache.solr.client.solrj.impl.Krb5HttpClientConfigurer;
 import org.apache.solr.client.solrj.request.CollectionAdminRequest;
 import org.apache.solr.client.solrj.response.QueryResponse;
 import org.apache.solr.common.SolrInputDocument;
@@ -54,6 +49,9 @@ import org.junit.Test;
 import org.junit.rules.RuleChain;
 import org.junit.rules.TestRule;
 
+import com.carrotsearch.randomizedtesting.annotations.ThreadLeakFilters;
+import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule;
+
 /**
  * Test 5 nodes Solr cluster with Kerberos plugin enabled.
  * This test is Ignored right now as Mini KDC has a known bug that
@@ -82,6 +80,7 @@ public class TestSolrCloudWithKerberosAlt extends LuceneTestCase {
   private MiniKdc kdc;
 
   private Locale savedLocale; // in case locale is broken and we need to fill in a working locale
+  
   @Rule
   public TestRule solrTestRules = RuleChain
       .outerRule(new SystemPropertiesRestoreRule());
@@ -101,7 +100,6 @@ public class TestSolrCloudWithKerberosAlt extends LuceneTestCase {
     savedLocale = KerberosTestUtil.overrideLocaleIfNotSpportedByMiniKdc();
     super.setUp();
     setupMiniKdc();
-    HttpClientUtil.setConfigurer(new Krb5HttpClientConfigurer());
   }
 
   private void setupMiniKdc() throws Exception {
@@ -157,7 +155,6 @@ public class TestSolrCloudWithKerberosAlt extends LuceneTestCase {
   }
 
   protected void testCollectionCreateSearchDelete() throws Exception {
-    HttpClientUtil.setConfigurer(new Krb5HttpClientConfigurer());
     String collectionName = "testkerberoscollection";
 
     MiniSolrCloudCluster miniCluster

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/test/org/apache/solr/cloud/TestTolerantUpdateProcessorCloud.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/TestTolerantUpdateProcessorCloud.java b/solr/core/src/test/org/apache/solr/cloud/TestTolerantUpdateProcessorCloud.java
index 054c074..929d736 100644
--- a/solr/core/src/test/org/apache/solr/cloud/TestTolerantUpdateProcessorCloud.java
+++ b/solr/core/src/test/org/apache/solr/cloud/TestTolerantUpdateProcessorCloud.java
@@ -17,6 +17,7 @@
 package org.apache.solr.cloud;
 
 import java.io.File;
+import java.io.IOException;
 import java.lang.invoke.MethodHandles;
 import java.net.URL;
 import java.util.ArrayList;
@@ -49,7 +50,6 @@ 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.SimpleOrderedMap;
-import org.apache.solr.util.RevertDefaultThreadHandlerRule;
 
 import org.junit.AfterClass;
 import org.junit.Before;
@@ -204,6 +204,21 @@ public class TestTolerantUpdateProcessorCloud extends SolrCloudTestCase {
     }
   }
   
+  @AfterClass
+  public static void afterClass() throws IOException {
+   close(S_ONE_LEADER_CLIENT);
+   close(S_TWO_LEADER_CLIENT);
+   close(S_ONE_NON_LEADER_CLIENT);
+   close(S_TWO_NON_LEADER_CLIENT);
+   close(NO_COLLECTION_CLIENT);
+  }
+  
+  private static void close(SolrClient client) throws IOException {
+    if (client != null) {
+      client.close();
+    }
+  }
+  
   @Before
   private void clearCollection() throws Exception {
     assertEquals(0, CLOUD_CLIENT.deleteByQuery("*:*").getStatus());

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/test/org/apache/solr/cloud/TestTolerantUpdateProcessorRandomCloud.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/TestTolerantUpdateProcessorRandomCloud.java b/solr/core/src/test/org/apache/solr/cloud/TestTolerantUpdateProcessorRandomCloud.java
index b3f0423..a722ad2 100644
--- a/solr/core/src/test/org/apache/solr/cloud/TestTolerantUpdateProcessorRandomCloud.java
+++ b/solr/core/src/test/org/apache/solr/cloud/TestTolerantUpdateProcessorRandomCloud.java
@@ -16,59 +16,43 @@
  */
 package org.apache.solr.cloud;
 
+import static org.apache.solr.cloud.TestTolerantUpdateProcessorCloud.addErr;
+import static org.apache.solr.cloud.TestTolerantUpdateProcessorCloud.assertUpdateTolerantErrors;
+import static org.apache.solr.cloud.TestTolerantUpdateProcessorCloud.delIErr;
+import static org.apache.solr.cloud.TestTolerantUpdateProcessorCloud.delQErr;
+import static org.apache.solr.cloud.TestTolerantUpdateProcessorCloud.f;
+import static org.apache.solr.cloud.TestTolerantUpdateProcessorCloud.update;
+import static org.apache.solr.common.params.CursorMarkParams.CURSOR_MARK_PARAM;
+import static org.apache.solr.common.params.CursorMarkParams.CURSOR_MARK_START;
+
 import java.io.File;
+import java.io.IOException;
 import java.lang.invoke.MethodHandles;
 import java.net.URL;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.BitSet;
 import java.util.HashMap;
-import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Random;
-import java.util.Set;
 
 import org.apache.lucene.util.TestUtil;
-import org.apache.solr.cloud.SolrCloudTestCase;
-import static org.apache.solr.cloud.TestTolerantUpdateProcessorCloud.assertUpdateTolerantErrors;
-import static org.apache.solr.cloud.TestTolerantUpdateProcessorCloud.addErr;
-import static org.apache.solr.cloud.TestTolerantUpdateProcessorCloud.delIErr;
-import static org.apache.solr.cloud.TestTolerantUpdateProcessorCloud.delQErr;
-import static org.apache.solr.cloud.TestTolerantUpdateProcessorCloud.f;
-import static org.apache.solr.cloud.TestTolerantUpdateProcessorCloud.update;
-import static org.apache.solr.cloud.TestTolerantUpdateProcessorCloud.ExpectedErr;
 import org.apache.solr.client.solrj.SolrClient;
 import org.apache.solr.client.solrj.embedded.JettySolrRunner;
-import org.apache.solr.client.solrj.impl.HttpSolrClient;
 import org.apache.solr.client.solrj.impl.CloudSolrClient;
+import org.apache.solr.client.solrj.impl.HttpSolrClient;
 import org.apache.solr.client.solrj.request.UpdateRequest;
 import org.apache.solr.client.solrj.response.QueryResponse;
 import org.apache.solr.client.solrj.response.UpdateResponse;
-import static org.apache.solr.common.params.CursorMarkParams.CURSOR_MARK_PARAM;
-import static org.apache.solr.common.params.CursorMarkParams.CURSOR_MARK_NEXT;
-import static org.apache.solr.common.params.CursorMarkParams.CURSOR_MARK_START;
+import org.apache.solr.cloud.TestTolerantUpdateProcessorCloud.ExpectedErr;
 import org.apache.solr.common.SolrDocument;
-import org.apache.solr.common.SolrDocumentList;
 import org.apache.solr.common.SolrInputDocument;
 import org.apache.solr.common.SolrInputField;
-import org.apache.solr.common.SolrException;
-import org.apache.solr.common.ToleratedUpdateError;
-import org.apache.solr.common.ToleratedUpdateError.CmdType;
-import org.apache.solr.common.cloud.ClusterState;
-import org.apache.solr.common.cloud.Replica;
-import org.apache.solr.common.cloud.Slice;
 import org.apache.solr.common.cloud.ZkStateReader;
-import org.apache.solr.common.params.ModifiableSolrParams;
 import org.apache.solr.common.params.SolrParams;
-import org.apache.solr.common.util.NamedList;
-import org.apache.solr.common.util.SimpleOrderedMap;
-import org.apache.solr.util.RevertDefaultThreadHandlerRule;
-
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
-
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -92,7 +76,7 @@ public class TestTolerantUpdateProcessorRandomCloud extends SolrCloudTestCase {
   /** A basic client for operations at the cloud level, default collection will be set */
   private static CloudSolrClient CLOUD_CLIENT;
   /** one HttpSolrClient for each server */
-  private static List<SolrClient> NODE_CLIENTS;
+  private static List<HttpSolrClient> NODE_CLIENTS;
 
   @BeforeClass
   private static void createMiniSolrCloudCluster() throws Exception {
@@ -123,7 +107,12 @@ public class TestTolerantUpdateProcessorRandomCloud extends SolrCloudTestCase {
     CLOUD_CLIENT = cluster.getSolrClient();
     CLOUD_CLIENT.setDefaultCollection(COLLECTION_NAME);
 
-    NODE_CLIENTS = new ArrayList<SolrClient>(numServers);
+    if (NODE_CLIENTS != null) {
+      for (HttpSolrClient client : NODE_CLIENTS) {
+        client.close();
+      }
+    }
+    NODE_CLIENTS = new ArrayList<HttpSolrClient>(numServers);
     
     for (JettySolrRunner jetty : cluster.getJettySolrRunners()) {
       URL jettyURL = jetty.getBaseUrl();
@@ -142,6 +131,15 @@ public class TestTolerantUpdateProcessorRandomCloud extends SolrCloudTestCase {
     assertEquals("index should be empty", 0L, countDocs(CLOUD_CLIENT));
   }
   
+  @AfterClass
+  public static void afterClass() throws IOException {
+    if (NODE_CLIENTS != null) {
+      for (HttpSolrClient client : NODE_CLIENTS) {
+        client.close();
+      }
+    }
+  }
+  
   public void testRandomUpdates() throws Exception {
     final int maxDocId = atLeast(10000);
     final BitSet expectedDocIds = new BitSet(maxDocId+1);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/test/org/apache/solr/cloud/ZkControllerTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/ZkControllerTest.java b/solr/core/src/test/org/apache/solr/cloud/ZkControllerTest.java
index 7b293ca..9123697 100644
--- a/solr/core/src/test/org/apache/solr/cloud/ZkControllerTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/ZkControllerTest.java
@@ -326,7 +326,7 @@ public class ZkControllerTest extends SolrTestCaseJ4 {
   }
 
   private static class MockCoreContainer extends CoreContainer {
-
+    UpdateShardHandler updateShardHandler = new UpdateShardHandler(UpdateShardHandlerConfig.DEFAULT);
     public MockCoreContainer() {
       super((Object)null);
       this.shardHandlerFactory = new HttpShardHandlerFactory();
@@ -338,7 +338,12 @@ public class ZkControllerTest extends SolrTestCaseJ4 {
     
     @Override
     public UpdateShardHandler getUpdateShardHandler() {
-      return new UpdateShardHandler(UpdateShardHandlerConfig.DEFAULT);
+      return updateShardHandler;
+    }
+    
+    @Override
+    public void shutdown() {
+      updateShardHandler.close();
     }
 
   }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/test/org/apache/solr/cloud/overseer/ZkStateReaderTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/overseer/ZkStateReaderTest.java b/solr/core/src/test/org/apache/solr/cloud/overseer/ZkStateReaderTest.java
index 10cc46c..3c45e23 100644
--- a/solr/core/src/test/org/apache/solr/cloud/overseer/ZkStateReaderTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/overseer/ZkStateReaderTest.java
@@ -32,7 +32,6 @@ import org.apache.solr.common.cloud.Slice;
 import org.apache.solr.common.cloud.SolrZkClient;
 import org.apache.solr.common.cloud.ZkStateReader;
 import org.apache.solr.common.util.Utils;
-import org.apache.zookeeper.KeeperException;
 
 public class ZkStateReaderTest extends SolrTestCaseJ4 {
 
@@ -96,7 +95,7 @@ public class ZkStateReaderTest extends SolrTestCaseJ4 {
         if (explicitRefresh) {
           reader.forceUpdateCollection("c1");
         } else {
-          for (int i = 0; i < 100; ++i) {
+          for (int i = 0; i < 500; ++i) {
             if (reader.getClusterState().hasCollection("c1")) {
               break;
             }
@@ -124,7 +123,7 @@ public class ZkStateReaderTest extends SolrTestCaseJ4 {
         if (explicitRefresh) {
           reader.forceUpdateCollection("c1");
         } else {
-          for (int i = 0; i < 100; ++i) {
+          for (int i = 0; i < 500; ++i) {
             if (reader.getClusterState().getCollection("c1").getStateFormat() == 2) {
               break;
             }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/test/org/apache/solr/core/OpenCloseCoreStressTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/core/OpenCloseCoreStressTest.java b/solr/core/src/test/org/apache/solr/core/OpenCloseCoreStressTest.java
index 7875b7c..71f3ee9 100644
--- a/solr/core/src/test/org/apache/solr/core/OpenCloseCoreStressTest.java
+++ b/solr/core/src/test/org/apache/solr/core/OpenCloseCoreStressTest.java
@@ -149,14 +149,12 @@ public class OpenCloseCoreStressTest extends SolrTestCaseJ4 {
 
     for (int idx = 0; idx < indexingThreads; ++idx) {
       HttpSolrClient client = new HttpSolrClient(url);
-      client.setDefaultMaxConnectionsPerHost(25);
       client.setConnectionTimeout(30000);
       client.setSoTimeout(60000);
       indexingClients.add(client);
     }
     for (int idx = 0; idx < queryThreads; ++idx) {
       HttpSolrClient client = new HttpSolrClient(url);
-      client.setDefaultMaxConnectionsPerHost(25);
       client.setConnectionTimeout(30000);
       client.setSoTimeout(30000);
       queryingClients.add(client);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/test/org/apache/solr/core/TestCoreContainer.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/core/TestCoreContainer.java b/solr/core/src/test/org/apache/solr/core/TestCoreContainer.java
index 44f9e5c..d23b8b1 100644
--- a/solr/core/src/test/org/apache/solr/core/TestCoreContainer.java
+++ b/solr/core/src/test/org/apache/solr/core/TestCoreContainer.java
@@ -336,7 +336,6 @@ public class TestCoreContainer extends SolrTestCaseJ4 {
 
     CoreContainer cc = init(CUSTOM_HANDLERS_SOLR_XML);
     try {
-      cc.load();
       assertThat(cc.getCollectionsHandler(), is(instanceOf(CustomCollectionsHandler.class)));
       assertThat(cc.getInfoHandler(), is(instanceOf(CustomInfoHandler.class)));
       assertThat(cc.getMultiCoreHandler(), is(instanceOf(CustomCoreAdminHandler.class)));

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/test/org/apache/solr/handler/TestReplicationHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/handler/TestReplicationHandler.java b/solr/core/src/test/org/apache/solr/handler/TestReplicationHandler.java
index eab3e87..8ea8d1b 100644
--- a/solr/core/src/test/org/apache/solr/handler/TestReplicationHandler.java
+++ b/solr/core/src/test/org/apache/solr/handler/TestReplicationHandler.java
@@ -159,8 +159,6 @@ public class TestReplicationHandler extends SolrTestCaseJ4 {
       HttpSolrClient client = new HttpSolrClient(buildUrl(port) + "/" + DEFAULT_TEST_CORENAME);
       client.setConnectionTimeout(15000);
       client.setSoTimeout(60000);
-      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/handler/TestReplicationHandlerBackup.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/handler/TestReplicationHandlerBackup.java b/solr/core/src/test/org/apache/solr/handler/TestReplicationHandlerBackup.java
index 29c0dd7..fe1a4ea 100644
--- a/solr/core/src/test/org/apache/solr/handler/TestReplicationHandlerBackup.java
+++ b/solr/core/src/test/org/apache/solr/handler/TestReplicationHandlerBackup.java
@@ -82,8 +82,6 @@ public class TestReplicationHandlerBackup extends SolrJettyTestBase {
       HttpSolrClient client = new HttpSolrClient(buildUrl(port, context) + "/" + DEFAULT_TEST_CORENAME);
       client.setConnectionTimeout(15000);
       client.setSoTimeout(60000);
-      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/handler/TestRestoreCore.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/handler/TestRestoreCore.java b/solr/core/src/test/org/apache/solr/handler/TestRestoreCore.java
index 1218783..0a80764 100644
--- a/solr/core/src/test/org/apache/solr/handler/TestRestoreCore.java
+++ b/solr/core/src/test/org/apache/solr/handler/TestRestoreCore.java
@@ -75,8 +75,6 @@ public class TestRestoreCore extends SolrJettyTestBase {
       HttpSolrClient client = new HttpSolrClient(buildUrl(port, context) + "/" + DEFAULT_TEST_CORENAME);
       client.setConnectionTimeout(15000);
       client.setSoTimeout(60000);
-      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/handler/component/DistributedQueryElevationComponentTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/handler/component/DistributedQueryElevationComponentTest.java b/solr/core/src/test/org/apache/solr/handler/component/DistributedQueryElevationComponentTest.java
index 0c18b25..91f39dc 100644
--- a/solr/core/src/test/org/apache/solr/handler/component/DistributedQueryElevationComponentTest.java
+++ b/solr/core/src/test/org/apache/solr/handler/component/DistributedQueryElevationComponentTest.java
@@ -116,6 +116,7 @@ public class DistributedQueryElevationComponentTest extends BaseDistributedSearc
         .setSort("id", SolrQuery.ORDER.desc);
     setDistributedParams(solrQuery);
     response = client.query(solrQuery);
+    client.close();
 
     assertTrue(response.getResults().getNumFound() > 0);
     document = response.getResults().get(0);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/test/org/apache/solr/search/AnalyticsMergeStrategyTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/search/AnalyticsMergeStrategyTest.java b/solr/core/src/test/org/apache/solr/search/AnalyticsMergeStrategyTest.java
index ed33182..160d2f7 100644
--- a/solr/core/src/test/org/apache/solr/search/AnalyticsMergeStrategyTest.java
+++ b/solr/core/src/test/org/apache/solr/search/AnalyticsMergeStrategyTest.java
@@ -19,6 +19,7 @@ package org.apache.solr.search;
 import org.apache.lucene.util.Constants;
 import org.apache.solr.BaseDistributedSearchTestCase;
 import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.SolrTestCaseJ4.SuppressObjectReleaseTracker;
 import org.apache.solr.client.solrj.response.QueryResponse;
 import org.apache.solr.common.params.ModifiableSolrParams;
 import org.apache.solr.common.util.NamedList;
@@ -32,6 +33,7 @@ import org.junit.Test;
  */
 
 @SolrTestCaseJ4.SuppressSSL(bugUrl="https://issues.apache.org/jira/browse/SOLR-8433")
+@SuppressObjectReleaseTracker(bugUrl="https://issues.apache.org/jira/browse/SOLR-8899")
 public class AnalyticsMergeStrategyTest extends BaseDistributedSearchTestCase {
 
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/test/org/apache/solr/search/stats/TestDistribIDF.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/search/stats/TestDistribIDF.java b/solr/core/src/test/org/apache/solr/search/stats/TestDistribIDF.java
index 9bb4d21..877742b 100644
--- a/solr/core/src/test/org/apache/solr/search/stats/TestDistribIDF.java
+++ b/solr/core/src/test/org/apache/solr/search/stats/TestDistribIDF.java
@@ -117,27 +117,30 @@ public class TestDistribIDF extends SolrTestCaseJ4 {
 
     //Test against all nodes
     for (JettySolrRunner jettySolrRunner : solrCluster.getJettySolrRunners()) {
-      SolrClient solrClient = new HttpSolrClient(jettySolrRunner.getBaseUrl().toString());
-      SolrClient solrClient_local = new HttpSolrClient(jettySolrRunner.getBaseUrl().toString());
+      try (SolrClient solrClient = new HttpSolrClient(jettySolrRunner.getBaseUrl().toString())) {
+        try (SolrClient solrClient_local = new HttpSolrClient(jettySolrRunner.getBaseUrl().toString())) {
 
-      SolrQuery query = new SolrQuery("cat:football");
-      query.setFields("*,score");
-      QueryResponse queryResponse = solrClient.query("onecollection", query);
-      assertEquals(2, queryResponse.getResults().getNumFound());
-      float score1 = (float) queryResponse.getResults().get(0).get("score");
-      float score2 = (float) queryResponse.getResults().get(1).get("score");
-      assertEquals("Doc1 score=" + score1 + " Doc2 score=" + score2, 0, Float.compare(score1, score2));
+          SolrQuery query = new SolrQuery("cat:football");
+          query.setFields("*,score");
+          QueryResponse queryResponse = solrClient.query("onecollection", query);
+          assertEquals(2, queryResponse.getResults().getNumFound());
+          float score1 = (float) queryResponse.getResults().get(0).get("score");
+          float score2 = (float) queryResponse.getResults().get(1).get("score");
+          assertEquals("Doc1 score=" + score1 + " Doc2 score=" + score2, 0, Float.compare(score1, score2));
 
-      query = new SolrQuery("cat:football");
-      query.setShowDebugInfo(true);
-      query.setFields("*,score");
-      queryResponse = solrClient_local.query("onecollection_local", query);
-      assertEquals(2, queryResponse.getResults().getNumFound());
-      assertEquals(2, queryResponse.getResults().get(0).get("id"));
-      assertEquals(1, queryResponse.getResults().get(1).get("id"));
-      float score1_local = (float) queryResponse.getResults().get(0).get("score");
-      float score2_local = (float) queryResponse.getResults().get(1).get("score");
-      assertEquals("Doc1 score=" + score1_local + " Doc2 score=" + score2_local, 1, Float.compare(score1_local, score2_local));
+          query = new SolrQuery("cat:football");
+          query.setShowDebugInfo(true);
+          query.setFields("*,score");
+          queryResponse = solrClient_local.query("onecollection_local", query);
+          assertEquals(2, queryResponse.getResults().getNumFound());
+          assertEquals(2, queryResponse.getResults().get(0).get("id"));
+          assertEquals(1, queryResponse.getResults().get(1).get("id"));
+          float score1_local = (float) queryResponse.getResults().get(0).get("score");
+          float score2_local = (float) queryResponse.getResults().get(1).get("score");
+          assertEquals("Doc1 score=" + score1_local + " Doc2 score=" + score2_local, 1,
+              Float.compare(score1_local, score2_local));
+        }
+      }
     }
   }
 
@@ -161,28 +164,33 @@ public class TestDistribIDF extends SolrTestCaseJ4 {
 
     //Test against all nodes
     for (JettySolrRunner jettySolrRunner : solrCluster.getJettySolrRunners()) {
-      SolrClient solrClient = new HttpSolrClient(jettySolrRunner.getBaseUrl().toString());
-      SolrClient solrClient_local = new HttpSolrClient(jettySolrRunner.getBaseUrl().toString());
 
-      SolrQuery query = new SolrQuery("cat:football");
-      query.setFields("*,score").add("collection", "collection1,collection2");
-      QueryResponse queryResponse = solrClient.query("collection1", query);
-      assertEquals(2, queryResponse.getResults().getNumFound());
-      float score1 = (float) queryResponse.getResults().get(0).get("score");
-      float score2 = (float) queryResponse.getResults().get(1).get("score");
-      assertEquals("Doc1 score=" + score1 + " Doc2 score=" + score2, 0, Float.compare(score1, score2));
+      try (SolrClient solrClient = new HttpSolrClient(jettySolrRunner.getBaseUrl().toString())) {
 
+        try (SolrClient solrClient_local = new HttpSolrClient(jettySolrRunner.getBaseUrl().toString())) {
+          SolrQuery query = new SolrQuery("cat:football");
+          query.setFields("*,score").add("collection", "collection1,collection2");
+          QueryResponse queryResponse = solrClient.query("collection1", query);
+          assertEquals(2, queryResponse.getResults().getNumFound());
+          float score1 = (float) queryResponse.getResults().get(0).get("score");
+          float score2 = (float) queryResponse.getResults().get(1).get("score");
+          assertEquals("Doc1 score=" + score1 + " Doc2 score=" + score2, 0, Float.compare(score1, score2));
 
-      query = new SolrQuery("cat:football");
-      query.setFields("*,score").add("collection", "collection1_local,collection2_local");
-      queryResponse = solrClient_local.query("collection1_local", query);
-      assertEquals(2, queryResponse.getResults().getNumFound());
-      assertEquals(2, queryResponse.getResults().get(0).get("id"));
-      assertEquals(1, queryResponse.getResults().get(1).get("id"));
-      float score1_local = (float) queryResponse.getResults().get(0).get("score");
-      float score2_local = (float) queryResponse.getResults().get(1).get("score");
-      assertEquals("Doc1 score=" + score1_local + " Doc2 score=" + score2_local, 1, Float.compare(score1_local, score2_local));
+          query = new SolrQuery("cat:football");
+          query.setFields("*,score").add("collection", "collection1_local,collection2_local");
+          queryResponse = solrClient_local.query("collection1_local", query);
+          assertEquals(2, queryResponse.getResults().getNumFound());
+          assertEquals(2, queryResponse.getResults().get(0).get("id"));
+          assertEquals(1, queryResponse.getResults().get(1).get("id"));
+          float score1_local = (float) queryResponse.getResults().get(0).get("score");
+          float score2_local = (float) queryResponse.getResults().get(1).get("score");
+          assertEquals("Doc1 score=" + score1_local + " Doc2 score=" + score2_local, 1,
+              Float.compare(score1_local, score2_local));
+        }
+
+      }
     }
+    
   }
 
   private void createCollection(String name, String config) throws Exception {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/test/org/apache/solr/security/BasicAuthIntegrationTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/security/BasicAuthIntegrationTest.java b/solr/core/src/test/org/apache/solr/security/BasicAuthIntegrationTest.java
index 96a8c14..9361615 100644
--- a/solr/core/src/test/org/apache/solr/security/BasicAuthIntegrationTest.java
+++ b/solr/core/src/test/org/apache/solr/security/BasicAuthIntegrationTest.java
@@ -36,6 +36,7 @@ import org.apache.http.util.EntityUtils;
 import org.apache.solr.client.solrj.SolrRequest;
 import org.apache.solr.client.solrj.embedded.JettySolrRunner;
 import org.apache.solr.client.solrj.impl.CloudSolrClient;
+import org.apache.solr.client.solrj.impl.HttpClientUtil;
 import org.apache.solr.client.solrj.impl.HttpSolrClient;
 import org.apache.solr.client.solrj.request.CollectionAdminRequest;
 import org.apache.solr.client.solrj.request.GenericSolrRequest;
@@ -61,7 +62,6 @@ import static java.nio.charset.StandardCharsets.UTF_8;
 import static java.util.Collections.singletonMap;
 import static org.apache.solr.common.cloud.ZkStateReader.BASE_URL_PROP;
 
-
 public class BasicAuthIntegrationTest extends TestMiniSolrCloudClusterBase {
 
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@@ -78,7 +78,7 @@ public class BasicAuthIntegrationTest extends TestMiniSolrCloudClusterBase {
     cloudSolrClient.setDefaultCollection(null);
 
     NamedList<Object> rsp;
-    HttpClient cl = cloudSolrClient.getLbClient().getHttpClient();
+    HttpClient cl = HttpClientUtil.createClient(null);
     String baseUrl = getRandomReplica(zkStateReader.getClusterState().getCollection(defaultCollName), random()).getStr(BASE_URL_PROP);
     verifySecurityStatus(cl, baseUrl + authcPrefix, "/errorMessages", null, 20);
     zkClient.setData("/security.json", STD_CONF.replaceAll("'", "\"").getBytes(UTF_8), true);
@@ -94,6 +94,7 @@ public class BasicAuthIntegrationTest extends TestMiniSolrCloudClusterBase {
         break;
       }
     }
+
     assertTrue("No server found to restart , looking for : "+baseUrl , found);
 
     String command = "{\n" +
@@ -118,6 +119,7 @@ public class BasicAuthIntegrationTest extends TestMiniSolrCloudClusterBase {
     verifySecurityStatus(cl, baseUrl + authcPrefix, "authentication.enabled", "true", 20);
     HttpResponse r = cl.execute(httpPost);
     int statusCode = r.getStatusLine().getStatusCode();
+    Utils.consumeFully(r.getEntity());
     assertEquals("proper_cred sent, but access denied", 200, statusCode);
     baseUrl = getRandomReplica(zkStateReader.getClusterState().getCollection(defaultCollName), random()).getStr(BASE_URL_PROP);
 
@@ -132,6 +134,7 @@ public class BasicAuthIntegrationTest extends TestMiniSolrCloudClusterBase {
     httpPost.addHeader("Content-Type", "application/json; charset=UTF-8");
     r = cl.execute(httpPost);
     assertEquals(200, r.getStatusLine().getStatusCode());
+    Utils.consumeFully(r.getEntity());
 
     baseUrl = getRandomReplica(zkStateReader.getClusterState().getCollection(defaultCollName), random()).getStr(BASE_URL_PROP);
     verifySecurityStatus(cl, baseUrl + authzPrefix, "authorization/user-role/harry", NOT_NULL_PREDICATE, 20);
@@ -148,6 +151,7 @@ public class BasicAuthIntegrationTest extends TestMiniSolrCloudClusterBase {
     verifySecurityStatus(cl, baseUrl + authzPrefix, "authorization/user-role/harry", NOT_NULL_PREDICATE, 20);
     r = cl.execute(httpPost);
     assertEquals(200, r.getStatusLine().getStatusCode());
+    Utils.consumeFully(r.getEntity());
 
     verifySecurityStatus(cl, baseUrl + authzPrefix, "authorization/permissions[1]/collection", "x", 20);
 
@@ -156,25 +160,26 @@ public class BasicAuthIntegrationTest extends TestMiniSolrCloudClusterBase {
     httpPost.setEntity(new ByteArrayEntity(Utils.toJSON(singletonMap("set-permission", Utils.makeMap
         ("name","collection-admin-edit", "role", "admin" )))));
     r = cl.execute(httpPost);
-
+    Utils.consumeFully(r.getEntity());
     verifySecurityStatus(cl, baseUrl + authzPrefix, "authorization/permissions[2]/name", "collection-admin-edit", 20);
 
     CollectionAdminRequest.Reload reload = new CollectionAdminRequest.Reload();
     reload.setCollectionName(defaultCollName);
 
-    HttpSolrClient solrClient = new HttpSolrClient(baseUrl);
-    try {
-      rsp = solrClient.request(reload);
-      fail("must have failed");
-    } catch (HttpSolrClient.RemoteSolrException e) {
+    try (HttpSolrClient solrClient = new HttpSolrClient(baseUrl)) {
+      try {
+        rsp = solrClient.request(reload);
+        fail("must have failed");
+      } catch (HttpSolrClient.RemoteSolrException e) {
 
-    }
-    reload.setMethod(SolrRequest.METHOD.POST);
-    try {
-      rsp = solrClient.request(reload);
-      fail("must have failed");
-    } catch (HttpSolrClient.RemoteSolrException e) {
+      }
+      reload.setMethod(SolrRequest.METHOD.POST);
+      try {
+        rsp = solrClient.request(reload);
+        fail("must have failed");
+      } catch (HttpSolrClient.RemoteSolrException e) {
 
+      }
     }
     cloudSolrClient.request(new CollectionAdminRequest.Reload()
         .setCollectionName(defaultCollName)
@@ -197,6 +202,7 @@ public class BasicAuthIntegrationTest extends TestMiniSolrCloudClusterBase {
     httpPost.addHeader("Content-Type", "application/json; charset=UTF-8");
     r = cl.execute(httpPost);
     assertEquals(200,r.getStatusLine().getStatusCode());
+    Utils.consumeFully(r.getEntity());
 
     SolrInputDocument doc = new SolrInputDocument();
     doc.setField("id","4");
@@ -205,6 +211,8 @@ public class BasicAuthIntegrationTest extends TestMiniSolrCloudClusterBase {
     update.add(doc);
     update.setCommitWithin(100);
     cloudSolrClient.request(update);
+    
+    HttpClientUtil.close(cl);
   }
 
   public static void verifySecurityStatus(HttpClient cl, String url, String objPath, Object expected, int count) throws Exception {
@@ -213,9 +221,10 @@ public class BasicAuthIntegrationTest extends TestMiniSolrCloudClusterBase {
     List<String> hierarchy = StrUtils.splitSmart(objPath, '/');
     for (int i = 0; i < count; i++) {
       HttpGet get = new HttpGet(url);
-      s = EntityUtils.toString(cl.execute(get).getEntity());
+      HttpResponse rsp = cl.execute(get);
+      s = EntityUtils.toString(rsp.getEntity());
       Map m = (Map) Utils.fromJSONString(s);
-
+      Utils.consumeFully(rsp.getEntity());
       Object actual = Utils.getObjectByPath(m, true, hierarchy);
       if (expected instanceof Predicate) {
         Predicate predicate = (Predicate) expected;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/test/org/apache/solr/security/PKIAuthenticationIntegrationTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/security/PKIAuthenticationIntegrationTest.java b/solr/core/src/test/org/apache/solr/security/PKIAuthenticationIntegrationTest.java
index 26aee07..30fe933 100644
--- a/solr/core/src/test/org/apache/solr/security/PKIAuthenticationIntegrationTest.java
+++ b/solr/core/src/test/org/apache/solr/security/PKIAuthenticationIntegrationTest.java
@@ -31,8 +31,6 @@ import org.apache.solr.cloud.AbstractFullDistribZkTestBase;
 import org.apache.solr.common.cloud.ZkStateReader;
 import org.apache.solr.common.params.ModifiableSolrParams;
 import org.apache.solr.common.util.Utils;
-import org.apache.solr.request.LocalSolrQueryRequest;
-import org.apache.zookeeper.CreateMode;
 import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/test/org/apache/solr/security/TestAuthorizationFramework.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/security/TestAuthorizationFramework.java b/solr/core/src/test/org/apache/solr/security/TestAuthorizationFramework.java
index 3f57376..4c4b52e 100644
--- a/solr/core/src/test/org/apache/solr/security/TestAuthorizationFramework.java
+++ b/solr/core/src/test/org/apache/solr/security/TestAuthorizationFramework.java
@@ -28,6 +28,7 @@ import org.apache.http.client.HttpClient;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.util.EntityUtils;
 import org.apache.lucene.util.LuceneTestCase;
+import org.apache.solr.client.solrj.impl.HttpClientUtil;
 import org.apache.solr.cloud.AbstractFullDistribZkTestBase;
 import org.apache.solr.common.cloud.ZkStateReader;
 import org.apache.solr.common.params.ModifiableSolrParams;
@@ -89,7 +90,7 @@ public class TestAuthorizationFramework extends AbstractFullDistribZkTestBase {
     List<String> hierarchy = StrUtils.splitSmart(objPath, '/');
     for (int i = 0; i < count; i++) {
       HttpGet get = new HttpGet(url);
-      s = EntityUtils.toString(cl.execute(get).getEntity());
+      s = EntityUtils.toString(cl.execute(get, HttpClientUtil.createNewHttpClientRequestContext()).getEntity());
       Map m = (Map) Utils.fromJSONString(s);
 
       Object actual = Utils.getObjectByPath(m, true, hierarchy);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/core/src/test/org/apache/solr/update/AutoCommitTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/update/AutoCommitTest.java b/solr/core/src/test/org/apache/solr/update/AutoCommitTest.java
index 080a02f..3221693 100644
--- a/solr/core/src/test/org/apache/solr/update/AutoCommitTest.java
+++ b/solr/core/src/test/org/apache/solr/update/AutoCommitTest.java
@@ -317,7 +317,7 @@ public class AutoCommitTest extends AbstractSolrTestCase {
     
     // Delete one document with commitWithin
     req.setContentStreams( toContentStreams(
-      delI("529", "commitWithin", "1000"), null ) );
+      delI("529", "commitWithin", "2000"), null ) );
     trigger.reset();
     handler.handleRequest( req, rsp );
       

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/server/etc/jetty-http.xml
----------------------------------------------------------------------
diff --git a/solr/server/etc/jetty-http.xml b/solr/server/etc/jetty-http.xml
index 90e523a..6d92830 100644
--- a/solr/server/etc/jetty-http.xml
+++ b/solr/server/etc/jetty-http.xml
@@ -35,7 +35,7 @@
         </Arg>
         <Set name="host"><Property name="jetty.host" /></Set>
         <Set name="port"><Property name="jetty.port" default="8983" /></Set>
-        <Set name="idleTimeout"><Property name="solr.jetty.http.idleTimeout" default="50000"/></Set>
+        <Set name="idleTimeout"><Property name="solr.jetty.http.idleTimeout" default="120000"/></Set>
         <Set name="soLingerTime"><Property name="solr.jetty.http.soLingerTime" default="-1"/></Set>
         <Set name="acceptorPriorityDelta"><Property name="solr.jetty.http.acceptorPriorityDelta" default="0"/></Set>
         <Set name="selectorPriorityDelta"><Property name="solr.jetty.http.selectorPriorityDelta" default="0"/></Set>

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/server/etc/jetty-https.xml
----------------------------------------------------------------------
diff --git a/solr/server/etc/jetty-https.xml b/solr/server/etc/jetty-https.xml
index e2770b1..d34d4bd 100644
--- a/solr/server/etc/jetty-https.xml
+++ b/solr/server/etc/jetty-https.xml
@@ -42,7 +42,7 @@
         </Arg>
         <Set name="host"><Property name="solr.jetty.host" /></Set>
         <Set name="port"><Property name="solr.jetty.https.port" default="8983" /></Set>
-        <Set name="idleTimeout"><Property name="solr.jetty.https.timeout" default="50000"/></Set>
+        <Set name="idleTimeout"><Property name="solr.jetty.https.timeout" default="120000"/></Set>
         <Set name="soLingerTime"><Property name="solr.jetty.https.soLingerTime" default="-1"/></Set>
         <Set name="acceptorPriorityDelta"><Property name="solr.jetty.ssl.acceptorPriorityDelta" default="0"/></Set>
         <Set name="selectorPriorityDelta"><Property name="solr.jetty.ssl.selectorPriorityDelta" default="0"/></Set>

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/server/etc/jetty.xml
----------------------------------------------------------------------
diff --git a/solr/server/etc/jetty.xml b/solr/server/etc/jetty.xml
index c819f04..f1b94c8 100644
--- a/solr/server/etc/jetty.xml
+++ b/solr/server/etc/jetty.xml
@@ -35,7 +35,7 @@
   <Get name="ThreadPool">
     <Set name="minThreads" type="int"><Property name="solr.jetty.threads.min" default="10"/></Set>
     <Set name="maxThreads" type="int"><Property name="solr.jetty.threads.max" default="10000"/></Set>
-    <Set name="idleTimeout" type="int"><Property name="solr.jetty.threads.idle.timeout" default="5000"/></Set>
+    <Set name="idleTimeout" type="int"><Property name="solr.jetty.threads.idle.timeout" default="120000"/></Set>
     <Set name="stopTimeout" type="int"><Property name="solr.jetty.threads.stop.timeout" default="60000"/></Set>
     <Set name="detailedDump">false</Set>
   </Get>

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java
index edfe1c3..43a4c18 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java
@@ -1345,4 +1345,12 @@ public class CloudSolrClient extends SolrClient {
     }    
     return results;
   }
+  
+  public void setConnectionTimeout(int timeout) {
+    this.lbClient.setConnectionTimeout(timeout); 
+  }
+
+  public void setSoTimeout(int timeout) {
+    this.lbClient.setSoTimeout(timeout);
+  }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ConcurrentUpdateSolrClient.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ConcurrentUpdateSolrClient.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ConcurrentUpdateSolrClient.java
index 5bec96a..d197e4b 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ConcurrentUpdateSolrClient.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ConcurrentUpdateSolrClient.java
@@ -20,6 +20,7 @@ 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.methods.HttpPost;
 import org.apache.http.entity.ContentProducer;
 import org.apache.http.entity.EntityTemplate;
@@ -86,6 +87,8 @@ public class ConcurrentUpdateSolrClient extends SolrClient {
   int pollQueueTime = 250;
   private final boolean streamDeletes;
   private boolean internalHttpClient;
+  private volatile Integer connectionTimeout;
+  private volatile Integer soTimeout;
 
   /**
    * Uses an internally managed HttpClient instance.
@@ -274,11 +277,22 @@ public class ConcurrentUpdateSolrClient extends SolrClient {
 
           method = new HttpPost(client.getBaseURL() + "/update"
               + requestParams.toQueryString());
+          
+          Builder requestConfigBuilder = HttpClientUtil.createDefaultRequestConfigBuilder();
+          if (soTimeout != null) {
+            requestConfigBuilder.setSocketTimeout(soTimeout);
+          }
+          if (connectionTimeout != null) {
+            requestConfigBuilder.setConnectTimeout(connectionTimeout);
+          }
+  
+          method.setConfig(requestConfigBuilder.build());
+          
           method.setEntity(template);
           method.addHeader("User-Agent", HttpSolrClient.AGENT);
           method.addHeader("Content-Type", contentType);
 
-          response = client.getHttpClient().execute(method);
+          response = client.getHttpClient().execute(method, HttpClientUtil.createNewHttpClientRequestContext());
           rspBody = response.getEntity().getContent();
           int statusCode = response.getStatusLine().getStatusCode();
           if (statusCode != HttpStatus.SC_OK) {
@@ -489,7 +503,7 @@ public class ConcurrentUpdateSolrClient extends SolrClient {
   }
   
   public void setConnectionTimeout(int timeout) {
-    HttpClientUtil.setConnectionTimeout(client.getHttpClient(), timeout);
+    this.connectionTimeout = timeout;
   }
 
   /**
@@ -497,7 +511,7 @@ public class ConcurrentUpdateSolrClient extends SolrClient {
    * not for indexing.
    */
   public void setSoTimeout(int timeout) {
-    HttpClientUtil.setSoTimeout(client.getHttpClient(), timeout);
+    this.soTimeout = timeout;
   }
 
   public void shutdownNow() {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpClientConfigurer.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpClientConfigurer.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpClientConfigurer.java
deleted file mode 100644
index 0f97bd0..0000000
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpClientConfigurer.java
+++ /dev/null
@@ -1,100 +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.client.solrj.impl;
-
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpRequestInterceptor;
-import org.apache.http.conn.ssl.SSLSocketFactory;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.protocol.HttpContext;
-import org.apache.solr.common.SolrException;
-import org.apache.solr.common.SolrException.ErrorCode;
-import org.apache.solr.common.params.SolrParams;
-
-/**
- * The default http client configurer. If the behaviour needs to be customized a
- * new HttpCilentConfigurer can be set by calling
- * {@link HttpClientUtil#setConfigurer(HttpClientConfigurer)}
- */
-public class HttpClientConfigurer {
-  
-  public void configure(DefaultHttpClient httpClient, SolrParams config) {
-    
-    if (config.get(HttpClientUtil.PROP_MAX_CONNECTIONS) != null) {
-      HttpClientUtil.setMaxConnections(httpClient,
-          config.getInt(HttpClientUtil.PROP_MAX_CONNECTIONS));
-    }
-    
-    if (config.get(HttpClientUtil.PROP_MAX_CONNECTIONS_PER_HOST) != null) {
-      HttpClientUtil.setMaxConnectionsPerHost(httpClient,
-          config.getInt(HttpClientUtil.PROP_MAX_CONNECTIONS_PER_HOST));
-    }
-    
-    if (config.get(HttpClientUtil.PROP_CONNECTION_TIMEOUT) != null) {
-      HttpClientUtil.setConnectionTimeout(httpClient,
-          config.getInt(HttpClientUtil.PROP_CONNECTION_TIMEOUT));
-    }
-    
-    if (config.get(HttpClientUtil.PROP_SO_TIMEOUT) != null) {
-      HttpClientUtil.setSoTimeout(httpClient,
-          config.getInt(HttpClientUtil.PROP_SO_TIMEOUT));
-    }
-    
-    if (config.get(HttpClientUtil.PROP_FOLLOW_REDIRECTS) != null) {
-      HttpClientUtil.setFollowRedirects(httpClient,
-          config.getBool(HttpClientUtil.PROP_FOLLOW_REDIRECTS));
-    }
-    
-    // always call setUseRetry, whether it is in config or not
-    HttpClientUtil.setUseRetry(httpClient,
-        config.getBool(HttpClientUtil.PROP_USE_RETRY, true));
-    
-    final String basicAuthUser = config
-        .get(HttpClientUtil.PROP_BASIC_AUTH_USER);
-    final String basicAuthPass = config
-        .get(HttpClientUtil.PROP_BASIC_AUTH_PASS);
-    HttpClientUtil.setBasicAuth(httpClient, basicAuthUser, basicAuthPass);
-    
-    if (config.get(HttpClientUtil.PROP_ALLOW_COMPRESSION) != null) {
-      HttpClientUtil.setAllowCompression(httpClient,
-          config.getBool(HttpClientUtil.PROP_ALLOW_COMPRESSION));
-    }
-    
-    boolean sslCheckPeerName = toBooleanDefaultIfNull(
-        toBooleanObject(System.getProperty(HttpClientUtil.SYS_PROP_CHECK_PEER_NAME)), true);
-    if(sslCheckPeerName == false) {
-      HttpClientUtil.setHostNameVerifier(httpClient, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
-    }
-  }
-  
-  public static boolean toBooleanDefaultIfNull(Boolean bool, boolean valueIfNull) {
-    if (bool == null) {
-      return valueIfNull;
-    }
-    return bool.booleanValue() ? true : false;
-  }
-  
-  public static Boolean toBooleanObject(String str) {
-    if ("true".equalsIgnoreCase(str)) {
-      return Boolean.TRUE;
-    } else if ("false".equalsIgnoreCase(str)) {
-      return Boolean.FALSE;
-    }
-    // no match
-    return null;
-  }
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ce172acb/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpClientUtil.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpClientUtil.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpClientUtil.java
index 2ad8975..72297b3 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpClientUtil.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpClientUtil.java
@@ -19,11 +19,11 @@ package org.apache.solr.client.solrj.impl;
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.invoke.MethodHandles;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
 import java.util.zip.GZIPInputStream;
 import java.util.zip.InflaterInputStream;
 
@@ -37,40 +37,50 @@ import org.apache.http.HttpResponse;
 import org.apache.http.HttpResponseInterceptor;
 import org.apache.http.auth.AuthScope;
 import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.CredentialsProvider;
 import org.apache.http.client.HttpClient;
-import org.apache.http.client.params.ClientParamBean;
-import org.apache.http.conn.ClientConnectionManager;
-import org.apache.http.conn.scheme.Scheme;
-import org.apache.http.conn.ssl.SSLSocketFactory;
-import org.apache.http.conn.ssl.X509HostnameVerifier;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.config.RequestConfig.Builder;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.config.Registry;
+import org.apache.http.config.RegistryBuilder;
+import org.apache.http.conn.ConnectionKeepAliveStrategy;
+import org.apache.http.conn.socket.ConnectionSocketFactory;
+import org.apache.http.conn.socket.PlainConnectionSocketFactory;
 import org.apache.http.entity.HttpEntityWrapper;
+import org.apache.http.impl.client.BasicCredentialsProvider;
 import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.DefaultHttpClient;
 import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
-import org.apache.http.impl.client.SystemDefaultHttpClient;
-import org.apache.http.impl.conn.PoolingClientConnectionManager;
-import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; // jdoc
-import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
 import org.apache.http.protocol.HttpContext;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.SolrException.ErrorCode;
 import org.apache.solr.common.params.ModifiableSolrParams;
 import org.apache.solr.common.params.SolrParams;
+import org.apache.solr.common.util.ObjectReleaseTracker;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
  * Utility class for creating/configuring httpclient instances. 
+ * 
+ * This class can touch internal HttpClient details and is subject to change.
+ * 
+ * @lucene.experimental
  */
 public class HttpClientUtil {
-  // socket timeout measured in ms, closes a socket if read
-  // takes longer than x ms to complete. throws
-  // java.net.SocketTimeoutException: Read timed out exception
-  public static final String PROP_SO_TIMEOUT = "socketTimeout";
-  // connection timeout measures in ms, closes a socket if connection
-  // cannot be established within x ms. with a
-  // java.net.SocketTimeoutException: Connection timed out
-  public static final String PROP_CONNECTION_TIMEOUT = "connTimeout";
+  
+  private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+  
+  private static final int DEFAULT_CONNECT_TIMEOUT = 60000;
+  private static final int DEFAULT_SO_TIMEOUT = 600000;
+  
+  private static final int VALIDATE_AFTER_INACTIVITY_DEFAULT = 3000;
+  private static final int EVICT_IDLE_CONNECTIONS_DEFAULT = 50000;
+  private static final String VALIDATE_AFTER_INACTIVITY = "validateAfterInactivity";
+  private static final String EVICT_IDLE_CONNECTIONS = "evictIdleConnections";
+
   // Maximum connections allowed per host
   public static final String PROP_MAX_CONNECTIONS_PER_HOST = "maxConnectionsPerHost";
   // Maximum total connections allowed
@@ -79,8 +89,6 @@ public class HttpClientUtil {
   public static final String PROP_USE_RETRY = "retry";
   // Allow compression (deflate,gzip) if server supports it
   public static final String PROP_ALLOW_COMPRESSION = "allowCompression";
-  // Follow redirects
-  public static final String PROP_FOLLOW_REDIRECTS = "followRedirects";
   // Basic auth username 
   public static final String PROP_BASIC_AUTH_USER = "httpBasicAuthUser";
   // Basic auth password 
@@ -88,25 +96,92 @@ public class HttpClientUtil {
   
   public static final String SYS_PROP_CHECK_PEER_NAME = "solr.ssl.checkPeerName";
   
-  private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+  // * NOTE* The following params configure the default request config and this
+  // is overridden by SolrJ clients. Use the setters on the SolrJ clients to
+  // to configure these settings if that is the intent.
+  
+  // Follow redirects
+  public static final String PROP_FOLLOW_REDIRECTS = "followRedirects";
+  
+  // socket timeout measured in ms, closes a socket if read
+  // takes longer than x ms to complete. throws
+  // java.net.SocketTimeoutException: Read timed out exception
+  public static final String PROP_SO_TIMEOUT = "socketTimeout";
+  // connection timeout measures in ms, closes a socket if connection
+  // cannot be established within x ms. with a
+  // java.net.SocketTimeoutException: Connection timed out
+  public static final String PROP_CONNECTION_TIMEOUT = "connTimeout";
   
   static final DefaultHttpRequestRetryHandler NO_RETRY = new DefaultHttpRequestRetryHandler(
       0, false);
 
-  private static HttpClientConfigurer configurer = new HttpClientConfigurer();
+  private static volatile SolrHttpClientBuilder httpClientBuilder;
+  
+  private static SolrHttpClientContextBuilder httpClientRequestContextBuilder = new SolrHttpClientContextBuilder();
+  
+  static {
+    resetHttpClientBuilder();
+  }
+  
+  public static abstract class SchemaRegistryProvider {
+    public abstract Registry<ConnectionSocketFactory> getSchemaRegistry();
+  }
+  
+  private static volatile SchemaRegistryProvider schemaRegistryProvider;
+  private static volatile String cookiePolicy;
 
   private static final List<HttpRequestInterceptor> interceptors = Collections.synchronizedList(new ArrayList<HttpRequestInterceptor>());
   
-  /**
-   * Replace the {@link HttpClientConfigurer} class used in configuring the http
-   * clients with a custom implementation.
-   */
-  public static void setConfigurer(HttpClientConfigurer newConfigurer) {
-    configurer = newConfigurer;
+  private static class DynamicInterceptor implements HttpRequestInterceptor {
+
+    @Override
+    public void process(HttpRequest request, HttpContext context) throws HttpException, IOException {
+      interceptors.forEach(new Consumer<HttpRequestInterceptor>() {
+
+        @Override
+        public void accept(HttpRequestInterceptor interceptor) {
+          try {
+            interceptor.process(request, context);
+          } catch (Exception e) {
+            logger.error("", e);
+          }
+        }
+      });
+
+    }
   }
   
-  public static HttpClientConfigurer getConfigurer() {
-    return configurer;
+  public static void setHttpClientBuilder(SolrHttpClientBuilder newHttpClientBuilder) {
+    httpClientBuilder = newHttpClientBuilder;
+  }
+  
+  public static void setHttpClientProvider(SolrHttpClientBuilder newHttpClientBuilder) {
+    httpClientBuilder = newHttpClientBuilder;
+  }
+
+  public static void setSchemeRegistryProvider(SchemaRegistryProvider newRegistryProvider) {
+    schemaRegistryProvider = newRegistryProvider;
+  }
+  
+  public static SolrHttpClientBuilder getHttpClientBuilder() {
+    return httpClientBuilder;
+  }
+  
+  public static SchemaRegistryProvider getSchemaRegisteryProvider() {
+    return schemaRegistryProvider;
+  }
+  
+  public static void resetHttpClientBuilder() {
+    schemaRegistryProvider = new SchemaRegistryProvider() {
+
+      @Override
+      public Registry<ConnectionSocketFactory> getSchemaRegistry() {
+        return RegistryBuilder.<ConnectionSocketFactory> create()
+            .register("http", PlainConnectionSocketFactory.getSocketFactory()).build();
+      }
+    };
+    httpClientBuilder = SolrHttpClientBuilder.create();
+
   }
   
   /**
@@ -116,195 +191,137 @@ public class HttpClientUtil {
    *          http client configuration, if null a client with default
    *          configuration (no additional configuration) is created. 
    */
-  public static CloseableHttpClient createClient(final SolrParams params) {
-    final ModifiableSolrParams config = new ModifiableSolrParams(params);
-    if (logger.isDebugEnabled()) {
-      logger.debug("Creating new http client, config:" + config);
+  public static CloseableHttpClient createClient(SolrParams params) {
+    PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(schemaRegistryProvider.getSchemaRegistry());
+
+    return createClient(params, cm);
+  }
+  
+  public static CloseableHttpClient createClient(SolrParams params, PoolingHttpClientConnectionManager cm) {
+    if (params == null) {
+      params = new ModifiableSolrParams();
     }
-    final DefaultHttpClient httpClient = HttpClientFactory.createHttpClient();
-    configureClient(httpClient, config);
-    return httpClient;
+    
+    return createClient(params, cm, false);
   }
   
   /**
    * Creates new http client by using the provided configuration.
    * 
    */
-  public static CloseableHttpClient createClient(final SolrParams params, ClientConnectionManager cm) {
+  public static CloseableHttpClient createClient(final SolrParams params, PoolingHttpClientConnectionManager cm, boolean sharedConnectionManager) {
     final ModifiableSolrParams config = new ModifiableSolrParams(params);
     if (logger.isDebugEnabled()) {
       logger.debug("Creating new http client, config:" + config);
     }
-    final DefaultHttpClient httpClient = HttpClientFactory.createHttpClient(cm);
-    configureClient(httpClient, config);
-    return httpClient;
-  }
-
-  /**
-   * Configures {@link DefaultHttpClient}, only sets parameters if they are
-   * present in config.
-   */
-  public static void configureClient(final DefaultHttpClient httpClient,
-      SolrParams config) {
-    configurer.configure(httpClient,  config);
-    synchronized(interceptors) {
-      for(HttpRequestInterceptor interceptor: interceptors) {
-        httpClient.addRequestInterceptor(interceptor);
-      }
+ 
+    if (params.get(PROP_SO_TIMEOUT) != null || params.get(PROP_CONNECTION_TIMEOUT) != null) {
+      throw new SolrException(ErrorCode.SERVER_ERROR, "The socket connect and read timeout cannot be set here and must be set");
     }
-  }
-  
-  public static void close(HttpClient httpClient) { 
-    if (httpClient instanceof CloseableHttpClient) {
-      org.apache.solr.common.util.IOUtils.closeQuietly((CloseableHttpClient) httpClient);
+    
+    cm.setMaxTotal(params.getInt(HttpClientUtil.PROP_MAX_CONNECTIONS, 10000));
+    cm.setDefaultMaxPerRoute(params.getInt(HttpClientUtil.PROP_MAX_CONNECTIONS_PER_HOST, 10000));
+    cm.setValidateAfterInactivity(Integer.getInteger(VALIDATE_AFTER_INACTIVITY, VALIDATE_AFTER_INACTIVITY_DEFAULT));
+
+    
+    HttpClientBuilder newHttpClientBuilder = HttpClientBuilder.create();
+
+    if (sharedConnectionManager) {
+      newHttpClientBuilder.setConnectionManagerShared(true);
     } else {
-      httpClient.getConnectionManager().shutdown();
+      newHttpClientBuilder.setConnectionManagerShared(false);
     }
-  }
+    
+    ConnectionKeepAliveStrategy keepAliveStrat = new ConnectionKeepAliveStrategy() {
+      @Override
+      public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
+        // we only close connections based on idle time, not ttl expiration
+        return -1;
+      }
+    };
 
-  public static void addRequestInterceptor(HttpRequestInterceptor interceptor) {
-    interceptors.add(interceptor);
-  }
+    if (httpClientBuilder.getAuthSchemeRegistryProvider() != null) {
+      newHttpClientBuilder.setDefaultAuthSchemeRegistry(httpClientBuilder.getAuthSchemeRegistryProvider().getAuthSchemeRegistry());
+    }
+    if (httpClientBuilder.getCookieSpecRegistryProvider() != null) {
+      newHttpClientBuilder.setDefaultCookieSpecRegistry(httpClientBuilder.getCookieSpecRegistryProvider().getCookieSpecRegistry());
+    }
+    if (httpClientBuilder.getCredentialsProviderProvider() != null) {
+      newHttpClientBuilder.setDefaultCredentialsProvider(httpClientBuilder.getCredentialsProviderProvider().getCredentialsProvider());
+    }
 
-  public static void removeRequestInterceptor(HttpRequestInterceptor interceptor) {
-    interceptors.remove(interceptor);
+    newHttpClientBuilder.addInterceptorLast(new DynamicInterceptor());
+    
+    newHttpClientBuilder = newHttpClientBuilder.setKeepAliveStrategy(keepAliveStrat)
+        .evictIdleConnections((long) Integer.getInteger(EVICT_IDLE_CONNECTIONS, EVICT_IDLE_CONNECTIONS_DEFAULT), TimeUnit.MILLISECONDS);
+    
+    HttpClientBuilder builder = setupBuilder(newHttpClientBuilder, params == null ? new ModifiableSolrParams() : params);
+    
+    HttpClient httpClient = builder.setConnectionManager(cm).build();
+    
+    assert ObjectReleaseTracker.track(httpClient);
+    return (CloseableHttpClient) httpClient;
   }
+  
+  private static HttpClientBuilder setupBuilder(HttpClientBuilder builder, SolrParams config) {
+   
+    Builder requestConfigBuilder = RequestConfig.custom()
+        .setRedirectsEnabled(config.getBool(HttpClientUtil.PROP_FOLLOW_REDIRECTS, false)).setDecompressionEnabled(false)
+        .setConnectTimeout(config.getInt(HttpClientUtil.PROP_CONNECTION_TIMEOUT, DEFAULT_CONNECT_TIMEOUT))
+        .setSocketTimeout(config.getInt(HttpClientUtil.PROP_SO_TIMEOUT, DEFAULT_SO_TIMEOUT));
 
-  /**
-   * Control HTTP payload compression.
-   * 
-   * @param allowCompression
-   *          true will enable compression (needs support from server), false
-   *          will disable compression.
-   */
-  public static void setAllowCompression(DefaultHttpClient httpClient,
-      boolean allowCompression) {
-    httpClient
-        .removeRequestInterceptorByClass(UseCompressionRequestInterceptor.class);
-    httpClient
-        .removeResponseInterceptorByClass(UseCompressionResponseInterceptor.class);
-    if (allowCompression) {
-      httpClient.addRequestInterceptor(new UseCompressionRequestInterceptor());
-      httpClient
-          .addResponseInterceptor(new UseCompressionResponseInterceptor());
+    String cpolicy = cookiePolicy;
+    if (cpolicy != null) {
+      requestConfigBuilder.setCookieSpec(cpolicy);
     }
-  }
+    
+    RequestConfig requestConfig = requestConfigBuilder.build();
+    
+    HttpClientBuilder retBuilder = builder.setDefaultRequestConfig(requestConfig);
+
+    if (config.getBool(HttpClientUtil.PROP_USE_RETRY, true)) {
+      retBuilder = retBuilder.setRetryHandler(new SolrHttpRequestRetryHandler(3));
 
-  /**
-   * Set http basic auth information. If basicAuthUser or basicAuthPass is null
-   * the basic auth configuration is cleared. Currently this is not preemtive
-   * authentication. So it is not currently possible to do a post request while
-   * using this setting.
-   */
-  public static void setBasicAuth(DefaultHttpClient httpClient,
-      String basicAuthUser, String basicAuthPass) {
-    if (basicAuthUser != null && basicAuthPass != null) {
-      httpClient.getCredentialsProvider().setCredentials(AuthScope.ANY,
-          new UsernamePasswordCredentials(basicAuthUser, basicAuthPass));
     } else {
-      httpClient.getCredentialsProvider().clear();
+      retBuilder = retBuilder.setRetryHandler(NO_RETRY);
     }
-  }
 
-  /**
-   * Set max connections allowed per host. This call will only work when
-   * {@link ThreadSafeClientConnManager} or
-   * {@link PoolingClientConnectionManager} is used.
-   */
-  public static void setMaxConnectionsPerHost(HttpClient httpClient,
-      int max) {
-    // would have been nice if there was a common interface
-    if (httpClient.getConnectionManager() instanceof ThreadSafeClientConnManager) {
-      ThreadSafeClientConnManager mgr = (ThreadSafeClientConnManager)httpClient.getConnectionManager();
-      mgr.setDefaultMaxPerRoute(max);
-    } else if (httpClient.getConnectionManager() instanceof PoolingClientConnectionManager) {
-      PoolingClientConnectionManager mgr = (PoolingClientConnectionManager)httpClient.getConnectionManager();
-      mgr.setDefaultMaxPerRoute(max);
+    final String basicAuthUser = config.get(HttpClientUtil.PROP_BASIC_AUTH_USER);
+    final String basicAuthPass = config.get(HttpClientUtil.PROP_BASIC_AUTH_PASS);
+    
+    if (basicAuthUser != null && basicAuthPass != null) {
+      CredentialsProvider credsProvider = new BasicCredentialsProvider();
+      credsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(basicAuthUser, basicAuthPass));
+      retBuilder.setDefaultCredentialsProvider(credsProvider);
     }
-  }
-
-  /**
-   * Set max total connections allowed. This call will only work when
-   * {@link ThreadSafeClientConnManager} or
-   * {@link PoolingClientConnectionManager} is used.
-   */
-  public static void setMaxConnections(final HttpClient httpClient,
-      int max) {
-    // would have been nice if there was a common interface
-    if (httpClient.getConnectionManager() instanceof ThreadSafeClientConnManager) {
-      ThreadSafeClientConnManager mgr = (ThreadSafeClientConnManager)httpClient.getConnectionManager();
-      mgr.setMaxTotal(max);
-    } else if (httpClient.getConnectionManager() instanceof PoolingClientConnectionManager) {
-      PoolingClientConnectionManager mgr = (PoolingClientConnectionManager)httpClient.getConnectionManager();
-      mgr.setMaxTotal(max);
+    
+    if (config.getBool(HttpClientUtil.PROP_ALLOW_COMPRESSION, false)) {
+      retBuilder.addInterceptorFirst(new UseCompressionRequestInterceptor());
+      retBuilder.addInterceptorFirst(new UseCompressionResponseInterceptor());
+    } else {
+      retBuilder.disableContentCompression();
     }
-  }
-  
 
-  /**
-   * Defines the socket timeout (SO_TIMEOUT) in milliseconds. A timeout value of
-   * zero is interpreted as an infinite timeout.
-   * 
-   * @param timeout timeout in milliseconds
-   */
-  public static void setSoTimeout(HttpClient httpClient, int timeout) {
-    HttpConnectionParams.setSoTimeout(httpClient.getParams(),
-        timeout);
+    return retBuilder;
   }
 
-  /**
-   * Control retry handler 
-   * @param useRetry when false the client will not try to retry failed requests.
-   */
-  public static void setUseRetry(final DefaultHttpClient httpClient,
-      boolean useRetry) {
-    if (!useRetry) {
-      httpClient.setHttpRequestRetryHandler(NO_RETRY);
-    } else {
-      // if the request is not fully sent, we retry
-      // streaming updates are not a problem, because they are not retryable
-      httpClient.setHttpRequestRetryHandler(new SolrHttpRequestRetryHandler(3));
-    }
-  }
+  public static void close(HttpClient httpClient) { 
 
-  /**
-   * Set connection timeout. A timeout value of zero is interpreted as an
-   * infinite timeout.
-   * 
-   * @param timeout
-   *          connection Timeout in milliseconds
-   */
-  public static void setConnectionTimeout(final HttpClient httpClient,
-      int timeout) {
-      HttpConnectionParams.setConnectionTimeout(httpClient.getParams(),
-          timeout);
-  }
+    org.apache.solr.common.util.IOUtils.closeQuietly((CloseableHttpClient) httpClient);
 
-  /**
-   * Set follow redirects.
-   *
-   * @param followRedirects  When true the client will follow redirects.
-   */
-  public static void setFollowRedirects(HttpClient httpClient,
-      boolean followRedirects) {
-    new ClientParamBean(httpClient.getParams()).setHandleRedirects(followRedirects);
+    assert ObjectReleaseTracker.release(httpClient);
   }
 
-  public static void setHostNameVerifier(DefaultHttpClient httpClient,
-      X509HostnameVerifier hostNameVerifier) {
-    Scheme httpsScheme = httpClient.getConnectionManager().getSchemeRegistry().get("https");
-    if (httpsScheme != null) {
-      SSLSocketFactory sslSocketFactory = (SSLSocketFactory) httpsScheme.getSchemeSocketFactory();
-      sslSocketFactory.setHostnameVerifier(hostNameVerifier);
-    }
+  public static void addRequestInterceptor(HttpRequestInterceptor interceptor) {
+    interceptors.add(interceptor);
   }
-  
-  public static void setStaleCheckingEnabled(final HttpClient httpClient, boolean enabled) {
-    HttpConnectionParams.setStaleCheckingEnabled(httpClient.getParams(), enabled);
+
+  public static void removeRequestInterceptor(HttpRequestInterceptor interceptor) {
+    interceptors.remove(interceptor);
   }
   
-  public static void setTcpNoDelay(final HttpClient httpClient, boolean tcpNoDelay) {
-    HttpConnectionParams.setTcpNoDelay(httpClient.getParams(), tcpNoDelay);
+  public static void clearRequestInterceptors() {
+    interceptors.clear();
   }
   
   private static class UseCompressionRequestInterceptor implements
@@ -374,35 +391,34 @@ public class HttpClientUtil {
     }
   }
 
-  public static class HttpClientFactory {
-    private static Class<? extends DefaultHttpClient> defaultHttpClientClass = DefaultHttpClient.class;
-    private static Class<? extends SystemDefaultHttpClient> systemDefaultHttpClientClass = SystemDefaultHttpClient.class;
-
+  public static void setHttpClientRequestContextBuilder(SolrHttpClientContextBuilder httpClientContextBuilder) {
+    httpClientRequestContextBuilder = httpClientContextBuilder;
+  }
 
-    public static SystemDefaultHttpClient createHttpClient() {
-      Constructor<? extends SystemDefaultHttpClient> constructor;
-      try {
-        constructor = systemDefaultHttpClientClass.getDeclaredConstructor();
-        return constructor.newInstance();
-      } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
-        throw new SolrException(ErrorCode.SERVER_ERROR, "Unable to create HttpClient instance. ", e);
-      }
-    }
+  /**
+   * 
+   */
+  public static HttpClientContext createNewHttpClientRequestContext() {
+    return httpClientRequestContextBuilder.createContext();
+  }
+  
+  public static Builder createDefaultRequestConfigBuilder() {
+    String cpolicy = cookiePolicy;
+    Builder builder = RequestConfig.custom();
 
-    public static DefaultHttpClient createHttpClient(ClientConnectionManager cm) {
-      Constructor<? extends DefaultHttpClient> constructor;
-      try {
-        constructor = defaultHttpClientClass.getDeclaredConstructor(new Class[]{ClientConnectionManager.class});
-        return constructor.newInstance(new Object[]{cm});
-      } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
-        throw new SolrException(ErrorCode.SERVER_ERROR, "Unable to create HttpClient instance, registered class is: " + defaultHttpClientClass, e);
-      }
+    builder.setSocketTimeout(DEFAULT_SO_TIMEOUT)
+        .setConnectTimeout(DEFAULT_CONNECT_TIMEOUT)
+        .setRedirectsEnabled(false)
+        .setDecompressionEnabled(false); // we do our own compression / decompression
+    if (cpolicy != null) {
+      builder.setCookieSpec(cpolicy);
     }
+    return builder;
+  }
 
-    public static void setHttpClientImpl(Class<? extends DefaultHttpClient> defaultHttpClient, Class<? extends SystemDefaultHttpClient> systemDefaultHttpClient) {
-      defaultHttpClientClass = defaultHttpClient;
-      systemDefaultHttpClientClass = systemDefaultHttpClient;
-    }
+  public static void setCookiePolicy(String policyName) {
+    cookiePolicy = policyName;
   }
 
+
 }