Skip to content

Commit 27a936e

Browse files
committed
Fix Elastic health indicator without RestHighLevelClient
Closes gh-28496
1 parent f96efa7 commit 27a936e

File tree

6 files changed

+111
-80
lines changed

6 files changed

+111
-80
lines changed

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration;
2424
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
25-
import org.springframework.boot.actuate.elasticsearch.ElasticsearchRestHealthIndicator;
25+
import org.springframework.boot.actuate.elasticsearch.ElasticsearchRestClientHealthIndicator;
2626
import org.springframework.boot.actuate.health.HealthContributor;
2727
import org.springframework.boot.autoconfigure.AutoConfiguration;
2828
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
@@ -34,7 +34,7 @@
3434

3535
/**
3636
* {@link EnableAutoConfiguration Auto-configuration} for
37-
* {@link ElasticsearchRestHealthIndicator} using the {@link RestClient}.
37+
* {@link ElasticsearchRestClientHealthIndicator}.
3838
*
3939
* @author Artsiom Yudovin
4040
* @since 2.1.1
@@ -44,7 +44,7 @@
4444
@ConditionalOnBean(RestClient.class)
4545
@ConditionalOnEnabledHealthIndicator("elasticsearch")
4646
public class ElasticSearchRestHealthContributorAutoConfiguration
47-
extends CompositeHealthContributorConfiguration<ElasticsearchRestHealthIndicator, RestClient> {
47+
extends CompositeHealthContributorConfiguration<ElasticsearchRestClientHealthIndicator, RestClient> {
4848

4949
@Bean
5050
@ConditionalOnMissingBean(name = { "elasticsearchHealthIndicator", "elasticsearchHealthContributor" })

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticSearchRestHealthContributorAutoConfigurationTests.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import org.junit.jupiter.api.Test;
2222

2323
import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration;
24-
import org.springframework.boot.actuate.elasticsearch.ElasticsearchRestHealthIndicator;
24+
import org.springframework.boot.actuate.elasticsearch.ElasticsearchRestClientHealthIndicator;
2525
import org.springframework.boot.autoconfigure.AutoConfigurations;
2626
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration;
2727
import org.springframework.boot.test.context.FilteredClassLoader;
@@ -46,8 +46,8 @@ class ElasticSearchRestHealthContributorAutoConfigurationTests {
4646

4747
@Test
4848
void runShouldCreateIndicator() {
49-
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(ElasticsearchRestHealthIndicator.class)
50-
.hasBean("elasticsearchHealthContributor"));
49+
this.contextRunner.run((context) -> assertThat(context)
50+
.hasSingleBean(ElasticsearchRestClientHealthIndicator.class).hasBean("elasticsearchHealthContributor"));
5151
}
5252

5353
@Test
@@ -56,29 +56,28 @@ void runWithoutRestHighLevelClientAndWithoutRestClientShouldNotCreateIndicator()
5656
this.contextRunner
5757
.withClassLoader(
5858
new FilteredClassLoader(org.elasticsearch.client.RestHighLevelClient.class, RestClient.class))
59-
.run((context) -> assertThat(context).doesNotHaveBean(ElasticsearchRestHealthIndicator.class)
59+
.run((context) -> assertThat(context).doesNotHaveBean(ElasticsearchRestClientHealthIndicator.class)
6060
.doesNotHaveBean("elasticsearchHealthContributor"));
6161
}
6262

6363
@Test
6464
void runWithoutRestHighLevelClientAndWithRestClientShouldCreateIndicator() {
6565
this.contextRunner.withUserConfiguration(CustomRestClientConfiguration.class)
66-
.run((context) -> assertThat(context).hasSingleBean(ElasticsearchRestHealthIndicator.class)
67-
.hasSingleBean(ElasticsearchRestHealthIndicator.class)
66+
.run((context) -> assertThat(context).hasSingleBean(ElasticsearchRestClientHealthIndicator.class)
6867
.hasBean("elasticsearchHealthContributor"));
6968
}
7069

7170
@Test
7271
void runWithRestHighLevelClientAndWithRestClientShouldCreateIndicator() {
7372
this.contextRunner.withUserConfiguration(CustomRestHighClientConfiguration.class)
74-
.run((context) -> assertThat(context).hasSingleBean(ElasticsearchRestHealthIndicator.class)
73+
.run((context) -> assertThat(context).hasSingleBean(ElasticsearchRestClientHealthIndicator.class)
7574
.hasBean("elasticsearchHealthContributor"));
7675
}
7776

7877
@Test
7978
void runWhenDisabledShouldNotCreateIndicator() {
8079
this.contextRunner.withPropertyValues("management.health.elasticsearch.enabled:false")
81-
.run((context) -> assertThat(context).doesNotHaveBean(ElasticsearchRestHealthIndicator.class)
80+
.run((context) -> assertThat(context).doesNotHaveBean(ElasticsearchRestClientHealthIndicator.class)
8281
.doesNotHaveBean("elasticsearchHealthContributor"));
8382
}
8483

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticsearchReactiveHealthContributorAutoConfigurationTests.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors.
2+
* Copyright 2012-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,7 +20,7 @@
2020

2121
import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration;
2222
import org.springframework.boot.actuate.elasticsearch.ElasticsearchReactiveHealthIndicator;
23-
import org.springframework.boot.actuate.elasticsearch.ElasticsearchRestHealthIndicator;
23+
import org.springframework.boot.actuate.elasticsearch.ElasticsearchRestClientHealthIndicator;
2424
import org.springframework.boot.autoconfigure.AutoConfigurations;
2525
import org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration;
2626
import org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRestClientAutoConfiguration;
@@ -55,7 +55,7 @@ void runWithRegularIndicatorShouldOnlyCreateReactiveIndicator() {
5555
.withConfiguration(AutoConfigurations.of(ElasticSearchRestHealthContributorAutoConfiguration.class))
5656
.run((context) -> assertThat(context).hasSingleBean(ElasticsearchReactiveHealthIndicator.class)
5757
.hasBean("elasticsearchHealthContributor")
58-
.doesNotHaveBean(ElasticsearchRestHealthIndicator.class));
58+
.doesNotHaveBean(ElasticsearchRestClientHealthIndicator.class));
5959
}
6060

6161
@Test
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
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.elasticsearch;
18+
19+
import java.io.InputStream;
20+
import java.nio.charset.StandardCharsets;
21+
import java.util.Map;
22+
23+
import org.apache.http.HttpStatus;
24+
import org.apache.http.StatusLine;
25+
import org.elasticsearch.client.Request;
26+
import org.elasticsearch.client.Response;
27+
import org.elasticsearch.client.RestClient;
28+
29+
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
30+
import org.springframework.boot.actuate.health.Health;
31+
import org.springframework.boot.actuate.health.HealthIndicator;
32+
import org.springframework.boot.json.JsonParser;
33+
import org.springframework.boot.json.JsonParserFactory;
34+
import org.springframework.util.StreamUtils;
35+
36+
/**
37+
* {@link HealthIndicator} for an Elasticsearch cluster using a {@link RestClient}.
38+
*
39+
* @author Artsiom Yudovin
40+
* @author Brian Clozel
41+
* @author Filip Hrisafov
42+
* @since 2.7.0
43+
*/
44+
public class ElasticsearchRestClientHealthIndicator extends AbstractHealthIndicator {
45+
46+
private static final String RED_STATUS = "red";
47+
48+
private final RestClient client;
49+
50+
private final JsonParser jsonParser;
51+
52+
public ElasticsearchRestClientHealthIndicator(RestClient client) {
53+
super("Elasticsearch health check failed");
54+
this.client = client;
55+
this.jsonParser = JsonParserFactory.getJsonParser();
56+
}
57+
58+
@Override
59+
protected void doHealthCheck(Health.Builder builder) throws Exception {
60+
Response response = this.client.performRequest(new Request("GET", "/_cluster/health/"));
61+
StatusLine statusLine = response.getStatusLine();
62+
if (statusLine.getStatusCode() != HttpStatus.SC_OK) {
63+
builder.down();
64+
builder.withDetail("statusCode", statusLine.getStatusCode());
65+
builder.withDetail("reasonPhrase", statusLine.getReasonPhrase());
66+
return;
67+
}
68+
try (InputStream inputStream = response.getEntity().getContent()) {
69+
doHealthCheck(builder, StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8));
70+
}
71+
}
72+
73+
private void doHealthCheck(Health.Builder builder, String json) {
74+
Map<String, Object> response = this.jsonParser.parseMap(json);
75+
String status = (String) response.get("status");
76+
if (RED_STATUS.equals(status)) {
77+
builder.outOfService();
78+
}
79+
else {
80+
builder.up();
81+
}
82+
builder.withDetails(response);
83+
}
84+
85+
}

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

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

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

