diff --git a/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheConnector.java b/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheConnector.java index 50fd7aff4a..16a11319a7 100644 --- a/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheConnector.java +++ b/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheConnector.java @@ -28,6 +28,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicLong; @@ -138,6 +139,12 @@ * be set to {@code true}. *

*

+ * Registration of {@link ApacheHttpClientBuilderConfigurator} instance on the + * {@link javax.ws.rs.client.Client#register(Object) Client} is supported. A configuration provided by + * {@link ApacheHttpClientBuilderConfigurator} will override the {@link org.apache.http.impl.client.HttpClientBuilder} + * configuration set by using the properties. + *

+ *

* If a {@link org.glassfish.jersey.client.ClientResponse} is obtained and an * entity is not read from the response then * {@link org.glassfish.jersey.client.ClientResponse#close()} MUST be called @@ -317,7 +324,15 @@ class ApacheConnector implements Connector { this.cookieStore = null; } clientBuilder.setDefaultRequestConfig(requestConfig); - this.client = clientBuilder.build(); + + Optional contract = config.getInstances().stream() + .filter(a -> ApacheHttpClientBuilderConfigurator.class.isInstance(a)).findFirst(); + + final HttpClientBuilder configuredBuilder = contract.isPresent() + ? ((ApacheHttpClientBuilderConfigurator) contract.get()).configure(clientBuilder) + : null; + + this.client = configuredBuilder != null ? configuredBuilder.build() : clientBuilder.build(); } private HttpClientConnectionManager getConnectionManager(final Client client, diff --git a/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheConnectorProvider.java b/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheConnectorProvider.java index b94923f493..d92d490fb1 100644 --- a/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheConnectorProvider.java +++ b/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheConnectorProvider.java @@ -72,6 +72,12 @@ * connection-based resources. *

*

+ * Registration of {@link ApacheHttpClientBuilderConfigurator} instance on the + * {@link javax.ws.rs.client.Client#register(Object) Client} is supported. A configuration provided by + * {@link ApacheHttpClientBuilderConfigurator} will override the {@link org.apache.http.impl.client.HttpClientBuilder} + * configuration set by using the properties. + *

+ *

* If a response entity is obtained that is an instance of {@link java.io.Closeable} * then the instance MUST be closed after processing the entity to release * connection-based resources. diff --git a/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheHttpClientBuilderConfigurator.java b/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheHttpClientBuilderConfigurator.java new file mode 100644 index 0000000000..251a5c49b6 --- /dev/null +++ b/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheHttpClientBuilderConfigurator.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package org.glassfish.jersey.apache.connector; + +import org.apache.http.impl.client.HttpClientBuilder; +import org.glassfish.jersey.spi.Contract; + +/** + * A callback interface used to configure {@link org.apache.http.impl.client.HttpClientBuilder}. It is called immediately before + * the {@link ApacheConnectorProvider} creates {@link org.apache.http.client.HttpClient}, after the + * {@link org.apache.http.impl.client.HttpClientBuilder} is configured using the properties. + */ +@Contract +public interface ApacheHttpClientBuilderConfigurator { + /** + * A callback method to configure the {@link org.apache.http.impl.client.HttpClientBuilder} + * @param httpClientBuilder {@link org.apache.http.impl.client.HttpClientBuilder} object to be further configured + * @return the configured {@link org.apache.http.impl.client.HttpClientBuilder}. If {@code null} is returned the + * {@code httpClientBuilder} is used by {@link ApacheConnectorProvider} instead. + */ + HttpClientBuilder configure(HttpClientBuilder httpClientBuilder); +} diff --git a/connectors/apache-connector/src/test/java/org/glassfish/jersey/apache/connector/AuthTest.java b/connectors/apache-connector/src/test/java/org/glassfish/jersey/apache/connector/AuthTest.java index 07586e9a07..dceb272c62 100644 --- a/connectors/apache-connector/src/test/java/org/glassfish/jersey/apache/connector/AuthTest.java +++ b/connectors/apache-connector/src/test/java/org/glassfish/jersey/apache/connector/AuthTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2019 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -33,6 +33,7 @@ import javax.inject.Singleton; +import org.apache.http.impl.client.HttpClientBuilder; import org.glassfish.jersey.client.ClientConfig; import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature; import org.glassfish.jersey.client.authentication.ResponseAuthenticationException; @@ -570,6 +571,25 @@ public void testAuthGetQueryParamsDigest() { .queryParam("param1", "value1") .queryParam("param2", "value2"); assertEquals("GET 3", r.request().get(String.class)); + } + + @Test + public void testAuthGetWithConfigurator() { + CredentialsProvider credentialsProvider = new org.apache.http.impl.client.BasicCredentialsProvider(); + credentialsProvider.setCredentials( + AuthScope.ANY, + new UsernamePasswordCredentials("name", "password") + ); + ApacheHttpClientBuilderConfigurator apacheHttpClientBuilderConfigurator = (httpClientBuilder) -> { + return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider); + }; + ClientConfig cc = new ClientConfig(); + cc.register(apacheHttpClientBuilderConfigurator); + cc.connectorProvider(new ApacheConnectorProvider()); + Client client = ClientBuilder.newClient(cc); + WebTarget r = client.target(getBaseUri()).path("test"); + + assertEquals("GET", r.request().get(String.class)); } }