Sfoglia il codice sorgente

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.
javanna 9 anni fa
parent
commit
9c4a5bbe7e

+ 29 - 45
core/src/main/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsNodes.java

@@ -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;
         }
     }

+ 1 - 2
core/src/main/java/org/elasticsearch/rest/action/admin/cluster/stats/RestClusterStatsAction.java

@@ -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));
     }
 }

+ 50 - 22
core/src/test/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsIT.java

@@ -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);
-
-        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);
-
-        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);
-
-        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);
+        assertCounts(response.getNodesStats().getCounts(), total, expectedCounts);
+
+        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);
+
+            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);
+            }
+
+            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));

+ 4 - 4
docs/reference/cluster/stats.asciidoc

@@ -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}"

+ 26 - 0
rest-api-spec/src/main/resources/rest-api-spec/test/cluster.stats/10_basic.yaml

@@ -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