Skip to content

Commit

Permalink
Update GET _cluster/health response to distinguish RED cluster from n…
Browse files Browse the repository at this point in the history
…o-master (elastic#34897)

Added boolean "discovered_master": true in the GET _cluster/health response to expose the presence of master.
  • Loading branch information
getsaurabh02 committed May 8, 2019
1 parent a967dde commit 443f631
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public class ClusterHealthResponse extends ActionResponse implements StatusToXCo
private static final String TIMED_OUT = "timed_out";
private static final String NUMBER_OF_NODES = "number_of_nodes";
private static final String NUMBER_OF_DATA_NODES = "number_of_data_nodes";
private static final String DISCOVERED_MASTER = "discovered_master";
private static final String NUMBER_OF_PENDING_TASKS = "number_of_pending_tasks";
private static final String NUMBER_OF_IN_FLIGHT_FETCH = "number_of_in_flight_fetch";
private static final String DELAYED_UNASSIGNED_SHARDS = "delayed_unassigned_shards";
Expand All @@ -74,6 +75,7 @@ public class ClusterHealthResponse extends ActionResponse implements StatusToXCo
// ClusterStateHealth fields
int numberOfNodes = (int) parsedObjects[i++];
int numberOfDataNodes = (int) parsedObjects[i++];
boolean hasDiscoveredMaster = (boolean) parsedObjects[i++];
int activeShards = (int) parsedObjects[i++];
int relocatingShards = (int) parsedObjects[i++];
int activePrimaryShards = (int) parsedObjects[i++];
Expand All @@ -93,9 +95,8 @@ public class ClusterHealthResponse extends ActionResponse implements StatusToXCo
}
}
ClusterStateHealth stateHealth = new ClusterStateHealth(activePrimaryShards, activeShards, relocatingShards,
initializingShards, unassignedShards, numberOfNodes, numberOfDataNodes, activeShardsPercent, status,
initializingShards, unassignedShards, numberOfNodes, numberOfDataNodes, hasDiscoveredMaster, activeShardsPercent, status,
indices);

// ClusterHealthResponse fields
String clusterName = (String) parsedObjects[i++];
int numberOfPendingTasks = (int) parsedObjects[i++];
Expand All @@ -114,6 +115,7 @@ public class ClusterHealthResponse extends ActionResponse implements StatusToXCo
// ClusterStateHealth fields
PARSER.declareInt(constructorArg(), new ParseField(NUMBER_OF_NODES));
PARSER.declareInt(constructorArg(), new ParseField(NUMBER_OF_DATA_NODES));
PARSER.declareBoolean(constructorArg(), new ParseField(DISCOVERED_MASTER));
PARSER.declareInt(constructorArg(), new ParseField(ACTIVE_SHARDS));
PARSER.declareInt(constructorArg(), new ParseField(RELOCATING_SHARDS));
PARSER.declareInt(constructorArg(), new ParseField(ACTIVE_PRIMARY_SHARDS));
Expand Down Expand Up @@ -213,6 +215,10 @@ public int getNumberOfDataNodes() {
return clusterStateHealth.getNumberOfDataNodes();
}

public boolean hasDiscoveredMaster() {
return clusterStateHealth.hasDiscoveredMaster();
}

public int getNumberOfPendingTasks() {
return this.numberOfPendingTasks;
}
Expand Down Expand Up @@ -326,6 +332,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
builder.field(TIMED_OUT, isTimedOut());
builder.field(NUMBER_OF_NODES, getNumberOfNodes());
builder.field(NUMBER_OF_DATA_NODES, getNumberOfDataNodes());
builder.field(DISCOVERED_MASTER, hasDiscoveredMaster());
builder.field(ACTIVE_PRIMARY_SHARDS, getActivePrimaryShards());
builder.field(ACTIVE_SHARDS, getActiveShards());
builder.field(RELOCATING_SHARDS, getRelocatingShards());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public final class ClusterStateHealth implements Iterable<ClusterIndexHealth>, W

