Enhance HttpComponents5MessageSender.

* The clientFactory could be null, so this must be handled.
* AuthScope.ANY no longer exists, so we need a suitable value object to take its place.
* Polish documentation and javadocs to support the community.

Resolves #1357.
This commit is contained in:
Lars Uffmann
2023-05-13 14:34:54 +02:00
committed by Greg L. Turnquist
parent 58c686874f
commit 24b466a0e1
3 changed files with 53 additions and 3 deletions

View File

@@ -33,6 +33,7 @@ import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuil
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.util.Timeout;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.ws.client.support.interceptor.ClientInterceptor;
/**
* {@link FactoryBean} to set up a {@link CloseableHttpClient} using HttpComponents HttpClient 5.
@@ -43,6 +44,18 @@ import org.springframework.beans.factory.FactoryBean;
*/
public class HttpComponents5ClientFactory implements FactoryBean<CloseableHttpClient> {
/**
* AuthScope to match any Host.
* <p>
* <b>HEADS-UP</b>: ANY has been removed from {@link AuthScope} since httpcomponents version 5.x. It has been
* redefined here to ease migration from httpcomponents 4. The associated functionality might be removed in a future
* version of apache httpcomponents. Consider using a {@link ClientInterceptor} to implement http client agnostic
* preemptive basic auth.
*
* @see AuthScope#AuthScope(String, String, int, String, String)
*/
public static final AuthScope ANY = new AuthScope(null, null, -1, null, null);
private static final Duration DEFAULT_CONNECTION_TIMEOUT = Duration.ofSeconds(60);
private static final Duration DEFAULT_READ_TIMEOUT = Duration.ofSeconds(60);
@@ -53,7 +66,7 @@ public class HttpComponents5ClientFactory implements FactoryBean<CloseableHttpCl
private int maxTotalConnections = -1;
private AuthScope authScope = null;
private AuthScope authScope = ANY;
private Credentials credentials = null;
@@ -78,7 +91,7 @@ public class HttpComponents5ClientFactory implements FactoryBean<CloseableHttpCl
/**
* Sets the authentication scope to be used. Only used when the {@code credentials} property has been set.
* <p>
* By default, the {@link AuthScope#ANY} is used.
* By default, the {@link #ANY} is used.
*
* @see #setCredentials(Credentials)
*/

View File

@@ -34,6 +34,7 @@ import org.apache.hc.core5.http.HttpHeaders;
import org.apache.hc.core5.http.HttpRequest;
import org.apache.hc.core5.http.HttpRequestInterceptor;
import org.apache.hc.core5.http.protocol.HttpContext;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
@@ -178,7 +179,10 @@ public class HttpComponents5MessageSender extends AbstractHttpWebServiceMessageS
@Override
public void afterPropertiesSet() throws Exception {
this.httpClient = clientFactory.getObject();
if (this.clientFactory != null) {
this.httpClient = clientFactory.getObject();
}
}
@Override

View File

@@ -0,0 +1,33 @@
package org.springframework.ws.transport.http;
import java.time.Duration;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.*;
class HttpComponents5MessageSenderTest {
@Test
void afterPropertiesSet_createHttpClient() throws Exception {
HttpComponents5MessageSender messageSender = new HttpComponents5MessageSender();
assertThat(messageSender.getHttpClient()).isNull();
Duration timeout = Duration.ofSeconds(1);
assertThatCode(() -> messageSender.setConnectionTimeout(timeout)).doesNotThrowAnyException();
messageSender.afterPropertiesSet();
assertThat(messageSender.getHttpClient()).isNotNull();
}
@Test
void afterPropertiesSet_httpClientAlreadySet() throws Exception {
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
HttpComponents5MessageSender messageSender = new HttpComponents5MessageSender(httpClient);
Duration timeout = Duration.ofSeconds(1);
assertThatCode(() -> messageSender.setConnectionTimeout(timeout)).isInstanceOf(IllegalStateException.class);
messageSender.afterPropertiesSet();
assertThat(messageSender.getHttpClient()).isSameAs(httpClient);
}
}