Skip to content
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
8 changes: 8 additions & 0 deletions changelog/unreleased/SOLR-17994-SolrClientCustomizer.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# See https://github.com/apache/solr/blob/main/dev-docs/changelog.adoc
title: Rename HttpClientBuilderFactory to SolrClientCustomizer, and property solr.httpclient.builder.factory to solr.solrj.http.customizer
type: other # added, changed, fixed, deprecated, removed, dependency_update, security, other
authors:
- name: David Smiley
links:
- name: SOLR-17994
url: https://issues.apache.org/jira/browse/SOLR-17994
4 changes: 2 additions & 2 deletions solr/bin/solr
Original file line number Diff line number Diff line change
Expand Up @@ -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.impl.PreemptiveBasicAuthClientCustomizer"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perhaps this env var should be renamed too

;;
*)
echo "ERROR: Value specified for SOLR_AUTH_TYPE environment variable is invalid."
Expand All @@ -355,7 +355,7 @@ if [ -n "${SOLR_AUTHENTICATION_CLIENT_CONFIGURER:-}" ]; then
echo " Please start using SOLR_AUTH_TYPE instead"
fi
if [ -n "${SOLR_AUTHENTICATION_CLIENT_BUILDER:-}" ]; then
AUTHC_CLIENT_BUILDER_ARG="-Dsolr.httpclient.builder.factory=$SOLR_AUTHENTICATION_CLIENT_BUILDER"
AUTHC_CLIENT_BUILDER_ARG="-Dsolr.solrj.http.customizer=$SOLR_AUTHENTICATION_CLIENT_BUILDER"
AUTHC_OPTS="${AUTHC_CLIENT_BUILDER_ARG:-}"
fi
# This looks strange, but it is to avoid extra spaces when we have only one of the values set
Expand Down
6 changes: 3 additions & 3 deletions solr/bin/solr.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -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.impl.PreemptiveBasicAuthClientCustomizer"
) ELSE (
echo ERROR: Value specified for SOLR_AUTH_TYPE configuration variable is invalid.
goto err
Expand All @@ -239,7 +239,7 @@ IF DEFINED SOLR_AUTHENTICATION_CLIENT_CONFIGURER (
echo Please start using SOLR_AUTH_TYPE instead
)
IF DEFINED SOLR_AUTHENTICATION_CLIENT_BUILDER (
set AUTHC_CLIENT_BUILDER_ARG="-Dsolr.httpclient.builder.factory=%SOLR_AUTHENTICATION_CLIENT_BUILDER%"
set AUTHC_CLIENT_BUILDER_ARG="-Dsolr.solrj.http.customizer=%SOLR_AUTHENTICATION_CLIENT_BUILDER%"
)
set "AUTHC_OPTS=%AUTHC_CLIENT_BUILDER_ARG% %SOLR_AUTHENTICATION_OPTS%"

Expand Down Expand Up @@ -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"
)
Expand Down
2 changes: 1 addition & 1 deletion solr/bin/solr.in.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -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.impl.PreemptiveBasicAuthClientCustomizer
REM set SOLR_AUTH_TYPE=basic
REM set SOLR_AUTHENTICATION_OPTS=-Dsolr.security.auth.basicauth.credentials=solr:SolrRocks

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrClientCustomizer;
import org.apache.solr.client.solrj.SolrQuery;
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.apache.CloudLegacySolrClient;
import org.apache.solr.client.solrj.apache.HttpSolrClient;
import org.apache.solr.client.solrj.impl.SolrHttpConstants;
import org.apache.solr.client.solrj.request.CollectionAdminRequest;
import org.apache.solr.client.solrj.request.QueryRequest;
import org.apache.solr.client.solrj.request.UpdateRequest;
Expand All @@ -48,8 +48,8 @@ public static void setupCluster() throws Exception {
// for context)
if (rarely()) {
System.setProperty(
SolrHttpConstants.SYS_PROP_HTTP_CLIENT_BUILDER_FACTORY,
"org.apache.solr.client.solrj.impl.PreemptiveBasicAuthClientBuilderFactory");
SolrClientCustomizer.CLIENT_CUSTOMIZER_SYSPROP,
"org.apache.solr.client.solrj.impl.PreemptiveBasicAuthClientCustomizer");
System.setProperty("solr.security.auth.basicauth.credentials", SecurityJson.USER_PASS);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,15 @@ NOTE: Properties marked with "!" indicate inverted meaning between old and new p

|solr.security.allow.urls|solr.allowUrls||A comma seperated list of urls for reading from.

|solr.security.allow.urls.enabled|!solr.disable.allow.urls|false|If using an allow list of accessible urls is enabled.
|solr.security.allow.urls.enabled|!solr.disable.allow.urls|false|If using an allow list of accessible urls is enabled.


|solr.security.auth.plugin|authenticationPlugin||Specifies the authentication plugin to use.

|solr.solrj.cloud.max.stale.retries|cloudSolrClientMaxStaleRetries|5|Sets the maximum number of retries for stale connection attempts in SolrJ cloud client.

|solr.solrj.http.customizer|solr.httpclient.builder.factory||A class loaded to customize HttpJettySolrClient upon creation.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HttpJettySolrClient slipped in here... hasn't been renamed from Http2SolrClient yet

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense


|solr.streamingexpressions.facet.tiered.enabled|solr.facet.stream.tiered|true|Controls whether tiered faceting is enabled for streaming expressions.

|solr.streamingexpressions.macros.enabled|StreamingExpressionMacros|false|Controls whether to expand URL parameters inside of the `expr` parameter.
Expand Down Expand Up @@ -142,8 +144,8 @@ System properties can be set in several ways:
2. In `solr.in.sh` (Unix) or `solr.in.cmd` (Windows) using environment variables
3. Through environment variables (with appropriate naming conventions)

Environment variables can also be used to set these properties.
You may find this useful in environments such as Docker.
Environment variables can also be used to set these properties.
You may find this useful in environments such as Docker.
Environment variables should be uppercase with dot notations equivalents, e.g. `SOLR_API_V2_ENABLED` for the property `solr.api.v2.enabled`.

== See Also
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -358,9 +358,9 @@ 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`.
`PreemptiveBasicAuthClientBuilderFactory` allows applications to provide credentials in two different ways:
Alternatively, users can use SolrJ's `PreemptiveBasicAuthClientCustomizer` to add basic authentication credentials to _all_ requests automatically.
To enable this feature, users should set the following system property `-Dsolr.solrj.http.customizer=org.apache.solr.client.solrj.impl.PreemptiveBasicAuthClientCustomizer`.
`PreemptiveBasicAuthClientCustomizer` 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`).
This option is straightforward, but may expose the credentials in the command line, depending on how they're set.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ Users who previously relied on collection-specific URLs to avoid including the c
This makes it clear that they pertain specifically to “JavaBin” rather than binary in general.