private final int numberOfNodes;
private final int numberOfDataNodes;
private final boolean hasDiscoveredMaster;
private final int activeShards;
private final int relocatingShards;
private final int activePrimaryShards;
Expand Down Expand Up @@ -67,6 +68,7 @@ public ClusterStateHealth(final ClusterState clusterState) {
public ClusterStateHealth(final ClusterState clusterState, final String[] concreteIndices) {
numberOfNodes = clusterState.nodes().getSize();
numberOfDataNodes = clusterState.nodes().getDataNodes().size();
hasDiscoveredMaster = clusterState.nodes().getMasterNodeId() != null;
indices = new HashMap<>();
for (String index : concreteIndices) {
IndexRoutingTable indexRoutingTable = clusterState.routingTable().index(index);
Expand Down Expand Up @@ -134,6 +136,7 @@ public ClusterStateHealth(final StreamInput in) throws IOException {
unassignedShards = in.readVInt();
numberOfNodes = in.readVInt();
numberOfDataNodes = in.readVInt();
hasDiscoveredMaster = in.readBoolean();
status = ClusterHealthStatus.fromValue(in.readByte());
int size = in.readVInt();
indices = new HashMap<>(size);
Expand All @@ -148,7 +151,7 @@ public ClusterStateHealth(final StreamInput in) throws IOException {
* For ClusterHealthResponse's XContent Parser
*/
public ClusterStateHealth(int activePrimaryShards, int activeShards, int relocatingShards, int initializingShards, int unassignedShards,
int numberOfNodes, int numberOfDataNodes, double activeShardsPercent, ClusterHealthStatus status,
int numberOfNodes, int numberOfDataNodes, boolean hasDiscoveredMaster, double activeShardsPercent, ClusterHealthStatus status,
Map<String, ClusterIndexHealth> indices) {
this.activePrimaryShards = activePrimaryShards;
this.activeShards = activeShards;
Expand All @@ -157,6 +160,7 @@ public ClusterStateHealth(int activePrimaryShards, int activeShards, int relocat
this.unassignedShards = unassignedShards;
this.numberOfNodes = numberOfNodes;
this.numberOfDataNodes = numberOfDataNodes;
this.hasDiscoveredMaster = hasDiscoveredMaster;
this.activeShardsPercent = activeShardsPercent;
this.status = status;
this.indices = indices;
Expand Down Expand Up @@ -202,6 +206,10 @@ public double getActiveShardsPercent() {
return activeShardsPercent;
}

public boolean hasDiscoveredMaster() {
return hasDiscoveredMaster;
}

@Override
public Iterator<ClusterIndexHealth> iterator() {
return indices.values().iterator();
Expand All @@ -216,6 +224,7 @@ public void writeTo(final StreamOutput out) throws IOException {
out.writeVInt(unassignedShards);
out.writeVInt(numberOfNodes);
out.writeVInt(numberOfDataNodes);
out.writeBoolean(hasDiscoveredMaster);
out.writeByte(status.value());
out.writeVInt(indices.size());
for (ClusterIndexHealth indexHealth : this) {
Expand All @@ -229,6 +238,7 @@ public String toString() {
return "ClusterStateHealth{" +
"numberOfNodes=" + numberOfNodes +
", numberOfDataNodes=" + numberOfDataNodes +
", hasDiscoveredMaster=" + hasDiscoveredMaster +
", activeShards=" + activeShards +
", relocatingShards=" + relocatingShards +
", activePrimaryShards=" + activePrimaryShards +
Expand All @@ -247,6 +257,7 @@ public boolean equals(Object o) {
ClusterStateHealth that = (ClusterStateHealth) o;
return numberOfNodes == that.numberOfNodes &&
numberOfDataNodes == that.numberOfDataNodes &&
hasDiscoveredMaster == that.hasDiscoveredMaster &&
activeShards == that.activeShards &&
relocatingShards == that.relocatingShards &&
activePrimaryShards == that.activePrimaryShards &&
Expand All @@ -259,7 +270,7 @@ public boolean equals(Object o) {

@Override
public int hashCode() {
return Objects.hash(numberOfNodes, numberOfDataNodes, activeShards, relocatingShards, activePrimaryShards, initializingShards,
return Objects.hash(numberOfNodes, numberOfDataNodes, hasDiscoveredMaster, activeShards, relocatingShards, activePrimaryShards, initializingShards,
unassignedShards, activeShardsPercent, status, indices);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ protected Table getTableWithHeader(final RestRequest request) {
t.addCell("status", "alias:st;desc:health status");
t.addCell("node.total", "alias:nt,nodeTotal;text-align:right;desc:total number of nodes");
t.addCell("node.data", "alias:nd,nodeData;text-align:right;desc:number of nodes that can store data");
t.addCell("discovered_master", "alias:dm;text-align:right;desc:discovered master");
t.addCell("shards", "alias:t,sh,shards.total,shardsTotal;text-align:right;desc:total number of shards");
t.addCell("pri", "alias:p,shards.primary,shardsPrimary;text-align:right;desc:number of primary shards");
t.addCell("relo", "alias:r,shards.relocating,shardsRelocating;text-align:right;desc:number of relocating nodes");
Expand All @@ -89,6 +90,7 @@ private Table buildTable(final ClusterHealthResponse health, final RestRequest r
t.addCell(health.getStatus().name().toLowerCase(Locale.ROOT));
t.addCell(health.getNumberOfNodes());
t.addCell(health.getNumberOfDataNodes());
t.addCell(health.hasDiscoveredMaster());
t.addCell(health.getActiveShards());
t.addCell(health.getActivePrimaryShards());
t.addCell(health.getRelocatingShards());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,16 @@

package org.elasticsearch.action.admin.cluster.health;

import org.elasticsearch.Version;
import org.elasticsearch.cluster.ClusterName;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.health.ClusterHealthStatus;
import org.elasticsearch.cluster.health.ClusterIndexHealth;
import org.elasticsearch.cluster.health.ClusterIndexHealthTests;
import org.elasticsearch.cluster.health.ClusterStateHealth;
import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.node.DiscoveryNodes;
import org.elasticsearch.common.io.stream.BytesStreamOutput;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.settings.Settings;
Expand All @@ -34,13 +37,15 @@
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.test.AbstractStreamableXContentTestCase;
import org.elasticsearch.test.ESTestCase;
import org.hamcrest.Matchers;

import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.EnumSet;
import java.util.function.Predicate;
import java.util.regex.Pattern;

Expand Down Expand Up @@ -81,6 +86,26 @@ public void testClusterHealth() throws IOException {
assertThat(clusterHealth.getActiveShardsPercent(), is(allOf(greaterThanOrEqualTo(0.0), lessThanOrEqualTo(100.0))));
}

public void testClusterHealthVerifyMasterNodeDiscovery() throws IOException {
DiscoveryNode localNode = new DiscoveryNode("node", ESTestCase.buildNewFakeTransportAddress(), Collections.emptyMap(),
EnumSet.allOf(DiscoveryNode.Role.class), Version.CURRENT);
//set the node information to verify master_node discovery in ClusterHealthResponse
ClusterState clusterState = ClusterState.builder(ClusterName.CLUSTER_NAME_SETTING.getDefault(Settings.EMPTY))
.nodes(DiscoveryNodes.builder()
.add(localNode)
.localNodeId(localNode.getId())
.masterNodeId(localNode.getId()))
.build();
int pendingTasks = randomIntBetween(0, 200);
int inFlight = randomIntBetween(0, 200);
int delayedUnassigned = randomIntBetween(0, 200);
TimeValue pendingTaskInQueueTime = TimeValue.timeValueMillis(randomIntBetween(1000, 100000));
ClusterHealthResponse clusterHealth = new ClusterHealthResponse("bla", new String[] {MetaData.ALL}, clusterState, pendingTasks, inFlight, delayedUnassigned, pendingTaskInQueueTime);
clusterHealth = maybeSerialize(clusterHealth);
assertThat(clusterHealth.getClusterStateHealth().hasDiscoveredMaster(), Matchers.equalTo(true));
assertClusterHealth(clusterHealth);
}

private void assertClusterHealth(ClusterHealthResponse clusterHealth) {
ClusterStateHealth clusterStateHealth = clusterHealth.getClusterStateHealth();

Expand All @@ -91,6 +116,7 @@ private void assertClusterHealth(ClusterHealthResponse clusterHealth) {
assertThat(clusterHealth.getUnassignedShards(), Matchers.equalTo(clusterStateHealth.getUnassignedShards()));
assertThat(clusterHealth.getNumberOfNodes(), Matchers.equalTo(clusterStateHealth.getNumberOfNodes()));
assertThat(clusterHealth.getNumberOfDataNodes(), Matchers.equalTo(clusterStateHealth.getNumberOfDataNodes()));
assertThat(clusterHealth.hasDiscoveredMaster(), Matchers.equalTo(clusterStateHealth.hasDiscoveredMaster()));
}

ClusterHealthResponse maybeSerialize(ClusterHealthResponse clusterHealth) throws IOException {
Expand Down Expand Up @@ -124,7 +150,7 @@ protected ClusterHealthResponse createTestInstance() {
}
}
ClusterStateHealth stateHealth = new ClusterStateHealth(randomInt(100), randomInt(100), randomInt(100),
randomInt(100), randomInt(100), randomInt(100), randomInt(100),
randomInt(100), randomInt(100), randomInt(100), randomInt(100), randomBoolean(),
randomDoubleBetween(0d, 100d, true), randomFrom(ClusterHealthStatus.values()), indices);

return new ClusterHealthResponse(randomAlphaOfLengthBetween(1, 10), randomInt(100), randomInt(100), randomInt(100),
Expand Down Expand Up @@ -189,7 +215,7 @@ protected ClusterHealthResponse mutateInstance(ClusterHealthResponse instance) {
ClusterStateHealth state = instance.getClusterStateHealth();
ClusterStateHealth newState = new ClusterStateHealth(state.getActivePrimaryShards() + between(1, 10),
state.getActiveShards(), state.getRelocatingShards(), state.getInitializingShards(), state.getUnassignedShards(),
state.getNumberOfNodes(), state.getNumberOfDataNodes(), state.getActiveShardsPercent(), state.getStatus(),
state.getNumberOfNodes(), state.getNumberOfDataNodes(), state.hasDiscoveredMaster(), state.getActiveShardsPercent(), state.getStatus(),
state.getIndices());
return new ClusterHealthResponse(instance.getClusterName(),
instance.getNumberOfPendingTasks(), instance.getNumberOfInFlightFetch(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,13 +173,15 @@ public void testClusterHealth() throws IOException {
ClusterState clusterState = ClusterState.builder(ClusterName.CLUSTER_NAME_SETTING.getDefault(Settings.EMPTY))
.metaData(metaData)
.routingTable(routingTable.build())
.nodes(clusterService.state().nodes())
.build();
String[] concreteIndices = indexNameExpressionResolver.concreteIndexNames(
clusterState, IndicesOptions.strictExpand(), (String[]) null
);
ClusterStateHealth clusterStateHealth = new ClusterStateHealth(clusterState, concreteIndices);
logger.info("cluster status: {}, expected {}", clusterStateHealth.getStatus(), counter.status());
clusterStateHealth = maybeSerialize(clusterStateHealth);
assertThat(clusterStateHealth.hasDiscoveredMaster(), equalTo(clusterService.state().nodes().getMasterNodeId() != null));
assertClusterHealth(clusterStateHealth, counter);
}

Expand Down

0 comments on commit 443f631

Please sign in to comment.