19-
import java.io.InputStream;
20-
import java.nio.charset.StandardCharsets;
21-
import java.util.Map;
22-
23-
import org.apache.http.HttpStatus;
24-
import org.apache.http.StatusLine;
25-
import org.elasticsearch.client.Request;
26-
import org.elasticsearch.client.Response;
2719
import org.elasticsearch.client.RestClient;
2820

29-
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
30-
import org.springframework.boot.actuate.health.Health;
3121
import org.springframework.boot.actuate.health.HealthIndicator;
32-
import org.springframework.boot.json.JsonParser;
33-
import org.springframework.boot.json.JsonParserFactory;
34-
import org.springframework.util.StreamUtils;
3522

3623
/**
3724
* {@link HealthIndicator} for an Elasticsearch cluster using a {@link RestClient}.
@@ -40,58 +27,18 @@
4027
* @author Brian Clozel
4128
* @author Filip Hrisafov
4229
* @since 2.1.1
30+
* @deprecated since 2.7.0 for removal in 2.9.0 in favor of
31+
* {@link ElasticsearchRestClientHealthIndicator}
4332
*/
44-
public class ElasticsearchRestHealthIndicator extends AbstractHealthIndicator {
45-
46-
private static final String RED_STATUS = "red";
47-
48-
private final RestClient client;
49-
50-
private final JsonParser jsonParser;
33+
@Deprecated
34+
public class ElasticsearchRestHealthIndicator extends ElasticsearchRestClientHealthIndicator {
5135

52-
/**
53-
* Create a new {@code ElasticsearchRestHealthIndicator} using the {@link RestClient}
54-
* obtained from the given high-level client.
55-
* @param client the high-level client
56-
* @deprecated since 2.7.0 for removal in 2.9.0 in favor of
57-
* {@link #ElasticsearchRestHealthIndicator(RestClient)}
58-
*/
59-
@Deprecated
6036
public ElasticsearchRestHealthIndicator(org.elasticsearch.client.RestHighLevelClient client) {
6137
this(client.getLowLevelClient());
6238
}
6339

6440
public ElasticsearchRestHealthIndicator(RestClient client) {
65-
super("Elasticsearch health check failed");
66-
this.client = client;
67-
this.jsonParser = JsonParserFactory.getJsonParser();
68-
}
69-
70-
@Override
71-
protected void doHealthCheck(Health.Builder builder) throws Exception {
72-
Response response = this.client.performRequest(new Request("GET", "/_cluster/health/"));
73-
StatusLine statusLine = response.getStatusLine();
74-
if (statusLine.getStatusCode() != HttpStatus.SC_OK) {
75-
builder.down();
76-
builder.withDetail("statusCode", statusLine.getStatusCode());
77-
builder.withDetail("reasonPhrase", statusLine.getReasonPhrase());
78-
return;
79-
}
80-
try (InputStream inputStream = response.getEntity().getContent()) {
81-
doHealthCheck(builder, StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8));
82-
}
83-
}
84-
85-
private void doHealthCheck(Health.Builder builder, String json) {
86-
Map<String, Object> response = this.jsonParser.parseMap(json);
87-
String status = (String) response.get("status");
88-
if (RED_STATUS.equals(status)) {
89-
builder.outOfService();
90-
}
91-
else {
92-
builder.up();
93-
}
94-
builder.withDetails(response);
41+
super(client);
9542
}
9643

9744
}
Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,16 @@
3737
import static org.mockito.Mockito.mock;
3838

