Skip to content

Commit

Permalink
Merge pull request #28496 from filiphr
Browse files Browse the repository at this point in the history
* gh-28496:
  Polish "Bring back Elasticsearch RestClient auto-configuration"
  Bring back Elasticsearch RestClient auto-configuration

Closes gh-28496
  • Loading branch information
wilkinsona committed Apr 12, 2022
2 parents e0ae1d3 + a7a71da commit 227c316
Show file tree
Hide file tree
Showing 7 changed files with 276 additions and 72 deletions.
Expand Up @@ -39,18 +39,16 @@
* @author Artsiom Yudovin
* @since 2.1.1
*/
@SuppressWarnings("deprecation")
@AutoConfiguration(after = ElasticsearchRestClientAutoConfiguration.class)
@ConditionalOnClass(org.elasticsearch.client.RestHighLevelClient.class)
@ConditionalOnBean(org.elasticsearch.client.RestHighLevelClient.class)
@ConditionalOnClass(RestClient.class)
@ConditionalOnBean(RestClient.class)
@ConditionalOnEnabledHealthIndicator("elasticsearch")
public class ElasticSearchRestHealthContributorAutoConfiguration extends
CompositeHealthContributorConfiguration<ElasticsearchRestHealthIndicator, org.elasticsearch.client.RestHighLevelClient> {
public class ElasticSearchRestHealthContributorAutoConfiguration
extends CompositeHealthContributorConfiguration<ElasticsearchRestHealthIndicator, RestClient> {

@Bean
@ConditionalOnMissingBean(name = { "elasticsearchHealthIndicator", "elasticsearchHealthContributor" })
public HealthContributor elasticsearchHealthContributor(
Map<String, org.elasticsearch.client.RestHighLevelClient> clients) {
public HealthContributor elasticsearchHealthContributor(Map<String, RestClient> clients) {
return createContributor(clients);
}

Expand Down
@@ -0,0 +1,111 @@
/*
* Copyright 2012-2022 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.actuate.autoconfigure.elasticsearch;

import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.junit.jupiter.api.Test;

import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration;
import org.springframework.boot.actuate.elasticsearch.ElasticsearchRestHealthIndicator;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration;
import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import static org.assertj.core.api.Assertions.assertThat;

/**
* Tests for {@link ElasticSearchRestHealthContributorAutoConfiguration}.
*
* @author Filip Hrisafov
* @author Andy Wilkinson
*/
class ElasticSearchRestHealthContributorAutoConfigurationTests {

private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(ElasticsearchRestClientAutoConfiguration.class,
ElasticSearchRestHealthContributorAutoConfiguration.class,
HealthContributorAutoConfiguration.class));

@Test
void runShouldCreateIndicator() {
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(ElasticsearchRestHealthIndicator.class)
.hasBean("elasticsearchHealthContributor"));
}

@Test
@SuppressWarnings("deprecation")
void runWithoutRestHighLevelClientAndWithoutRestClientShouldNotCreateIndicator() {
this.contextRunner
.withClassLoader(
new FilteredClassLoader(org.elasticsearch.client.RestHighLevelClient.class, RestClient.class))
.run((context) -> assertThat(context).doesNotHaveBean(ElasticsearchRestHealthIndicator.class)
.doesNotHaveBean("elasticsearchHealthContributor"));
}

@Test
void runWithoutRestHighLevelClientAndWithRestClientShouldCreateIndicator() {
this.contextRunner.withUserConfiguration(CustomRestClientConfiguration.class)
.run((context) -> assertThat(context).hasSingleBean(ElasticsearchRestHealthIndicator.class)
.hasSingleBean(ElasticsearchRestHealthIndicator.class)
.hasBean("elasticsearchHealthContributor"));
}

@Test
void runWithRestHighLevelClientAndWithRestClientShouldCreateIndicator() {
this.contextRunner.withUserConfiguration(CustomRestHighClientConfiguration.class)
.run((context) -> assertThat(context).hasSingleBean(ElasticsearchRestHealthIndicator.class)
.hasBean("elasticsearchHealthContributor"));
}

@Test
void runWhenDisabledShouldNotCreateIndicator() {
this.contextRunner.withPropertyValues("management.health.elasticsearch.enabled:false")
.run((context) -> assertThat(context).doesNotHaveBean(ElasticsearchRestHealthIndicator.class)
.doesNotHaveBean("elasticsearchHealthContributor"));
}

@Configuration(proxyBeanMethods = false)
static class CustomRestClientConfiguration {

@Bean
RestClient customRestClient(RestClientBuilder builder) {
return builder.build();
}

}

@Configuration(proxyBeanMethods = false)
@SuppressWarnings("deprecation")
static class CustomRestHighClientConfiguration {

@Bean
org.elasticsearch.client.RestHighLevelClient customRestHighClient(RestClientBuilder builder) {
return new org.elasticsearch.client.RestHighLevelClient(builder);
}

@Bean
RestClient customClient(org.elasticsearch.client.RestHighLevelClient restHighLevelClient) {
return restHighLevelClient.getLowLevelClient();
}

}

}
Expand Up @@ -22,6 +22,8 @@
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientConfigurations.RestClientBuilderConfiguration;
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientConfigurations.RestClientConfiguration;
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientConfigurations.RestClientFromRestHighLevelClientConfiguration;
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientConfigurations.RestClientSnifferConfiguration;
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientConfigurations.RestHighLevelClientConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
Expand All @@ -40,6 +42,7 @@
@EnableConfigurationProperties({ ElasticsearchProperties.class, ElasticsearchRestClientProperties.class,
DeprecatedElasticsearchRestClientProperties.class })
@Import({ RestClientBuilderConfiguration.class, RestHighLevelClientConfiguration.class,
RestClientFromRestHighLevelClientConfiguration.class, RestClientConfiguration.class,
RestClientSnifferConfiguration.class })
public class ElasticsearchRestClientAutoConfiguration {

Expand Down
Expand Up @@ -36,6 +36,7 @@
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
import org.springframework.boot.context.properties.PropertyMapper;
import org.springframework.context.annotation.Bean;
Expand All @@ -46,6 +47,7 @@
* Elasticsearch rest client configurations.
*
* @author Stephane Nicoll
* @author Filip Hrisafov
*/
class ElasticsearchRestClientConfigurations {

Expand Down Expand Up @@ -126,16 +128,41 @@ org.elasticsearch.client.RestHighLevelClient elasticsearchRestHighLevelClient(

@SuppressWarnings("deprecation")
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(Sniffer.class)
@ConditionalOnClass(org.elasticsearch.client.RestHighLevelClient.class)
@ConditionalOnSingleCandidate(org.elasticsearch.client.RestHighLevelClient.class)
@ConditionalOnMissingBean(RestClient.class)
static class RestClientFromRestHighLevelClientConfiguration {

@Bean
RestClient elasticsearchRestClient(org.elasticsearch.client.RestHighLevelClient restHighLevelClient) {
return restHighLevelClient.getLowLevelClient();
}

}

@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingClass("org.elasticsearch.client.RestHighLevelClient")
@ConditionalOnMissingBean(RestClient.class)
static class RestClientConfiguration {

@Bean
RestClient elasticsearchRestClient(RestClientBuilder restClientBuilder) {
return restClientBuilder.build();
}

}

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(Sniffer.class)
@ConditionalOnSingleCandidate(RestClient.class)
static class RestClientSnifferConfiguration {

@Bean
@ConditionalOnMissingBean
Sniffer elasticsearchSniffer(org.elasticsearch.client.RestHighLevelClient client,
ElasticsearchRestClientProperties properties,
@SuppressWarnings("deprecation")
Sniffer elasticsearchSniffer(RestClient client, ElasticsearchRestClientProperties properties,
DeprecatedElasticsearchRestClientProperties deprecatedProperties) {
SnifferBuilder builder = Sniffer.builder(client.getLowLevelClient());
SnifferBuilder builder = Sniffer.builder(client);
PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
Duration interval = deprecatedProperties.isCustomized() ? deprecatedProperties.getSniffer().getInterval()
: properties.getSniffer().getInterval();
Expand Down
Expand Up @@ -16,13 +16,19 @@

package org.springframework.boot.autoconfigure.elasticsearch;

import java.io.InputStream;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestClient;
import org.junit.jupiter.api.Test;
import org.testcontainers.elasticsearch.ElasticsearchContainer;
import org.testcontainers.junit.jupiter.Container;
Expand All @@ -40,6 +46,7 @@
* @author Brian Clozel
* @author Vedran Pavic
* @author Evgeniy Cheban
* @author Filip Hrisafov
*/
@Testcontainers(disabledWithoutDocker = true)
class ElasticsearchRestClientAutoConfigurationIntegrationTests {
Expand All @@ -53,7 +60,7 @@ class ElasticsearchRestClientAutoConfigurationIntegrationTests {

@Test
@SuppressWarnings("deprecation")
void restClientCanQueryElasticsearchNode() {
void restHighLevelClientCanQueryElasticsearchNode() {
this.contextRunner
.withPropertyValues("spring.elasticsearch.uris=" + elasticsearch.getHttpHostAddress(),
"spring.elasticsearch.connection-timeout=120s", "spring.elasticsearch.socket-timeout=120s")
Expand All @@ -70,4 +77,23 @@ void restClientCanQueryElasticsearchNode() {
});
}

@Test
void restClientCanQueryElasticsearchNode() {
this.contextRunner
.withPropertyValues("spring.elasticsearch.uris=" + elasticsearch.getHttpHostAddress(),
"spring.elasticsearch.connection-timeout=120s", "spring.elasticsearch.socket-timeout=120s")
.run((context) -> {
RestClient client = context.getBean(RestClient.class);
Request index = new Request("PUT", "/test/_doc/2");
index.setJsonEntity("{" + " \"a\": \"alpha\"," + " \"b\": \"bravo\"" + "}");
client.performRequest(index);
Request getRequest = new Request("GET", "/test/_doc/2");
Response response = client.performRequest(getRequest);
try (InputStream input = response.getEntity().getContent()) {
JsonNode result = new ObjectMapper().readTree(input);
assertThat(result.path("found").asBoolean()).isTrue();
}
});
}

}

0 comments on commit 227c316

Please sign in to comment.