From 8de8403e1624cce68b4eb03703b2763b748455d8 Mon Sep 17 00:00:00 2001 From: artsiom Date: Mon, 19 Nov 2018 12:39:10 +0300 Subject: [PATCH 1/4] adding actuator health check support for Elasticsearch REST Clients --- .../pom.xml | 5 ++ ...hRestHealthIndicatorAutoConfiguration.java | 75 +++++++++++++++++++ .../spring-boot-actuator/pom.xml | 5 ++ .../ElasticsearchRestHealthIndicator.java | 69 +++++++++++++++++ 4 files changed, 154 insertions(+) create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticSearchRestHealthIndicatorAutoConfiguration.java create mode 100644 spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicator.java diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml b/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml index 130f4cc33b55..304d993add79 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml @@ -263,6 +263,11 @@ elasticsearch true + + org.elasticsearch.client + elasticsearch-rest-high-level-client + true + org.eclipse.jetty jetty-server diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticSearchRestHealthIndicatorAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticSearchRestHealthIndicatorAutoConfiguration.java new file mode 100644 index 000000000000..08298995bf32 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticSearchRestHealthIndicatorAutoConfiguration.java @@ -0,0 +1,75 @@ +/* + * Copyright 2012-2018 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 + * + * http://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 java.util.Map; + +import org.elasticsearch.client.RestHighLevelClient; + +import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthIndicatorConfiguration; +import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; +import org.springframework.boot.actuate.autoconfigure.health.HealthIndicatorAutoConfiguration; +import org.springframework.boot.actuate.elasticsearch.ElasticsearchRestHealthIndicator; +import org.springframework.boot.actuate.health.HealthIndicator; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.elasticsearch.rest.RestClientAutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for + * {@link ElasticsearchRestHealthIndicator} using the {@link RestHighLevelClient}. + * + * @author Artsiom Yudovin + * @since 2.1.0 + */ + +@Configuration +@ConditionalOnClass(RestHighLevelClient.class) +@ConditionalOnBean(RestHighLevelClient.class) +@ConditionalOnEnabledHealthIndicator("elasticsearch") +@AutoConfigureBefore(HealthIndicatorAutoConfiguration.class) +@AutoConfigureAfter({ RestClientAutoConfiguration.class, + ElasticSearchClientHealthIndicatorAutoConfiguration.class }) +public class ElasticSearchRestHealthIndicatorAutoConfiguration extends + CompositeHealthIndicatorConfiguration { + + private final Map clients; + + public ElasticSearchRestHealthIndicatorAutoConfiguration( + Map clients) { + this.clients = clients; + } + + @Bean + @ConditionalOnMissingBean(name = "elasticsearchRestHealthIndicator") + public HealthIndicator elasticsearchRestHealthIndicator() { + return createHealthIndicator(this.clients); + } + + @Override + protected ElasticsearchRestHealthIndicator createHealthIndicator( + RestHighLevelClient client) { + return new ElasticsearchRestHealthIndicator(client); + } + +} diff --git a/spring-boot-project/spring-boot-actuator/pom.xml b/spring-boot-project/spring-boot-actuator/pom.xml index de7fa8560cf5..e51d838af2bc 100644 --- a/spring-boot-project/spring-boot-actuator/pom.xml +++ b/spring-boot-project/spring-boot-actuator/pom.xml @@ -77,6 +77,11 @@ jest true + + org.elasticsearch.client + elasticsearch-rest-high-level-client + true + io.undertow undertow-servlet diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicator.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicator.java new file mode 100644 index 000000000000..09fc511cbcba --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicator.java @@ -0,0 +1,69 @@ +/* + * Copyright 2012-2018 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 + * + * http://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.elasticsearch; + +import org.elasticsearch.action.admin.cluster.health.ClusterHealthRequest; +import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; +import org.elasticsearch.client.RequestOptions; +import org.elasticsearch.client.RestHighLevelClient; + +import org.springframework.boot.actuate.health.AbstractHealthIndicator; +import org.springframework.boot.actuate.health.Health; +import org.springframework.boot.actuate.health.HealthIndicator; + +/** + * {@link HealthIndicator} for an Elasticsearch cluster by REST. + * + * @author Artsiom Yudovin + * @since 2.1.0 + */ +public class ElasticsearchRestHealthIndicator extends AbstractHealthIndicator { + + private final RestHighLevelClient client; + + public ElasticsearchRestHealthIndicator(RestHighLevelClient client) { + super("Elasticsearch health check failed"); + this.client = client; + } + + @Override + protected void doHealthCheck(Health.Builder builder) throws Exception { + ClusterHealthResponse response = this.client.cluster() + .health(new ClusterHealthRequest(), RequestOptions.DEFAULT); + + switch (response.getStatus()) { + case GREEN: + case YELLOW: + builder.up(); + break; + case RED: + default: + builder.down(); + break; + } + + builder.withDetail("clusterName", response.getClusterName()); + builder.withDetail("numberOfNodes", response.getNumberOfNodes()); + builder.withDetail("numberOfDataNodes", response.getNumberOfDataNodes()); + builder.withDetail("activePrimaryShards", response.getActivePrimaryShards()); + builder.withDetail("activeShards", response.getActiveShards()); + builder.withDetail("relocatingShards", response.getRelocatingShards()); + builder.withDetail("initializingShards", response.getInitializingShards()); + builder.withDetail("unassignedShards", response.getUnassignedShards()); + } + +} From 765e2635bbe4aa47be1fe5ec5a48fde7488821c2 Mon Sep 17 00:00:00 2001 From: artsiom Date: Mon, 19 Nov 2018 12:58:24 +0300 Subject: [PATCH 2/4] adding actuator health check support for Elasticsearch REST Clients --- .../ElasticsearchRestHealthIndicator.java | 28 ++++++------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicator.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicator.java index 09fc511cbcba..09e6ca5a52a5 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicator.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicator.java @@ -16,8 +16,7 @@ package org.springframework.boot.actuate.elasticsearch; -import org.elasticsearch.action.admin.cluster.health.ClusterHealthRequest; -import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; +import org.elasticsearch.action.main.MainResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; @@ -42,28 +41,19 @@ public ElasticsearchRestHealthIndicator(RestHighLevelClient client) { @Override protected void doHealthCheck(Health.Builder builder) throws Exception { - ClusterHealthResponse response = this.client.cluster() - .health(new ClusterHealthRequest(), RequestOptions.DEFAULT); + MainResponse info = this.client.info(RequestOptions.DEFAULT); - switch (response.getStatus()) { - case GREEN: - case YELLOW: + if (info.isAvailable()) { builder.up(); - break; - case RED: - default: + } + else { builder.down(); - break; } - builder.withDetail("clusterName", response.getClusterName()); - builder.withDetail("numberOfNodes", response.getNumberOfNodes()); - builder.withDetail("numberOfDataNodes", response.getNumberOfDataNodes()); - builder.withDetail("activePrimaryShards", response.getActivePrimaryShards()); - builder.withDetail("activeShards", response.getActiveShards()); - builder.withDetail("relocatingShards", response.getRelocatingShards()); - builder.withDetail("initializingShards", response.getInitializingShards()); - builder.withDetail("unassignedShards", response.getUnassignedShards()); + builder.withDetail("clusterName", info.getClusterName()); + builder.withDetail("nodeName", info.getNodeName()); + builder.withDetail("clusterUuid", info.getClusterUuid()); + builder.withDetail("version", info.getVersion()); } } From da11afdfc96afcae1947c675bff32ec5eae78bec Mon Sep 17 00:00:00 2001 From: artsiom Date: Tue, 20 Nov 2018 12:29:09 +0300 Subject: [PATCH 3/4] updating by comments and adding unit tests --- .../pom.xml | 2 +- ...hRestHealthIndicatorAutoConfiguration.java | 17 ++- .../spring-boot-actuator/pom.xml | 9 +- .../ElasticsearchRestHealthIndicator.java | 43 ++++-- ...chRestHealthIndicatorIntegrationTests.java | 80 +++++++++++ .../ElasticsearchRestHealthIndicatorTest.java | 127 ++++++++++++++++++ 6 files changed, 253 insertions(+), 25 deletions(-) create mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicatorIntegrationTests.java create mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicatorTest.java diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml b/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml index 304d993add79..e77d8e53453c 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml @@ -265,7 +265,7 @@ org.elasticsearch.client - elasticsearch-rest-high-level-client + elasticsearch-rest-client true diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticSearchRestHealthIndicatorAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticSearchRestHealthIndicatorAutoConfiguration.java index 08298995bf32..c47b934e6de7 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticSearchRestHealthIndicatorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/elasticsearch/ElasticSearchRestHealthIndicatorAutoConfiguration.java @@ -18,7 +18,7 @@ import java.util.Map; -import org.elasticsearch.client.RestHighLevelClient; +import org.elasticsearch.client.RestClient; import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthIndicatorConfiguration; import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; @@ -37,26 +37,26 @@ /** * {@link EnableAutoConfiguration Auto-configuration} for - * {@link ElasticsearchRestHealthIndicator} using the {@link RestHighLevelClient}. + * {@link ElasticsearchRestHealthIndicator} using the {@link RestClient}. * * @author Artsiom Yudovin * @since 2.1.0 */ @Configuration -@ConditionalOnClass(RestHighLevelClient.class) -@ConditionalOnBean(RestHighLevelClient.class) +@ConditionalOnClass(RestClient.class) +@ConditionalOnBean(RestClient.class) @ConditionalOnEnabledHealthIndicator("elasticsearch") @AutoConfigureBefore(HealthIndicatorAutoConfiguration.class) @AutoConfigureAfter({ RestClientAutoConfiguration.class, ElasticSearchClientHealthIndicatorAutoConfiguration.class }) public class ElasticSearchRestHealthIndicatorAutoConfiguration extends - CompositeHealthIndicatorConfiguration { + CompositeHealthIndicatorConfiguration { - private final Map clients; + private final Map clients; public ElasticSearchRestHealthIndicatorAutoConfiguration( - Map clients) { + Map clients) { this.clients = clients; } @@ -67,8 +67,7 @@ public HealthIndicator elasticsearchRestHealthIndicator() { } @Override - protected ElasticsearchRestHealthIndicator createHealthIndicator( - RestHighLevelClient client) { + protected ElasticsearchRestHealthIndicator createHealthIndicator(RestClient client) { return new ElasticsearchRestHealthIndicator(client); } diff --git a/spring-boot-project/spring-boot-actuator/pom.xml b/spring-boot-project/spring-boot-actuator/pom.xml index e51d838af2bc..0fa301f14327 100644 --- a/spring-boot-project/spring-boot-actuator/pom.xml +++ b/spring-boot-project/spring-boot-actuator/pom.xml @@ -79,7 +79,7 @@ org.elasticsearch.client - elasticsearch-rest-high-level-client + elasticsearch-rest-client true @@ -343,5 +343,12 @@ jsonassert test + + org.testcontainers + elasticsearch + 1.10.1 + test + + diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicator.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicator.java index 09e6ca5a52a5..fb542496afaf 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicator.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicator.java @@ -16,9 +16,15 @@ package org.springframework.boot.actuate.elasticsearch; -import org.elasticsearch.action.main.MainResponse; -import org.elasticsearch.client.RequestOptions; -import org.elasticsearch.client.RestHighLevelClient; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; + +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import org.apache.http.HttpStatus; +import org.elasticsearch.client.Request; +import org.elasticsearch.client.Response; +import org.elasticsearch.client.RestClient; import org.springframework.boot.actuate.health.AbstractHealthIndicator; import org.springframework.boot.actuate.health.Health; @@ -32,28 +38,37 @@ */ public class ElasticsearchRestHealthIndicator extends AbstractHealthIndicator { - private final RestHighLevelClient client; + private final RestClient client; + + private final JsonParser jsonParser = new JsonParser(); - public ElasticsearchRestHealthIndicator(RestHighLevelClient client) { + public ElasticsearchRestHealthIndicator(RestClient client) { super("Elasticsearch health check failed"); this.client = client; } @Override protected void doHealthCheck(Health.Builder builder) throws Exception { - MainResponse info = this.client.info(RequestOptions.DEFAULT); + Response response = this.client + .performRequest(new Request("GET", "/_cluster/health/")); - if (info.isAvailable()) { - builder.up(); + if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { + builder.down(); } else { - builder.down(); + try (InputStreamReader reader = new InputStreamReader( + response.getEntity().getContent(), StandardCharsets.UTF_8)) { + JsonElement root = this.jsonParser.parse(reader); + JsonElement status = root.getAsJsonObject().get("status"); + if (status.getAsString() + .equals(io.searchbox.cluster.Health.Status.RED.getKey())) { + builder.outOfService(); + } + else { + builder.up(); + } + } } - - builder.withDetail("clusterName", info.getClusterName()); - builder.withDetail("nodeName", info.getNodeName()); - builder.withDetail("clusterUuid", info.getClusterUuid()); - builder.withDetail("version", info.getVersion()); } } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicatorIntegrationTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicatorIntegrationTests.java new file mode 100644 index 000000000000..5ab62c8b7b3a --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicatorIntegrationTests.java @@ -0,0 +1,80 @@ +/* + * Copyright 2012-2018 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 + * + * http://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.elasticsearch; + +import org.apache.http.HttpHost; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.client.CredentialsProvider; +import org.apache.http.impl.client.BasicCredentialsProvider; +import org.elasticsearch.client.RestClient; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; +import org.testcontainers.elasticsearch.ElasticsearchContainer; + +import org.springframework.boot.actuate.health.Health; +import org.springframework.boot.actuate.health.Status; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link ElasticsearchRestHealthIndicator}. + * + * @author Artsiom Yudovin + */ +public class ElasticsearchRestHealthIndicatorIntegrationTests { + + @ClassRule + public static final ElasticsearchContainer container = new ElasticsearchContainer( + "docker.elastic.co/elasticsearch/elasticsearch:6.4.1"); + + private ElasticsearchRestHealthIndicator elasticsearchRestHealthIndicator; + + @BeforeClass + public static void start() { + container.start(); + } + + @AfterClass + public static void stop() { + container.stop(); + } + + @Before + public void initClient() { + final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); + credentialsProvider.setCredentials(AuthScope.ANY, + new UsernamePasswordCredentials("elastic", "changeme")); + RestClient client = RestClient + .builder(HttpHost.create(container.getHttpHostAddress())) + .setHttpClientConfigCallback((httpClientBuilder) -> httpClientBuilder + .setDefaultCredentialsProvider(credentialsProvider)) + .build(); + this.elasticsearchRestHealthIndicator = new ElasticsearchRestHealthIndicator( + client); + } + + @Test + public void elasticsearchIsUp() { + Health health = this.elasticsearchRestHealthIndicator.health(); + assertThat(health.getStatus()).isEqualTo(Status.UP); + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicatorTest.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicatorTest.java new file mode 100644 index 000000000000..67caab025a32 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicatorTest.java @@ -0,0 +1,127 @@ +/* + * Copyright 2012-2018 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 + * + * http://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.elasticsearch; + +import java.io.ByteArrayInputStream; +import java.io.IOException; + +import org.apache.http.StatusLine; +import org.apache.http.entity.BasicHttpEntity; +import org.elasticsearch.client.Request; +import org.elasticsearch.client.Response; +import org.elasticsearch.client.RestClient; +import org.junit.Test; + +import org.springframework.boot.actuate.health.Status; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.mock; +import static org.mockito.BDDMockito.when; + +/** + * Tests for {@link ElasticsearchRestHealthIndicator}. + * + * @author Artsiom Yudovin + */ +public class ElasticsearchRestHealthIndicatorTest { + + private final RestClient restClient = mock(RestClient.class); + + private final ElasticsearchRestHealthIndicator elasticsearchRestHealthIndicator = new ElasticsearchRestHealthIndicator( + this.restClient); + + @Test + public void elasticsearchIsUp() throws IOException { + BasicHttpEntity httpEntity = new BasicHttpEntity(); + httpEntity.setContent( + new ByteArrayInputStream(createJsonResult(200, "green").getBytes())); + + Response response = mock(Response.class); + StatusLine statusLine = mock(StatusLine.class); + + when(statusLine.getStatusCode()).thenReturn(200); + when(response.getStatusLine()).thenReturn(statusLine); + when(response.getEntity()).thenReturn(httpEntity); + when(this.restClient.performRequest(any(Request.class))).thenReturn(response); + + assertThat(this.elasticsearchRestHealthIndicator.health().getStatus()) + .isEqualTo(Status.UP); + } + + @Test + public void elasticsearchIsDown() throws IOException { + when(this.restClient.performRequest(any(Request.class))) + .thenThrow(new IOException("Couldn't connect")); + + assertThat(this.elasticsearchRestHealthIndicator.health().getStatus()) + .isEqualTo(Status.DOWN); + } + + @Test + public void elasticsearchIsDownByResponseCode() throws IOException { + + Response response = mock(Response.class); + StatusLine statusLine = mock(StatusLine.class); + + when(statusLine.getStatusCode()).thenReturn(500); + when(response.getStatusLine()).thenReturn(statusLine); + when(this.restClient.performRequest(any(Request.class))).thenReturn(response); + + assertThat(this.elasticsearchRestHealthIndicator.health().getStatus()) + .isEqualTo(Status.DOWN); + } + + @Test + public void elasticsearchIsOutOfServiceByStatus() throws IOException { + BasicHttpEntity httpEntity = new BasicHttpEntity(); + httpEntity.setContent( + new ByteArrayInputStream(createJsonResult(200, "red").getBytes())); + + Response response = mock(Response.class); + StatusLine statusLine = mock(StatusLine.class); + + when(statusLine.getStatusCode()).thenReturn(200); + when(response.getStatusLine()).thenReturn(statusLine); + when(response.getEntity()).thenReturn(httpEntity); + when(this.restClient.performRequest(any(Request.class))).thenReturn(response); + + assertThat(this.elasticsearchRestHealthIndicator.health().getStatus()) + .isEqualTo(Status.OUT_OF_SERVICE); + } + + private String createJsonResult(int responseCode, String status) { + String json; + if (responseCode == 200) { + json = String.format("{\"cluster_name\":\"elasticsearch\"," + + "\"status\":\"%s\",\"timed_out\":false,\"number_of_nodes\":1," + + "\"number_of_data_nodes\":1,\"active_primary_shards\":0," + + "\"active_shards\":0,\"relocating_shards\":0,\"initializing_shards\":0," + + "\"unassigned_shards\":0,\"delayed_unassigned_shards\":0," + + "\"number_of_pending_tasks\":0,\"number_of_in_flight_fetch\":0," + + "\"task_max_waiting_in_queue_millis\":0,\"active_shards_percent_as_number\":100.0}", + status); + } + else { + json = "{\n" + " \"error\": \"Server Error\",\n" + " \"status\": " + + responseCode + "\n" + "}"; + } + + return json; + } + +} From 893478fbafed51dacdcd959335093ca32ff5c406 Mon Sep 17 00:00:00 2001 From: artsiom Date: Tue, 20 Nov 2018 12:53:58 +0300 Subject: [PATCH 4/4] removing testContainer --- .../spring-boot-actuator/pom.xml | 6 -- ...chRestHealthIndicatorIntegrationTests.java | 80 ------------------- 2 files changed, 86 deletions(-) delete mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicatorIntegrationTests.java diff --git a/spring-boot-project/spring-boot-actuator/pom.xml b/spring-boot-project/spring-boot-actuator/pom.xml index 0fa301f14327..392a8cdabf8e 100644 --- a/spring-boot-project/spring-boot-actuator/pom.xml +++ b/spring-boot-project/spring-boot-actuator/pom.xml @@ -343,12 +343,6 @@ jsonassert test - - org.testcontainers - elasticsearch - 1.10.1 - test - diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicatorIntegrationTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicatorIntegrationTests.java deleted file mode 100644 index 5ab62c8b7b3a..000000000000 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/elasticsearch/ElasticsearchRestHealthIndicatorIntegrationTests.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2012-2018 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 - * - * http://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.elasticsearch; - -import org.apache.http.HttpHost; -import org.apache.http.auth.AuthScope; -import org.apache.http.auth.UsernamePasswordCredentials; -import org.apache.http.client.CredentialsProvider; -import org.apache.http.impl.client.BasicCredentialsProvider; -import org.elasticsearch.client.RestClient; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.Test; -import org.testcontainers.elasticsearch.ElasticsearchContainer; - -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.Status; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link ElasticsearchRestHealthIndicator}. - * - * @author Artsiom Yudovin - */ -public class ElasticsearchRestHealthIndicatorIntegrationTests { - - @ClassRule - public static final ElasticsearchContainer container = new ElasticsearchContainer( - "docker.elastic.co/elasticsearch/elasticsearch:6.4.1"); - - private ElasticsearchRestHealthIndicator elasticsearchRestHealthIndicator; - - @BeforeClass - public static void start() { - container.start(); - } - - @AfterClass - public static void stop() { - container.stop(); - } - - @Before - public void initClient() { - final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); - credentialsProvider.setCredentials(AuthScope.ANY, - new UsernamePasswordCredentials("elastic", "changeme")); - RestClient client = RestClient - .builder(HttpHost.create(container.getHttpHostAddress())) - .setHttpClientConfigCallback((httpClientBuilder) -> httpClientBuilder - .setDefaultCredentialsProvider(credentialsProvider)) - .build(); - this.elasticsearchRestHealthIndicator = new ElasticsearchRestHealthIndicator( - client); - } - - @Test - public void elasticsearchIsUp() { - Health health = this.elasticsearchRestHealthIndicator.health(); - assertThat(health.getStatus()).isEqualTo(Status.UP); - } - -}