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:
parent
f786e9866c
commit
9c4a5bbe7e
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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}"
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue