From a92001130fd5082351f0d51713653b0ca5d9c8d5 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Thu, 24 Oct 2024 18:52:52 -0700 Subject: [PATCH] Deprecate `ClientHttpRequestFactories` Deprecate `ClientHttpRequestFactories` and refactor its internals to delegate to the new `ClientHttpRequestFactoryBuilder` interface. Closes gh-36266 --- .../reference/pages/io/rest-client.adoc | 2 +- .../restclient/ssl/settings/MyService.java | 14 +- .../restclient/ssl/settings/MyService.kt | 8 +- .../client/ClientHttpRequestFactories.java | 361 ++---------------- .../ClientHttpRequestFactorySettings.java | 3 + .../boot/web/client/RestTemplateBuilder.java | 4 + ...stractClientHttpRequestFactoriesTests.java | 1 + ...tpRequestFactoriesHttpComponentsTests.java | 1 + .../ClientHttpRequestFactoriesJettyTests.java | 1 + ...lientHttpRequestFactoriesReactorTests.java | 1 + ...ClientHttpRequestFactoriesSimpleTests.java | 1 + .../ClientHttpRequestFactoriesTests.java | 3 +- ...ClientHttpRequestFactorySettingsTests.java | 3 +- .../web/client/RestTemplateBuilderTests.java | 1 + 14 files changed, 51 insertions(+), 353 deletions(-) diff --git a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/io/rest-client.adoc b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/io/rest-client.adoc index ebea6544a9..9a1264e24c 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/io/rest-client.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/io/rest-client.adoc @@ -125,7 +125,7 @@ The following code shows a typical example: include-code::MyService[] -If you need to apply other customization in addition to an SSL bundle, you can use the `ClientHttpRequestFactorySettings` class with `ClientHttpRequestFactories`: +If you need to apply other customization in addition to an SSL bundle, you can use the `ClientHttpRequestFactorySettings` class with `ClientHttpRequestFactoryBuilder`: include-code::settings/MyService[] diff --git a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/restclient/restclient/ssl/settings/MyService.java b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/restclient/restclient/ssl/settings/MyService.java index 8fef86df53..f8aaef7cb0 100644 --- a/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/restclient/restclient/ssl/settings/MyService.java +++ b/spring-boot-project/spring-boot-docs/src/main/java/org/springframework/boot/docs/io/restclient/restclient/ssl/settings/MyService.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,9 +18,9 @@ package org.springframework.boot.docs.io.restclient.restclient.ssl.settings; import java.time.Duration; +import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder; +import org.springframework.boot.http.client.ClientHttpRequestFactorySettings; import org.springframework.boot.ssl.SslBundles; -import org.springframework.boot.web.client.ClientHttpRequestFactories; -import org.springframework.boot.web.client.ClientHttpRequestFactorySettings; import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.stereotype.Service; import org.springframework.web.client.RestClient; @@ -31,10 +31,10 @@ public class MyService { private final RestClient restClient; public MyService(RestClient.Builder restClientBuilder, SslBundles sslBundles) { - ClientHttpRequestFactorySettings settings = ClientHttpRequestFactorySettings.DEFAULTS - .withReadTimeout(Duration.ofMinutes(2)) - .withSslBundle(sslBundles.getBundle("mybundle")); - ClientHttpRequestFactory requestFactory = ClientHttpRequestFactories.get(settings); + ClientHttpRequestFactorySettings settings = ClientHttpRequestFactorySettings + .ofSslBundle(sslBundles.getBundle("mybundle")) + .withReadTimeout(Duration.ofMinutes(2)); + ClientHttpRequestFactory requestFactory = ClientHttpRequestFactoryBuilder.detect().build(settings); this.restClient = restClientBuilder.baseUrl("https://example.org").requestFactory(requestFactory).build(); } diff --git a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/restclient/restclient/ssl/settings/MyService.kt b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/restclient/restclient/ssl/settings/MyService.kt index e153262f82..c4133fa8fb 100644 --- a/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/restclient/restclient/ssl/settings/MyService.kt +++ b/spring-boot-project/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/io/restclient/restclient/ssl/settings/MyService.kt @@ -16,9 +16,9 @@ package org.springframework.boot.docs.io.restclient.restclient.ssl.settings +import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder; +import org.springframework.boot.http.client.ClientHttpRequestFactorySettings; import org.springframework.boot.ssl.SslBundles -import org.springframework.boot.web.client.ClientHttpRequestFactories -import org.springframework.boot.web.client.ClientHttpRequestFactorySettings import org.springframework.stereotype.Service import org.springframework.web.client.RestClient import java.time.Duration @@ -29,10 +29,10 @@ class MyService(restClientBuilder: RestClient.Builder, sslBundles: SslBundles) { private val restClient: RestClient init { - val settings = ClientHttpRequestFactorySettings.DEFAULTS + val settings = ClientHttpRequestFactorySettings.defaults() .withReadTimeout(Duration.ofMinutes(2)) .withSslBundle(sslBundles.getBundle("mybundle")) - val requestFactory = ClientHttpRequestFactories.get(settings) + val requestFactory = ClientHttpRequestFactoryBuilder.detect().build(settings); restClient = restClientBuilder .baseUrl("https://example.org") .requestFactory(requestFactory).build() diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/ClientHttpRequestFactories.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/ClientHttpRequestFactories.java index ca6898d3d9..5e69394fc6 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/ClientHttpRequestFactories.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/ClientHttpRequestFactories.java @@ -16,38 +16,10 @@ package org.springframework.boot.web.client; -import java.io.IOException; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.net.HttpURLConnection; -import java.time.Duration; -import java.util.concurrent.TimeUnit; import java.util.function.Supplier; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLException; -import javax.net.ssl.SSLSocketFactory; - -import io.netty.handler.ssl.SslContextBuilder; -import org.apache.hc.client5.http.classic.HttpClient; -import org.apache.hc.client5.http.impl.classic.HttpClientBuilder; -import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager; -import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; -import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy; -import org.apache.hc.client5.http.ssl.DefaultHostnameVerifier; -import org.apache.hc.core5.http.io.SocketConfig; -import org.eclipse.jetty.client.transport.HttpClientTransportDynamic; -import org.eclipse.jetty.io.ClientConnector; -import org.eclipse.jetty.util.ssl.SslContextFactory; -import reactor.netty.tcp.SslProvider.SslContextSpec; - -import org.springframework.boot.context.properties.PropertyMapper; -import org.springframework.boot.ssl.SslBundle; -import org.springframework.boot.ssl.SslManagerBundle; -import org.springframework.boot.ssl.SslOptions; -import org.springframework.http.client.AbstractClientHttpRequestFactoryWrapper; +import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder; +import org.springframework.boot.http.client.JdkClientHttpRequestFactoryBuilder; import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.http.client.JdkClientHttpRequestFactory; @@ -56,8 +28,6 @@ import org.springframework.http.client.ReactorClientHttpRequestFactory; import org.springframework.http.client.SimpleClientHttpRequestFactory; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; -import org.springframework.util.ReflectionUtils; -import org.springframework.util.function.ThrowingConsumer; /** * Utility class that can be used to create {@link ClientHttpRequestFactory} instances @@ -67,21 +37,12 @@ import org.springframework.util.function.ThrowingConsumer; * @author Phillip Webb * @author Scott Frederick * @since 3.0.0 + * @deprecated since 3.4.0 for removal in 3.6.0 in favor of + * {@link ClientHttpRequestFactoryBuilder} */ +@Deprecated(since = "3.4.0", forRemoval = true) public final class ClientHttpRequestFactories { - static final String APACHE_HTTP_CLIENT_CLASS = "org.apache.hc.client5.http.impl.classic.HttpClients"; - - private static final boolean APACHE_HTTP_CLIENT_PRESENT = ClassUtils.isPresent(APACHE_HTTP_CLIENT_CLASS, null); - - static final String JETTY_CLIENT_CLASS = "org.eclipse.jetty.client.HttpClient"; - - private static final boolean JETTY_CLIENT_PRESENT = ClassUtils.isPresent(JETTY_CLIENT_CLASS, null); - - static final String REACTOR_CLIENT_CLASS = "reactor.netty.http.client.HttpClient"; - - private static final boolean REACTOR_CLIENT_PRESENT = ClassUtils.isPresent(REACTOR_CLIENT_CLASS, null); - private ClientHttpRequestFactories() { } @@ -98,18 +59,10 @@ public final class ClientHttpRequestFactories { * @param settings the settings to apply * @return a new {@link ClientHttpRequestFactory} */ + @SuppressWarnings("removal") public static ClientHttpRequestFactory get(ClientHttpRequestFactorySettings settings) { Assert.notNull(settings, "Settings must not be null"); - if (APACHE_HTTP_CLIENT_PRESENT) { - return HttpComponents.get(settings); - } - if (JETTY_CLIENT_PRESENT) { - return Jetty.get(settings); - } - if (REACTOR_CLIENT_PRESENT) { - return Reactor.get(settings); - } - return Simple.get(settings); + return detectBuilder().build(settings.adapt()); } /** @@ -131,29 +84,11 @@ public final class ClientHttpRequestFactories { * @param settings the settings to apply * @return a new {@link ClientHttpRequestFactory} instance */ - @SuppressWarnings("unchecked") + @SuppressWarnings("removal") public static T get(Class requestFactoryType, ClientHttpRequestFactorySettings settings) { Assert.notNull(settings, "Settings must not be null"); - if (requestFactoryType == ClientHttpRequestFactory.class) { - return (T) get(settings); - } - if (requestFactoryType == HttpComponentsClientHttpRequestFactory.class) { - return (T) HttpComponents.get(settings); - } - if (requestFactoryType == JettyClientHttpRequestFactory.class) { - return (T) Jetty.get(settings); - } - if (requestFactoryType == ReactorClientHttpRequestFactory.class) { - return (T) Reactor.get(settings); - } - if (requestFactoryType == JdkClientHttpRequestFactory.class) { - return (T) Jdk.get(settings); - } - if (requestFactoryType == SimpleClientHttpRequestFactory.class) { - return (T) Simple.get(settings); - } - return get(() -> createRequestFactory(requestFactoryType), settings); + return getBuilder(requestFactoryType).build(settings.adapt()); } /** @@ -164,278 +99,28 @@ public final class ClientHttpRequestFactories { * @param settings the settings to apply * @return a new {@link ClientHttpRequestFactory} instance */ + @SuppressWarnings("removal") public static T get(Supplier requestFactorySupplier, ClientHttpRequestFactorySettings settings) { - return Reflective.get(requestFactorySupplier, settings); + return ClientHttpRequestFactoryBuilder.of(requestFactorySupplier).build(settings.adapt()); } - private static T createRequestFactory(Class requestFactory) { - try { - Constructor constructor = requestFactory.getDeclaredConstructor(); - constructor.setAccessible(true); - return constructor.newInstance(); - } - catch (Exception ex) { - throw new IllegalStateException(ex); + @SuppressWarnings("unchecked") + private static ClientHttpRequestFactoryBuilder getBuilder( + Class requestFactoryType) { + if (requestFactoryType == ClientHttpRequestFactory.class) { + return (ClientHttpRequestFactoryBuilder) detectBuilder(); } + return ClientHttpRequestFactoryBuilder.of(requestFactoryType); } - /** - * Support for {@link HttpComponentsClientHttpRequestFactory}. - */ - static class HttpComponents { - - static HttpComponentsClientHttpRequestFactory get(ClientHttpRequestFactorySettings settings) { - HttpComponentsClientHttpRequestFactory requestFactory = createRequestFactory(settings.readTimeout(), - settings.sslBundle()); - PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); - map.from(settings::connectTimeout).asInt(Duration::toMillis).to(requestFactory::setConnectTimeout); - return requestFactory; + private static ClientHttpRequestFactoryBuilder detectBuilder() { + ClientHttpRequestFactoryBuilder builder = ClientHttpRequestFactoryBuilder.detect(); + if (builder instanceof JdkClientHttpRequestFactoryBuilder) { + // Same logic as earlier versions which did not support JDK client factories + return ClientHttpRequestFactoryBuilder.simple(); } - - private static HttpComponentsClientHttpRequestFactory createRequestFactory(Duration readTimeout, - SslBundle sslBundle) { - return new HttpComponentsClientHttpRequestFactory(createHttpClient(readTimeout, sslBundle)); - } - - private static HttpClient createHttpClient(Duration readTimeout, SslBundle sslBundle) { - PoolingHttpClientConnectionManagerBuilder connectionManagerBuilder = PoolingHttpClientConnectionManagerBuilder - .create(); - if (readTimeout != null) { - SocketConfig socketConfig = SocketConfig.custom() - .setSoTimeout((int) readTimeout.toMillis(), TimeUnit.MILLISECONDS) - .build(); - connectionManagerBuilder.setDefaultSocketConfig(socketConfig); - } - if (sslBundle != null) { - SslOptions options = sslBundle.getOptions(); - connectionManagerBuilder.setTlsSocketStrategy(new DefaultClientTlsStrategy(sslBundle.createSslContext(), - options.getEnabledProtocols(), options.getCiphers(), null, new DefaultHostnameVerifier())); - } - PoolingHttpClientConnectionManager connectionManager = connectionManagerBuilder.useSystemProperties() - .build(); - return HttpClientBuilder.create().useSystemProperties().setConnectionManager(connectionManager).build(); - } - - } - - /** - * Support for {@link JettyClientHttpRequestFactory}. - */ - static class Jetty { - - static JettyClientHttpRequestFactory get(ClientHttpRequestFactorySettings settings) { - JettyClientHttpRequestFactory requestFactory = createRequestFactory(settings.sslBundle()); - PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); - map.from(settings::connectTimeout).asInt(Duration::toMillis).to(requestFactory::setConnectTimeout); - map.from(settings::readTimeout).asInt(Duration::toMillis).to(requestFactory::setReadTimeout); - return requestFactory; - } - - private static JettyClientHttpRequestFactory createRequestFactory(SslBundle sslBundle) { - if (sslBundle != null) { - SSLContext sslContext = sslBundle.createSslContext(); - SslContextFactory.Client sslContextFactory = new SslContextFactory.Client(); - sslContextFactory.setSslContext(sslContext); - ClientConnector connector = new ClientConnector(); - connector.setSslContextFactory(sslContextFactory); - org.eclipse.jetty.client.HttpClient httpClient = new org.eclipse.jetty.client.HttpClient( - new HttpClientTransportDynamic(connector)); - return new JettyClientHttpRequestFactory(httpClient); - } - return new JettyClientHttpRequestFactory(); - } - - } - - /** - * Support for {@link ReactorClientHttpRequestFactory}. - */ - static class Reactor { - - static ReactorClientHttpRequestFactory get(ClientHttpRequestFactorySettings settings) { - ReactorClientHttpRequestFactory requestFactory = createRequestFactory(settings.sslBundle()); - PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); - map.from(settings::connectTimeout).asInt(Duration::toMillis).to(requestFactory::setConnectTimeout); - map.from(settings::readTimeout).asInt(Duration::toMillis).to(requestFactory::setReadTimeout); - return requestFactory; - } - - private static ReactorClientHttpRequestFactory createRequestFactory(SslBundle sslBundle) { - if (sslBundle != null) { - reactor.netty.http.client.HttpClient httpClient = reactor.netty.http.client.HttpClient.create() - .secure((ThrowingConsumer.of((spec) -> configureSsl(spec, sslBundle)))); - return new ReactorClientHttpRequestFactory(httpClient); - } - return new ReactorClientHttpRequestFactory(); - } - - private static void configureSsl(SslContextSpec spec, SslBundle sslBundle) throws SSLException { - SslOptions options = sslBundle.getOptions(); - SslManagerBundle managers = sslBundle.getManagers(); - SslContextBuilder builder = SslContextBuilder.forClient() - .keyManager(managers.getKeyManagerFactory()) - .trustManager(managers.getTrustManagerFactory()) - .ciphers(SslOptions.asSet(options.getCiphers())) - .protocols(options.getEnabledProtocols()); - spec.sslContext(builder.build()); - } - - } - - /** - * Support for {@link JdkClientHttpRequestFactory}. - */ - static class Jdk { - - static JdkClientHttpRequestFactory get(ClientHttpRequestFactorySettings settings) { - java.net.http.HttpClient httpClient = createHttpClient(settings.connectTimeout(), settings.sslBundle()); - JdkClientHttpRequestFactory requestFactory = new JdkClientHttpRequestFactory(httpClient); - PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); - map.from(settings::readTimeout).to(requestFactory::setReadTimeout); - return requestFactory; - } - - private static java.net.http.HttpClient createHttpClient(Duration connectTimeout, SslBundle sslBundle) { - java.net.http.HttpClient.Builder builder = java.net.http.HttpClient.newBuilder(); - if (connectTimeout != null) { - builder.connectTimeout(connectTimeout); - } - if (sslBundle != null) { - builder.sslContext(sslBundle.createSslContext()); - } - return builder.build(); - } - - } - - /** - * Support for {@link SimpleClientHttpRequestFactory}. - */ - static class Simple { - - static SimpleClientHttpRequestFactory get(ClientHttpRequestFactorySettings settings) { - SslBundle sslBundle = settings.sslBundle(); - SimpleClientHttpRequestFactory requestFactory = (sslBundle != null) - ? new SimpleClientHttpsRequestFactory(sslBundle) : new SimpleClientHttpRequestFactory(); - Assert.state(sslBundle == null || !sslBundle.getOptions().isSpecified(), - "SSL Options cannot be specified with Java connections"); - PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); - map.from(settings::readTimeout).asInt(Duration::toMillis).to(requestFactory::setReadTimeout); - map.from(settings::connectTimeout).asInt(Duration::toMillis).to(requestFactory::setConnectTimeout); - return requestFactory; - } - - /** - * {@link SimpleClientHttpsRequestFactory} to configure SSL from an - * {@link SslBundle}. - */ - private static class SimpleClientHttpsRequestFactory extends SimpleClientHttpRequestFactory { - - private final SslBundle sslBundle; - - SimpleClientHttpsRequestFactory(SslBundle sslBundle) { - this.sslBundle = sslBundle; - } - - @Override - protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException { - super.prepareConnection(connection, httpMethod); - if (this.sslBundle != null && connection instanceof HttpsURLConnection secureConnection) { - SSLSocketFactory socketFactory = this.sslBundle.createSslContext().getSocketFactory(); - secureConnection.setSSLSocketFactory(socketFactory); - } - } - - } - - } - - /** - * Support for reflective configuration of an unknown {@link ClientHttpRequestFactory} - * implementation. - */ - static class Reflective { - - static T get(Supplier requestFactorySupplier, - ClientHttpRequestFactorySettings settings) { - T requestFactory = requestFactorySupplier.get(); - configure(requestFactory, settings); - return requestFactory; - } - - private static void configure(ClientHttpRequestFactory requestFactory, - ClientHttpRequestFactorySettings settings) { - ClientHttpRequestFactory unwrapped = unwrapRequestFactoryIfNecessary(requestFactory); - PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); - map.from(settings::connectTimeout).to((connectTimeout) -> setConnectTimeout(unwrapped, connectTimeout)); - map.from(settings::readTimeout).to((readTimeout) -> setReadTimeout(unwrapped, readTimeout)); - } - - private static ClientHttpRequestFactory unwrapRequestFactoryIfNecessary( - ClientHttpRequestFactory requestFactory) { - if (!(requestFactory instanceof AbstractClientHttpRequestFactoryWrapper)) { - return requestFactory; - } - Field field = ReflectionUtils.findField(AbstractClientHttpRequestFactoryWrapper.class, "requestFactory"); - ReflectionUtils.makeAccessible(field); - ClientHttpRequestFactory unwrappedRequestFactory = requestFactory; - while (unwrappedRequestFactory instanceof AbstractClientHttpRequestFactoryWrapper) { - unwrappedRequestFactory = (ClientHttpRequestFactory) ReflectionUtils.getField(field, - unwrappedRequestFactory); - } - return unwrappedRequestFactory; - } - - private static void setConnectTimeout(ClientHttpRequestFactory factory, Duration connectTimeout) { - Method method = tryFindMethod(factory, "setConnectTimeout", Duration.class); - if (method != null) { - invoke(factory, method, connectTimeout); - return; - } - method = findMethod(factory, "setConnectTimeout", int.class); - int timeout = Math.toIntExact(connectTimeout.toMillis()); - invoke(factory, method, timeout); - } - - private static void setReadTimeout(ClientHttpRequestFactory factory, Duration readTimeout) { - Method method = tryFindMethod(factory, "setReadTimeout", Duration.class); - if (method != null) { - invoke(factory, method, readTimeout); - return; - } - method = findMethod(factory, "setReadTimeout", int.class); - int timeout = Math.toIntExact(readTimeout.toMillis()); - invoke(factory, method, timeout); - } - - private static Method findMethod(ClientHttpRequestFactory requestFactory, String methodName, - Class... parameters) { - Method method = ReflectionUtils.findMethod(requestFactory.getClass(), methodName, parameters); - Assert.state(method != null, () -> "Request factory %s does not have a suitable %s method" - .formatted(requestFactory.getClass().getName(), methodName)); - Assert.state(!method.isAnnotationPresent(Deprecated.class), - () -> "Request factory %s has the %s method marked as deprecated" - .formatted(requestFactory.getClass().getName(), methodName)); - return method; - } - - private static Method tryFindMethod(ClientHttpRequestFactory requestFactory, String methodName, - Class... parameters) { - Method method = ReflectionUtils.findMethod(requestFactory.getClass(), methodName, parameters); - if (method == null) { - return null; - } - if (method.isAnnotationPresent(Deprecated.class)) { - return null; - } - return method; - } - - private static void invoke(ClientHttpRequestFactory requestFactory, Method method, Object... parameters) { - ReflectionUtils.invokeMethod(method, requestFactory, parameters); - } - + return builder; } } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/ClientHttpRequestFactorySettings.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/ClientHttpRequestFactorySettings.java index f8c851b89d..163651cf3a 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/ClientHttpRequestFactorySettings.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/ClientHttpRequestFactorySettings.java @@ -33,7 +33,10 @@ import org.springframework.http.client.ClientHttpRequestFactory; * @author Scott Frederick * @since 3.0.0 * @see ClientHttpRequestFactoryBuilder + * @deprecated since 3.4.0 for removal in 3.6.0 in favor of + * {@link org.springframework.boot.http.client.ClientHttpRequestFactorySettings} */ +@Deprecated(since = "3.4.0", forRemoval = true) public record ClientHttpRequestFactorySettings(Duration connectTimeout, Duration readTimeout, SslBundle sslBundle) { /** diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/RestTemplateBuilder.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/RestTemplateBuilder.java index 06f45dee1c..2f5e35b5ab 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/RestTemplateBuilder.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/RestTemplateBuilder.java @@ -330,9 +330,13 @@ public class RestTemplateBuilder { * @param requestFactoryFunction the settings to request factory function * @return a new builder instance * @since 3.0.0 + * @deprecated since 3.4.0 for removal in 3.6.0 in favor of + * {@link #requestFactoryBuilder(ClientHttpRequestFactoryBuilder)} * @see ClientHttpRequestFactoryBuilder * @see #requestFactoryBuilder(ClientHttpRequestFactoryBuilder) */ + @Deprecated(since = "3.4.0", forRemoval = true) + @SuppressWarnings("removal") public RestTemplateBuilder requestFactory( Function requestFactoryFunction) { Assert.notNull(requestFactoryFunction, "RequestFactoryFunction must not be null"); diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/AbstractClientHttpRequestFactoriesTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/AbstractClientHttpRequestFactoriesTests.java index 3e7e24def7..5b81f4c3d9 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/AbstractClientHttpRequestFactoriesTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/AbstractClientHttpRequestFactoriesTests.java @@ -57,6 +57,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; * @author Andy Wilkinson */ @DirtiesUrlFactories +@SuppressWarnings("removal") abstract class AbstractClientHttpRequestFactoriesTests { private final Class requestFactoryType; diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesHttpComponentsTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesHttpComponentsTests.java index 82b5c3330a..d7d99502d0 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesHttpComponentsTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesHttpComponentsTests.java @@ -30,6 +30,7 @@ import org.springframework.test.util.ReflectionTestUtils; * * @author Andy Wilkinson */ +@SuppressWarnings("removal") class ClientHttpRequestFactoriesHttpComponentsTests extends AbstractClientHttpRequestFactoriesTests { diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesJettyTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesJettyTests.java index c8afb5845e..06ce1f8716 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesJettyTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesJettyTests.java @@ -28,6 +28,7 @@ import org.springframework.test.util.ReflectionTestUtils; * @author Arjen Poutsma */ @ClassPathExclusions("httpclient5-*.jar") +@SuppressWarnings("removal") class ClientHttpRequestFactoriesJettyTests extends AbstractClientHttpRequestFactoriesTests { diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesReactorTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesReactorTests.java index c538014ddf..d92afb894b 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesReactorTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesReactorTests.java @@ -32,6 +32,7 @@ import org.springframework.test.util.ReflectionTestUtils; * @author Andy Wilkinson */ @ClassPathExclusions({ "httpclient5-*.jar", "jetty-client-*.jar" }) +@SuppressWarnings("removal") class ClientHttpRequestFactoriesReactorTests extends AbstractClientHttpRequestFactoriesTests { diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesSimpleTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesSimpleTests.java index 651232c7b5..b83e0fe5a4 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesSimpleTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesSimpleTests.java @@ -27,6 +27,7 @@ import org.springframework.test.util.ReflectionTestUtils; * @author Andy Wilkinson */ @ClassPathExclusions({ "httpclient5-*.jar", "jetty-client-*.jar", "reactor-netty-http-*.jar" }) +@SuppressWarnings("removal") class ClientHttpRequestFactoriesSimpleTests extends AbstractClientHttpRequestFactoriesTests { diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesTests.java index 577aacc07e..dec8bbf602 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactoriesTests.java @@ -38,6 +38,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException; * * @author Andy Wilkinson */ +@SuppressWarnings("removal") class ClientHttpRequestFactoriesTests { @Test @@ -76,8 +77,6 @@ class ClientHttpRequestFactoriesTests { } @Test - @Deprecated(since = "3.2.0") - @SuppressWarnings("removal") void getOfOkHttpFactoryReturnsOkHttpFactory() { ClientHttpRequestFactory requestFactory = ClientHttpRequestFactories.get( org.springframework.http.client.OkHttp3ClientHttpRequestFactory.class, diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactorySettingsTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactorySettingsTests.java index c9145b7dd2..a2699bc49d 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactorySettingsTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/ClientHttpRequestFactorySettingsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,6 +30,7 @@ import static org.mockito.Mockito.mock; * * @author Phillip Webb */ +@SuppressWarnings("removal") class ClientHttpRequestFactorySettingsTests { private static final Duration ONE_SECOND = Duration.ofSeconds(1); diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/RestTemplateBuilderTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/RestTemplateBuilderTests.java index a49ee833a6..0b2e39a75c 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/RestTemplateBuilderTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/RestTemplateBuilderTests.java @@ -273,6 +273,7 @@ class RestTemplateBuilderTests { } @Test + @SuppressWarnings("removal") void requestFactoryWhenFunctionIsNullShouldThrowException() { assertThatIllegalArgumentException().isThrownBy(() -> this.builder.requestFactory( (Function) null))