diff --git a/changelog/unreleased/SOLR-17771-cloudhttp2solrclient-builder- now also can work.yml b/changelog/unreleased/SOLR-17771-cloudhttp2solrclient-builder- now also can work.yml index f121838cb96..d1d6618ce39 100644 --- a/changelog/unreleased/SOLR-17771-cloudhttp2solrclient-builder- now also can work.yml +++ b/changelog/unreleased/SOLR-17771-cloudhttp2solrclient-builder- now also can work.yml @@ -1,4 +1,4 @@ -title: '`CloudHttp2SolrClient.Builder` now also can work with `HttpJdkSolrClient`.' +title: '`CloudSolrClient.Builder` / now also can work with `HttpJdkSolrClient`.' type: changed authors: - name: James Dyer diff --git a/changelog/unreleased/SOLR-18005-MoveToJettyPackageAndRename.yml b/changelog/unreleased/SOLR-18005-MoveToJettyPackageAndRename.yml new file mode 100644 index 00000000000..47ffa749c83 --- /dev/null +++ b/changelog/unreleased/SOLR-18005-MoveToJettyPackageAndRename.yml @@ -0,0 +1,8 @@ +# See https://github.com/apache/solr/blob/main/dev-docs/changelog.adoc +title: Add CloudJettySolrClient. Moved CloudHttp2SolrClient.Builder to CloudSolrClient. Rename Http2SolrClient to HttpJettySolrClient +type: other # added, changed, fixed, deprecated, removed, dependency_update, security, other +authors: + - name: David Smiley +links: + - name: SOLR-18005 + url: https://issues.apache.org/jira/browse/SOLR-18005 diff --git a/solr/benchmark/src/java/org/apache/solr/bench/MiniClusterState.java b/solr/benchmark/src/java/org/apache/solr/bench/MiniClusterState.java index baf4ccedbfb..87dba1cb477 100755 --- a/solr/benchmark/src/java/org/apache/solr/bench/MiniClusterState.java +++ b/solr/benchmark/src/java/org/apache/solr/bench/MiniClusterState.java @@ -38,7 +38,7 @@ import java.util.concurrent.TimeUnit; import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.SolrServerException; -import org.apache.solr.client.solrj.impl.Http2SolrClient; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.client.solrj.request.CollectionAdminRequest; import org.apache.solr.client.solrj.request.QueryRequest; import org.apache.solr.client.solrj.request.UpdateRequest; @@ -82,7 +82,7 @@ public static class MiniClusterBenchState { MiniSolrCloudCluster cluster; /** The Client. */ - public Http2SolrClient client; + public HttpJettySolrClient client; /** The Run cnt. */ int runCnt = 0; @@ -291,7 +291,7 @@ public void startMiniCluster(int nodeCount) { } zkHost = cluster.getZkServer().getZkAddress(); - client = new Http2SolrClient.Builder(nodes.get(0)).useHttp1_1(useHttp1).build(); + client = new HttpJettySolrClient.Builder(nodes.get(0)).useHttp1_1(useHttp1).build(); log("done starting mini cluster"); log(""); diff --git a/solr/benchmark/src/java/org/apache/solr/bench/search/StreamingSearch.java b/solr/benchmark/src/java/org/apache/solr/bench/search/StreamingSearch.java index 09928af733c..a9860763dbe 100644 --- a/solr/benchmark/src/java/org/apache/solr/bench/search/StreamingSearch.java +++ b/solr/benchmark/src/java/org/apache/solr/bench/search/StreamingSearch.java @@ -27,12 +27,12 @@ import org.apache.solr.bench.MiniClusterState; import org.apache.solr.bench.MiniClusterState.MiniClusterBenchState; import org.apache.solr.client.solrj.SolrServerException; -import org.apache.solr.client.solrj.impl.Http2SolrClient; import org.apache.solr.client.solrj.io.SolrClientCache; import org.apache.solr.client.solrj.io.Tuple; import org.apache.solr.client.solrj.io.stream.CloudSolrStream; import org.apache.solr.client.solrj.io.stream.StreamContext; import org.apache.solr.client.solrj.io.stream.TupleStream; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.common.params.CommonParams; import org.apache.solr.common.params.ModifiableSolrParams; import org.openjdk.jmh.annotations.Benchmark; @@ -68,7 +68,7 @@ public static class BenchState { private String zkHost; private ModifiableSolrParams params; private StreamContext streamContext; - private Http2SolrClient http2SolrClient; + private HttpJettySolrClient httpJettySolrClient; @Setup(Level.Trial) public void setup(MiniClusterBenchState miniClusterState) throws Exception { @@ -98,7 +98,7 @@ public void setupIteration(MiniClusterState.MiniClusterBenchState miniClusterSta throws SolrServerException, IOException { SolrClientCache solrClientCache; // TODO tune params? - var client = new Http2SolrClient.Builder().useHttp1_1(useHttp1).build(); + var client = new HttpJettySolrClient.Builder().useHttp1_1(useHttp1).build(); solrClientCache = new SolrClientCache(client); streamContext = new StreamContext(); @@ -108,8 +108,8 @@ public void setupIteration(MiniClusterState.MiniClusterBenchState miniClusterSta @TearDown(Level.Iteration) public void teardownIt() { streamContext.getSolrClientCache().close(); - if (http2SolrClient != null) { - http2SolrClient.close(); + if (httpJettySolrClient != null) { + httpJettySolrClient.close(); } } } diff --git a/solr/bin/solr b/solr/bin/solr index d17f00a4013..d9a95a41efe 100755 --- a/solr/bin/solr +++ b/solr/bin/solr @@ -342,7 +342,7 @@ fi if [ -n "${SOLR_AUTH_TYPE:-}" ]; then case "$(echo "$SOLR_AUTH_TYPE" | awk '{print tolower($0)}')" in basic) - SOLR_AUTHENTICATION_CLIENT_BUILDER="org.apache.solr.client.solrj.impl.PreemptiveBasicAuthClientBuilderFactory" + SOLR_AUTHENTICATION_CLIENT_BUILDER="org.apache.solr.client.solrj.jetty.PreemptiveBasicAuthClientBuilderFactory" ;; *) echo "ERROR: Value specified for SOLR_AUTH_TYPE environment variable is invalid." diff --git a/solr/bin/solr.cmd b/solr/bin/solr.cmd index 44262f4f974..7396804262b 100755 --- a/solr/bin/solr.cmd +++ b/solr/bin/solr.cmd @@ -227,7 +227,7 @@ IF DEFINED SOLR_AUTH_TYPE ( IF DEFINED SOLR_AUTH_TYPE ( IF /I "%SOLR_AUTH_TYPE%" == "basic" ( - set SOLR_AUTHENTICATION_CLIENT_BUILDER="org.apache.solr.client.solrj.impl.PreemptiveBasicAuthClientBuilderFactory" + set SOLR_AUTHENTICATION_CLIENT_BUILDER="org.apache.solr.client.solrj.jetty.PreemptiveBasicAuthClientBuilderFactory" ) ELSE ( echo ERROR: Value specified for SOLR_AUTH_TYPE configuration variable is invalid. goto err @@ -1172,7 +1172,7 @@ for %%a in (%*) do ( ) else ( set "option!option!=%%a" if "!option!" equ "--solr-home" set "SOLR_HOME=%%a" - if "!option!" equ "--server-dir" set "SOLR_SERVER_DIR=%%a" + if "!option!" equ "--server-dir" set "SOLR_SERVER_DIR=%%a" if not "!option!" equ "--solr-home" if not "!option!" equ "--server-dir" ( set "AUTH_PARAMS=!AUTH_PARAMS! !option! %%a" ) diff --git a/solr/bin/solr.in.cmd b/solr/bin/solr.in.cmd index c90a9fa1c32..d605e04b712 100755 --- a/solr/bin/solr.in.cmd +++ b/solr/bin/solr.in.cmd @@ -173,7 +173,7 @@ REM set SOLR_SSL_CLIENT_TRUST_STORE_TYPE= REM Settings for authentication REM Please configure only one of SOLR_AUTHENTICATION_CLIENT_BUILDER or SOLR_AUTH_TYPE parameters -REM set SOLR_AUTHENTICATION_CLIENT_BUILDER=org.apache.solr.client.solrj.impl.PreemptiveBasicAuthClientBuilderFactory +REM set SOLR_AUTHENTICATION_CLIENT_BUILDER=org.apache.solr.client.solrj.jetty.PreemptiveBasicAuthClientBuilderFactory REM set SOLR_AUTH_TYPE=basic REM set SOLR_AUTHENTICATION_OPTS=-Dsolr.security.auth.basicauth.credentials=solr:SolrRocks @@ -251,6 +251,6 @@ REM Configure the default replica placement plugin to use if one is not configur REM See https://solr.apache.org/guide/solr/latest/configuration-guide/replica-placement-plugins.html for details REM set SOLR_PLACEMENTPLUGIN_DEFAULT=simple -REM Solr internally doesn't use cookies. If you don't need any of those, and you don't +REM Solr internally doesn't use cookies. If you don't need any of those, and you don't REM need them for an external system (such as a load balancer), you can disable the use of a CookieStore with: REM set SOLR_OPTS=%SOLR_OPTS% -Dsolr.solrj.http.cookies.enabled=false diff --git a/solr/bin/solr.in.sh b/solr/bin/solr.in.sh index 4752790d44f..569066fede4 100644 --- a/solr/bin/solr.in.sh +++ b/solr/bin/solr.in.sh @@ -189,7 +189,7 @@ # Settings for authentication # Please configure only one of SOLR_AUTHENTICATION_CLIENT_BUILDER or SOLR_AUTH_TYPE parameters -#SOLR_AUTHENTICATION_CLIENT_BUILDER="org.apache.solr.client.solrj.impl.PreemptiveBasicAuthClientBuilderFactory" +#SOLR_AUTHENTICATION_CLIENT_BUILDER="org.apache.solr.client.solrj.jetty.PreemptiveBasicAuthClientBuilderFactory" #SOLR_AUTH_TYPE="basic" #SOLR_AUTHENTICATION_OPTS="-Dsolr.security.auth.basicauth.credentials=solr:SolrRocks" @@ -287,6 +287,6 @@ # See https://solr.apache.org/guide/solr/latest/configuration-guide/replica-placement-plugins.html for details #SOLR_PLACEMENTPLUGIN_DEFAULT=simple -# Solr internally doesn't use cookies. If you don't need any of those, and you don't +# Solr internally doesn't use cookies. If you don't need any of those, and you don't # need them for an external system (such as a load balancer), you can disable the use of a CookieStore with: #SOLR_OPTS="$SOLR_OPTS -Dsolr.solrj.http.cookies.enabled=false" diff --git a/solr/core/src/java/org/apache/solr/cli/CLIUtils.java b/solr/core/src/java/org/apache/solr/cli/CLIUtils.java index 59937f79017..0520fab4e51 100644 --- a/solr/core/src/java/org/apache/solr/cli/CLIUtils.java +++ b/solr/core/src/java/org/apache/solr/cli/CLIUtils.java @@ -40,10 +40,9 @@ import org.apache.solr.client.solrj.SolrClient; import org.apache.solr.client.solrj.SolrRequest; import org.apache.solr.client.solrj.SolrServerException; -import org.apache.solr.client.solrj.impl.CloudHttp2SolrClient; import org.apache.solr.client.solrj.impl.CloudSolrClient; -import org.apache.solr.client.solrj.impl.Http2SolrClient; import org.apache.solr.client.solrj.impl.SolrZkClientTimeout; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.client.solrj.request.CollectionAdminRequest; import org.apache.solr.client.solrj.request.CoresApi; import org.apache.solr.client.solrj.request.GenericSolrRequest; @@ -109,8 +108,8 @@ public static SolrClient getSolrClient(String solrUrl, String credentials, boole if (!barePath && !solrUrl.endsWith("/solr") && !solrUrl.contains("/solr/")) { solrUrl = solrUrl + "/solr"; } - Http2SolrClient.Builder builder = - new Http2SolrClient.Builder(solrUrl) + var builder = + new HttpJettySolrClient.Builder(solrUrl) .withMaxConnectionsPerHost(32) .withKeyStoreReloadInterval(-1, TimeUnit.SECONDS) .withOptionalBasicAuthCredentials(credentials); @@ -200,7 +199,7 @@ public static String normalizeSolrUrl(CommandLine cli) throws Exception { + solrUrl + "."); } else { - try (CloudSolrClient cloudSolrClient = getCloudHttp2SolrClient(zkHost)) { + try (CloudSolrClient cloudSolrClient = getCloudSolrClient(zkHost)) { cloudSolrClient.connect(); Set liveNodes = cloudSolrClient.getClusterState().getLiveNodes(); if (liveNodes.isEmpty()) @@ -283,13 +282,13 @@ public static SolrZkClient getSolrZkClient(CommandLine cli, String zkHost) throw .build(); } - public static CloudHttp2SolrClient getCloudHttp2SolrClient(String zkHost) { - return getCloudHttp2SolrClient(zkHost, null); + public static CloudSolrClient getCloudSolrClient(String zkHost) { + return getCloudSolrClient(zkHost, null); } - public static CloudHttp2SolrClient getCloudHttp2SolrClient( - String zkHost, Http2SolrClient.Builder builder) { - return new CloudHttp2SolrClient.Builder(Collections.singletonList(zkHost), Optional.empty()) + public static CloudSolrClient getCloudSolrClient( + String zkHost, HttpJettySolrClient.Builder builder) { + return new CloudSolrClient.Builder(Collections.singletonList(zkHost), Optional.empty()) .withHttpClientBuilder(builder) .build(); } diff --git a/solr/core/src/java/org/apache/solr/cli/CreateTool.java b/solr/core/src/java/org/apache/solr/cli/CreateTool.java index 5ce1fdbfb8c..78eb6eb2901 100644 --- a/solr/core/src/java/org/apache/solr/cli/CreateTool.java +++ b/solr/core/src/java/org/apache/solr/cli/CreateTool.java @@ -32,8 +32,8 @@ import org.apache.solr.client.solrj.SolrRequest; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.impl.CloudSolrClient; -import org.apache.solr.client.solrj.impl.Http2SolrClient; import org.apache.solr.client.solrj.impl.JsonMapResponseParser; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.client.solrj.request.CollectionAdminRequest; import org.apache.solr.client.solrj.request.CoreAdminRequest; import org.apache.solr.client.solrj.request.GenericSolrRequest; @@ -208,8 +208,8 @@ protected void createCore(CommandLine cli, SolrClient solrClient) throws Excepti } protected void createCollection(CommandLine cli) throws Exception { - Http2SolrClient.Builder builder = - new Http2SolrClient.Builder() + var builder = + new HttpJettySolrClient.Builder() .withIdleTimeout(30, TimeUnit.SECONDS) .withConnectionTimeout(15, TimeUnit.SECONDS) .withKeyStoreReloadInterval(-1, TimeUnit.SECONDS) @@ -217,7 +217,7 @@ protected void createCollection(CommandLine cli) throws Exception { cli.getOptionValue(CommonCLIOptions.CREDENTIALS_OPTION)); String zkHost = CLIUtils.getZkHost(cli); echoIfVerbose("Connecting to ZooKeeper at " + zkHost); - try (CloudSolrClient cloudSolrClient = CLIUtils.getCloudHttp2SolrClient(zkHost, builder)) { + try (CloudSolrClient cloudSolrClient = CLIUtils.getCloudSolrClient(zkHost, builder)) { cloudSolrClient.connect(); createCollection(cloudSolrClient, cli); } diff --git a/solr/core/src/java/org/apache/solr/cli/DeleteTool.java b/solr/core/src/java/org/apache/solr/cli/DeleteTool.java index ce330576a71..25be18d95f5 100644 --- a/solr/core/src/java/org/apache/solr/cli/DeleteTool.java +++ b/solr/core/src/java/org/apache/solr/cli/DeleteTool.java @@ -28,8 +28,8 @@ import org.apache.solr.client.solrj.SolrClient; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.impl.CloudSolrClient; -import org.apache.solr.client.solrj.impl.Http2SolrClient; import org.apache.solr.client.solrj.impl.JsonMapResponseParser; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.client.solrj.request.CollectionAdminRequest; import org.apache.solr.client.solrj.request.CoreAdminRequest; import org.apache.solr.common.cloud.ZkStateReader; @@ -105,8 +105,8 @@ public void runImpl(CommandLine cli) throws Exception { } protected void deleteCollection(CommandLine cli) throws Exception { - Http2SolrClient.Builder builder = - new Http2SolrClient.Builder() + var builder = + new HttpJettySolrClient.Builder() .withIdleTimeout(30, TimeUnit.SECONDS) .withConnectionTimeout(15, TimeUnit.SECONDS) .withKeyStoreReloadInterval(-1, TimeUnit.SECONDS) @@ -114,7 +114,7 @@ protected void deleteCollection(CommandLine cli) throws Exception { cli.getOptionValue(CommonCLIOptions.CREDENTIALS_OPTION)); String zkHost = CLIUtils.getZkHost(cli); - try (CloudSolrClient cloudSolrClient = CLIUtils.getCloudHttp2SolrClient(zkHost, builder)) { + try (CloudSolrClient cloudSolrClient = CLIUtils.getCloudSolrClient(zkHost, builder)) { echoIfVerbose("Connecting to ZooKeeper at " + zkHost); cloudSolrClient.connect(); deleteCollection(cloudSolrClient, cli); diff --git a/solr/core/src/java/org/apache/solr/cli/ExportTool.java b/solr/core/src/java/org/apache/solr/cli/ExportTool.java index af2cf6ba590..fc1930cd658 100644 --- a/solr/core/src/java/org/apache/solr/cli/ExportTool.java +++ b/solr/core/src/java/org/apache/solr/cli/ExportTool.java @@ -60,11 +60,10 @@ import org.apache.solr.client.solrj.SolrRequest; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.StreamingResponseCallback; -import org.apache.solr.client.solrj.impl.CloudHttp2SolrClient; import org.apache.solr.client.solrj.impl.CloudSolrClient; import org.apache.solr.client.solrj.impl.ClusterStateProvider; -import org.apache.solr.client.solrj.impl.Http2SolrClient; import org.apache.solr.client.solrj.impl.StreamingJavaBinResponseParser; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.client.solrj.request.GenericSolrRequest; import org.apache.solr.client.solrj.request.QueryRequest; import org.apache.solr.common.SolrDocument; @@ -252,11 +251,10 @@ DocsSink getSink() { abstract void exportDocs() throws Exception; void fetchUniqueKey() throws SolrServerException, IOException { - Http2SolrClient.Builder builder = - new Http2SolrClient.Builder().withOptionalBasicAuthCredentials(credentials); + var builder = new HttpJettySolrClient.Builder().withOptionalBasicAuthCredentials(credentials); solrClient = - new CloudHttp2SolrClient.Builder(Collections.singletonList(baseurl)) + new CloudSolrClient.Builder(Collections.singletonList(baseurl)) .withHttpClientBuilder(builder) .build(); NamedList response = diff --git a/solr/core/src/java/org/apache/solr/cli/HealthcheckTool.java b/solr/core/src/java/org/apache/solr/cli/HealthcheckTool.java index bf795a51596..c8b6b78e6ce 100644 --- a/solr/core/src/java/org/apache/solr/cli/HealthcheckTool.java +++ b/solr/core/src/java/org/apache/solr/cli/HealthcheckTool.java @@ -32,7 +32,6 @@ import org.apache.commons.cli.Options; import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.SolrRequest; -import org.apache.solr.client.solrj.impl.CloudHttp2SolrClient; import org.apache.solr.client.solrj.impl.CloudSolrClient; import org.apache.solr.client.solrj.request.GenericSolrRequest; import org.apache.solr.client.solrj.response.QueryResponse; @@ -88,7 +87,7 @@ public void runImpl(CommandLine cli) throws Exception { CLIO.err("Healthcheck tool only works in Solr Cloud mode."); runtime.exit(1); } - try (CloudHttp2SolrClient cloudSolrClient = CLIUtils.getCloudHttp2SolrClient(zkHost)) { + try (var cloudSolrClient = CLIUtils.getCloudSolrClient(zkHost)) { echoIfVerbose("\nConnecting to ZooKeeper at " + zkHost + " ..."); cloudSolrClient.connect(); runCloudTool(cloudSolrClient, cli); diff --git a/solr/core/src/java/org/apache/solr/cli/PostLogsTool.java b/solr/core/src/java/org/apache/solr/cli/PostLogsTool.java index fd993291ed8..0cf5e95a943 100644 --- a/solr/core/src/java/org/apache/solr/cli/PostLogsTool.java +++ b/solr/core/src/java/org/apache/solr/cli/PostLogsTool.java @@ -38,7 +38,7 @@ import org.apache.commons.cli.Option; import org.apache.commons.cli.Options; import org.apache.solr.client.solrj.SolrClient; -import org.apache.solr.client.solrj.impl.Http2SolrClient; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.client.solrj.request.UpdateRequest; import org.apache.solr.common.SolrInputDocument; import org.apache.solr.common.SolrInputField; @@ -107,8 +107,8 @@ public void runCommand(String baseUrl, String root, String credentials) throws I + "] must point to a particular collection but appears to be a Solr base URL"); } - Http2SolrClient.Builder builder = - new Http2SolrClient.Builder(URLUtil.extractBaseUrl(baseUrl)) + var builder = + new HttpJettySolrClient.Builder(URLUtil.extractBaseUrl(baseUrl)) .withDefaultCollection(URLUtil.extractCoreFromCoreUrl(baseUrl)) .withKeyStoreReloadInterval(-1, TimeUnit.SECONDS) .withOptionalBasicAuthCredentials(credentials); diff --git a/solr/core/src/java/org/apache/solr/cli/RunExampleTool.java b/solr/core/src/java/org/apache/solr/cli/RunExampleTool.java index aecc0676ebb..9fcd71c911d 100644 --- a/solr/core/src/java/org/apache/solr/cli/RunExampleTool.java +++ b/solr/core/src/java/org/apache/solr/cli/RunExampleTool.java @@ -44,7 +44,6 @@ import org.apache.commons.exec.environment.EnvironmentUtils; import org.apache.commons.io.file.PathUtils; import org.apache.solr.client.solrj.SolrClient; -import org.apache.solr.client.solrj.impl.CloudHttp2SolrClient; import org.apache.solr.client.solrj.impl.CloudSolrClient; import org.apache.solr.common.SolrException; import org.apache.solr.common.util.EnvUtils; @@ -635,8 +634,7 @@ protected void runCloudExample(CommandLine cli) throws Exception { /** wait until the number of live nodes == numNodes. */ protected void waitToSeeLiveNodes(String zkHost, int numNodes) { try (CloudSolrClient cloudClient = - new CloudHttp2SolrClient.Builder(Collections.singletonList(zkHost), Optional.empty()) - .build()) { + new CloudSolrClient.Builder(Collections.singletonList(zkHost), Optional.empty()).build()) { cloudClient.connect(); Set liveNodes = cloudClient.getClusterState().getLiveNodes(); int numLiveNodes = (liveNodes != null) ? liveNodes.size() : 0; diff --git a/solr/core/src/java/org/apache/solr/cloud/RecoveryStrategy.java b/solr/core/src/java/org/apache/solr/cloud/RecoveryStrategy.java index 4ab9713d017..0b8c2a744da 100644 --- a/solr/core/src/java/org/apache/solr/cloud/RecoveryStrategy.java +++ b/solr/core/src/java/org/apache/solr/cloud/RecoveryStrategy.java @@ -32,7 +32,7 @@ import org.apache.lucene.store.Directory; import org.apache.solr.client.solrj.SolrClient; import org.apache.solr.client.solrj.SolrServerException; -import org.apache.solr.client.solrj.impl.Http2SolrClient; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.client.solrj.request.AbstractUpdateRequest; import org.apache.solr.client.solrj.request.CoreAdminRequest.WaitForState; import org.apache.solr.client.solrj.request.UpdateRequest; @@ -177,9 +177,10 @@ public final void setRecoveringAfterStartup(boolean recoveringAfterStartup) { this.recoveringAfterStartup = recoveringAfterStartup; } - private Http2SolrClient.Builder recoverySolrClientBuilder(String baseUrl, String leaderCoreName) { + private HttpJettySolrClient.Builder recoverySolrClientBuilder( + String baseUrl, String leaderCoreName) { final UpdateShardHandlerConfig cfg = cc.getConfig().getUpdateShardHandlerConfig(); - return new Http2SolrClient.Builder(baseUrl) + return new HttpJettySolrClient.Builder(baseUrl) .withDefaultCollection(leaderCoreName) .withHttpClient(cc.getUpdateShardHandler().getRecoveryOnlyHttpClient()); } diff --git a/solr/core/src/java/org/apache/solr/cloud/SyncStrategy.java b/solr/core/src/java/org/apache/solr/cloud/SyncStrategy.java index a686743f6b5..1b2789cb3a0 100644 --- a/solr/core/src/java/org/apache/solr/cloud/SyncStrategy.java +++ b/solr/core/src/java/org/apache/solr/cloud/SyncStrategy.java @@ -26,7 +26,7 @@ import java.util.concurrent.TimeUnit; import org.apache.solr.client.solrj.SolrClient; import org.apache.solr.client.solrj.SolrServerException; -import org.apache.solr.client.solrj.impl.Http2SolrClient; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.client.solrj.request.CoreAdminRequest.RequestRecovery; import org.apache.solr.common.cloud.ZkCoreNodeProps; import org.apache.solr.common.cloud.ZkNodeProps; @@ -53,7 +53,7 @@ public class SyncStrategy { private volatile boolean isClosed; - private final Http2SolrClient solrClient; + private final HttpJettySolrClient solrClient; private final ExecutorService updateExecutor; @@ -358,7 +358,7 @@ private void requestRecovery( recoverRequestCmd.setAction(CoreAdminAction.REQUESTRECOVERY); recoverRequestCmd.setCoreName(coreName); try (SolrClient client = - new Http2SolrClient.Builder(baseUrl) + new HttpJettySolrClient.Builder(baseUrl) .withHttpClient(solrClient) .withIdleTimeout(120000, TimeUnit.MILLISECONDS) .build()) { diff --git a/solr/core/src/java/org/apache/solr/cloud/ZkController.java b/solr/core/src/java/org/apache/solr/cloud/ZkController.java index e0ed4912a83..d57c5cb1d99 100644 --- a/solr/core/src/java/org/apache/solr/cloud/ZkController.java +++ b/solr/core/src/java/org/apache/solr/cloud/ZkController.java @@ -61,12 +61,12 @@ import org.apache.solr.client.api.util.SolrVersion; import org.apache.solr.client.solrj.SolrClient; import org.apache.solr.client.solrj.cloud.SolrCloudManager; -import org.apache.solr.client.solrj.impl.CloudHttp2SolrClient; import org.apache.solr.client.solrj.impl.CloudSolrClient; -import org.apache.solr.client.solrj.impl.Http2SolrClient; import org.apache.solr.client.solrj.impl.SolrClientCloudManager; import org.apache.solr.client.solrj.impl.SolrZkClientTimeout; import org.apache.solr.client.solrj.impl.ZkClientClusterStateProvider; +import org.apache.solr.client.solrj.jetty.CloudJettySolrClient; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.client.solrj.request.CoreAdminRequest.WaitForState; import org.apache.solr.cloud.api.collections.DistributedCollectionConfigSetCommandRunner; import org.apache.solr.cloud.overseer.ClusterStateMutator; @@ -207,7 +207,7 @@ public String toString() { public final ZkStateReader zkStateReader; private SolrCloudManager cloudManager; - private CloudHttp2SolrClient cloudSolrClient; + private CloudSolrClient cloudSolrClient; private final ExecutorService zkConnectionListenerCallbackExecutor = ExecutorUtil.newMDCAwareSingleThreadExecutor( @@ -963,7 +963,7 @@ public SolrCloudManager getSolrCloudManager() { return cloudManager; } cloudSolrClient = - new CloudHttp2SolrClient.Builder(new ZkClientClusterStateProvider(zkStateReader)) + new CloudJettySolrClient.Builder(new ZkClientClusterStateProvider(zkStateReader)) .withHttpClient(cc.getDefaultHttpSolrClient()) .build(); cloudManager = new SolrClientCloudManager(cloudSolrClient, cc.getObjectCache()); @@ -2320,7 +2320,7 @@ private ZkCoreNodeProps waitForLeaderToSeeDownState( // TODO ideally want 8sec connection timeout but can't easily also share the client // listeners try (SolrClient client = - new Http2SolrClient.Builder(leaderBaseUrl) + new HttpJettySolrClient.Builder(leaderBaseUrl) .withHttpClient(getCoreContainer().getDefaultHttpSolrClient()) .withIdleTimeout(30000, TimeUnit.MILLISECONDS) .build()) { diff --git a/solr/core/src/java/org/apache/solr/cloud/api/collections/CollectionHandlingUtils.java b/solr/core/src/java/org/apache/solr/cloud/api/collections/CollectionHandlingUtils.java index 22f3618d111..85440f4b650 100644 --- a/solr/core/src/java/org/apache/solr/cloud/api/collections/CollectionHandlingUtils.java +++ b/solr/core/src/java/org/apache/solr/cloud/api/collections/CollectionHandlingUtils.java @@ -39,7 +39,7 @@ import org.apache.solr.client.solrj.SolrClient; import org.apache.solr.client.solrj.SolrResponse; import org.apache.solr.client.solrj.SolrServerException; -import org.apache.solr.client.solrj.impl.Http2SolrClient; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.client.solrj.request.AbstractUpdateRequest; import org.apache.solr.client.solrj.request.UpdateRequest; import org.apache.solr.client.solrj.response.UpdateResponse; @@ -219,7 +219,7 @@ static void checkResults(String label, NamedList results, boolean failur } static void commit( - Http2SolrClient solrClient, + HttpJettySolrClient solrClient, NamedList results, String slice, Replica parentShardLeader) { @@ -244,7 +244,7 @@ static void commit( } private static UpdateResponse softCommit( - Http2SolrClient solrClient, String baseUrl, String coreName) + HttpJettySolrClient solrClient, String baseUrl, String coreName) throws SolrServerException, IOException { UpdateRequest ureq = new UpdateRequest(); ureq.setAction(AbstractUpdateRequest.ACTION.COMMIT, false, true, true); 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 be631383c6b..42f8bd2ec7e 100644 --- a/solr/core/src/java/org/apache/solr/core/CoreContainer.java +++ b/solr/core/src/java/org/apache/solr/core/CoreContainer.java @@ -69,9 +69,9 @@ import org.apache.solr.api.ContainerPluginsRegistry; import org.apache.solr.api.JerseyResource; import org.apache.solr.client.solrj.SolrRequest; -import org.apache.solr.client.solrj.impl.Http2SolrClient; import org.apache.solr.client.solrj.impl.HttpSolrClientBase; import org.apache.solr.client.solrj.io.SolrClientCache; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.client.solrj.util.SolrIdentifierValidator; import org.apache.solr.cloud.CloudDescriptor; import org.apache.solr.cloud.ClusterSingleton; @@ -2389,10 +2389,10 @@ public PlacementPluginFactory getPlacementPlugi * *

