Skip to content

Commit 48e07c8

Browse files
committed
Merge branch '2.1.x'
Closes gh-17753
2 parents 0407121 + a76aaab commit 48e07c8

File tree

3 files changed

+176
-61
lines changed

3 files changed

+176
-61
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/elasticsearch/rest/RestClientAutoConfiguration.java

Lines changed: 5 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -16,80 +16,27 @@
1616

1717
package org.springframework.boot.autoconfigure.elasticsearch.rest;
1818

19-
import java.time.Duration;
20-
21-
import org.apache.http.HttpHost;
22-
import org.apache.http.auth.AuthScope;
23-
import org.apache.http.auth.Credentials;
24-
import org.apache.http.auth.UsernamePasswordCredentials;
25-
import org.apache.http.client.CredentialsProvider;
26-
import org.apache.http.impl.client.BasicCredentialsProvider;
2719
import org.elasticsearch.client.RestClient;
28-
import org.elasticsearch.client.RestClientBuilder;
29-
import org.elasticsearch.client.RestHighLevelClient;
3020

31-
import org.springframework.beans.factory.ObjectProvider;
3221
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
3322
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
34-
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
3523
import org.springframework.boot.context.properties.EnableConfigurationProperties;
36-
import org.springframework.boot.context.properties.PropertyMapper;
37-
import org.springframework.context.annotation.Bean;
3824
import org.springframework.context.annotation.Configuration;
25+
import org.springframework.context.annotation.Import;
3926

