Skip to content

Commit 227c316

Browse files
committed
Merge pull request #28496 from filiphr
* gh-28496: Polish "Bring back Elasticsearch RestClient auto-configuration" Bring back Elasticsearch RestClient auto-configuration Closes gh-28496
2 parents e0ae1d3 + a7a71da commit 227c316

File tree

7 files changed

+276
-72
lines changed

7 files changed

+276
-72
lines changed

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticSearchRestHealthContributorAutoConfiguration.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,16 @@
3939
* @author Artsiom Yudovin
4040
* @since 2.1.1
4141
*/
42-
@SuppressWarnings("deprecation")
4342
@AutoConfiguration(after = ElasticsearchRestClientAutoConfiguration.class)
44-
@ConditionalOnClass(org.elasticsearch.client.RestHighLevelClient.class)
45-
@ConditionalOnBean(org.elasticsearch.client.RestHighLevelClient.class)
43+
@ConditionalOnClass(RestClient.class)
44+
@ConditionalOnBean(RestClient.class)
4645
@ConditionalOnEnabledHealthIndicator("elasticsearch")
47-
public class ElasticSearchRestHealthContributorAutoConfiguration extends
48-
CompositeHealthContributorConfiguration<ElasticsearchRestHealthIndicator, org.elasticsearch.client.RestHighLevelClient> {
46+
public class ElasticSearchRestHealthContributorAutoConfiguration
47+
extends CompositeHealthContributorConfiguration<ElasticsearchRestHealthIndicator, RestClient> {
4948

5049
@Bean
5150
@ConditionalOnMissingBean(name = { "elasticsearchHealthIndicator", "elasticsearchHealthContributor" })
52-
public HealthContributor elasticsearchHealthContributor(
53-
Map<String, org.elasticsearch.client.RestHighLevelClient> clients) {
51+
public HealthContributor elasticsearchHealthContributor(Map<String, RestClient> clients) {
5452
return createContributor(clients);
5553
}
5654

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/*
2+
* Copyright 2012-2022 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.actuate.autoconfigure.elasticsearch;
18+
19+
import org.elasticsearch.client.RestClient;
20+
import org.elasticsearch.client.RestClientBuilder;
21+
import org.junit.jupiter.api.Test;
22+
23+
import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration;
24+
import org.springframework.boot.actuate.elasticsearch.ElasticsearchRestHealthIndicator;
25+
import org.springframework.boot.autoconfigure.AutoConfigurations;
26+
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration;
27+
import org.springframework.boot.test.context.FilteredClassLoader;
28+
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
29+
import org.springframework.context.annotation.Bean;
30+
import org.springframework.context.annotation.Configuration;
31+
32+
import static org.assertj.core.api.Assertions.assertThat;
33+
34+
/**
35+
* Tests for {@link ElasticSearchRestHealthContributorAutoConfiguration}.
36+
*
37+
* @author Filip Hrisafov
38+
* @author Andy Wilkinson
39+
*/
40+
class ElasticSearchRestHealthContributorAutoConfigurationTests {
41+
42+
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
43+
.withConfiguration(AutoConfigurations.of(ElasticsearchRestClientAutoConfiguration.class,
44+
ElasticSearchRestHealthContributorAutoConfiguration.class,
45+
HealthContributorAutoConfiguration.class));
46+
47+
@Test
48+
void runShouldCreateIndicator() {
49+
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(ElasticsearchRestHealthIndicator.class)
50+
.hasBean("elasticsearchHealthContributor"));
51+
}
52+
53+
@Test
54+
@SuppressWarnings("deprecation")
55+
void runWithoutRestHighLevelClientAndWithoutRestClientShouldNotCreateIndicator() {
56+
this.contextRunner
57+
.withClassLoader(
58+
new FilteredClassLoader(org.elasticsearch.client.RestHighLevelClient.class, RestClient.class))
59+
.run((context) -> assertThat(context).doesNotHaveBean(ElasticsearchRestHealthIndicator.class)
60+
.doesNotHaveBean("elasticsearchHealthContributor"));
61+
}
62+
63+
@Test
64+
void runWithoutRestHighLevelClientAndWithRestClientShouldCreateIndicator() {
65+
this.contextRunner.withUserConfiguration(CustomRestClientConfiguration.class)
66+
.run((context) -> assertThat(context).hasSingleBean(ElasticsearchRestHealthIndicator.class)
67+
.hasSingleBean(ElasticsearchRestHealthIndicator.class)
68+
.hasBean("elasticsearchHealthContributor"));
69+
}
70+
71+
@Test
72+
void runWithRestHighLevelClientAndWithRestClientShouldCreateIndicator() {
73+
this.contextRunner.withUserConfiguration(CustomRestHighClientConfiguration.class)
74+
.run((context) -> assertThat(context).hasSingleBean(ElasticsearchRestHealthIndicator.class)
75+
.hasBean("elasticsearchHealthContributor"));
76+
}
77+
78+
@Test
79+
void runWhenDisabledShouldNotCreateIndicator() {
80+
this.contextRunner.withPropertyValues("management.health.elasticsearch.enabled:false")
81+
.run((context) -> assertThat(context).doesNotHaveBean(ElasticsearchRestHealthIndicator.class)
82+
.doesNotHaveBean("elasticsearchHealthContributor"));
83+
}
84+
85+
@Configuration(proxyBeanMethods = false)
86+
static class CustomRestClientConfiguration {
87+
88+
@Bean
89+
RestClient customRestClient(RestClientBuilder builder) {
90+
return builder.build();
91+
}
92+
93+
}
94+
95+
@Configuration(proxyBeanMethods = false)
96+
@SuppressWarnings("deprecation")
97+
static class CustomRestHighClientConfiguration {
98+
99+
@Bean
100+
org.elasticsearch.client.RestHighLevelClient customRestHighClient(RestClientBuilder builder) {
101+
return new org.elasticsearch.client.RestHighLevelClient(builder);
102+
}
103+
104+
@Bean
105+
RestClient customClient(org.elasticsearch.client.RestHighLevelClient restHighLevelClient) {
106+
return restHighLevelClient.getLowLevelClient();
107+
}
108+
109+
}
110+
111+
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
2323
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
2424
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientConfigurations.RestClientBuilderConfiguration;
25+
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientConfigurations.RestClientConfiguration;
26+
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientConfigurations.RestClientFromRestHighLevelClientConfiguration;
2527
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientConfigurations.RestClientSnifferConfiguration;
2628
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientConfigurations.RestHighLevelClientConfiguration;
2729
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@@ -40,6 +42,7 @@
4042
@EnableConfigurationProperties({ ElasticsearchProperties.class, ElasticsearchRestClientProperties.class,
4143
DeprecatedElasticsearchRestClientProperties.class })
4244
@Import({ RestClientBuilderConfiguration.class, RestHighLevelClientConfiguration.class,
45+
RestClientFromRestHighLevelClientConfiguration.class, RestClientConfiguration.class,
4346
RestClientSnifferConfiguration.class })
4447
public class ElasticsearchRestClientAutoConfiguration {
4548

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

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.springframework.beans.factory.ObjectProvider;
3737
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
3838
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
39+
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
3940
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
4041
import org.springframework.boot.context.properties.PropertyMapper;
4142
import org.springframework.context.annotation.Bean;
@@ -46,6 +47,7 @@
4647
* Elasticsearch rest client configurations.
4748
*
4849
* @author Stephane Nicoll
50+
* @author Filip Hrisafov
4951
*/
5052
class ElasticsearchRestClientConfigurations {
5153

@@ -126,16 +128,41 @@ org.elasticsearch.client.RestHighLevelClient elasticsearchRestHighLevelClient(
126128

127129
@SuppressWarnings("deprecation")
128130
@Configuration(proxyBeanMethods = false)
129-
@ConditionalOnClass(Sniffer.class)
131+
@ConditionalOnClass(org.elasticsearch.client.RestHighLevelClient.class)
130132
@ConditionalOnSingleCandidate(org.elasticsearch.client.RestHighLevelClient.class)
133+
@ConditionalOnMissingBean(RestClient.class)
134+
static class RestClientFromRestHighLevelClientConfiguration {
135+
136+
@Bean
137+
RestClient elasticsearchRestClient(org.elasticsearch.client.RestHighLevelClient restHighLevelClient) {
138+
return restHighLevelClient.getLowLevelClient();
139+
}
140+
141+
}
142+
143+
@Configuration(proxyBeanMethods = false)
144+
@ConditionalOnMissingClass("org.elasticsearch.client.RestHighLevelClient")
145+
@ConditionalOnMissingBean(RestClient.class)
146+
static class RestClientConfiguration {
147+
148+
@Bean
149+
RestClient elasticsearchRestClient(RestClientBuilder restClientBuilder) {
150+
return restClientBuilder.build();
151+
}
152+
153+
}
154+
155+
@Configuration(proxyBeanMethods = false)
156+
@ConditionalOnClass(Sniffer.class)
157+
@ConditionalOnSingleCandidate(RestClient.class)
131158
static class RestClientSnifferConfiguration {
132159

133160
@Bean
134161
@ConditionalOnMissingBean
135-
Sniffer elasticsearchSniffer(org.elasticsearch.client.RestHighLevelClient client,
136-
ElasticsearchRestClientProperties properties,
162+
@SuppressWarnings("deprecation")
163+
Sniffer elasticsearchSniffer(RestClient client, ElasticsearchRestClientProperties properties,
137164
DeprecatedElasticsearchRestClientProperties deprecatedProperties) {
138-
SnifferBuilder builder = Sniffer.builder(client.getLowLevelClient());
165+
SnifferBuilder builder = Sniffer.builder(client);
139166
PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
140167
Duration interval = deprecatedProperties.isCustomized() ? deprecatedProperties.getSniffer().getInterval()
141168
: properties.getSniffer().getInterval();

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

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,19 @@
1616

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

19+
import java.io.InputStream;
1920
import java.time.Duration;
2021
import java.util.HashMap;
2122
import java.util.Map;
2223

24+
import com.fasterxml.jackson.databind.JsonNode;
25+
import com.fasterxml.jackson.databind.ObjectMapper;
2326
import org.elasticsearch.action.get.GetRequest;
2427
import org.elasticsearch.action.index.IndexRequest;
28+
import org.elasticsearch.client.Request;
2529
import org.elasticsearch.client.RequestOptions;
30+
import org.elasticsearch.client.Response;
31+
import org.elasticsearch.client.RestClient;
2632
import org.junit.jupiter.api.Test;
2733
import org.testcontainers.elasticsearch.ElasticsearchContainer;
2834
import org.testcontainers.junit.jupiter.Container;
@@ -40,6 +46,7 @@
4046
* @author Brian Clozel
4147
* @author Vedran Pavic
4248
* @author Evgeniy Cheban
49+
* @author Filip Hrisafov
4350
*/
4451
@Testcontainers(disabledWithoutDocker = true)
4552
class ElasticsearchRestClientAutoConfigurationIntegrationTests {
@@ -53,7 +60,7 @@ class ElasticsearchRestClientAutoConfigurationIntegrationTests {
5360

5461
@Test
5562
@SuppressWarnings("deprecation")
56-
void restClientCanQueryElasticsearchNode() {
63+
void restHighLevelClientCanQueryElasticsearchNode() {
5764
this.contextRunner
5865
.withPropertyValues("spring.elasticsearch.uris=" + elasticsearch.getHttpHostAddress(),
5966
"spring.elasticsearch.connection-timeout=120s", "spring.elasticsearch.socket-timeout=120s")
@@ -70,4 +77,23 @@ void restClientCanQueryElasticsearchNode() {
7077
});
7178
}
7279

80+
@Test
81+
void restClientCanQueryElasticsearchNode() {
82+
this.contextRunner
83+
.withPropertyValues("spring.elasticsearch.uris=" + elasticsearch.getHttpHostAddress(),
84+
"spring.elasticsearch.connection-timeout=120s", "spring.elasticsearch.socket-timeout=120s")
85+
.run((context) -> {
86+
RestClient client = context.getBean(RestClient.class);
87+
Request index = new Request("PUT", "/test/_doc/2");
88+
index.setJsonEntity("{" + " \"a\": \"alpha\"," + " \"b\": \"bravo\"" + "}");
89+
client.performRequest(index);
90+
Request getRequest = new Request("GET", "/test/_doc/2");
91+
Response response = client.performRequest(getRequest);
92+
try (InputStream input = response.getEntity().getContent()) {
93+
JsonNode result = new ObjectMapper().readTree(input);
94+
assertThat(result.path("found").asBoolean()).isTrue();
95+
}
96+
});
97+
}
98+
7399
}

0 commit comments

Comments
 (0)