The caller does not need to close the client. * - * @return the existing {@link Http2SolrClient} + * @return the existing {@link HttpJettySolrClient} * @see HttpSolrClientBase#requestWithBaseUrl(String, SolrRequest, String) */ - public Http2SolrClient getDefaultHttpSolrClient() { + public HttpJettySolrClient getDefaultHttpSolrClient() { return solrClientProvider.getSolrClient(); } diff --git a/solr/core/src/java/org/apache/solr/core/HttpSolrClientProvider.java b/solr/core/src/java/org/apache/solr/core/HttpSolrClientProvider.java index a8c27f27ffa..8168ac420bc 100644 --- a/solr/core/src/java/org/apache/solr/core/HttpSolrClientProvider.java +++ b/solr/core/src/java/org/apache/solr/core/HttpSolrClientProvider.java @@ -18,7 +18,7 @@ import io.opentelemetry.api.common.Attributes; import java.util.concurrent.TimeUnit; -import org.apache.solr.client.solrj.impl.Http2SolrClient; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.common.util.IOUtils; import org.apache.solr.metrics.SolrMetricsContext; import org.apache.solr.security.HttpClientBuilderPlugin; @@ -34,7 +34,7 @@ final class HttpSolrClientProvider implements AutoCloseable { static final String METRIC_SCOPE_NAME = "defaultHttpSolrClientProvider"; - private final Http2SolrClient httpSolrClient; + private final HttpJettySolrClient httpSolrClient; private final InstrumentedHttpListenerFactory trackHttpSolrMetrics; @@ -42,8 +42,8 @@ final class HttpSolrClientProvider implements AutoCloseable { trackHttpSolrMetrics = new InstrumentedHttpListenerFactory(getNameStrategy(cfg)); initializeMetrics(parentContext); - Http2SolrClient.Builder httpClientBuilder = - new Http2SolrClient.Builder().addListenerFactory(trackHttpSolrMetrics); + var httpClientBuilder = + new HttpJettySolrClient.Builder().addListenerFactory(trackHttpSolrMetrics); if (cfg != null) { httpClientBuilder @@ -68,7 +68,7 @@ private void initializeMetrics(SolrMetricsContext parentContext) { trackHttpSolrMetrics.initializeMetrics(solrMetricsContext, Attributes.empty()); } - Http2SolrClient getSolrClient() { + HttpJettySolrClient getSolrClient() { return httpSolrClient; } 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 430fad38971..dc496f3084b 100644 --- a/solr/core/src/java/org/apache/solr/handler/IndexFetcher.java +++ b/solr/core/src/java/org/apache/solr/handler/IndexFetcher.java @@ -91,9 +91,9 @@ import org.apache.solr.client.api.model.FileMetaData; import org.apache.solr.client.solrj.SolrRequest; import org.apache.solr.client.solrj.SolrServerException; -import org.apache.solr.client.solrj.impl.Http2SolrClient; import org.apache.solr.client.solrj.impl.InputStreamResponseParser; import org.apache.solr.client.solrj.impl.SolrHttpConstants; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.client.solrj.request.GenericSolrRequest; import org.apache.solr.cloud.CloudDescriptor; import org.apache.solr.cloud.ZkController; @@ -179,7 +179,7 @@ public class IndexFetcher { boolean fetchFromLeader = false; - private final Http2SolrClient solrClient; + private final HttpJettySolrClient solrClient; private Integer soTimeout; @@ -251,10 +251,10 @@ public String getMessage() { // It's crucial not to remove the authentication credentials as they are essential for User // managed replication. // GitHub PR #2276 - private Http2SolrClient createSolrClient( + private HttpJettySolrClient createSolrClient( SolrCore core, String httpBasicAuthUser, String httpBasicAuthPassword, String leaderBaseUrl) { final UpdateShardHandler updateShardHandler = core.getCoreContainer().getUpdateShardHandler(); - return new Http2SolrClient.Builder(leaderBaseUrl) + return new HttpJettySolrClient.Builder(leaderBaseUrl) .withHttpClient(updateShardHandler.getRecoveryOnlyHttpClient()) .withBasicAuthCredentials(httpBasicAuthUser, httpBasicAuthPassword) .withIdleTimeout(soTimeout, TimeUnit.MILLISECONDS) diff --git a/solr/core/src/java/org/apache/solr/handler/SolrConfigHandler.java b/solr/core/src/java/org/apache/solr/handler/SolrConfigHandler.java index b22626f3339..bbaf39b1931 100644 --- a/solr/core/src/java/org/apache/solr/handler/SolrConfigHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/SolrConfigHandler.java @@ -55,8 +55,8 @@ import org.apache.solr.api.Api; import org.apache.solr.api.ApiBag; import org.apache.solr.client.solrj.SolrResponse; -import org.apache.solr.client.solrj.impl.Http2SolrClient; import org.apache.solr.client.solrj.io.stream.expr.Expressible; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.client.solrj.request.CollectionRequiringSolrRequest; import org.apache.solr.client.solrj.response.SimpleSolrResponse; import org.apache.solr.cloud.ZkController; @@ -844,10 +844,10 @@ private static void waitForAllReplicasState( // course) List concurrentTasks = new ArrayList<>(); - var http2SolrClient = zkController.getCoreContainer().getDefaultHttpSolrClient(); + var httpSolrClient = zkController.getCoreContainer().getDefaultHttpSolrClient(); for (Replica replica : getActiveReplicas(zkController, collection)) { PerReplicaCallable e = - new PerReplicaCallable(http2SolrClient, replica, prop, expectedVersion, maxWaitSecs); + new PerReplicaCallable(httpSolrClient, replica, prop, expectedVersion, maxWaitSecs); concurrentTasks.add(e); } if (concurrentTasks.isEmpty()) return; // nothing to wait for ... @@ -963,7 +963,7 @@ public Name getPermissionName(AuthorizationContext ctx) { private static class PerReplicaCallable extends CollectionRequiringSolrRequest implements Callable { - private final Http2SolrClient solrClient; + private final HttpJettySolrClient solrClient; Replica replica; String prop; int expectedZkVersion; @@ -971,7 +971,7 @@ private static class PerReplicaCallable extends CollectionRequiringSolrRequest solrClients = new HashMap<>(); private List errors = Collections.synchronizedList(new ArrayList<>()); @@ -114,7 +114,7 @@ private String getFullUrl(String url) { return fullUrl; } - public Http2SolrClient getHttpClient() { + public HttpJettySolrClient getHttpClient() { return httpClient; } @@ -168,7 +168,7 @@ static class Builder extends ConcurrentUpdateJettySolrClient.Builder { */ public Builder( String baseSolrUrl, - Http2SolrClient client, + HttpJettySolrClient client, SolrCmdDistributor.Req req, List errors) { super(baseSolrUrl, client); 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 8410de18ffa..8abb54c066d 100644 --- a/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java +++ b/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java @@ -24,8 +24,8 @@ import java.util.concurrent.SynchronousQueue; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; -import org.apache.solr.client.solrj.impl.Http2SolrClient; import org.apache.solr.client.solrj.impl.SolrHttpConstants; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.common.SolrException; import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.util.ExecutorUtil; @@ -64,9 +64,9 @@ public class UpdateShardHandler implements SolrInfoBean { private ExecutorService recoveryExecutor; - private final Http2SolrClient updateOnlyClient; + private final HttpJettySolrClient updateOnlyClient; - private final Http2SolrClient recoveryOnlyClient; + private final HttpJettySolrClient recoveryOnlyClient; private final InstrumentedHttpListenerFactory trackHttpSolrMetrics; @@ -99,8 +99,8 @@ public UpdateShardHandler(UpdateShardHandlerConfig cfg) { Set.of( DistributedUpdateProcessor.DISTRIB_FROM, DistributingUpdateProcessorFactory.DISTRIB_UPDATE_PARAM); - Http2SolrClient.Builder updateOnlyClientBuilder = new Http2SolrClient.Builder(); - Http2SolrClient.Builder recoveryOnlyClientBuilder = new Http2SolrClient.Builder(); + var updateOnlyClientBuilder = new HttpJettySolrClient.Builder(); + var recoveryOnlyClientBuilder = new HttpJettySolrClient.Builder(); if (cfg != null) { updateOnlyClientBuilder .addListenerFactory(trackHttpSolrMetrics) @@ -189,12 +189,12 @@ public SolrMetricsContext getSolrMetricsContext() { } // don't introduce a bug, this client is for sending updates only! - public Http2SolrClient getUpdateOnlyHttpClient() { + public HttpJettySolrClient getUpdateOnlyHttpClient() { return updateOnlyClient; } // don't introduce a bug, this client is for recovery ops only! - public Http2SolrClient getRecoveryOnlyHttpClient() { + public HttpJettySolrClient getRecoveryOnlyHttpClient() { return recoveryOnlyClient; } diff --git a/solr/core/src/java/org/apache/solr/util/stats/InstrumentedHttpListenerFactory.java b/solr/core/src/java/org/apache/solr/util/stats/InstrumentedHttpListenerFactory.java index e31e02b85d2..9f38d8845da 100644 --- a/solr/core/src/java/org/apache/solr/util/stats/InstrumentedHttpListenerFactory.java +++ b/solr/core/src/java/org/apache/solr/util/stats/InstrumentedHttpListenerFactory.java @@ -23,7 +23,7 @@ import io.opentelemetry.api.trace.Span; import java.util.Locale; import java.util.Map; -import org.apache.solr.client.solrj.impl.HttpListenerFactory; +import org.apache.solr.client.solrj.jetty.HttpListenerFactory; import org.apache.solr.common.SolrException; import org.apache.solr.common.util.CollectionUtil; import org.apache.solr.metrics.SolrMetricProducer; diff --git a/solr/core/src/test/org/apache/solr/cli/TestExportTool.java b/solr/core/src/test/org/apache/solr/cli/TestExportTool.java index d356c439849..13ad5859e3d 100644 --- a/solr/core/src/test/org/apache/solr/cli/TestExportTool.java +++ b/solr/core/src/test/org/apache/solr/cli/TestExportTool.java @@ -34,7 +34,7 @@ import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.client.solrj.SolrClient; import org.apache.solr.client.solrj.SolrQuery; -import org.apache.solr.client.solrj.impl.Http2SolrClient; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.client.solrj.request.AbstractUpdateRequest; import org.apache.solr.client.solrj.request.CollectionAdminRequest; import org.apache.solr.client.solrj.request.JavaBinUpdateRequestCodec; @@ -216,7 +216,7 @@ public void testVeryLargeCluster() throws Exception { long totalDocsFromCores = 0; for (Slice slice : coll.getSlices()) { Replica replica = slice.getLeader(); - try (SolrClient client = new Http2SolrClient.Builder(replica.getBaseUrl()).build()) { + try (SolrClient client = new HttpJettySolrClient.Builder(replica.getBaseUrl()).build()) { long count = ExportTool.getDocCount(replica.getCoreName(), client, "*:*"); docCounts.put(replica.getCoreName(), count); totalDocsFromCores += count; diff --git a/solr/core/src/test/org/apache/solr/cloud/OverseerTest.java b/solr/core/src/test/org/apache/solr/cloud/OverseerTest.java index d7680eaff7d..b1aaf9e457b 100644 --- a/solr/core/src/test/org/apache/solr/cloud/OverseerTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/OverseerTest.java @@ -50,10 +50,10 @@ import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.client.solrj.SolrClient; import org.apache.solr.client.solrj.cloud.SolrCloudManager; -import org.apache.solr.client.solrj.impl.CloudHttp2SolrClient; -import org.apache.solr.client.solrj.impl.Http2SolrClient; +import org.apache.solr.client.solrj.impl.CloudSolrClient; import org.apache.solr.client.solrj.impl.SolrClientCloudManager; import org.apache.solr.client.solrj.impl.ZkClientClusterStateProvider; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.cloud.overseer.NodeMutator; import org.apache.solr.cloud.overseer.OverseerAction; import org.apache.solr.cloud.overseer.ZkWriteCommand; @@ -1826,12 +1826,12 @@ public Void answer(InvocationOnMock invocation) { private SolrCloudManager getCloudDataProvider(ZkStateReader zkStateReader) { var httpSolrClient = - new Http2SolrClient.Builder() + new HttpJettySolrClient.Builder() .withIdleTimeout(30000, TimeUnit.MILLISECONDS) .withConnectionTimeout(15000, TimeUnit.MILLISECONDS) .build(); var cloudSolrClient = - new CloudHttp2SolrClient.Builder(new ZkClientClusterStateProvider(zkStateReader)) + new CloudSolrClient.Builder(new ZkClientClusterStateProvider(zkStateReader)) .withHttpClient(httpSolrClient) .build(); solrClients.add(cloudSolrClient); diff --git a/solr/core/src/test/org/apache/solr/cloud/RecoveryZkTestWithAuth.java b/solr/core/src/test/org/apache/solr/cloud/RecoveryZkTestWithAuth.java index 77c910a8da2..688543c8487 100644 --- a/solr/core/src/test/org/apache/solr/cloud/RecoveryZkTestWithAuth.java +++ b/solr/core/src/test/org/apache/solr/cloud/RecoveryZkTestWithAuth.java @@ -29,6 +29,7 @@ import org.apache.solr.client.solrj.apache.CloudLegacySolrClient; import org.apache.solr.client.solrj.apache.HttpSolrClient; import org.apache.solr.client.solrj.impl.SolrHttpConstants; +import org.apache.solr.client.solrj.jetty.PreemptiveBasicAuthClientBuilderFactory; import org.apache.solr.client.solrj.request.CollectionAdminRequest; import org.apache.solr.client.solrj.request.QueryRequest; import org.apache.solr.client.solrj.request.UpdateRequest; @@ -49,7 +50,7 @@ public static void setupCluster() throws Exception { if (rarely()) { System.setProperty( SolrHttpConstants.SYS_PROP_HTTP_CLIENT_BUILDER_FACTORY, - "org.apache.solr.client.solrj.impl.PreemptiveBasicAuthClientBuilderFactory"); + PreemptiveBasicAuthClientBuilderFactory.class.getName()); System.setProperty("solr.security.auth.basicauth.credentials", SecurityJson.USER_PASS); } diff --git a/solr/core/src/test/org/apache/solr/cloud/TestMiniSolrCloudClusterSSL.java b/solr/core/src/test/org/apache/solr/cloud/TestMiniSolrCloudClusterSSL.java index c82864b7f6f..457429a21ac 100644 --- a/solr/core/src/test/org/apache/solr/cloud/TestMiniSolrCloudClusterSSL.java +++ b/solr/core/src/test/org/apache/solr/cloud/TestMiniSolrCloudClusterSSL.java @@ -38,8 +38,8 @@ import org.apache.solr.client.solrj.apache.HttpClientUtil; import org.apache.solr.client.solrj.apache.HttpSolrClient; import org.apache.solr.client.solrj.impl.CloudSolrClient; -import org.apache.solr.client.solrj.impl.Http2SolrClient; import org.apache.solr.client.solrj.impl.SolrHttpConstants; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.client.solrj.request.CollectionAdminRequest; import org.apache.solr.client.solrj.request.CoreAdminRequest; import org.apache.solr.common.cloud.ZkStateReader; @@ -90,14 +90,14 @@ public void before() { log.info( "NOTE: This Test ignores the randomized SSL & clientAuth settings selected by base class"); HttpClientUtil.resetHttpClientBuilder(); // also resets SocketFactoryRegistryProvider - Http2SolrClient.resetSslContextFactory(); + HttpJettySolrClient.resetSslContextFactory(); System.clearProperty(ZkStateReader.URL_SCHEME); } @After public void after() { HttpClientUtil.resetHttpClientBuilder(); // also resets SocketFactoryRegistryProvider - Http2SolrClient.resetSslContextFactory(); + HttpJettySolrClient.resetSslContextFactory(); System.clearProperty(ZkStateReader.URL_SCHEME); SSLContext.setDefault(DEFAULT_SSL_CONTEXT); } @@ -106,7 +106,7 @@ public void testNoSsl() throws Exception { final SSLTestConfig sslConfig = new SSLTestConfig(false, false); HttpClientUtil.setSocketFactoryRegistryProvider( sslConfig.buildClientSocketFactoryRegistryProvider()); // must be reset - Http2SolrClient.setDefaultSSLConfig(sslConfig.buildClientSSLConfig()); // must be reset + HttpJettySolrClient.setDefaultSSLConfig(sslConfig.buildClientSSLConfig()); // must be reset System.setProperty(ZkStateReader.URL_SCHEME, "http"); checkClusterWithNodeReplacement(sslConfig); } @@ -118,7 +118,7 @@ public void testNoSslButSillyClientAuth() throws Exception { final SSLTestConfig sslConfig = new SSLTestConfig(false, true); HttpClientUtil.setSocketFactoryRegistryProvider( sslConfig.buildClientSocketFactoryRegistryProvider()); - Http2SolrClient.setDefaultSSLConfig(sslConfig.buildClientSSLConfig()); + HttpJettySolrClient.setDefaultSSLConfig(sslConfig.buildClientSSLConfig()); System.setProperty(ZkStateReader.URL_SCHEME, "http"); checkClusterWithNodeReplacement(sslConfig); } @@ -127,7 +127,7 @@ public void testSslAndNoClientAuth() throws Exception { final SSLTestConfig sslConfig = new SSLTestConfig(true, false); HttpClientUtil.setSocketFactoryRegistryProvider( sslConfig.buildClientSocketFactoryRegistryProvider()); - Http2SolrClient.setDefaultSSLConfig(sslConfig.buildClientSSLConfig()); + HttpJettySolrClient.setDefaultSSLConfig(sslConfig.buildClientSSLConfig()); System.setProperty(ZkStateReader.URL_SCHEME, "https"); checkClusterWithNodeReplacement(sslConfig); } @@ -139,7 +139,7 @@ public void testSslAndClientAuth() throws Exception { HttpClientUtil.setSocketFactoryRegistryProvider( sslConfig.buildClientSocketFactoryRegistryProvider()); - Http2SolrClient.setDefaultSSLConfig(sslConfig.buildClientSSLConfig()); + HttpJettySolrClient.setDefaultSSLConfig(sslConfig.buildClientSSLConfig()); System.setProperty(ZkStateReader.URL_SCHEME, "https"); checkClusterWithNodeReplacement(sslConfig); } @@ -148,7 +148,7 @@ public void testSslWithCheckPeerName() throws Exception { final SSLTestConfig sslConfig = new SSLTestConfig(true, false, true); HttpClientUtil.setSocketFactoryRegistryProvider( sslConfig.buildClientSocketFactoryRegistryProvider()); - Http2SolrClient.setDefaultSSLConfig(sslConfig.buildClientSSLConfig()); + HttpJettySolrClient.setDefaultSSLConfig(sslConfig.buildClientSSLConfig()); System.setProperty(ZkStateReader.URL_SCHEME, "https"); checkClusterWithNodeReplacement(sslConfig); } @@ -181,7 +181,7 @@ private void checkClusterWithNodeReplacement(SSLTestConfig sslConfig) throws Exc SolrHttpConstants.SYS_PROP_CHECK_PEER_NAME, Boolean.toString(sslConfig.getCheckPeerName())); HttpClientUtil.resetHttpClientBuilder(); - Http2SolrClient.resetSslContextFactory(); + HttpJettySolrClient.resetSslContextFactory(); // recheck that we can communicate with all the jetty instances in our cluster checkClusterJettys(cluster, sslConfig); @@ -197,7 +197,7 @@ public void testSslWithInvalidPeerName() throws Exception { final SSLTestConfig sslConfig = new SSLTestConfig(true, false, false); HttpClientUtil.setSocketFactoryRegistryProvider( sslConfig.buildClientSocketFactoryRegistryProvider()); - Http2SolrClient.setDefaultSSLConfig(sslConfig.buildClientSSLConfig()); + HttpJettySolrClient.setDefaultSSLConfig(sslConfig.buildClientSSLConfig()); System.setProperty(ZkStateReader.URL_SCHEME, "https"); final JettyConfig config = JettyConfig.builder().withSSLConfig(sslConfig.buildServerSSLConfig()).build(); @@ -210,7 +210,7 @@ public void testSslWithInvalidPeerName() throws Exception { // our existing certificate, but *does* care about validating the peer name System.setProperty(SolrHttpConstants.SYS_PROP_CHECK_PEER_NAME, "true"); HttpClientUtil.resetHttpClientBuilder(); - Http2SolrClient.resetSslContextFactory(); + HttpJettySolrClient.resetSslContextFactory(); // and validate we get failures when trying to talk to our cluster... final List jettys = cluster.getJettySolrRunners(); @@ -432,7 +432,7 @@ public static SolrClient getRandomizedHttpSolrClient(String url) { // ... so we are hopefully future proofing against possible changes to // SolrTestCaseJ4.getHttpSolrClient that "optimize" the test client construction in a way that // would prevent us from finding bugs with regular HttpSolrClient instantiation. - // This test fails if you return a Http2SolrClient + // This test fails if you return a HttpJettySolrClient if (random().nextBoolean()) { return (new HttpSolrClient.Builder(url)).build(); } // else... diff --git a/solr/core/src/test/org/apache/solr/cloud/TestQueryingOnDownCollection.java b/solr/core/src/test/org/apache/solr/cloud/TestQueryingOnDownCollection.java index 6254d3d2917..cc353b3ff60 100644 --- a/solr/core/src/test/org/apache/solr/cloud/TestQueryingOnDownCollection.java +++ b/solr/core/src/test/org/apache/solr/cloud/TestQueryingOnDownCollection.java @@ -21,7 +21,7 @@ import org.apache.solr.client.solrj.SolrClient; import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.SolrRequest; -import org.apache.solr.client.solrj.impl.Http2SolrClient; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.client.solrj.request.CollectionAdminRequest; import org.apache.solr.client.solrj.request.QueryRequest; import org.apache.solr.client.solrj.request.UpdateRequest; @@ -103,7 +103,7 @@ public void testQueryToDownCollectionShouldFailFast() throws Exception { // run same set of tests on v2 client which uses V2HttpCall try (SolrClient v2Client = - new Http2SolrClient.Builder(cluster.getJettySolrRunner(0).getBaseUrl().toString()) + new HttpJettySolrClient.Builder(cluster.getJettySolrRunner(0).getBaseUrl().toString()) .build()) { SolrException error = 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 9eab3a3cafe..7b5840efc64 100644 --- a/solr/core/src/test/org/apache/solr/cloud/ZkControllerTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/ZkControllerTest.java @@ -39,7 +39,7 @@ import java.util.concurrent.atomic.AtomicReference; import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.client.api.util.SolrVersion; -import org.apache.solr.client.solrj.impl.Http2SolrClient; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.common.MapWriter; import org.apache.solr.common.SolrException; import org.apache.solr.common.cloud.ClusterProperties; @@ -784,7 +784,7 @@ public void tearDown() throws Exception { private static class MockCoreContainer extends CoreContainer { UpdateShardHandler updateShardHandler = new UpdateShardHandler(UpdateShardHandlerConfig.DEFAULT); - Http2SolrClient solrClient; + HttpJettySolrClient solrClient; public MockCoreContainer() { super(SolrXmlConfig.fromString(TEST_PATH(), "")); @@ -793,7 +793,7 @@ public MockCoreContainer() { this.shardHandlerFactory = httpShardHandlerFactory; this.coreAdminHandler = new CoreAdminHandler(); this.metricManager = mock(SolrMetricManager.class); - this.solrClient = new Http2SolrClient.Builder().build(); + this.solrClient = new HttpJettySolrClient.Builder().build(); } @Override @@ -812,7 +812,7 @@ public void shutdown() { } @Override - public Http2SolrClient getDefaultHttpSolrClient() { + public HttpJettySolrClient getDefaultHttpSolrClient() { return solrClient; } diff --git a/solr/core/src/test/org/apache/solr/core/snapshots/TestSolrCoreSnapshots.java b/solr/core/src/test/org/apache/solr/core/snapshots/TestSolrCoreSnapshots.java index 478a67aa479..3ee972c063b 100644 --- a/solr/core/src/test/org/apache/solr/core/snapshots/TestSolrCoreSnapshots.java +++ b/solr/core/src/test/org/apache/solr/core/snapshots/TestSolrCoreSnapshots.java @@ -34,7 +34,7 @@ import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.client.solrj.SolrClient; import org.apache.solr.client.solrj.impl.CloudSolrClient; -import org.apache.solr.client.solrj.impl.Http2SolrClient; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.client.solrj.request.CollectionAdminRequest; import org.apache.solr.client.solrj.request.CoreAdminRequest.CreateSnapshot; import org.apache.solr.client.solrj.request.CoreAdminRequest.DeleteSnapshot; @@ -110,7 +110,7 @@ public void testBackupRestore() throws Exception { try (SolrClient adminClient = getHttpSolrClient(cluster.getJettySolrRunners().get(0).getBaseUrl().toString()); SolrClient leaderClient = - new Http2SolrClient.Builder(replica.getBaseUrl()) + new HttpJettySolrClient.Builder(replica.getBaseUrl()) .withDefaultCollection(replica.getCoreName()) .build()) { @@ -204,7 +204,7 @@ public void testIndexOptimization() throws Exception { try (SolrClient adminClient = getHttpSolrClient(cluster.getJettySolrRunners().get(0).getBaseUrl().toString()); SolrClient leaderClient = - new Http2SolrClient.Builder(replica.getBaseUrl()) + new HttpJettySolrClient.Builder(replica.getBaseUrl()) .withDefaultCollection(replica.getCoreName()) .build()) { diff --git a/solr/core/src/test/org/apache/solr/handler/ReplicationTestHelper.java b/solr/core/src/test/org/apache/solr/handler/ReplicationTestHelper.java index 1127bbb48be..0a25972f7ac 100644 --- a/solr/core/src/test/org/apache/solr/handler/ReplicationTestHelper.java +++ b/solr/core/src/test/org/apache/solr/handler/ReplicationTestHelper.java @@ -37,7 +37,7 @@ import org.apache.solr.client.solrj.SolrRequest; import org.apache.solr.client.solrj.SolrRequest.SolrRequestType; import org.apache.solr.client.solrj.SolrServerException; -import org.apache.solr.client.solrj.impl.Http2SolrClient; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.client.solrj.request.GenericSolrRequest; import org.apache.solr.client.solrj.response.QueryResponse; import org.apache.solr.common.SolrDocumentList; @@ -85,8 +85,8 @@ public static SolrClient createNewSolrClient(String baseUrl) { * @param baseUrl the root URL for a Solr node * @param collectionOrCore an optional default collection/core for the created client */ - public static Http2SolrClient createNewSolrClient(String baseUrl, String collectionOrCore) { - return new Http2SolrClient.Builder(baseUrl) + public static HttpJettySolrClient createNewSolrClient(String baseUrl, String collectionOrCore) { + return new HttpJettySolrClient.Builder(baseUrl) .withDefaultCollection(collectionOrCore) .withConnectionTimeout(15000, TimeUnit.MILLISECONDS) .withIdleTimeout(90000, TimeUnit.MILLISECONDS) diff --git a/solr/core/src/test/org/apache/solr/handler/TestHttpRequestId.java b/solr/core/src/test/org/apache/solr/handler/TestHttpRequestId.java index eedd23870bb..7865c74d954 100644 --- a/solr/core/src/test/org/apache/solr/handler/TestHttpRequestId.java +++ b/solr/core/src/test/org/apache/solr/handler/TestHttpRequestId.java @@ -27,7 +27,7 @@ import java.util.concurrent.TimeoutException; import org.apache.logging.log4j.core.LogEvent; import org.apache.solr.SolrJettyTestBase; -import org.apache.solr.client.solrj.impl.Http2SolrClient; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.client.solrj.request.SolrPing; import org.apache.solr.common.util.ExecutorUtil; import org.apache.solr.common.util.NamedList; @@ -39,7 +39,7 @@ import org.junit.Test; import org.slf4j.MDC; -@LogLevel("org.apache.solr.client.solrj.impl.Http2SolrClient=DEBUG") +@LogLevel("org.apache.solr.client.solrj.jetty.HttpJettySolrClient=DEBUG") public class TestHttpRequestId extends SolrJettyTestBase { @BeforeClass @@ -82,7 +82,7 @@ private void setupClientAndRun( final String value = "TestHttpRequestId" + System.nanoTime(); try (LogListener reqLog = - LogListener.debug(Http2SolrClient.class).substring("response processing")) { + LogListener.debug(HttpJettySolrClient.class).substring("response processing")) { // client setup needs to be same as HttpShardHandlerFactory ThreadPoolExecutor commExecutor = new ExecutorUtil.MDCAwareThreadPoolExecutor( @@ -94,8 +94,8 @@ private void setupClientAndRun( new SolrNamedThreadFactory("httpShardExecutor"), false); CompletableFuture> cf; - try (Http2SolrClient client = - new Http2SolrClient.Builder(getBaseUrl()) + try (var client = + new HttpJettySolrClient.Builder(getBaseUrl()) .withDefaultCollection(collection) .withExecutor(commExecutor) .build()) { diff --git a/solr/core/src/test/org/apache/solr/handler/TestUserManagedReplicationWithAuth.java b/solr/core/src/test/org/apache/solr/handler/TestUserManagedReplicationWithAuth.java index af7d03fec4c..a004ce614a2 100644 --- a/solr/core/src/test/org/apache/solr/handler/TestUserManagedReplicationWithAuth.java +++ b/solr/core/src/test/org/apache/solr/handler/TestUserManagedReplicationWithAuth.java @@ -33,7 +33,7 @@ import org.apache.solr.client.solrj.SolrRequest; import org.apache.solr.client.solrj.SolrResponse; import org.apache.solr.client.solrj.SolrServerException; -import org.apache.solr.client.solrj.impl.Http2SolrClient; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.client.solrj.request.HealthCheckRequest; import org.apache.solr.client.solrj.request.QueryRequest; import org.apache.solr.client.solrj.request.UpdateRequest; @@ -49,7 +49,7 @@ @SuppressSSL public class TestUserManagedReplicationWithAuth extends SolrTestCaseJ4 { JettySolrRunner leaderJetty, followerJetty, followerJettyWithAuth; - Http2SolrClient leaderClient, followerClient, followerClientWithAuth; + HttpJettySolrClient leaderClient, followerClient, followerClientWithAuth; ReplicationTestHelper.SolrInstance leader = null, follower = null, followerWithAuth = null; private static String user = "solr"; @@ -226,7 +226,7 @@ private QueryResponse queryWithBasicAuth(SolrClient client, SolrQuery q) return withBasicAuth(new QueryRequest(q)).process(client); } - private void disablePoll(JettySolrRunner Jetty, Http2SolrClient solrClient) + private void disablePoll(JettySolrRunner Jetty, HttpJettySolrClient solrClient) throws SolrServerException, IOException { ModifiableSolrParams disablePollParams = new ModifiableSolrParams(); disablePollParams.set(COMMAND, CMD_DISABLE_POLL); diff --git a/solr/core/src/test/org/apache/solr/packagemanager/TestPackageManager.java b/solr/core/src/test/org/apache/solr/packagemanager/TestPackageManager.java index 2d4892239f0..58089790229 100644 --- a/solr/core/src/test/org/apache/solr/packagemanager/TestPackageManager.java +++ b/solr/core/src/test/org/apache/solr/packagemanager/TestPackageManager.java @@ -24,7 +24,7 @@ import org.apache.solr.cli.CLITestHelper; import org.apache.solr.cli.ToolRuntime; import org.apache.solr.client.solrj.SolrClient; -import org.apache.solr.client.solrj.impl.Http2SolrClient; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.client.solrj.request.CollectionAdminRequest; import org.apache.solr.cloud.SolrCloudTestCase; import org.apache.solr.common.cloud.SolrZkClient; @@ -49,7 +49,7 @@ public void setUp() throws Exception { public void testWrongVerificationJPathIsThrown() throws IOException { SolrZkClient zkClient = cluster.getZkClient(); URL baseURLV2 = cluster.getJettySolrRunner(0).getBaseURLV2(); - try (Http2SolrClient solrClient = new Http2SolrClient.Builder(baseURLV2.toString()).build()) { + try (var solrClient = new HttpJettySolrClient.Builder(baseURLV2.toString()).build()) { ToolRuntime runtime = new CLITestHelper.TestingRuntime(false); try (PackageManager manager = new StubPackageManager(runtime, solrClient, zkClient)) { SolrPackage.Plugin plugin = new SolrPackage.Plugin(); diff --git a/solr/core/src/test/org/apache/solr/search/TestCoordinatorRole.java b/solr/core/src/test/org/apache/solr/search/TestCoordinatorRole.java index 65ff8220c6d..0d48114e045 100644 --- a/solr/core/src/test/org/apache/solr/search/TestCoordinatorRole.java +++ b/solr/core/src/test/org/apache/solr/search/TestCoordinatorRole.java @@ -39,7 +39,7 @@ import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.apache.HttpSolrClient; import org.apache.solr.client.solrj.impl.CloudSolrClient; -import org.apache.solr.client.solrj.impl.Http2SolrClient; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.client.solrj.request.CollectionAdminRequest; import org.apache.solr.client.solrj.request.QueryRequest; import org.apache.solr.client.solrj.request.UpdateRequest; @@ -466,7 +466,7 @@ private String getHostCoreName(String COLL, String qaNode, Consumer p CommonParams.JAVABIN); p.accept(q); SolrDocumentList docs = null; - try (SolrClient solrClient = new Http2SolrClient.Builder(qaNode).build()) { + try (SolrClient solrClient = new HttpJettySolrClient.Builder(qaNode).build()) { for (int i = 0; i < 100; i++) { try { QueryResponse queryResponse = solrClient.query(COLL, q); diff --git a/solr/core/src/test/org/apache/solr/security/AuthWithShardHandlerFactoryOverrideTest.java b/solr/core/src/test/org/apache/solr/security/AuthWithShardHandlerFactoryOverrideTest.java index eff43b40d22..b1dfedc3f78 100644 --- a/solr/core/src/test/org/apache/solr/security/AuthWithShardHandlerFactoryOverrideTest.java +++ b/solr/core/src/test/org/apache/solr/security/AuthWithShardHandlerFactoryOverrideTest.java @@ -18,7 +18,7 @@ import org.apache.solr.client.solrj.SolrClient; import org.apache.solr.client.solrj.SolrResponse; -import org.apache.solr.client.solrj.impl.Http2SolrClient; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.client.solrj.request.CollectionAdminRequest; import org.apache.solr.client.solrj.request.QueryRequest; import org.apache.solr.cloud.SolrCloudAuthTestCase; @@ -83,7 +83,7 @@ public void tearDown() throws Exception { @Test public void collectionTest() throws Exception { try (SolrClient client = - new Http2SolrClient.Builder(cluster.getJettySolrRunner(0).getBaseUrl().toString()) + new HttpJettySolrClient.Builder(cluster.getJettySolrRunner(0).getBaseUrl().toString()) .build()) { for (int i = 0; i < 30; i++) { @@ -103,7 +103,7 @@ public void collectionTest() throws Exception { @Test public void aliasTest() throws Exception { try (SolrClient client = - new Http2SolrClient.Builder(cluster.getJettySolrRunner(0).getBaseUrl().toString()) + new HttpJettySolrClient.Builder(cluster.getJettySolrRunner(0).getBaseUrl().toString()) .build()) { for (int i = 0; i < 30; i++) { diff --git a/solr/core/src/test/org/apache/solr/security/BasicAuthOnSingleNodeTest.java b/solr/core/src/test/org/apache/solr/security/BasicAuthOnSingleNodeTest.java index 8b6708fe825..183e6ba3235 100644 --- a/solr/core/src/test/org/apache/solr/security/BasicAuthOnSingleNodeTest.java +++ b/solr/core/src/test/org/apache/solr/security/BasicAuthOnSingleNodeTest.java @@ -18,7 +18,7 @@ package org.apache.solr.security; import org.apache.solr.client.solrj.SolrClient; -import org.apache.solr.client.solrj.impl.Http2SolrClient; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.client.solrj.request.CollectionAdminRequest; import org.apache.solr.client.solrj.request.QueryRequest; import org.apache.solr.cloud.SolrCloudAuthTestCase; @@ -52,7 +52,7 @@ public void tearDown() throws Exception { @Test public void basicTest() throws Exception { try (SolrClient client = - new Http2SolrClient.Builder(cluster.getJettySolrRunner(0).getBaseUrl().toString()) + new HttpJettySolrClient.Builder(cluster.getJettySolrRunner(0).getBaseUrl().toString()) .build()) { // SOLR-13510, this will be failed if the listener (handling inject credential in header) is @@ -69,7 +69,7 @@ public void basicTest() throws Exception { @Test public void testDeleteSecurityJsonZnode() throws Exception { try (SolrClient client = - new Http2SolrClient.Builder(cluster.getJettySolrRunner(0).getBaseUrl().toString()) + new HttpJettySolrClient.Builder(cluster.getJettySolrRunner(0).getBaseUrl().toString()) .build()) { try { new QueryRequest(params("q", "*:*")).process(client, COLLECTION); diff --git a/solr/core/src/test/org/apache/solr/util/tracing/TestSimplePropagatorDistributedTracing.java b/solr/core/src/test/org/apache/solr/util/tracing/TestSimplePropagatorDistributedTracing.java index e822352bc39..806040c755c 100644 --- a/solr/core/src/test/org/apache/solr/util/tracing/TestSimplePropagatorDistributedTracing.java +++ b/solr/core/src/test/org/apache/solr/util/tracing/TestSimplePropagatorDistributedTracing.java @@ -27,7 +27,6 @@ import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.apache.CloudLegacySolrClient; -import org.apache.solr.client.solrj.impl.CloudHttp2SolrClient; import org.apache.solr.client.solrj.impl.CloudSolrClient; import org.apache.solr.client.solrj.request.CollectionAdminRequest; import org.apache.solr.client.solrj.request.QueryRequest; @@ -88,7 +87,7 @@ public void testQueryRequest() throws IOException, SolrServerException { assertSameTraceId(reqLog, traceId); } - try (SolrClient testClient = newCloudHttp2SolrClient()) { + try (SolrClient testClient = newCloudSolrClient()) { // verify all query events have the same auto-generated trace id var r1 = testClient.query(COLLECTION, new SolrQuery("*:*")); assertEquals(0, r1.getStatus()); @@ -132,7 +131,7 @@ public void testUpdateRequest() throws IOException, SolrServerException { assertSameTraceId(reqLog, traceId); } - try (SolrClient testClient = newCloudHttp2SolrClient()) { + try (SolrClient testClient = newCloudSolrClient()) { // verify all indexing events have trace id present testClient.add(COLLECTION, sdoc("id", "2")); testClient.add(COLLECTION, sdoc("id", "4")); @@ -177,9 +176,9 @@ private CloudSolrClient newCloudLegacySolrClient() { .build(); } - private CloudHttp2SolrClient newCloudHttp2SolrClient() { + private CloudSolrClient newCloudSolrClient() { var builder = - new CloudHttp2SolrClient.Builder( + new CloudSolrClient.Builder( List.of(cluster.getZkServer().getZkAddress()), Optional.empty()); var client = builder.build(); client.connect(); diff --git a/solr/cross-dc-manager/src/java/org/apache/solr/crossdc/manager/consumer/KafkaCrossDcConsumer.java b/solr/cross-dc-manager/src/java/org/apache/solr/crossdc/manager/consumer/KafkaCrossDcConsumer.java index 7e6e9f1bd65..bf1ba691f26 100644 --- a/solr/cross-dc-manager/src/java/org/apache/solr/crossdc/manager/consumer/KafkaCrossDcConsumer.java +++ b/solr/cross-dc-manager/src/java/org/apache/solr/crossdc/manager/consumer/KafkaCrossDcConsumer.java @@ -43,7 +43,6 @@ import org.apache.kafka.common.serialization.StringDeserializer; import org.apache.solr.client.solrj.SolrRequest; import org.apache.solr.client.solrj.SolrResponse; -import org.apache.solr.client.solrj.impl.CloudHttp2SolrClient; import org.apache.solr.client.solrj.impl.CloudSolrClient; import org.apache.solr.client.solrj.request.UpdateRequest; import org.apache.solr.common.SolrInputDocument; @@ -122,7 +121,7 @@ public void close() { protected CloudSolrClient createSolrClient() { log.debug("Creating new SolrClient..."); - return new CloudHttp2SolrClient.Builder( + return new CloudSolrClient.Builder( Collections.singletonList(zkConnectString), Optional.empty()) .build(); } diff --git a/solr/modules/jwt-auth/src/java/org/apache/solr/security/jwt/JWTAuthPlugin.java b/solr/modules/jwt-auth/src/java/org/apache/solr/security/jwt/JWTAuthPlugin.java index 634245c4b56..83d0e99303b 100644 --- a/solr/modules/jwt-auth/src/java/org/apache/solr/security/jwt/JWTAuthPlugin.java +++ b/solr/modules/jwt-auth/src/java/org/apache/solr/security/jwt/JWTAuthPlugin.java @@ -46,7 +46,7 @@ import java.util.stream.Collectors; import org.apache.solr.api.AnnotatedApi; import org.apache.solr.api.Api; -import org.apache.solr.client.solrj.impl.Http2SolrClient; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.common.SolrException; import org.apache.solr.common.SpecProvider; import org.apache.solr.common.util.CommandOperation; @@ -941,7 +941,7 @@ AuthCode getAuthCode() { @Override protected boolean interceptInternodeRequest(Request request) { - Object userToken = request.getAttributes().get(Http2SolrClient.REQ_PRINCIPAL_KEY); + Object userToken = request.getAttributes().get(HttpJettySolrClient.REQ_PRINCIPAL_KEY); if (userToken instanceof JWTPrincipal jwtPrincipal) { request.headers( h -> h.put(HttpHeader.AUTHORIZATION.asString(), "Bearer " + jwtPrincipal.getToken())); diff --git a/solr/solr-ref-guide/modules/deployment-guide/examples/UsingSolrJRefGuideExamplesTest.java b/solr/solr-ref-guide/modules/deployment-guide/examples/UsingSolrJRefGuideExamplesTest.java index dc8e860a363..d1d08f1b6bc 100644 --- a/solr/solr-ref-guide/modules/deployment-guide/examples/UsingSolrJRefGuideExamplesTest.java +++ b/solr/solr-ref-guide/modules/deployment-guide/examples/UsingSolrJRefGuideExamplesTest.java @@ -31,8 +31,8 @@ import org.apache.solr.client.solrj.SolrQuery.ORDER; import org.apache.solr.client.solrj.SolrRequest; import org.apache.solr.client.solrj.beans.Field; -import org.apache.solr.client.solrj.impl.CloudHttp2SolrClient; -import org.apache.solr.client.solrj.impl.Http2SolrClient; +import org.apache.solr.client.solrj.impl.CloudSolrClient; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.client.solrj.request.CollectionAdminRequest; import org.apache.solr.client.solrj.response.CollectionAdminResponse; import org.apache.solr.client.solrj.response.QueryResponse; @@ -242,7 +242,7 @@ private SolrClient getSolrClient() { private SolrClient getTechProductSolrClient() { // tag::solrj-solrclient-timeouts[] final String solrUrl = "http://localhost:8983/solr"; - return new Http2SolrClient.Builder(solrUrl) + return new HttpJettySolrClient.Builder(solrUrl) .withConnectionTimeout(10000, TimeUnit.MILLISECONDS) .withIdleTimeout(60000, TimeUnit.MILLISECONDS) .build(); @@ -254,7 +254,7 @@ private SolrClient getBaseURLCloudSolrClient() { final List solrUrls = new ArrayList<>(); solrUrls.add("http://solr1:8983/solr"); solrUrls.add("http://solr2:8983/solr"); - return new CloudHttp2SolrClient.Builder(solrUrls).build(); + return new CloudSolrClient.Builder(solrUrls).build(); // end::solrj-cloudsolrclient-baseurl[] } @@ -264,7 +264,7 @@ private SolrClient getZookeeperNoRootCloudSolrClient() { zkServers.add("zookeeper1:2181"); zkServers.add("zookeeper2:2181"); zkServers.add("zookeeper3:2181"); - return new CloudHttp2SolrClient.Builder(zkServers, Optional.empty()).build(); + return new CloudSolrClient.Builder(zkServers, Optional.empty()).build(); // end::solrj-cloudsolrclient-zookeepernoroot[] } @@ -274,7 +274,7 @@ private SolrClient getZookeeperRootCloudSolrClient() { zkServers.add("zookeeper1:2181"); zkServers.add("zookeeper2:2181"); zkServers.add("zookeeper3:2181"); - return new CloudHttp2SolrClient.Builder(zkServers, Optional.of("/solr")).build(); + return new CloudSolrClient.Builder(zkServers, Optional.of("/solr")).build(); // end::solrj-cloudsolrclient-zookeeperroot[] } diff --git a/solr/solr-ref-guide/modules/deployment-guide/pages/basic-authentication-plugin.adoc b/solr/solr-ref-guide/modules/deployment-guide/pages/basic-authentication-plugin.adoc index 490f932582e..204731a89e4 100644 --- a/solr/solr-ref-guide/modules/deployment-guide/pages/basic-authentication-plugin.adoc +++ b/solr/solr-ref-guide/modules/deployment-guide/pages/basic-authentication-plugin.adoc @@ -336,30 +336,30 @@ While this is method is simple, it can often be inconvenient to ensure the crede It also doesn't work with the many `SolrClient` methods which don't consume `SolrRequest` objects. === Per-Client Credentials -Http2SolrClient supports setting the credentials at the client level when building it. +HttpJettySolrClient & HttpJdkSolrClient support setting the credentials at the client level when building it. This will ensure all requests issued with this particular client get the Basic Authentication headers set. [source,java] ---- -Http2SolrClient client = new Http2SolrClient.Builder(solrUrl) +var client = new HttpJettySolrClient.Builder(solrUrl) .withBasicAuthCredentials(userName, password).build(); QueryResponse rsp = req.process(client); ---- -CloudHttp2SolrClient supports receiving an `Http2SolrClient.Builder` instance for creating its internal client, so to set the credentials at the client level you could use a code like: +CloudSolrClient's Builder supports receiving an `Http2SolrClient.Builder` instance for creating its internal client, so to set the credentials at the client level you could use a code like: [source,java] ---- -Http2SolrClient.Builder http2ClientBuilder = Http2SolrClient.Builder().withBasicAuthCredentials(userName, password); -CloudHttp2SolrClient client = new CloudHttp2SolrClient.Builder(zkHostList, chroot) - .withInternalClientBuilder(http2ClientBuilder).build(); +var httpClientBuilder = HttpJettySolrClient.Builder().withBasicAuthCredentials(userName, password); +var client = new CloudSolrClient.Builder(zkHostList, chroot) + .withInternalClientBuilder(httpClientBuilder).build(); QueryResponse rsp = req.process(client); ---- === Global (JVM) Basic Auth Credentials Alternatively, users can use SolrJ's `PreemptiveBasicAuthClientBuilderFactory` to add basic authentication credentials to _all_ requests automatically. -To enable this feature, users should set the following system property `-Dsolr.httpclient.builder.factory=org.apache.solr.client.solrj.impl.PreemptiveBasicAuthClientBuilderFactory`. +To enable this feature, users should set the following system property `-Dsolr.httpclient.builder.factory=org.apache.solr.client.solrj.jetty.PreemptiveBasicAuthClientBuilderFactory`. `PreemptiveBasicAuthClientBuilderFactory` allows applications to provide credentials in two different ways: . The `solr.security.auth.basicauth.credentials` system property can be passed, containing the credentials directly (e.g., `-Dsolr.security.auth.basicauth.credentials=username:password`). diff --git a/solr/solr-ref-guide/modules/deployment-guide/pages/enabling-ssl.adoc b/solr/solr-ref-guide/modules/deployment-guide/pages/enabling-ssl.adoc index dc7c2341ab2..dd8998b8e19 100644 --- a/solr/solr-ref-guide/modules/deployment-guide/pages/enabling-ssl.adoc +++ b/solr/solr-ref-guide/modules/deployment-guide/pages/enabling-ssl.adoc @@ -254,9 +254,9 @@ Note that the truststore file is not actively monitored, so if you need to apply to update it and after that touch the keystore to trigger a reload. === SolrJ client -Http2SolrClient builder has a method `withKeyStoreReloadInterval(long interval, TimeUnit unit)` to initialize a scanner -that will watch and update the keystore and truststore for changes. If you are using CloudHttp2SolrClient, you can use -the `withInternalClientBuilder(Http2SolrClient.Builder internalClientBuilder)` to configure the internal http client +The HTTP SolrClient builder has a method `withKeyStoreReloadInterval(long interval, TimeUnit unit)` to initialize a scanner +that will watch and update the keystore and truststore for changes. If you are using CloudSolrClient, you can use +the `withHttpClientBuilder(internalClientBuilder)` to configure the internal http client with a keystore reload interval. The minimum reload interval is 1 second. If not set (or set to 0 or a negative value), the keystore/truststore won't be updated in the client. diff --git a/solr/solr-ref-guide/modules/deployment-guide/pages/solrj.adoc b/solr/solr-ref-guide/modules/deployment-guide/pages/solrj.adoc index 6df63275c39..3913d16e3a9 100644 --- a/solr/solr-ref-guide/modules/deployment-guide/pages/solrj.adoc +++ b/solr/solr-ref-guide/modules/deployment-guide/pages/solrj.adoc @@ -95,11 +95,11 @@ Requests are sent in the form of {solr-javadocs}/solrj/org/apache/solr/client/so `SolrClient` has a few concrete implementations, each geared towards a different usage-pattern or resiliency model: -- {solr-javadocs}/solrj/org/apache/solr/client/solrj/impl/Http2SolrClient.html[`Http2SolrClient`] - a general purpose client based on Jetty HttpClient. Supports HTTP/2 and HTTP/1.1, async, non-blocking. Most used & tested. +- {solr-javadocs}/solrj/org/apache/solr/client/solrj/jetty/HttpJettySolrClient.html[`HttpJettySolrClient`] - a general purpose client based on Jetty HttpClient. Supports HTTP/2 and HTTP/1.1, async, non-blocking. Most used & tested. - {solr-javadocs}/solrj/org/apache/solr/client/solrj/impl/HttpJdkSolrClient.html[`HttpJdkSolrClient`] - a general purpose client based on JDK HttpClient. Supports HTTP/2 and HTTP/1.1, async, non-blocking. Has no dependencies. - {solr-javadocs}/solrj/org/apache/solr/client/solrj/impl/LBSolrClient.html[`LBSolrClient`] - an internal client that delegates to other clients pointed at different URLs for fail-over/availability. Adjusts the list of "in-service" nodes based on node health. - {solr-javadocs}/solrj/org/apache/solr/client/solrj/impl/CloudSolrClient.html[`CloudSolrClient`] - the ideal client for SolrCloud. Using the "cluster state", it routes requests to the optimal nodes, including splitting out the documents in an UpdateRequest to different nodes. -- {solr-javadocs}/solrj/org/apache/solr/client/solrj/impl/ConcurrentUpdateJettySolrClient.html[`ConcurrentUpdateJettySolrClient`] - geared towards indexing-centric workloads. +- {solr-javadocs}/solrj/org/apache/solr/client/solrj/jetty/ConcurrentUpdateJettySolrClient.html[`ConcurrentUpdateJettySolrClient`] - geared towards indexing-centric workloads. Buffers documents internally before sending larger batches to Solr. === Common Configuration Options @@ -114,8 +114,8 @@ Unless otherwise specified, SolrJ expects these URLs to point to the root Solr p A few notable exceptions to this are described below: -- *Http2SolrClient* - Users of `Http2SolrClient` may choose to skip providing a root URL to their client, in favor of specifying the URL as an argument for the `Http2SolrClient.requestWithBaseUrl` method. -Calling any other `request` methods on a URL-less `Http2SolrClient` will result in an `IllegalArgumentException`. +- *HttpJettySolrClient* & *HttpJdkSolrClient* - Users of these may choose to skip providing a root URL to their client, in favor of specifying the URL as an argument for the `requestWithBaseUrl` method. +Calling any other `request` methods on a URL-less `HttpJettySolrClient` will result in an `IllegalArgumentException`. - *LBSolrClient* - Solr's "load balancing" client is frequently used to round-robin requests across a set of replicas or cores. URLs are still expected to point to the Solr root (i.e. "/solr"), but to support this use-case the URLs are often supplemented by an additional parameter to specify the targeted core. Alternatively, some "load balancing" methods make use of an `Endpoint` abstraction to provide this URL and core information in a more structured way. diff --git a/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc b/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc index e8707afb94b..8647a3d6400 100644 --- a/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc +++ b/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc @@ -73,6 +73,12 @@ That no longer happens in Solr 10. It is only used to load a configuration as a * Starting in 10, the Maven POM for SolrJ does not refer to SolrJ modules like ZooKeeper. If you require such functionality, you need to add additional dependencies. +* Classes using Jetty HttpClient have been moved to a new package `org.apache.solr.solrj.jetty`. +The following classes were renamed with some refactorings: `Http2SolrClient` to `HttpJettySolrClient`, `ConcurrentUpdateHttp2SolrClient` to `ConcurrentUpdateJettySolrClient`, `LBHttp2SolrClient` to `LBJettySolrClient`. +`CloudHttp2SolrClient.Builder` has moved to `CloudSolrClient`; users should generally have no need to refer to `CloudHttp2SolrClient` or any class/member with "http2" in it. +The builder will check if Jetty `HttpClient` is available and use that, otherwise fallback on a JDK based `HttpClient`. +`CloudJettySolrClient` is new, proving an explicit option. + * `SolrClient` implementations that rely on "base URL" strings now only accept "root" URL paths (i.e. URLs that end in "/solr"). Users who previously relied on collection-specific URLs to avoid including the collection name with each request can instead achieve this by specifying a "default collection" using the `withDefaultCollection` method available on most `SolrClient` Builders. diff --git a/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-8.adoc b/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-8.adoc index 5e21087a965..105c61dee70 100644 --- a/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-8.adoc +++ b/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-8.adoc @@ -80,8 +80,7 @@ In order to support SSL over HTTP/2 connections, Solr uses ALPN. Java 8 does not include an implementation of ALPN, therefore Solr will start with HTTP/1 only when SSL is enabled and Java 8 is in use. ==== Client Changes for HTTP/2 -{solr-javadocs}/solrj/org/apache/solr/client/solrj/impl/Http2SolrClient.html[`Http2SolrClient`] -with HTTP/2 and async capabilities based on Jetty Client is introduced. This client replaced +`Http2SolrClient` with HTTP/2 and async capabilities based on Jetty Client is introduced. This client replaced `HttpSolrClient` and `ConcurrentUpdateSolrClient` for sending most internal requests (sent by `UpdateShardHandler` and `HttpShardHandler`). diff --git a/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/SolrClientCache.java b/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/SolrClientCache.java index ec94c7d5aa9..3f5013fe664 100644 --- a/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/SolrClientCache.java +++ b/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/SolrClientCache.java @@ -26,10 +26,11 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import org.apache.solr.client.solrj.SolrClient; -import org.apache.solr.client.solrj.impl.CloudHttp2SolrClient; import org.apache.solr.client.solrj.impl.CloudSolrClient; -import org.apache.solr.client.solrj.impl.Http2SolrClient; +import org.apache.solr.client.solrj.impl.HttpSolrClientBase; +import org.apache.solr.client.solrj.impl.HttpSolrClientBuilderBase; import org.apache.solr.client.solrj.impl.SolrHttpConstants; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.common.AlreadyClosedException; import org.apache.solr.common.util.IOUtils; import org.apache.solr.common.util.URLUtil; @@ -46,19 +47,19 @@ public class SolrClientCache implements Closeable { private static final int minSocketTimeout = Math.max(Integer.getInteger(SolrHttpConstants.PROP_SO_TIMEOUT, MIN_TIMEOUT), MIN_TIMEOUT); - private String basicAuthCredentials = null; // Only support with the http2SolrClient + protected String basicAuthCredentials = null; // Only support with the httpJettySolrClient private final Map solrClients = new HashMap<>(); - private final Http2SolrClient http2SolrClient; + private final HttpSolrClientBase httpSolrClient; private final AtomicBoolean isClosed = new AtomicBoolean(false); private final AtomicReference defaultZkHost = new AtomicReference<>(); public SolrClientCache() { - this.http2SolrClient = null; + this.httpSolrClient = null; } - public SolrClientCache(Http2SolrClient http2SolrClient) { - this.http2SolrClient = http2SolrClient; + public SolrClientCache(HttpSolrClientBase httpSolrClient) { + this.httpSolrClient = httpSolrClient; } public void setBasicAuthCredentials(String basicAuthCredentials) { @@ -90,24 +91,18 @@ public synchronized CloudSolrClient getCloudSolrClient(String zkHost) { boolean canUseACLs = Optional.ofNullable(defaultZkHost.get()).map(zkHostNoChroot::equals).orElse(false); - final var client = - newCloudHttp2SolrClient(zkHost, http2SolrClient, canUseACLs, basicAuthCredentials); + final var client = newCloudSolrClient(zkHost, httpSolrClient, canUseACLs); solrClients.put(zkHost, client); return client; } - private static CloudHttp2SolrClient newCloudHttp2SolrClient( - String zkHost, - Http2SolrClient http2SolrClient, - boolean canUseACLs, - String basicAuthCredentials) { + protected CloudSolrClient newCloudSolrClient( + String zkHost, HttpSolrClientBase httpSolrClient, boolean canUseACLs) { final List hosts = List.of(zkHost); - var builder = new CloudHttp2SolrClient.Builder(hosts, Optional.empty()); + var builder = new CloudSolrClient.Builder(hosts, Optional.empty()); builder.canUseZkACLs(canUseACLs); // using internal builder to ensure the internal client gets closed - builder = - builder.withHttpClientBuilder( - newHttp2SolrClientBuilder(null, http2SolrClient, basicAuthCredentials)); + builder = builder.withHttpClientBuilder(newHttpSolrClientBuilder(null, httpSolrClient)); var client = builder.build(); try { client.connect(); @@ -132,21 +127,20 @@ public synchronized SolrClient getHttpSolrClient(String baseUrl) { if (solrClients.containsKey(baseUrl)) { return solrClients.get(baseUrl); } - final var client = - newHttp2SolrClientBuilder(baseUrl, http2SolrClient, basicAuthCredentials).build(); + final var client = newHttpSolrClientBuilder(baseUrl, httpSolrClient).build(); solrClients.put(baseUrl, client); return client; } - private static Http2SolrClient.Builder newHttp2SolrClientBuilder( - String url, Http2SolrClient http2SolrClient, String basicAuthCredentials) { + protected HttpSolrClientBuilderBase newHttpSolrClientBuilder( + String url, HttpSolrClientBase httpSolrClient) { final var builder = (url == null || URLUtil.isBaseUrl(url)) // URL may be null here and set by caller - ? new Http2SolrClient.Builder(url) - : new Http2SolrClient.Builder(URLUtil.extractBaseUrl(url)) + ? new HttpJettySolrClient.Builder(url) + : new HttpJettySolrClient.Builder(URLUtil.extractBaseUrl(url)) .withDefaultCollection(URLUtil.extractCoreFromCoreUrl(url)); - if (http2SolrClient != null) { - builder.withHttpClient(http2SolrClient); + if (httpSolrClient != null) { + builder.withHttpClient((HttpJettySolrClient) httpSolrClient); // TODO support JDK // cannot set connection timeout } else { builder.withConnectionTimeout(minConnTimeout, TimeUnit.MILLISECONDS); diff --git a/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/sql/DatabaseMetaDataImpl.java b/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/sql/DatabaseMetaDataImpl.java index 5228f98dae3..74f3fee7d4b 100644 --- a/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/sql/DatabaseMetaDataImpl.java +++ b/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/sql/DatabaseMetaDataImpl.java @@ -28,7 +28,7 @@ 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.Http2SolrClient; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.client.solrj.response.QueryResponse; import org.apache.solr.common.cloud.ClusterState; import org.apache.solr.common.util.SimpleOrderedMap; @@ -124,7 +124,7 @@ public String getDatabaseProductVersion() throws SQLException { for (String node : liveNodes) { try { String nodeURL = Utils.getBaseUrlForNodeName(node, urlScheme); - solrClient = new Http2SolrClient.Builder(nodeURL).build(); + solrClient = new HttpJettySolrClient.Builder(nodeURL).build(); QueryResponse rsp = solrClient.query(sysQuery); return String.valueOf( diff --git a/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/NodeValueFetcher.java b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/NodeValueFetcher.java index bd9b237cecd..7972f8ab3e2 100644 --- a/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/NodeValueFetcher.java +++ b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/NodeValueFetcher.java @@ -180,10 +180,10 @@ private void getRemoteMetricsFromTags( String baseUrl = ctx.zkClientClusterStateProvider.getZkStateReader().getBaseUrlForNodeName(ctx.getNode()); - SimpleSolrResponse rsp = ctx.http2SolrClient().requestWithBaseUrl(baseUrl, req::process); + NamedList response = ctx.httpSolrClient().requestWithBaseUrl(baseUrl, req, null); // TODO come up with a better solution to stream this response instead of loading in memory - try (InputStream prometheusStream = (InputStream) rsp.getResponse().get(STREAM_KEY)) { + try (InputStream prometheusStream = (InputStream) response.get(STREAM_KEY)) { List prometheusLines = Metrics.prometheusMetricStream(prometheusStream).toList(); for (Metrics t : requestedMetricNames) { Object value = t.extractFromPrometheus(prometheusLines); diff --git a/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/SolrClientCloudManager.java b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/SolrClientCloudManager.java index 30afd6bed57..b6aae92ecc1 100644 --- a/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/SolrClientCloudManager.java +++ b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/SolrClientCloudManager.java @@ -17,7 +17,6 @@ package org.apache.solr.client.solrj.impl; -import java.lang.invoke.MethodHandles; import org.apache.solr.client.solrj.cloud.DistribStateManager; import org.apache.solr.client.solrj.cloud.NodeStateProvider; import org.apache.solr.client.solrj.cloud.SolrCloudManager; @@ -26,14 +25,11 @@ import org.apache.solr.common.util.IOUtils; import org.apache.solr.common.util.ObjectCache; import org.apache.solr.common.util.TimeSource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** Class that implements {@link SolrCloudManager} using a SolrClient */ public class SolrClientCloudManager implements SolrCloudManager { - private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - private final CloudHttp2SolrClient cloudSolrClient; + private final CloudSolrClient cloudSolrClient; private final ZkDistribStateManager stateManager; private final ZkStateReader zkStateReader; private final SolrZkClient zkClient; @@ -41,7 +37,7 @@ public class SolrClientCloudManager implements SolrCloudManager { private final boolean closeObjectCache; private volatile boolean isClosed; - public SolrClientCloudManager(CloudHttp2SolrClient client, ObjectCache objectCache) { + public SolrClientCloudManager(CloudSolrClient client, ObjectCache objectCache) { this.cloudSolrClient = client; this.zkStateReader = ZkStateReader.from(client); this.zkClient = zkStateReader.getZkClient(); diff --git a/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/SolrClientNodeStateProvider.java b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/SolrClientNodeStateProvider.java index da494738281..bebb9456917 100644 --- a/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/SolrClientNodeStateProvider.java +++ b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/SolrClientNodeStateProvider.java @@ -58,12 +58,12 @@ public class SolrClientNodeStateProvider implements NodeStateProvider, MapWriter @SuppressWarnings({"rawtypes"}) private Map nodeVsTags = new HashMap<>(); - public SolrClientNodeStateProvider(CloudHttp2SolrClient solrClient) { - if (!(solrClient.getHttpClient() instanceof Http2SolrClient)) { + public SolrClientNodeStateProvider(CloudSolrClient solrClient) { + if (!(solrClient instanceof CloudHttp2SolrClient)) { throw new IllegalArgumentException( - "The passed-in Cloud Solr Client must delegate to " + Http2SolrClient.class); + "The passed-in CloudSolrClient must be a " + CloudHttp2SolrClient.class); } - this.solrClient = solrClient; + this.solrClient = (CloudHttp2SolrClient) solrClient; try { readReplicaDetails(); } catch (IOException e) { @@ -219,8 +219,7 @@ static void processMetricStream( ctx.zkClientClusterStateProvider.getZkStateReader().getBaseUrlForNodeName(solrNode); try (InputStream in = - (InputStream) - ctx.http2SolrClient().requestWithBaseUrl(baseUrl, req, null).get(STREAM_KEY)) { + (InputStream) ctx.httpSolrClient().requestWithBaseUrl(baseUrl, req, null).get(STREAM_KEY)) { NodeValueFetcher.Metrics.prometheusMetricStream(in).forEach(lineProcessor); } catch (Exception e) { @@ -257,18 +256,14 @@ public boolean isNodeAlive(String node) { } public RemoteCallCtx(String node, CloudHttp2SolrClient cloudSolrClient) { - if (!(cloudSolrClient.getHttpClient() instanceof Http2SolrClient)) { - throw new IllegalArgumentException( - "The passed-in Cloud Solr Client must delegate to " + Http2SolrClient.class); - } this.node = node; this.cloudSolrClient = cloudSolrClient; this.zkClientClusterStateProvider = (ZkClientClusterStateProvider) cloudSolrClient.getClusterStateProvider(); } - protected Http2SolrClient http2SolrClient() { - return (Http2SolrClient) cloudSolrClient.getHttpClient(); + protected HttpSolrClientBase httpSolrClient() { + return cloudSolrClient.getHttpClient(); } /** diff --git a/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/NodesSysPropsCacher.java b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/NodesSysPropsCacher.java index f8773b6e213..46974dce6d4 100644 --- a/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/NodesSysPropsCacher.java +++ b/solr/solrj-zookeeper/src/java/org/apache/solr/common/cloud/NodesSysPropsCacher.java @@ -22,7 +22,7 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.apache.solr.client.solrj.SolrRequest; -import org.apache.solr.client.solrj.impl.Http2SolrClient; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.client.solrj.request.GenericSolrRequest; import org.apache.solr.common.NavigableObject; import org.apache.solr.common.SolrException; @@ -34,9 +34,9 @@ public class NodesSysPropsCacher implements NodesSysProps, AutoCloseable { private volatile boolean isClosed = false; private final Map> nodeVsTagsCache = new ConcurrentHashMap<>(); private ZkStateReader zkStateReader; - private final Http2SolrClient solrClient; + private final HttpJettySolrClient solrClient; - public NodesSysPropsCacher(Http2SolrClient solrClient, ZkStateReader zkStateReader) { + public NodesSysPropsCacher(HttpJettySolrClient solrClient, ZkStateReader zkStateReader) { this.zkStateReader = zkStateReader; this.solrClient = solrClient; zkStateReader.registerLiveNodesListener( diff --git a/solr/solrj-zookeeper/src/test/org/apache/solr/client/solrj/impl/NodeValueFetcherTest.java b/solr/solrj-zookeeper/src/test/org/apache/solr/client/solrj/impl/NodeValueFetcherTest.java index 29edd771b43..59d38f64f2c 100644 --- a/solr/solrj-zookeeper/src/test/org/apache/solr/client/solrj/impl/NodeValueFetcherTest.java +++ b/solr/solrj-zookeeper/src/test/org/apache/solr/client/solrj/impl/NodeValueFetcherTest.java @@ -65,8 +65,8 @@ public void cleanup() throws Exception { @Test public void testGetTags() throws Exception { - try (var cloudHttp2SolrClient = - new CloudHttp2SolrClient.Builder( + try (var cloudSolrClient = + new CloudSolrClient.Builder( Collections.singletonList(cluster.getZkServer().getZkAddress()), Optional.empty()) .build()) { int totalCores = 0; @@ -75,7 +75,7 @@ public void testGetTags() throws Exception { // We should get same number than when we created the collection for (JettySolrRunner runner : cluster.getJettySolrRunners()) { String node = runner.getNodeName(); - RemoteCallCtx ctx = new RemoteCallCtx(node, cloudHttp2SolrClient); + RemoteCallCtx ctx = new RemoteCallCtx(node, cloudSolrClient); NodeValueFetcher fetcher = new NodeValueFetcher(); Set requestedTags = Set.of("cores"); diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/embedded/package.html b/solr/solrj/src/java/org/apache/solr/client/solrj/embedded/package.html deleted file mode 100644 index 4fa9c318686..00000000000 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/embedded/package.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - -SolrJ client implementations for embedded solr access. - - diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudHttp2SolrClient.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudHttp2SolrClient.java index 6886952c25c..1eb61d4c9c5 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudHttp2SolrClient.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudHttp2SolrClient.java @@ -17,63 +17,43 @@ package org.apache.solr.client.solrj.impl; -import java.lang.invoke.MethodHandles; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Optional; import java.util.concurrent.TimeUnit; -import org.apache.solr.client.solrj.ResponseParser; -import org.apache.solr.client.solrj.impl.SolrZkClientTimeout.SolrZkClientTimeoutAware; -import org.apache.solr.client.solrj.request.RequestWriter; -import org.apache.solr.client.solrj.request.UpdateRequest; -import org.apache.solr.common.SolrException; import org.apache.solr.common.util.IOUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** - * SolrJ client class to communicate with SolrCloud using an Http/2-capable Solr Client. Instances - * of this class communicate with Zookeeper to discover Solr endpoints for SolrCloud collections, - * and then use the {@link LBSolrClient} to issue requests. + * This {@link CloudSolrClient} is a base implementation using a {@link HttpSolrClientBase}. The '2' + * in the name has no differentiating significance anymore. * * @since solr 8.0 + * @lucene.internal */ @SuppressWarnings("serial") public class CloudHttp2SolrClient extends CloudSolrClient { - private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); private final ClusterStateProvider stateProvider; private final LBSolrClient lbClient; private final HttpSolrClientBase myClient; private final boolean clientIsInternal; - private static final boolean JETTY_CLIENT_AVAILABLE; - - static { - boolean jettyClientAvailable = true; - try { - Class.forName("org.eclipse.jetty.client.HttpClient"); - } catch (ClassNotFoundException e) { - jettyClientAvailable = false; - } - JETTY_CLIENT_AVAILABLE = jettyClientAvailable; - } - /** * Create a new client object that connects to Zookeeper and is always aware of the SolrCloud * state. If there is a fully redundant Zookeeper quorum and SolrCloud has enough replicas for * every shard in a collection, there is no single point of failure. Updates will be sent to shard * leaders by default. * - * @param builder a {@link CloudHttp2SolrClient.Builder} with the options used to create the - * client. + * @param builder a {@link CloudSolrClient.Builder} with the options used to create the client. */ protected CloudHttp2SolrClient(Builder builder) { super(builder.shardLeadersOnly, builder.parallelUpdates, builder.directUpdatesToLeadersOnly); this.clientIsInternal = builder.httpClient == null; - this.myClient = createOrGetHttpClientFromBuilder(builder); - this.stateProvider = createClusterStateProvider(builder); + try { + this.myClient = builder.createOrGetHttpClient(); + this.lbClient = builder.createOrGetLbClient(myClient); + this.stateProvider = createClusterStateProvider(builder); + } catch (RuntimeException e) { + close(); + throw e; + } this.retryExpiryTimeNano = builder.retryExpiryTimeNano; this.defaultCollection = builder.defaultCollection; if (builder.requestWriter != null) { @@ -89,62 +69,15 @@ protected CloudHttp2SolrClient(Builder builder) { // If caches are expired then they are refreshed after acquiring a lock. Set the number of // locks. this.locks = objectList(builder.parallelCacheRefreshesLocks); - - this.lbClient = builder.createOrGetLbClient(myClient); - } - - private HttpSolrClientBase createOrGetHttpClientFromBuilder(Builder builder) { - if (builder.httpClient != null) { - return builder.httpClient; - } else if (builder.internalClientBuilder != null) { - return builder.internalClientBuilder.build(); - } else if (JETTY_CLIENT_AVAILABLE) { - log.debug("Using {} as the delegate http client", Http2SolrClient.class); - return new Http2SolrClient.Builder().build(); - } else { - log.debug("Using {} as the delegate http client", HttpJdkSolrClient.class); - return new HttpJdkSolrClient.Builder().build(); - } } private ClusterStateProvider createClusterStateProvider(Builder builder) { if (builder.stateProvider != null) { return builder.stateProvider; } else if (builder.zkHosts.isEmpty()) { - return createHttp2ClusterStateProvider(builder.solrUrls, this.myClient); + return builder.createHttpClusterStateProvider(this.myClient); } else { - return createZkClusterStateProvider(builder); - } - } - - private ClusterStateProvider createZkClusterStateProvider(Builder builder) { - try { - ClusterStateProvider stateProvider = - ClusterStateProvider.newZkClusterStateProvider( - builder.zkHosts, builder.zkChroot, builder.canUseZkACLs); - if (stateProvider instanceof SolrZkClientTimeoutAware timeoutAware) { - timeoutAware.setZkClientTimeout(builder.zkClientTimeout); - timeoutAware.setZkConnectTimeout(builder.zkConnectTimeout); - } - return stateProvider; - } catch (Exception e) { - close(); - throw e; - } - } - - private ClusterStateProvider createHttp2ClusterStateProvider( - List solrUrls, HttpSolrClientBase httpClient) { - try { - return new Http2ClusterStateProvider<>(solrUrls, httpClient); - } catch (Exception e) { - close(); // doesn't throw - throw new RuntimeException( - "Couldn't initialize a HttpClusterStateProvider (is/are the " - + "Solr server(s), " - + solrUrls - + ", down?)", - e); + return builder.createZkClusterStateProvider(); } } @@ -172,289 +105,4 @@ public ClusterStateProvider getClusterStateProvider() { public HttpSolrClientBase getHttpClient() { return myClient; } - - /** Constructs {@link CloudHttp2SolrClient} instances from provided configuration. */ - public static class Builder { - protected Collection zkHosts = new ArrayList<>(); - protected List solrUrls = new ArrayList<>(); - protected String zkChroot; - protected HttpSolrClientBase httpClient; - protected boolean shardLeadersOnly = true; - protected boolean directUpdatesToLeadersOnly = false; - protected boolean parallelUpdates = true; - protected ClusterStateProvider stateProvider; - protected HttpSolrClientBuilderBase internalClientBuilder; - private RequestWriter requestWriter; - private ResponseParser responseParser; - private long retryExpiryTimeNano = - TimeUnit.NANOSECONDS.convert(3, TimeUnit.SECONDS); // 3 seconds or 3 million nanos - - private String defaultCollection; - private long timeToLiveSeconds = 60; - private int parallelCacheRefreshesLocks = 3; - private int zkConnectTimeout = SolrZkClientTimeout.DEFAULT_ZK_CONNECT_TIMEOUT; - private int zkClientTimeout = SolrZkClientTimeout.DEFAULT_ZK_CLIENT_TIMEOUT; - private boolean canUseZkACLs = true; - - /** - * Provide a series of Solr URLs to be used when configuring {@link CloudHttp2SolrClient} - * instances. The solr client will use these urls to understand the cluster topology, which solr - * nodes are active etc. - * - *

