Browse Source

Add packaging to cluster stats response (#41048)

This commit adds a packaging_types field to the cluster stats response
that outlines the build flavors and types present in a cluster.
Jason Tedor 6 years ago
parent
commit
57032c0ebb

+ 9 - 2
docs/reference/cluster/stats.asciidoc

@@ -195,13 +195,19 @@ Will return, for example:
       },
       "discovery_types": {
         ...
-      }
+      },
+      "packaging_types": [
+        {
+          ...
+        }
+      ]
    }
 }
 --------------------------------------------------
 // TESTRESPONSE[s/"plugins": \[[^\]]*\]/"plugins": $body.$_path/]
 // TESTRESPONSE[s/"network_types": \{[^\}]*\}/"network_types": $body.$_path/]
 // TESTRESPONSE[s/"discovery_types": \{[^\}]*\}/"discovery_types": $body.$_path/]
+// TESTRESPONSE[s/"packaging_types": \[[^\]]*\]/"packaging_types": $body.$_path/]
 // TESTRESPONSE[s/: true|false/: $body.$_path/]
 // TESTRESPONSE[s/: (\-)?[0-9]+/: $body.$_path/]
 // TESTRESPONSE[s/: "[^"]*"/: $body.$_path/]
@@ -209,7 +215,8 @@ Will return, for example:
 // 1. Ignore the contents of the `plugins` object because we don't know all of
 //    the plugins that will be in it. And because we figure folks don't need to
 //    see an exhaustive list anyway.
-// 2. Similarly, ignore the contents of `network_types` and `discovery_types`.
+// 2. Similarly, ignore the contents of `network_types`, `discovery_types`, and
+//    `packaging_types`.
 // 3. All of the numbers and strings on the right hand side of *every* field in
 //    the response are ignored. So we're really only asserting things about the
 //    the shape of this response, not the values in it.

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

@@ -71,3 +71,15 @@
       cluster.stats: {}
 
   - is_true: nodes.discovery_types
+
+---
+"get cluster stats returns packaging types":
+
+  - skip:
+      version: " - 7.99.99"
+      reason:  "packaging types are added for v8.0.0"
+
+  - do:
+      cluster.stats: {}
+
+  - is_true: nodes.packaging_types

+ 39 - 0
server/src/main/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsNodes.java

@@ -27,6 +27,7 @@ import org.elasticsearch.action.admin.cluster.node.info.NodeInfo;
 import org.elasticsearch.action.admin.cluster.node.stats.NodeStats;
 import org.elasticsearch.cluster.node.DiscoveryNode;
 import org.elasticsearch.common.Strings;
+import org.elasticsearch.common.collect.Tuple;
 import org.elasticsearch.common.network.NetworkModule;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.transport.TransportAddress;
@@ -61,6 +62,7 @@ public class ClusterStatsNodes implements ToXContentFragment {
     private final Set<PluginInfo> plugins;
     private final NetworkTypes networkTypes;
     private final DiscoveryTypes discoveryTypes;
+    private final PackagingTypes packagingTypes;
 
     ClusterStatsNodes(List<ClusterStatsNodeResponse> nodeResponses) {
         this.versions = new HashSet<>();
@@ -93,6 +95,7 @@ public class ClusterStatsNodes implements ToXContentFragment {
         this.jvm = new JvmStats(nodeInfos, nodeStats);
         this.networkTypes = new NetworkTypes(nodeInfos);
         this.discoveryTypes = new DiscoveryTypes(nodeInfos);
+        this.packagingTypes = new PackagingTypes(nodeInfos);
     }
 
     public Counts getCounts() {
@@ -172,6 +175,8 @@ public class ClusterStatsNodes implements ToXContentFragment {
         builder.endObject();
 
         discoveryTypes.toXContent(builder, params);
+
+        packagingTypes.toXContent(builder, params);
         return builder;
     }
 
@@ -650,4 +655,38 @@ public class ClusterStatsNodes implements ToXContentFragment {
         }
     }
 
+    static class PackagingTypes implements ToXContentFragment {
+
+        private final Map<Tuple<String, String>, AtomicInteger> packagingTypes;
+
+        PackagingTypes(final List<NodeInfo> nodeInfos) {
+            final var packagingTypes = new HashMap<Tuple<String, String>, AtomicInteger>();
+            for (final var nodeInfo : nodeInfos) {
+                final var flavor = nodeInfo.getBuild().flavor().displayName();
+                final var type = nodeInfo.getBuild().type().displayName();
+                packagingTypes.computeIfAbsent(Tuple.tuple(flavor, type), k -> new AtomicInteger()).incrementAndGet();
+            }
+            this.packagingTypes = Collections.unmodifiableMap(packagingTypes);
+        }
+
+        @Override
+        public XContentBuilder toXContent(final XContentBuilder builder, final Params params) throws IOException {
+            builder.startArray("packaging_types");
+            {
+                for (final var entry : packagingTypes.entrySet()) {
+                    builder.startObject();
+                    {
+                        builder.field("flavor", entry.getKey().v1());
+                        builder.field("type", entry.getKey().v2());
+                        builder.field("count", entry.getValue().get());
+                    }
+                    builder.endObject();
+                }
+            }
+            builder.endArray();
+            return builder;
+        }
+
+    }
+
 }

+ 14 - 1
x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/collector/cluster/ClusterStatsMonitoringDocTests.java

@@ -5,6 +5,7 @@
  */
 package org.elasticsearch.xpack.monitoring.collector.cluster;
 
+import org.elasticsearch.Build;
 import org.elasticsearch.Version;
 import org.elasticsearch.action.admin.cluster.node.info.NodeInfo;
 import org.elasticsearch.action.admin.cluster.node.info.PluginsAndModules;
@@ -268,6 +269,11 @@ public class ClusterStatsMonitoringDocTests extends BaseMonitoringDocTestCase<Cl
         when(mockJvmInfo.getBundledJdk()).thenReturn(true);
         when(mockJvmInfo.getUsingBundledJdk()).thenReturn(true);
 
+        final Build mockBuild = mock(Build.class);
+        when(mockBuild.flavor()).thenReturn(Build.Flavor.DEFAULT);
+        when(mockBuild.type()).thenReturn(Build.Type.DOCKER);
+        when(mockNodeInfo.getBuild()).thenReturn(mockBuild);
+
         final NodeStats mockNodeStats = mock(NodeStats.class);
         when(mockNodeStats.getTimestamp()).thenReturn(0L);
 
@@ -521,7 +527,14 @@ public class ClusterStatsMonitoringDocTests extends BaseMonitoringDocTestCase<Cl
                       + "},"
                       + "\"discovery_types\":{"
                         + "\"_disco\":1"
-                      + "}"
+                      + "},"
+                      + "\"packaging_types\":["
+                        + "{"
+                          + "\"flavor\":\"default\","
+                          + "\"type\":\"docker\","
+                          + "\"count\":1"
+                        + "}"
+                      + "]"
                     + "}"
                   + "},"
                   + "\"cluster_state\":{"