Skip to content

Commit 3e160a4

Browse files
committed
Bring back Elasticsearch RestClient auto-configuration
Prior to this commit, Spring Boot would only auto-configure the `RestHighLevelClient` and `RestClientBuilder` if the `RestHighLevelClient` was present. This was done in 1d73d4e. This commit brings back the exposing of the `RestClient` bean in Spring Boot when exposing the `RestHighLevelClient` or when the `RestHighLevelClient` is not present. It allows for using the Spring Boot auto configuration and its customizers of the `RestClientBuilder` in a similar way as it is done for the `RestTeamplateBuilder` and the `WebClient.Builder`. Now the presence of the `org.elasticsearch.client:elasticsearch-rest-high-level-client` is optional. This opens the door for potentially adding support to the new [Elasticsearch Java Client](https://github.com/elastic/elasticsearch-java) that is based on the same `RestClient`
1 parent 83e4430 commit 3e160a4

File tree

7 files changed

+152
-45
lines changed

7 files changed

+152
-45
lines changed

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

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import java.util.Map;
2020

2121
import org.elasticsearch.client.RestClient;
22-
import org.elasticsearch.client.RestHighLevelClient;
2322

2423
import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration;
2524
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
@@ -42,16 +41,16 @@
4241
* @since 2.1.1
4342
*/
4443
@Configuration(proxyBeanMethods = false)
45-
@ConditionalOnClass(RestHighLevelClient.class)
46-
@ConditionalOnBean(RestHighLevelClient.class)
44+
@ConditionalOnClass(RestClient.class)
45+
@ConditionalOnBean(RestClient.class)
4746
@ConditionalOnEnabledHealthIndicator("elasticsearch")
4847
@AutoConfigureAfter(ElasticsearchRestClientAutoConfiguration.class)
4948
public class ElasticSearchRestHealthContributorAutoConfiguration
50-
extends CompositeHealthContributorConfiguration<ElasticsearchRestHealthIndicator, RestHighLevelClient> {
49+
extends CompositeHealthContributorConfiguration<ElasticsearchRestHealthIndicator, RestClient> {
5150

5251
@Bean
5352
@ConditionalOnMissingBean(name = { "elasticsearchHealthIndicator", "elasticsearchHealthContributor" })
54-
public HealthContributor elasticsearchHealthContributor(Map<String, RestHighLevelClient> clients) {
53+
public HealthContributor elasticsearchHealthContributor(Map<String, RestClient> clients) {
5554
return createContributor(clients);
5655
}
5756

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@ public class ElasticsearchRestHealthIndicator extends AbstractHealthIndicator {
5050

5151
private final JsonParser jsonParser;
5252

53+
/**
54+
* Create a health indicator using the RestHighLevelClient.
55+
* @param client the RestHighLevelClient that used to get the RestClient
56+
* @deprecated since 2.7.0 for removal in 2.9.0 in favor of
57+
* {@link #ElasticsearchRestHealthIndicator(RestClient)}
58+
*/
59+
@Deprecated
5360
public ElasticsearchRestHealthIndicator(RestHighLevelClient client) {
5461
this(client.getLowLevelClient());
5562
}

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

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,11 @@
1717
package org.springframework.boot.autoconfigure.elasticsearch;
1818

1919
import org.elasticsearch.client.RestClient;
20-
import org.elasticsearch.client.RestHighLevelClient;
2120

2221
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
2322
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
24-
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
2523
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientConfigurations.RestClientBuilderConfiguration;
24+
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientConfigurations.RestClientConfiguration;
2625
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientConfigurations.RestClientSnifferConfiguration;
2726
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientConfigurations.RestHighLevelClientConfiguration;
2827
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@@ -38,11 +37,10 @@
3837
*/
3938
@SuppressWarnings("deprecation")
4039
@Configuration(proxyBeanMethods = false)
41-
@ConditionalOnClass(RestHighLevelClient.class)
42-
@ConditionalOnMissingBean(RestClient.class)
40+
@ConditionalOnClass(RestClient.class)
4341
@EnableConfigurationProperties({ ElasticsearchProperties.class, ElasticsearchRestClientProperties.class,
4442
DeprecatedElasticsearchRestClientProperties.class })
45-
@Import({ RestClientBuilderConfiguration.class, RestHighLevelClientConfiguration.class,
43+
@Import({ RestClientBuilderConfiguration.class, RestHighLevelClientConfiguration.class, RestClientConfiguration.class,
4644
RestClientSnifferConfiguration.class })
4745
public class ElasticsearchRestClientAutoConfiguration {
4846

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

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import org.springframework.beans.factory.ObjectProvider;
3838
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
3939
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
40+
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
4041
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
4142
import org.springframework.boot.context.properties.PropertyMapper;
4243
import org.springframework.context.annotation.Bean;
@@ -112,27 +113,45 @@ private HttpHost createHttpHost(URI uri) {
112113
}
113114

114115
@Configuration(proxyBeanMethods = false)
115-
@ConditionalOnMissingBean(RestHighLevelClient.class)
116+
@ConditionalOnClass(RestHighLevelClient.class)
117+
@ConditionalOnMissingBean({ RestHighLevelClient.class, RestClient.class })
116118
static class RestHighLevelClientConfiguration {
117119

118120
@Bean
119121
RestHighLevelClient elasticsearchRestHighLevelClient(RestClientBuilder restClientBuilder) {
120122
return new RestHighLevelClient(restClientBuilder);
121123
}
122124

125+
@Bean
126+
RestClient elasticsearchRestClient(RestHighLevelClient restHighLevelClient) {
127+
return restHighLevelClient.getLowLevelClient();
128+
}
129+
130+
}
131+
132+
@Configuration(proxyBeanMethods = false)
133+
@ConditionalOnMissingClass("org.elasticsearch.client.RestHighLevelClient")
134+
@ConditionalOnMissingBean(RestClient.class)
135+
static class RestClientConfiguration {
136+
137+
@Bean
138+
RestClient elasticsearchRestClient(RestClientBuilder restClientBuilder) {
139+
return restClientBuilder.build();
140+
}
141+
123142
}
124143

125144
@Configuration(proxyBeanMethods = false)
126145
@ConditionalOnClass(Sniffer.class)
127-
@ConditionalOnSingleCandidate(RestHighLevelClient.class)
146+
@ConditionalOnSingleCandidate(RestClient.class)
128147
static class RestClientSnifferConfiguration {
129148

130149
@Bean
131150
@ConditionalOnMissingBean
132151
@SuppressWarnings("deprecation")
133-
Sniffer elasticsearchSniffer(RestHighLevelClient client, ElasticsearchRestClientProperties properties,
152+
Sniffer elasticsearchSniffer(RestClient client, ElasticsearchRestClientProperties properties,
134153
DeprecatedElasticsearchRestClientProperties deprecatedProperties) {
135-
SnifferBuilder builder = Sniffer.builder(client.getLowLevelClient());
154+
SnifferBuilder builder = Sniffer.builder(client);
136155
PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
137156
Duration interval = deprecatedProperties.isCustomized() ? deprecatedProperties.getSniffer().getInterval()
138157
: properties.getSniffer().getInterval();

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

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,27 @@
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.elasticsearch.client.RestHighLevelClient;
2733
import org.junit.jupiter.api.Test;
2834
import org.testcontainers.elasticsearch.ElasticsearchContainer;
2935
import org.testcontainers.junit.jupiter.Container;
3036
import org.testcontainers.junit.jupiter.Testcontainers;
3137

3238
import org.springframework.boot.autoconfigure.AutoConfigurations;
39+
import org.springframework.boot.test.context.FilteredClassLoader;
3340
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
3441
import org.springframework.boot.testsupport.testcontainers.DockerImageNames;
3542

@@ -41,6 +48,7 @@
4148
* @author Brian Clozel
4249
* @author Vedran Pavic
4350
* @author Evgeniy Cheban
51+
* @author Filip Hrisafov
4452
*/
4553
@Testcontainers(disabledWithoutDocker = true)
4654
class ElasticsearchRestClientAutoConfigurationIntegrationTests {
@@ -53,7 +61,7 @@ class ElasticsearchRestClientAutoConfigurationIntegrationTests {
5361
.withConfiguration(AutoConfigurations.of(ElasticsearchRestClientAutoConfiguration.class));
5462

5563
@Test
56-
void restClientCanQueryElasticsearchNode() {
64+
void restHighLevelClientCanQueryElasticsearchNode() {
5765
this.contextRunner
5866
.withPropertyValues("spring.elasticsearch.uris=" + elasticsearch.getHttpHostAddress(),
5967
"spring.elasticsearch.connection-timeout=120s", "spring.elasticsearch.socket-timeout=120s")
@@ -69,4 +77,42 @@ void restClientCanQueryElasticsearchNode() {
6977
});
7078
}
7179

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+
99+
@Test
100+
void restClientCanQueryElasticsearchNodeWithoutHighLevelClient() {
101+
this.contextRunner.withClassLoader(new FilteredClassLoader(RestHighLevelClient.class))
102+
.withPropertyValues("spring.elasticsearch.uris=" + elasticsearch.getHttpHostAddress(),
103+
"spring.elasticsearch.connection-timeout=120s", "spring.elasticsearch.socket-timeout=120s")
104+
.run((context) -> {
105+
RestClient client = context.getBean(RestClient.class);
106+
Request index = new Request("PUT", "/test/_doc/3");
107+
index.setJsonEntity("{" + " \"a\": \"alpha\"," + " \"b\": \"bravo\"" + "}");
108+
client.performRequest(index);
109+
Request getRequest = new Request("GET", "/test/_doc/3");
110+
Response response = client.performRequest(getRequest);
111+
try (InputStream input = response.getEntity().getContent()) {
112+
JsonNode result = new ObjectMapper().readTree(input);
113+
assertThat(result.path("found").asBoolean()).isTrue();
114+
}
115+
});
116+
}
117+
72118
}

0 commit comments

Comments
 (0)