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 9116fe8f2b300..5f00ba35c7b69 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 @@ -47,6 +47,7 @@ import org.opensearch.common.Priority; import org.opensearch.common.settings.Settings; import org.opensearch.common.util.concurrent.OpenSearchExecutors; +import org.opensearch.core.common.unit.ByteSizeValue; import org.opensearch.monitor.os.OsStats; import org.opensearch.node.NodeRoleSettings; import org.opensearch.test.OpenSearchIntegTestCase; @@ -772,6 +773,41 @@ public void testClusterStatsWithIndexMetricWithDocsFilter() throws IOException { assertTrue(statsResponseWithAllIndicesMetrics.getIndicesStats().getDocs().getAverageSizeInBytes() > 0); } + public void testClusterStatsWithSelectiveMetricsFilterAndNoIndex() { + internalCluster().startNode(); + ensureGreen(); + ClusterStatsResponse statsResponseWithAllIndicesMetrics = client().admin() + .cluster() + .prepareClusterStats() + .useAggregatedNodeLevelResponses(randomBoolean()) + .requestMetrics(Set.of(Metric.OS, Metric.FS, Metric.INDICES)) + .indexMetrics(Set.of(IndexMetric.FIELDDATA, IndexMetric.SHARDS, IndexMetric.SEGMENTS, IndexMetric.DOCS, IndexMetric.STORE)) + .computeAllMetrics(false) + .get(); + assertNotNull(statsResponseWithAllIndicesMetrics); + assertNotNull(statsResponseWithAllIndicesMetrics.getNodesStats()); + assertNotNull(statsResponseWithAllIndicesMetrics.getIndicesStats()); + validateNodeStatsOutput(Set.of(Metric.FS, Metric.OS), statsResponseWithAllIndicesMetrics); + validateIndicesStatsOutput( + Set.of(IndexMetric.FIELDDATA, IndexMetric.SHARDS, IndexMetric.SEGMENTS, IndexMetric.DOCS, IndexMetric.STORE), + statsResponseWithAllIndicesMetrics + ); + assertEquals(0, statsResponseWithAllIndicesMetrics.getIndicesStats().getShards().getIndices()); + assertEquals(0, statsResponseWithAllIndicesMetrics.getIndicesStats().getShards().getTotal()); + assertEquals(0, statsResponseWithAllIndicesMetrics.getIndicesStats().getShards().getPrimaries()); + assertEquals(0, statsResponseWithAllIndicesMetrics.getIndicesStats().getDocs().getCount()); + assertEquals(0, statsResponseWithAllIndicesMetrics.getIndicesStats().getDocs().getDeleted()); + assertEquals(0, statsResponseWithAllIndicesMetrics.getIndicesStats().getDocs().getTotalSizeInBytes()); + assertEquals(0, statsResponseWithAllIndicesMetrics.getIndicesStats().getStore().getSizeInBytes()); + assertEquals(new ByteSizeValue(0), statsResponseWithAllIndicesMetrics.getIndicesStats().getStore().getReservedSize()); + assertEquals(new ByteSizeValue(0), statsResponseWithAllIndicesMetrics.getIndicesStats().getFieldData().getMemorySize()); + assertEquals(0, statsResponseWithAllIndicesMetrics.getIndicesStats().getFieldData().getEvictions()); + assertNull(statsResponseWithAllIndicesMetrics.getIndicesStats().getFieldData().getFields()); + assertEquals(0, statsResponseWithAllIndicesMetrics.getIndicesStats().getSegments().getCount()); + assertEquals(0, statsResponseWithAllIndicesMetrics.getIndicesStats().getSegments().getIndexWriterMemoryInBytes()); + assertEquals(0, statsResponseWithAllIndicesMetrics.getIndicesStats().getSegments().getVersionMapMemoryInBytes()); + } + private void validateNodeStatsOutput(Set expectedMetrics, ClusterStatsResponse clusterStatsResponse) { // Ingest, network types, discovery types and packaging types stats are not included here as they don't have a get method exposed. Set NodeMetrics = Set.of(Metric.OS, Metric.JVM, Metric.FS, Metric.PROCESS, Metric.PLUGINS); 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 55fd62940fb86..9620c682e746f 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 @@ -49,7 +49,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import java.util.function.Consumer; /** * Cluster Stats per index @@ -83,46 +82,11 @@ public ClusterStatsIndices( ) { Map countsPerIndex = new HashMap<>(); this.docs = indicesMetrics.contains(IndexMetric.DOCS) ? new DocsStats() : null; - Consumer docsStatsConsumer = (docs) -> { - if (this.docs != null) { - this.docs.add(docs); - } - }; - this.store = indicesMetrics.contains(IndexMetric.STORE) ? new StoreStats() : null; - Consumer storeStatsConsumer = (store) -> { - if (this.store != null) { - this.store.add(store); - } - }; - this.fieldData = indicesMetrics.contains(IndexMetric.FIELDDATA) ? new FieldDataStats() : null; - Consumer fieldDataConsumer = (fieldDataStats) -> { - if (this.fieldData != null) { - this.fieldData.add(fieldDataStats); - } - }; - this.queryCache = indicesMetrics.contains(IndexMetric.QUERY_CACHE) ? new QueryCacheStats() : null; - Consumer queryCacheStatsConsumer = (queryCacheStats) -> { - if (this.queryCache != null) { - this.queryCache.add(queryCacheStats); - } - }; - this.completion = indicesMetrics.contains(IndexMetric.COMPLETION) ? new CompletionStats() : null; - Consumer completionStatsConsumer = (completionStats) -> { - if (this.completion != null) { - this.completion.add(completionStats); - } - }; - this.segments = indicesMetrics.contains(IndexMetric.SEGMENTS) ? new SegmentsStats() : null; - Consumer segmentsStatsConsumer = (segmentsStats) -> { - if (this.segments != null) { - this.segments.add(segmentsStats); - } - }; for (ClusterStatsNodeResponse r : nodeResponses) { // Aggregated response from the node @@ -139,12 +103,24 @@ public ClusterStatsIndices( } } - docsStatsConsumer.accept(r.getAggregatedNodeLevelStats().commonStats.docs); - storeStatsConsumer.accept(r.getAggregatedNodeLevelStats().commonStats.store); - fieldDataConsumer.accept(r.getAggregatedNodeLevelStats().commonStats.fieldData); - queryCacheStatsConsumer.accept(r.getAggregatedNodeLevelStats().commonStats.queryCache); - completionStatsConsumer.accept(r.getAggregatedNodeLevelStats().commonStats.completion); - segmentsStatsConsumer.accept(r.getAggregatedNodeLevelStats().commonStats.segments); + if (docs != null) { + docs.add(r.getAggregatedNodeLevelStats().commonStats.docs); + } + if (store != null) { + store.add(r.getAggregatedNodeLevelStats().commonStats.store); + } + if (fieldData != null) { + fieldData.add(r.getAggregatedNodeLevelStats().commonStats.fieldData); + } + if (queryCache != null) { + queryCache.add(r.getAggregatedNodeLevelStats().commonStats.queryCache); + } + if (completion != null) { + completion.add(r.getAggregatedNodeLevelStats().commonStats.completion); + } + if (segments != null) { + segments.add(r.getAggregatedNodeLevelStats().commonStats.segments); + } } else { // Default response from the node for (org.opensearch.action.admin.indices.stats.ShardStats shardStats : r.shardsStats()) { @@ -160,13 +136,25 @@ public ClusterStatsIndices( if (shardStats.getShardRouting().primary()) { indexShardStats.primaries++; - docsStatsConsumer.accept(shardCommonStats.docs); + if (docs != null) { + docs.add(shardCommonStats.docs); + } + } + if (store != null) { + store.add(shardCommonStats.store); + } + if (fieldData != null) { + fieldData.add(shardCommonStats.fieldData); + } + if (queryCache != null) { + queryCache.add(shardCommonStats.queryCache); + } + if (completion != null) { + completion.add(shardCommonStats.completion); + } + if (segments != null) { + segments.add(shardCommonStats.segments); } - storeStatsConsumer.accept(shardCommonStats.store); - fieldDataConsumer.accept(shardCommonStats.fieldData); - queryCacheStatsConsumer.accept(shardCommonStats.queryCache); - completionStatsConsumer.accept(shardCommonStats.completion); - segmentsStatsConsumer.accept(shardCommonStats.segments); } } } 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 index 8c8284fa36211..8b46f676636fd 100644 --- 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 @@ -150,4 +150,22 @@ public void testAllIndexMetricsRequestWithOtherIndicesMetric() { ); } + public void testIndexMetricsRequestWithoutMetricIndices() { + final HashMap params = new HashMap<>(); + params.put("metric", "os"); + final String indexMetric = randomSubsetOf(1, RestClusterStatsAction.INDEX_METRIC_TO_REQUEST_CONSUMER_MAP.keySet()).get(0); + 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 index metrics [" + indexMetric + "] but indices stats not requested") + ) + ); + } + }