adapt cluster stats api to node.client setting removal

The cluster stats api now returns counts for each node role. The `master_data`, `master_only`, `data_only` and `client` fields have been removed from the response in favour of `master`, `data`, `ingest` and `coordinating_only`. The same node can have multiple roles, hence contribute to multiple roles counts. Every node is implicitly a coordinating node, so whenever a node has no explicit roles, it will be counted as coordinating only.
This commit is contained in:
javanna 2016-03-04 14:15:49 +01:00 committed by Luca Cavanna
parent f786e9866c
commit 9c4a5bbe7e
5 changed files with 107 additions and 70 deletions

View File

@ -41,7 +41,9 @@ import org.elasticsearch.plugins.PluginInfo;
import java.io.IOException;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class ClusterStatsNodes implements ToXContent, Streamable {
@ -213,25 +215,29 @@ public class ClusterStatsNodes implements ToXContent, Streamable {
}
public static class Counts implements Streamable, ToXContent {
int total;
int masterOnly;
int dataOnly;
int masterData;
int client;
static final String COORDINATING_ONLY = "coordinating_only";
private int total;
private Map<String, Integer> roles;
Counts() {
roles = new HashMap<>();
for (DiscoveryNode.Role role : DiscoveryNode.Role.values()) {
roles.put(role.getRoleName(), 0);
}
roles.put(COORDINATING_ONLY, 0);
}
public void addNodeInfo(NodeInfo nodeInfo) {
total++;
DiscoveryNode node = nodeInfo.getNode();
if (node.masterNode()) {
if (node.dataNode()) {
masterData++;
} else {
masterOnly++;
if (nodeInfo.getNode().getRoles().size() == 0) {
Integer count = roles.get(COORDINATING_ONLY);
roles.put(COORDINATING_ONLY, ++count);
} else {
for (DiscoveryNode.Role role : nodeInfo.getNode().getRoles()) {
Integer count = roles.get(role.getRoleName());
roles.put(role.getRoleName(), ++count);
}
} else if (node.dataNode()) {
dataOnly++;
} else if (node.clientNode()) {
client++;
}
}
@ -239,20 +245,8 @@ public class ClusterStatsNodes implements ToXContent, Streamable {
return total;
}
public int getMasterOnly() {
return masterOnly;
}
public int getDataOnly() {
return dataOnly;
}
public int getMasterData() {
return masterData;
}
public int getClient() {
return client;
public Map<String, Integer> getRoles() {
return roles;
}
public static Counts readCounts(StreamInput in) throws IOException {
@ -262,38 +256,28 @@ public class ClusterStatsNodes implements ToXContent, Streamable {
}
@Override
@SuppressWarnings("unchecked")
public void readFrom(StreamInput in) throws IOException {
total = in.readVInt();
masterOnly = in.readVInt();
dataOnly = in.readVInt();
masterData = in.readVInt();
client = in.readVInt();
roles = (Map<String, Integer>)in.readGenericValue();
}
@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeVInt(total);
out.writeVInt(masterOnly);
out.writeVInt(dataOnly);
out.writeVInt(masterData);
out.writeVInt(client);
out.writeGenericValue(roles);
}
static final class Fields {
static final XContentBuilderString TOTAL = new XContentBuilderString("total");
static final XContentBuilderString MASTER_ONLY = new XContentBuilderString("master_only");
static final XContentBuilderString DATA_ONLY = new XContentBuilderString("data_only");
static final XContentBuilderString MASTER_DATA = new XContentBuilderString("master_data");
static final XContentBuilderString CLIENT = new XContentBuilderString("client");
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.field(Fields.TOTAL, total);
builder.field(Fields.MASTER_ONLY, masterOnly);
builder.field(Fields.DATA_ONLY, dataOnly);
builder.field(Fields.MASTER_DATA, masterData);
builder.field(Fields.CLIENT, client);
for (Map.Entry<String, Integer> entry : roles.entrySet()) {
builder.field(entry.getKey(), entry.getValue());
}
return builder;
}
}

View File

@ -20,7 +20,6 @@
package org.elasticsearch.rest.action.admin.cluster.stats;
import org.elasticsearch.action.admin.cluster.stats.ClusterStatsRequest;
import org.elasticsearch.action.admin.cluster.stats.ClusterStatsResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
@ -47,6 +46,6 @@ public class RestClusterStatsAction extends BaseRestHandler {
public void handleRequest(final RestRequest request, final RestChannel channel, final Client client) {
ClusterStatsRequest clusterStatsRequest = new ClusterStatsRequest().nodesIds(request.paramAsStringArray("nodeId", null));
clusterStatsRequest.timeout(request.param("timeout"));
client.admin().cluster().clusterStats(clusterStatsRequest, new RestToXContentListener<ClusterStatsResponse>(channel));
client.admin().cluster().clusterStats(clusterStatsRequest, new RestToXContentListener<>(channel));
}
}

View File

@ -23,6 +23,7 @@ import org.elasticsearch.Version;
import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse;
import org.elasticsearch.client.Requests;
import org.elasticsearch.cluster.health.ClusterHealthStatus;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.common.Priority;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.concurrent.EsExecutors;
@ -34,6 +35,8 @@ import org.elasticsearch.test.ESIntegTestCase.Scope;
import org.hamcrest.Matchers;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import static org.elasticsearch.common.settings.Settings.settingsBuilder;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
@ -43,12 +46,9 @@ import static org.hamcrest.Matchers.is;
@ClusterScope(scope = Scope.SUITE, numDataNodes = 1, numClientNodes = 0)
public class ClusterStatsIT extends ESIntegTestCase {
private void assertCounts(ClusterStatsNodes.Counts counts, int total, int masterOnly, int dataOnly, int masterData, int client) {
assertThat(counts.getTotal(), Matchers.equalTo(total));
assertThat(counts.getMasterOnly(), Matchers.equalTo(masterOnly));
assertThat(counts.getDataOnly(), Matchers.equalTo(dataOnly));
assertThat(counts.getMasterData(), Matchers.equalTo(masterData));
assertThat(counts.getClient(), Matchers.equalTo(client));
private void assertCounts(ClusterStatsNodes.Counts counts, int total, Map<String, Integer> roles) {
assertThat(counts.getTotal(), equalTo(total));
assertThat(counts.getRoles(), equalTo(roles));
}
private void waitForNodes(int numNodes) {
@ -58,25 +58,53 @@ public class ClusterStatsIT extends ESIntegTestCase {
}
public void testNodeCounts() {
int total = 1;
Map<String, Integer> expectedCounts = new HashMap<>();
expectedCounts.put(DiscoveryNode.Role.DATA.getRoleName(), 1);
expectedCounts.put(DiscoveryNode.Role.MASTER.getRoleName(), 1);
expectedCounts.put(DiscoveryNode.Role.INGEST.getRoleName(), 1);
expectedCounts.put(ClusterStatsNodes.Counts.COORDINATING_ONLY, 0);
int numNodes = randomIntBetween(1, 5);
ClusterStatsResponse response = client().admin().cluster().prepareClusterStats().get();
assertCounts(response.getNodesStats().getCounts(), 1, 0, 0, 1, 0);
assertCounts(response.getNodesStats().getCounts(), total, expectedCounts);
internalCluster().startNode(Settings.builder().put(Node.NODE_DATA_SETTING.getKey(), false));
waitForNodes(2);
response = client().admin().cluster().prepareClusterStats().get();
assertCounts(response.getNodesStats().getCounts(), 2, 1, 0, 1, 0);
for (int i = 0; i < numNodes; i++) {
boolean isDataNode = randomBoolean();
boolean isMasterNode = randomBoolean();
boolean isIngestNode = randomBoolean();
Settings settings = Settings.builder().put(Node.NODE_DATA_SETTING.getKey(), isDataNode)
.put(Node.NODE_MASTER_SETTING.getKey(), isMasterNode).put(Node.NODE_INGEST_SETTING.getKey(), isIngestNode)
.build();
internalCluster().startNode(settings);
total++;
waitForNodes(total);
internalCluster().startNode(Settings.builder().put(Node.NODE_MASTER_SETTING.getKey(), false));
waitForNodes(3);
response = client().admin().cluster().prepareClusterStats().get();
assertCounts(response.getNodesStats().getCounts(), 3, 1, 1, 1, 0);
if (isDataNode) {
incrementCountForRole(DiscoveryNode.Role.DATA.getRoleName(), expectedCounts);
}
if (isMasterNode) {
incrementCountForRole(DiscoveryNode.Role.MASTER.getRoleName(), expectedCounts);
}
if (isIngestNode) {
incrementCountForRole(DiscoveryNode.Role.INGEST.getRoleName(), expectedCounts);
}
if (!isDataNode && !isMasterNode && !isIngestNode) {
incrementCountForRole(ClusterStatsNodes.Counts.COORDINATING_ONLY, expectedCounts);
}
internalCluster().startNode(Settings.builder().put(Node.NODE_CLIENT_SETTING.getKey(), true));
waitForNodes(4);
response = client().admin().cluster().prepareClusterStats().get();
assertCounts(response.getNodesStats().getCounts(), 4, 1, 1, 1, 1);
response = client().admin().cluster().prepareClusterStats().get();
assertCounts(response.getNodesStats().getCounts(), total, expectedCounts);
}
}
private static void incrementCountForRole(String role, Map<String, Integer> counts) {
Integer count = counts.get(role);
if (count == null) {
counts.put(role, 1);
} else {
counts.put(role, ++count);
}
}
private void assertShardStats(ClusterStatsIndices.ShardStats stats, int indices, int total, int primaries, double replicationFactor) {
assertThat(stats.getIndices(), Matchers.equalTo(indices));

View File

@ -92,10 +92,10 @@ Will return, for example:
"nodes": {
"count": {
"total": 2,
"master_only": 0,
"data_only": 0,
"master_data": 2,
"client": 0
"master": 2,
"data": 2,
"ingest": 2,
"coordinating_only": 0
},
"versions": [
"{version}"

View File

@ -0,0 +1,26 @@
---
"cluster stats test":
- do:
cluster.stats: {}
- is_true: timestamp
- is_true: cluster_name
- match: {status: green}
- gte: { indices.count: 0}
- is_true: indices.docs
- is_true: indices.store
- is_true: indices.fielddata
- is_true: indices.query_cache
- is_true: indices.completion
- is_true: indices.segments
- is_true: indices.percolate
- gte: { nodes.count.total: 1}
- gte: { nodes.count.master: 1}
- gte: { nodes.count.data: 1}
- gte: { nodes.count.ingest: 0}
- gte: { nodes.count.coordinating_only: 0}
- is_true: nodes.os
- is_true: nodes.process
- is_true: nodes.jvm
- is_true: nodes.fs
- is_true: nodes.plugins