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]

Reply via email to