4027
/**
4128
* {@link EnableAutoConfiguration Auto-configuration} for Elasticsearch REST clients.
4229
*
4330
* @author Brian Clozel
31+
* @author Stephane Nicoll
4432
* @since 2.1.0
4533
*/
4634
@Configuration(proxyBeanMethods = false)
4735
@ConditionalOnClass(RestClient.class)
4836
@EnableConfigurationProperties(RestClientProperties.class)
37+
@Import({ RestClientConfigurations.RestClientBuilderConfiguration.class,
38+
RestClientConfigurations.RestHighLevelClientConfiguration.class,
39+
RestClientConfigurations.RestClientFallbackConfiguration.class })
4940
public class RestClientAutoConfiguration {
5041

51-
@Bean
52-
@ConditionalOnMissingBean
53-
public RestClient restClient(RestClientBuilder builder) {
54-
return builder.build();
55-
}
56-
57-
@Bean
58-
@ConditionalOnMissingBean
59-
public RestClientBuilder restClientBuilder(RestClientProperties properties,
60-
ObjectProvider<RestClientBuilderCustomizer> builderCustomizers) {
61-
HttpHost[] hosts = properties.getUris().stream().map(HttpHost::create).toArray(HttpHost[]::new);
62-
RestClientBuilder builder = RestClient.builder(hosts);
63-
PropertyMapper map = PropertyMapper.get();
64-
map.from(properties::getUsername).whenHasText().to((username) -> {
65-
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
66-
Credentials credentials = new UsernamePasswordCredentials(properties.getUsername(),
67-
properties.getPassword());
68-
credentialsProvider.setCredentials(AuthScope.ANY, credentials);
69-
builder.setHttpClientConfigCallback(
70-
(httpClientBuilder) -> httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider));
71-
});
72-
builder.setRequestConfigCallback((requestConfigBuilder) -> {
73-
map.from(properties::getConnectionTimeout).whenNonNull().asInt(Duration::toMillis)
74-
.to(requestConfigBuilder::setConnectTimeout);
75-
map.from(properties::getReadTimeout).whenNonNull().asInt(Duration::toMillis)
76-
.to(requestConfigBuilder::setSocketTimeout);
77-
return requestConfigBuilder;
78-
});
79-
builderCustomizers.orderedStream().forEach((customizer) -> customizer.customize(builder));
80-
return builder;
81-
}
82-
83-
@Configuration(proxyBeanMethods = false)
84-
@ConditionalOnClass(RestHighLevelClient.class)
85-
public static class RestHighLevelClientConfiguration {
86-
87-
@Bean
88-
@ConditionalOnMissingBean
89-
public RestHighLevelClient restHighLevelClient(RestClientBuilder restClientBuilder) {
90-
return new RestHighLevelClient(restClientBuilder);
91-
}
92-
93-
}
94-
9542
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/*
2+
* Copyright 2012-2019 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 org.springframework.boot.autoconfigure.elasticsearch.rest;
18+
19+
import java.time.Duration;
20+
21+
import org.apache.http.HttpHost;
22+
import org.apache.http.auth.AuthScope;
23+
import org.apache.http.auth.Credentials;
24+
import org.apache.http.auth.UsernamePasswordCredentials;
25+
import org.apache.http.client.CredentialsProvider;
26+
import org.apache.http.impl.client.BasicCredentialsProvider;
27+
import org.elasticsearch.client.RestClient;
28+
import org.elasticsearch.client.RestClientBuilder;
29+
import org.elasticsearch.client.RestHighLevelClient;
30+
31+
import org.springframework.beans.factory.ObjectProvider;
32+
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
33+
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
34+
import org.springframework.boot.context.properties.PropertyMapper;
35+
import org.springframework.context.annotation.Bean;
36+
import org.springframework.context.annotation.Configuration;
37+
38+
/**
39+
* Elasticsearch rest client infrastructure configurations.
40+
*
41+
* @author Brian Clozel
42+
* @author Stephane Nicoll
43+
*/
44+
class RestClientConfigurations {
45+
46+
@Configuration(proxyBeanMethods = false)
47+
static class RestClientBuilderConfiguration {
48+
49+
@Bean
50+
@ConditionalOnMissingBean
51+
RestClientBuilder restClientBuilder(RestClientProperties properties,
52+
ObjectProvider<RestClientBuilderCustomizer> builderCustomizers) {
53+
HttpHost[] hosts = properties.getUris().stream().map(HttpHost::create).toArray(HttpHost[]::new);
54+
RestClientBuilder builder = RestClient.builder(hosts);
55+
PropertyMapper map = PropertyMapper.get();
56+
map.from(properties::getUsername).whenHasText().to((username) -> {
57+
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
58+
Credentials credentials = new UsernamePasswordCredentials(properties.getUsername(),
59+
properties.getPassword());
60+
credentialsProvider.setCredentials(AuthScope.ANY, credentials);
61+
builder.setHttpClientConfigCallback(
62+
(httpClientBuilder) -> httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider));
63+
});
64+
builder.setRequestConfigCallback((requestConfigBuilder) -> {
65+
map.from(properties::getConnectionTimeout).whenNonNull().asInt(Duration::toMillis)
66+
.to(requestConfigBuilder::setConnectTimeout);
67+
map.from(properties::getReadTimeout).whenNonNull().asInt(Duration::toMillis)
68+
.to(requestConfigBuilder::setSocketTimeout);
69+
return requestConfigBuilder;
70+
});
71+
builderCustomizers.orderedStream().forEach((customizer) -> customizer.customize(builder));
72+
return builder;
73+
}
74+
75+
}
76+
77+
@Configuration(proxyBeanMethods = false)
78+
@ConditionalOnClass(RestHighLevelClient.class)
79+
static class RestHighLevelClientConfiguration {
80+
81+
@Bean
82+
@ConditionalOnMissingBean
83+
RestHighLevelClient restHighLevelClient(RestClientBuilder restClientBuilder) {
84+
return new RestHighLevelClient(restClientBuilder);
85+
}
86+
87+
@Bean
88+
@ConditionalOnMissingBean
89+
RestClient restClient(RestClientBuilder builder, ObjectProvider<RestHighLevelClient> restHighLevelClient) {
90+
RestHighLevelClient client = restHighLevelClient.getIfUnique();
91+
if (client != null) {
92+
return client.getLowLevelClient();
93+
}
94+
return builder.build();
95+
}
96+
97+
}
98+
99+
@Configuration(proxyBeanMethods = false)
100+
static class RestClientFallbackConfiguration {
101+
102+
@Bean
103+
@ConditionalOnMissingBean
104+
RestClient restClient(RestClientBuilder builder) {
105+
return builder.build();
106+
}
107+
108+
}
109+
110+
}

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/elasticsearch/rest/RestClientAutoConfigurationTests.java

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.testcontainers.junit.jupiter.Container;
3232

