Move XContent Rendering and Cluster Health Status calculations to ClusterHealthResponse
This commit is contained in:
parent
d5192ecd31
commit
17e7d01753
|
@ -22,12 +22,21 @@ package org.elasticsearch.action.admin.cluster.health;
|
|||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Maps;
|
||||
import org.elasticsearch.action.ActionResponse;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.cluster.routing.IndexRoutingTable;
|
||||
import org.elasticsearch.cluster.routing.RoutingTableValidation;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilderString;
|
||||
import org.elasticsearch.rest.RestStatus;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.google.common.collect.Lists.newArrayList;
|
||||
|
@ -36,7 +45,7 @@ import static org.elasticsearch.action.admin.cluster.health.ClusterIndexHealth.r
|
|||
/**
|
||||
*
|
||||
*/
|
||||
public class ClusterHealthResponse extends ActionResponse implements Iterable<ClusterIndexHealth> {
|
||||
public class ClusterHealthResponse extends ActionResponse implements Iterable<ClusterIndexHealth>, ToXContent {
|
||||
|
||||
private String clusterName;
|
||||
int numberOfNodes = 0;
|
||||
|
@ -59,6 +68,48 @@ public class ClusterHealthResponse extends ActionResponse implements Iterable<Cl
|
|||
this.validationFailures = validationFailures;
|
||||
}
|
||||
|
||||
public ClusterHealthResponse(String clusterName, String[] concreteIndices, ClusterState clusterState) {
|
||||
this.clusterName = clusterName;
|
||||
RoutingTableValidation validation = clusterState.routingTable().validate(clusterState.metaData());
|
||||
validationFailures = validation.failures();
|
||||
numberOfNodes = clusterState.nodes().size();
|
||||
numberOfDataNodes = clusterState.nodes().dataNodes().size();
|
||||
|
||||
for (String index : concreteIndices) {
|
||||
IndexRoutingTable indexRoutingTable = clusterState.routingTable().index(index);
|
||||
IndexMetaData indexMetaData = clusterState.metaData().index(index);
|
||||
if (indexRoutingTable == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ClusterIndexHealth indexHealth = new ClusterIndexHealth(indexMetaData, indexRoutingTable);
|
||||
|
||||
indices.put(indexHealth.getIndex(), indexHealth);
|
||||
}
|
||||
|
||||
status = ClusterHealthStatus.GREEN;
|
||||
|
||||
for (ClusterIndexHealth indexHealth : indices.values()) {
|
||||
activePrimaryShards += indexHealth.activePrimaryShards;
|
||||
activeShards += indexHealth.activeShards;
|
||||
relocatingShards += indexHealth.relocatingShards;
|
||||
initializingShards += indexHealth.initializingShards;
|
||||
unassignedShards += indexHealth.unassignedShards;
|
||||
if (indexHealth.getStatus() == ClusterHealthStatus.RED) {
|
||||
status = ClusterHealthStatus.RED;
|
||||
break;
|
||||
} else if (indexHealth.getStatus() == ClusterHealthStatus.YELLOW && status != ClusterHealthStatus.RED) {
|
||||
status = ClusterHealthStatus.YELLOW;
|
||||
}
|
||||
}
|
||||
|
||||
if (!validationFailures.isEmpty()) {
|
||||
status = ClusterHealthStatus.RED;
|
||||
} else if (clusterState.blocks().hasGlobalBlock(RestStatus.SERVICE_UNAVAILABLE)) {
|
||||
status = ClusterHealthStatus.RED;
|
||||
}
|
||||
}
|
||||
|
||||
public String getClusterName() {
|
||||
return clusterName;
|
||||
}
|
||||
|
@ -201,4 +252,73 @@ public class ClusterHealthResponse extends ActionResponse implements Iterable<Cl
|
|||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
static final class Fields {
|
||||
static final XContentBuilderString CLUSTER_NAME = new XContentBuilderString("cluster_name");
|
||||
static final XContentBuilderString STATUS = new XContentBuilderString("status");
|
||||
static final XContentBuilderString TIMED_OUT = new XContentBuilderString("timed_out");
|
||||
static final XContentBuilderString NUMBER_OF_NODES = new XContentBuilderString("number_of_nodes");
|
||||
static final XContentBuilderString NUMBER_OF_DATA_NODES = new XContentBuilderString("number_of_data_nodes");
|
||||
static final XContentBuilderString ACTIVE_PRIMARY_SHARDS = new XContentBuilderString("active_primary_shards");
|
||||
static final XContentBuilderString ACTIVE_SHARDS = new XContentBuilderString("active_shards");
|
||||
static final XContentBuilderString RELOCATING_SHARDS = new XContentBuilderString("relocating_shards");
|
||||
static final XContentBuilderString INITIALIZING_SHARDS = new XContentBuilderString("initializing_shards");
|
||||
static final XContentBuilderString UNASSIGNED_SHARDS = new XContentBuilderString("unassigned_shards");
|
||||
static final XContentBuilderString VALIDATION_FAILURES = new XContentBuilderString("validation_failures");
|
||||
static final XContentBuilderString INDICES = new XContentBuilderString("indices");
|
||||
}
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.field(Fields.CLUSTER_NAME, getClusterName());
|
||||
builder.field(Fields.STATUS, getStatus().name().toLowerCase(Locale.ROOT));
|
||||
builder.field(Fields.TIMED_OUT, isTimedOut());
|
||||
builder.field(Fields.NUMBER_OF_NODES, getNumberOfNodes());
|
||||
builder.field(Fields.NUMBER_OF_DATA_NODES, getNumberOfDataNodes());
|
||||
builder.field(Fields.ACTIVE_PRIMARY_SHARDS, getActivePrimaryShards());
|
||||
builder.field(Fields.ACTIVE_SHARDS, getActiveShards());
|
||||
builder.field(Fields.RELOCATING_SHARDS, getRelocatingShards());
|
||||
builder.field(Fields.INITIALIZING_SHARDS, getInitializingShards());
|
||||
builder.field(Fields.UNASSIGNED_SHARDS, getUnassignedShards());
|
||||
|
||||
String level = params.param("level", "cluster");
|
||||
boolean outputIndices = "indices".equals(level) || "shards".equals(level);
|
||||
|
||||
|
||||
if (!getValidationFailures().isEmpty()) {
|
||||
builder.startArray(Fields.VALIDATION_FAILURES);
|
||||
for (String validationFailure : getValidationFailures()) {
|
||||
builder.value(validationFailure);
|
||||
}
|
||||
// if we don't print index level information, still print the index validation failures
|
||||
// so we know why the status is red
|
||||
if (!outputIndices) {
|
||||
for (ClusterIndexHealth indexHealth : indices.values()) {
|
||||
builder.startObject(indexHealth.getIndex());
|
||||
|
||||
if (!indexHealth.getValidationFailures().isEmpty()) {
|
||||
builder.startArray(Fields.VALIDATION_FAILURES);
|
||||
for (String validationFailure : indexHealth.getValidationFailures()) {
|
||||
builder.value(validationFailure);
|
||||
}
|
||||
builder.endArray();
|
||||
}
|
||||
|
||||
builder.endObject();
|
||||
}
|
||||
}
|
||||
builder.endArray();
|
||||
}
|
||||
|
||||
if (outputIndices) {
|
||||
builder.startObject(Fields.INDICES);
|
||||
for (ClusterIndexHealth indexHealth : indices.values()) {
|
||||
builder.startObject(indexHealth.getIndex(), XContentBuilder.FieldCaseConversion.NONE);
|
||||
indexHealth.toXContent(builder, params);
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,13 +70,6 @@ public class ClusterIndexHealth implements Iterable<ClusterShardHealth>, Streama
|
|||
private ClusterIndexHealth() {
|
||||
}
|
||||
|
||||
public ClusterIndexHealth(String index, int numberOfShards, int numberOfReplicas, List<String> validationFailures) {
|
||||
this.index = index;
|
||||
this.numberOfShards = numberOfShards;
|
||||
this.numberOfReplicas = numberOfReplicas;
|
||||
this.validationFailures = validationFailures;
|
||||
}
|
||||
|
||||
public ClusterIndexHealth(IndexMetaData indexMetaData, IndexRoutingTable indexRoutingTable) {
|
||||
this.index = indexMetaData.index();
|
||||
this.numberOfShards = indexMetaData.getNumberOfShards();
|
||||
|
@ -277,7 +270,7 @@ public class ClusterIndexHealth implements Iterable<ClusterShardHealth>, Streama
|
|||
builder.endArray();
|
||||
}
|
||||
|
||||
if (params.paramAsBoolean("output_shards", false)) {
|
||||
if ("shards".equals(params.param("level", "indices"))) {
|
||||
builder.startObject(Fields.SHARDS);
|
||||
|
||||
for (ClusterShardHealth shardHealth : shards.values()) {
|
||||
|
|
|
@ -26,13 +26,10 @@ import org.elasticsearch.cluster.ClusterName;
|
|||
import org.elasticsearch.cluster.ClusterService;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.cluster.ProcessedClusterStateUpdateTask;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.cluster.routing.IndexRoutingTable;
|
||||
import org.elasticsearch.cluster.routing.RoutingTableValidation;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.indices.IndexMissingException;
|
||||
import org.elasticsearch.rest.RestStatus;
|
||||
import org.elasticsearch.threadpool.ThreadPool;
|
||||
import org.elasticsearch.transport.TransportService;
|
||||
|
||||
|
@ -226,54 +223,16 @@ public class TransportClusterHealthAction extends TransportMasterNodeOperationAc
|
|||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Calculating health based on state version [{}]", clusterState.version());
|
||||
}
|
||||
RoutingTableValidation validation = clusterState.routingTable().validate(clusterState.metaData());
|
||||
ClusterHealthResponse response = new ClusterHealthResponse(clusterName.value(), validation.failures());
|
||||
response.numberOfNodes = clusterState.nodes().size();
|
||||
response.numberOfDataNodes = clusterState.nodes().dataNodes().size();
|
||||
|
||||
String[] concreteIndices;
|
||||
try {
|
||||
concreteIndices = clusterState.metaData().concreteIndicesIgnoreMissing(request.indices());
|
||||
} catch (IndexMissingException e) {
|
||||
// one of the specified indices is not there - treat it as RED.
|
||||
ClusterHealthResponse response = new ClusterHealthResponse(clusterName.value(), Strings.EMPTY_ARRAY, clusterState);
|
||||
response.status = ClusterHealthStatus.RED;
|
||||
return response;
|
||||
}
|
||||
for (String index : concreteIndices) {
|
||||
IndexRoutingTable indexRoutingTable = clusterState.routingTable().index(index);
|
||||
IndexMetaData indexMetaData = clusterState.metaData().index(index);
|
||||
if (indexRoutingTable == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ClusterIndexHealth indexHealth = new ClusterIndexHealth(indexMetaData, indexRoutingTable);
|
||||
|
||||
response.indices.put(indexHealth.getIndex(), indexHealth);
|
||||
}
|
||||
|
||||
for (ClusterIndexHealth indexHealth : response) {
|
||||
response.activePrimaryShards += indexHealth.activePrimaryShards;
|
||||
response.activeShards += indexHealth.activeShards;
|
||||
response.relocatingShards += indexHealth.relocatingShards;
|
||||
response.initializingShards += indexHealth.initializingShards;
|
||||
response.unassignedShards += indexHealth.unassignedShards;
|
||||
}
|
||||
|
||||
response.status = ClusterHealthStatus.GREEN;
|
||||
if (!response.getValidationFailures().isEmpty()) {
|
||||
response.status = ClusterHealthStatus.RED;
|
||||
} else if (clusterState.blocks().hasGlobalBlock(RestStatus.SERVICE_UNAVAILABLE)) {
|
||||
response.status = ClusterHealthStatus.RED;
|
||||
} else {
|
||||
for (ClusterIndexHealth indexHealth : response) {
|
||||
if (indexHealth.getStatus() == ClusterHealthStatus.RED) {
|
||||
response.status = ClusterHealthStatus.RED;
|
||||
break;
|
||||
}
|
||||
if (indexHealth.getStatus() == ClusterHealthStatus.YELLOW) {
|
||||
response.status = ClusterHealthStatus.YELLOW;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return response;
|
||||
return new ClusterHealthResponse(clusterName.value(), concreteIndices, clusterState);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,25 +19,20 @@
|
|||
|
||||
package org.elasticsearch.rest.action.admin.cluster.health;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.action.admin.cluster.health.ClusterHealthRequest;
|
||||
import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse;
|
||||
import org.elasticsearch.action.admin.cluster.health.ClusterHealthStatus;
|
||||
import org.elasticsearch.action.admin.cluster.health.ClusterIndexHealth;
|
||||
import org.elasticsearch.client.Client;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilderString;
|
||||
import org.elasticsearch.rest.*;
|
||||
import org.elasticsearch.rest.action.support.RestXContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.client.Requests.clusterHealthRequest;
|
||||
import static org.elasticsearch.rest.RestStatus.PRECONDITION_FAILED;
|
||||
|
@ -47,8 +42,6 @@ import static org.elasticsearch.rest.RestStatus.PRECONDITION_FAILED;
|
|||
*/
|
||||
public class RestClusterHealthAction extends BaseRestHandler {
|
||||
|
||||
private static final Map<String, String> SHARD_LEVEL_PARAMS = ImmutableMap.of("output_shards", "true");
|
||||
|
||||
@Inject
|
||||
public RestClusterHealthAction(Settings settings, Client client, RestController controller) {
|
||||
super(settings, client);
|
||||
|
@ -62,7 +55,6 @@ public class RestClusterHealthAction extends BaseRestHandler {
|
|||
ClusterHealthRequest clusterHealthRequest = clusterHealthRequest(Strings.splitStringByCommaToArray(request.param("index")));
|
||||
clusterHealthRequest.local(request.paramAsBoolean("local", clusterHealthRequest.local()));
|
||||
clusterHealthRequest.listenerThreaded(false);
|
||||
int level = 0;
|
||||
try {
|
||||
clusterHealthRequest.masterNodeTimeout(request.paramAsTime("master_timeout", clusterHealthRequest.masterNodeTimeout()));
|
||||
clusterHealthRequest.timeout(request.paramAsTime("timeout", clusterHealthRequest.timeout()));
|
||||
|
@ -73,16 +65,6 @@ public class RestClusterHealthAction extends BaseRestHandler {
|
|||
clusterHealthRequest.waitForRelocatingShards(request.paramAsInt("wait_for_relocating_shards", clusterHealthRequest.waitForRelocatingShards()));
|
||||
clusterHealthRequest.waitForActiveShards(request.paramAsInt("wait_for_active_shards", clusterHealthRequest.waitForActiveShards()));
|
||||
clusterHealthRequest.waitForNodes(request.param("wait_for_nodes", clusterHealthRequest.waitForNodes()));
|
||||
String sLevel = request.param("level");
|
||||
if (sLevel != null) {
|
||||
if ("cluster".equals(sLevel)) {
|
||||
level = 0;
|
||||
} else if ("indices".equals(sLevel)) {
|
||||
level = 1;
|
||||
} else if ("shards".equals(sLevel)) {
|
||||
level = 2;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
XContentBuilder builder = RestXContentBuilder.restContentBuilder(request);
|
||||
|
@ -92,7 +74,7 @@ public class RestClusterHealthAction extends BaseRestHandler {
|
|||
}
|
||||
return;
|
||||
}
|
||||
final int fLevel = level;
|
||||
|
||||
client.admin().cluster().health(clusterHealthRequest, new ActionListener<ClusterHealthResponse>() {
|
||||
@Override
|
||||
public void onResponse(ClusterHealthResponse response) {
|
||||
|
@ -105,61 +87,7 @@ public class RestClusterHealthAction extends BaseRestHandler {
|
|||
//}
|
||||
XContentBuilder builder = RestXContentBuilder.restContentBuilder(request);
|
||||
builder.startObject();
|
||||
|
||||
builder.field(Fields.CLUSTER_NAME, response.getClusterName());
|
||||
builder.field(Fields.STATUS, response.getStatus().name().toLowerCase(Locale.ROOT));
|
||||
builder.field(Fields.TIMED_OUT, response.isTimedOut());
|
||||
builder.field(Fields.NUMBER_OF_NODES, response.getNumberOfNodes());
|
||||
builder.field(Fields.NUMBER_OF_DATA_NODES, response.getNumberOfDataNodes());
|
||||
builder.field(Fields.ACTIVE_PRIMARY_SHARDS, response.getActivePrimaryShards());
|
||||
builder.field(Fields.ACTIVE_SHARDS, response.getActiveShards());
|
||||
builder.field(Fields.RELOCATING_SHARDS, response.getRelocatingShards());
|
||||
builder.field(Fields.INITIALIZING_SHARDS, response.getInitializingShards());
|
||||
builder.field(Fields.UNASSIGNED_SHARDS, response.getUnassignedShards());
|
||||
|
||||
if (!response.getValidationFailures().isEmpty()) {
|
||||
builder.startArray(Fields.VALIDATION_FAILURES);
|
||||
for (String validationFailure : response.getValidationFailures()) {
|
||||
builder.value(validationFailure);
|
||||
}
|
||||
// if we don't print index level information, still print the index validation failures
|
||||
// so we know why the status is red
|
||||
if (fLevel == 0) {
|
||||
for (ClusterIndexHealth indexHealth : response) {
|
||||
builder.startObject(indexHealth.getIndex());
|
||||
|
||||
if (!indexHealth.getValidationFailures().isEmpty()) {
|
||||
builder.startArray(Fields.VALIDATION_FAILURES);
|
||||
for (String validationFailure : indexHealth.getValidationFailures()) {
|
||||
builder.value(validationFailure);
|
||||
}
|
||||
builder.endArray();
|
||||
}
|
||||
|
||||
builder.endObject();
|
||||
}
|
||||
}
|
||||
builder.endArray();
|
||||
}
|
||||
|
||||
if (fLevel > 0) {
|
||||
builder.startObject(Fields.INDICES);
|
||||
for (ClusterIndexHealth indexHealth : response) {
|
||||
builder.startObject(indexHealth.getIndex(), XContentBuilder.FieldCaseConversion.NONE);
|
||||
|
||||
ToXContent.Params params;
|
||||
if (fLevel > 1) {
|
||||
params = new ToXContent.DelegatingMapParams(SHARD_LEVEL_PARAMS, request);
|
||||
} else {
|
||||
params = request;
|
||||
}
|
||||
indexHealth.toXContent(builder, params);
|
||||
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
|
||||
response.toXContent(builder, request);
|
||||
builder.endObject();
|
||||
|
||||
channel.sendResponse(new XContentRestResponse(request, status, builder));
|
||||
|
@ -178,19 +106,4 @@ public class RestClusterHealthAction extends BaseRestHandler {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
static final class Fields {
|
||||
static final XContentBuilderString CLUSTER_NAME = new XContentBuilderString("cluster_name");
|
||||
static final XContentBuilderString STATUS = new XContentBuilderString("status");
|
||||
static final XContentBuilderString TIMED_OUT = new XContentBuilderString("timed_out");
|
||||
static final XContentBuilderString NUMBER_OF_NODES = new XContentBuilderString("number_of_nodes");
|
||||
static final XContentBuilderString NUMBER_OF_DATA_NODES = new XContentBuilderString("number_of_data_nodes");
|
||||
static final XContentBuilderString ACTIVE_PRIMARY_SHARDS = new XContentBuilderString("active_primary_shards");
|
||||
static final XContentBuilderString ACTIVE_SHARDS = new XContentBuilderString("active_shards");
|
||||
static final XContentBuilderString RELOCATING_SHARDS = new XContentBuilderString("relocating_shards");
|
||||
static final XContentBuilderString INITIALIZING_SHARDS = new XContentBuilderString("initializing_shards");
|
||||
static final XContentBuilderString UNASSIGNED_SHARDS = new XContentBuilderString("unassigned_shards");
|
||||
static final XContentBuilderString VALIDATION_FAILURES = new XContentBuilderString("validation_failures");
|
||||
static final XContentBuilderString INDICES = new XContentBuilderString("indices");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue