From 38a27c582668b94b6c751cb9282d002551fc6825 Mon Sep 17 00:00:00 2001 From: Swetha Guptha Date: Sun, 29 Sep 2024 12:07:07 +0530 Subject: [PATCH] Serialise metrics/index_metrics using bit mask. Signed-off-by: Swetha Guptha --- .../admin/cluster/stats/ClusterStatsIT.java | 237 +++++++++++------- .../cluster/stats/ClusterStatsIndices.java | 20 +- .../cluster/stats/ClusterStatsNodes.java | 50 ++-- .../cluster/stats/ClusterStatsRequest.java | 120 ++++----- .../stats/ClusterStatsRequestBuilder.java | 7 +- .../cluster/stats/ClusterStatsResponse.java | 24 +- .../stats/TransportClusterStatsAction.java | 39 +-- .../admin/cluster/RestClusterStatsAction.java | 16 +- .../ClusterStatsRequestBuilderTests.java | 21 +- .../cluster/RestClusterStatsActionTests.java | 85 +++++++ 10 files changed, 383 insertions(+), 236 deletions(-) create mode 100644 server/src/test/java/org/opensearch/rest/action/admin/cluster/RestClusterStatsActionTests.java diff --git a/server/src/internalClusterTest/java/org/opensearch/action/admin/cluster/stats/ClusterStatsIT.java b/server/src/internalClusterTest/java/org/opensearch/action/admin/cluster/stats/ClusterStatsIT.java index 35f3b58813794..9cddcc4b3eeca 100644 --- a/server/src/internalClusterTest/java/org/opensearch/action/admin/cluster/stats/ClusterStatsIT.java +++ b/server/src/internalClusterTest/java/org/opensearch/action/admin/cluster/stats/ClusterStatsIT.java @@ -37,7 +37,7 @@ import org.opensearch.action.admin.cluster.node.stats.NodeStats; import org.opensearch.action.admin.cluster.node.stats.NodesStatsRequest; import org.opensearch.action.admin.cluster.node.stats.NodesStatsResponse; -import org.opensearch.action.admin.cluster.stats.ClusterStatsRequest.IndexMetrics; +import org.opensearch.action.admin.cluster.stats.ClusterStatsRequest.IndexMetric; import org.opensearch.action.admin.cluster.stats.ClusterStatsRequest.Metric; import org.opensearch.client.Client; import org.opensearch.client.Requests; @@ -232,6 +232,7 @@ public void testIndicesShardStatsWithoutNodeLevelAggregations() { } public void testIndicesShardStatsWithNodeLevelAggregations() { + internalCluster().startNode(); ensureGreen(); ClusterStatsResponse response = client().admin().cluster().prepareClusterStats().useAggregatedNodeLevelResponses(true).get(); @@ -507,122 +508,186 @@ public void testNodeRolesWithDataNodeLegacySettings() throws ExecutionException, assertEquals(expectedNodesRoles, Set.of(getNodeRoles(client, 0), getNodeRoles(client, 1))); } - public void testClusterStatsMetricFiltering() { + public void testClusterStatsApplyMetricFilterDisabled() throws IOException { internalCluster().startNode(); ensureGreen(); client().admin().indices().prepareCreate("test1").setMapping("{\"properties\":{\"foo\":{\"type\": \"keyword\"}}}").get(); - ClusterStatsResponse response = client().admin() + ClusterStatsRequestBuilder clusterStatsRequestBuilder = client().admin() + .cluster() + .prepareClusterStats() + .useAggregatedNodeLevelResponses(randomBoolean()); + assertFalse(clusterStatsRequestBuilder.request().applyMetricFiltering()); + + ClusterStatsResponse response = clusterStatsRequestBuilder.get(); + assertNotNull(response.getNodesStats()); + assertNotNull(response.getIndicesStats()); + + ClusterStatsResponse statsResponseWithMetricFilterDisabled = client().admin() .cluster() .prepareClusterStats() .useAggregatedNodeLevelResponses(randomBoolean()) - .requestMetrics(Set.of(Metric.FS.metricName(), Metric.JVM.metricName(), Metric.PLUGINS.metricName(), Metric.OS.metricName())) - .applyMetricFiltering(true) + .applyMetricFiltering(false) + .requestMetrics(Set.of(Metric.FS, Metric.JVM, Metric.PLUGINS, Metric.OS)) .get(); + + assertNotNull(statsResponseWithMetricFilterDisabled.getNodesStats()); + assertEquals( + response.getNodesStats().getCounts().getTotal(), + statsResponseWithMetricFilterDisabled.getNodesStats().getCounts().getTotal() + ); + assertEquals( + response.getNodesStats().getCounts().getRoles(), + statsResponseWithMetricFilterDisabled.getNodesStats().getCounts().getRoles() + ); + assertEquals(response.getNodesStats().getVersions(), statsResponseWithMetricFilterDisabled.getNodesStats().getVersions()); + assertEquals(response.getNodesStats().getPlugins(), statsResponseWithMetricFilterDisabled.getNodesStats().getPlugins()); + assertNotNull(statsResponseWithMetricFilterDisabled.getNodesStats().getOs()); + assertNotNull(statsResponseWithMetricFilterDisabled.getNodesStats().getJvm()); + assertNotNull(statsResponseWithMetricFilterDisabled.getNodesStats().getProcess()); + assertNotNull(statsResponseWithMetricFilterDisabled.getNodesStats().getFs()); + + assertNotNull(statsResponseWithMetricFilterDisabled.getIndicesStats()); + assertEquals(response.getIndicesStats().getFieldData(), statsResponseWithMetricFilterDisabled.getIndicesStats().getFieldData()); + assertEquals(response.getIndicesStats().getAnalysis(), statsResponseWithMetricFilterDisabled.getIndicesStats().getAnalysis()); + assertEquals(response.getIndicesStats().getMappings(), statsResponseWithMetricFilterDisabled.getIndicesStats().getMappings()); + assertEquals(response.getIndicesStats().getIndexCount(), statsResponseWithMetricFilterDisabled.getIndicesStats().getIndexCount()); + assertEquals( + response.getIndicesStats().getShards().getTotal(), + statsResponseWithMetricFilterDisabled.getIndicesStats().getShards().getTotal() + ); + assertEquals( + response.getIndicesStats().getShards().getPrimaries(), + statsResponseWithMetricFilterDisabled.getIndicesStats().getShards().getPrimaries() + ); + assertNotNull(statsResponseWithMetricFilterDisabled.getIndicesStats().getSegments()); + assertNotNull(statsResponseWithMetricFilterDisabled.getIndicesStats().getDocs()); + assertNotNull(statsResponseWithMetricFilterDisabled.getIndicesStats().getQueryCache()); + assertNotNull(statsResponseWithMetricFilterDisabled.getIndicesStats().getCompletion()); + assertNotNull(statsResponseWithMetricFilterDisabled.getIndicesStats().getStore()); + } + + public void testClusterStatsWithMetricsFilter() { + internalCluster().startNode(); + ensureGreen(); + + client().admin().indices().prepareCreate("test1").setMapping("{\"properties\":{\"foo\":{\"type\": \"keyword\"}}}").get(); + + ClusterStatsRequestBuilder clusterStatsRequestBuilder = client().admin() + .cluster() + .prepareClusterStats() + .useAggregatedNodeLevelResponses(randomBoolean()); + assertFalse(clusterStatsRequestBuilder.request().applyMetricFiltering()); + + ClusterStatsResponse response = clusterStatsRequestBuilder.get(); + assertNotNull(response); assertNotNull(response.getNodesStats()); - assertNotNull(response.getNodesStats().getJvm()); - assertNotNull(response.getNodesStats().getOs()); - assertNotNull(response.getNodesStats().getPlugins()); - assertNotNull(response.getNodesStats().getFs()); - assertNull(response.getIndicesStats()); + assertNotNull(response.getIndicesStats()); - response = client().admin() + ClusterStatsResponse statsResponseWithAllNodeStatsMetrics = client().admin() .cluster() .prepareClusterStats() .useAggregatedNodeLevelResponses(randomBoolean()) - .requestMetrics(Set.of(Metric.INDICES.metricName())) - .indexMetrics(IndexMetrics.allIndicesMetrics()) + .requestMetrics(ClusterStatsNodes.NODE_STATS_METRICS) .applyMetricFiltering(true) .get(); - assertNotNull(response.getIndicesStats()); - assertNotNull(response.getIndicesStats().getMappings()); - assertNotNull(response.getIndicesStats().getAnalysis()); - assertNotNull(response.getIndicesStats().getCompletion()); - assertNotNull(response.getIndicesStats().getQueryCache()); - assertNotNull(response.getIndicesStats().getShards()); - assertNotNull(response.getIndicesStats().getSegments()); - assertNotNull(response.getIndicesStats().getStore()); - assertNotNull(response.getIndicesStats().getFieldData()); - assertNotNull(response.getIndicesStats().getIndexCount()); - assertNull(response.getNodesStats()); + assertNotNull(statsResponseWithAllNodeStatsMetrics); + assertNotNull(statsResponseWithAllNodeStatsMetrics.getNodesStats()); + assertNull(statsResponseWithAllNodeStatsMetrics.getIndicesStats()); + assertEquals( + response.getNodesStats().getCounts().getTotal(), + statsResponseWithAllNodeStatsMetrics.getNodesStats().getCounts().getTotal() + ); + assertEquals( + response.getNodesStats().getCounts().getRoles(), + statsResponseWithAllNodeStatsMetrics.getNodesStats().getCounts().getRoles() + ); + assertEquals(response.getNodesStats().getVersions(), statsResponseWithAllNodeStatsMetrics.getNodesStats().getVersions()); + assertEquals(response.getNodesStats().getPlugins(), statsResponseWithAllNodeStatsMetrics.getNodesStats().getPlugins()); + assertNotNull(statsResponseWithAllNodeStatsMetrics.getNodesStats().getOs()); + assertNotNull(statsResponseWithAllNodeStatsMetrics.getNodesStats().getJvm()); + assertNotNull(statsResponseWithAllNodeStatsMetrics.getNodesStats().getProcess()); + assertNotNull(statsResponseWithAllNodeStatsMetrics.getNodesStats().getFs()); + + ClusterStatsResponse statsResponseWithIndicesRequestMetrics = client().admin() + .cluster() + .prepareClusterStats() + .useAggregatedNodeLevelResponses(randomBoolean()) + .requestMetrics(Set.of(Metric.PLUGINS, Metric.INDICES)) + .applyMetricFiltering(true) + .get(); + assertNotNull(statsResponseWithIndicesRequestMetrics); + assertNotNull(statsResponseWithIndicesRequestMetrics.getNodesStats()); + assertEquals(response.getNodesStats().getPlugins(), statsResponseWithAllNodeStatsMetrics.getNodesStats().getPlugins()); + assertNull(statsResponseWithIndicesRequestMetrics.getNodesStats().getOs()); + assertNull(statsResponseWithIndicesRequestMetrics.getNodesStats().getFs()); + assertNull(statsResponseWithIndicesRequestMetrics.getNodesStats().getProcess()); + assertNull(statsResponseWithIndicesRequestMetrics.getNodesStats().getJvm()); + assertNotNull(statsResponseWithIndicesRequestMetrics.getIndicesStats()); + assertEquals(response.getIndicesStats().getIndexCount(), statsResponseWithIndicesRequestMetrics.getIndicesStats().getIndexCount()); + } - response = client().admin().cluster().prepareClusterStats().useAggregatedNodeLevelResponses(randomBoolean()).get(); - assertNotNull(response.getIndicesStats()); + public void testClusterStatsWithIndexMetricFilter() { + internalCluster().startNode(); + ensureGreen(); + + client().admin().indices().prepareCreate("test1").setMapping("{\"properties\":{\"foo\":{\"type\": \"keyword\"}}}").get(); + + ClusterStatsRequestBuilder clusterStatsRequestBuilder = client().admin() + .cluster() + .prepareClusterStats() + .useAggregatedNodeLevelResponses(randomBoolean()); + assertFalse(clusterStatsRequestBuilder.request().applyMetricFiltering()); + + ClusterStatsResponse response = clusterStatsRequestBuilder.get(); + assertNotNull(response); assertNotNull(response.getNodesStats()); - assertNotNull(response.getIndicesStats().getMappings()); - assertNotNull(response.getIndicesStats().getAnalysis()); - assertNotNull(response.getNodesStats().getJvm()); - assertNotNull(response.getNodesStats().getOs()); + assertNotNull(response.getIndicesStats()); - response = client().admin() + ClusterStatsResponse statsResponseWithSpecificIndicesMetrics = client().admin() .cluster() .prepareClusterStats() .useAggregatedNodeLevelResponses(randomBoolean()) - .requestMetrics(Set.of(Metric.INDICES.metricName())) - .indexMetrics( - Set.of( - IndexMetrics.SHARDS.metricName(), - IndexMetrics.DOCS.metricName(), - IndexMetrics.MAPPINGS.metricName(), - IndexMetrics.ANALYSIS.metricName() - ) - ) + .requestMetrics(Set.of(Metric.INDICES)) + .indexMetrics(Set.of(IndexMetric.MAPPINGS, IndexMetric.ANALYSIS)) .applyMetricFiltering(true) .get(); - assertNotNull(response.getIndicesStats()); - assertNotNull(response.getIndicesStats().getShards()); - assertNotNull(response.getIndicesStats().getDocs()); - assertNotNull(response.getIndicesStats().getMappings()); - assertNotNull(response.getIndicesStats().getAnalysis()); - assertNull(response.getIndicesStats().getStore()); - assertNull(response.getIndicesStats().getSegments()); - assertNull(response.getIndicesStats().getCompletion()); - assertNull(response.getIndicesStats().getQueryCache()); - assertNull(response.getNodesStats()); - - response = client().admin() + assertNotNull(statsResponseWithSpecificIndicesMetrics); + assertNull(statsResponseWithSpecificIndicesMetrics.getNodesStats()); + assertNotNull(statsResponseWithSpecificIndicesMetrics.getIndicesStats()); + assertEquals(response.getIndicesStats().getIndexCount(), statsResponseWithSpecificIndicesMetrics.getIndicesStats().getIndexCount()); + assertEquals(response.getIndicesStats().getMappings(), statsResponseWithSpecificIndicesMetrics.getIndicesStats().getMappings()); + assertEquals(response.getIndicesStats().getAnalysis(), statsResponseWithSpecificIndicesMetrics.getIndicesStats().getAnalysis()); + + ClusterStatsResponse statsResponseWithAllIndicesMetrics = client().admin() .cluster() .prepareClusterStats() .useAggregatedNodeLevelResponses(randomBoolean()) - .requestMetrics(Set.of(Metric.OS.metricName(), Metric.PROCESS.metricName(), Metric.INDICES.metricName())) - .indexMetrics(Set.of(IndexMetrics.SHARDS.metricName(), IndexMetrics.MAPPINGS.metricName())) + .requestMetrics(Set.of(Metric.INDICES)) + .indexMetrics(Set.of(IndexMetric.values())) .applyMetricFiltering(true) .get(); - assertNotNull(response.getNodesStats()); - assertNotNull(response.getNodesStats().getOs()); - assertNotNull(response.getNodesStats().getProcess()); - assertNull(response.getNodesStats().getPlugins()); - assertNull(response.getNodesStats().getFs()); - assertNotNull(response.getIndicesStats()); - assertNotNull(response.getIndicesStats().getShards()); - assertNotNull(response.getIndicesStats().getMappings()); - assertNull(response.getIndicesStats().getAnalysis()); - assertNull(response.getIndicesStats().getFieldData()); - - assertThrows( - IllegalStateException.class, - () -> client().admin() - .cluster() - .prepareClusterStats() - .useAggregatedNodeLevelResponses(randomBoolean()) - .requestMetrics(Set.of("random_metric")) - .applyMetricFiltering(true) - .get() + assertNotNull(statsResponseWithAllIndicesMetrics); + assertNull(statsResponseWithAllIndicesMetrics.getNodesStats()); + assertNotNull(statsResponseWithAllIndicesMetrics.getIndicesStats()); + assertEquals(response.getIndicesStats().getFieldData(), statsResponseWithAllIndicesMetrics.getIndicesStats().getFieldData()); + assertEquals(response.getIndicesStats().getAnalysis(), statsResponseWithAllIndicesMetrics.getIndicesStats().getAnalysis()); + assertEquals(response.getIndicesStats().getMappings(), statsResponseWithAllIndicesMetrics.getIndicesStats().getMappings()); + assertEquals(response.getIndicesStats().getIndexCount(), statsResponseWithAllIndicesMetrics.getIndicesStats().getIndexCount()); + assertEquals( + response.getIndicesStats().getShards().getTotal(), + statsResponseWithAllIndicesMetrics.getIndicesStats().getShards().getTotal() ); - - assertThrows( - IllegalStateException.class, - () -> client().admin() - .cluster() - .prepareClusterStats() - .useAggregatedNodeLevelResponses(randomBoolean()) - .requestMetrics(Metric.allMetrics()) - .indexMetrics(Set.of("random_metric")) - .applyMetricFiltering(true) - .get() + assertEquals( + response.getIndicesStats().getShards().getPrimaries(), + statsResponseWithAllIndicesMetrics.getIndicesStats().getShards().getPrimaries() ); - + assertNotNull(statsResponseWithAllIndicesMetrics.getIndicesStats().getSegments()); + assertNotNull(statsResponseWithAllIndicesMetrics.getIndicesStats().getDocs()); + assertNotNull(statsResponseWithAllIndicesMetrics.getIndicesStats().getQueryCache()); + assertNotNull(statsResponseWithAllIndicesMetrics.getIndicesStats().getCompletion()); + assertNotNull(statsResponseWithAllIndicesMetrics.getIndicesStats().getStore()); } private Map getExpectedCounts( diff --git a/server/src/main/java/org/opensearch/action/admin/cluster/stats/ClusterStatsIndices.java b/server/src/main/java/org/opensearch/action/admin/cluster/stats/ClusterStatsIndices.java index 7bece7f014b95..3d3e022a142a0 100644 --- a/server/src/main/java/org/opensearch/action/admin/cluster/stats/ClusterStatsIndices.java +++ b/server/src/main/java/org/opensearch/action/admin/cluster/stats/ClusterStatsIndices.java @@ -32,7 +32,7 @@ package org.opensearch.action.admin.cluster.stats; -import org.opensearch.action.admin.cluster.stats.ClusterStatsRequest.IndexMetrics; +import org.opensearch.action.admin.cluster.stats.ClusterStatsRequest.IndexMetric; import org.opensearch.action.admin.indices.stats.CommonStats; import org.opensearch.common.annotation.PublicApi; import org.opensearch.core.xcontent.ToXContentFragment; @@ -71,52 +71,52 @@ public class ClusterStatsIndices implements ToXContentFragment { private MappingStats mappings; public ClusterStatsIndices(List nodeResponses, MappingStats mappingStats, AnalysisStats analysisStats) { - this(IndexMetrics.allIndicesMetrics(), nodeResponses, mappingStats, analysisStats); + this(Set.of(IndexMetric.values()), nodeResponses, mappingStats, analysisStats); } public ClusterStatsIndices( - Set indicesMetrics, + Set indicesMetrics, List nodeResponses, MappingStats mappingStats, AnalysisStats analysisStats ) { Map countsPerIndex = new HashMap<>(); Consumer docsStatsConsumer = (docs) -> { - if (IndexMetrics.DOCS.containedIn(indicesMetrics)) { + if (indicesMetrics.contains(IndexMetric.DOCS)) { if (this.docs == null) this.docs = new DocsStats(); this.docs.add(docs); } }; Consumer storeStatsConsumer = (store) -> { - if (IndexMetrics.STORE.containedIn(indicesMetrics)) { + if (indicesMetrics.contains(IndexMetric.STORE)) { if (this.store == null) this.store = new StoreStats(); this.store.add(store); } }; Consumer fieldDataConsumer = (fieldDataStats) -> { - if (IndexMetrics.FIELDDATA.containedIn(indicesMetrics)) { + if (indicesMetrics.contains(IndexMetric.FIELDDATA)) { if (this.fieldData == null) this.fieldData = new FieldDataStats(); this.fieldData.add(fieldDataStats); } }; Consumer queryCacheStatsConsumer = (queryCacheStats) -> { - if (IndexMetrics.QUERY_CACHE.containedIn(indicesMetrics)) { + if (indicesMetrics.contains(IndexMetric.QUERY_CACHE)) { if (this.queryCache == null) this.queryCache = new QueryCacheStats(); this.queryCache.add(queryCacheStats); } }; Consumer completionStatsConsumer = (completionStats) -> { - if (IndexMetrics.COMPLETION.containedIn(indicesMetrics)) { + if (indicesMetrics.contains(IndexMetric.COMPLETION)) { if (this.completion == null) this.completion = new CompletionStats(); this.completion.add(completionStats); } }; Consumer segmentsStatsConsumer = (segmentsStats) -> { - if (IndexMetrics.SEGMENTS.containedIn(indicesMetrics)) { + if (indicesMetrics.contains(IndexMetric.SEGMENTS)) { if (this.segments == null) this.segments = new SegmentsStats(); this.segments.add(segmentsStats); } @@ -170,7 +170,7 @@ public ClusterStatsIndices( } indexCount = countsPerIndex.size(); - if (IndexMetrics.SHARDS.containedIn(indicesMetrics)) { + if (indicesMetrics.contains(IndexMetric.SHARDS)) { shards = new ShardStats(); for (final ShardStats indexCountsCursor : countsPerIndex.values()) { shards.addIndexShardCount(indexCountsCursor); diff --git a/server/src/main/java/org/opensearch/action/admin/cluster/stats/ClusterStatsNodes.java b/server/src/main/java/org/opensearch/action/admin/cluster/stats/ClusterStatsNodes.java index 9ebda488d3ac7..657e3b425db21 100644 --- a/server/src/main/java/org/opensearch/action/admin/cluster/stats/ClusterStatsNodes.java +++ b/server/src/main/java/org/opensearch/action/admin/cluster/stats/ClusterStatsNodes.java @@ -90,26 +90,29 @@ public class ClusterStatsNodes implements ToXContentFragment { private final PackagingTypes packagingTypes; private final IngestStats ingestStats; - public static final Set NODE_STATS_METRICS = Set.of( - Metric.OS.metricName(), - Metric.PROCESS.metricName(), - Metric.JVM.metricName(), - Metric.FS.metricName(), - Metric.PLUGINS.metricName(), - Metric.INGEST.metricName(), - Metric.NETWORK_TYPES.metricName(), - Metric.DISCOVERY_TYPES.metricName(), - Metric.PACKAGING_TYPES.metricName() + public static final Set NODE_STATS_METRICS = Set.of( + // Stats computed from node info and node stat + Metric.OS, + Metric.JVM, + // Stats computed from node stat + Metric.FS, + Metric.PROCESS, + Metric.INGEST, + // Stats computed from node info + Metric.PLUGINS, + Metric.NETWORK_TYPES, + Metric.DISCOVERY_TYPES, + Metric.PACKAGING_TYPES ); ClusterStatsNodes(List nodeResponses) { - this(Metric.allMetrics(), nodeResponses); + this(Set.of(Metric.values()), nodeResponses); } - ClusterStatsNodes(Set requestedMetrics, List nodeResponses) { + ClusterStatsNodes(Set requestedMetrics, List nodeResponses) { this.versions = new HashSet<>(); - this.fs = ClusterStatsRequest.Metric.FS.containedIn(requestedMetrics) ? new FsInfo.Path() : null; - this.plugins = ClusterStatsRequest.Metric.PLUGINS.containedIn(requestedMetrics) ? new HashSet<>() : null; + this.fs = requestedMetrics.contains(ClusterStatsRequest.Metric.FS) ? new FsInfo.Path() : null; + this.plugins = requestedMetrics.contains(ClusterStatsRequest.Metric.PLUGINS) ? new HashSet<>() : null; Set seenAddresses = new HashSet<>(nodeResponses.size()); List nodeInfos = new ArrayList<>(nodeResponses.size()); @@ -132,18 +135,15 @@ public class ClusterStatsNodes implements ToXContentFragment { this.fs.add(nodeResponse.nodeStats().getFs().getTotal()); } } + this.counts = new Counts(nodeInfos); - this.os = ClusterStatsRequest.Metric.OS.containedIn(requestedMetrics) ? new OsStats(nodeInfos, nodeStats) : null; - this.process = ClusterStatsRequest.Metric.PROCESS.containedIn(requestedMetrics) ? new ProcessStats(nodeStats) : null; - this.jvm = ClusterStatsRequest.Metric.JVM.containedIn(requestedMetrics) ? new JvmStats(nodeInfos, nodeStats) : null; - this.networkTypes = ClusterStatsRequest.Metric.NETWORK_TYPES.containedIn(requestedMetrics) ? new NetworkTypes(nodeInfos) : null; - this.discoveryTypes = ClusterStatsRequest.Metric.DISCOVERY_TYPES.containedIn(requestedMetrics) - ? new DiscoveryTypes(nodeInfos) - : null; - this.packagingTypes = ClusterStatsRequest.Metric.PACKAGING_TYPES.containedIn(requestedMetrics) - ? new PackagingTypes(nodeInfos) - : null; - this.ingestStats = ClusterStatsRequest.Metric.INGEST.containedIn(requestedMetrics) ? new IngestStats(nodeStats) : null; + this.networkTypes = requestedMetrics.contains(ClusterStatsRequest.Metric.NETWORK_TYPES) ? new NetworkTypes(nodeInfos) : null; + this.discoveryTypes = requestedMetrics.contains(ClusterStatsRequest.Metric.DISCOVERY_TYPES) ? new DiscoveryTypes(nodeInfos) : null; + this.packagingTypes = requestedMetrics.contains(ClusterStatsRequest.Metric.PACKAGING_TYPES) ? new PackagingTypes(nodeInfos) : null; + this.ingestStats = requestedMetrics.contains(ClusterStatsRequest.Metric.INGEST) ? new IngestStats(nodeStats) : null; + this.process = requestedMetrics.contains(ClusterStatsRequest.Metric.PROCESS) ? new ProcessStats(nodeStats) : null; + this.os = requestedMetrics.contains(ClusterStatsRequest.Metric.OS) ? new OsStats(nodeInfos, nodeStats) : null; + this.jvm = requestedMetrics.contains(ClusterStatsRequest.Metric.JVM) ? new JvmStats(nodeInfos, nodeStats) : null; } public Counts getCounts() { diff --git a/server/src/main/java/org/opensearch/action/admin/cluster/stats/ClusterStatsRequest.java b/server/src/main/java/org/opensearch/action/admin/cluster/stats/ClusterStatsRequest.java index 1526c817ddbdb..25ab3e933a686 100644 --- a/server/src/main/java/org/opensearch/action/admin/cluster/stats/ClusterStatsRequest.java +++ b/server/src/main/java/org/opensearch/action/admin/cluster/stats/ClusterStatsRequest.java @@ -39,10 +39,8 @@ import org.opensearch.core.common.io.stream.StreamOutput; import java.io.IOException; -import java.util.Arrays; import java.util.HashSet; import java.util.Set; -import java.util.stream.Collectors; /** * A request to get cluster level stats. @@ -52,8 +50,8 @@ @PublicApi(since = "1.0.0") public class ClusterStatsRequest extends BaseNodesRequest { - private final Set requestedMetrics = new HashSet<>(); - private final Set indexMetricsRequested = new HashSet<>(); + private final Set requestedMetrics = new HashSet<>(); + private final Set indexMetricsRequested = new HashSet<>(); private Boolean applyMetricFiltering = false; public ClusterStatsRequest(StreamInput in) throws IOException { @@ -63,8 +61,18 @@ public ClusterStatsRequest(StreamInput in) throws IOException { } if (in.getVersion().onOrAfter(Version.V_3_0_0)) { applyMetricFiltering = in.readOptionalBoolean(); - requestedMetrics.addAll(in.readStringList()); - indexMetricsRequested.addAll(in.readStringList()); + final long longMetricsFlags = in.readLong(); + for (Metric metric : Metric.values()) { + if ((longMetricsFlags & (1 << metric.getIndex())) != 0) { + requestedMetrics.add(metric); + } + } + final long longIndexMetricFlags = in.readLong(); + for (IndexMetric indexMetric : IndexMetric.values()) { + if ((longIndexMetricFlags & (1 << indexMetric.getIndex())) != 0) { + indexMetricsRequested.add(indexMetric); + } + } } } @@ -97,10 +105,7 @@ public void applyMetricFiltering(boolean honourMetricFiltering) { /** * Add Metric */ - public ClusterStatsRequest addMetric(String metric) { - if (Metric.allMetrics().contains(metric) == false) { - throw new IllegalStateException("Used an illegal Metric: " + metric); - } + public ClusterStatsRequest addMetric(Metric metric) { requestedMetrics.add(metric); return this; } @@ -108,33 +113,22 @@ public ClusterStatsRequest addMetric(String metric) { /** * Get the names of requested metrics */ - public Set requestedMetrics() { + public Set requestedMetrics() { return new HashSet<>(requestedMetrics); } /** * Add IndexMetric */ - public ClusterStatsRequest addIndexMetric(String indexMetric) { - if (IndexMetrics.allIndicesMetrics().contains(indexMetric) == false) { - throw new IllegalStateException("Used an illegal index metric: " + indexMetric); - } + public ClusterStatsRequest addIndexMetric(IndexMetric indexMetric) { indexMetricsRequested.add(indexMetric); return this; } - public Set indicesMetrics() { + public Set indicesMetrics() { return new HashSet<>(indexMetricsRequested); } - public void clearRequestedMetrics() { - requestedMetrics.clear(); - } - - public void clearIndicesMetrics() { - indexMetricsRequested.clear(); - } - @Override public void writeTo(StreamOutput out) throws IOException { super.writeTo(out); @@ -143,8 +137,16 @@ public void writeTo(StreamOutput out) throws IOException { } if (out.getVersion().onOrAfter(Version.V_3_0_0)) { out.writeOptionalBoolean(applyMetricFiltering); - out.writeStringArray(requestedMetrics.toArray(new String[0])); - out.writeStringArray(indexMetricsRequested.toArray(new String[0])); + long longMetricFlags = 0; + for (Metric metric : requestedMetrics) { + longMetricFlags |= (1 << metric.getIndex()); + } + out.writeLong(longMetricFlags); + long longIndexMetricFlags = 0; + for (IndexMetric indexMetric : indexMetricsRequested) { + longIndexMetricFlags |= (1 << indexMetric.getIndex()); + } + out.writeLong(longIndexMetricFlags); } } @@ -154,33 +156,32 @@ public void writeTo(StreamOutput out) throws IOException { */ @PublicApi(since = "3.0.0") public enum Metric { - OS("os"), - PROCESS("process"), - JVM("jvm"), - FS("fs"), - PLUGINS("plugins"), - INGEST("ingest"), - NETWORK_TYPES("network_types"), - DISCOVERY_TYPES("discovery_types"), - PACKAGING_TYPES("packaging_types"), - INDICES("indices"); + OS("os", 0), + JVM("jvm", 1), + FS("fs", 2), + PROCESS("process", 3), + INGEST("ingest", 4), + PLUGINS("plugins", 5), + NETWORK_TYPES("network_types", 6), + DISCOVERY_TYPES("discovery_types", 7), + PACKAGING_TYPES("packaging_types", 8), + INDICES("indices", 9); private String metricName; - Metric(String name) { + private int index; + + Metric(String name, int index) { this.metricName = name; + this.index = index; } public String metricName() { return this.metricName; } - public static Set allMetrics() { - return Arrays.stream(values()).map(Metric::metricName).collect(Collectors.toSet()); - } - - public boolean containedIn(Set metricNames) { - return metricNames.contains(this.metricName()); + public int getIndex() { + return index; } } @@ -190,33 +191,32 @@ public boolean containedIn(Set metricNames) { * from the cluster stats endpoint. */ @PublicApi(since = "3.0.0") - public enum IndexMetrics { - SHARDS("shards"), - DOCS("docs"), - STORE("store"), - FIELDDATA("fielddata"), - QUERY_CACHE("query_cache"), - COMPLETION("completion"), - SEGMENTS("segments"), - ANALYSIS("analysis"), - MAPPINGS("mappings"); + public enum IndexMetric { + SHARDS("shards", 0), + DOCS("docs", 1), + STORE("store", 2), + FIELDDATA("fielddata", 3), + QUERY_CACHE("query_cache", 4), + COMPLETION("completion", 5), + SEGMENTS("segments", 6), + ANALYSIS("analysis", 7), + MAPPINGS("mappings", 8); private String metricName; - IndexMetrics(String name) { + private int index; + + IndexMetric(String name, int index) { this.metricName = name; + this.index = index; } public String metricName() { return this.metricName; } - public boolean containedIn(Set metricNames) { - return metricNames.contains(this.metricName()); - } - - public static Set allIndicesMetrics() { - return Arrays.stream(values()).map(IndexMetrics::metricName).collect(Collectors.toSet()); + public int getIndex() { + return this.index; } } } diff --git a/server/src/main/java/org/opensearch/action/admin/cluster/stats/ClusterStatsRequestBuilder.java b/server/src/main/java/org/opensearch/action/admin/cluster/stats/ClusterStatsRequestBuilder.java index 63305825d3ed3..fb2ba86531a32 100644 --- a/server/src/main/java/org/opensearch/action/admin/cluster/stats/ClusterStatsRequestBuilder.java +++ b/server/src/main/java/org/opensearch/action/admin/cluster/stats/ClusterStatsRequestBuilder.java @@ -38,6 +38,9 @@ import java.util.Set; +import static org.opensearch.action.admin.cluster.stats.ClusterStatsRequest.IndexMetric; +import static org.opensearch.action.admin.cluster.stats.ClusterStatsRequest.Metric; + /** * Transport request builder for obtaining cluster stats * @@ -63,12 +66,12 @@ public final ClusterStatsRequestBuilder applyMetricFiltering(boolean applyMetric return this; } - public final ClusterStatsRequestBuilder requestMetrics(Set requestMetrics) { + public final ClusterStatsRequestBuilder requestMetrics(Set requestMetrics) { requestMetrics.forEach(request::addMetric); return this; } - public final ClusterStatsRequestBuilder indexMetrics(Set indexMetrics) { + public final ClusterStatsRequestBuilder indexMetrics(Set indexMetrics) { indexMetrics.forEach(request::addIndexMetric); return this; } diff --git a/server/src/main/java/org/opensearch/action/admin/cluster/stats/ClusterStatsResponse.java b/server/src/main/java/org/opensearch/action/admin/cluster/stats/ClusterStatsResponse.java index f994b0ddb78b1..870996bb61b23 100644 --- a/server/src/main/java/org/opensearch/action/admin/cluster/stats/ClusterStatsResponse.java +++ b/server/src/main/java/org/opensearch/action/admin/cluster/stats/ClusterStatsResponse.java @@ -33,6 +33,7 @@ package org.opensearch.action.admin.cluster.stats; import org.opensearch.action.FailedNodeException; +import org.opensearch.action.admin.cluster.stats.ClusterStatsRequest.IndexMetric; import org.opensearch.action.admin.cluster.stats.ClusterStatsRequest.Metric; import org.opensearch.action.support.nodes.BaseNodesResponse; import org.opensearch.cluster.ClusterName; @@ -91,16 +92,7 @@ public ClusterStatsResponse( List failures, ClusterState state ) { - this( - timestamp, - clusterUUID, - clusterName, - nodes, - failures, - state, - ClusterStatsRequest.Metric.allMetrics(), - ClusterStatsRequest.IndexMetrics.allIndicesMetrics() - ); + this(timestamp, clusterUUID, clusterName, nodes, failures, state, Set.of(Metric.values()), Set.of(IndexMetric.values())); } public ClusterStatsResponse( @@ -110,8 +102,8 @@ public ClusterStatsResponse( List nodes, List failures, ClusterState state, - Set requestedMetrics, - Set indicesMetrics + Set requestedMetrics, + Set indicesMetrics ) { super(clusterName, nodes, failures); this.clusterUUID = clusterUUID; @@ -119,11 +111,9 @@ public ClusterStatsResponse( nodesStats = requestedMetrics.stream().anyMatch(ClusterStatsNodes.NODE_STATS_METRICS::contains) ? new ClusterStatsNodes(requestedMetrics, nodes) : null; - MappingStats mappingStats = ClusterStatsRequest.IndexMetrics.MAPPINGS.containedIn(indicesMetrics) ? MappingStats.of(state) : null; - AnalysisStats analysisStats = ClusterStatsRequest.IndexMetrics.ANALYSIS.containedIn(indicesMetrics) - ? AnalysisStats.of(state) - : null; - indicesStats = Metric.INDICES.containedIn(requestedMetrics) + MappingStats mappingStats = indicesMetrics.contains(IndexMetric.MAPPINGS) ? MappingStats.of(state) : null; + AnalysisStats analysisStats = indicesMetrics.contains(IndexMetric.ANALYSIS) ? AnalysisStats.of(state) : null; + indicesStats = requestedMetrics.contains(Metric.INDICES) ? new ClusterStatsIndices(indicesMetrics, nodes, mappingStats, analysisStats) : null; ClusterHealthStatus status = null; diff --git a/server/src/main/java/org/opensearch/action/admin/cluster/stats/TransportClusterStatsAction.java b/server/src/main/java/org/opensearch/action/admin/cluster/stats/TransportClusterStatsAction.java index 5bae001c15bd1..051a7669bfcac 100644 --- a/server/src/main/java/org/opensearch/action/admin/cluster/stats/TransportClusterStatsAction.java +++ b/server/src/main/java/org/opensearch/action/admin/cluster/stats/TransportClusterStatsAction.java @@ -79,20 +79,19 @@ public class TransportClusterStatsAction extends TransportNodesAction< TransportClusterStatsAction.ClusterStatsNodeRequest, ClusterStatsNodeResponse> { - private static final Map INDEX_METRIC_TO_SHARDS_STATS_FLAG_MAP = Map.of( - ClusterStatsRequest.IndexMetrics.DOCS.metricName(), + private static final Map INDEX_METRIC_TO_SHARDS_STATS_FLAG_MAP = Map.of( + ClusterStatsRequest.IndexMetric.DOCS, CommonStatsFlags.Flag.Docs, - ClusterStatsRequest.IndexMetrics.STORE.metricName(), + ClusterStatsRequest.IndexMetric.STORE, CommonStatsFlags.Flag.Store, - ClusterStatsRequest.IndexMetrics.FIELDDATA.metricName(), + ClusterStatsRequest.IndexMetric.FIELDDATA, CommonStatsFlags.Flag.FieldData, - ClusterStatsRequest.IndexMetrics.QUERY_CACHE.metricName(), + ClusterStatsRequest.IndexMetric.QUERY_CACHE, CommonStatsFlags.Flag.QueryCache, - ClusterStatsRequest.IndexMetrics.COMPLETION.metricName(), + ClusterStatsRequest.IndexMetric.COMPLETION, CommonStatsFlags.Flag.Completion, - ClusterStatsRequest.IndexMetrics.SEGMENTS.metricName(), + ClusterStatsRequest.IndexMetric.SEGMENTS, CommonStatsFlags.Flag.Segments - ); private final NodeService nodeService; @@ -171,20 +170,20 @@ protected ClusterStatsNodeResponse newNodeResponse(StreamInput in) throws IOExce protected ClusterStatsNodeResponse nodeOperation(ClusterStatsNodeRequest nodeRequest) { NodeInfo nodeInfo = nodeService.info(true, true, false, true, false, true, false, true, false, false, false, false); boolean applyMetricFiltering = nodeRequest.request.applyMetricFiltering(); - Set requestedMetrics = nodeRequest.request.requestedMetrics(); + Set requestedMetrics = nodeRequest.request.requestedMetrics(); NodeStats nodeStats = nodeService.stats( CommonStatsFlags.NONE, - !applyMetricFiltering || Metric.OS.containedIn(requestedMetrics), - !applyMetricFiltering || Metric.PROCESS.containedIn(requestedMetrics), - !applyMetricFiltering || Metric.JVM.containedIn(requestedMetrics), + isMetricRequired(applyMetricFiltering, Metric.OS, requestedMetrics), + isMetricRequired(applyMetricFiltering, Metric.PROCESS, requestedMetrics), + isMetricRequired(applyMetricFiltering, Metric.JVM, requestedMetrics), false, - !applyMetricFiltering || Metric.FS.containedIn(requestedMetrics), + isMetricRequired(applyMetricFiltering, Metric.FS, requestedMetrics), false, false, false, false, false, - !applyMetricFiltering || Metric.INGEST.containedIn(requestedMetrics), + isMetricRequired(applyMetricFiltering, Metric.INGEST, requestedMetrics), false, false, false, @@ -202,11 +201,11 @@ protected ClusterStatsNodeResponse nodeOperation(ClusterStatsNodeRequest nodeReq false ); List shardsStats = new ArrayList<>(); - if (!applyMetricFiltering || Metric.INDICES.containedIn(requestedMetrics)) { + if (isMetricRequired(applyMetricFiltering, Metric.INDICES, requestedMetrics)) { CommonStatsFlags commonStatsFlags = new CommonStatsFlags(); - for (String metric : nodeRequest.request.indicesMetrics()) { - if (INDEX_METRIC_TO_SHARDS_STATS_FLAG_MAP.containsKey(metric)) { - commonStatsFlags.set(INDEX_METRIC_TO_SHARDS_STATS_FLAG_MAP.get(metric), true); + for (ClusterStatsRequest.IndexMetric indexMetric : nodeRequest.request.indicesMetrics()) { + if (INDEX_METRIC_TO_SHARDS_STATS_FLAG_MAP.containsKey(indexMetric)) { + commonStatsFlags.set(INDEX_METRIC_TO_SHARDS_STATS_FLAG_MAP.get(indexMetric), true); } } for (IndexService indexService : indicesService) { @@ -256,6 +255,10 @@ protected ClusterStatsNodeResponse nodeOperation(ClusterStatsNodeRequest nodeReq ); } + private boolean isMetricRequired(boolean applyMetricFilter, Metric metric, Set requestedMetrics) { + return !applyMetricFilter || requestedMetrics.contains(metric); + } + /** * Inner Cluster Stats Node Request * diff --git a/server/src/main/java/org/opensearch/rest/action/admin/cluster/RestClusterStatsAction.java b/server/src/main/java/org/opensearch/rest/action/admin/cluster/RestClusterStatsAction.java index e3858c27815ab..3874e043eea30 100644 --- a/server/src/main/java/org/opensearch/rest/action/admin/cluster/RestClusterStatsAction.java +++ b/server/src/main/java/org/opensearch/rest/action/admin/cluster/RestClusterStatsAction.java @@ -80,15 +80,15 @@ public List routes() { static { Map> metricRequestConsumerMap = new HashMap<>(); for (ClusterStatsRequest.Metric metric : ClusterStatsRequest.Metric.values()) { - metricRequestConsumerMap.put(metric.metricName(), request -> request.addMetric(metric.metricName())); + metricRequestConsumerMap.put(metric.metricName(), request -> request.addMetric(metric)); } METRIC_REQUEST_CONSUMER_MAP = Collections.unmodifiableMap(metricRequestConsumerMap); } static { Map> metricMap = new HashMap<>(); - for (ClusterStatsRequest.IndexMetrics indexMetric : ClusterStatsRequest.IndexMetrics.values()) { - metricMap.put(indexMetric.metricName(), request -> request.addIndexMetric(indexMetric.metricName())); + for (ClusterStatsRequest.IndexMetric indexMetric : ClusterStatsRequest.IndexMetric.values()) { + metricMap.put(indexMetric.metricName(), request -> request.addIndexMetric(indexMetric)); } INDEX_METRIC_TO_REQUEST_CONSUMER_MAP = Collections.unmodifiableMap(metricMap); } @@ -100,7 +100,7 @@ public String getName() { @Override public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException { - Set metrics = Strings.tokenizeByCommaToSet(request.param("metric", null)); + Set metrics = Strings.tokenizeByCommaToSet(request.param("metric", "_all")); Set indexMetrics = Strings.tokenizeByCommaToSet(request.param("index_metric", null)); String[] nodeIds = request.paramAsStringArray("nodeId", null); @@ -126,7 +126,7 @@ public RestChannelConsumer prepareRequest(final RestRequest request, final NodeC Locale.ROOT, "request [%s] contains _all and individual index metrics [%s]", request.path(), - request.param("sub_metric") + request.param("index_metric") ) ); } @@ -162,10 +162,10 @@ public RestChannelConsumer prepareRequest(final RestRequest request, final NodeC ); } - if (ClusterStatsRequest.Metric.INDICES.containedIn(metricsRequested)) { + if (metricsRequested.contains(ClusterStatsRequest.Metric.INDICES.metricName())) { final Set indexMetricsRequested = new HashSet<>(); if (indexMetrics.isEmpty() || indexMetrics.contains("_all")) { - indexMetricsRequested.addAll(ClusterStatsRequest.IndexMetrics.allIndicesMetrics()); + indexMetricsRequested.addAll(INDEX_METRIC_TO_REQUEST_CONSUMER_MAP.keySet()); } else { indexMetricsRequested.addAll(indexMetrics); } @@ -181,7 +181,7 @@ public RestChannelConsumer prepareRequest(final RestRequest request, final NodeC if (!invalidIndexMetrics.isEmpty()) { throw new IllegalArgumentException( - unrecognized(request, invalidIndexMetrics, INDEX_METRIC_TO_REQUEST_CONSUMER_MAP.keySet(), "index_metric") + unrecognized(request, invalidIndexMetrics, INDEX_METRIC_TO_REQUEST_CONSUMER_MAP.keySet(), "index metric") ); } } diff --git a/server/src/test/java/org/opensearch/action/admin/cluster/stats/ClusterStatsRequestBuilderTests.java b/server/src/test/java/org/opensearch/action/admin/cluster/stats/ClusterStatsRequestBuilderTests.java index 1c64c01eb0e49..df77590879e87 100644 --- a/server/src/test/java/org/opensearch/action/admin/cluster/stats/ClusterStatsRequestBuilderTests.java +++ b/server/src/test/java/org/opensearch/action/admin/cluster/stats/ClusterStatsRequestBuilderTests.java @@ -8,7 +8,7 @@ package org.opensearch.action.admin.cluster.stats; -import org.opensearch.action.admin.cluster.stats.ClusterStatsRequest.IndexMetrics; +import org.opensearch.action.admin.cluster.stats.ClusterStatsRequest.IndexMetric; import org.opensearch.action.admin.cluster.stats.ClusterStatsRequest.Metric; import org.opensearch.test.OpenSearchTestCase; import org.opensearch.test.client.NoOpClient; @@ -59,8 +59,10 @@ public void testRequestedMetrics() { this.testClient, ClusterStatsAction.INSTANCE ); - clusterStatsRequestBuilder.requestMetrics(Set.of(Metric.OS.metricName(), Metric.JVM.metricName())); - assertEquals(Set.of(Metric.OS.metricName(), Metric.JVM.metricName()), clusterStatsRequestBuilder.request().requestedMetrics()); + clusterStatsRequestBuilder.applyMetricFiltering(true); + clusterStatsRequestBuilder.requestMetrics(Set.of(Metric.OS, Metric.JVM)); + assertTrue(clusterStatsRequestBuilder.request().applyMetricFiltering()); + assertEquals(Set.of(Metric.OS, Metric.JVM), clusterStatsRequestBuilder.request().requestedMetrics()); } public void testIndicesMetrics() { @@ -68,13 +70,12 @@ public void testIndicesMetrics() { this.testClient, ClusterStatsAction.INSTANCE ); - clusterStatsRequestBuilder.requestMetrics(Set.of(Metric.INDICES.metricName(), Metric.JVM.metricName())); - clusterStatsRequestBuilder.indexMetrics(Set.of(IndexMetrics.MAPPINGS.metricName(), IndexMetrics.ANALYSIS.metricName())); - assertEquals(Set.of(Metric.INDICES.metricName(), Metric.JVM.metricName()), clusterStatsRequestBuilder.request().requestedMetrics()); - assertEquals( - Set.of(IndexMetrics.MAPPINGS.metricName(), IndexMetrics.ANALYSIS.metricName()), - clusterStatsRequestBuilder.request().indicesMetrics() - ); + clusterStatsRequestBuilder.applyMetricFiltering(true); + clusterStatsRequestBuilder.requestMetrics(Set.of(Metric.INDICES, Metric.JVM)); + clusterStatsRequestBuilder.indexMetrics(Set.of(IndexMetric.MAPPINGS, IndexMetric.ANALYSIS)); + assertTrue(clusterStatsRequestBuilder.request().applyMetricFiltering()); + assertEquals(Set.of(Metric.INDICES, Metric.JVM), clusterStatsRequestBuilder.request().requestedMetrics()); + assertEquals(Set.of(IndexMetric.MAPPINGS, IndexMetric.ANALYSIS), clusterStatsRequestBuilder.request().indicesMetrics()); } } diff --git a/server/src/test/java/org/opensearch/rest/action/admin/cluster/RestClusterStatsActionTests.java b/server/src/test/java/org/opensearch/rest/action/admin/cluster/RestClusterStatsActionTests.java new file mode 100644 index 0000000000000..9ec04dfc55ee2 --- /dev/null +++ b/server/src/test/java/org/opensearch/rest/action/admin/cluster/RestClusterStatsActionTests.java @@ -0,0 +1,85 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.rest.action.admin.cluster; + +import org.opensearch.client.node.NodeClient; +import org.opensearch.rest.RestRequest; +import org.opensearch.test.OpenSearchTestCase; +import org.opensearch.test.rest.FakeRestRequest; + +import java.util.HashMap; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.object.HasToString.hasToString; +import static org.mockito.Mockito.mock; + +public class RestClusterStatsActionTests extends OpenSearchTestCase { + + private RestClusterStatsAction action; + + @Override + public void setUp() throws Exception { + super.setUp(); + action = new RestClusterStatsAction(); + } + + public void testUnrecognizedMetric() { + final HashMap params = new HashMap<>(); + final String metric = randomAlphaOfLength(64); + params.put("metric", metric); + final RestRequest request = new FakeRestRequest.Builder(xContentRegistry()).withPath("/_cluster/stats").withParams(params).build(); + final IllegalArgumentException e = expectThrows( + IllegalArgumentException.class, + () -> action.prepareRequest(request, mock(NodeClient.class)) + ); + assertThat(e, hasToString(containsString("request [/_cluster/stats] contains unrecognized metric: [" + metric + "]"))); + } + + public void testUnrecognizedIndexMetric() { + final HashMap params = new HashMap<>(); + params.put("metric", "_all,"); + final String indexMetric = randomAlphaOfLength(64); + params.put("index_metric", indexMetric); + final RestRequest request = new FakeRestRequest.Builder(xContentRegistry()).withPath("/_cluster/stats").withParams(params).build(); + final IllegalArgumentException e = expectThrows( + IllegalArgumentException.class, + () -> action.prepareRequest(request, mock(NodeClient.class)) + ); + assertThat(e, hasToString(containsString("request [/_cluster/stats] contains unrecognized index metric: [" + indexMetric + "]"))); + } + + public void testAllMetricsRequestWithOtherMetric() { + final HashMap params = new HashMap<>(); + final String metric = randomSubsetOf(1, RestClusterStatsAction.METRIC_REQUEST_CONSUMER_MAP.keySet()).get(0); + params.put("metric", "_all," + metric); + final RestRequest request = new FakeRestRequest.Builder(xContentRegistry()).withPath("/_cluster/stats").withParams(params).build(); + final IllegalArgumentException e = expectThrows( + IllegalArgumentException.class, + () -> action.prepareRequest(request, mock(NodeClient.class)) + ); + assertThat(e, hasToString(containsString("request [/_cluster/stats] contains _all and individual metrics [_all," + metric + "]"))); + } + + public void testAllIndexMetricsRequestWithOtherIndicesMetric() { + final HashMap params = new HashMap<>(); + params.put("metric", "_all,"); + final String indexMetric = randomSubsetOf(1, RestClusterStatsAction.INDEX_METRIC_TO_REQUEST_CONSUMER_MAP.keySet()).get(0); + params.put("index_metric", "_all," + indexMetric); + final RestRequest request = new FakeRestRequest.Builder(xContentRegistry()).withPath("/_cluster/stats").withParams(params).build(); + final IllegalArgumentException e = expectThrows( + IllegalArgumentException.class, + () -> action.prepareRequest(request, mock(NodeClient.class)) + ); + assertThat( + e, + hasToString(containsString("request [/_cluster/stats] contains _all and individual index metrics [_all," + indexMetric + "]")) + ); + } + +}