From 0696dfd5176bd29e4eec3759af36f9ea9da4a89d Mon Sep 17 00:00:00 2001 From: Vinay Krishna Pudyodu Date: Tue, 1 Apr 2025 16:15:53 -0700 Subject: [PATCH 1/4] Include search replica in _cat/indices response Signed-off-by: Vinay Krishna Pudyodu --- .../cluster/health/ClusterIndexHealth.java | 19 ++++++++++++++ .../rest/action/cat/RestIndicesAction.java | 2 ++ .../health/ClusterIndexHealthTests.java | 26 +++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/server/src/main/java/org/opensearch/cluster/health/ClusterIndexHealth.java b/server/src/main/java/org/opensearch/cluster/health/ClusterIndexHealth.java index 77d96cb0af792..ffe6f15d7fdf1 100644 --- a/server/src/main/java/org/opensearch/cluster/health/ClusterIndexHealth.java +++ b/server/src/main/java/org/opensearch/cluster/health/ClusterIndexHealth.java @@ -71,6 +71,7 @@ public final class ClusterIndexHealth implements Iterable, W private static final String STATUS = "status"; private static final String NUMBER_OF_SHARDS = "number_of_shards"; private static final String NUMBER_OF_REPLICAS = "number_of_replicas"; + private static final String NUMBER_OF_SEARCH_REPLICAS = "number_of_search_replicas"; private static final String ACTIVE_PRIMARY_SHARDS = "active_primary_shards"; private static final String ACTIVE_SHARDS = "active_shards"; private static final String RELOCATING_SHARDS = "relocating_shards"; @@ -85,6 +86,7 @@ public final class ClusterIndexHealth implements Iterable, W int i = 0; int numberOfShards = (int) parsedObjects[i++]; int numberOfReplicas = (int) parsedObjects[i++]; + int numberOfSearchReplicas = (int) parsedObjects[i++]; int activeShards = (int) parsedObjects[i++]; int relocatingShards = (int) parsedObjects[i++]; int initializingShards = (int) parsedObjects[i++]; @@ -107,6 +109,7 @@ public final class ClusterIndexHealth implements Iterable, W index, numberOfShards, numberOfReplicas, + numberOfSearchReplicas, activeShards, relocatingShards, initializingShards, @@ -126,6 +129,7 @@ public final class ClusterIndexHealth implements Iterable, W static { PARSER.declareInt(constructorArg(), new ParseField(NUMBER_OF_SHARDS)); PARSER.declareInt(constructorArg(), new ParseField(NUMBER_OF_REPLICAS)); + PARSER.declareInt(constructorArg(), new ParseField(NUMBER_OF_SEARCH_REPLICAS)); PARSER.declareInt(constructorArg(), new ParseField(ACTIVE_SHARDS)); PARSER.declareInt(constructorArg(), new ParseField(RELOCATING_SHARDS)); PARSER.declareInt(constructorArg(), new ParseField(INITIALIZING_SHARDS)); @@ -139,6 +143,7 @@ public final class ClusterIndexHealth implements Iterable, W private final String index; private final int numberOfShards; private final int numberOfReplicas; + private final int numberOfSearchReplicas; private final int activeShards; private final int relocatingShards; private final int initializingShards; @@ -152,6 +157,7 @@ public ClusterIndexHealth(final IndexMetadata indexMetadata, final IndexRoutingT this.index = indexMetadata.getIndex().getName(); this.numberOfShards = indexMetadata.getNumberOfShards(); this.numberOfReplicas = indexMetadata.getNumberOfReplicas(); + this.numberOfSearchReplicas = indexMetadata.getNumberOfSearchOnlyReplicas(); shards = new HashMap<>(); for (IndexShardRoutingTable shardRoutingTable : indexRoutingTable) { @@ -200,6 +206,7 @@ public ClusterIndexHealth( this.index = indexMetadata.getIndex().getName(); this.numberOfShards = indexMetadata.getNumberOfShards(); this.numberOfReplicas = indexMetadata.getNumberOfReplicas(); + this.numberOfSearchReplicas = indexMetadata.getNumberOfSearchOnlyReplicas(); shards = new HashMap<>(); @@ -299,6 +306,7 @@ public ClusterIndexHealth(final StreamInput in) throws IOException { index = in.readString(); numberOfShards = in.readVInt(); numberOfReplicas = in.readVInt(); + numberOfSearchReplicas = in.readVInt(); activePrimaryShards = in.readVInt(); activeShards = in.readVInt(); relocatingShards = in.readVInt(); @@ -321,6 +329,7 @@ public ClusterIndexHealth(final StreamInput in) throws IOException { String index, int numberOfShards, int numberOfReplicas, + int numberOfSearchReplicas, int activeShards, int relocatingShards, int initializingShards, @@ -332,6 +341,7 @@ public ClusterIndexHealth(final StreamInput in) throws IOException { this.index = index; this.numberOfShards = numberOfShards; this.numberOfReplicas = numberOfReplicas; + this.numberOfSearchReplicas = numberOfSearchReplicas; this.activeShards = activeShards; this.relocatingShards = relocatingShards; this.initializingShards = initializingShards; @@ -353,6 +363,10 @@ public int getNumberOfReplicas() { return numberOfReplicas; } + public int getNumberOfSearchReplicas() { + return numberOfSearchReplicas; + } + public int getActiveShards() { return activeShards; } @@ -395,6 +409,7 @@ public void writeTo(final StreamOutput out) throws IOException { out.writeString(index); out.writeVInt(numberOfShards); out.writeVInt(numberOfReplicas); + out.writeVInt(numberOfSearchReplicas); out.writeVInt(activePrimaryShards); out.writeVInt(activeShards); out.writeVInt(relocatingShards); @@ -410,6 +425,7 @@ public XContentBuilder toXContent(final XContentBuilder builder, final Params pa builder.field(STATUS, getStatus().name().toLowerCase(Locale.ROOT)); builder.field(NUMBER_OF_SHARDS, getNumberOfShards()); builder.field(NUMBER_OF_REPLICAS, getNumberOfReplicas()); + builder.field(NUMBER_OF_SEARCH_REPLICAS, getNumberOfSearchReplicas()); builder.field(ACTIVE_PRIMARY_SHARDS, getActivePrimaryShards()); builder.field(ACTIVE_SHARDS, getActiveShards()); builder.field(RELOCATING_SHARDS, getRelocatingShards()); @@ -451,6 +467,8 @@ public String toString() { + numberOfShards + ", numberOfReplicas=" + numberOfReplicas + + ", numberOfSearchReplicas=" + + numberOfSearchReplicas + ", activeShards=" + activeShards + ", relocatingShards=" @@ -476,6 +494,7 @@ public boolean equals(Object o) { return Objects.equals(index, that.index) && numberOfShards == that.numberOfShards && numberOfReplicas == that.numberOfReplicas + && numberOfSearchReplicas == that.numberOfSearchReplicas && activeShards == that.activeShards && relocatingShards == that.relocatingShards && initializingShards == that.initializingShards diff --git a/server/src/main/java/org/opensearch/rest/action/cat/RestIndicesAction.java b/server/src/main/java/org/opensearch/rest/action/cat/RestIndicesAction.java index 34299124aa2d3..58f22ac5971ab 100644 --- a/server/src/main/java/org/opensearch/rest/action/cat/RestIndicesAction.java +++ b/server/src/main/java/org/opensearch/rest/action/cat/RestIndicesAction.java @@ -420,6 +420,7 @@ protected Table getTableWithHeader(final RestRequest request, final PageToken pa table.addCell("uuid", "alias:id,uuid;desc:index uuid"); table.addCell("pri", "alias:p,shards.primary,shardsPrimary;text-align:right;desc:number of primary shards"); table.addCell("rep", "alias:r,shards.replica,shardsReplica;text-align:right;desc:number of replica shards"); + table.addCell("srep", "alias:s,shards.searchReplica,shardsSearchReplica;text-align:right;desc:number of search replica shards"); table.addCell("docs.count", "alias:dc,docsCount;text-align:right;desc:available docs"); table.addCell("docs.deleted", "alias:dd,docsDeleted;text-align:right;desc:deleted docs"); @@ -847,6 +848,7 @@ protected Table buildTable( table.addCell(indexMetadata.getIndexUUID()); table.addCell(indexHealth == null ? null : indexHealth.getNumberOfShards()); table.addCell(indexHealth == null ? null : indexHealth.getNumberOfReplicas()); + table.addCell(indexHealth == null ? null : indexHealth.getNumberOfSearchReplicas()); table.addCell(primaryStats.getDocs() == null ? null : primaryStats.getDocs().getCount()); table.addCell(primaryStats.getDocs() == null ? null : primaryStats.getDocs().getDeleted()); diff --git a/server/src/test/java/org/opensearch/cluster/health/ClusterIndexHealthTests.java b/server/src/test/java/org/opensearch/cluster/health/ClusterIndexHealthTests.java index 0d542c211ac76..13f372df1b6b1 100644 --- a/server/src/test/java/org/opensearch/cluster/health/ClusterIndexHealthTests.java +++ b/server/src/test/java/org/opensearch/cluster/health/ClusterIndexHealthTests.java @@ -125,6 +125,7 @@ public static ClusterIndexHealth randomIndexHealth(String indexName, ClusterHeal randomInt(1000), randomInt(1000), randomInt(1000), + randomInt(1000), randomFrom(ClusterHealthStatus.values()), shards ); @@ -164,6 +165,7 @@ protected ClusterIndexHealth mutateInstance(ClusterIndexHealth instance) throws "index", "numberOfShards", "numberOfReplicas", + "numberOfSearchReplicas", "activeShards", "relocatingShards", "initializingShards", @@ -178,6 +180,7 @@ protected ClusterIndexHealth mutateInstance(ClusterIndexHealth instance) throws instance.getIndex() + randomAlphaOfLengthBetween(2, 5), instance.getNumberOfShards(), instance.getNumberOfReplicas(), + instance.getNumberOfSearchReplicas(), instance.getActiveShards(), instance.getRelocatingShards(), instance.getInitializingShards(), @@ -191,6 +194,7 @@ protected ClusterIndexHealth mutateInstance(ClusterIndexHealth instance) throws instance.getIndex(), instance.getNumberOfShards() + between(1, 10), instance.getNumberOfReplicas(), + instance.getNumberOfSearchReplicas(), instance.getActiveShards(), instance.getRelocatingShards(), instance.getInitializingShards(), @@ -204,6 +208,21 @@ protected ClusterIndexHealth mutateInstance(ClusterIndexHealth instance) throws instance.getIndex(), instance.getNumberOfShards(), instance.getNumberOfReplicas() + between(1, 10), + instance.getNumberOfSearchReplicas(), + instance.getActiveShards(), + instance.getRelocatingShards(), + instance.getInitializingShards(), + instance.getUnassignedShards(), + instance.getActivePrimaryShards(), + instance.getStatus(), + instance.getShards() + ); + case "numberOfSearchReplicas": + return new ClusterIndexHealth( + instance.getIndex(), + instance.getNumberOfShards(), + instance.getNumberOfReplicas(), + instance.getNumberOfSearchReplicas() + between(1, 10), instance.getActiveShards(), instance.getRelocatingShards(), instance.getInitializingShards(), @@ -217,6 +236,7 @@ protected ClusterIndexHealth mutateInstance(ClusterIndexHealth instance) throws instance.getIndex(), instance.getNumberOfShards(), instance.getNumberOfReplicas(), + instance.getNumberOfSearchReplicas(), instance.getActiveShards() + between(1, 10), instance.getRelocatingShards(), instance.getInitializingShards(), @@ -230,6 +250,7 @@ protected ClusterIndexHealth mutateInstance(ClusterIndexHealth instance) throws instance.getIndex(), instance.getNumberOfShards(), instance.getNumberOfReplicas(), + instance.getNumberOfSearchReplicas(), instance.getActiveShards(), instance.getRelocatingShards() + between(1, 10), instance.getInitializingShards(), @@ -243,6 +264,7 @@ protected ClusterIndexHealth mutateInstance(ClusterIndexHealth instance) throws instance.getIndex(), instance.getNumberOfShards(), instance.getNumberOfReplicas(), + instance.getNumberOfSearchReplicas(), instance.getActiveShards(), instance.getRelocatingShards(), instance.getInitializingShards() + between(1, 10), @@ -256,6 +278,7 @@ protected ClusterIndexHealth mutateInstance(ClusterIndexHealth instance) throws instance.getIndex(), instance.getNumberOfShards(), instance.getNumberOfReplicas(), + instance.getNumberOfSearchReplicas(), instance.getActiveShards(), instance.getRelocatingShards(), instance.getInitializingShards(), @@ -269,6 +292,7 @@ protected ClusterIndexHealth mutateInstance(ClusterIndexHealth instance) throws instance.getIndex(), instance.getNumberOfShards(), instance.getNumberOfReplicas(), + instance.getNumberOfSearchReplicas(), instance.getActiveShards(), instance.getRelocatingShards(), instance.getInitializingShards(), @@ -287,6 +311,7 @@ protected ClusterIndexHealth mutateInstance(ClusterIndexHealth instance) throws instance.getIndex(), instance.getNumberOfShards(), instance.getNumberOfReplicas(), + instance.getNumberOfSearchReplicas(), instance.getActiveShards(), instance.getRelocatingShards(), instance.getInitializingShards(), @@ -307,6 +332,7 @@ protected ClusterIndexHealth mutateInstance(ClusterIndexHealth instance) throws instance.getIndex(), instance.getNumberOfShards(), instance.getNumberOfReplicas(), + instance.getNumberOfSearchReplicas(), instance.getActiveShards(), instance.getRelocatingShards(), instance.getInitializingShards(), From e8a6fdb252d03c678a124d1f8f89cd910f2d7438 Mon Sep 17 00:00:00 2001 From: Vinay Krishna Pudyodu Date: Tue, 1 Apr 2025 17:18:48 -0700 Subject: [PATCH 2/4] Add changelog Signed-off-by: Vinay Krishna Pudyodu --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 448e5361e3fc4..e4496f93f3862 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Added Kinesis support as a plugin for the pull-based ingestion ([#17615](https://github.com/opensearch-project/OpenSearch/pull/17615)) - [Security Manager Replacement] Create initial Java Agent to intercept Socket::connect calls ([#17724](https://github.com/opensearch-project/OpenSearch/pull/17724)) - Add ingestion management APIs for pause, resume and get ingestion state ([#17631](https://github.com/opensearch-project/OpenSearch/pull/17631)) +- Include search replica in _cat/indices response ([#17756](https://github.com/opensearch-project/OpenSearch/pull/17756)) ### Changed - Migrate BC libs to their FIPS counterparts ([#14912](https://github.com/opensearch-project/OpenSearch/pull/14912)) From 5960fe661c9eeaff6e7422578fbc0d8d71cd44fd Mon Sep 17 00:00:00 2001 From: Vinay Krishna Pudyodu Date: Wed, 2 Apr 2025 11:09:11 -0700 Subject: [PATCH 3/4] Added bwc conditions Signed-off-by: Vinay Krishna Pudyodu --- .../opensearch/cluster/health/ClusterIndexHealth.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/org/opensearch/cluster/health/ClusterIndexHealth.java b/server/src/main/java/org/opensearch/cluster/health/ClusterIndexHealth.java index ffe6f15d7fdf1..eb90f014988f0 100644 --- a/server/src/main/java/org/opensearch/cluster/health/ClusterIndexHealth.java +++ b/server/src/main/java/org/opensearch/cluster/health/ClusterIndexHealth.java @@ -32,6 +32,7 @@ package org.opensearch.cluster.health; +import org.opensearch.Version; import org.opensearch.action.admin.cluster.health.ClusterHealthRequest; import org.opensearch.cluster.metadata.IndexMetadata; import org.opensearch.cluster.routing.IndexRoutingTable; @@ -306,7 +307,11 @@ public ClusterIndexHealth(final StreamInput in) throws IOException { index = in.readString(); numberOfShards = in.readVInt(); numberOfReplicas = in.readVInt(); - numberOfSearchReplicas = in.readVInt(); + if (in.getVersion().onOrAfter(Version.V_3_0_0)) { + numberOfSearchReplicas = in.readVInt(); + } else { + numberOfSearchReplicas = 0; + } activePrimaryShards = in.readVInt(); activeShards = in.readVInt(); relocatingShards = in.readVInt(); @@ -409,7 +414,9 @@ public void writeTo(final StreamOutput out) throws IOException { out.writeString(index); out.writeVInt(numberOfShards); out.writeVInt(numberOfReplicas); - out.writeVInt(numberOfSearchReplicas); + if (out.getVersion().onOrAfter(Version.V_3_0_0)) { + out.writeVInt(numberOfSearchReplicas); + } out.writeVInt(activePrimaryShards); out.writeVInt(activeShards); out.writeVInt(relocatingShards); From cd7259a137abcc58c99da40bc5bd8702a2c6959b Mon Sep 17 00:00:00 2001 From: Vinay Krishna Pudyodu Date: Wed, 2 Apr 2025 12:04:55 -0700 Subject: [PATCH 4/4] Updated rest-api-spec test for cat indices Signed-off-by: Vinay Krishna Pudyodu --- .../resources/rest-api-spec/test/cat.indices/10_basic.yml | 2 ++ .../resources/rest-api-spec/test/cat.indices/20_hidden.yml | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/cat.indices/10_basic.yml b/rest-api-spec/src/main/resources/rest-api-spec/test/cat.indices/10_basic.yml index 7b62bd90052ac..52c8636d4159c 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/test/cat.indices/10_basic.yml +++ b/rest-api-spec/src/main/resources/rest-api-spec/test/cat.indices/10_basic.yml @@ -30,6 +30,7 @@ 0 \s+ 0 \s+ 0 \s+ + 0 \s+ (\d+|\d+[.]\d+)(kb|b) \s+ (\d+|\d+[.]\d+)(kb|b) \s* ) @@ -124,6 +125,7 @@ index-2 \s+ ([a-zA-Z0-9=/_+]|[\\\-]){22} \s+ 3 \s+ + 0 \s+ 0 \s+ \s+ \s+ diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/cat.indices/20_hidden.yml b/rest-api-spec/src/main/resources/rest-api-spec/test/cat.indices/20_hidden.yml index 7a8cf51d4a129..eeb7d47163e76 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/test/cat.indices/20_hidden.yml +++ b/rest-api-spec/src/main/resources/rest-api-spec/test/cat.indices/20_hidden.yml @@ -32,6 +32,7 @@ 0 \s+ 0 \s+ 0 \s+ + 0 \s+ (\d+|\d+[.]\d+)(kb|b) \s+ (\d+|\d+[.]\d+)(kb|b) \s* ) @@ -71,6 +72,7 @@ 0 \s+ 0 \s+ 0 \s+ + 0 \s+ (\d+|\d+[.]\d+)(kb|b) \s+ (\d+|\d+[.]\d+)(kb|b) \s* ) @@ -116,6 +118,7 @@ 0 \s+ 0 \s+ 0 \s+ + 0 \s+ (\d+|\d+[.]\d+)(kb|b) \s+ (\d+|\d+[.]\d+)(kb|b) \s* ) @@ -134,6 +137,7 @@ 0 \s+ 0 \s+ 0 \s+ + 0 \s+ (\d+|\d+[.]\d+)(kb|b) \s+ (\d+|\d+[.]\d+)(kb|b) \s* ) @@ -176,6 +180,7 @@ 0 \s+ 0 \s+ 0 \s+ + 0 \s+ (\d+|\d+[.]\d+)(kb|b) \s+ (\d+|\d+[.]\d+)(kb|b) \s* ) @@ -194,6 +199,7 @@ 0 \s+ 0 \s+ 0 \s+ + 0 \s+ (\d+|\d+[.]\d+)(kb|b) \s+ (\d+|\d+[.]\d+)(kb|b) \s* ) @@ -234,6 +240,7 @@ 0 \s+ 0 \s+ 0 \s+ + 0 \s+ (\d+|\d+[.]\d+)(kb|b) \s+ (\d+|\d+[.]\d+)(kb|b) \s* )