Provided Solr URLs are expected to point to the root Solr path - * ("http://hostname:8983/solr"); they should not include any collections, cores, or other path - * components. - * - *

Usage example: - * - *

-     *   final List<String> solrBaseUrls = new ArrayList<String>();
-     *   solrBaseUrls.add("http://solr1:8983/solr"); solrBaseUrls.add("http://solr2:8983/solr"); solrBaseUrls.add("http://solr3:8983/solr");
-     *   final SolrClient client = new CloudHttp2SolrClient.Builder(solrBaseUrls).build();
-     * 
- */ - public Builder(List solrUrls) { - this.solrUrls = solrUrls; - } - - /** - * Provide a series of ZK hosts which will be used when configuring {@link CloudHttp2SolrClient} - * instances. - * - *

Usage example when Solr stores data at the ZooKeeper root ('/'): - * - *

-     *   final List<String> zkServers = new ArrayList<String>();
-     *   zkServers.add("zookeeper1:2181"); zkServers.add("zookeeper2:2181"); zkServers.add("zookeeper3:2181");
-     *   final SolrClient client = new CloudHttp2SolrClient.Builder(zkServers, Optional.empty()).build();
-     * 
- * - * Usage example when Solr data is stored in a ZooKeeper chroot: - * - *
-     *    final List<String> zkServers = new ArrayList<String>();
-     *    zkServers.add("zookeeper1:2181"); zkServers.add("zookeeper2:2181"); zkServers.add("zookeeper3:2181");
-     *    final SolrClient client = new CloudHttp2SolrClient.Builder(zkServers, Optional.of("/solr")).build();
-     *  
- * - * @param zkHosts a List of at least one ZooKeeper host and port (e.g. "zookeeper1:2181") - * @param zkChroot the path to the root ZooKeeper node containing Solr data. Provide {@code - * java.util.Optional.empty()} if no ZK chroot is used. - */ - public Builder(List zkHosts, Optional zkChroot) { - this.zkHosts = zkHosts; - if (zkChroot.isPresent()) this.zkChroot = zkChroot.get(); - } - - /** for an expert use-case */ - public Builder(ClusterStateProvider stateProvider) { - this.stateProvider = stateProvider; - } - - /** Whether to use the default ZK ACLs when building a ZK Client. */ - public Builder canUseZkACLs(boolean canUseZkACLs) { - this.canUseZkACLs = canUseZkACLs; - return this; - } - - /** - * Tells {@link Builder} that created clients should be configured such that {@link - * CloudSolrClient#isUpdatesToLeaders} returns true. - * - * @see #sendUpdatesToAnyReplica - * @see CloudSolrClient#isUpdatesToLeaders - */ - public Builder sendUpdatesOnlyToShardLeaders() { - shardLeadersOnly = true; - return this; - } - - /** - * Tells {@link Builder} that created clients should be configured such that {@link - * CloudSolrClient#isUpdatesToLeaders} returns false. - * - * @see #sendUpdatesOnlyToShardLeaders - * @see CloudSolrClient#isUpdatesToLeaders - */ - public Builder sendUpdatesToAnyReplica() { - shardLeadersOnly = false; - return this; - } - - /** - * Tells {@link CloudHttp2SolrClient.Builder} that created clients should send direct updates to - * shard leaders only. - * - *

UpdateRequests whose leaders cannot be found will "fail fast" on the client side with a - * {@link SolrException} - * - * @see #sendDirectUpdatesToAnyShardReplica - * @see CloudSolrClient#isDirectUpdatesToLeadersOnly - */ - public Builder sendDirectUpdatesToShardLeadersOnly() { - directUpdatesToLeadersOnly = true; - return this; - } - - /** - * Tells {@link CloudHttp2SolrClient.Builder} that created clients can send updates to any shard - * replica (shard leaders and non-leaders). - * - *

Shard leaders are still preferred, but the created clients will fall back to using other - * replicas if a leader cannot be found. - * - * @see #sendDirectUpdatesToShardLeadersOnly - * @see CloudSolrClient#isDirectUpdatesToLeadersOnly - */ - public Builder sendDirectUpdatesToAnyShardReplica() { - directUpdatesToLeadersOnly = false; - return this; - } - - /** Provides a {@link RequestWriter} for created clients to use when handing requests. */ - public Builder withRequestWriter(RequestWriter requestWriter) { - this.requestWriter = requestWriter; - return this; - } - - /** Provides a {@link ResponseParser} for created clients to use when handling requests. */ - public Builder withResponseParser(ResponseParser responseParser) { - this.responseParser = responseParser; - return this; - } - - /** - * Tells {@link CloudHttp2SolrClient.Builder} whether created clients should send shard updates - * serially or in parallel - * - *

When an {@link UpdateRequest} affects multiple shards, {@link CloudHttp2SolrClient} splits - * it up and sends a request to each affected shard. This setting chooses whether those - * sub-requests are sent serially or in parallel. - * - *

If not set, this defaults to 'true' and sends sub-requests in parallel. - */ - public Builder withParallelUpdates(boolean parallelUpdates) { - this.parallelUpdates = parallelUpdates; - return this; - } - - /** - * When caches are expired then they are refreshed after acquiring a lock. Use this to set the - * number of locks. - * - *

Defaults to 3. - */ - public Builder withParallelCacheRefreshes(int parallelCacheRefreshesLocks) { - this.parallelCacheRefreshesLocks = parallelCacheRefreshesLocks; - return this; - } - - /** - * This is the time to wait to re-fetch the state after getting the same state version from ZK - */ - public Builder withRetryExpiryTime(long expiryTime, TimeUnit unit) { - this.retryExpiryTimeNano = TimeUnit.NANOSECONDS.convert(expiryTime, unit); - return this; - } - - /** Sets the default collection for request. */ - public Builder withDefaultCollection(String defaultCollection) { - this.defaultCollection = defaultCollection; - return this; - } - - /** - * Sets the cache ttl for DocCollection Objects cached. - * - * @param timeToLive ttl value - */ - public Builder withCollectionCacheTtl(long timeToLive, TimeUnit unit) { - assert timeToLive > 0; - this.timeToLiveSeconds = TimeUnit.SECONDS.convert(timeToLive, unit); - return this; - } - - /** - * Set the internal Solr HTTP client. - * - *

Note: closing the client instance is the responsibility of the caller. - * - * @return this - */ - public Builder withHttpClient(HttpSolrClientBase httpSolrClient) { - if (this.internalClientBuilder != null) { - throw new IllegalStateException( - "The builder can't accept an httpClient AND an internalClientBuilder, only one of those can be provided"); - } - this.httpClient = httpSolrClient; - return this; - } - - /** - * If provided, the CloudHttp2SolrClient will build it's internal client using this builder - * (instead of the empty default one). Providing this builder allows users to configure the - * internal clients (authentication, timeouts, etc.). - * - * @param internalClientBuilder the builder to use for creating the internal http client. - * @return this - */ - public Builder withHttpClientBuilder(HttpSolrClientBuilderBase internalClientBuilder) { - if (this.httpClient != null) { - throw new IllegalStateException( - "The builder can't accept an httpClient AND an internalClientBuilder, only one of those can be provided"); - } - this.internalClientBuilder = internalClientBuilder; - return this; - } - - @Deprecated(since = "9.10") - public Builder withInternalClientBuilder( - HttpSolrClientBuilderBase internalClientBuilder) { - return withHttpClientBuilder(internalClientBuilder); - } - - /** - * Sets the Zk connection timeout - * - * @param zkConnectTimeout timeout value - * @param unit time unit - */ - public Builder withZkConnectTimeout(int zkConnectTimeout, TimeUnit unit) { - this.zkConnectTimeout = Math.toIntExact(unit.toMillis(zkConnectTimeout)); - return this; - } - - /** - * Sets the Zk client session timeout - * - * @param zkClientTimeout timeout value - * @param unit time unit - */ - public Builder withZkClientTimeout(int zkClientTimeout, TimeUnit unit) { - this.zkClientTimeout = Math.toIntExact(unit.toMillis(zkClientTimeout)); - return this; - } - - /** Create a {@link CloudHttp2SolrClient} based on the provided configuration. */ - public CloudHttp2SolrClient build() { - int providedOptions = 0; - if (!zkHosts.isEmpty()) providedOptions++; - if (!solrUrls.isEmpty()) providedOptions++; - if (stateProvider != null) providedOptions++; - - if (providedOptions > 1) { - throw new IllegalArgumentException( - "Only one of zkHost(s), solrUrl(s), or stateProvider should be specified."); - } else if (providedOptions == 0) { - throw new IllegalArgumentException( - "One of zkHosts, solrUrls, or stateProvider must be specified."); - } - - return new CloudHttp2SolrClient(this); - } - - protected LBSolrClient createOrGetLbClient(HttpSolrClientBase myClient) { - return myClient.createLBSolrClient(); - } - } } 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 cecbc4fcd23..bd504d2535d 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 @@ -21,6 +21,7 @@ import java.io.IOException; import java.lang.invoke.MethodHandles; +import java.lang.reflect.Constructor; import java.net.SocketException; import java.net.UnknownHostException; import java.util.ArrayList; @@ -33,6 +34,7 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Random; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -82,6 +84,12 @@ import org.slf4j.LoggerFactory; import org.slf4j.MDC; +/** + * A {@link SolrClient} that routes requests to ideal nodes, including splitting update batches to + * the correct shards. It uses {@link LBSolrClient} as well, thus offering fail-over abilities if a + * core or node becomes unavailable. It's able to know where to route requests due to its knowledge + * of the SolrCloud "cluster state". + */ public abstract class CloudSolrClient extends SolrClient { private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); @@ -119,6 +127,368 @@ public abstract class CloudSolrClient extends SolrClient { protected volatile Object[] locks = objectList(3); + /** + * Constructs {@link CloudSolrClient} instances from provided configuration. It will use a Jetty + * based {@code HttpClient} if available, or will otherwise use the JDK. + */ + public static class Builder { + private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + // If the Jetty-based HttpJettySolrClient builder is on the classpath, this will be its no-arg + // constructor; otherwise it will be null and we will fall back to the JDK HTTP client. + private static final Constructor> + HTTP_JETTY_SOLR_CLIENT_BUILDER_CTOR; + + static { + Constructor> ctor = null; + try { + @SuppressWarnings("unchecked") + Class> builderClass = + (Class>) + Class.forName("org.apache.solr.client.solrj.jetty.HttpJettySolrClient$Builder"); + ctor = builderClass.getDeclaredConstructor(); + ctor.newInstance(); // perhaps fails because Jetty libs aren't on the classpath + } catch (Throwable t) { + // Class not present or incompatible; leave ctor as null to indicate unavailability + if (log.isTraceEnabled()) { + log.trace( + "HttpJettySolrClient$Builder not available on classpath; will use HttpJdkSolrClient", + t); + } + } + HTTP_JETTY_SOLR_CLIENT_BUILDER_CTOR = ctor; + } + + protected Collection zkHosts = new ArrayList<>(); + protected List solrUrls = new ArrayList<>(); + protected String zkChroot; + protected HttpSolrClientBase httpClient; + protected boolean shardLeadersOnly = true; + protected boolean directUpdatesToLeadersOnly = false; + protected boolean parallelUpdates = true; + protected ClusterStateProvider stateProvider; + protected HttpSolrClientBuilderBase internalClientBuilder; + protected RequestWriter requestWriter; + protected ResponseParser responseParser; + protected long retryExpiryTimeNano = + TimeUnit.NANOSECONDS.convert(3, TimeUnit.SECONDS); // 3 seconds or 3 million nanos + + protected String defaultCollection; + protected long timeToLiveSeconds = 60; + protected int parallelCacheRefreshesLocks = 3; + protected int zkConnectTimeout = SolrZkClientTimeout.DEFAULT_ZK_CONNECT_TIMEOUT; + protected int zkClientTimeout = SolrZkClientTimeout.DEFAULT_ZK_CLIENT_TIMEOUT; + protected boolean canUseZkACLs = true; + + /** + * Provide a series of Solr URLs to be used when configuring {@link CloudSolrClient} instances. + * The solr client will use these urls to understand the cluster topology, which solr nodes are + * active etc. + * + *

Provided Solr URLs are expected to point to the root Solr path + * ("http://hostname:8983/solr"); they should not include any collections, cores, or other path + * components. + * + *

Usage example: + * + *

+     *   final List<String> solrBaseUrls = new ArrayList<String>();
+     *   solrBaseUrls.add("http://solr1:8983/solr"); solrBaseUrls.add("http://solr2:8983/solr"); solrBaseUrls.add("http://solr3:8983/solr");
+     *   final SolrClient client = new CloudSolrClient.Builder(solrBaseUrls).build();
+     * 
+ */ + public Builder(List solrUrls) { + this.solrUrls = solrUrls; + } + + /** + * Provide a series of ZK hosts which will be used when configuring {@link CloudSolrClient} + * instances. + * + *

Usage example when Solr stores data at the ZooKeeper root ('/'): + * + *

+     *   final List<String> zkServers = new ArrayList<String>();
+     *   zkServers.add("zookeeper1:2181"); zkServers.add("zookeeper2:2181"); zkServers.add("zookeeper3:2181");
+     *   final SolrClient client = new CloudSolrClient.Builder(zkServers, Optional.empty()).build();
+     * 
+ * + * Usage example when Solr data is stored in a ZooKeeper chroot: + * + *
+     *    final List<String> zkServers = new ArrayList<String>();
+     *    zkServers.add("zookeeper1:2181"); zkServers.add("zookeeper2:2181"); zkServers.add("zookeeper3:2181");
+     *    final SolrClient client = new CloudSolrClient.Builder(zkServers, Optional.of("/solr")).build();
+     *  
+ * + * @param zkHosts a List of at least one ZooKeeper host and port (e.g. "zookeeper1:2181") + * @param zkChroot the path to the root ZooKeeper node containing Solr data. Provide {@code + * java.util.Optional.empty()} if no ZK chroot is used. + */ + public Builder(List zkHosts, Optional zkChroot) { + this.zkHosts = zkHosts; + if (zkChroot.isPresent()) this.zkChroot = zkChroot.get(); + } + + /** for an expert use-case */ + public Builder(ClusterStateProvider stateProvider) { + this.stateProvider = stateProvider; + } + + /** Whether to use the default ZK ACLs when building a ZK Client. */ + public Builder canUseZkACLs(boolean canUseZkACLs) { + this.canUseZkACLs = canUseZkACLs; + return this; + } + + /** + * Tells {@link Builder} that created clients should be configured such that {@link + * CloudSolrClient#isUpdatesToLeaders} returns true. + * + * @see #sendUpdatesToAnyReplica + * @see CloudSolrClient#isUpdatesToLeaders + */ + public Builder sendUpdatesOnlyToShardLeaders() { + shardLeadersOnly = true; + return this; + } + + /** + * Tells {@link Builder} that created clients should be configured such that {@link + * CloudSolrClient#isUpdatesToLeaders} returns false. + * + * @see #sendUpdatesOnlyToShardLeaders + * @see CloudSolrClient#isUpdatesToLeaders + */ + public Builder sendUpdatesToAnyReplica() { + shardLeadersOnly = false; + return this; + } + + /** + * Tells {@link CloudSolrClient.Builder} that created clients should send direct updates to + * shard leaders only. + * + *

UpdateRequests whose leaders cannot be found will "fail fast" on the client side with a + * {@link SolrException} + * + * @see #sendDirectUpdatesToAnyShardReplica + * @see CloudSolrClient#isDirectUpdatesToLeadersOnly + */ + public Builder sendDirectUpdatesToShardLeadersOnly() { + directUpdatesToLeadersOnly = true; + return this; + } + + /** + * Tells {@link CloudSolrClient.Builder} that created clients can send updates to any shard + * replica (shard leaders and non-leaders). + * + *

Shard leaders are still preferred, but the created clients will fall back to using other + * replicas if a leader cannot be found. + * + * @see #sendDirectUpdatesToShardLeadersOnly + * @see CloudSolrClient#isDirectUpdatesToLeadersOnly + */ + public Builder sendDirectUpdatesToAnyShardReplica() { + directUpdatesToLeadersOnly = false; + return this; + } + + /** Provides a {@link RequestWriter} for created clients to use when handing requests. */ + public Builder withRequestWriter(RequestWriter requestWriter) { + this.requestWriter = requestWriter; + return this; + } + + /** Provides a {@link ResponseParser} for created clients to use when handling requests. */ + public Builder withResponseParser(ResponseParser responseParser) { + this.responseParser = responseParser; + return this; + } + + /** + * Tells {@link CloudSolrClient.Builder} whether created clients should send shard updates + * serially or in parallel + * + *

When an {@link UpdateRequest} affects multiple shards, {@link CloudSolrClient} splits it + * up and sends a request to each affected shard. This setting chooses whether those + * sub-requests are sent serially or in parallel. + * + *

If not set, this defaults to 'true' and sends sub-requests in parallel. + */ + public Builder withParallelUpdates(boolean parallelUpdates) { + this.parallelUpdates = parallelUpdates; + return this; + } + + /** + * When caches are expired then they are refreshed after acquiring a lock. Use this to set the + * number of locks. + * + *

Defaults to 3. + */ + public Builder withParallelCacheRefreshes(int parallelCacheRefreshesLocks) { + this.parallelCacheRefreshesLocks = parallelCacheRefreshesLocks; + return this; + } + + /** + * This is the time to wait to re-fetch the state after getting the same state version from ZK + */ + public Builder withRetryExpiryTime(long expiryTime, TimeUnit unit) { + this.retryExpiryTimeNano = TimeUnit.NANOSECONDS.convert(expiryTime, unit); + return this; + } + + /** Sets the default collection for request. */ + public Builder withDefaultCollection(String defaultCollection) { + this.defaultCollection = defaultCollection; + return this; + } + + /** + * Sets the cache ttl for DocCollection Objects cached. + * + * @param timeToLive ttl value + */ + public Builder withCollectionCacheTtl(long timeToLive, TimeUnit unit) { + assert timeToLive > 0; + this.timeToLiveSeconds = TimeUnit.SECONDS.convert(timeToLive, unit); + return this; + } + + /** + * Set the internal Solr HTTP client. + * + *

Note: closing the client instance is the responsibility of the caller. + * + * @return this + */ + public Builder withHttpClient(HttpSolrClientBase httpSolrClient) { + if (this.internalClientBuilder != null) { + throw new IllegalStateException( + "The builder can't accept an httpClient AND an internalClientBuilder, only one of those can be provided"); + } + this.httpClient = httpSolrClient; + return this; + } + + /** + * If provided, the CloudSolrClient will build it's internal client using this builder (instead + * of the empty default one). Providing this builder allows users to configure the internal + * clients (authentication, timeouts, etc.). + * + * @param internalClientBuilder the builder to use for creating the internal http client. + * @return this + */ + public Builder withHttpClientBuilder(HttpSolrClientBuilderBase internalClientBuilder) { + if (this.httpClient != null) { + throw new IllegalStateException( + "The builder can't accept an httpClient AND an internalClientBuilder, only one of those can be provided"); + } + this.internalClientBuilder = internalClientBuilder; + return this; + } + + @Deprecated(since = "9.10") + public Builder withInternalClientBuilder( + HttpSolrClientBuilderBase internalClientBuilder) { + return withHttpClientBuilder(internalClientBuilder); + } + + /** + * Sets the Zk connection timeout + * + * @param zkConnectTimeout timeout value + * @param unit time unit + */ + public Builder withZkConnectTimeout(int zkConnectTimeout, TimeUnit unit) { + this.zkConnectTimeout = Math.toIntExact(unit.toMillis(zkConnectTimeout)); + return this; + } + + /** + * Sets the Zk client session timeout + * + * @param zkClientTimeout timeout value + * @param unit time unit + */ + public Builder withZkClientTimeout(int zkClientTimeout, TimeUnit unit) { + this.zkClientTimeout = Math.toIntExact(unit.toMillis(zkClientTimeout)); + return this; + } + + /** Create a {@link CloudSolrClient} based on the provided configuration. */ + public CloudHttp2SolrClient build() { + int providedOptions = 0; + if (!zkHosts.isEmpty()) providedOptions++; + if (!solrUrls.isEmpty()) providedOptions++; + if (stateProvider != null) providedOptions++; + + if (providedOptions > 1) { + throw new IllegalArgumentException( + "Only one of zkHost(s), solrUrl(s), or stateProvider should be specified."); + } else if (providedOptions == 0) { + throw new IllegalArgumentException( + "One of zkHosts, solrUrls, or stateProvider must be specified."); + } + + return new CloudHttp2SolrClient(this); + } + + protected HttpSolrClientBase createOrGetHttpClient() { + if (httpClient != null) { + return httpClient; + } else if (internalClientBuilder != null) { + return internalClientBuilder.build(); + } + + HttpSolrClientBuilderBase builder; + if (HTTP_JETTY_SOLR_CLIENT_BUILDER_CTOR != null) { + try { + log.debug("Using HttpJettySolrClient as the delegate http client"); + builder = HTTP_JETTY_SOLR_CLIENT_BUILDER_CTOR.newInstance(); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new RuntimeException(e); + } + } else { + log.debug("Using HttpJdkSolrClient as the delegate http client"); + builder = new HttpJdkSolrClient.Builder(); + } + return builder.build(); + } + + protected LBSolrClient createOrGetLbClient(HttpSolrClientBase myClient) { + return myClient.createLBSolrClient(); + } + + protected ClusterStateProvider createZkClusterStateProvider() { + ClusterStateProvider stateProvider = + ClusterStateProvider.newZkClusterStateProvider(zkHosts, zkChroot, canUseZkACLs); + if (stateProvider instanceof SolrZkClientTimeout.SolrZkClientTimeoutAware timeoutAware) { + timeoutAware.setZkClientTimeout(zkClientTimeout); + timeoutAware.setZkConnectTimeout(zkConnectTimeout); + } + return stateProvider; + } + + protected ClusterStateProvider createHttpClusterStateProvider(HttpSolrClientBase httpClient) { + try { + return new HttpClusterStateProvider<>(solrUrls, httpClient); + } catch (Exception e) { + throw new RuntimeException( + "Couldn't initialize a HttpClusterStateProvider (is/are the " + + "Solr server(s), " + + solrUrls + + ", down?)", + e); + } + } + } + protected static class StateCache extends ConcurrentHashMap { final AtomicLong puts = new AtomicLong(); final AtomicLong hits = new AtomicLong(); diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ConcurrentUpdateBaseSolrClient.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ConcurrentUpdateBaseSolrClient.java index 745bc1ffd2d..38a82b1791e 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ConcurrentUpdateBaseSolrClient.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ConcurrentUpdateBaseSolrClient.java @@ -634,7 +634,7 @@ public void shutdownNow() { /** Constructs {@link ConcurrentUpdateBaseSolrClient} instances from provided configuration. */ public abstract static class Builder { - public long idleTimeoutMillis; + protected long idleTimeoutMillis; protected HttpSolrClientBase client; protected String baseSolrUrl; protected String defaultCollection; @@ -643,7 +643,7 @@ public abstract static class Builder { protected ExecutorService executorService; protected boolean streamDeletes; protected boolean closeHttpClient; - private long pollQueueTimeMillis; + protected long pollQueueTimeMillis; /** * Initialize a Builder object, based on the provided URL and client. @@ -784,5 +784,9 @@ public Builder setPollQueueTime(long pollQueueTime, TimeUnit unit) { * Create a {@link ConcurrentUpdateBaseSolrClient} based on the provided configuration options. */ public abstract ConcurrentUpdateBaseSolrClient build(); + + public HttpSolrClientBase getClient() { + return client; + } } } diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpClientBuilderFactory.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpClientBuilderFactory.java index 2295360c9cc..48558e9b076 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpClientBuilderFactory.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpClientBuilderFactory.java @@ -17,13 +17,14 @@ package org.apache.solr.client.solrj.impl; import java.io.Closeable; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; /** - * A config hook for post-configuration of a {@linkplain Http2SolrClient} by its builder. + * A config hook for post-configuration of a {@linkplain HttpJettySolrClient} by its builder. * * @see SolrHttpConstants#SYS_PROP_HTTP_CLIENT_BUILDER_FACTORY * @lucene.experimental */ public interface HttpClientBuilderFactory extends Closeable { - default void setup(Http2SolrClient client) {} + default void setup(HttpJettySolrClient client) {} } diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/Http2ClusterStateProvider.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpClusterStateProvider.java similarity index 85% rename from solr/solrj/src/java/org/apache/solr/client/solrj/impl/Http2ClusterStateProvider.java rename to solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpClusterStateProvider.java index d6407514522..17b41e951a0 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/Http2ClusterStateProvider.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpClusterStateProvider.java @@ -20,19 +20,22 @@ import java.io.IOException; import java.util.List; -public class Http2ClusterStateProvider +/** A CSP that uses Solr HTTP APIs. */ +public class HttpClusterStateProvider extends BaseHttpClusterStateProvider { + // formerly known as Http2ClusterStateProvider + final C httpClient; /** * Provide the solr urls and a solr http client for this cluster state provider to use. It is the - * caller's responsibiity to close the client. + * caller's responsibility to close the client. * * @param solrUrls root path solr urls * @param httpClient an instance of HttpSolrClientBase * @throws Exception if a problem with initialization occurs */ - public Http2ClusterStateProvider(List solrUrls, C httpClient) throws Exception { + public HttpClusterStateProvider(List solrUrls, C httpClient) throws Exception { if (httpClient == null) { throw new IllegalArgumentException("You must provide an Http client."); } diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpJdkSolrClient.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpJdkSolrClient.java index 4e0472cc2d8..d405dc989f2 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpJdkSolrClient.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpJdkSolrClient.java @@ -90,7 +90,7 @@ protected HttpJdkSolrClient(String serverBaseUrl, HttpJdkSolrClient.Builder buil HttpClient.Builder b = HttpClient.newBuilder(); HttpClient.Redirect followRedirects = - Boolean.TRUE.equals(builder.followRedirects) + Boolean.TRUE.equals(builder.getFollowRedirects()) ? HttpClient.Redirect.NORMAL : HttpClient.Redirect.NEVER; b.followRedirects(followRedirects); @@ -103,8 +103,8 @@ protected HttpJdkSolrClient(String serverBaseUrl, HttpJdkSolrClient.Builder buil b.sslContext(builder.sslContext); } - if (builder.executor != null) { - this.executor = builder.executor; + if (builder.getExecutor() != null) { + this.executor = builder.getExecutor(); this.shutdownExecutor = false; } else { BlockingQueue queue = new LinkedBlockingQueue<>(1024); @@ -129,12 +129,13 @@ protected HttpJdkSolrClient(String serverBaseUrl, HttpJdkSolrClient.Builder buil b.cookieHandler(builder.cookieHandler); } - if (builder.proxyHost != null) { - if (builder.proxyIsSocks4) { + if (builder.getProxyHost() != null) { + if (builder.isProxyIsSocks4()) { log.warn( "Socks4 is likely not supported by this client. See https://bugs.openjdk.org/browse/JDK-8214516"); } - b.proxy(ProxySelector.of(new InetSocketAddress(builder.proxyHost, builder.proxyPort))); + b.proxy( + ProxySelector.of(new InetSocketAddress(builder.getProxyHost(), builder.getProxyPort()))); } this.httpClient = b.build(); updateDefaultMimeTypeForParser(); @@ -583,7 +584,7 @@ public HttpJdkSolrClient build() { @Override public Builder withHttpClient(HttpJdkSolrClient httpSolrClient) { super.withHttpClient(httpSolrClient); - if (this.executor == null) { + if (this.getExecutor() == null) { this.executor = httpSolrClient.executor; } if (this.sslContext == null) { diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrClientBase.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrClientBase.java index ffed7779fb4..27df0a6ebd9 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrClientBase.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrClientBase.java @@ -48,6 +48,11 @@ import org.apache.solr.common.util.NamedList; import org.apache.solr.common.util.Utils; +/** + * Utility/base functionality for direct HTTP client implementations. + * + * @lucene.internal + */ public abstract class HttpSolrClientBase extends SolrClient { protected static final String DEFAULT_PATH = ClientUtils.DEFAULT_PATH; @@ -116,7 +121,7 @@ protected ResponseParser responseParser(SolrRequest solrRequest) { return solrRequest.getResponseParser() == null ? this.parser : solrRequest.getResponseParser(); } - protected RequestWriter getRequestWriter() { + public RequestWriter getRequestWriter() { return requestWriter; } diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrClientBuilderBase.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrClientBuilderBase.java index 2821ebc4cae..e7ac05a2faa 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrClientBuilderBase.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrClientBuilderBase.java @@ -120,7 +120,7 @@ public B withBasicAuthCredentials(String user, String pass) { } } this.basicAuthAuthorizationStr = - Http2SolrClient.basicAuthCredentialsToAuthorizationString(user, pass); + HttpSolrClientBase.basicAuthCredentialsToAuthorizationString(user, pass); return (B) this; } @@ -250,4 +250,32 @@ public B withOptionalBasicAuthCredentials(String credentials) { } return (B) this; } + + public Integer getMaxConnectionsPerHost() { + return maxConnectionsPerHost; + } + + public Boolean getFollowRedirects() { + return followRedirects; + } + + public String getProxyHost() { + return proxyHost; + } + + public int getProxyPort() { + return proxyPort; + } + + public boolean isProxyIsSocks4() { + return proxyIsSocks4; + } + + public boolean isProxyIsSecure() { + return proxyIsSecure; + } + + public ExecutorService getExecutor() { + return executor; + } } diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBSolrClient.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBSolrClient.java index 1b9fbc5a3c6..920b3c49821 100644 --- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBSolrClient.java +++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBSolrClient.java @@ -81,7 +81,7 @@ *

* *
- * SolrClient client = new LBSolrClient.Builder(http2SolrClient,
+ * SolrClient client = new LBSolrClient.Builder(httpSolrClient,
  *         new LBSolrClient.Endpoint("http://host1:8080/solr"), new LBSolrClient.Endpoint("http://host2:8080/solr"))
  *     .build();
  * 
@@ -94,7 +94,7 @@ *
* *
- * SolrClient client = new LBSolrClient.Builder(http2SolrClient,
+ * SolrClient client = new LBSolrClient.Builder(httpSolrClient,
  *         new LBSolrClient.Endpoint("http://host1:8080/solr", "coreA"),
  *         new LBSolrClient.Endpoint("http://host2:8080/solr", "coreB"))
  *     .build();
@@ -614,7 +614,8 @@ private NamedList doRequest(Endpoint endpoint, SolrRequest solrReques
   private NamedList doRequest(
       SolrClient solrClient, String baseUrl, String collection, SolrRequest solrRequest)
       throws SolrServerException, IOException {
-    // Some implementations of LBSolrClient.getClient(...) return a Http2SolrClient that may not be
+    // Some implementations of LBSolrClient.getClient(...) return a HttpJettySolrClient that may not
+    // be
     // pointed at the desired URL (or any URL for that matter).  We special case that here to ensure
     // the appropriate URL is provided.
     if (solrClient instanceof HttpSolrClientBase hasReqWithUrl) {
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/AuthenticationStoreHolder.java b/solr/solrj/src/java/org/apache/solr/client/solrj/jetty/AuthenticationStoreHolder.java
similarity index 98%
rename from solr/solrj/src/java/org/apache/solr/client/solrj/impl/AuthenticationStoreHolder.java
rename to solr/solrj/src/java/org/apache/solr/client/solrj/jetty/AuthenticationStoreHolder.java
index 85b62ab64a4..a80ced5abdb 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/AuthenticationStoreHolder.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/jetty/AuthenticationStoreHolder.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.solr.client.solrj.impl;
+package org.apache.solr.client.solrj.jetty;
 
 import java.net.URI;
 import org.eclipse.jetty.client.Authentication;
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/jetty/CloudJettySolrClient.java b/solr/solrj/src/java/org/apache/solr/client/solrj/jetty/CloudJettySolrClient.java
new file mode 100644
index 00000000000..2e00c97c276
--- /dev/null
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/jetty/CloudJettySolrClient.java
@@ -0,0 +1,66 @@
+/*
+ * 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.jetty;
+
+import java.util.List;
+import org.apache.solr.client.solrj.impl.CloudHttp2SolrClient;
+import org.apache.solr.client.solrj.impl.CloudSolrClient;
+import org.apache.solr.client.solrj.impl.ClusterStateProvider;
+
+/**
+ * A {@link org.apache.solr.client.solrj.impl.CloudSolrClient} using Jetty {@code HttpClient} for
+ * HTTP communication. This is Solr's most robust CloudSolrClient.
+ */
+public class CloudJettySolrClient extends CloudHttp2SolrClient {
+
+  protected CloudJettySolrClient(Builder builder) {
+    super(builder);
+  }
+
+  public static class Builder extends CloudSolrClient.Builder {
+
+    public Builder(List solrUrls) {
+      super(solrUrls);
+    }
+
+    public Builder(ClusterStateProvider stateProvider) {
+      super(stateProvider);
+    }
+
+    @Override
+    public CloudJettySolrClient build() {
+      return new CloudJettySolrClient(this);
+    }
+
+    @Override
+    protected HttpJettySolrClient createOrGetHttpClient() {
+      if (httpClient != null) {
+        return (HttpJettySolrClient) httpClient;
+      } else if (internalClientBuilder != null) {
+        return (HttpJettySolrClient) internalClientBuilder.build();
+      } else {
+        return new HttpJettySolrClient.Builder().build();
+      }
+    }
+  }
+
+  @Override
+  public HttpJettySolrClient getHttpClient() {
+    return (HttpJettySolrClient) super.getHttpClient();
+  }
+}
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ConcurrentUpdateJettySolrClient.java b/solr/solrj/src/java/org/apache/solr/client/solrj/jetty/ConcurrentUpdateJettySolrClient.java
similarity index 85%
rename from solr/solrj/src/java/org/apache/solr/client/solrj/impl/ConcurrentUpdateJettySolrClient.java
rename to solr/solrj/src/java/org/apache/solr/client/solrj/jetty/ConcurrentUpdateJettySolrClient.java
index 866ac66729e..2ac6577d8b2 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ConcurrentUpdateJettySolrClient.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/jetty/ConcurrentUpdateJettySolrClient.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.solr.client.solrj.impl;
+package org.apache.solr.client.solrj.jetty;
 
 import java.io.Closeable;
 import java.io.IOException;
@@ -25,6 +25,8 @@
 import java.util.Objects;
 import java.util.concurrent.TimeUnit;
 import org.apache.solr.client.solrj.SolrRequest;
+import org.apache.solr.client.solrj.impl.ConcurrentUpdateBaseSolrClient;
+import org.apache.solr.client.solrj.impl.HttpSolrClientBase;
 import org.apache.solr.client.solrj.request.UpdateRequest;
 import org.apache.solr.client.solrj.util.ClientUtils;
 import org.apache.solr.common.params.ModifiableSolrParams;
@@ -35,24 +37,26 @@
 import org.eclipse.jetty.client.Request;
 import org.eclipse.jetty.http.HttpMethod;
 
-/** A ConcurrentUpdate SolrClient using {@link Http2SolrClient}. */
+/** A ConcurrentUpdate SolrClient using {@link HttpJettySolrClient}. */
 public class ConcurrentUpdateJettySolrClient extends ConcurrentUpdateBaseSolrClient {
   protected static final Charset FALLBACK_CHARSET = StandardCharsets.UTF_8;
 
-  private final Http2SolrClient client;
+  private final HttpJettySolrClient client;
 
   public static class Builder extends ConcurrentUpdateBaseSolrClient.Builder {
     /**
-     * @see ConcurrentUpdateBaseSolrClient.Builder#Builder(String, HttpSolrClientBase)
+     * @see org.apache.solr.client.solrj.impl.ConcurrentUpdateBaseSolrClient.Builder#Builder(String,
+     *     HttpSolrClientBase)
      */
-    public Builder(String baseUrl, Http2SolrClient client) {
+    public Builder(String baseUrl, HttpJettySolrClient client) {
       this(baseUrl, client, false);
     }
 
     /**
-     * @see ConcurrentUpdateBaseSolrClient.Builder#Builder(String, HttpSolrClientBase, boolean)
+     * @see org.apache.solr.client.solrj.impl.ConcurrentUpdateBaseSolrClient.Builder#Builder(String,
+     *     HttpSolrClientBase, boolean)
      */
-    public Builder(String baseSolrUrl, Http2SolrClient client, boolean closeHttpClient) {
+    public Builder(String baseSolrUrl, HttpJettySolrClient client, boolean closeHttpClient) {
       super(baseSolrUrl, client, closeHttpClient);
       this.idleTimeoutMillis = client.getIdleTimeoutMillis();
     }
@@ -65,7 +69,7 @@ public ConcurrentUpdateJettySolrClient build() {
 
   protected ConcurrentUpdateJettySolrClient(Builder builder) {
     super(builder);
-    this.client = (Http2SolrClient) builder.client;
+    this.client = (HttpJettySolrClient) builder.getClient();
   }
 
   @Override
@@ -141,7 +145,7 @@ public InputStreamResponseListener getResponseListener() {
 
   private OutStream initOutStream(String baseUrl, UpdateRequest updateRequest, String collection)
       throws IOException {
-    String contentType = client.requestWriter.getUpdateContentType();
+    String contentType = client.getRequestWriter().getUpdateContentType();
     final SolrParams origParams = updateRequest.getParams();
     ModifiableSolrParams requestParams =
         client.initializeSolrParams(updateRequest, client.responseParser(updateRequest));
@@ -159,10 +163,10 @@ private OutStream initOutStream(String baseUrl, UpdateRequest updateRequest, Str
             .body(content);
     client.decorateRequest(postRequest, updateRequest, false);
     InputStreamResponseListener responseListener =
-        new Http2SolrClient.InputStreamReleaseTrackingResponseListener();
+        new HttpJettySolrClient.InputStreamReleaseTrackingResponseListener();
     postRequest.send(responseListener);
 
-    boolean isXml = ClientUtils.TEXT_XML.equals(client.requestWriter.getUpdateContentType());
+    boolean isXml = ClientUtils.TEXT_XML.equals(client.getRequestWriter().getUpdateContentType());
     OutStream outStream = new OutStream(collection, origParams, content, responseListener, isXml);
     if (isXml) {
       outStream.write("".getBytes(FALLBACK_CHARSET));
@@ -172,7 +176,7 @@ private OutStream initOutStream(String baseUrl, UpdateRequest updateRequest, Str
 
   private void send(OutStream outStream, SolrRequest req, String collection) throws IOException {
     assert outStream.belongToThisStream(req, collection);
-    client.requestWriter.write(req, outStream.content.getOutputStream());
+    client.getRequestWriter().write(req, outStream.content.getOutputStream());
     if (outStream.isXml) {
       // check for commit or optimize
       SolrParams params = req.getParams();
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/Http2SolrClient.java b/solr/solrj/src/java/org/apache/solr/client/solrj/jetty/HttpJettySolrClient.java
similarity index 87%
rename from solr/solrj/src/java/org/apache/solr/client/solrj/impl/Http2SolrClient.java
rename to solr/solrj/src/java/org/apache/solr/client/solrj/jetty/HttpJettySolrClient.java
index 7a377946811..b485d2ccf48 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/Http2SolrClient.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/jetty/HttpJettySolrClient.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.solr.client.solrj.impl;
+package org.apache.solr.client.solrj.jetty;
 
 import java.io.FilterInputStream;
 import java.io.IOException;
@@ -43,13 +43,17 @@
 import org.apache.solr.client.solrj.SolrClientFunction;
 import org.apache.solr.client.solrj.SolrRequest;
 import org.apache.solr.client.solrj.SolrServerException;
-import org.apache.solr.client.solrj.embedded.SSLConfig;
-import org.apache.solr.client.solrj.impl.HttpListenerFactory.RequestResponseListener;
-import org.apache.solr.client.solrj.jetty.LBJettySolrClient;
+import org.apache.solr.client.solrj.impl.HttpClientBuilderFactory;
+import org.apache.solr.client.solrj.impl.HttpSolrClientBase;
+import org.apache.solr.client.solrj.impl.HttpSolrClientBuilderBase;
+import org.apache.solr.client.solrj.impl.LBSolrClient;
+import org.apache.solr.client.solrj.impl.SolrHttpConstants;
+import org.apache.solr.client.solrj.jetty.HttpListenerFactory.RequestResponseListener;
 import org.apache.solr.client.solrj.request.RequestWriter;
 import org.apache.solr.client.solrj.util.ClientUtils;
 import org.apache.solr.common.params.ModifiableSolrParams;
 import org.apache.solr.common.util.ContentStream;
+import org.apache.solr.common.util.EnvUtils;
 import org.apache.solr.common.util.ExecutorUtil;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.common.util.ObjectReleaseTracker;
@@ -96,7 +100,8 @@
  * HttpSolrClientBuilderBase#useHttp1_1(boolean)}. In retrospect, the name should have been {@code
  * HttpJettySolrClient}.
  */
-public class Http2SolrClient extends HttpSolrClientBase {
+public class HttpJettySolrClient extends HttpSolrClientBase {
+  // formerly known at Http2SolrClient
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
   public static final String REQ_PRINCIPAL_KEY = "solr-req-principal";
   private static final String USER_AGENT =
@@ -119,26 +124,19 @@ public class Http2SolrClient extends HttpSolrClientBase {
 
   private KeyStoreScanner scanner;
 
-  protected Http2SolrClient(String serverBaseUrl, Builder builder) {
+  protected HttpJettySolrClient(String serverBaseUrl, Builder builder) {
     super(serverBaseUrl, builder);
 
     if (builder.httpClient != null) {
       // Validate that no conflicting options are provided when using an existing HttpClient
-      if (builder.followRedirects != null
-          || builder.connectionTimeoutMillis != null
-          || builder.maxConnectionsPerHost != null
-          || builder.useHttp1_1 != null
-          || builder.proxyHost != null
-          || builder.sslConfig != null
-          || builder.cookieStore != null
-          || builder.keyStoreReloadIntervalSecs != null) {
+      if (builder.hasHttpClientBuildingOptions()) {
         throw new IllegalArgumentException(
             "You cannot provide the HttpClient and also specify options that are used to build a new client");
       }
 
       this.httpClient = builder.httpClient;
       if (this.executor == null) {
-        this.executor = builder.executor;
+        this.executor = builder.getExecutor();
       }
 
       initAuthStoreFromExistingClient(httpClient);
@@ -197,7 +195,8 @@ private void applyHttpClientBuilderFactory() {
           | ClassNotFoundException
           | InvocationTargetException
           | NoSuchMethodException e) {
-        throw new RuntimeException("Unable to instantiate " + Http2SolrClient.class.getName(), e);
+        throw new RuntimeException(
+            "Unable to instantiate " + HttpJettySolrClient.class.getName(), e);
       }
       factory.setup(this);
     }
@@ -214,7 +213,7 @@ public HttpClient getHttpClient() {
   }
 
   private HttpClient createHttpClient(Builder builder) {
-    executor = builder.executor;
+    executor = builder.getExecutor();
     if (executor == null) {
       BlockingArrayQueue queue = new BlockingArrayQueue<>(256, 256);
       this.executor =
@@ -226,15 +225,17 @@ private HttpClient createHttpClient(Builder builder) {
     }
 
     SSLConfig sslConfig =
-        builder.sslConfig != null ? builder.sslConfig : Http2SolrClient.defaultSSLConfig;
+        builder.sslConfig != null ? builder.sslConfig : HttpJettySolrClient.defaultSSLConfig;
     SslContextFactory.Client sslContextFactory =
         (sslConfig == null)
             ? getDefaultSslContextFactory()
             : sslConfig.createClientContextFactory();
 
     Long keyStoreReloadIntervalSecs = builder.keyStoreReloadIntervalSecs;
-    if (keyStoreReloadIntervalSecs == null && Boolean.getBoolean("solr.keyStoreReload.enabled")) {
-      keyStoreReloadIntervalSecs = Long.getLong("solr.jetty.sslContext.reload.scanInterval", 30);
+    if (keyStoreReloadIntervalSecs == null
+        && EnvUtils.getPropertyAsBool("solr.keystore.reload.enabled", false)) {
+      keyStoreReloadIntervalSecs =
+          EnvUtils.getPropertyAsLong("solr.jetty.ssl.context.reload.scan.interval.secs", 30l);
     }
     if (sslContextFactory != null
         && sslContextFactory.getKeyStoreResource() != null
@@ -268,17 +269,17 @@ private HttpClient createHttpClient(Builder builder) {
     HttpClientTransport transport;
     if (builder.shouldUseHttp1_1()) {
       if (log.isDebugEnabled()) {
-        log.debug("Create Http2SolrClient with HTTP/1.1 transport");
+        log.debug("Create HttpJettySolrClient with HTTP/1.1 transport");
       }
 
       transport = new HttpClientTransportOverHTTP(clientConnector);
       httpClient = new HttpClient(transport);
-      if (builder.maxConnectionsPerHost != null) {
-        httpClient.setMaxConnectionsPerDestination(builder.maxConnectionsPerHost);
+      if (builder.getMaxConnectionsPerHost() != null) {
+        httpClient.setMaxConnectionsPerDestination(builder.getMaxConnectionsPerHost());
       }
     } else {
       if (log.isDebugEnabled()) {
-        log.debug("Create Http2SolrClient with HTTP/2 transport");
+        log.debug("Create HttpJettySolrClient with HTTP/2 transport");
       }
 
       HTTP2Client http2client = new HTTP2Client(clientConnector);
@@ -290,7 +291,7 @@ private HttpClient createHttpClient(Builder builder) {
     httpClient.setExecutor(this.executor);
     httpClient.setStrictEventOrdering(false);
     httpClient.setConnectBlocking(true);
-    httpClient.setFollowRedirects(Boolean.TRUE.equals(builder.followRedirects));
+    httpClient.setFollowRedirects(Boolean.TRUE.equals(builder.getFollowRedirects()));
     httpClient.setMaxRequestsQueuedPerDestination(
         asyncTracker.getMaxRequestsQueuedPerDestination());
     httpClient.setUserAgentField(new HttpField(HttpHeader.USER_AGENT, USER_AGENT));
@@ -319,24 +320,24 @@ private HttpClient createHttpClient(Builder builder) {
   }
 
   private void setupProxy(Builder builder, HttpClient httpClient) {
-    if (builder.proxyHost == null) {
+    if (builder.getProxyHost() == null) {
       return;
     }
-    Address address = new Address(builder.proxyHost, builder.proxyPort);
+    Address address = new Address(builder.getProxyHost(), builder.getProxyPort());
 
     final ProxyConfiguration.Proxy proxy;
-    if (builder.proxyIsSocks4) {
-      proxy = new Socks4Proxy(address, builder.proxyIsSecure);
+    if (builder.isProxyIsSocks4()) {
+      proxy = new Socks4Proxy(address, builder.isProxyIsSecure());
     } else {
       final Protocol protocol;
       if (builder.shouldUseHttp1_1()) {
         protocol = HttpClientTransportOverHTTP.HTTP11;
       } else {
         // see HttpClientTransportOverHTTP2#newOrigin
-        String protocolName = builder.proxyIsSecure ? "h2" : "h2c";
+        String protocolName = builder.isProxyIsSecure() ? "h2" : "h2c";
         protocol = new Protocol(List.of(protocolName), false);
       }
-      proxy = new HttpProxy(address, builder.proxyIsSecure, protocol);
+      proxy = new HttpProxy(address, builder.isProxyIsSecure(), protocol);
     }
     httpClient.getProxyConfiguration().addProxy(proxy);
   }
@@ -504,7 +505,6 @@ public NamedList request(SolrRequest solrRequest, String collection)
   }
 
   @Override
-  @Deprecated
   public NamedList requestWithBaseUrl(
       String baseUrl, SolrRequest solrRequest, String collection)
       throws SolrServerException, IOException {
@@ -515,17 +515,18 @@ public NamedList requestWithBaseUrl(
    * Temporarily modifies the client to use a different base URL and runs the provided lambda
    *
    * @param baseUrl the base URL to use on any requests made within the 'clientFunction' lambda
-   * @param clientFunction a Function that consumes a Http2SolrClient and returns an arbitrary value
+   * @param clientFunction a Function that consumes a HttpJettySolrClient and returns an arbitrary
+   *     value
    * @return the value returned after invoking 'clientFunction'
    * @param  the type returned by the provided function (and by this method)
    */
   public  R requestWithBaseUrl(
-      String baseUrl, SolrClientFunction clientFunction)
+      String baseUrl, SolrClientFunction clientFunction)
       throws SolrServerException, IOException {
 
     // Despite the name, try-with-resources used here to avoid IDE and ObjectReleaseTracker
     // complaints
-    try (final var derivedClient = new NoCloseHttp2SolrClient(baseUrl, this)) {
+    try (final var derivedClient = new NoCloseHttpJettySolrClient(baseUrl, this)) {
       return clientFunction.apply(derivedClient);
     }
   }
@@ -537,7 +538,30 @@ protected LBSolrClient createLBSolrClient() {
 
   @Override
   public HttpSolrClientBuilderBase builder() {
-    return new Http2SolrClient.Builder().withHttpClient(this);
+    return new HttpJettySolrClient.Builder().withHttpClient(this);
+  }
+
+  // merely exposing for superclass's method visibility to this package
+  @Override
+  protected ModifiableSolrParams initializeSolrParams(
+      SolrRequest solrRequest, ResponseParser parserToUse) {
+    return super.initializeSolrParams(solrRequest, parserToUse);
+  }
+
+  // merely exposing for superclass's method visibility to this package
+  @Override
+  protected ResponseParser responseParser(SolrRequest solrRequest) {
+    return super.responseParser(solrRequest);
+  }
+
+  // merely exposing for superclass's method visibility to this package
+  String basicAuthAuthorizationStr() {
+    return basicAuthAuthorizationStr;
+  }
+
+  // merely exposing for superclass's method visibility to this package
+  protected static String basicAuthCredentialsToAuthorizationString(String user, String pass) {
+    return HttpSolrClientBase.basicAuthCredentialsToAuthorizationString(user, pass);
   }
 
   private NamedList processErrorsAndResponse(
@@ -784,17 +808,17 @@ protected String allProcessorSupportedContentTypesCommaDelimited(
   }
 
   /**
-   * An Http2SolrClient that doesn't close or cleanup any resources
+   * An HttpJettySolrClient that doesn't close or cleanup any resources
    *
    * 

Only safe to use as a derived copy of an existing instance which retains responsibility for * closing all involved resources. * * @see #requestWithBaseUrl(String, SolrClientFunction) */ - private static class NoCloseHttp2SolrClient extends Http2SolrClient { + private static class NoCloseHttpJettySolrClient extends HttpJettySolrClient { - public NoCloseHttp2SolrClient(String baseUrl, Http2SolrClient parentClient) { - super(baseUrl, new Http2SolrClient.Builder(baseUrl).withHttpClient(parentClient)); + public NoCloseHttpJettySolrClient(String baseUrl, HttpJettySolrClient parentClient) { + super(baseUrl, new HttpJettySolrClient.Builder(baseUrl).withHttpClient(parentClient)); this.asyncTracker = parentClient.asyncTracker; } @@ -848,7 +872,7 @@ public void waitForComplete() { } public static class Builder - extends HttpSolrClientBuilderBase { + extends HttpSolrClientBuilderBase { private HttpClient httpClient; @@ -870,7 +894,7 @@ public Builder() { *

The provided URL must point to the root Solr path ("/solr"), for example: * *

-     *   SolrClient client = new Http2SolrClient.Builder("http://my-solr-server:8983/solr")
+     *   SolrClient client = new HttpJettySolrClient.Builder("http://my-solr-server:8983/solr")
      *       .withDefaultCollection("core1")
      *       .build();
      *   QueryResponse resp = client.query(new SolrQuery("*:*"));
@@ -890,7 +914,7 @@ public Builder(String baseSolrUrl) {
      * @param listenerFactory a HttpListenerFactory
      * @return This Builder
      */
-    public Http2SolrClient.Builder addListenerFactory(HttpListenerFactory listenerFactory) {
+    public HttpJettySolrClient.Builder addListenerFactory(HttpListenerFactory listenerFactory) {
       if (this.listenerFactories == null) {
         this.listenerFactories = new ArrayList<>(1);
       }
@@ -904,14 +928,14 @@ public Http2SolrClient.Builder addListenerFactory(HttpListenerFactory listenerFa
      * @param listenerFactories a list of HttpListenerFactory instances
      * @return This Builder
      */
-    public Http2SolrClient.Builder withListenerFactories(
+    public HttpJettySolrClient.Builder withListenerFactories(
         List listenerFactories) {
       this.listenerFactories = listenerFactories;
       return this;
     }
 
-    public HttpSolrClientBuilderBase withSSLConfig(
-        SSLConfig sslConfig) {
+    public HttpSolrClientBuilderBase
+        withSSLConfig(SSLConfig sslConfig) {
       this.sslConfig = sslConfig;
       return this;
     }
@@ -925,7 +949,7 @@ public HttpSolrClientBuilderBase withS
      * @param unit The unit for the interval
      * @return This builder
      */
-    public Http2SolrClient.Builder withKeyStoreReloadInterval(long interval, TimeUnit unit) {
+    public HttpJettySolrClient.Builder withKeyStoreReloadInterval(long interval, TimeUnit unit) {
       this.keyStoreReloadIntervalSecs = unit.toSeconds(interval);
       if (this.keyStoreReloadIntervalSecs == 0 && interval > 0) {
         this.keyStoreReloadIntervalSecs = 1L;
@@ -937,7 +961,7 @@ private HttpCookieStore getCookieStore() {
       if (cookieStore == null) {
         return cookieStore;
       }
-      if (Boolean.getBoolean("solr.http.disableCookies")) {
+      if (!EnvUtils.getPropertyAsBool("solr.solrj.http.cookies.enabled", false)) {
         return new HttpCookieStore.Empty();
       }
       /*
@@ -952,23 +976,23 @@ protected  B build(Class type) {
     }
 
     @Override
-    public Http2SolrClient build() {
-      return new Http2SolrClient(baseSolrUrl, this);
+    public HttpJettySolrClient build() {
+      return new HttpJettySolrClient(baseSolrUrl, this);
     }
 
     @Override
-    public Builder withHttpClient(Http2SolrClient http2SolrClient) {
-      super.withHttpClient(http2SolrClient);
-      this.httpClient = http2SolrClient.httpClient;
+    public Builder withHttpClient(HttpJettySolrClient httpJettySolrClient) {
+      super.withHttpClient(httpJettySolrClient);
+      this.httpClient = httpJettySolrClient.httpClient;
 
       if (this.idleTimeoutMillis == null) {
-        this.idleTimeoutMillis = http2SolrClient.idleTimeoutMillis;
+        this.idleTimeoutMillis = httpJettySolrClient.idleTimeoutMillis;
       }
       if (this.listenerFactories == null) {
-        this.listenerFactories = http2SolrClient.listenerFactory;
+        this.listenerFactories = httpJettySolrClient.listenerFactory;
       }
       if (this.executor == null) {
-        this.executor = http2SolrClient.executor;
+        this.executor = httpJettySolrClient.executor;
       }
       return this;
     }
@@ -983,15 +1007,26 @@ public Builder withCookieStore(HttpCookieStore cookieStore) {
       this.cookieStore = cookieStore;
       return this;
     }
+
+    private boolean hasHttpClientBuildingOptions() {
+      return followRedirects != null
+          || connectionTimeoutMillis != null
+          || maxConnectionsPerHost != null
+          || useHttp1_1 != null
+          || proxyHost != null
+          || sslConfig != null
+          || cookieStore != null
+          || keyStoreReloadIntervalSecs != null;
+    }
   }
 
   public static void setDefaultSSLConfig(SSLConfig sslConfig) {
-    Http2SolrClient.defaultSSLConfig = sslConfig;
+    HttpJettySolrClient.defaultSSLConfig = sslConfig;
   }
 
   // public for testing, only used by tests
   public static void resetSslContextFactory() {
-    Http2SolrClient.defaultSSLConfig = null;
+    HttpJettySolrClient.defaultSSLConfig = null;
   }
 
   /* package-private for testing */
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpListenerFactory.java b/solr/solrj/src/java/org/apache/solr/client/solrj/jetty/HttpListenerFactory.java
similarity index 92%
rename from solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpListenerFactory.java
rename to solr/solrj/src/java/org/apache/solr/client/solrj/jetty/HttpListenerFactory.java
index cf42a0107f0..e084e3fff65 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpListenerFactory.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/jetty/HttpListenerFactory.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.solr.client.solrj.impl;
+package org.apache.solr.client.solrj.jetty;
 
 import org.eclipse.jetty.client.Request;
 import org.eclipse.jetty.client.Response;
@@ -28,7 +28,7 @@ abstract class RequestResponseListener
     /**
      * Callback method invoked when the request begins being processed in order to be sent. This is
      * the last opportunity to modify the request. This method will NOT be ensured to be called on
-     * the same thread as the thread calling {@code Http2SolrClient} methods.
+     * the same thread as the thread calling {@code HttpJettySolrClient} methods.
      *
      * @param request the request that begins being processed
      */
@@ -37,7 +37,7 @@ public void onBegin(Request request) {}
 
     /**
      * Callback method invoked when the request is queued, waiting to be sent. This method will be
-     * ensured to be called on the same thread as the thread calling {@code Http2SolrClient}
+     * ensured to be called on the same thread as the thread calling {@code HttpJettySolrClient}
      * methods.
      *
      * @param request the request being queued
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/jetty/LBJettySolrClient.java b/solr/solrj/src/java/org/apache/solr/client/solrj/jetty/LBJettySolrClient.java
index 4790fabcf3a..970199edb7a 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/jetty/LBJettySolrClient.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/jetty/LBJettySolrClient.java
@@ -21,7 +21,6 @@
 import org.apache.solr.client.solrj.SolrClient;
 import org.apache.solr.client.solrj.SolrRequest;
 import org.apache.solr.client.solrj.SolrServerException;
-import org.apache.solr.client.solrj.impl.Http2SolrClient;
 import org.apache.solr.client.solrj.impl.LBAsyncSolrClient;
 import org.apache.solr.client.solrj.impl.LBSolrClient;
 import org.apache.solr.common.util.NamedList;
@@ -33,9 +32,9 @@ protected LBJettySolrClient(Builder builder) {
     super(builder);
   }
 
-  public static class Builder extends LBSolrClient.Builder {
+  public static class Builder extends LBSolrClient.Builder {
 
-    public Builder(Http2SolrClient solrClient, Endpoint... endpoints) {
+    public Builder(HttpJettySolrClient solrClient, Endpoint... endpoints) {
       super(solrClient, endpoints);
     }
 
@@ -49,6 +48,6 @@ public LBJettySolrClient build() {
   protected CompletableFuture> requestAsyncWithUrl(
       SolrClient client, String baseUrl, SolrRequest request)
       throws SolrServerException, IOException {
-    return ((Http2SolrClient) client).requestWithBaseUrl(baseUrl, c -> c.requestAsync(request));
+    return ((HttpJettySolrClient) client).requestWithBaseUrl(baseUrl, c -> c.requestAsync(request));
   }
 }
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/PreemptiveBasicAuthClientBuilderFactory.java b/solr/solrj/src/java/org/apache/solr/client/solrj/jetty/PreemptiveBasicAuthClientBuilderFactory.java
similarity index 94%
rename from solr/solrj/src/java/org/apache/solr/client/solrj/impl/PreemptiveBasicAuthClientBuilderFactory.java
rename to solr/solrj/src/java/org/apache/solr/client/solrj/jetty/PreemptiveBasicAuthClientBuilderFactory.java
index e0680be0874..a7553d6cb3d 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/PreemptiveBasicAuthClientBuilderFactory.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/jetty/PreemptiveBasicAuthClientBuilderFactory.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.solr.client.solrj.impl;
+package org.apache.solr.client.solrj.jetty;
 
 import java.io.BufferedReader;
 import java.io.IOException;
@@ -26,7 +26,8 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
-import org.apache.solr.client.solrj.util.SolrBasicAuthentication;
+import org.apache.solr.client.solrj.impl.HttpClientBuilderFactory;
+import org.apache.solr.client.solrj.impl.SolrHttpConstants;
 import org.apache.solr.common.params.MapSolrParams;
 import org.apache.solr.common.params.SolrParams;
 import org.apache.solr.common.util.StrUtils;
@@ -69,7 +70,7 @@ public static void setDefaultSolrParams(SolrParams params) {
   public void close() throws IOException {}
 
   @Override
-  public void setup(Http2SolrClient client) {
+  public void setup(HttpJettySolrClient client) {
     final String basicAuthUser =
         CREDENTIAL_RESOLVER.defaultParams.get(SolrHttpConstants.PROP_BASIC_AUTH_USER);
     final String basicAuthPass =
@@ -77,7 +78,7 @@ public void setup(Http2SolrClient client) {
     this.setup(client, basicAuthUser, basicAuthPass);
   }
 
-  public void setup(Http2SolrClient client, String basicAuthUser, String basicAuthPass) {
+  public void setup(HttpJettySolrClient client, String basicAuthUser, String basicAuthPass) {
     if (basicAuthUser == null || basicAuthPass == null) {
       throw new IllegalArgumentException(
           "username & password must be specified with " + getClass().getName());
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/embedded/SSLConfig.java b/solr/solrj/src/java/org/apache/solr/client/solrj/jetty/SSLConfig.java
similarity index 99%
rename from solr/solrj/src/java/org/apache/solr/client/solrj/embedded/SSLConfig.java
rename to solr/solrj/src/java/org/apache/solr/client/solrj/jetty/SSLConfig.java
index 0acb4395e08..b8a344852ab 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/embedded/SSLConfig.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/jetty/SSLConfig.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.solr.client.solrj.embedded;
+package org.apache.solr.client.solrj.jetty;
 
 import org.eclipse.jetty.util.ssl.SslContextFactory;
 
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/util/SolrBasicAuthentication.java b/solr/solrj/src/java/org/apache/solr/client/solrj/jetty/SolrBasicAuthentication.java
similarity index 98%
rename from solr/solrj/src/java/org/apache/solr/client/solrj/util/SolrBasicAuthentication.java
rename to solr/solrj/src/java/org/apache/solr/client/solrj/jetty/SolrBasicAuthentication.java
index 002a34e53ee..69fe77b1097 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/util/SolrBasicAuthentication.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/jetty/SolrBasicAuthentication.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.solr.client.solrj.util;
+package org.apache.solr.client.solrj.jetty;
 
 import java.net.URI;
 import java.nio.charset.StandardCharsets;
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleBinaryHttp2Test.java b/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleBinaryHttp2Test.java
index 8a7987d6ec9..991bbdedf71 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleBinaryHttp2Test.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleBinaryHttp2Test.java
@@ -19,9 +19,9 @@
 
 import java.util.concurrent.TimeUnit;
 import org.apache.solr.SolrTestCaseJ4;
-import org.apache.solr.client.solrj.impl.Http2SolrClient;
 import org.apache.solr.client.solrj.impl.JavaBinRequestWriter;
 import org.apache.solr.client.solrj.impl.JavaBinResponseParser;
+import org.apache.solr.client.solrj.jetty.HttpJettySolrClient;
 import org.junit.BeforeClass;
 
 /**
@@ -38,7 +38,7 @@ public static void beforeTest() throws Exception {
 
   @Override
   public SolrClient createNewSolrClient() {
-    return new Http2SolrClient.Builder(getBaseUrl())
+    return new HttpJettySolrClient.Builder(getBaseUrl())
         .withDefaultCollection(DEFAULT_TEST_CORENAME)
         .withConnectionTimeout(DEFAULT_CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS)
         .withRequestWriter(new JavaBinRequestWriter())
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleJettyTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleJettyTest.java
index 9050a0dec7c..338aea55400 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleJettyTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleJettyTest.java
@@ -60,7 +60,7 @@ public static void beforeTest() throws Exception {
   @Test
   public void testBadSetup() {
     String url = "http" + (isSSLMode() ? "s" : "") + "://127.0.0.1/?core=xxx";
-    // This test does NOT fail for Http2SolrClient
+    // This test does NOT fail for HttpJettySolrClient
     expectThrows(Exception.class, () -> new HttpSolrClient.Builder(url).build());
   }
 
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleStreamingBinaryHttp2Test.java b/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleStreamingBinaryHttp2Test.java
index 46369c1f0cd..1e9ee584448 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleStreamingBinaryHttp2Test.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleStreamingBinaryHttp2Test.java
@@ -23,9 +23,9 @@
 import org.apache.solr.client.solrj.SolrClient;
 import org.apache.solr.client.solrj.SolrQuery;
 import org.apache.solr.client.solrj.StreamingResponseCallback;
-import org.apache.solr.client.solrj.impl.Http2SolrClient;
 import org.apache.solr.client.solrj.impl.JavaBinRequestWriter;
 import org.apache.solr.client.solrj.impl.JavaBinResponseParser;
+import org.apache.solr.client.solrj.jetty.HttpJettySolrClient;
 import org.apache.solr.client.solrj.response.QueryResponse;
 import org.apache.solr.common.SolrDocument;
 import org.apache.solr.common.SolrInputDocument;
@@ -38,8 +38,8 @@ public class SolrExampleStreamingBinaryHttp2Test extends SolrExampleStreamingHtt
   public SolrClient createNewSolrClient() {
     String url = getBaseUrl();
     // smaller queue size hits locks more often
-    Http2SolrClient solrClient =
-        new Http2SolrClient.Builder()
+    var solrClient =
+        new HttpJettySolrClient.Builder()
             .withRequestWriter(new JavaBinRequestWriter())
             .withResponseParser(new JavaBinResponseParser())
             .build();
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleStreamingHttp2Test.java b/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleStreamingHttp2Test.java
index cf7bc4bd10e..99027d7c0ff 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleStreamingHttp2Test.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleStreamingHttp2Test.java
@@ -23,10 +23,10 @@
 import java.util.List;
 import org.apache.solr.client.solrj.SolrClient;
 import org.apache.solr.client.solrj.SolrExampleTests;
-import org.apache.solr.client.solrj.impl.ConcurrentUpdateJettySolrClient;
-import org.apache.solr.client.solrj.impl.Http2SolrClient;
 import org.apache.solr.client.solrj.impl.XMLRequestWriter;
 import org.apache.solr.client.solrj.impl.XMLResponseParser;
+import org.apache.solr.client.solrj.jetty.ConcurrentUpdateJettySolrClient;
+import org.apache.solr.client.solrj.jetty.HttpJettySolrClient;
 import org.apache.solr.client.solrj.request.AbstractUpdateRequest;
 import org.apache.solr.client.solrj.request.UpdateRequest;
 import org.apache.solr.common.SolrInputDocument;
@@ -47,8 +47,8 @@ public static void beforeTest() throws Exception {
   public SolrClient createNewSolrClient() {
     String url = getBaseUrl();
     // smaller queue size hits locks more often
-    Http2SolrClient solrClient =
-        new Http2SolrClient.Builder()
+    var solrClient =
+        new HttpJettySolrClient.Builder()
             .withRequestWriter(new XMLRequestWriter())
             .withResponseParser(new XMLResponseParser())
             .build();
@@ -65,7 +65,7 @@ public void testWaitOptions() throws Exception {
     // SOLR-3903
     final List failures = new ArrayList<>();
     final String serverUrl = getBaseUrl();
-    try (Http2SolrClient http2Client = new Http2SolrClient.Builder().build();
+    try (var http2Client = new HttpJettySolrClient.Builder().build();
         var concurrentClient =
             new FailureRecordingConcurrentUpdateSolrClient.Builder(serverUrl, http2Client)
                 .withDefaultCollection(DEFAULT_TEST_CORENAME)
@@ -108,7 +108,7 @@ public void handleError(Throwable ex) {
     }
 
     static class Builder extends ConcurrentUpdateJettySolrClient.Builder {
-      public Builder(String baseSolrUrl, Http2SolrClient http2Client) {
+      public Builder(String baseSolrUrl, HttpJettySolrClient http2Client) {
         super(baseSolrUrl, http2Client);
       }
 
@@ -135,7 +135,7 @@ public void handleError(Throwable ex) {
 
     public static class Builder extends ConcurrentUpdateJettySolrClient.Builder {
 
-      public Builder(String baseSolrUrl, Http2SolrClient http2Client) {
+      public Builder(String baseSolrUrl, HttpJettySolrClient http2Client) {
         super(baseSolrUrl, http2Client, true);
       }
 
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleXMLHttp2Test.java b/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleXMLHttp2Test.java
index 765c2b33573..113e9f1c213 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleXMLHttp2Test.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/SolrExampleXMLHttp2Test.java
@@ -20,9 +20,9 @@
 import java.util.concurrent.TimeUnit;
 import org.apache.solr.client.solrj.SolrClient;
 import org.apache.solr.client.solrj.SolrExampleTests;
-import org.apache.solr.client.solrj.impl.Http2SolrClient;
 import org.apache.solr.client.solrj.impl.XMLRequestWriter;
 import org.apache.solr.client.solrj.impl.XMLResponseParser;
+import org.apache.solr.client.solrj.jetty.HttpJettySolrClient;
 import org.junit.BeforeClass;
 
 /**
@@ -38,8 +38,8 @@ public static void beforeTest() throws Exception {
   @Override
   public SolrClient createNewSolrClient() {
 
-    Http2SolrClient client =
-        new Http2SolrClient.Builder(getBaseUrl())
+    var client =
+        new HttpJettySolrClient.Builder(getBaseUrl())
             .withDefaultCollection(DEFAULT_TEST_CORENAME)
             .withConnectionTimeout(DEFAULT_CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS)
             .withRequestWriter(new XMLRequestWriter())
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudHttp2SolrClientBuilderTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudHttp2SolrClientBuilderTest.java
index 6f8f8587b51..cd9b4d20096 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudHttp2SolrClientBuilderTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudHttp2SolrClientBuilderTest.java
@@ -29,6 +29,7 @@
 import java.util.List;
 import java.util.Optional;
 import java.util.concurrent.TimeUnit;
+import org.apache.solr.client.solrj.jetty.HttpJettySolrClient;
 import org.apache.solr.cloud.SolrCloudTestCase;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -55,8 +56,7 @@ public static void setupCluster() throws Exception {
   @Test
   public void testSingleZkHostSpecified() throws IOException {
     try (CloudSolrClient createdClient =
-        new CloudHttp2SolrClient.Builder(
-                Collections.singletonList(ANY_ZK_HOST), Optional.of(ANY_CHROOT))
+        new CloudSolrClient.Builder(Collections.singletonList(ANY_ZK_HOST), Optional.of(ANY_CHROOT))
             .build()) {
       try (ZkClientClusterStateProvider zkClientClusterStateProvider =
           ZkClientClusterStateProvider.from(createdClient)) {
@@ -73,7 +73,7 @@ public void testSeveralZkHostsSpecifiedSingly() throws IOException {
     zkHostList.add(ANY_ZK_HOST);
     zkHostList.add(ANY_OTHER_ZK_HOST);
     try (CloudSolrClient createdClient =
-        new CloudHttp2SolrClient.Builder(zkHostList, Optional.of(ANY_CHROOT)).build()) {
+        new CloudSolrClient.Builder(zkHostList, Optional.of(ANY_CHROOT)).build()) {
       try (ZkClientClusterStateProvider zkClientClusterStateProvider =
           ZkClientClusterStateProvider.from(createdClient)) {
         final String clientZkHost = zkClientClusterStateProvider.getZkHost();
@@ -90,7 +90,7 @@ public void testSeveralZkHostsSpecifiedTogether() throws IOException {
     zkHosts.add(ANY_ZK_HOST);
     zkHosts.add(ANY_OTHER_ZK_HOST);
     try (CloudSolrClient createdClient =
-        new CloudHttp2SolrClient.Builder(zkHosts, Optional.of(ANY_CHROOT)).build()) {
+        new CloudSolrClient.Builder(zkHosts, Optional.of(ANY_CHROOT)).build()) {
       try (ZkClientClusterStateProvider zkClientClusterStateProvider =
           ZkClientClusterStateProvider.from(createdClient)) {
         final String clientZkHost = zkClientClusterStateProvider.getZkHost();
@@ -104,8 +104,7 @@ public void testSeveralZkHostsSpecifiedTogether() throws IOException {
   @Test
   public void testByDefaultConfiguresClientToSendUpdatesOnlyToShardLeaders() throws IOException {
     try (CloudSolrClient createdClient =
-        new CloudHttp2SolrClient.Builder(
-                Collections.singletonList(ANY_ZK_HOST), Optional.of(ANY_CHROOT))
+        new CloudSolrClient.Builder(Collections.singletonList(ANY_ZK_HOST), Optional.of(ANY_CHROOT))
             .build()) {
       assertTrue(createdClient.isUpdatesToLeaders());
     }
@@ -114,8 +113,7 @@ public void testByDefaultConfiguresClientToSendUpdatesOnlyToShardLeaders() throw
   @Test
   public void testIsDirectUpdatesToLeadersOnlyDefault() throws IOException {
     try (CloudSolrClient createdClient =
-        new CloudHttp2SolrClient.Builder(
-                Collections.singletonList(ANY_ZK_HOST), Optional.of(ANY_CHROOT))
+        new CloudSolrClient.Builder(Collections.singletonList(ANY_ZK_HOST), Optional.of(ANY_CHROOT))
             .build()) {
       assertFalse(createdClient.isDirectUpdatesToLeadersOnly());
     }
@@ -126,29 +124,28 @@ public void testExternalClientAndInternalBuilderTogether() {
     expectThrows(
         IllegalStateException.class,
         () ->
-            new CloudHttp2SolrClient.Builder(
+            new CloudSolrClient.Builder(
                     Collections.singletonList(ANY_ZK_HOST), Optional.of(ANY_CHROOT))
-                .withHttpClient(mock(Http2SolrClient.class))
-                .withHttpClientBuilder(mock(Http2SolrClient.Builder.class))
+                .withHttpClient(mock(HttpJettySolrClient.class))
+                .withHttpClientBuilder(mock(HttpJettySolrClient.Builder.class))
                 .build());
     expectThrows(
         IllegalStateException.class,
         () ->
-            new CloudHttp2SolrClient.Builder(
+            new CloudSolrClient.Builder(
                     Collections.singletonList(ANY_ZK_HOST), Optional.of(ANY_CHROOT))
-                .withHttpClientBuilder(mock(Http2SolrClient.Builder.class))
-                .withHttpClient(mock(Http2SolrClient.class))
+                .withHttpClientBuilder(mock(HttpJettySolrClient.Builder.class))
+                .withHttpClient(mock(HttpJettySolrClient.class))
                 .build());
   }
 
   @Test
   public void testProvideInternalJettyClientBuilder() throws IOException {
-    Http2SolrClient http2Client = mock(Http2SolrClient.class);
-    Http2SolrClient.Builder http2ClientBuilder = mock(Http2SolrClient.Builder.class);
+    HttpJettySolrClient http2Client = mock(HttpJettySolrClient.class);
+    HttpJettySolrClient.Builder http2ClientBuilder = mock(HttpJettySolrClient.Builder.class);
     when(http2ClientBuilder.build()).thenReturn(http2Client);
-    CloudHttp2SolrClient.Builder clientBuilder =
-        new CloudHttp2SolrClient.Builder(
-                Collections.singletonList(ANY_ZK_HOST), Optional.of(ANY_CHROOT))
+    CloudSolrClient.Builder clientBuilder =
+        new CloudSolrClient.Builder(Collections.singletonList(ANY_ZK_HOST), Optional.of(ANY_CHROOT))
             .withHttpClientBuilder(http2ClientBuilder);
     verify(http2ClientBuilder, never()).build();
     try (CloudHttp2SolrClient client = clientBuilder.build()) {
@@ -165,9 +162,8 @@ public void testProvideInternalJdkClientBuilder() throws IOException {
     var http2Client = mock(HttpJdkSolrClient.class);
     HttpJdkSolrClient.Builder http2ClientBuilder = mock(HttpJdkSolrClient.Builder.class);
     when(http2ClientBuilder.build()).thenReturn(http2Client);
-    CloudHttp2SolrClient.Builder clientBuilder =
-        new CloudHttp2SolrClient.Builder(
-                Collections.singletonList(ANY_ZK_HOST), Optional.of(ANY_CHROOT))
+    CloudSolrClient.Builder clientBuilder =
+        new CloudSolrClient.Builder(Collections.singletonList(ANY_ZK_HOST), Optional.of(ANY_CHROOT))
             .withHttpClientBuilder(http2ClientBuilder);
     verify(http2ClientBuilder, never()).build();
     try (CloudHttp2SolrClient client = clientBuilder.build()) {
@@ -181,10 +177,9 @@ public void testProvideInternalJdkClientBuilder() throws IOException {
 
   @Test
   public void testProvideExternalJettyClient() throws IOException {
-    Http2SolrClient http2Client = mock(Http2SolrClient.class);
-    CloudHttp2SolrClient.Builder clientBuilder =
-        new CloudHttp2SolrClient.Builder(
-                Collections.singletonList(ANY_ZK_HOST), Optional.of(ANY_CHROOT))
+    HttpJettySolrClient http2Client = mock(HttpJettySolrClient.class);
+    CloudSolrClient.Builder clientBuilder =
+        new CloudSolrClient.Builder(Collections.singletonList(ANY_ZK_HOST), Optional.of(ANY_CHROOT))
             .withHttpClient(http2Client);
     try (CloudHttp2SolrClient client = clientBuilder.build()) {
       assertEquals(http2Client, client.getHttpClient());
@@ -196,9 +191,8 @@ public void testProvideExternalJettyClient() throws IOException {
   @Test
   public void testProvideExternalJdkClient() throws IOException {
     HttpJdkSolrClient http2Client = mock(HttpJdkSolrClient.class);
-    CloudHttp2SolrClient.Builder clientBuilder =
-        new CloudHttp2SolrClient.Builder(
-                Collections.singletonList(ANY_ZK_HOST), Optional.of(ANY_CHROOT))
+    CloudSolrClient.Builder clientBuilder =
+        new CloudSolrClient.Builder(Collections.singletonList(ANY_ZK_HOST), Optional.of(ANY_CHROOT))
             .withHttpClient(http2Client);
     try (CloudHttp2SolrClient client = clientBuilder.build()) {
       assertEquals(http2Client, client.getHttpClient());
@@ -210,19 +204,17 @@ public void testProvideExternalJdkClient() throws IOException {
   @Test
   public void testDefaultClientUsesJetty() throws IOException {
     try (CloudHttp2SolrClient createdClient =
-        new CloudHttp2SolrClient.Builder(
-                Collections.singletonList(ANY_ZK_HOST), Optional.of(ANY_CHROOT))
+        new CloudSolrClient.Builder(Collections.singletonList(ANY_ZK_HOST), Optional.of(ANY_CHROOT))
             .build()) {
-      assertTrue(createdClient.getHttpClient() instanceof Http2SolrClient);
-      assertTrue(createdClient.getLbClient().getClient(null) instanceof Http2SolrClient);
+      assertTrue(createdClient.getHttpClient() instanceof HttpJettySolrClient);
+      assertTrue(createdClient.getLbClient().getClient(null) instanceof HttpJettySolrClient);
     }
   }
 
   @Test
   public void testDefaultCollectionPassedFromBuilderToClient() throws IOException {
     try (CloudHttp2SolrClient createdClient =
-        new CloudHttp2SolrClient.Builder(
-                Collections.singletonList(ANY_ZK_HOST), Optional.of(ANY_CHROOT))
+        new CloudSolrClient.Builder(Collections.singletonList(ANY_ZK_HOST), Optional.of(ANY_CHROOT))
             .withDefaultCollection("aCollection")
             .build()) {
       assertEquals("aCollection", createdClient.getDefaultCollection());
@@ -231,10 +223,10 @@ public void testDefaultCollectionPassedFromBuilderToClient() throws IOException
 
   /**
    * Tests the consistency between the HTTP client used by {@link CloudHttp2SolrClient} and the one
-   * used by its associated {@link Http2ClusterStateProvider}. This method ensures that whether a
+   * used by its associated {@link HttpClusterStateProvider}. This method ensures that whether a
    * {@link CloudHttp2SolrClient} is created with a specific HTTP client, an internal client
    * builder, or with no specific HTTP client at all, the same HTTP client instance is used both by
-   * the {@link CloudHttp2SolrClient} and by its {@link Http2ClusterStateProvider}.
+   * the {@link CloudHttp2SolrClient} and by its {@link HttpClusterStateProvider}.
    */
   @Test
   public void testHttpClientPreservedInHttp2ClusterStateProvider() throws IOException {
@@ -244,21 +236,21 @@ public void testHttpClientPreservedInHttp2ClusterStateProvider() throws IOExcept
     testHttpClientConsistency(solrUrls, null, null);
 
     // httpClient - No internalClientBuilder
-    try (Http2SolrClient httpClient = new Http2SolrClient.Builder().build()) {
+    try (var httpClient = new HttpJettySolrClient.Builder().build()) {
       testHttpClientConsistency(solrUrls, httpClient, null);
     }
 
     // No httpClient - internalClientBuilder
-    Http2SolrClient.Builder internalClientBuilder = new Http2SolrClient.Builder();
+    var internalClientBuilder = new HttpJettySolrClient.Builder();
     testHttpClientConsistency(solrUrls, null, internalClientBuilder);
   }
 
   private void testHttpClientConsistency(
       List solrUrls,
-      Http2SolrClient httpClient,
-      Http2SolrClient.Builder internalClientBuilder)
+      HttpJettySolrClient httpClient,
+      HttpJettySolrClient.Builder internalClientBuilder)
       throws IOException {
-    CloudHttp2SolrClient.Builder clientBuilder = new CloudHttp2SolrClient.Builder(solrUrls);
+    CloudSolrClient.Builder clientBuilder = new CloudSolrClient.Builder(solrUrls);
 
     if (httpClient != null) {
       clientBuilder.withHttpClient(httpClient);
@@ -269,14 +261,13 @@ private void testHttpClientConsistency(
     try (CloudHttp2SolrClient client = clientBuilder.build()) {
       assertEquals(
           client.getHttpClient(),
-          ((Http2ClusterStateProvider) client.getClusterStateProvider()).getHttpClient());
+          ((HttpClusterStateProvider) client.getClusterStateProvider()).getHttpClient());
     }
   }
 
   public void testCustomStateProvider() throws IOException {
     ZkClientClusterStateProvider stateProvider = mock(ZkClientClusterStateProvider.class);
-    try (CloudSolrClient cloudSolrClient =
-        new CloudHttp2SolrClient.Builder(stateProvider).build()) {
+    try (CloudSolrClient cloudSolrClient = new CloudSolrClient.Builder(stateProvider).build()) {
       assertEquals(stateProvider, cloudSolrClient.getClusterStateProvider());
     }
     verify(stateProvider, times(1)).close();
@@ -286,7 +277,7 @@ public void testCustomStateProvider() throws IOException {
   @SuppressWarnings({"try"})
   public void test0Timeouts() throws IOException {
     try (CloudSolrClient createdClient =
-        new CloudHttp2SolrClient.Builder(Collections.singletonList(ANY_ZK_HOST), Optional.empty())
+        new CloudSolrClient.Builder(Collections.singletonList(ANY_ZK_HOST), Optional.empty())
             .withZkConnectTimeout(0, TimeUnit.MILLISECONDS)
             .withZkClientTimeout(0, TimeUnit.MILLISECONDS)
             .build()) {
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudHttp2SolrClientMultiConstructorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudHttp2SolrClientMultiConstructorTest.java
index c4210bab7b4..5442d705860 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudHttp2SolrClientMultiConstructorTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudHttp2SolrClientMultiConstructorTest.java
@@ -69,7 +69,7 @@ public void testZkConnectionStringConstructorWithValidChroot() throws IOExceptio
     }
 
     try (CloudSolrClient client =
-        new CloudHttp2SolrClient.Builder(new ArrayList<>(hosts), Optional.ofNullable(clientChroot))
+        new CloudSolrClient.Builder(new ArrayList<>(hosts), Optional.ofNullable(clientChroot))
             .build()) {
       try (ZkClientClusterStateProvider zkClientClusterStateProvider =
           ZkClientClusterStateProvider.from(client)) {
@@ -82,6 +82,6 @@ public void testZkConnectionStringConstructorWithValidChroot() throws IOExceptio
   public void testBadChroot() {
     final List zkHosts = new ArrayList<>();
     zkHosts.add("host1:2181");
-    new CloudHttp2SolrClient.Builder(zkHosts, Optional.of("foo")).build();
+    new CloudSolrClient.Builder(zkHosts, Optional.of("foo")).build();
   }
 }
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudHttp2SolrClientRetryTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudHttp2SolrClientRetryTest.java
index 58b1b2db48c..9584ffc65cc 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudHttp2SolrClientRetryTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudHttp2SolrClientRetryTest.java
@@ -21,6 +21,7 @@
 
 import java.util.Collections;
 import java.util.Optional;
+import org.apache.solr.client.solrj.jetty.HttpJettySolrClient;
 import org.apache.solr.client.solrj.request.CollectionAdminRequest;
 import org.apache.solr.cloud.SolrCloudTestCase;
 import org.apache.solr.common.SolrInputDocument;
@@ -49,7 +50,7 @@ public static void setupCluster() throws Exception {
   public void testRetry() throws Exception {
 
     // Randomly decide to use either the Jetty Http Client or the JDK Http Client
-    var jettyClientBuilder = new Http2SolrClient.Builder();
+    var jettyClientBuilder = new HttpJettySolrClient.Builder();
 
     // forcing Http/1.1 to avoid an extra HEAD request with the first update.
     // (This causes the counts to be 1 greater than what we test for here.)
@@ -59,7 +60,7 @@ public void testRetry() throws Exception {
             .withSSLContext(MockTrustManager.ALL_TRUSTING_SSL_CONTEXT);
 
     var cloudSolrclientBuilder =
-        new CloudHttp2SolrClient.Builder(
+        new CloudSolrClient.Builder(
             Collections.singletonList(cluster.getZkServer().getZkAddress()), Optional.empty());
     cloudSolrclientBuilder.withHttpClientBuilder(
         random().nextBoolean() ? jettyClientBuilder : jdkClientBuilder);
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudHttp2SolrClientTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudHttp2SolrClientTest.java
index 8697baf87a8..22d581bd4b7 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudHttp2SolrClientTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/CloudHttp2SolrClientTest.java
@@ -44,6 +44,7 @@
 import org.apache.solr.client.solrj.SolrServerException;
 import org.apache.solr.client.solrj.apache.CloudLegacySolrClient;
 import org.apache.solr.client.solrj.apache.HttpClientUtil;
+import org.apache.solr.client.solrj.jetty.HttpJettySolrClient;
 import org.apache.solr.client.solrj.request.AbstractUpdateRequest;
 import org.apache.solr.client.solrj.request.CollectionAdminRequest;
 import org.apache.solr.client.solrj.request.GenericSolrRequest;
@@ -121,20 +122,20 @@ public static void setupCluster() throws Exception {
     solrUrls.add(cluster.getJettySolrRunner(0).getBaseUrl().toString());
 
     httpJettyBasedCloudSolrClient =
-        new CloudHttp2SolrClient.Builder(solrUrls)
-            .withHttpClientBuilder(new Http2SolrClient.Builder())
+        new CloudSolrClient.Builder(solrUrls)
+            .withHttpClientBuilder(new HttpJettySolrClient.Builder())
             .build();
-    assertTrue(httpJettyBasedCloudSolrClient.getHttpClient() instanceof Http2SolrClient);
+    assertTrue(httpJettyBasedCloudSolrClient.getHttpClient() instanceof HttpJettySolrClient);
     assertTrue(
         httpJettyBasedCloudSolrClient.getClusterStateProvider()
-            instanceof Http2ClusterStateProvider);
+            instanceof HttpClusterStateProvider);
     assertTrue(
-        ((Http2ClusterStateProvider) httpJettyBasedCloudSolrClient.getClusterStateProvider())
+        ((HttpClusterStateProvider) httpJettyBasedCloudSolrClient.getClusterStateProvider())
                 .getHttpClient()
-            instanceof Http2SolrClient);
+            instanceof HttpJettySolrClient);
 
     httpJdkBasedCloudSolrClient =
-        new CloudHttp2SolrClient.Builder(solrUrls)
+        new CloudSolrClient.Builder(solrUrls)
             .withHttpClientBuilder(
                 new HttpJdkSolrClient.Builder()
                     .withSSLContext(MockTrustManager.ALL_TRUSTING_SSL_CONTEXT))
@@ -142,17 +143,17 @@ public static void setupCluster() throws Exception {
     assertTrue(httpJdkBasedCloudSolrClient.getHttpClient() instanceof HttpJdkSolrClient);
     assertTrue(
         httpJdkBasedCloudSolrClient.getClusterStateProvider()
-            instanceof Http2ClusterStateProvider);
+            instanceof HttpClusterStateProvider);
     assertTrue(
-        ((Http2ClusterStateProvider) httpJdkBasedCloudSolrClient.getClusterStateProvider())
+        ((HttpClusterStateProvider) httpJdkBasedCloudSolrClient.getClusterStateProvider())
                 .getHttpClient()
             instanceof HttpJdkSolrClient);
 
     zkBasedCloudSolrClient =
-        new CloudHttp2SolrClient.Builder(
+        new CloudSolrClient.Builder(
                 Collections.singletonList(cluster.getZkServer().getZkAddress()), Optional.empty())
             .build();
-    assertTrue(zkBasedCloudSolrClient.getHttpClient() instanceof Http2SolrClient);
+    assertTrue(zkBasedCloudSolrClient.getHttpClient() instanceof HttpJettySolrClient);
     assertTrue(
         zkBasedCloudSolrClient.getClusterStateProvider() instanceof ZkClientClusterStateProvider);
   }
@@ -345,7 +346,7 @@ public void testHttpCspPerf() throws Exception {
   private CloudSolrClient createHttpCSPBasedCloudSolrClient() {
     final List solrUrls = new ArrayList<>();
     solrUrls.add(cluster.getJettySolrRunner(0).getBaseUrl().toString());
-    return new CloudHttp2SolrClient.Builder(solrUrls).build();
+    return new CloudSolrClient.Builder(solrUrls).build();
   }
 
   @Test
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ClusterStateProviderTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ClusterStateProviderTest.java
index 7af3580e687..80f7b5e625b 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ClusterStateProviderTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ClusterStateProviderTest.java
@@ -35,6 +35,7 @@
 import java.util.function.Supplier;
 import org.apache.solr.client.solrj.SolrRequest;
 import org.apache.solr.client.solrj.SolrServerException;
+import org.apache.solr.client.solrj.jetty.HttpJettySolrClient;
 import org.apache.solr.client.solrj.request.CollectionAdminRequest;
 import org.apache.solr.client.solrj.response.CollectionAdminResponse;
 import org.apache.solr.cloud.SolrCloudTestCase;
@@ -101,9 +102,9 @@ public static Iterable parameters() throws NoSuchMethodException {
         new String[] {"http2ClusterStateProvider"}, new String[] {"zkClientClusterStateProvider"});
   }
 
-  static class ClosingHttp2ClusterStateProvider
-      extends Http2ClusterStateProvider {
-    public ClosingHttp2ClusterStateProvider(List solrUrls, HttpSolrClientBase httpClient)
+  static class ClosingHttpClusterStateProvider
+      extends HttpClusterStateProvider {
+    public ClosingHttpClusterStateProvider(List solrUrls, HttpSolrClientBase httpClient)
         throws Exception {
       super(solrUrls, httpClient);
     }
@@ -119,7 +120,7 @@ public void close() throws IOException {
     }
   }
 
-  private static Http2ClusterStateProvider http2ClusterStateProvider(String userAgent) {
+  private static HttpClusterStateProvider http2ClusterStateProvider(String userAgent) {
     try {
       var useJdkProvider = random().nextBoolean();
       HttpSolrClientBase client;
@@ -132,7 +133,7 @@ private static Http2ClusterStateProvider http2ClusterStateProvider(String use
                       .withSSLContext(MockTrustManager.ALL_TRUSTING_SSL_CONTEXT),
                   userAgent);
         } else {
-          var http2SolrClient = new Http2SolrClient.Builder().build();
+          var http2SolrClient = new HttpJettySolrClient.Builder().build();
           http2SolrClient
               .getHttpClient()
               .setUserAgentField(new HttpField(HttpHeader.USER_AGENT, userAgent));
@@ -144,13 +145,13 @@ private static Http2ClusterStateProvider http2ClusterStateProvider(String use
                 ? new HttpJdkSolrClient.Builder()
                     .withSSLContext(MockTrustManager.ALL_TRUSTING_SSL_CONTEXT)
                     .build()
-                : new Http2SolrClient.Builder().build();
+                : new HttpJettySolrClient.Builder().build();
       }
       var clientClassName = client.getClass().getName();
       log.info("Using Http client implementation: {}", clientClassName);
 
       var csp =
-          new ClosingHttp2ClusterStateProvider(
+          new ClosingHttpClusterStateProvider(
               List.of(
                   cluster.getJettySolrRunner(0).getBaseUrl().toString(),
                   cluster.getJettySolrRunner(1).getBaseUrl().toString()),
@@ -161,7 +162,7 @@ private static Http2ClusterStateProvider http2ClusterStateProvider(String use
     }
   }
 
-  private static Http2ClusterStateProvider http2ClusterStateProvider() {
+  private static HttpClusterStateProvider http2ClusterStateProvider() {
     return http2ClusterStateProvider(null);
   }
 
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/HttpClusterStateSSLTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/HttpClusterStateSSLTest.java
index b791a0286d1..4fde78387a4 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/HttpClusterStateSSLTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/HttpClusterStateSSLTest.java
@@ -83,19 +83,17 @@ public void testHttpClusterStateWithSSL() throws Exception {
 
     // verify the http derived cluster state (on the client side) agrees with what the server stored
     try (CloudSolrClient httpBasedCloudSolrClient =
-        new CloudHttp2SolrClient.Builder(Collections.singletonList(url0.toExternalForm()))
-            .build()) {
+        new CloudSolrClient.Builder(Collections.singletonList(url0.toExternalForm())).build()) {
       ClusterStateProvider csp = httpBasedCloudSolrClient.getClusterStateProvider();
-      assertTrue(csp instanceof Http2ClusterStateProvider);
+      assertTrue(csp instanceof HttpClusterStateProvider);
       verifyUrlSchemeInClusterState(csp.getCollection(collectionId), expectedReplicas);
     }
 
     // http2
     try (CloudSolrClient http2BasedClient =
-        new CloudHttp2SolrClient.Builder(Collections.singletonList(url0.toExternalForm()))
-            .build()) {
+        new CloudSolrClient.Builder(Collections.singletonList(url0.toExternalForm())).build()) {
       ClusterStateProvider csp = http2BasedClient.getClusterStateProvider();
-      assertTrue(csp instanceof Http2ClusterStateProvider);
+      assertTrue(csp instanceof HttpClusterStateProvider);
       verifyUrlSchemeInClusterState(csp.getCollection(collectionId), expectedReplicas);
     }
 
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/LB2SolrClientTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/LB2SolrClientTest.java
index ed0975b5181..f8d388b239d 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/LB2SolrClientTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/LB2SolrClientTest.java
@@ -31,6 +31,7 @@
 import org.apache.solr.client.solrj.SolrClient;
 import org.apache.solr.client.solrj.SolrQuery;
 import org.apache.solr.client.solrj.SolrServerException;
+import org.apache.solr.client.solrj.jetty.HttpJettySolrClient;
 import org.apache.solr.client.solrj.response.QueryResponse;
 import org.apache.solr.client.solrj.response.SolrResponseBase;
 import org.apache.solr.common.SolrInputDocument;
@@ -114,7 +115,7 @@ public void tearDown() throws Exception {
   private LBClientHolder client(LBSolrClient.Endpoint... baseSolrEndpoints) {
     if (random().nextBoolean()) {
       var delegateClient =
-          new Http2SolrClient.Builder()
+          new HttpJettySolrClient.Builder()
               .withConnectionTimeout(1000, TimeUnit.MILLISECONDS)
               .withIdleTimeout(2000, TimeUnit.MILLISECONDS)
               .build();
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/LBAsyncSolrClientTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/LBAsyncSolrClientTest.java
index a83bd793b49..fafe1557819 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/LBAsyncSolrClientTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/LBAsyncSolrClientTest.java
@@ -29,6 +29,7 @@
 import org.apache.solr.client.solrj.SolrClientFunction;
 import org.apache.solr.client.solrj.SolrRequest;
 import org.apache.solr.client.solrj.SolrServerException;
+import org.apache.solr.client.solrj.jetty.HttpJettySolrClient;
 import org.apache.solr.client.solrj.jetty.LBJettySolrClient;
 import org.apache.solr.client.solrj.request.QueryRequest;
 import org.apache.solr.common.SolrException;
@@ -45,8 +46,9 @@ public void testSynchronous() throws Exception {
     LBSolrClient.Endpoint ep2 = new LBSolrClient.Endpoint("http://endpoint.two");
     List endpointList = List.of(ep1, ep2);
 
-    Http2SolrClient.Builder b =
-        new Http2SolrClient.Builder("http://base.url").withConnectionTimeout(10, TimeUnit.SECONDS);
+    var b =
+        new HttpJettySolrClient.Builder("http://base.url")
+            .withConnectionTimeout(10, TimeUnit.SECONDS);
 
     try (MockHttpSolrClient client = new MockHttpSolrClient("http://base.url", b);
         var testClient = new LBJettySolrClient.Builder(client, ep1, ep2).build()) {
@@ -73,8 +75,9 @@ public void testSynchronousWithFalures() throws Exception {
     LBSolrClient.Endpoint ep2 = new LBSolrClient.Endpoint("http://endpoint.two");
     List endpointList = List.of(ep1, ep2);
 
-    Http2SolrClient.Builder b =
-        new Http2SolrClient.Builder("http://base.url").withConnectionTimeout(10, TimeUnit.SECONDS);
+    var b =
+        new HttpJettySolrClient.Builder("http://base.url")
+            .withConnectionTimeout(10, TimeUnit.SECONDS);
 
     try (MockHttpSolrClient client = new MockHttpSolrClient("http://base.url", b);
         var testClient = new LBJettySolrClient.Builder(client, ep1, ep2).build()) {
@@ -131,8 +134,9 @@ public void testAsyncWithFailures() {
     LBSolrClient.Endpoint ep2 = new LBSolrClient.Endpoint("http://endpoint.two");
     List endpointList = List.of(ep1, ep2);
 
-    Http2SolrClient.Builder b =
-        new Http2SolrClient.Builder("http://base.url").withConnectionTimeout(10, TimeUnit.SECONDS);
+    var b =
+        new HttpJettySolrClient.Builder("http://base.url")
+            .withConnectionTimeout(10, TimeUnit.SECONDS);
 
     try (MockHttpSolrClient client = new MockHttpSolrClient("http://base.url", b);
         var testClient = new LBJettySolrClient.Builder(client, ep1, ep2).build()) {
@@ -195,8 +199,9 @@ public void testAsync() {
     LBSolrClient.Endpoint ep2 = new LBSolrClient.Endpoint("http://endpoint.two");
     List endpointList = List.of(ep1, ep2);
 
-    Http2SolrClient.Builder b =
-        new Http2SolrClient.Builder("http://base.url").withConnectionTimeout(10, TimeUnit.SECONDS);
+    var b =
+        new HttpJettySolrClient.Builder("http://base.url")
+            .withConnectionTimeout(10, TimeUnit.SECONDS);
     try (MockHttpSolrClient client = new MockHttpSolrClient("http://base.url", b);
         var testClient = new LBJettySolrClient.Builder(client, ep1, ep2).build()) {
 
@@ -253,7 +258,7 @@ public void testAsync() {
     }
   }
 
-  public static class MockHttpSolrClient extends Http2SolrClient {
+  public static class MockHttpSolrClient extends HttpJettySolrClient {
 
     public List> lastSolrRequests = new ArrayList<>();
 
@@ -287,7 +292,7 @@ public NamedList request(final SolrRequest request, String collection
 
     @Override
     public  R requestWithBaseUrl(
-        String baseUrl, SolrClientFunction clientFunction)
+        String baseUrl, SolrClientFunction clientFunction)
         throws SolrServerException, IOException {
       // This use of 'tmpBaseUrl' is NOT thread safe, but that's fine for our purposes here.
       try {
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/SendUpdatesToLeadersOverrideTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/SendUpdatesToLeadersOverrideTest.java
index 48ca0bd515a..8c9f8a60245 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/SendUpdatesToLeadersOverrideTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/SendUpdatesToLeadersOverrideTest.java
@@ -215,7 +215,7 @@ public void testBuilderImplicitBehavior() throws Exception {
       assertTrue(client.isUpdatesToLeaders());
     }
     try (CloudSolrClient client =
-        new CloudHttp2SolrClient.Builder(
+        new CloudSolrClient.Builder(
                 Collections.singletonList(cluster.getZkServer().getZkAddress()), Optional.empty())
             .build()) {
       assertTrue(client.isUpdatesToLeaders());
@@ -246,7 +246,7 @@ public void testLegacyClientThatDoesNotDefaultToLeaders() throws Exception {
 
   public void testHttp2ClientThatDefaultsToLeaders() throws Exception {
     try (CloudSolrClient client =
-        new CloudHttp2SolrClient.Builder(
+        new CloudSolrClient.Builder(
                 Collections.singletonList(cluster.getZkServer().getZkAddress()), Optional.empty())
             .sendUpdatesOnlyToShardLeaders()
             .build()) {
@@ -257,7 +257,7 @@ public void testHttp2ClientThatDefaultsToLeaders() throws Exception {
 
   public void testHttp2ClientThatDoesNotDefaultToLeaders() throws Exception {
     try (CloudSolrClient client =
-        new CloudHttp2SolrClient.Builder(
+        new CloudSolrClient.Builder(
                 Collections.singletonList(cluster.getZkServer().getZkAddress()), Optional.empty())
             .sendUpdatesToAnyReplica()
             .build()) {
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ConcurrentUpdateJettySolrClientBadInputTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/jetty/ConcurrentUpdateJettySolrClientBadInputTest.java
similarity index 95%
rename from solr/solrj/src/test/org/apache/solr/client/solrj/impl/ConcurrentUpdateJettySolrClientBadInputTest.java
rename to solr/solrj/src/test/org/apache/solr/client/solrj/jetty/ConcurrentUpdateJettySolrClientBadInputTest.java
index e6adb0d0987..e2e2d18b832 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ConcurrentUpdateJettySolrClientBadInputTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/jetty/ConcurrentUpdateJettySolrClientBadInputTest.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.solr.client.solrj.impl;
+package org.apache.solr.client.solrj.jetty;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -40,7 +40,7 @@ public static void beforeTest() throws Exception {
   @Test
   public void testDeleteByIdReportsInvalidIdLists() throws Exception {
 
-    try (Http2SolrClient http2Client = new Http2SolrClient.Builder().build();
+    try (var http2Client = new HttpJettySolrClient.Builder().build();
         var client =
             new ConcurrentUpdateJettySolrClient.Builder(getBaseUrl(), http2Client)
                 .withDefaultCollection(ANY_COLLECTION)
@@ -73,7 +73,7 @@ public void testDeleteByIdReportsInvalidIdLists() throws Exception {
           });
     }
 
-    try (Http2SolrClient http2Client = new Http2SolrClient.Builder().build();
+    try (var http2Client = new HttpJettySolrClient.Builder().build();
         var client =
             new ConcurrentUpdateJettySolrClient.Builder(getBaseUrl(), http2Client)
                 .withDefaultCollection(ANY_COLLECTION)
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ConcurrentUpdateJettySolrClientMultiCollectionTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/jetty/ConcurrentUpdateJettySolrClientMultiCollectionTest.java
similarity index 96%
rename from solr/solrj/src/test/org/apache/solr/client/solrj/impl/ConcurrentUpdateJettySolrClientMultiCollectionTest.java
rename to solr/solrj/src/test/org/apache/solr/client/solrj/jetty/ConcurrentUpdateJettySolrClientMultiCollectionTest.java
index ef8ae2927cc..c8f23aaf673 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ConcurrentUpdateJettySolrClientMultiCollectionTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/jetty/ConcurrentUpdateJettySolrClientMultiCollectionTest.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.solr.client.solrj.impl;
+package org.apache.solr.client.solrj.jetty;
 
 import java.io.IOException;
 import org.apache.solr.client.solrj.SolrClient;
@@ -65,7 +65,7 @@ public void deleteCollections() throws Exception {
   public void testEnsureDocumentsSentToCorrectCollection() throws Exception {
     int numTotalDocs = 1000;
     int numExpectedPerCollection = numTotalDocs / 2;
-    try (Http2SolrClient http2Client = new Http2SolrClient.Builder().build();
+    try (var http2Client = new HttpJettySolrClient.Builder().build();
         var client =
             new ConcurrentUpdateJettySolrClient.Builder(solrUrl, http2Client)
                 .withQueueSize(numTotalDocs)
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ConcurrentUpdateJettySolrClientTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/jetty/ConcurrentUpdateJettySolrClientTest.java
similarity index 96%
rename from solr/solrj/src/test/org/apache/solr/client/solrj/impl/ConcurrentUpdateJettySolrClientTest.java
rename to solr/solrj/src/test/org/apache/solr/client/solrj/jetty/ConcurrentUpdateJettySolrClientTest.java
index 39a1e75e400..3850d8f45da 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ConcurrentUpdateJettySolrClientTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/jetty/ConcurrentUpdateJettySolrClientTest.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.solr.client.solrj.impl;
+package org.apache.solr.client.solrj.jetty;
 
 import jakarta.servlet.ServletException;
 import jakarta.servlet.http.HttpServlet;
@@ -188,7 +188,7 @@ public void testConcurrentUpdate() throws Exception {
     final AtomicInteger errorCounter = new AtomicInteger(0);
     final StringBuilder errors = new StringBuilder();
 
-    try (Http2SolrClient http2Client = new Http2SolrClient.Builder().build();
+    try (var http2Client = new HttpJettySolrClient.Builder().build();
         var concurrentClient =
             new OutcomeCountingConcurrentUpdateSolrClient.Builder(
                     serverUrl, http2Client, successCounter, errorCounter, errors)
@@ -246,7 +246,7 @@ public void testCollectionParameters() throws IOException, SolrServerException {
     int cussThreadCount = 2;
     int cussQueueSize = 10;
 
-    try (Http2SolrClient http2Client = new Http2SolrClient.Builder().build();
+    try (var http2Client = new HttpJettySolrClient.Builder().build();
         var concurrentClient =
             (new ConcurrentUpdateJettySolrClient.Builder(getBaseUrl(), http2Client))
                 .withQueueSize(cussQueueSize)
@@ -266,7 +266,7 @@ public void testCollectionParameters() throws IOException, SolrServerException {
               .getNumFound());
     }
 
-    try (Http2SolrClient http2Client = new Http2SolrClient.Builder().build();
+    try (var http2Client = new HttpJettySolrClient.Builder().build();
         var concurrentClient =
             new ConcurrentUpdateJettySolrClient.Builder(getBaseUrl(), http2Client)
                 .withDefaultCollection(DEFAULT_TEST_CORENAME)
@@ -288,7 +288,7 @@ public void testConcurrentCollectionUpdate() throws Exception {
     int numRunnables = 5;
     int expected = numDocs * numRunnables;
 
-    try (Http2SolrClient http2Client = new Http2SolrClient.Builder().build();
+    try (var http2Client = new HttpJettySolrClient.Builder().build();
         var concurrentClient =
             new ConcurrentUpdateJettySolrClient.Builder(getBaseUrl(), http2Client)
                 .withQueueSize(cussQueueSize)
@@ -325,7 +325,7 @@ public void testConcurrentCollectionUpdate() throws Exception {
       concurrentClient.shutdownNow();
     }
 
-    try (Http2SolrClient http2Client = new Http2SolrClient.Builder().build();
+    try (var http2Client = new HttpJettySolrClient.Builder().build();
         var concurrentClient =
             new ConcurrentUpdateJettySolrClient.Builder(getBaseUrl(), http2Client)
                 .withDefaultCollection(DEFAULT_TEST_CORENAME)
@@ -369,7 +369,7 @@ static class Builder extends ConcurrentUpdateJettySolrClient.Builder {
 
       public Builder(
           String baseSolrUrl,
-          Http2SolrClient http2Client,
+          HttpJettySolrClient http2Client,
           AtomicInteger successCounter,
           AtomicInteger failureCounter,
           StringBuilder errors) {
@@ -395,7 +395,7 @@ public void testSocketTimeoutOnCommit() throws IOException, SolrServerException
     InetAddress localHost = InetAddress.getLocalHost();
     try (ServerSocket server = new ServerSocket(0, 1, localHost);
         var http2Client =
-            new Http2SolrClient.Builder().withIdleTimeout(1, TimeUnit.MILLISECONDS).build();
+            new HttpJettySolrClient.Builder().withIdleTimeout(1, TimeUnit.MILLISECONDS).build();
         var client =
             new ConcurrentUpdateJettySolrClient.Builder(
                     "http://"
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/Http2SolrClientCompatibilityTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/jetty/HttpJettySolrClientCompatibilityTest.java
similarity index 87%
rename from solr/solrj/src/test/org/apache/solr/client/solrj/impl/Http2SolrClientCompatibilityTest.java
rename to solr/solrj/src/test/org/apache/solr/client/solrj/jetty/HttpJettySolrClientCompatibilityTest.java
index fbc3cb394cf..68f1b663a9f 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/Http2SolrClientCompatibilityTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/jetty/HttpJettySolrClientCompatibilityTest.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.solr.client.solrj.impl;
+package org.apache.solr.client.solrj.jetty;
 
 import org.apache.solr.SolrJettyTestBase;
 import org.apache.solr.SolrTestCaseJ4;
@@ -32,15 +32,15 @@
 
 @LogLevel("org.eclipse.jetty.client=DEBUG;org.eclipse.jetty.util=DEBUG")
 @SolrTestCaseJ4.SuppressSSL
-public class Http2SolrClientCompatibilityTest extends SolrJettyTestBase {
+public class HttpJettySolrClientCompatibilityTest extends SolrJettyTestBase {
 
   public void testSystemPropertyFlag() {
     System.setProperty("solr.http1", "true");
-    try (Http2SolrClient client = new Http2SolrClient.Builder().build()) {
+    try (var client = new HttpJettySolrClient.Builder().build()) {
       assertTrue(client.getHttpClient().getTransport() instanceof HttpClientTransportOverHTTP);
     }
     System.clearProperty("solr.http1");
-    try (Http2SolrClient client = new Http2SolrClient.Builder().build()) {
+    try (var client = new HttpJettySolrClient.Builder().build()) {
       assertTrue(client.getHttpClient().getTransport() instanceof HttpClientTransportOverHTTP2);
     }
   }
@@ -54,8 +54,8 @@ public void testConnectToOldNodesUsingHttp1() throws Exception {
             .build();
     createAndStartJetty(legacyExampleCollection1SolrHome(), jettyConfig);
 
-    try (Http2SolrClient client =
-        new Http2SolrClient.Builder(getBaseUrl() + "/debug/foo").useHttp1_1(true).build()) {
+    try (var client =
+        new HttpJettySolrClient.Builder(getBaseUrl() + "/debug/foo").useHttp1_1(true).build()) {
       assertTrue(client.getHttpClient().getTransport() instanceof HttpClientTransportOverHTTP);
       try {
         client.query(new SolrQuery("*:*"), SolrRequest.METHOD.GET);
@@ -75,8 +75,8 @@ public void testConnectToNewNodesUsingHttp1() throws Exception {
             .build();
     createAndStartJetty(legacyExampleCollection1SolrHome(), jettyConfig);
 
-    try (Http2SolrClient client =
-        new Http2SolrClient.Builder(getBaseUrl() + "/debug/foo").useHttp1_1(true).build()) {
+    try (var client =
+        new HttpJettySolrClient.Builder(getBaseUrl() + "/debug/foo").useHttp1_1(true).build()) {
       assertTrue(client.getHttpClient().getTransport() instanceof HttpClientTransportOverHTTP);
       try {
         client.query(new SolrQuery("*:*"), SolrRequest.METHOD.GET);
@@ -100,8 +100,7 @@ public void testConnectToOldNodesUsingHttp2() throws Exception {
     createAndStartJetty(legacyExampleCollection1SolrHome(), jettyConfig);
 
     System.clearProperty("solr.http1");
-    try (Http2SolrClient client =
-        new Http2SolrClient.Builder(getBaseUrl() + "/debug/foo").build()) {
+    try (var client = new HttpJettySolrClient.Builder(getBaseUrl() + "/debug/foo").build()) {
       assertTrue(client.getHttpClient().getTransport() instanceof HttpClientTransportOverHTTP2);
       try {
         client.query(new SolrQuery("*:*"), SolrRequest.METHOD.GET);
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/Http2SolrClientProxyTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/jetty/HttpJettySolrClientProxyTest.java
similarity index 92%
rename from solr/solrj/src/test/org/apache/solr/client/solrj/impl/Http2SolrClientProxyTest.java
rename to solr/solrj/src/test/org/apache/solr/client/solrj/jetty/HttpJettySolrClientProxyTest.java
index 10dc7930cdf..221e1517f33 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/Http2SolrClientProxyTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/jetty/HttpJettySolrClientProxyTest.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.solr.client.solrj.impl;
+package org.apache.solr.client.solrj.jetty;
 
 import com.carrotsearch.randomizedtesting.RandomizedTest;
 import java.util.Arrays;
@@ -25,6 +25,8 @@
 import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.client.solrj.SolrQuery;
 import org.apache.solr.client.solrj.cloud.SocketProxy;
+import org.apache.solr.client.solrj.impl.HttpJdkSolrClient;
+import org.apache.solr.client.solrj.impl.HttpSolrClientBase;
 import org.apache.solr.common.SolrInputDocument;
 import org.apache.solr.embedded.JettyConfig;
 import org.apache.solr.util.ExternalPaths;
@@ -34,7 +36,7 @@
 import org.junit.ClassRule;
 import org.junit.Test;
 
-public class Http2SolrClientProxyTest extends SolrTestCaseJ4 {
+public class HttpJettySolrClientProxyTest extends SolrTestCaseJ4 {
 
   @ClassRule public static SolrJettyTestRule solrClientTestRule = new SolrJettyTestRule();
 
@@ -71,10 +73,10 @@ public void before() {
   public void testProxyWithHttp2SolrClient() throws Exception {
     assertNotNull(proxy);
     var builder =
-        new Http2SolrClient.Builder(url)
+        new HttpJettySolrClient.Builder(url)
             .withProxyConfiguration(host, proxy.getListenPort(), false, false);
 
-    try (Http2SolrClient client = builder.build()) {
+    try (HttpJettySolrClient client = builder.build()) {
       testProxy(client);
     }
   }
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/Http2SolrClientTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/jetty/HttpJettySolrClientTest.java
similarity index 80%
rename from solr/solrj/src/test/org/apache/solr/client/solrj/impl/Http2SolrClientTest.java
rename to solr/solrj/src/test/org/apache/solr/client/solrj/jetty/HttpJettySolrClientTest.java
index 856e2103abe..62d1cea2d76 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/Http2SolrClientTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/jetty/HttpJettySolrClientTest.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.solr.client.solrj.impl;
+package org.apache.solr.client.solrj.jetty;
 
 import static org.apache.solr.handler.admin.api.ReplicationAPIBase.FILE_STREAM;
 import static org.hamcrest.core.StringContains.containsStringIgnoringCase;
@@ -35,6 +35,14 @@
 import org.apache.solr.client.solrj.SolrQuery;
 import org.apache.solr.client.solrj.SolrRequest;
 import org.apache.solr.client.solrj.SolrServerException;
+import org.apache.solr.client.solrj.impl.HttpSolrClientBuilderBase;
+import org.apache.solr.client.solrj.impl.HttpSolrClientTestBase;
+import org.apache.solr.client.solrj.impl.InputStreamResponseParser;
+import org.apache.solr.client.solrj.impl.JavaBinRequestWriter;
+import org.apache.solr.client.solrj.impl.JavaBinResponseParser;
+import org.apache.solr.client.solrj.impl.SolrHttpConstants;
+import org.apache.solr.client.solrj.impl.XMLRequestWriter;
+import org.apache.solr.client.solrj.impl.XMLResponseParser;
 import org.apache.solr.client.solrj.request.QueryRequest;
 import org.apache.solr.client.solrj.request.SolrPing;
 import org.apache.solr.common.SolrException;
@@ -50,19 +58,19 @@
 import org.eclipse.jetty.util.ssl.SslContextFactory;
 import org.junit.Test;
 
-public class Http2SolrClientTest extends HttpSolrClientTestBase {
+public class HttpJettySolrClientTest extends HttpSolrClientTestBase {
 
   @Override
   protected String expectedUserAgent() {
-    return "Solr[" + Http2SolrClient.class.getName() + "] " + SolrVersion.LATEST_STRING;
+    return "Solr[" + HttpJettySolrClient.class.getName() + "] " + SolrVersion.LATEST_STRING;
   }
 
   @Override
   @SuppressWarnings(value = "unchecked")
   protected > B builder(
       String url, int connectionTimeout, int socketTimeout) {
-    Http2SolrClient.Builder b =
-        new Http2SolrClient.Builder(url)
+    var b =
+        new HttpJettySolrClient.Builder(url)
             .withConnectionTimeout(connectionTimeout, TimeUnit.MILLISECONDS)
             .withIdleTimeout(socketTimeout, TimeUnit.MILLISECONDS);
     return (B) b;
@@ -71,8 +79,8 @@ protected String expectedUserAgent() {
   @Test
   public void testTimeout() throws Exception {
     SolrQuery q = new SolrQuery("*:*");
-    try (Http2SolrClient client =
-        (Http2SolrClient)
+    try (HttpJettySolrClient client =
+        (HttpJettySolrClient)
             builder(getBaseUrl() + SLOW_SERVLET_PATH, DEFAULT_CONNECTION_TIMEOUT, 2000)
                 .withDefaultCollection(DEFAULT_CORE)
                 .build()) {
@@ -86,8 +94,8 @@ public void testTimeout() throws Exception {
   @Test
   public void test0IdleTimeout() throws Exception {
     SolrQuery q = new SolrQuery("*:*");
-    try (Http2SolrClient client =
-        (Http2SolrClient)
+    try (HttpJettySolrClient client =
+        (HttpJettySolrClient)
             builder(getBaseUrl() + DEBUG_SERVLET_PATH, DEFAULT_CONNECTION_TIMEOUT, 0)
                 .withDefaultCollection(DEFAULT_CORE)
                 .build()) {
@@ -101,8 +109,8 @@ public void test0IdleTimeout() throws Exception {
   @Test
   public void testRequestTimeout() throws Exception {
     SolrQuery q = new SolrQuery("*:*");
-    try (Http2SolrClient client =
-        (Http2SolrClient)
+    try (HttpJettySolrClient client =
+        (HttpJettySolrClient)
             builder(getBaseUrl() + SLOW_SERVLET_PATH, DEFAULT_CONNECTION_TIMEOUT, 0)
                 .withDefaultCollection(DEFAULT_CORE)
                 .withRequestTimeout(500, TimeUnit.MILLISECONDS)
@@ -120,8 +128,8 @@ public void testRequestTimeout() throws Exception {
    */
   @Test
   public void testSolrExceptionCodeNotFromSolr() throws IOException, SolrServerException {
-    try (Http2SolrClient client =
-        new Http2SolrClient.Builder(getBaseUrl() + DEBUG_SERVLET_PATH)
+    try (var client =
+        new HttpJettySolrClient.Builder(getBaseUrl() + DEBUG_SERVLET_PATH)
             .withDefaultCollection(DEFAULT_CORE)
             .build()) {
       super.testSolrExceptionCodeNotFromSolr(client);
@@ -136,7 +144,7 @@ public void testSolrExceptionWithNullBaseurl() throws IOException, SolrServerExc
     final int status = 527;
     DebugServlet.setErrorCode(status);
 
-    try (Http2SolrClient client = new Http2SolrClient.Builder(null).build()) {
+    try (var client = new HttpJettySolrClient.Builder(null).build()) {
       try {
         // if client base url is null, request url will be used in exception message
         client.requestWithBaseUrl(getBaseUrl() + DEBUG_SERVLET_PATH, new SolrPing(), DEFAULT_CORE);
@@ -159,12 +167,11 @@ protected void testQuerySetup(SolrRequest.METHOD method, ResponseParser rp) thro
     q.setParam("a", MUST_ENCODE);
     q.setParam("case_sensitive_param", "lowercase");
     q.setParam("CASE_SENSITIVE_PARAM", "uppercase");
-    Http2SolrClient.Builder b =
-        new Http2SolrClient.Builder(url).withDefaultCollection(DEFAULT_CORE);
+    var b = new HttpJettySolrClient.Builder(url).withDefaultCollection(DEFAULT_CORE);
     if (rp != null) {
       b.withResponseParser(rp);
     }
-    try (Http2SolrClient client = b.build()) {
+    try (HttpJettySolrClient client = b.build()) {
       client.query(q, method);
       assertEquals(
           client.getParser().getWriterType(), DebugServlet.parameters.get(CommonParams.WT)[0]);
@@ -218,8 +225,8 @@ public void testOverrideBaseUrl() throws Exception {
     queryParams.add("q", "*:*");
 
     // Ensure the correct URL is used by the lambda-based requestWithBaseUrl method
-    try (Http2SolrClient client =
-        new Http2SolrClient.Builder(defaultUrl).withDefaultCollection(DEFAULT_CORE).build()) {
+    try (var client =
+        new HttpJettySolrClient.Builder(defaultUrl).withDefaultCollection(DEFAULT_CORE).build()) {
       try {
         client.requestWithBaseUrl(urlToUse, (c) -> c.query(queryParams));
       } catch (SolrClient.RemoteSolrException rse) {
@@ -229,8 +236,8 @@ public void testOverrideBaseUrl() throws Exception {
     }
 
     // Ensure the correct URL is used by the SolrRequest-based requestWithBaseUrl method
-    try (Http2SolrClient client =
-        new Http2SolrClient.Builder(defaultUrl).withDefaultCollection(DEFAULT_CORE).build()) {
+    try (var client =
+        new HttpJettySolrClient.Builder(defaultUrl).withDefaultCollection(DEFAULT_CORE).build()) {
       try {
         client.requestWithBaseUrl(urlToUse, new QueryRequest(queryParams), null);
       } catch (SolrClient.RemoteSolrException rse) {
@@ -244,8 +251,8 @@ public void testOverrideBaseUrl() throws Exception {
   public void testDelete() throws Exception {
     DebugServlet.clear();
     String url = getBaseUrl() + DEBUG_SERVLET_PATH;
-    try (Http2SolrClient client =
-        new Http2SolrClient.Builder(url).withDefaultCollection(DEFAULT_CORE).build()) {
+    try (var client =
+        new HttpJettySolrClient.Builder(url).withDefaultCollection(DEFAULT_CORE).build()) {
       try {
         client.deleteById("id");
       } catch (SolrClient.RemoteSolrException ignored) {
@@ -259,8 +266,8 @@ public void testDelete() throws Exception {
   public void testDeleteXml() throws Exception {
     DebugServlet.clear();
     String url = getBaseUrl() + "/debug/foo";
-    try (Http2SolrClient client =
-        new Http2SolrClient.Builder(url)
+    try (var client =
+        new HttpJettySolrClient.Builder(url)
             .withDefaultCollection(DEFAULT_CORE)
             .withResponseParser(new XMLResponseParser())
             .build()) {
@@ -276,8 +283,8 @@ public void testDeleteXml() throws Exception {
   @Test
   public void testGetById() throws Exception {
     DebugServlet.clear();
-    try (Http2SolrClient client =
-        new Http2SolrClient.Builder(getBaseUrl() + DEBUG_SERVLET_PATH)
+    try (var client =
+        new HttpJettySolrClient.Builder(getBaseUrl() + DEBUG_SERVLET_PATH)
             .withDefaultCollection(DEFAULT_CORE)
             .build()) {
       super.testGetById(client);
@@ -287,8 +294,8 @@ public void testGetById() throws Exception {
   @Test
   public void testUpdateDefault() throws Exception {
     String url = getBaseUrl() + DEBUG_SERVLET_PATH;
-    try (Http2SolrClient client =
-        new Http2SolrClient.Builder(url).withDefaultCollection(DEFAULT_CORE).build()) {
+    try (var client =
+        new HttpJettySolrClient.Builder(url).withDefaultCollection(DEFAULT_CORE).build()) {
       testUpdate(client, WT.JAVABIN, "application/javabin", MUST_ENCODE);
     }
   }
@@ -296,8 +303,8 @@ public void testUpdateDefault() throws Exception {
   @Test
   public void testUpdateXml() throws Exception {
     String url = getBaseUrl() + "/debug/foo";
-    try (Http2SolrClient client =
-        new Http2SolrClient.Builder(url)
+    try (var client =
+        new HttpJettySolrClient.Builder(url)
             .withDefaultCollection(DEFAULT_CORE)
             .withRequestWriter(new XMLRequestWriter())
             .withResponseParser(new XMLResponseParser())
@@ -309,8 +316,8 @@ public void testUpdateXml() throws Exception {
   @Test
   public void testUpdateJavabin() throws Exception {
     String url = getBaseUrl() + "/debug/foo";
-    try (Http2SolrClient client =
-        new Http2SolrClient.Builder(url)
+    try (var client =
+        new HttpJettySolrClient.Builder(url)
             .withDefaultCollection(DEFAULT_CORE)
             .withRequestWriter(new JavaBinRequestWriter())
             .withResponseParser(new JavaBinResponseParser())
@@ -345,8 +352,10 @@ public void testAsyncQueryWithSharedClient() throws Exception {
     ResponseParser rp = new XMLResponseParser();
     final var queryParams = new MapSolrParams(Collections.singletonMap("q", "*:*"));
     final var builder =
-        new Http2SolrClient.Builder(url).withDefaultCollection(DEFAULT_CORE).withResponseParser(rp);
-    try (Http2SolrClient originalClient = builder.build()) {
+        new HttpJettySolrClient.Builder(url)
+            .withDefaultCollection(DEFAULT_CORE)
+            .withResponseParser(rp);
+    try (HttpJettySolrClient originalClient = builder.build()) {
       final var derivedBuilder = builder.withHttpClient(originalClient);
       super.testQueryAsync(derivedBuilder);
     }
@@ -355,8 +364,8 @@ public void testAsyncQueryWithSharedClient() throws Exception {
   @Test
   public void testFollowRedirect() throws Exception {
     final String clientUrl = getBaseUrl() + REDIRECT_SERVLET_PATH;
-    try (Http2SolrClient client =
-        new Http2SolrClient.Builder(clientUrl)
+    try (var client =
+        new HttpJettySolrClient.Builder(clientUrl)
             .withDefaultCollection(DEFAULT_CORE)
             .withFollowRedirects(true)
             .build()) {
@@ -368,8 +377,8 @@ public void testFollowRedirect() throws Exception {
   @Test
   public void testDoNotFollowRedirect() throws Exception {
     final String clientUrl = getBaseUrl() + REDIRECT_SERVLET_PATH;
-    try (Http2SolrClient client =
-        new Http2SolrClient.Builder(clientUrl)
+    try (var client =
+        new HttpJettySolrClient.Builder(clientUrl)
             .withDefaultCollection(DEFAULT_CORE)
             .withFollowRedirects(false)
             .build()) {
@@ -386,15 +395,15 @@ public void testRedirectSwapping() throws Exception {
     SolrQuery q = new SolrQuery("*:*");
 
     // default for follow redirects is false
-    try (Http2SolrClient client =
-        new Http2SolrClient.Builder(clientUrl).withDefaultCollection(DEFAULT_CORE).build()) {
+    try (var client =
+        new HttpJettySolrClient.Builder(clientUrl).withDefaultCollection(DEFAULT_CORE).build()) {
 
       SolrServerException e = expectThrows(SolrServerException.class, () -> client.query(q));
       assertTrue(e.getMessage().contains("redirect"));
     }
 
-    try (Http2SolrClient client =
-        new Http2SolrClient.Builder(clientUrl)
+    try (var client =
+        new HttpJettySolrClient.Builder(clientUrl)
             .withDefaultCollection(DEFAULT_CORE)
             .withFollowRedirects(true)
             .build()) {
@@ -403,8 +412,8 @@ public void testRedirectSwapping() throws Exception {
     }
 
     // set explicit false for following redirects
-    try (Http2SolrClient client =
-        new Http2SolrClient.Builder(clientUrl)
+    try (var client =
+        new HttpJettySolrClient.Builder(clientUrl)
             .withDefaultCollection(DEFAULT_CORE)
             .withFollowRedirects(false)
             .build()) {
@@ -416,8 +425,8 @@ public void testRedirectSwapping() throws Exception {
 
   @Test
   public void testCollectionParameters() throws IOException, SolrServerException {
-    Http2SolrClient baseUrlClient = new Http2SolrClient.Builder(getBaseUrl()).build();
-    Http2SolrClient collection1UrlClient = new Http2SolrClient.Builder(getCoreUrl()).build();
+    var baseUrlClient = new HttpJettySolrClient.Builder(getBaseUrl()).build();
+    var collection1UrlClient = new HttpJettySolrClient.Builder(getCoreUrl()).build();
     testCollectionParameters(baseUrlClient, collection1UrlClient);
   }
 
@@ -431,11 +440,11 @@ public void testQueryString() throws Exception {
   public void testGetDefaultSslContextFactory() {
     assertEquals(
         "HTTPS",
-        Http2SolrClient.getDefaultSslContextFactory().getEndpointIdentificationAlgorithm());
+        HttpJettySolrClient.getDefaultSslContextFactory().getEndpointIdentificationAlgorithm());
 
     System.setProperty("javax.net.ssl.keyStoreType", "foo");
     System.setProperty("javax.net.ssl.trustStoreType", "bar");
-    SslContextFactory.Client sslContextFactory = Http2SolrClient.getDefaultSslContextFactory();
+    SslContextFactory.Client sslContextFactory = HttpJettySolrClient.getDefaultSslContextFactory();
     assertEquals("HTTPS", sslContextFactory.getEndpointIdentificationAlgorithm());
     assertEquals("foo", sslContextFactory.getKeyStoreType());
     assertEquals("bar", sslContextFactory.getTrustStoreType());
@@ -445,7 +454,7 @@ public void testGetDefaultSslContextFactory() {
     System.setProperty("solr.ssl.check.peer.name.enabled", "true");
     System.setProperty("javax.net.ssl.keyStoreType", "foo");
     System.setProperty("javax.net.ssl.trustStoreType", "bar");
-    SslContextFactory.Client sslContextFactory2 = Http2SolrClient.getDefaultSslContextFactory();
+    SslContextFactory.Client sslContextFactory2 = HttpJettySolrClient.getDefaultSslContextFactory();
     assertEquals("HTTPS", sslContextFactory2.getEndpointIdentificationAlgorithm());
     assertEquals("foo", sslContextFactory2.getKeyStoreType());
     assertEquals("bar", sslContextFactory2.getTrustStoreType());
@@ -456,7 +465,7 @@ public void testGetDefaultSslContextFactory() {
     System.setProperty("solr.ssl.check.peer.name.enabled", "false");
     System.setProperty("javax.net.ssl.keyStoreType", "foo");
     System.setProperty("javax.net.ssl.trustStoreType", "bar");
-    SslContextFactory.Client sslContextFactory3 = Http2SolrClient.getDefaultSslContextFactory();
+    SslContextFactory.Client sslContextFactory3 = HttpJettySolrClient.getDefaultSslContextFactory();
     assertNull(sslContextFactory3.getEndpointIdentificationAlgorithm());
     assertEquals("foo", sslContextFactory3.getKeyStoreType());
     assertEquals("bar", sslContextFactory3.getTrustStoreType());
@@ -477,8 +486,8 @@ protected void expectThrowsAndMessage(
 
   @Test
   public void testSetCredentialsExplicitly() {
-    try (Http2SolrClient client =
-        new Http2SolrClient.Builder(getBaseUrl() + DEBUG_SERVLET_PATH)
+    try (var client =
+        new HttpJettySolrClient.Builder(getBaseUrl() + DEBUG_SERVLET_PATH)
             .withDefaultCollection(DEFAULT_CORE)
             .withBasicAuthCredentials("foo", "explicit")
             .build(); ) {
@@ -496,8 +505,8 @@ public void testSetCredentialsWithSysProps() throws IOException, SolrServerExcep
     // Hack to ensure we get a new set of parameters for this test
     PreemptiveBasicAuthClientBuilderFactory.setDefaultSolrParams(
         new PreemptiveBasicAuthClientBuilderFactory.CredentialsResolver().defaultParams);
-    try (Http2SolrClient client =
-        new Http2SolrClient.Builder(getBaseUrl() + DEBUG_SERVLET_PATH)
+    try (var client =
+        new HttpJettySolrClient.Builder(getBaseUrl() + DEBUG_SERVLET_PATH)
             .withDefaultCollection(DEFAULT_CORE)
             .build()) {
       QueryRequest r = new QueryRequest(new SolrQuery("quick brown fox"));
@@ -526,8 +535,8 @@ public void testSetCredentialsWithSysProps() throws IOException, SolrServerExcep
 
   @Test
   public void testPerRequestCredentials() {
-    try (Http2SolrClient client =
-        new Http2SolrClient.Builder(getBaseUrl() + DEBUG_SERVLET_PATH)
+    try (var client =
+        new HttpJettySolrClient.Builder(getBaseUrl() + DEBUG_SERVLET_PATH)
             .withDefaultCollection(DEFAULT_CORE)
             .withBasicAuthCredentials("foo2", "explicit")
             .build(); ) {
@@ -537,8 +546,8 @@ public void testPerRequestCredentials() {
 
   @Test
   public void testNoCredentials() {
-    try (Http2SolrClient client =
-        new Http2SolrClient.Builder(getBaseUrl() + DEBUG_SERVLET_PATH)
+    try (var client =
+        new HttpJettySolrClient.Builder(getBaseUrl() + DEBUG_SERVLET_PATH)
             .withDefaultCollection(DEFAULT_CORE)
             .build(); ) {
       super.testNoCredentials(client);
@@ -548,8 +557,8 @@ public void testNoCredentials() {
   @Test
   public void testUseOptionalCredentials() {
     // username foo, password with embedded colon separator is "expli:cit".
-    try (Http2SolrClient client =
-        new Http2SolrClient.Builder(getBaseUrl() + DEBUG_SERVLET_PATH)
+    try (var client =
+        new HttpJettySolrClient.Builder(getBaseUrl() + DEBUG_SERVLET_PATH)
             .withDefaultCollection(DEFAULT_CORE)
             .withOptionalBasicAuthCredentials("foo:expli:cit")
             .build(); ) {
@@ -559,8 +568,8 @@ public void testUseOptionalCredentials() {
 
   @Test
   public void testUseOptionalCredentialsWithNull() {
-    try (Http2SolrClient client =
-        new Http2SolrClient.Builder(getBaseUrl() + DEBUG_SERVLET_PATH)
+    try (var client =
+        new HttpJettySolrClient.Builder(getBaseUrl() + DEBUG_SERVLET_PATH)
             .withDefaultCollection(DEFAULT_CORE)
             .withOptionalBasicAuthCredentials(null)
             .build(); ) {
@@ -573,12 +582,14 @@ public void testMalformedOptionalCredentials() {
 
     expectThrowsAndMessage(
         IllegalStateException.class,
-        () -> new Http2SolrClient.Builder().withOptionalBasicAuthCredentials("usernamepassword"),
+        () ->
+            new HttpJettySolrClient.Builder().withOptionalBasicAuthCredentials("usernamepassword"),
         "Invalid Authentication credential formatting. Provide username and password in the 'username:password' format.");
 
     expectThrowsAndMessage(
         IllegalStateException.class,
-        () -> new Http2SolrClient.Builder().withOptionalBasicAuthCredentials("username password"),
+        () ->
+            new HttpJettySolrClient.Builder().withOptionalBasicAuthCredentials("username password"),
         "Invalid Authentication credential formatting. Provide username and password in the 'username:password' format.");
   }
 
@@ -586,11 +597,11 @@ public void testMalformedOptionalCredentials() {
   public void testBadExplicitCredentials() {
     expectThrowsAndMessage(
         IllegalStateException.class,
-        () -> new Http2SolrClient.Builder().withBasicAuthCredentials("foo", null),
+        () -> new HttpJettySolrClient.Builder().withBasicAuthCredentials("foo", null),
         "Invalid Authentication credentials");
     expectThrowsAndMessage(
         IllegalStateException.class,
-        () -> new Http2SolrClient.Builder().withBasicAuthCredentials(null, "foo"),
+        () -> new HttpJettySolrClient.Builder().withBasicAuthCredentials(null, "foo"),
         "Invalid Authentication credentials");
   }
 
@@ -599,7 +610,7 @@ public void testBadHttpFactory() {
     System.setProperty(SolrHttpConstants.SYS_PROP_HTTP_CLIENT_BUILDER_FACTORY, "FakeClassName");
     try {
       SolrClient client =
-          new Http2SolrClient.Builder(getBaseUrl() + DEBUG_SERVLET_PATH)
+          new HttpJettySolrClient.Builder(getBaseUrl() + DEBUG_SERVLET_PATH)
               .withDefaultCollection(DEFAULT_CORE)
               .build();
       fail("Expecting exception");
@@ -610,8 +621,8 @@ public void testBadHttpFactory() {
 
   @Test
   public void testGetRawStream() throws Exception {
-    try (Http2SolrClient client =
-        (Http2SolrClient)
+    try (HttpJettySolrClient client =
+        (HttpJettySolrClient)
             builder(
                     getBaseUrl() + DEBUG_SERVLET_PATH,
                     DEFAULT_CONNECTION_TIMEOUT,
@@ -624,38 +635,38 @@ public void testGetRawStream() throws Exception {
 
   @Test
   public void testBuilder() {
-    try (Http2SolrClient seed =
-        new Http2SolrClient.Builder("baseSolrUrl")
+    try (var seed =
+        new HttpJettySolrClient.Builder("baseSolrUrl")
             .withBasicAuthCredentials("testu", "testp")
             .build()) {
 
-      try (Http2SolrClient clone1 =
-          new Http2SolrClient.Builder("baseSolrUrl").withHttpClient(seed).build()) {
+      try (var clone1 =
+          new HttpJettySolrClient.Builder("baseSolrUrl").withHttpClient(seed).build()) {
         String expected1 =
-            Http2SolrClient.basicAuthCredentialsToAuthorizationString("testu", "testp");
-        assertEquals(expected1, clone1.basicAuthAuthorizationStr);
+            HttpJettySolrClient.basicAuthCredentialsToAuthorizationString("testu", "testp");
+        assertEquals(expected1, clone1.basicAuthAuthorizationStr());
       }
 
       // test overwrite seed value
-      try (Http2SolrClient clone2 =
-          new Http2SolrClient.Builder("baseSolrUrl")
+      try (var clone2 =
+          new HttpJettySolrClient.Builder("baseSolrUrl")
               .withHttpClient(seed)
               .withBasicAuthCredentials("testu2", "testp2")
               .build()) {
         String expected2 =
-            Http2SolrClient.basicAuthCredentialsToAuthorizationString("testu2", "testp2");
-        assertEquals(expected2, clone2.basicAuthAuthorizationStr);
+            HttpJettySolrClient.basicAuthCredentialsToAuthorizationString("testu2", "testp2");
+        assertEquals(expected2, clone2.basicAuthAuthorizationStr());
       }
 
       // test overwrite seed value, order of builder method calls reversed
-      try (Http2SolrClient clone3 =
-          new Http2SolrClient.Builder("baseSolrUrl")
+      try (var clone3 =
+          new HttpJettySolrClient.Builder("baseSolrUrl")
               .withBasicAuthCredentials("testu3", "testp3")
               .withHttpClient(seed)
               .build()) {
         String expected3 =
-            Http2SolrClient.basicAuthCredentialsToAuthorizationString("testu3", "testp3");
-        assertEquals(expected3, clone3.basicAuthAuthorizationStr);
+            HttpJettySolrClient.basicAuthCredentialsToAuthorizationString("testu3", "testp3");
+        assertEquals(expected3, clone3.basicAuthAuthorizationStr());
       }
     }
   }
@@ -663,14 +674,14 @@ public void testBuilder() {
   @Test
   public void testIdleTimeoutWithHttpClient() throws Exception {
     String url = getBaseUrl() + SLOW_STREAM_SERVLET_PATH;
-    try (Http2SolrClient oldClient =
-        new Http2SolrClient.Builder(url)
+    try (var oldClient =
+        new HttpJettySolrClient.Builder(url)
             .withRequestTimeout(Long.MAX_VALUE, TimeUnit.MILLISECONDS)
             .withIdleTimeout(100, TimeUnit.MILLISECONDS)
             .build()) {
 
-      try (Http2SolrClient onlyBaseUrlChangedClient =
-          new Http2SolrClient.Builder(url).withHttpClient(oldClient).build()) {
+      try (var onlyBaseUrlChangedClient =
+          new HttpJettySolrClient.Builder(url).withHttpClient(oldClient).build()) {
         assertEquals(
             oldClient.getIdleTimeoutMillis(), onlyBaseUrlChangedClient.getIdleTimeoutMillis());
         assertEquals(oldClient.getHttpClient(), onlyBaseUrlChangedClient.getHttpClient());
@@ -684,8 +695,8 @@ public void testIdleTimeoutWithHttpClient() throws Exception {
       assertIsTimeout(expectThrows(SolrServerException.class, () -> oldClient.request(req)));
 
       long newIdleTimeoutMs = timeToSendMs + 1000; // enough time to succeed
-      try (Http2SolrClient idleTimeoutChangedClient =
-          new Http2SolrClient.Builder(url)
+      try (var idleTimeoutChangedClient =
+          new HttpJettySolrClient.Builder(url)
               .withHttpClient(oldClient)
               .withIdleTimeout(newIdleTimeoutMs, TimeUnit.MILLISECONDS)
               .build()) {
@@ -705,14 +716,14 @@ public void testIdleTimeoutWithHttpClient() throws Exception {
   @Test
   public void testRequestTimeoutWithHttpClient() throws Exception {
     String url = getBaseUrl() + SLOW_STREAM_SERVLET_PATH;
-    try (Http2SolrClient oldClient =
-        new Http2SolrClient.Builder(url)
+    try (var oldClient =
+        new HttpJettySolrClient.Builder(url)
             .withIdleTimeout(Long.MAX_VALUE, TimeUnit.MILLISECONDS)
             .withRequestTimeout(100, TimeUnit.MILLISECONDS)
             .build()) {
 
-      try (Http2SolrClient onlyBaseUrlChangedClient =
-          new Http2SolrClient.Builder(url).withHttpClient(oldClient).build()) {
+      try (var onlyBaseUrlChangedClient =
+          new HttpJettySolrClient.Builder(url).withHttpClient(oldClient).build()) {
         // Client created with the same HTTP client should have the same behavior
         assertEquals(oldClient.getHttpClient(), onlyBaseUrlChangedClient.getHttpClient());
       }
@@ -723,8 +734,8 @@ public void testRequestTimeoutWithHttpClient() throws Exception {
       assertIsTimeout(expectThrows(SolrServerException.class, () -> oldClient.request(req)));
 
       int newRequestTimeoutMs = 10 * 1000; // enough time to succeed
-      try (Http2SolrClient requestTimeoutChangedClient =
-          new Http2SolrClient.Builder(url)
+      try (var requestTimeoutChangedClient =
+          new HttpJettySolrClient.Builder(url)
               .withHttpClient(oldClient)
               .withRequestTimeout(newRequestTimeoutMs, TimeUnit.MILLISECONDS)
               .build()) {
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/PreemptiveBasicAuthClientBuilderFactoryTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/jetty/PreemptiveBasicAuthClientBuilderFactoryTest.java
similarity index 99%
rename from solr/solrj/src/test/org/apache/solr/client/solrj/impl/PreemptiveBasicAuthClientBuilderFactoryTest.java
rename to solr/solrj/src/test/org/apache/solr/client/solrj/jetty/PreemptiveBasicAuthClientBuilderFactoryTest.java
index d50ede6ba57..3ee8f4dcc78 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/PreemptiveBasicAuthClientBuilderFactoryTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/jetty/PreemptiveBasicAuthClientBuilderFactoryTest.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.solr.client.solrj.impl;
+package org.apache.solr.client.solrj.jetty;
 
 import java.io.BufferedWriter;
 import java.io.IOException;
diff --git a/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java b/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
index da99074d3a8..0668215e3ea 100644
--- a/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
+++ b/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
@@ -84,9 +84,9 @@
 import org.apache.solr.client.solrj.apache.CloudLegacySolrClient;
 import org.apache.solr.client.solrj.apache.HttpClientUtil;
 import org.apache.solr.client.solrj.apache.HttpSolrClient;
-import org.apache.solr.client.solrj.impl.CloudHttp2SolrClient;
+import org.apache.solr.client.solrj.impl.CloudSolrClient;
 import org.apache.solr.client.solrj.impl.ClusterStateProvider;
-import org.apache.solr.client.solrj.impl.Http2SolrClient;
+import org.apache.solr.client.solrj.jetty.HttpJettySolrClient;
 import org.apache.solr.client.solrj.response.SolrResponseBase;
 import org.apache.solr.client.solrj.util.ClientUtils;
 import org.apache.solr.cloud.IpTables;
@@ -290,7 +290,7 @@ public static void setupTestCases() {
     // based on randomized SSL config, set SocketFactoryRegistryProvider appropriately
     HttpClientUtil.setSocketFactoryRegistryProvider(
         sslConfig.buildClientSocketFactoryRegistryProvider());
-    Http2SolrClient.setDefaultSSLConfig(sslConfig.buildClientSSLConfig());
+    HttpJettySolrClient.setDefaultSSLConfig(sslConfig.buildClientSSLConfig());
     if (isSSLMode()) {
       // SolrCloud tests should usually clear this
       System.setProperty(URL_SCHEME, HTTPS);
@@ -331,7 +331,7 @@ public static void teardownTestCases() throws Exception {
       System.clearProperty("solr.cloud.wait-for-updates-with-stale-state-pause");
       System.clearProperty("solr.zkclienttmeout");
       HttpClientUtil.resetHttpClientBuilder();
-      Http2SolrClient.resetSslContextFactory();
+      HttpJettySolrClient.resetSslContextFactory();
 
       clearNumericTypesProperties();
 
@@ -2526,10 +2526,10 @@ public static Object skewed(Object likely, Object unlikely) {
   }
 
   /**
-   * A variant of {@link org.apache.solr.client.solrj.impl.CloudHttp2SolrClient.Builder} that will
+   * A variant of {@link org.apache.solr.client.solrj.impl.CloudSolrClient.Builder} that will
    * randomize some internal settings.
    */
-  public static class RandomizingCloudHttp2SolrClientBuilder extends CloudHttp2SolrClient.Builder {
+  public static class RandomizingCloudHttp2SolrClientBuilder extends CloudSolrClient.Builder {
 
     public RandomizingCloudHttp2SolrClientBuilder(List zkHosts, Optional zkChroot) {
       super(zkHosts, zkChroot);
@@ -2627,7 +2627,8 @@ public static HttpClient getHttpClient(String url) {
 
   /**
    * This method creates a basic HttpSolrClient. Tests that want to control the creation process
-   * should use the {@link org.apache.solr.client.solrj.impl.Http2SolrClient.Builder} class directly
+   * should use the {@link org.apache.solr.client.solrj.jetty.HttpJettySolrClient.Builder} class
+   * directly
    *
    * @param url the base URL for a Solr node. Should not contain a core or collection name.
    */
@@ -2642,7 +2643,8 @@ public static HttpSolrClient getHttpSolrClient(Replica replica) {
 
   /**
    * This method creates a basic HttpSolrClient. Tests that want to control the creation process
-   * should use the {@link org.apache.solr.client.solrj.impl.Http2SolrClient.Builder} class directly
+   * should use the {@link org.apache.solr.client.solrj.jetty.HttpJettySolrClient.Builder} class
+   * directly
    *
    * @param url the base URL of a Solr node. Should not include a collection or core name.
    * @param defaultCoreName the name of a core that the created client should default to when making
diff --git a/solr/test-framework/src/java/org/apache/solr/client/solrj/apache/HttpClusterStateProvider.java b/solr/test-framework/src/java/org/apache/solr/client/solrj/apache/HttpClusterStateProvider.java
index 7c715ba23f6..9cbc41899f4 100644
--- a/solr/test-framework/src/java/org/apache/solr/client/solrj/apache/HttpClusterStateProvider.java
+++ b/solr/test-framework/src/java/org/apache/solr/client/solrj/apache/HttpClusterStateProvider.java
@@ -21,12 +21,11 @@
 import org.apache.http.client.HttpClient;
 import org.apache.solr.client.solrj.SolrClient;
 import org.apache.solr.client.solrj.impl.BaseHttpClusterStateProvider;
-import org.apache.solr.client.solrj.impl.Http2ClusterStateProvider;
 
 /**
  * Retrieves cluster state via Solr HTTP APIs
  *
- * @deprecated Please use {@link Http2ClusterStateProvider}
+ * @deprecated Please use {@link org.apache.solr.client.solrj.impl.HttpClusterStateProvider}
  */
 @Deprecated(since = "9.0")
 public class HttpClusterStateProvider extends BaseHttpClusterStateProvider {
diff --git a/solr/test-framework/src/java/org/apache/solr/client/solrj/apache/HttpSolrClient.java b/solr/test-framework/src/java/org/apache/solr/client/solrj/apache/HttpSolrClient.java
index ec2f3d2844c..58d4fa63a74 100644
--- a/solr/test-framework/src/java/org/apache/solr/client/solrj/apache/HttpSolrClient.java
+++ b/solr/test-framework/src/java/org/apache/solr/client/solrj/apache/HttpSolrClient.java
@@ -76,12 +76,12 @@
 import org.apache.solr.client.solrj.SolrClient;
 import org.apache.solr.client.solrj.SolrRequest;
 import org.apache.solr.client.solrj.SolrServerException;
-import org.apache.solr.client.solrj.impl.Http2SolrClient;
 import org.apache.solr.client.solrj.impl.HttpJdkSolrClient;
 import org.apache.solr.client.solrj.impl.InputStreamResponseParser;
 import org.apache.solr.client.solrj.impl.JavaBinRequestWriter;
 import org.apache.solr.client.solrj.impl.JavaBinResponseParser;
 import org.apache.solr.client.solrj.impl.RemoteExecutionException;
+import org.apache.solr.client.solrj.jetty.HttpJettySolrClient;
 import org.apache.solr.client.solrj.request.RequestWriter;
 import org.apache.solr.client.solrj.util.ClientUtils;
 import org.apache.solr.common.SolrException;
@@ -98,7 +98,7 @@
 /**
  * A SolrClient implementation that talks directly to a Solr server via Apache HTTP client
  *
- * @deprecated Please use {@link Http2SolrClient} or {@link HttpJdkSolrClient}
+ * @deprecated Please use {@link HttpJettySolrClient} or {@link HttpJdkSolrClient}
  */
 @Deprecated(since = "9.0")
 public class HttpSolrClient extends SolrClient {
@@ -809,7 +809,7 @@ public boolean isUseMultiPartPost() {
   /**
    * Constructs {@link HttpSolrClient} instances from provided configuration.
    *
-   * @deprecated Please use {@link Http2SolrClient}
+   * @deprecated Please use {@link HttpJettySolrClient}
    */
   @Deprecated(since = "9.0")
   public static class Builder extends SolrClientBuilder {
diff --git a/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java b/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java
index 1d7c0361c89..6b2fe9a8d4e 100644
--- a/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java
+++ b/solr/test-framework/src/java/org/apache/solr/cloud/AbstractFullDistribZkTestBase.java
@@ -2154,7 +2154,7 @@ ZkStateReader.PULL_REPLICAS, getPullReplicaCount(),
   /**
    * This method may randomize unspecified aspects of the resulting SolrClient. Tests that do
    * not wish to have any randomized behavior should use the {@link
-   * org.apache.solr.client.solrj.impl.CloudHttp2SolrClient.Builder} class directly
+   * org.apache.solr.client.solrj.impl.CloudSolrClient.Builder} class directly
    */
   public static CloudSolrClient getCloudSolrClient(
       String zkHost,
diff --git a/solr/test-framework/src/java/org/apache/solr/cloud/MiniSolrCloudCluster.java b/solr/test-framework/src/java/org/apache/solr/cloud/MiniSolrCloudCluster.java
index 917c2335409..5ed9269f0fe 100644
--- a/solr/test-framework/src/java/org/apache/solr/cloud/MiniSolrCloudCluster.java
+++ b/solr/test-framework/src/java/org/apache/solr/cloud/MiniSolrCloudCluster.java
@@ -57,8 +57,8 @@
 import org.apache.lucene.tests.util.LuceneTestCase;
 import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.client.solrj.apache.CloudLegacySolrClient;
-import org.apache.solr.client.solrj.embedded.SSLConfig;
 import org.apache.solr.client.solrj.impl.CloudSolrClient;
+import org.apache.solr.client.solrj.jetty.SSLConfig;
 import org.apache.solr.client.solrj.request.CollectionAdminRequest;
 import org.apache.solr.client.solrj.request.ConfigSetAdminRequest;
 import org.apache.solr.common.SolrException;
diff --git a/solr/test-framework/src/java/org/apache/solr/embedded/JettyConfig.java b/solr/test-framework/src/java/org/apache/solr/embedded/JettyConfig.java
index 6ec7e5d1ca7..0f8cfb28238 100644
--- a/solr/test-framework/src/java/org/apache/solr/embedded/JettyConfig.java
+++ b/solr/test-framework/src/java/org/apache/solr/embedded/JettyConfig.java
@@ -21,7 +21,7 @@
 import java.util.Map;
 import java.util.TreeMap;
 import org.apache.solr.SolrTestCaseJ4;
-import org.apache.solr.client.solrj.embedded.SSLConfig;
+import org.apache.solr.client.solrj.jetty.SSLConfig;
 import org.eclipse.jetty.ee10.servlet.ServletHolder;
 
 public class JettyConfig {
diff --git a/solr/test-framework/src/java/org/apache/solr/embedded/JettySolrRunner.java b/solr/test-framework/src/java/org/apache/solr/embedded/JettySolrRunner.java
index 8bc00fec346..2e7e0f4ae07 100644
--- a/solr/test-framework/src/java/org/apache/solr/embedded/JettySolrRunner.java
+++ b/solr/test-framework/src/java/org/apache/solr/embedded/JettySolrRunner.java
@@ -55,7 +55,7 @@
 import org.apache.solr.client.solrj.SolrServerException;
 import org.apache.solr.client.solrj.apache.HttpSolrClient;
 import org.apache.solr.client.solrj.cloud.SocketProxy;
-import org.apache.solr.client.solrj.embedded.SSLConfig;
+import org.apache.solr.client.solrj.jetty.SSLConfig;
 import org.apache.solr.client.solrj.request.CoresApi;
 import org.apache.solr.common.util.TimeSource;
 import org.apache.solr.common.util.Utils;
diff --git a/solr/test-framework/src/java/org/apache/solr/util/SSLTestConfig.java b/solr/test-framework/src/java/org/apache/solr/util/SSLTestConfig.java
index 74e4fdf6f39..78be26e2e34 100644
--- a/solr/test-framework/src/java/org/apache/solr/util/SSLTestConfig.java
+++ b/solr/test-framework/src/java/org/apache/solr/util/SSLTestConfig.java
@@ -37,8 +37,8 @@
 import org.apache.http.ssl.SSLContextBuilder;
 import org.apache.http.ssl.SSLContexts;
 import org.apache.solr.client.solrj.apache.HttpClientUtil.SocketFactoryRegistryProvider;
-import org.apache.solr.client.solrj.embedded.SSLConfig;
 import org.apache.solr.client.solrj.impl.SolrHttpConstants;
+import org.apache.solr.client.solrj.jetty.SSLConfig;
 import org.eclipse.jetty.util.resource.Resource;
 import org.eclipse.jetty.util.resource.ResourceFactory;
 import org.eclipse.jetty.util.security.CertificateUtils;
diff --git a/solr/test-framework/src/java/org/apache/solr/util/SolrJMetricTestUtils.java b/solr/test-framework/src/java/org/apache/solr/util/SolrJMetricTestUtils.java
index ccff28c55c9..5e8f7a9d7a8 100644
--- a/solr/test-framework/src/java/org/apache/solr/util/SolrJMetricTestUtils.java
+++ b/solr/test-framework/src/java/org/apache/solr/util/SolrJMetricTestUtils.java
@@ -23,8 +23,8 @@
 import org.apache.solr.client.solrj.SolrClient;
 import org.apache.solr.client.solrj.SolrRequest;
 import org.apache.solr.client.solrj.SolrServerException;
-import org.apache.solr.client.solrj.impl.Http2SolrClient;
 import org.apache.solr.client.solrj.impl.InputStreamResponseParser;
+import org.apache.solr.client.solrj.jetty.HttpJettySolrClient;
 import org.apache.solr.client.solrj.request.GenericSolrRequest;
 import org.apache.solr.common.params.SolrParams;
 import org.apache.solr.common.util.NamedList;
@@ -56,7 +56,7 @@ public static Double getNumCoreRequests(
       String baseUrl, String collectionName, String category, String handler)
       throws SolrServerException, IOException {
 
-    try (Http2SolrClient client = new Http2SolrClient.Builder(baseUrl).build()) {
+    try (var client = new HttpJettySolrClient.Builder(baseUrl).build()) {
       var req =
           new GenericSolrRequest(
               SolrRequest.METHOD.GET,
@@ -89,7 +89,7 @@ public static Double getNumCoreRequests(
   public static Double getNumNodeRequestErrors(String baseUrl, String category, String handler)
       throws SolrServerException, IOException {
 
-    try (Http2SolrClient client = new Http2SolrClient.Builder(baseUrl).build()) {
+    try (var client = new HttpJettySolrClient.Builder(baseUrl).build()) {
       var req =
           new GenericSolrRequest(
               SolrRequest.METHOD.GET,
diff --git a/solr/test-framework/src/test/org/apache/solr/client/solrj/apache/CloudSolrClientBuilderTest.java b/solr/test-framework/src/test/org/apache/solr/client/solrj/apache/CloudSolrClientBuilderTest.java
index 280add47de7..9ff91933e94 100644
--- a/solr/test-framework/src/test/org/apache/solr/client/solrj/apache/CloudSolrClientBuilderTest.java
+++ b/solr/test-framework/src/test/org/apache/solr/client/solrj/apache/CloudSolrClientBuilderTest.java
@@ -24,7 +24,6 @@
 import java.util.Optional;
 import java.util.concurrent.TimeUnit;
 import org.apache.solr.SolrTestCase;
-import org.apache.solr.client.solrj.impl.CloudHttp2SolrClient;
 import org.apache.solr.client.solrj.impl.CloudSolrClient;
 import org.apache.solr.client.solrj.impl.ZkClientClusterStateProvider;
 import org.junit.Test;
@@ -37,8 +36,7 @@ public class CloudSolrClientBuilderTest extends SolrTestCase {
   @Test
   public void testSingleZkHostSpecified() throws IOException {
     try (CloudSolrClient createdClient =
-        new CloudHttp2SolrClient.Builder(
-                Collections.singletonList(ANY_ZK_HOST), Optional.of(ANY_CHROOT))
+        new CloudSolrClient.Builder(Collections.singletonList(ANY_ZK_HOST), Optional.of(ANY_CHROOT))
             .build(); ) {
       try (ZkClientClusterStateProvider zkClientClusterStateProvider =
           ZkClientClusterStateProvider.from(createdClient)) {
@@ -54,7 +52,7 @@ public void testSeveralZkHostsSpecifiedSingly() throws IOException {
     zkHostList.add(ANY_ZK_HOST);
     zkHostList.add(ANY_OTHER_ZK_HOST);
     try (CloudSolrClient createdClient =
-        new CloudHttp2SolrClient.Builder(zkHostList, Optional.of(ANY_CHROOT)).build()) {
+        new CloudSolrClient.Builder(zkHostList, Optional.of(ANY_CHROOT)).build()) {
       try (ZkClientClusterStateProvider zkClientClusterStateProvider =
           ZkClientClusterStateProvider.from(createdClient)) {
         final String clientZkHost = zkClientClusterStateProvider.getZkHost();
@@ -70,7 +68,7 @@ public void testSeveralZkHostsSpecifiedTogether() throws IOException {
     zkHosts.add(ANY_ZK_HOST);
     zkHosts.add(ANY_OTHER_ZK_HOST);
     try (CloudSolrClient createdClient =
-        new CloudHttp2SolrClient.Builder(zkHosts, Optional.of(ANY_CHROOT)).build()) {
+        new CloudSolrClient.Builder(zkHosts, Optional.of(ANY_CHROOT)).build()) {
       try (ZkClientClusterStateProvider zkClientClusterStateProvider =
           ZkClientClusterStateProvider.from(createdClient)) {
         final String clientZkHost = zkClientClusterStateProvider.getZkHost();
@@ -83,8 +81,7 @@ public void testSeveralZkHostsSpecifiedTogether() throws IOException {
   @Test
   public void testByDefaultConfiguresClientToSendUpdatesOnlyToShardLeaders() throws IOException {
     try (CloudSolrClient createdClient =
-        new CloudHttp2SolrClient.Builder(
-                Collections.singletonList(ANY_ZK_HOST), Optional.of(ANY_CHROOT))
+        new CloudSolrClient.Builder(Collections.singletonList(ANY_ZK_HOST), Optional.of(ANY_CHROOT))
             .build()) {
       assertTrue(createdClient.isUpdatesToLeaders());
     }
@@ -93,8 +90,7 @@ public void testByDefaultConfiguresClientToSendUpdatesOnlyToShardLeaders() throw
   @Test
   public void testIsDirectUpdatesToLeadersOnlyDefault() throws IOException {
     try (CloudSolrClient createdClient =
-        new CloudHttp2SolrClient.Builder(
-                Collections.singletonList(ANY_ZK_HOST), Optional.of(ANY_CHROOT))
+        new CloudSolrClient.Builder(Collections.singletonList(ANY_ZK_HOST), Optional.of(ANY_CHROOT))
             .build()) {
       assertFalse(createdClient.isDirectUpdatesToLeadersOnly());
     }
diff --git a/solr/test-framework/src/test/org/apache/solr/client/solrj/apache/CloudSolrClientMultiConstructorTest.java b/solr/test-framework/src/test/org/apache/solr/client/solrj/apache/CloudSolrClientMultiConstructorTest.java
index 6d8f3ef8a61..5ee728580b8 100644
--- a/solr/test-framework/src/test/org/apache/solr/client/solrj/apache/CloudSolrClientMultiConstructorTest.java
+++ b/solr/test-framework/src/test/org/apache/solr/client/solrj/apache/CloudSolrClientMultiConstructorTest.java
@@ -24,7 +24,6 @@
 import java.util.Optional;
 import org.apache.lucene.tests.util.TestUtil;
 import org.apache.solr.SolrTestCase;
-import org.apache.solr.client.solrj.impl.CloudHttp2SolrClient;
 import org.apache.solr.client.solrj.impl.CloudSolrClient;
 import org.apache.solr.client.solrj.impl.ZkClientClusterStateProvider;
 import org.junit.Test;
@@ -72,7 +71,7 @@ public void testZkConnecstionStringSetterWithValidChroot() throws IOException {
     }
 
     try (CloudSolrClient client =
-        (new CloudHttp2SolrClient.Builder(new ArrayList<>(hosts), Optional.ofNullable(clientChroot))
+        (new CloudSolrClient.Builder(new ArrayList<>(hosts), Optional.ofNullable(clientChroot))
             .build())) {
       try (ZkClientClusterStateProvider zkClientClusterStateProvider =
           ZkClientClusterStateProvider.from(client)) {
@@ -116,6 +115,6 @@ public void testZkConnectionStringConstructorWithValidChroot() throws IOExceptio
   public void testBadChroot() {
     final List zkHosts = new ArrayList<>();
     zkHosts.add("host1:2181");
-    new CloudHttp2SolrClient.Builder(zkHosts, Optional.of("foo")).build();
+    new CloudSolrClient.Builder(zkHosts, Optional.of("foo")).build();
   }
 }