Browse Source

Polish "Relax conditions to create HttpService client with RestClient"

See gh-48274
pull/48321/head
Stéphane Nicoll 3 weeks ago
parent
commit
4feb1faf3a
  1. 2
      module/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/HttpServiceClientAutoConfiguration.java
  2. 41
      module/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/NotReactiveWebApplicationCondition.java
  3. 54
      module/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/NotReactiveWebApplicationOrVirtualThreadsExecutorEnabledCondition.java
  4. 34
      module/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/service/HttpServiceClientAutoConfigurationTests.java

2
module/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/HttpServiceClientAutoConfiguration.java

@ -29,7 +29,6 @@ import org.springframework.boot.restclient.RestClientCustomizer;
import org.springframework.boot.restclient.autoconfigure.RestClientAutoConfiguration; import org.springframework.boot.restclient.autoconfigure.RestClientAutoConfiguration;
import org.springframework.boot.ssl.SslBundles; import org.springframework.boot.ssl.SslBundles;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.core.io.ResourceLoader; import org.springframework.core.io.ResourceLoader;
import org.springframework.web.client.RestClient; import org.springframework.web.client.RestClient;
import org.springframework.web.client.support.RestClientAdapter; import org.springframework.web.client.support.RestClientAdapter;
@ -46,7 +45,6 @@ import org.springframework.web.service.registry.HttpServiceProxyRegistry;
@AutoConfiguration(after = { ImperativeHttpClientAutoConfiguration.class, RestClientAutoConfiguration.class }) @AutoConfiguration(after = { ImperativeHttpClientAutoConfiguration.class, RestClientAutoConfiguration.class })
@ConditionalOnClass(RestClientAdapter.class) @ConditionalOnClass(RestClientAdapter.class)
@ConditionalOnBean(HttpServiceProxyRegistry.class) @ConditionalOnBean(HttpServiceProxyRegistry.class)
@Conditional(NotReactiveWebApplicationOrVirtualThreadsExecutorEnabledCondition.class)
@EnableConfigurationProperties(HttpServiceClientProperties.class) @EnableConfigurationProperties(HttpServiceClientProperties.class)
public final class HttpServiceClientAutoConfiguration { public final class HttpServiceClientAutoConfiguration {

41
module/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/NotReactiveWebApplicationCondition.java

@ -1,41 +0,0 @@
/*
* Copyright 2012-present 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.restclient.autoconfigure.service;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
import org.springframework.boot.autoconfigure.condition.NoneNestedConditions;
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
/**
* {@link SpringBootCondition} that applies only when running in a non-reactive web
* application.
*
* @author Phillip Webb
*/
class NotReactiveWebApplicationCondition extends NoneNestedConditions {
NotReactiveWebApplicationCondition() {
super(ConfigurationPhase.PARSE_CONFIGURATION);
}
@ConditionalOnWebApplication(type = Type.REACTIVE)
private static final class ReactiveWebApplication {
}
}

54
module/spring-boot-restclient/src/main/java/org/springframework/boot/restclient/autoconfigure/service/NotReactiveWebApplicationOrVirtualThreadsExecutorEnabledCondition.java

@ -1,54 +0,0 @@
/*
* Copyright 2012-present 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.restclient.autoconfigure.service;
import org.springframework.boot.autoconfigure.condition.AnyNestedCondition;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnThreading;
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration;
import org.springframework.boot.thread.Threading;
import org.springframework.context.annotation.Conditional;
/**
* {@link SpringBootCondition} that applies when running in a non-reactive web application
* or virtual threads are enabled.
*
* Package-private by design to avoid exposing conditions as public API. Should be kept in
* sync with
* {@code org.springframework.boot.restclient.autoconfigure.NotReactiveWebApplicationOrVirtualThreadsExecutorEnabledCondition}.
*
* @author Dmitry Sulman
*/
class NotReactiveWebApplicationOrVirtualThreadsExecutorEnabledCondition extends AnyNestedCondition {
NotReactiveWebApplicationOrVirtualThreadsExecutorEnabledCondition() {
super(ConfigurationPhase.REGISTER_BEAN);
}
@Conditional(NotReactiveWebApplicationCondition.class)
private static final class NotReactiveWebApplication {
}
@ConditionalOnThreading(Threading.VIRTUAL)
@ConditionalOnBean(name = TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME)
private static final class VirtualThreadsExecutorEnabled {
}
}

34
module/spring-boot-restclient/src/test/java/org/springframework/boot/restclient/autoconfigure/service/HttpServiceClientAutoConfigurationTests.java

@ -35,7 +35,6 @@ import org.mockito.ArgumentCaptor;
import org.springframework.aop.Advisor; import org.springframework.aop.Advisor;
import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration;
import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder; import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder;
import org.springframework.boot.http.client.HttpClientSettings; import org.springframework.boot.http.client.HttpClientSettings;
import org.springframework.boot.http.client.HttpRedirects; import org.springframework.boot.http.client.HttpRedirects;
@ -44,7 +43,6 @@ import org.springframework.boot.http.client.autoconfigure.imperative.ImperativeH
import org.springframework.boot.restclient.RestClientCustomizer; import org.springframework.boot.restclient.RestClientCustomizer;
import org.springframework.boot.restclient.autoconfigure.RestClientAutoConfiguration; import org.springframework.boot.restclient.autoconfigure.RestClientAutoConfiguration;
import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.http.client.ClientHttpRequestFactory;
@ -56,12 +54,10 @@ import org.springframework.web.client.RestClient.Builder;
import org.springframework.web.client.support.RestClientHttpServiceGroupConfigurer; import org.springframework.web.client.support.RestClientHttpServiceGroupConfigurer;
import org.springframework.web.service.annotation.GetExchange; import org.springframework.web.service.annotation.GetExchange;
import org.springframework.web.service.registry.HttpServiceGroup; import org.springframework.web.service.registry.HttpServiceGroup;
import org.springframework.web.service.registry.HttpServiceGroup.ClientType;
import org.springframework.web.service.registry.HttpServiceGroupConfigurer.ClientCallback; import org.springframework.web.service.registry.HttpServiceGroupConfigurer.ClientCallback;
import org.springframework.web.service.registry.HttpServiceGroupConfigurer.Groups; import org.springframework.web.service.registry.HttpServiceGroupConfigurer.Groups;
import org.springframework.web.service.registry.HttpServiceProxyRegistry; import org.springframework.web.service.registry.HttpServiceProxyRegistry;
import org.springframework.web.service.registry.ImportHttpServices; import org.springframework.web.service.registry.ImportHttpServices;
import org.springframework.web.util.UriComponentsBuilder;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.given;
@ -221,23 +217,6 @@ class HttpServiceClientAutoConfigurationTests {
.run((context) -> assertThat(context).doesNotHaveBean(HttpServiceProxyRegistry.class)); .run((context) -> assertThat(context).doesNotHaveBean(HttpServiceProxyRegistry.class));
} }
@Test
void restClientServiceClientsApplyPropertiesWhenReactiveWithVirtualThreads() {
new ReactiveWebApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(HttpServiceClientAutoConfiguration.class,
ImperativeHttpClientAutoConfiguration.class, RestClientAutoConfiguration.class,
TaskExecutionAutoConfiguration.class))
.withPropertyValues("spring.threads.virtual.enabled=true",
"spring.http.serviceclient.echo.base-url=https://example.com")
.withUserConfiguration(ReactiveHttpClientConfiguration.class)
.run((context) -> {
RestClient restClient = getRestClient(context.getBean(ReactiveTestClient.class));
UriComponentsBuilder baseUri = (UriComponentsBuilder) Extractors.byName("uriBuilderFactory.baseUri")
.apply(restClient);
assertThat(baseUri.build().toUriString()).isEqualTo("https://example.com");
});
}
private HttpClient getJdkHttpClient(Object proxy) { private HttpClient getJdkHttpClient(Object proxy) {
return (HttpClient) Extractors.byName("clientRequestFactory.httpClient").apply(getRestClient(proxy)); return (HttpClient) Extractors.byName("clientRequestFactory.httpClient").apply(getRestClient(proxy));
} }
@ -336,17 +315,4 @@ class HttpServiceClientAutoConfigurationTests {
} }
@Configuration(proxyBeanMethods = false)
@ImportHttpServices(types = ReactiveTestClient.class, clientType = ClientType.REST_CLIENT, group = "echo")
static class ReactiveHttpClientConfiguration {
}
interface ReactiveTestClient {
@GetExchange("/echo")
String echo();
}
} }

Loading…
Cancel
Save