This is an automated email from the ASF dual-hosted git repository.
devmadhuu pushed a commit to branch HDDS-11233
in repository https://gitbox.apache.org/repos/asf/ozone.git
The following commit(s) were added to refs/heads/HDDS-11233 by this push:
new bab81927f1b HDDS-16037. Support Storage Tier per pipeline in Ozone
Admin Datanode List Command (#11066)
bab81927f1b is described below
commit bab81927f1b2099d687a0a500f1a05791c77f324
Author: Anurag Parvatikar <[email protected]>
AuthorDate: Mon Aug 31 10:51:34 2026 +0530
HDDS-16037. Support Storage Tier per pipeline in Ozone Admin Datanode List
Command (#11066)
---
.../hdds/scm/cli/datanode/ListInfoSubcommand.java | 11 ++-
.../scm/cli/datanode/TestListInfoSubcommand.java | 95 ++++++++++++++++++++++
2 files changed, 103 insertions(+), 3 deletions(-)
diff --git
a/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/hdds/scm/cli/datanode/ListInfoSubcommand.java
b/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/hdds/scm/cli/datanode/ListInfoSubcommand.java
index 646bc1ef62f..59ed8f43e8f 100644
---
a/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/hdds/scm/cli/datanode/ListInfoSubcommand.java
+++
b/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/hdds/scm/cli/datanode/ListInfoSubcommand.java
@@ -27,6 +27,7 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.hadoop.hdds.cli.HddsVersionProvider;
+import org.apache.hadoop.hdds.client.StorageTier;
import org.apache.hadoop.hdds.protocol.DatanodeDetails;
import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
import org.apache.hadoop.hdds.scm.cli.ScmSubcommand;
@@ -208,9 +209,9 @@ private void printDatanodeInfo(BasicDatanodeInfo dn) {
p -> pipelineListInfo.append(p.getId().getId().toString())
.append('/').append(p.getReplicationConfig().toString())
.append('/').append(p.getType().toString())
-
.append('/').append(p.getPipelineState().toString()).append('/')
- .append(datanode.getID().equals(p.getLeaderId()) ?
- "Leader" : "Follower")
+ .append('/').append(p.getPipelineState().toString())
+ .append('/').append(datanode.getID().equals(p.getLeaderId()) ?
"Leader" : "Follower")
+
.append('/').append(formatSupportedStorageTier(p.getSupportedStorageTier()))
.append(System.lineSeparator()));
}
} else {
@@ -243,4 +244,8 @@ private void printDatanodeInfo(BasicDatanodeInfo dn) {
System.out.printf("Percentage Used : %.2f%%%n%n", dn.getPercentUsed());
}
}
+
+ private static String formatSupportedStorageTier(StorageTier tier) {
+ return tier == null ? "[]" : "[" + tier.getTierName() + "]";
+ }
}
diff --git
a/hadoop-ozone/cli-admin/src/test/java/org/apache/hadoop/hdds/scm/cli/datanode/TestListInfoSubcommand.java
b/hadoop-ozone/cli-admin/src/test/java/org/apache/hadoop/hdds/scm/cli/datanode/TestListInfoSubcommand.java
index 7a0d3333164..28e76561c51 100644
---
a/hadoop-ozone/cli-admin/src/test/java/org/apache/hadoop/hdds/scm/cli/datanode/TestListInfoSubcommand.java
+++
b/hadoop-ozone/cli-admin/src/test/java/org/apache/hadoop/hdds/scm/cli/datanode/TestListInfoSubcommand.java
@@ -40,13 +40,20 @@
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.apache.hadoop.hdds.client.RatisReplicationConfig;
+import org.apache.hadoop.hdds.client.StorageTier;
+import org.apache.hadoop.hdds.protocol.DatanodeDetails;
import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
+import org.apache.hadoop.hdds.protocol.proto.HddsProtos.ReplicationFactor;
import org.apache.hadoop.hdds.scm.client.ScmClient;
+import org.apache.hadoop.hdds.scm.pipeline.Pipeline;
+import org.apache.hadoop.hdds.scm.pipeline.PipelineID;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
+import org.junit.jupiter.params.provider.EnumSource;
import picocli.CommandLine;
/**
@@ -459,6 +466,94 @@ private void validateOrderingFromTextOutput(String output,
String orderDirection
}
}
+ @ParameterizedTest
+ @EnumSource(value = StorageTier.class, names = {"EMPTY"}, mode =
EnumSource.Mode.EXCLUDE)
+ public void testRelatedPipelineShowsStorageTier(StorageTier tier) throws
Exception {
+ List<HddsProtos.Node> nodes = getNodeDetails();
+ HddsProtos.Node node = nodes.get(0);
+
+ ScmClient scmClient = mock(ScmClient.class);
+ when(scmClient.queryNode(any(), any(), any(), any())).thenReturn(nodes);
+ when(scmClient.listPipelines()).thenReturn(
+ Collections.singletonList(pipelineContaining(node, tier)));
+
+ CommandLine c = new CommandLine(cmd);
+ c.parseArgs();
+ cmd.execute(scmClient);
+
+ String output = outContent.toString(DEFAULT_ENCODING);
+ assertThat(output).containsPattern(
+ "[^/]+/[^/]+/[^/]+/[^/]+/(Leader|Follower)/\\[" + tier.getTierName() +
"\\]");
+ }
+
+ @Test
+ public void testRelatedPipelineOmitsTierWhenNull() throws Exception {
+ List<HddsProtos.Node> nodes = getNodeDetails();
+ HddsProtos.Node node = nodes.get(0);
+
+ ScmClient scmClient = mock(ScmClient.class);
+ when(scmClient.queryNode(any(), any(), any(), any())).thenReturn(nodes);
+ when(scmClient.listPipelines()).thenReturn(
+ Collections.singletonList(pipelineContaining(node, null)));
+
+ CommandLine c = new CommandLine(cmd);
+ c.parseArgs();
+ cmd.execute(scmClient);
+
+ String output = outContent.toString(DEFAULT_ENCODING);
+ assertThat(output).containsPattern(
+
"[^/]+/[^/]+/[^/]+/[^/]+/(Leader|Follower)/\\[\\]").doesNotContain("null");
+ }
+
+ @Test
+ public void testRelatedPipelineShowsLeaderAndFollower() throws Exception {
+ List<HddsProtos.Node> nodes = getNodeDetails();
+ List<HddsProtos.Node> pipelineNodes = nodes.subList(0, 2);
+ DatanodeDetails leader =
DatanodeDetails.getFromProtoBuf(pipelineNodes.get(0).getNodeID());
+
+ ScmClient scmClient = mock(ScmClient.class);
+ when(scmClient.queryNode(any(), any(), any(), any())).thenReturn(nodes);
+ when(scmClient.listPipelines()).thenReturn(
+ Collections.singletonList(pipelineContaining(pipelineNodes, leader,
StorageTier.SSD)));
+
+ CommandLine c = new CommandLine(cmd);
+ c.parseArgs();
+ cmd.execute(scmClient);
+
+ String output = outContent.toString(DEFAULT_ENCODING);
+ String tierName = StorageTier.SSD.getTierName();
+ assertThat(output).containsPattern(
+ "[^/]+/[^/]+/[^/]+/[^/]+/Leader/\\[" + tierName + "\\]");
+ assertThat(output).containsPattern(
+ "[^/]+/[^/]+/[^/]+/[^/]+/Follower/\\[" + tierName + "\\]");
+ }
+
+ private Pipeline pipelineContaining(HddsProtos.Node node, StorageTier tier) {
+ DatanodeDetails dn = DatanodeDetails.getFromProtoBuf(node.getNodeID());
+ return Pipeline.newBuilder()
+ .setId(PipelineID.randomId())
+
.setReplicationConfig(RatisReplicationConfig.getInstance(ReplicationFactor.THREE))
+ .setState(Pipeline.PipelineState.OPEN)
+ .setNodes(Collections.singletonList(dn))
+ .setSupportedStorageTier(tier)
+ .build();
+ }
+
+ private Pipeline pipelineContaining(List<HddsProtos.Node> nodes,
DatanodeDetails leader, StorageTier tier) {
+ List<DatanodeDetails> dns = new ArrayList<>();
+ for (HddsProtos.Node node : nodes) {
+ dns.add(DatanodeDetails.getFromProtoBuf(node.getNodeID()));
+ }
+ return Pipeline.newBuilder()
+ .setId(PipelineID.randomId())
+
.setReplicationConfig(RatisReplicationConfig.getInstance(ReplicationFactor.THREE))
+ .setState(Pipeline.PipelineState.OPEN)
+ .setNodes(dns)
+ .setLeaderId(leader.getID())
+ .setSupportedStorageTier(tier)
+ .build();
+ }
+
private List<HddsProtos.Node> getNodeDetails() {
List<HddsProtos.Node> nodes = new ArrayList<>();
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]