Skip to content

Commit 74ded53

Browse files
authored
Fix: RegistrationClient auto-configuration (#4402)
1 parent 32ffbfe commit 74ded53

File tree

3 files changed

+206
-2
lines changed

3 files changed

+206
-2
lines changed

spring-boot-admin-client/src/main/java/de/codecentric/boot/admin/client/config/SpringBootAdminClientAutoConfiguration.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ public RegistrationClient registrationClient(ClientProperties client) {
159159
}
160160

161161
@Configuration(proxyBeanMethods = false)
162-
@ConditionalOnBean(RestClient.Builder.class)
162+
@ConditionalOnBean({ RestClient.Builder.class, ClientHttpRequestFactoryBuilder.class })
163163
public static class RestClientRegistrationClientConfig {
164164

165165
@Bean
@@ -183,7 +183,6 @@ public RegistrationClient registrationClient(ClientProperties client, RestClient
183183

184184
@Configuration(proxyBeanMethods = false)
185185
@ConditionalOnBean(WebClient.Builder.class)
186-
@ConditionalOnMissingBean({ RestTemplateBuilder.class, RestClient.Builder.class })
187186
public static class ReactiveRegistrationClientConfig {
188187

189188
@Bean
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
/*
2+
* Copyright 2014-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package de.codecentric.boot.admin.client.config;
18+
19+
import java.util.function.Function;
20+
import java.util.stream.Stream;
21+
22+
import org.junit.jupiter.params.ParameterizedTest;
23+
import org.junit.jupiter.params.provider.Arguments;
24+
import org.junit.jupiter.params.provider.MethodSource;
25+
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
26+
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration;
27+
import org.springframework.boot.autoconfigure.AutoConfigurations;
28+
import org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener;
29+
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration;
30+
import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder;
31+
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
32+
import org.springframework.boot.web.client.RestTemplateBuilder;
33+
import org.springframework.web.client.RestClient;
34+
import org.springframework.web.reactive.function.client.WebClient;
35+
36+
import de.codecentric.boot.admin.client.registration.BlockingRegistrationClient;
37+
import de.codecentric.boot.admin.client.registration.ReactiveRegistrationClient;
38+
import de.codecentric.boot.admin.client.registration.RegistrationClient;
39+
import de.codecentric.boot.admin.client.registration.RestClientRegistrationClient;
40+
41+
import static org.assertj.core.api.Assertions.assertThat;
42+
43+
public class SpringBootAdminClientRegistrationClientAutoConfigurationTest {
44+
45+
@ParameterizedTest(name = "{0}")
46+
@MethodSource("contextRunnerCustomizations")
47+
public void autoConfiguresRegistrationClient(String testCaseName,
48+
Function<WebApplicationContextRunner, WebApplicationContextRunner> customizer,
49+
Class<RegistrationClient> expectedRegistrationClient) {
50+
WebApplicationContextRunner webApplicationContextRunner = new WebApplicationContextRunner()
51+
.withConfiguration(
52+
AutoConfigurations.of(EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class,
53+
DispatcherServletAutoConfiguration.class, SpringBootAdminClientAutoConfiguration.class))
54+
.with(customizer)
55+
.withInitializer(new ConditionEvaluationReportLoggingListener());
56+
57+
webApplicationContextRunner.withPropertyValues("spring.boot.admin.client.url:http://localhost:8081")
58+
.run((context) -> {
59+
RegistrationClient registrationClient = context.getBean(RegistrationClient.class);
60+
61+
assertThat(registrationClient).isInstanceOf(expectedRegistrationClient);
62+
});
63+
}
64+
65+
/**
66+
* <img src="doc-files/RegistrationClientTestCases.png" alt="">
67+
* @return context runner customizations
68+
*/
69+
public static Stream<Arguments> contextRunnerCustomizations() {
70+
return Stream.of(//
71+
Arguments.of(//
72+
"Test case 01", //
73+
customizer() //
74+
.withRestTemplateBuilder()
75+
.withRestClientBuilder()
76+
.withClientHttpRequestFactoryBuilder()
77+
.withWebClientBuilder()
78+
.build(), //
79+
ReactiveRegistrationClient.class),
80+
Arguments.of(//
81+
"Test case 02", //
82+
customizer() //
83+
.withRestTemplateBuilder()
84+
.withRestClientBuilder()
85+
.withClientHttpRequestFactoryBuilder()
86+
.build(), //
87+
RestClientRegistrationClient.class),
88+
Arguments.of(//
89+
"Test case 03", //
90+
customizer() //
91+
.withRestTemplateBuilder()
92+
.withRestClientBuilder()
93+
.withWebClientBuilder()
94+
.build(), //
95+
ReactiveRegistrationClient.class),
96+
Arguments.of(//
97+
"Test case 04", //
98+
customizer() //
99+
.withRestTemplateBuilder()
100+
.withRestClientBuilder()
101+
.build(), //
102+
BlockingRegistrationClient.class),
103+
Arguments.of(//
104+
"Test case 05", //
105+
customizer() //
106+
.withRestTemplateBuilder()
107+
.withClientHttpRequestFactoryBuilder()
108+
.withWebClientBuilder()
109+
.build(), //
110+
ReactiveRegistrationClient.class),
111+
Arguments.of(//
112+
"Test case 06", //
113+
customizer() //
114+
.withRestTemplateBuilder()
115+
.withClientHttpRequestFactoryBuilder()
116+
.build(), //
117+
BlockingRegistrationClient.class),
118+
Arguments.of(//
119+
"Test case 07", //
120+
customizer() //
121+
.withRestTemplateBuilder()
122+
.withWebClientBuilder()
123+
.build(), //
124+
ReactiveRegistrationClient.class),
125+
Arguments.of(//
126+
"Test case 08", //
127+
customizer() //
128+
.withRestTemplateBuilder()
129+
.build(), //
130+
BlockingRegistrationClient.class),
131+
Arguments.of(//
132+
"Test case 09", //
133+
customizer() //
134+
.withRestClientBuilder()
135+
.withClientHttpRequestFactoryBuilder()
136+
.withWebClientBuilder()
137+
.build(), //
138+
ReactiveRegistrationClient.class),
139+
Arguments.of(//
140+
"Test case 10", //
141+
customizer() //
142+
.withRestClientBuilder()
143+
.withClientHttpRequestFactoryBuilder()
144+
.build(), //
145+
RestClientRegistrationClient.class),
146+
Arguments.of(//
147+
"Test case 11", //
148+
customizer() //
149+
.withRestClientBuilder()
150+
.withWebClientBuilder()
151+
.build(), //
152+
ReactiveRegistrationClient.class),
153+
Arguments.of(//
154+
"Test case 13", //
155+
customizer() //
156+
.withClientHttpRequestFactoryBuilder()
157+
.withWebClientBuilder()
158+
.build(), //
159+
ReactiveRegistrationClient.class),
160+
Arguments.of(//
161+
"Test case 15", //
162+
customizer() //
163+
.withWebClientBuilder()
164+
.build(), //
165+
ReactiveRegistrationClient.class) //
166+
);
167+
}
168+
169+
private static ContextRunnerCustomizerBuilder customizer() {
170+
return new ContextRunnerCustomizerBuilder();
171+
}
172+
173+
private static final class ContextRunnerCustomizerBuilder {
174+
175+
private Function<WebApplicationContextRunner, WebApplicationContextRunner> customizer = (runner) -> runner;
176+
177+
ContextRunnerCustomizerBuilder withRestTemplateBuilder() {
178+
customizer = customizer
179+
.andThen((runner) -> runner.withBean(RestTemplateBuilder.class, RestTemplateBuilder::new));
180+
return this;
181+
}
182+
183+
ContextRunnerCustomizerBuilder withRestClientBuilder() {
184+
customizer = customizer.andThen((runner) -> runner.withBean(RestClient.Builder.class, RestClient::builder));
185+
return this;
186+
}
187+
188+
ContextRunnerCustomizerBuilder withClientHttpRequestFactoryBuilder() {
189+
customizer = customizer.andThen((runner) -> runner.withBean(ClientHttpRequestFactoryBuilder.class,
190+
ClientHttpRequestFactoryBuilder::detect));
191+
return this;
192+
}
193+
194+
ContextRunnerCustomizerBuilder withWebClientBuilder() {
195+
customizer = customizer.andThen((runner) -> runner.withBean(WebClient.Builder.class, WebClient::builder));
196+
return this;
197+
}
198+
199+
Function<WebApplicationContextRunner, WebApplicationContextRunner> build() {
200+
return customizer;
201+
}
202+
203+
}
204+
205+
}
124 KB
Loading

0 commit comments

Comments
 (0)