3333
import org.springframework.boot.autoconfigure.AutoConfigurations;
34+
import org.springframework.boot.test.context.FilteredClassLoader;
3435
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
3536
import org.springframework.boot.testsupport.testcontainers.DisabledWithoutDockerTestcontainers;
3637
import org.springframework.context.annotation.Bean;
@@ -56,14 +57,46 @@ class RestClientAutoConfigurationTests {
5657

5758
@Test
5859
void configureShouldCreateBothRestClientVariants() {
59-
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(RestClient.class)
60-
.hasSingleBean(RestHighLevelClient.class));
60+
this.contextRunner.run((context) -> {
61+
assertThat(context).hasSingleBean(RestClient.class).hasSingleBean(RestHighLevelClient.class);
62+
assertThat(context.getBean(RestClient.class))
63+
.isSameAs(context.getBean(RestHighLevelClient.class).getLowLevelClient());
64+
});
6165
}
6266

6367
@Test
6468
void configureWhenCustomClientShouldBackOff() {
6569
this.contextRunner.withUserConfiguration(CustomRestClientConfiguration.class)
66-
.run((context) -> assertThat(context).hasSingleBean(RestClient.class).hasBean("customRestClient"));
70+
.run((context) -> assertThat(context).getBeanNames(RestClient.class).containsOnly("customRestClient"));
71+
}
72+
73+
@Test
74+
void configureWhenCustomRestHighLevelClientShouldBackOff() {
75+
this.contextRunner.withUserConfiguration(CustomRestHighLevelClientConfiguration.class).run((context) -> {
76+
assertThat(context).hasSingleBean(RestClient.class).hasSingleBean(RestHighLevelClient.class);
77+
assertThat(context.getBean(RestClient.class))
78+
.isSameAs(context.getBean(RestHighLevelClient.class).getLowLevelClient());
79+
});
80+
}
81+
82+
@Test
83+
void configureWhenDefaultRestClientShouldCreateWhenNoUniqueRestHighLevelClient() {
84+
this.contextRunner.withUserConfiguration(TwoCustomRestHighLevelClientConfiguration.class).run((context) -> {
85+
assertThat(context).hasSingleBean(RestClient.class);
86+
RestClient restClient = context.getBean(RestClient.class);
87+
Map<String, RestHighLevelClient> restHighLevelClients = context.getBeansOfType(RestHighLevelClient.class);
88+
assertThat(restHighLevelClients).hasSize(2);
89+
for (RestHighLevelClient restHighLevelClient : restHighLevelClients.values()) {
90+
assertThat(restHighLevelClient.getLowLevelClient()).isNotSameAs(restClient);
91+
}
92+
});
93+
}
94+
95+
@Test
96+
void configureWhenHighLevelClientIsNotAvailableShouldCreateRestClientOnly() {
97+
this.contextRunner.withClassLoader(new FilteredClassLoader(RestHighLevelClient.class))
98+
.run((context) -> assertThat(context).hasSingleBean(RestClient.class)
99+
.doesNotHaveBean(RestHighLevelClient.class));
67100
}
68101

69102
@Test
@@ -138,4 +171,29 @@ RestClientBuilderCustomizer myCustomizer() {
138171

139172
}
140173

174+
@Configuration(proxyBeanMethods = false)
175+
static class CustomRestHighLevelClientConfiguration {
176+
177+
@Bean
178+
RestHighLevelClient customRestHighLevelClient(RestClientBuilder builder) {
179+
return new RestHighLevelClient(builder);
180+
}
181+
182+
}
183+
184+
@Configuration(proxyBeanMethods = false)
185+
static class TwoCustomRestHighLevelClientConfiguration {
186+
187+
@Bean
188+
RestHighLevelClient customRestHighLevelClient(RestClientBuilder builder) {
189+
return new RestHighLevelClient(builder);
190+
}
191+
192+
@Bean
193+
RestHighLevelClient customRestHighLevelClient1(RestClientBuilder builder) {
194+
return new RestHighLevelClient(builder);
195+
}
196+
197+
}
198+
141199
}

0 commit comments

Comments
 (0)