You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by tf...@apache.org on 2021/03/26 23:37:13 UTC
[lucene-solr] branch branch_8x updated: SOLR-15155: Let
CloudHttp2SolrClient accept an external Http2SolrClient Builder (#15)
This is an automated email from the ASF dual-hosted git repository.
tflobbe pushed a commit to branch branch_8x
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git
The following commit(s) were added to refs/heads/branch_8x by this push:
new db44134 SOLR-15155: Let CloudHttp2SolrClient accept an external Http2SolrClient Builder (#15)
db44134 is described below
commit db44134e02662633c93f7789d802bfc1e499a4a4
Author: Tomas Fernandez Lobbe <tf...@apache.org>
AuthorDate: Fri Mar 26 16:17:23 2021 -0700
SOLR-15155: Let CloudHttp2SolrClient accept an external Http2SolrClient Builder (#15)
This allows configuring the internal client with things like timeouts, credentials, etc
---
solr/CHANGES.txt | 2 +
.../client/solrj/impl/CloudHttp2SolrClient.java | 34 ++++++++++++--
.../impl/CloudHttp2SolrClientBuilderTest.java | 54 +++++++++++++++++++++-
3 files changed, 86 insertions(+), 4 deletions(-)
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 6ab85e7..fcc26fa 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -46,6 +46,8 @@ Improvements
* SOLR-11233: Add optional JAVA8_GC_LOG_FILE_OPTS for bin/solr. (Pranav Murugappan, Christine Poerschke)
+* SOLR-15155: Let CloudHttp2SolrClient accept an external Http2SolrClient Builder (Tomás Fernández Löbbe)
+
Optimizations
---------------------
* SOLR-15079: Block Collapse - Faster collapse code when groups are co-located via Block Join style nested doc indexing.
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 8e6ac82..3de79ca 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
@@ -44,7 +44,7 @@ public class CloudHttp2SolrClient extends BaseCloudSolrClient {
private final ClusterStateProvider stateProvider;
private final LBHttp2SolrClient lbClient;
- private Http2SolrClient myClient;
+ private final Http2SolrClient myClient;
private final boolean clientIsInternal;
/**
@@ -57,8 +57,17 @@ public class CloudHttp2SolrClient extends BaseCloudSolrClient {
*/
protected CloudHttp2SolrClient(Builder builder) {
super(builder.shardLeadersOnly, builder.parallelUpdates, builder.directUpdatesToLeadersOnly);
- this.clientIsInternal = builder.httpClient == null;
- this.myClient = (builder.httpClient == null) ? new Http2SolrClient.Builder().build() : builder.httpClient;
+ if (builder.httpClient == null) {
+ this.clientIsInternal = true;
+ if (builder.internalClientBuilder == null) {
+ this.myClient = new Http2SolrClient.Builder().build();
+ } else {
+ this.myClient = builder.internalClientBuilder.build();
+ }
+ } else {
+ this.clientIsInternal = false;
+ this.myClient = builder.httpClient;
+ }
if (builder.stateProvider == null) {
if (builder.zkHosts != null && builder.solrUrls != null) {
throw new IllegalArgumentException("Both zkHost(s) & solrUrl(s) have been specified. Only specify one.");
@@ -125,6 +134,7 @@ public class CloudHttp2SolrClient extends BaseCloudSolrClient {
protected boolean directUpdatesToLeadersOnly = false;
protected boolean parallelUpdates = true;
protected ClusterStateProvider stateProvider;
+ protected Http2SolrClient.Builder internalClientBuilder;
/**
* Provide a series of Solr URLs to be used when configuring {@link CloudHttp2SolrClient} instances.
@@ -207,11 +217,29 @@ public class CloudHttp2SolrClient extends BaseCloudSolrClient {
}
public Builder withHttpClient(Http2SolrClient httpClient) {
+ 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 = httpClient;
return this;
}
/**
+ * If provided, the CloudHttp2SolrClient will build it's internal Http2SolrClient 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 withInternalClientBuilder(Http2SolrClient.Builder 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;
+ }
+
+ /**
* Create a {@link CloudHttp2SolrClient} based on the provided configuration.
*/
public CloudHttp2SolrClient build() {
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 d841333..cb0a5df 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
@@ -25,6 +25,13 @@ import java.util.Optional;
import org.apache.solr.SolrTestCase;
import org.junit.Test;
+import org.mockito.Mockito;
+
+import static org.apache.solr.SolrTestCaseJ4.assumeWorkingMockito;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
public class CloudHttp2SolrClientBuilderTest extends SolrTestCase {
private static final String ANY_CHROOT = "/ANY_CHROOT";
@@ -70,7 +77,7 @@ public class CloudHttp2SolrClientBuilderTest extends SolrTestCase {
@Test
public void testByDefaultConfiguresClientToSendUpdatesOnlyToShardLeaders() throws IOException {
try(CloudHttp2SolrClient createdClient = new CloudHttp2SolrClient.Builder(Collections.singletonList(ANY_ZK_HOST), Optional.of(ANY_CHROOT)).build()) {
- assertTrue(createdClient.isUpdatesToLeaders() == true);
+ assertTrue(createdClient.isUpdatesToLeaders());
}
}
@@ -81,4 +88,49 @@ public class CloudHttp2SolrClientBuilderTest extends SolrTestCase {
}
}
+ @Test
+ public void testExternalClientAndInternalBuilderTogether() {
+ assumeWorkingMockito();
+ expectThrows(IllegalStateException.class, () -> new CloudHttp2SolrClient.Builder(Collections.singletonList(ANY_ZK_HOST), Optional.of(ANY_CHROOT))
+ .withHttpClient(Mockito.mock(Http2SolrClient.class))
+ .withInternalClientBuilder(Mockito.mock(Http2SolrClient.Builder.class))
+ .build());
+ expectThrows(IllegalStateException.class, () -> new CloudHttp2SolrClient.Builder(Collections.singletonList(ANY_ZK_HOST), Optional.of(ANY_CHROOT))
+ .withInternalClientBuilder(Mockito.mock(Http2SolrClient.Builder.class))
+ .withHttpClient(Mockito.mock(Http2SolrClient.class))
+ .build());
+ }
+
+ @Test
+ public void testProvideInternalBuilder() throws IOException {
+ assumeWorkingMockito();
+ Http2SolrClient http2Client = Mockito.mock(Http2SolrClient.class);
+ Http2SolrClient.Builder http2ClientBuilder = Mockito.mock(Http2SolrClient.Builder.class);
+ when(http2ClientBuilder.build()).thenReturn(http2Client);
+ CloudHttp2SolrClient.Builder clientBuilder = new CloudHttp2SolrClient.Builder(Collections.singletonList(ANY_ZK_HOST), Optional.of(ANY_CHROOT))
+ .withInternalClientBuilder(http2ClientBuilder);
+ verify(http2ClientBuilder, never()).build();
+ try (CloudHttp2SolrClient client = clientBuilder.build()) {
+ assertEquals(http2Client, client.getHttpClient());
+ verify(http2ClientBuilder, times(1)).build();
+ verify(http2Client, never()).close();
+ }
+ // it's internal, should be closed when closing CloudSolrClient
+ verify(http2Client, times(1)).close();
+ }
+
+ @Test
+ public void testProvideExternalClient() throws IOException {
+ assumeWorkingMockito();
+ Http2SolrClient http2Client = Mockito.mock(Http2SolrClient.class);
+ CloudHttp2SolrClient.Builder clientBuilder = new CloudHttp2SolrClient.Builder(Collections.singletonList(ANY_ZK_HOST), Optional.of(ANY_CHROOT))
+ .withHttpClient(http2Client);
+ try (CloudHttp2SolrClient client = clientBuilder.build()) {
+ assertEquals(http2Client, client.getHttpClient());
+ }
+ // it's external, should be NOT closed when closing CloudSolrClient
+ verify(http2Client, never()).close();
+ http2Client.close();
+ }
+
}