* The deprecated SolrClient implementations based on Apache HttpClient are removed from Solrj, thus the related dependencies are no longer present.
The system property `solr.httpclient.builder.factory` now only configures SolrClients using a Jetty based HttpClient.
The system property `solr.solrj.http.customizer` (formerly `solr.httpclient.builder.factory`) now only configures SolrClients using a Jetty based HttpClient.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We haven't done in ref guide any "formerly known" language out side of the Solr properties ref guide page for all the renamed props.


=== SolrCloud Overseer

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,21 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.solr.client.solrj.impl;

import java.io.Closeable;
package org.apache.solr.client.solrj;

/**
* A config hook for post-configuration of a {@linkplain Http2SolrClient} by its builder.
* A config hook for post-configuration of a {@linkplain SolrClient} by its builder. It is not
* supported by all builders.
*
* @see SolrHttpConstants#SYS_PROP_HTTP_CLIENT_BUILDER_FACTORY
* @see #CLIENT_CUSTOMIZER_SYSPROP
* @lucene.experimental
*/
public interface HttpClientBuilderFactory extends Closeable {
default void setup(Http2SolrClient client) {}
public interface SolrClientCustomizer {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doesn't need to be Closeable!

/**
* A Java system property to select the {@linkplain SolrClientCustomizer} used for configuring
* HTTP based SolrClients.
*/
String CLIENT_CUSTOMIZER_SYSPROP = "solr.solrj.http.customizer";

void setup(SolrClient client);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No longer mandate a specific type of SolrClient

}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import org.apache.solr.client.api.util.SolrVersion;
import org.apache.solr.client.solrj.ResponseParser;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrClientCustomizer;
import org.apache.solr.client.solrj.SolrClientFunction;
import org.apache.solr.client.solrj.SolrRequest;
import org.apache.solr.client.solrj.SolrResponse;
Expand All @@ -55,6 +56,7 @@
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.params.UpdateParams;
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;
Expand Down Expand Up @@ -164,7 +166,7 @@ protected Http2SolrClient(String serverBaseUrl, Builder builder) {
this.idleTimeoutMillis = builder.getIdleTimeoutMillis();

try {
applyHttpClientBuilderFactory();
applyClientCustomizer();
} catch (RuntimeException e) {
try {
this.close();
Expand All @@ -185,16 +187,15 @@ private void initAuthStoreFromExistingClient(HttpClient httpClient) {
this.authenticationStore = (AuthenticationStoreHolder) httpClient.getAuthenticationStore();
}

private void applyHttpClientBuilderFactory() {
String factoryClassName =
System.getProperty(SolrHttpConstants.SYS_PROP_HTTP_CLIENT_BUILDER_FACTORY);
private void applyClientCustomizer() {
String factoryClassName = EnvUtils.getProperty(SolrClientCustomizer.CLIENT_CUSTOMIZER_SYSPROP);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now using EnvUtils; should now work consistently with the env var pattern if someone wishes

if (factoryClassName != null) {
log.debug("Using Http Builder Factory: {}", factoryClassName);
HttpClientBuilderFactory factory;
log.debug("Using {}", factoryClassName);
SolrClientCustomizer factory;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO rename to instance

try {
factory =
Class.forName(factoryClassName)
.asSubclass(HttpClientBuilderFactory.class)
.asSubclass(SolrClientCustomizer.class)
.getDeclaredConstructor()
.newInstance();
} catch (InstantiationException
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrClientCustomizer;
import org.apache.solr.client.solrj.util.SolrBasicAuthentication;
import org.apache.solr.common.params.MapSolrParams;
import org.apache.solr.common.params.SolrParams;
Expand All @@ -38,7 +40,7 @@
* HttpClientConfigurer implementation providing support for preemptive Http Basic authentication
* scheme.
*/
public class PreemptiveBasicAuthClientBuilderFactory implements HttpClientBuilderFactory {
public class PreemptiveBasicAuthClientCustomizer implements SolrClientCustomizer {
/**
* A system property used to specify a properties file containing default parameters used for
* creating an HTTP client. This is specifically useful for configuring the HTTP basic auth
Expand Down Expand Up @@ -66,15 +68,15 @@ public static void setDefaultSolrParams(SolrParams params) {
}

@Override
public void close() throws IOException {}

@Override
public void setup(Http2SolrClient client) {
public void setup(SolrClient client) {
if (client instanceof Http2SolrClient == false) {
return;
}
Comment on lines +71 to +74
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gerlowskija , responding to your feedback:

The code here isn't really different than the behavior today -- if you set the sys prop, it only applies to Http2SolrClient (Jetty). If we start using this mechanism at not only the Http SolrClient level but also CloudSolrClient or whatever else that may or may not apply to this customizer, then it should skip it. But I get your concern. Perhaps the property should reflect the usage... so solr.solrj.http.jetty.customizer vs solr.solrj.http.jdk.customizer (hypothetical). With this approach, the implementation should throw an exception if the type is wrong. And the implementation should reflect it as well, like putting "Jetty" into PreemptiveBasicAuthClientJettyCustomizer. LMK what you think; I'd prefer this way.

final String basicAuthUser =
CREDENTIAL_RESOLVER.defaultParams.get(SolrHttpConstants.PROP_BASIC_AUTH_USER);
final String basicAuthPass =
CREDENTIAL_RESOLVER.defaultParams.get(SolrHttpConstants.PROP_BASIC_AUTH_PASS);
this.setup(client, basicAuthUser, basicAuthPass);
this.setup((Http2SolrClient) client, basicAuthUser, basicAuthPass);
}

public void setup(Http2SolrClient client, String basicAuthUser, String basicAuthPass) {
Expand All @@ -98,10 +100,9 @@ static class CredentialsResolver {

public CredentialsResolver() {
String credentials =
System.getProperty(
PreemptiveBasicAuthClientBuilderFactory.SYS_PROP_BASIC_AUTH_CREDENTIALS);
System.getProperty(PreemptiveBasicAuthClientCustomizer.SYS_PROP_BASIC_AUTH_CREDENTIALS);
String configFile =
System.getProperty(PreemptiveBasicAuthClientBuilderFactory.SYS_PROP_HTTP_CLIENT_CONFIG);
System.getProperty(PreemptiveBasicAuthClientCustomizer.SYS_PROP_HTTP_CLIENT_CONFIG);

if (credentials != null && configFile != null) {
throw new IllegalArgumentException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,6 @@ public interface SolrHttpConstants {
/** Maximum total connections allowed */
String PROP_MAX_CONNECTIONS = "maxConnections";

/**
* A Java system property to select the {@linkplain HttpClientBuilderFactory} used for configuring
* HTTP based SolrClients.
*/
String SYS_PROP_HTTP_CLIENT_BUILDER_FACTORY = "solr.httpclient.builder.factory";
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I felt this was better organized on the class that loads it. I can change back if asked.


/**
* System property consulted to determine if HTTP based SolrClients will require hostname
* validation of SSL Certificates. The default behavior is to enforce peer name validation.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.apache.solr.client.api.util.SolrVersion;
import org.apache.solr.client.solrj.ResponseParser;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrClientCustomizer;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrRequest;
import org.apache.solr.client.solrj.SolrServerException;
Expand Down Expand Up @@ -487,13 +488,13 @@ public void testSetCredentialsExplicitly() {
@Test
public void testSetCredentialsWithSysProps() throws IOException, SolrServerException {
System.setProperty(
PreemptiveBasicAuthClientBuilderFactory.SYS_PROP_BASIC_AUTH_CREDENTIALS, "foo:bar");
PreemptiveBasicAuthClientCustomizer.SYS_PROP_BASIC_AUTH_CREDENTIALS, "foo:bar");
System.setProperty(
SolrHttpConstants.SYS_PROP_HTTP_CLIENT_BUILDER_FACTORY,
PreemptiveBasicAuthClientBuilderFactory.class.getName());
SolrClientCustomizer.CLIENT_CUSTOMIZER_SYSPROP,
PreemptiveBasicAuthClientCustomizer.class.getName());
// Hack to ensure we get a new set of parameters for this test
PreemptiveBasicAuthClientBuilderFactory.setDefaultSolrParams(
new PreemptiveBasicAuthClientBuilderFactory.CredentialsResolver().defaultParams);
PreemptiveBasicAuthClientCustomizer.setDefaultSolrParams(
new PreemptiveBasicAuthClientCustomizer.CredentialsResolver().defaultParams);
try (Http2SolrClient client =
new Http2SolrClient.Builder(getBaseUrl() + DEBUG_SERVLET_PATH)
.withDefaultCollection(DEFAULT_CORE)
Expand All @@ -516,9 +517,9 @@ public void testSetCredentialsWithSysProps() throws IOException, SolrServerExcep
"Basic " + Base64.getEncoder().encodeToString("foo:bar".getBytes(StandardCharsets.UTF_8)),
authorizationHeader);
} finally {
System.clearProperty(PreemptiveBasicAuthClientBuilderFactory.SYS_PROP_BASIC_AUTH_CREDENTIALS);
System.clearProperty(SolrHttpConstants.SYS_PROP_HTTP_CLIENT_BUILDER_FACTORY);
PreemptiveBasicAuthClientBuilderFactory.setDefaultSolrParams(SolrParams.of());
System.clearProperty(PreemptiveBasicAuthClientCustomizer.SYS_PROP_BASIC_AUTH_CREDENTIALS);
System.clearProperty(SolrClientCustomizer.CLIENT_CUSTOMIZER_SYSPROP);
PreemptiveBasicAuthClientCustomizer.setDefaultSolrParams(SolrParams.of());
}
}

Expand Down Expand Up @@ -594,7 +595,7 @@ public void testBadExplicitCredentials() {

@Test
public void testBadHttpFactory() {
System.setProperty(SolrHttpConstants.SYS_PROP_HTTP_CLIENT_BUILDER_FACTORY, "FakeClassName");
System.setProperty(SolrClientCustomizer.CLIENT_CUSTOMIZER_SYSPROP, "FakeClassName");
try {
SolrClient client =
new Http2SolrClient.Builder(getBaseUrl() + DEBUG_SERVLET_PATH)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@
import org.apache.solr.SolrJettyTestBase;
import org.apache.solr.client.solrj.ResponseParser;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrClientCustomizer;
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.apache.HttpClientUtil;
import org.apache.solr.client.solrj.request.QueryRequest;
import org.apache.solr.client.solrj.request.UpdateRequest;
import org.apache.solr.client.solrj.response.QueryResponse;
Expand Down Expand Up @@ -91,7 +91,7 @@ public static void beforeTest() throws Exception {
@Override
public void tearDown() throws Exception {
System.clearProperty("solr.security.auth.basicauth.credentials");
System.clearProperty(HttpClientUtil.SYS_PROP_HTTP_CLIENT_BUILDER_FACTORY);
System.clearProperty(SolrClientCustomizer.CLIENT_CUSTOMIZER_SYSPROP);
DebugServlet.clear();
super.tearDown();
}
Expand Down
Loading