Use cluster endpoint in Jest HealthIndicator

This commit changes the requested endpoint for the Jest
HealthIndicator. The `"/_all/_stats"` was previously used, but
the response size can be quite large and costly.

This is now using the `"/_cluster/health"` endpoint.
This commit is contained in:
Julian Devia 2018-10-20 12:15:47 -05:00 committed by Brian Clozel
parent 1341789819
commit 3e6a4eb6e3
2 changed files with 41 additions and 13 deletions

View File

@ -17,11 +17,9 @@
package org.springframework.boot.actuate.elasticsearch;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import io.searchbox.client.JestClient;
import io.searchbox.client.JestResult;
import io.searchbox.indices.Stats;
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
import org.springframework.boot.actuate.health.Health;
@ -31,6 +29,7 @@ import org.springframework.boot.actuate.health.HealthIndicator;
* {@link HealthIndicator} for Elasticsearch using a {@link JestClient}.
*
* @author Stephane Nicoll
* @author Julian Devia Serna
* @since 2.0.0
*/
public class ElasticsearchJestHealthIndicator extends AbstractHealthIndicator {
@ -46,11 +45,12 @@ public class ElasticsearchJestHealthIndicator extends AbstractHealthIndicator {
@Override
protected void doHealthCheck(Health.Builder builder) throws Exception {
JestResult aliases = this.jestClient.execute(new Stats.Builder().build());
JsonElement root = this.jsonParser.parse(aliases.getJsonString());
JsonObject shards = root.getAsJsonObject().get("_shards").getAsJsonObject();
int failedShards = shards.get("failed").getAsInt();
if (failedShards != 0) {
JestResult healthResult = this.jestClient
.execute(new io.searchbox.cluster.Health.Builder().build());
JsonElement root = this.jsonParser.parse(healthResult.getJsonString());
JsonElement status = root.getAsJsonObject().get("status");
if (!healthResult.isSucceeded() || healthResult.getResponseCode() != 200 || status
.getAsString().equals(io.searchbox.cluster.Health.Status.RED.getKey())) {
builder.outOfService();
}
else {

View File

@ -39,6 +39,7 @@ import static org.mockito.Mockito.mock;
* Tests for {@link ElasticsearchJestHealthIndicator}.
*
* @author Stephane Nicoll
* @author Julian Devia Serna
*/
public class ElasticsearchJestHealthIndicatorTests {
@ -51,7 +52,7 @@ public class ElasticsearchJestHealthIndicatorTests {
@Test
public void elasticsearchIsUp() throws IOException {
given(this.jestClient.execute(any(Action.class)))
.willReturn(createJestResult(4, 0));
.willReturn(createJestResult("green", 200, true));
Health health = this.healthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.UP);
}
@ -67,19 +68,46 @@ public class ElasticsearchJestHealthIndicatorTests {
@SuppressWarnings("unchecked")
@Test
public void elasticsearchIsOutOfService() throws IOException {
public void elasticsearchIsOutOfServiceByStatus() throws IOException {
given(this.jestClient.execute(any(Action.class)))
.willReturn(createJestResult(4, 1));
.willReturn(createJestResult("red", 200, true));
Health health = this.healthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.OUT_OF_SERVICE);
}
private static JestResult createJestResult(int shards, int failedShards) {
String json = String.format("{_shards: {\n" + "total: %s,\n" + "successful: %s,\n"
+ "failed: %s\n" + "}}", shards, shards - failedShards, failedShards);
@SuppressWarnings("unchecked")
@Test
public void elasticsearchIsOutOfServiceByResponseCode() throws IOException {
given(this.jestClient.execute(any(Action.class)))
.willReturn(createJestResult("", 500, true));
Health health = this.healthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.OUT_OF_SERVICE);
}
@SuppressWarnings("unchecked")
@Test
public void elasticsearchIsOutOfServiceBySucceeded() throws IOException {
given(this.jestClient.execute(any(Action.class)))
.willReturn(createJestResult("red", 500, false));
Health health = this.healthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.OUT_OF_SERVICE);
}
private static JestResult createJestResult(String status, int responseCode,
boolean succeeded) {
String json = String.format("{\"cluster_name\":\"docker-cluster\","
+ "\"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);
SearchResult searchResult = new SearchResult(new Gson());
searchResult.setJsonString(json);
searchResult.setJsonObject(new JsonParser().parse(json).getAsJsonObject());
searchResult.setResponseCode(responseCode);
searchResult.setSucceeded(succeeded);
return searchResult;
}