Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SOLR-17541: LBSolrClient implementations should agree on 'getClient()' semantics #2899

Open
wants to merge 24 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 3 additions & 8 deletions solr/core/src/java/org/apache/solr/cloud/ZkController.java
Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,6 @@ public String toString() {
public final ZkStateReader zkStateReader;
private SolrCloudManager cloudManager;

// only for internal usage
private Http2SolrClient http2SolrClient;

private CloudHttp2SolrClient cloudSolrClient;

private final String zkServerAddress; // example: 127.0.0.1:54062/solr
Expand Down Expand Up @@ -776,7 +773,6 @@ public void close() {
sysPropsCacher.close();
customThreadPool.execute(() -> IOUtils.closeQuietly(cloudManager));
customThreadPool.execute(() -> IOUtils.closeQuietly(cloudSolrClient));
customThreadPool.execute(() -> IOUtils.closeQuietly(http2SolrClient));

try {
try {
Expand Down Expand Up @@ -872,15 +868,14 @@ public SolrCloudManager getSolrCloudManager() {
if (cloudManager != null) {
return cloudManager;
}
http2SolrClient =
var httpClientBuilder =
new Http2SolrClient.Builder()
.withHttpClient(cc.getDefaultHttpSolrClient())
.withIdleTimeout(30000, TimeUnit.MILLISECONDS)
.withConnectionTimeout(15000, TimeUnit.MILLISECONDS)
.build();
.withConnectionTimeout(15000, TimeUnit.MILLISECONDS);
cloudSolrClient =
new CloudHttp2SolrClient.Builder(new ZkClientClusterStateProvider(zkStateReader))
.withHttpClient(http2SolrClient)
.withInternalClientBuilder(httpClientBuilder)
.build();
cloudManager = new SolrClientCloudManager(cloudSolrClient, cc.getObjectCache());
cloudManager.getClusterStateProvider().connect();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
*/
package org.apache.solr.core;

import java.util.List;
import java.util.concurrent.TimeUnit;
import org.apache.solr.client.solrj.impl.Http2SolrClient;
import org.apache.solr.common.util.IOUtils;
Expand All @@ -37,14 +36,15 @@ final class HttpSolrClientProvider implements AutoCloseable {

private final Http2SolrClient httpSolrClient;

private final Http2SolrClient.Builder httpClientBuilder;

private final InstrumentedHttpListenerFactory trackHttpSolrMetrics;

HttpSolrClientProvider(UpdateShardHandlerConfig cfg, SolrMetricsContext parentContext) {
trackHttpSolrMetrics = new InstrumentedHttpListenerFactory(getNameStrategy(cfg));
initializeMetrics(parentContext);

Http2SolrClient.Builder httpClientBuilder =
new Http2SolrClient.Builder().withListenerFactory(List.of(trackHttpSolrMetrics));
this.httpClientBuilder = new Http2SolrClient.Builder().addListenerFactory(trackHttpSolrMetrics);

if (cfg != null) {
httpClientBuilder
Expand Down Expand Up @@ -76,7 +76,7 @@ Http2SolrClient getSolrClient() {
}

void setSecurityBuilder(HttpClientBuilderPlugin builder) {
builder.setup(httpSolrClient);
builder.setup(httpClientBuilder, httpSolrClient);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ public class HttpShardHandler extends ShardHandler {
protected AtomicInteger pending;

private final Map<String, List<String>> shardToURLs;
protected LBHttp2SolrClient<Http2SolrClient> lbClient;
protected LBHttp2SolrClient<Http2SolrClient.Builder> lbClient;

public HttpShardHandler(HttpShardHandlerFactory httpShardHandlerFactory) {
this.httpShardHandlerFactory = httpShardHandlerFactory;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,9 @@ public class HttpShardHandlerFactory extends ShardHandlerFactory
protected ExecutorService commExecutor;

protected volatile Http2SolrClient defaultClient;
protected Http2SolrClient.Builder httpSolrClientBuilder;
protected InstrumentedHttpListenerFactory httpListenerFactory;
protected LBHttp2SolrClient<Http2SolrClient> loadbalancer;
protected LBHttp2SolrClient<Http2SolrClient.Builder> loadbalancer;

int corePoolSize = 0;
int maximumPoolSize = Integer.MAX_VALUE;
Expand Down Expand Up @@ -305,16 +306,16 @@ public void init(PluginInfo info) {
sb);
int soTimeout =
getParameter(args, HttpClientUtil.PROP_SO_TIMEOUT, HttpClientUtil.DEFAULT_SO_TIMEOUT, sb);

this.defaultClient =
this.httpSolrClientBuilder =
new Http2SolrClient.Builder()
.withConnectionTimeout(connectionTimeout, TimeUnit.MILLISECONDS)
.withIdleTimeout(soTimeout, TimeUnit.MILLISECONDS)
.withExecutor(commExecutor)
.withMaxConnectionsPerHost(maxConnectionsPerHost)
.build();
this.defaultClient.addListenerFactory(this.httpListenerFactory);
this.loadbalancer = new LBHttp2SolrClient.Builder<Http2SolrClient>(defaultClient).build();
.addListenerFactory(this.httpListenerFactory);
this.defaultClient = httpSolrClientBuilder.build();

this.loadbalancer = new LBHttp2SolrClient.Builder<>(httpSolrClientBuilder).build();

initReplicaListTransformers(getParameter(args, "replicaRouting", null, sb));

Expand All @@ -324,7 +325,7 @@ public void init(PluginInfo info) {
@Override
public void setSecurityBuilder(HttpClientBuilderPlugin clientBuilderPlugin) {
if (clientBuilderPlugin != null) {
clientBuilderPlugin.setup(defaultClient);
clientBuilderPlugin.setup(httpSolrClientBuilder, defaultClient);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,8 @@ public interface HttpClientBuilderPlugin {
public SolrHttpClientBuilder getHttpClientBuilder(SolrHttpClientBuilder builder);

public default void setup(Http2SolrClient client) {}

public default void setup(Http2SolrClient.Builder httpClientBuilder, Http2SolrClient client) {
setup(client);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -374,8 +374,17 @@ PublicKey fetchPublicKeyFromRemote(String nodename) {
}
}

@Override
public void setup(Http2SolrClient.Builder httpClientBuilder, Http2SolrClient client) {
setup(client, httpClientBuilder);
}

@Override
public void setup(Http2SolrClient client) {
setup(client, null);
}

private void setup(Http2SolrClient client, Http2SolrClient.Builder builder) {
final HttpListenerFactory.RequestResponseListener listener =
new HttpListenerFactory.RequestResponseListener() {
private static final String CACHED_REQUEST_USER_KEY = "cachedRequestUser";
Expand Down Expand Up @@ -431,7 +440,12 @@ private Optional<String> getUserFromJettyRequest(Request request) {
(String) request.getAttributes().get(CACHED_REQUEST_USER_KEY));
}
};
client.addListenerFactory(() -> listener);
if (client != null) {
client.addListenerFactory(() -> listener);
}
if (builder != null) {
builder.addListenerFactory(() -> listener);
}
}

@Override
Expand Down
1 change: 1 addition & 0 deletions solr/core/src/test/org/apache/solr/cli/PostToolTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ public void testBasicRun() throws Exception {

withBasicAuth(CollectionAdminRequest.createCollection(collection, "conf1", 1, 1, 0, 0))
.processAndWait(cluster.getSolrClient(), 10);
waitForState("creating", collection, activeClusterShape(1, 1));

File jsonDoc = File.createTempFile("temp", ".json");

Expand Down
9 changes: 4 additions & 5 deletions solr/core/src/test/org/apache/solr/cloud/OverseerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1945,17 +1945,16 @@ public Void answer(InvocationOnMock invocation) {
}

private SolrCloudManager getCloudDataProvider(ZkStateReader zkStateReader) {
var httpSolrClient =
var httpSolrClientBuilder =
new Http2SolrClient.Builder()
.withIdleTimeout(30000, TimeUnit.MILLISECONDS)
.withConnectionTimeout(15000, TimeUnit.MILLISECONDS)
.build();
.withConnectionTimeout(15000, TimeUnit.MILLISECONDS);
var cloudSolrClient =
new CloudHttp2SolrClient.Builder(new ZkClientClusterStateProvider(zkStateReader))
.withHttpClient(httpSolrClient)
.withInternalClientBuilder(httpSolrClientBuilder)
.build();
solrClients.add(cloudSolrClient);
solrClients.add(httpSolrClient);
solrClients.add(httpSolrClientBuilder.build());
SolrClientCloudManager sccm = new SolrClientCloudManager(cloudSolrClient, null);
sccm.getClusterStateProvider().connect();
return sccm;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@

import java.io.IOException;

/** A lambda intended for invoking SolrClient operations */
/**
* A lambda intended for invoking SolrClient operations
*
* @lucene.experimental
*/
@FunctionalInterface
public interface SolrClientFunction<C extends SolrClient, R> {
R apply(C c) throws IOException, SolrServerException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,8 @@
public class CloudHttp2SolrClient extends CloudSolrClient {

private final ClusterStateProvider stateProvider;
private final LBHttp2SolrClient<Http2SolrClient> lbClient;
private final LBHttp2SolrClient<Http2SolrClient.Builder> lbClient;
private final Http2SolrClient myClient;
private final boolean clientIsInternal;

/**
* Create a new client object that connects to Zookeeper and is always aware of the SolrCloud
Expand All @@ -54,8 +53,8 @@ public class CloudHttp2SolrClient extends CloudSolrClient {
*/
protected CloudHttp2SolrClient(Builder builder) {
super(builder.shardLeadersOnly, builder.parallelUpdates, builder.directUpdatesToLeadersOnly);
this.clientIsInternal = builder.httpClient == null;
this.myClient = createOrGetHttpClientFromBuilder(builder);
var httpClientBuilder = createOrGetHttpClientBuilder(builder);
this.myClient = httpClientBuilder.build();
this.stateProvider = createClusterStateProvider(builder);
this.retryExpiryTimeNano = builder.retryExpiryTimeNano;
this.defaultCollection = builder.defaultCollection;
Expand All @@ -73,16 +72,14 @@ protected CloudHttp2SolrClient(Builder builder) {
// locks.
this.locks = objectList(builder.parallelCacheRefreshesLocks);

this.lbClient = new LBHttp2SolrClient.Builder<Http2SolrClient>(myClient).build();
this.lbClient = new LBHttp2SolrClient.Builder<>(httpClientBuilder).build();
}

private Http2SolrClient createOrGetHttpClientFromBuilder(Builder builder) {
if (builder.httpClient != null) {
return builder.httpClient;
} else if (builder.internalClientBuilder != null) {
return builder.internalClientBuilder.build();
private Http2SolrClient.Builder createOrGetHttpClientBuilder(Builder builder) {
if (builder.internalClientBuilder != null) {
return builder.internalClientBuilder;
} else {
return new Http2SolrClient.Builder().build();
return new Http2SolrClient.Builder();
}
}

Expand Down Expand Up @@ -129,7 +126,7 @@ private ClusterStateProvider createHttp2ClusterStateProvider(

private void closeMyClientIfNeeded() {
try {
if (clientIsInternal && myClient != null) {
if (myClient != null) {
myClient.close();
}
} catch (Exception e) {
Expand All @@ -148,7 +145,7 @@ public void close() throws IOException {
}

@Override
public LBHttp2SolrClient<Http2SolrClient> getLbClient() {
public LBHttp2SolrClient<Http2SolrClient.Builder> getLbClient() {
return lbClient;
}

Expand All @@ -171,7 +168,6 @@ public static class Builder {
protected Collection<String> zkHosts = new ArrayList<>();
protected List<String> solrUrls = new ArrayList<>();
protected String zkChroot;
protected Http2SolrClient httpClient;
protected boolean shardLeadersOnly = true;
protected boolean directUpdatesToLeadersOnly = false;
protected boolean parallelUpdates = true;
Expand Down Expand Up @@ -404,23 +400,6 @@ public Builder withCollectionCacheTtl(long timeToLive, TimeUnit unit) {
return this;
}

/**
* Set the internal http client.
*
* <p>Note: closing the httpClient instance is at the responsibility of the caller.
*
* @param httpClient http client
* @return this
*/
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
Expand All @@ -430,10 +409,6 @@ public Builder withHttpClient(Http2SolrClient httpClient) {
* @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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,7 @@ protected Http2SolrClient(String serverBaseUrl, Builder builder) {
this.httpClient = createHttpClient(builder);
this.closeClient = true;
}
if (builder.listenerFactory != null) {
this.listenerFactory.addAll(builder.listenerFactory);
}
this.listenerFactory.addAll(builder.listenerFactories);
updateDefaultMimeTypeForParser();

this.httpClient.setFollowRedirects(Boolean.TRUE.equals(builder.followRedirects));
Expand Down Expand Up @@ -571,6 +569,7 @@ public final <R extends SolrResponse> R requestWithBaseUrl(
* @param clientFunction a Function that consumes a Http2SolrClient and returns an arbitrary value
* @return the value returned after invoking 'clientFunction'
* @param <R> the type returned by the provided function (and by this method)
* @lucene.experimental
*/
public <R> R requestWithBaseUrl(
String baseUrl, SolrClientFunction<Http2SolrClient, R> clientFunction)
Expand Down Expand Up @@ -906,7 +905,7 @@ public static class Builder

protected Long keyStoreReloadIntervalSecs;

private List<HttpListenerFactory> listenerFactory;
private List<HttpListenerFactory> listenerFactories = new ArrayList<>(0);

public Builder() {
super();
Expand All @@ -932,8 +931,27 @@ public Builder(String baseSolrUrl) {
this.baseSolrUrl = baseSolrUrl;
}

public Http2SolrClient.Builder withListenerFactory(List<HttpListenerFactory> listenerFactory) {
this.listenerFactory = listenerFactory;
/**
* specify a listener factory, which will be appened to any existing values.
*
* @param listenerFactory a HttpListenerFactory
* @return This Builder
*/
public Http2SolrClient.Builder addListenerFactory(HttpListenerFactory listenerFactory) {
this.listenerFactories.add(listenerFactory);
return this;
}

/**
* Specify listener factories, which will replace any existing values.
*
* @param listenerFactories a list of HttpListenerFactory instances
* @return This Builder
*/
public Http2SolrClient.Builder withListenerFactories(
List<HttpListenerFactory> listenerFactories) {
this.listenerFactories.clear();
this.listenerFactories.addAll(listenerFactories);
return this;
}

Expand Down Expand Up @@ -1109,9 +1127,9 @@ public Builder withHttpClient(Http2SolrClient http2SolrClient) {
if (this.urlParamNames == null) {
this.urlParamNames = http2SolrClient.urlParamNames;
}
if (this.listenerFactory == null) {
this.listenerFactory = new ArrayList<HttpListenerFactory>();
http2SolrClient.listenerFactory.forEach(this.listenerFactory::add);
if (this.listenerFactories.isEmpty()) {
this.listenerFactories.clear();
http2SolrClient.listenerFactory.forEach(this.listenerFactories::add);
}
if (this.executor == null) {
this.executor = http2SolrClient.executor;
Expand Down
Loading
Loading