This is an automated email from the ASF dual-hosted git repository.
sodonnell pushed a commit to branch HDDS-1880-Decom
in repository https://gitbox.apache.org/repos/asf/hadoop-ozone.git
The following commit(s) were added to refs/heads/HDDS-1880-Decom by this push:
new f64476c HDDS-4340. Add Operational State to the datanode list command
(#1491)
f64476c is described below
commit f64476c06e6268fbec683f6104ff39876adbb90c
Author: Stephen O'Donnell <[email protected]>
AuthorDate: Wed Oct 21 17:10:30 2020 +0100
HDDS-4340. Add Operational State to the datanode list command (#1491)
---
hadoop-hdds/tools/pom.xml | 6 ++
.../hdds/scm/cli/datanode/ListInfoSubcommand.java | 46 ++++++--
.../scm/cli/datanode/TestListInfoSubcommand.java | 119 +++++++++++++++++++++
3 files changed, 164 insertions(+), 7 deletions(-)
diff --git a/hadoop-hdds/tools/pom.xml b/hadoop-hdds/tools/pom.xml
index dfda5a6..9da6f93 100644
--- a/hadoop-hdds/tools/pom.xml
+++ b/hadoop-hdds/tools/pom.xml
@@ -78,6 +78,12 @@ https://maven.apache.org/xsd/maven-4.0.0.xsd">
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <version>${mockito1-hadoop.version}</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
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 2ce9c87..38ad390 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
@@ -60,30 +60,34 @@ public class ListInfoSubcommand extends ScmSubcommand {
if (Strings.isNullOrEmpty(ipaddress) && Strings.isNullOrEmpty(uuid)) {
getAllNodes(scmClient).forEach(this::printDatanodeInfo);
} else {
- Stream<DatanodeDetails> allNodes = getAllNodes(scmClient).stream();
+ Stream<DatanodeWithAttributes> allNodes =
getAllNodes(scmClient).stream();
if (!Strings.isNullOrEmpty(ipaddress)) {
- allNodes = allNodes.filter(p -> p.getIpAddress()
+ allNodes = allNodes.filter(p -> p.getDatanodeDetails().getIpAddress()
.compareToIgnoreCase(ipaddress) == 0);
}
if (!Strings.isNullOrEmpty(uuid)) {
- allNodes = allNodes.filter(p -> p.getUuid().toString().equals(uuid));
+ allNodes = allNodes.filter(p ->
+ p.getDatanodeDetails().toString().equals(uuid));
}
allNodes.forEach(this::printDatanodeInfo);
}
}
- private List<DatanodeDetails> getAllNodes(ScmClient scmClient)
+ private List<DatanodeWithAttributes> getAllNodes(ScmClient scmClient)
throws IOException {
List<HddsProtos.Node> nodes = scmClient.queryNode(null,
HddsProtos.NodeState.HEALTHY, HddsProtos.QueryScope.CLUSTER, "");
return nodes.stream()
- .map(p -> DatanodeDetails.getFromProtoBuf(p.getNodeID()))
+ .map(p -> new DatanodeWithAttributes(
+ DatanodeDetails.getFromProtoBuf(p.getNodeID()),
+ p.getNodeOperationalStates(0), p.getNodeStates(0)))
.collect(Collectors.toList());
}
- private void printDatanodeInfo(DatanodeDetails datanode) {
+ private void printDatanodeInfo(DatanodeWithAttributes dna) {
StringBuilder pipelineListInfo = new StringBuilder();
+ DatanodeDetails datanode = dna.getDatanodeDetails();
int relatedPipelineNum = 0;
if (!pipelines.isEmpty()) {
List<Pipeline> relatedPipelines = pipelines.stream().filter(
@@ -108,6 +112,34 @@ public class ListInfoSubcommand extends ScmSubcommand {
System.out.println("Datanode: " + datanode.getUuid().toString() +
" (" + datanode.getNetworkLocation() + "/" + datanode.getIpAddress()
+ "/" + datanode.getHostName() + "/" + relatedPipelineNum +
- " pipelines) \n" + "Related pipelines: \n" + pipelineListInfo);
+ " pipelines)");
+ System.out.println("Operational State: " + dna.getOpState());
+ System.out.println("Related pipelines: \n" + pipelineListInfo);
+ }
+
+ private static class DatanodeWithAttributes {
+ private DatanodeDetails datanodeDetails;
+ private HddsProtos.NodeOperationalState operationalState;
+ private HddsProtos.NodeState healthState;
+
+ DatanodeWithAttributes(DatanodeDetails dn,
+ HddsProtos.NodeOperationalState opState,
+ HddsProtos.NodeState healthState) {
+ this.datanodeDetails = dn;
+ this.operationalState = opState;
+ this.healthState = healthState;
+ }
+
+ public DatanodeDetails getDatanodeDetails() {
+ return datanodeDetails;
+ }
+
+ public HddsProtos.NodeOperationalState getOpState() {
+ return operationalState;
+ }
+
+ public HddsProtos.NodeState getHealthState() {
+ return healthState;
+ }
}
}
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
new file mode 100644
index 0000000..45d4d7b
--- /dev/null
+++
b/hadoop-hdds/tools/src/test/java/org/apache/hadoop/hdds/scm/cli/datanode/TestListInfoSubcommand.java
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hdds.scm.cli.datanode;
+
+import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
+import org.apache.hadoop.hdds.scm.client.ScmClient;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.mockito.Mockito;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.any;
+
+/**
+ * Unit tests to validate the the TestListInfoSubCommand class includes the
+ * correct output when executed against a mock client.
+ */
+public class TestListInfoSubcommand {
+
+ private ListInfoSubcommand cmd;
+ private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
+ private final ByteArrayOutputStream errContent = new ByteArrayOutputStream();
+ private final PrintStream originalOut = System.out;
+ private final PrintStream originalErr = System.err;
+
+ @Before
+ public void setup() {
+ cmd = new ListInfoSubcommand();
+ System.setOut(new PrintStream(outContent));
+ System.setErr(new PrintStream(errContent));
+ }
+
+ @After
+ public void tearDown() {
+ System.setOut(originalOut);
+ System.setErr(originalErr);
+ }
+
+ @Test
+ public void testDataNodeOperationalStateIncludedInOutput() throws Exception {
+ ScmClient scmClient = mock(ScmClient.class);
+
Mockito.when(scmClient.queryNode(any(HddsProtos.NodeOperationalState.class),
+ any(HddsProtos.NodeState.class), any(HddsProtos.QueryScope.class),
+ Mockito.anyString()))
+ .thenAnswer(invocation -> getNodeDetails());
+ Mockito.when(scmClient.listPipelines())
+ .thenReturn(new ArrayList<>());
+
+ cmd.execute(scmClient);
+
+ // The output should contain a string like:
+ // <other lines>
+ // Operational State: <STATE>
+ // <other lines>
+ Pattern p = Pattern.compile(
+ "^Operational State:\\s+IN_SERVICE$", Pattern.MULTILINE);
+ Matcher m = p.matcher(outContent.toString());
+ assertTrue(m.find());
+ // Should also have a node with the state DECOMMISSIONING
+ p = Pattern.compile(
+ "^Operational State:\\s+DECOMMISSIONING$", Pattern.MULTILINE);
+ m = p.matcher(outContent.toString());
+ assertTrue(m.find());
+ }
+
+ private List<HddsProtos.Node> getNodeDetails() {
+ List<HddsProtos.Node> nodes = new ArrayList<>();
+
+ for (int i=0; i<2; i++) {
+ HddsProtos.DatanodeDetailsProto.Builder dnd =
+ HddsProtos.DatanodeDetailsProto.newBuilder();
+ dnd.setHostName("host" + i);
+ dnd.setIpAddress("1.2.3." + i+1);
+ dnd.setNetworkLocation("/default");
+ dnd.setNetworkName("host" + i);
+ dnd.addPorts(HddsProtos.Port.newBuilder()
+ .setName("ratis").setValue(5678).build());
+ dnd.setUuid(UUID.randomUUID().toString());
+
+ HddsProtos.Node.Builder builder = HddsProtos.Node.newBuilder();
+ if (i == 0) {
+ builder.addNodeOperationalStates(
+ HddsProtos.NodeOperationalState.IN_SERVICE);
+ } else {
+ builder.addNodeOperationalStates(
+ HddsProtos.NodeOperationalState.DECOMMISSIONING);
+ }
+ builder.addNodeStates(HddsProtos.NodeState.HEALTHY);
+ builder.setNodeID(dnd.build());
+ nodes.add(builder.build());
+ }
+ return nodes;
+ }
+}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]