From 73954c1dd98dd9f0aa535aeefcd1484d09fd75dc Mon Sep 17 00:00:00 2001 From: Sammi Chen Date: Thu, 6 Jun 2019 11:13:39 +0800 Subject: [PATCH] HDDS-1612. Add 'scmcli printTopology' shell command to print datanode topology. Contributed by Sammi Chen.(#910) --- .../hadoop/hdds/protocol/DatanodeDetails.java | 2 + hadoop-hdds/common/src/main/proto/hdds.proto | 1 + .../apache/hadoop/hdds/scm/cli/SCMCLI.java | 3 +- .../hdds/scm/cli/TopologySubcommand.java | 80 +++++++++++++++++++ 4 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 hadoop-hdds/tools/src/main/java/org/apache/hadoop/hdds/scm/cli/TopologySubcommand.java diff --git a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/protocol/DatanodeDetails.java b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/protocol/DatanodeDetails.java index be6f44cd41..34de02899d 100644 --- a/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/protocol/DatanodeDetails.java +++ b/hadoop-hdds/common/src/main/java/org/apache/hadoop/hdds/protocol/DatanodeDetails.java @@ -212,6 +212,8 @@ public HddsProtos.DatanodeDetailsProto getProtoBufMessage() { if (certSerialId != null) { builder.setCertSerialId(certSerialId); } + builder.setNetworkLocation(getNetworkLocation()); + for (Port port : ports) { builder.addPorts(HddsProtos.Port.newBuilder() .setName(port.getName().toString()) diff --git a/hadoop-hdds/common/src/main/proto/hdds.proto b/hadoop-hdds/common/src/main/proto/hdds.proto index ddde7ea93a..2d5cb03ba0 100644 --- a/hadoop-hdds/common/src/main/proto/hdds.proto +++ b/hadoop-hdds/common/src/main/proto/hdds.proto @@ -34,6 +34,7 @@ message DatanodeDetailsProto { required string hostName = 3; // hostname repeated Port ports = 4; optional string certSerialId = 5; // Certificate serial id. + optional string networkLocation = 6; // Network topology location } /** diff --git a/hadoop-hdds/tools/src/main/java/org/apache/hadoop/hdds/scm/cli/SCMCLI.java b/hadoop-hdds/tools/src/main/java/org/apache/hadoop/hdds/scm/cli/SCMCLI.java index 5013a74725..1a19a3c3ea 100644 --- a/hadoop-hdds/tools/src/main/java/org/apache/hadoop/hdds/scm/cli/SCMCLI.java +++ b/hadoop-hdds/tools/src/main/java/org/apache/hadoop/hdds/scm/cli/SCMCLI.java @@ -84,7 +84,8 @@ CreateSubcommand.class, CloseSubcommand.class, ListPipelinesSubcommand.class, - ClosePipelineSubcommand.class + ClosePipelineSubcommand.class, + TopologySubcommand.class }, mixinStandardHelpOptions = true) public class SCMCLI extends GenericCli { diff --git a/hadoop-hdds/tools/src/main/java/org/apache/hadoop/hdds/scm/cli/TopologySubcommand.java b/hadoop-hdds/tools/src/main/java/org/apache/hadoop/hdds/scm/cli/TopologySubcommand.java new file mode 100644 index 0000000000..6deccd1dad --- /dev/null +++ b/hadoop-hdds/tools/src/main/java/org/apache/hadoop/hdds/scm/cli/TopologySubcommand.java @@ -0,0 +1,80 @@ +/** + * 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; + +import org.apache.hadoop.hdds.cli.HddsVersionProvider; +import org.apache.hadoop.hdds.protocol.proto.HddsProtos; +import org.apache.hadoop.hdds.scm.client.ScmClient; +import picocli.CommandLine; +import static org.apache.hadoop.hdds.protocol.proto.HddsProtos.NodeState.DEAD; +import static org.apache.hadoop.hdds.protocol.proto.HddsProtos.NodeState.DECOMMISSIONED; +import static org.apache.hadoop.hdds.protocol.proto.HddsProtos.NodeState.DECOMMISSIONING; +import static org.apache.hadoop.hdds.protocol.proto.HddsProtos.NodeState.HEALTHY; +import static org.apache.hadoop.hdds.protocol.proto.HddsProtos.NodeState.STALE; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Callable; + +/** + * Handler of printTopology command. + */ +@CommandLine.Command( + name = "printTopology", + description = "Print a tree of the network topology as reported by SCM", + mixinStandardHelpOptions = true, + versionProvider = HddsVersionProvider.class) +public class TopologySubcommand implements Callable { + + @CommandLine.ParentCommand + private SCMCLI parent; + + private static List stateArray = new ArrayList<>(); + + static { + stateArray.add(HEALTHY); + stateArray.add(STALE); + stateArray.add(DEAD); + stateArray.add(DECOMMISSIONING); + stateArray.add(DECOMMISSIONED); + } + + @Override + public Void call() throws Exception { + try (ScmClient scmClient = parent.createScmClient()) { + for (HddsProtos.NodeState state : stateArray) { + List nodes = scmClient.queryNode(state, + HddsProtos.QueryScope.CLUSTER, ""); + if (nodes != null && nodes.size() > 0) { + // show node state + System.out.println("State = " + state.toString()); + // format "hostname/ipAddress networkLocation" + nodes.forEach(node -> { + System.out.print(node.getNodeID().getHostName() + "/" + + node.getNodeID().getIpAddress()); + System.out.println(" " + + (node.getNodeID().getNetworkLocation() != null ? + node.getNodeID().getNetworkLocation() : "NA")); + }); + } + } + return null; + } + } +} \ No newline at end of file