3939
/**
40-
* Tests for {@link ElasticsearchRestHealthIndicator}.
40+
* Tests for {@link ElasticsearchRestClientHealthIndicator}.
4141
*
4242
* @author Artsiom Yudovin
4343
* @author Filip Hrisafov
4444
*/
45-
class ElasticsearchRestHealthIndicatorTests {
45+
class ElasticsearchRestClientHealthIndicatorTests {
4646

4747
private final RestClient restClient = mock(RestClient.class);
4848

49-
private final ElasticsearchRestHealthIndicator elasticsearchRestHealthIndicator = new ElasticsearchRestHealthIndicator(
49+
private final ElasticsearchRestClientHealthIndicator elasticsearchRestClientHealthIndicator = new ElasticsearchRestClientHealthIndicator(
5050
this.restClient);
5151

5252
@Test
@@ -59,7 +59,7 @@ void elasticsearchIsUp() throws IOException {
5959
given(response.getStatusLine()).willReturn(statusLine);
6060
given(response.getEntity()).willReturn(httpEntity);
6161
given(this.restClient.performRequest(any(Request.class))).willReturn(response);
62-
Health health = this.elasticsearchRestHealthIndicator.health();
62+
Health health = this.elasticsearchRestClientHealthIndicator.health();
6363
assertThat(health.getStatus()).isEqualTo(Status.UP);
6464
assertHealthDetailsWithStatus(health.getDetails(), "green");
6565
}
@@ -74,15 +74,15 @@ void elasticsearchWithYellowStatusIsUp() throws IOException {
7474
given(response.getStatusLine()).willReturn(statusLine);
7575
given(response.getEntity()).willReturn(httpEntity);
7676
given(this.restClient.performRequest(any(Request.class))).willReturn(response);
77-
Health health = this.elasticsearchRestHealthIndicator.health();
77+
Health health = this.elasticsearchRestClientHealthIndicator.health();
7878
assertThat(health.getStatus()).isEqualTo(Status.UP);
7979
assertHealthDetailsWithStatus(health.getDetails(), "yellow");
8080
}
8181

8282
@Test
8383
void elasticsearchIsDown() throws IOException {
8484
given(this.restClient.performRequest(any(Request.class))).willThrow(new IOException("Couldn't connect"));
85-
Health health = this.elasticsearchRestHealthIndicator.health();
85+
Health health = this.elasticsearchRestClientHealthIndicator.health();
8686
assertThat(health.getStatus()).isEqualTo(Status.DOWN);
8787
assertThat(health.getDetails()).contains(entry("error", "java.io.IOException: Couldn't connect"));
8888
}
@@ -95,7 +95,7 @@ void elasticsearchIsDownByResponseCode() throws IOException {
9595
given(statusLine.getReasonPhrase()).willReturn("Internal server error");
9696
given(response.getStatusLine()).willReturn(statusLine);
9797
given(this.restClient.performRequest(any(Request.class))).willReturn(response);
98-
Health health = this.elasticsearchRestHealthIndicator.health();
98+
Health health = this.elasticsearchRestClientHealthIndicator.health();
9999
assertThat(health.getStatus()).isEqualTo(Status.DOWN);
100100
assertThat(health.getDetails()).contains(entry("statusCode", 500),
101101
entry("reasonPhrase", "Internal server error"));
@@ -111,7 +111,7 @@ void elasticsearchIsOutOfServiceByStatus() throws IOException {
111111
given(response.getStatusLine()).willReturn(statusLine);
112112
given(response.getEntity()).willReturn(httpEntity);
113113
given(this.restClient.performRequest(any(Request.class))).willReturn(response);
114-
Health health = this.elasticsearchRestHealthIndicator.health();
114+
Health health = this.elasticsearchRestClientHealthIndicator.health();
115115
assertThat(health.getStatus()).isEqualTo(Status.OUT_OF_SERVICE);
116116
assertHealthDetailsWithStatus(health.getDetails(), "red");
117117
}

0 commit comments

Comments
 (0)