diff --git a/hadoop-hdds/tools/src/main/java/org/apache/hadoop/hdds/scm/cli/datanode/ListInfoSubcommand.java b/hadoop-hdds/tools/src/main/java/org/apache/hadoop/hdds/scm/cli/datanode/ListInfoSubcommand.java index 53da0825927f..236d0c3dafb7 100644 --- a/hadoop-hdds/tools/src/main/java/org/apache/hadoop/hdds/scm/cli/datanode/ListInfoSubcommand.java +++ b/hadoop-hdds/tools/src/main/java/org/apache/hadoop/hdds/scm/cli/datanode/ListInfoSubcommand.java @@ -76,12 +76,13 @@ public void execute(ScmClient scmClient) throws IOException { private List getAllNodes(ScmClient scmClient) throws IOException { List nodes = scmClient.queryNode(null, - HddsProtos.NodeState.HEALTHY, HddsProtos.QueryScope.CLUSTER, ""); + null, HddsProtos.QueryScope.CLUSTER, ""); return nodes.stream() .map(p -> new DatanodeWithAttributes( DatanodeDetails.getFromProtoBuf(p.getNodeID()), p.getNodeOperationalStates(0), p.getNodeStates(0))) + .sorted((o1, o2) -> o1.healthState.compareTo(o2.healthState)) .collect(Collectors.toList()); } @@ -114,6 +115,7 @@ private void printDatanodeInfo(DatanodeWithAttributes dna) { + "/" + datanode.getHostName() + "/" + relatedPipelineNum + " pipelines)"); System.out.println("Operational State: " + dna.getOpState()); + System.out.println("Health State: " + dna.getHealthState()); System.out.println("Related pipelines:\n" + pipelineListInfo); } diff --git a/hadoop-hdds/tools/src/test/java/org/apache/hadoop/hdds/scm/cli/datanode/TestListInfoSubcommand.java b/hadoop-hdds/tools/src/test/java/org/apache/hadoop/hdds/scm/cli/datanode/TestListInfoSubcommand.java index ba8d46849b54..b6af473d6f7d 100644 --- a/hadoop-hdds/tools/src/test/java/org/apache/hadoop/hdds/scm/cli/datanode/TestListInfoSubcommand.java +++ b/hadoop-hdds/tools/src/test/java/org/apache/hadoop/hdds/scm/cli/datanode/TestListInfoSubcommand.java @@ -65,7 +65,8 @@ public void tearDown() { } @Test - public void testDataNodeOperationalStateIncludedInOutput() throws Exception { + public void testDataNodeOperationalStateAndHealthIncludedInOutput() + throws Exception { ScmClient scmClient = mock(ScmClient.class); Mockito.when(scmClient.queryNode(any(HddsProtos.NodeOperationalState.class), any(HddsProtos.NodeState.class), any(HddsProtos.QueryScope.class), @@ -89,12 +90,22 @@ public void testDataNodeOperationalStateIncludedInOutput() throws Exception { "^Operational State:\\s+DECOMMISSIONING$", Pattern.MULTILINE); m = p.matcher(outContent.toString(DEFAULT_ENCODING)); assertTrue(m.find()); + for (HddsProtos.NodeState state : HddsProtos.NodeState.values()) { + p = Pattern.compile( + "^Health State:\\s+"+state+"$", Pattern.MULTILINE); + m = p.matcher(outContent.toString(DEFAULT_ENCODING)); + assertTrue(m.find()); + } + // Ensure the nodes are ordered by health state HEALTHY, STALE, DEAD + p = Pattern.compile(".+HEALTHY.+STALE.+DEAD.+", Pattern.DOTALL); + m = p.matcher(outContent.toString(DEFAULT_ENCODING)); + assertTrue(m.find()); } private List getNodeDetails() { List nodes = new ArrayList<>(); - for (int i=0; i<2; i++) { + for (int i=0; i<3; i++) { HddsProtos.DatanodeDetailsProto.Builder dnd = HddsProtos.DatanodeDetailsProto.newBuilder(); dnd.setHostName("host" + i); @@ -109,11 +120,16 @@ private List getNodeDetails() { if (i == 0) { builder.addNodeOperationalStates( HddsProtos.NodeOperationalState.IN_SERVICE); - } else { + builder.addNodeStates(HddsProtos.NodeState.STALE); + } else if (i == 1) { builder.addNodeOperationalStates( HddsProtos.NodeOperationalState.DECOMMISSIONING); + builder.addNodeStates(HddsProtos.NodeState.DEAD); + } else { + builder.addNodeOperationalStates( + HddsProtos.NodeOperationalState.IN_SERVICE); + builder.addNodeStates(HddsProtos.NodeState.HEALTHY); } - builder.addNodeStates(HddsProtos.NodeState.HEALTHY); builder.setNodeID(dnd.build()); nodes.add(builder.build()); }