Skip to content

Commit 21af08b

Browse files
author
Aleksander Lech
committed
Added support for healthcheck for ReactiveElasticsearchClient
1 parent 2c72350 commit 21af08b

File tree

7 files changed

+192
-2
lines changed

7 files changed

+192
-2
lines changed

spring-boot-project/spring-boot-actuator-autoconfigure/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ dependencies {
9999
optional("org.springframework.data:spring-data-mongodb")
100100
optional("org.springframework.data:spring-data-neo4j")
101101
optional("org.springframework.data:spring-data-redis")
102+
optional("org.springframework.data:spring-data-elasticsearch")
102103
optional("org.springframework.data:spring-data-solr")
103104
optional("org.springframework.integration:spring-integration-core")
104105
optional("org.springframework.kafka:spring-kafka")
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright 2012-2020 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 java.util.Map;
20+
21+
import reactor.core.publisher.Flux;
22+
23+
import org.springframework.boot.actuate.autoconfigure.health.CompositeReactiveHealthContributorConfiguration;
24+
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
25+
import org.springframework.boot.actuate.elasticsearch.ElasticsearchReactiveHealthIndicator;
26+
import org.springframework.boot.actuate.health.ReactiveHealthContributor;
27+
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
28+
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
29+
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
30+
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
31+
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
32+
import org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRestClientAutoConfiguration;
33+
import org.springframework.context.annotation.Bean;
34+
import org.springframework.context.annotation.Configuration;
35+
import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient;
36+
37+
/**
38+
* {@link EnableAutoConfiguration Auto-configuration} for
39+
* {@link ElasticsearchReactiveHealthIndicator} using the
40+
* {@link ReactiveElasticsearchClient}.
41+
*
42+
* @author Aleksander Lech
43+
* @since 2.3
44+
*/
45+
@Configuration(proxyBeanMethods = false)
46+
@ConditionalOnClass({ ReactiveElasticsearchClient.class, Flux.class })
47+
@ConditionalOnBean(ReactiveElasticsearchClient.class)
48+
@ConditionalOnEnabledHealthIndicator("elasticsearch")
49+
@AutoConfigureAfter(ReactiveElasticsearchRestClientAutoConfiguration.class)
50+
public class ElasticSearchReactiveHealthContributorAutoConfiguration extends
51+
CompositeReactiveHealthContributorConfiguration<ElasticsearchReactiveHealthIndicator, ReactiveElasticsearchClient> {
52+
53+
@Bean
54+
@ConditionalOnMissingBean(name = { "elasticsearchHealthIndicator", "elasticsearchHealthContributor" })
55+
public ReactiveHealthContributor elasticsearchHealthContributor(Map<String, ReactiveElasticsearchClient> clients) {
56+
return createContributor(clients);
57+
}
58+
59+
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ public class ElasticSearchRestHealthContributorAutoConfiguration
4949
extends CompositeHealthContributorConfiguration<ElasticsearchRestHealthIndicator, RestClient> {
5050

5151
@Bean
52-
@ConditionalOnMissingBean(name = { "elasticsearchRestHealthIndicator", "elasticsearchRestHealthContributor" })
53-
public HealthContributor elasticsearchRestHealthContributor(Map<String, RestClient> clients) {
52+
@ConditionalOnMissingBean(name = { "elasticsearchHealthIndicator", "elasticsearchHealthContributor" })
53+
public HealthContributor elasticsearchHealthContributor(Map<String, RestClient> clients) {
5454
return createContributor(clients);
5555
}
5656

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring.factories

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ org.springframework.boot.actuate.autoconfigure.context.ShutdownEndpointAutoConfi
1515
org.springframework.boot.actuate.autoconfigure.couchbase.CouchbaseHealthContributorAutoConfiguration,\
1616
org.springframework.boot.actuate.autoconfigure.couchbase.CouchbaseReactiveHealthContributorAutoConfiguration,\
1717
org.springframework.boot.actuate.autoconfigure.elasticsearch.ElasticSearchRestHealthContributorAutoConfiguration,\
18+
org.springframework.boot.actuate.autoconfigure.elasticsearch.ElasticSearchReactiveHealthContributorAutoConfiguration,\
1819
org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration,\
1920
org.springframework.boot.actuate.autoconfigure.endpoint.jmx.JmxEndpointAutoConfiguration,\
2021
org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration,\
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Copyright 2012-2020 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.junit.jupiter.api.Test;
20+
21+
import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration;
22+
import org.springframework.boot.actuate.elasticsearch.ElasticsearchReactiveHealthIndicator;
23+
import org.springframework.boot.actuate.elasticsearch.ElasticsearchRestHealthIndicator;
24+
import org.springframework.boot.autoconfigure.AutoConfigurations;
25+
import org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration;
26+
import org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRestClientAutoConfiguration;
27+
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration;
28+
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
29+
30+
import static org.assertj.core.api.Assertions.assertThat;
31+
32+
/**
33+
* Tests for {@link ElasticSearchReactiveHealthContributorAutoConfiguration}.
34+
*
35+
* @author Aleksander Lech
36+
*/
37+
class ElasticsearchReactiveHealthContributorAutoConfigurationTests {
38+
39+
private ApplicationContextRunner contextRunner = new ApplicationContextRunner().withConfiguration(AutoConfigurations
40+
.of(ElasticsearchDataAutoConfiguration.class, ReactiveElasticsearchRestClientAutoConfiguration.class,
41+
ElasticsearchRestClientAutoConfiguration.class,
42+
ElasticSearchReactiveHealthContributorAutoConfiguration.class,
43+
HealthContributorAutoConfiguration.class));
44+
45+
@Test
46+
void runShouldCreateIndicator() {
47+
this.contextRunner.run((context) -> assertThat(context)
48+
.hasSingleBean(ElasticsearchReactiveHealthIndicator.class).hasBean("elasticsearchHealthContributor"));
49+
}
50+
51+
@Test
52+
void runWithRegularIndicatorShouldOnlyCreateReactiveIndicator() {
53+
this.contextRunner
54+
.withConfiguration(AutoConfigurations.of(ElasticSearchRestHealthContributorAutoConfiguration.class))
55+
.run((context) -> assertThat(context).hasSingleBean(ElasticsearchReactiveHealthIndicator.class)
56+
.hasBean("elasticsearchHealthContributor")
57+
.doesNotHaveBean(ElasticsearchRestHealthIndicator.class));
58+
}
59+
60+
@Test
61+
void runWhenDisabledShouldNotCreateIndicator() {
62+
this.contextRunner.withPropertyValues("management.health.elasticsearch.enabled:false")
63+
.run((context) -> assertThat(context).doesNotHaveBean(ElasticsearchReactiveHealthIndicator.class)
64+
.doesNotHaveBean("elasticsearchHealthContributor"));
65+
}
66+
67+
}

spring-boot-project/spring-boot-actuator/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ dependencies {
6060
optional("org.springframework.data:spring-data-neo4j")
6161
optional("org.springframework.data:spring-data-redis")
6262
optional("org.springframework.data:spring-data-rest-webmvc")
63+
optional("org.springframework.data:spring-data-elasticsearch")
6364
optional("org.springframework.data:spring-data-solr")
6465
optional("org.springframework.integration:spring-integration-core")
6566
optional("org.springframework.security:spring-security-core")
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright 2012-2020 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.elasticsearch;
18+
19+
import java.util.stream.Collectors;
20+
21+
import reactor.core.publisher.Mono;
22+
23+
import org.springframework.boot.actuate.health.AbstractReactiveHealthIndicator;
24+
import org.springframework.boot.actuate.health.Health;
25+
import org.springframework.boot.actuate.health.HealthIndicator;
26+
import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient;
27+
28+
/**
29+
* {@link HealthIndicator} for an Elasticsearch cluster using a
30+
* {@link ReactiveElasticsearchClient}.
31+
*
32+
* @author Aleksander Lech
33+
* @since 2.3
34+
*/
35+
public class ElasticsearchReactiveHealthIndicator extends AbstractReactiveHealthIndicator {
36+
37+
private final ReactiveElasticsearchClient client;
38+
39+
public ElasticsearchReactiveHealthIndicator(ReactiveElasticsearchClient client) {
40+
super("Elasticsearch health check failed");
41+
this.client = client;
42+
}
43+
44+
@Override
45+
protected Mono<Health> doHealthCheck(Health.Builder builder) {
46+
return this.client.status().map((status) -> {
47+
if (status.isOk()) {
48+
builder.up();
49+
}
50+
else {
51+
builder.down();
52+
}
53+
54+
builder.withDetails(status.hosts().stream().collect(Collectors
55+
.toMap((host) -> host.getEndpoint().getHostString(), (host) -> host.getState().toString())));
56+
57+
return builder.build();
58+
});
59+
}
60+
61+
}

0 commit comments

Comments
 (0)