You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ozone.apache.org by ms...@apache.org on 2020/04/15 14:42:11 UTC

[hadoop-ozone] branch master updated: HDDS-3134. Debug Tool that gives chunk location information given a key. (#684)

This is an automated email from the ASF dual-hosted git repository.

msingh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hadoop-ozone.git


The following commit(s) were added to refs/heads/master by this push:
     new 506778f  HDDS-3134. Debug Tool that gives chunk location information given a key. (#684)
506778f is described below

commit 506778f48db56812afde7e8040eec335d582489a
Author: Sadanand Shenoy <sa...@gmail.com>
AuthorDate: Wed Apr 15 20:12:03 2020 +0530

    HDDS-3134. Debug Tool that gives chunk location information given a key. (#684)
---
 .../container/keyvalue/KeyValueContainerData.java  |   5 +-
 .../hdds/scm/cli/ContainerOperationClient.java     |   5 +
 .../src/main/smoketest/basic/ozone-shell.robot     |   4 +-
 hadoop-ozone/dist/src/shell/ozone/ozone            |   6 +-
 .../hadoop/ozone/debug/ChunkDataNodeDetails.java   |  43 ++++++
 .../apache/hadoop/ozone/debug/ChunkDetails.java    |  54 +++++++
 .../apache/hadoop/ozone/debug/ChunkKeyHandler.java | 171 +++++++++++++++++++++
 .../hadoop/ozone/debug/ContainerChunkInfo.java     |  93 +++++++++++
 .../org/apache/hadoop/ozone/debug/OzoneDebug.java  |  49 ++++++
 .../apache/hadoop/ozone/debug/package-info.java    |  24 +++
 10 files changed, 446 insertions(+), 8 deletions(-)

diff --git a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/KeyValueContainerData.java b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/KeyValueContainerData.java
index 1e373de..caae215 100644
--- a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/KeyValueContainerData.java
+++ b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/KeyValueContainerData.java
@@ -141,9 +141,6 @@ public class KeyValueContainerData extends ContainerData {
    * @return Path to base dir
    */
   public String getContainerPath() {
-    if (metadataPath == null) {
-      return null;
-    }
     return new File(metadataPath).getParent();
   }
 
@@ -226,7 +223,7 @@ public class KeyValueContainerData extends ContainerData {
   public ContainerDataProto getProtoBufMessage() {
     ContainerDataProto.Builder builder = ContainerDataProto.newBuilder();
     builder.setContainerID(this.getContainerID());
-    builder.setContainerPath(this.getMetadataPath());
+    builder.setContainerPath(this.getContainerPath());
     builder.setState(this.getState());
 
     for (Map.Entry<String, String> entry : getMetadata().entrySet()) {
diff --git a/hadoop-hdds/tools/src/main/java/org/apache/hadoop/hdds/scm/cli/ContainerOperationClient.java b/hadoop-hdds/tools/src/main/java/org/apache/hadoop/hdds/scm/cli/ContainerOperationClient.java
index 15f6ce8..b08b6b4 100644
--- a/hadoop-hdds/tools/src/main/java/org/apache/hadoop/hdds/scm/cli/ContainerOperationClient.java
+++ b/hadoop-hdds/tools/src/main/java/org/apache/hadoop/hdds/scm/cli/ContainerOperationClient.java
@@ -69,6 +69,11 @@ public class ContainerOperationClient implements ScmClient {
   private final HddsProtos.ReplicationType replicationType;
   private final StorageContainerLocationProtocol
       storageContainerLocationClient;
+
+  public XceiverClientManager getXceiverClientManager() {
+    return xceiverClientManager;
+  }
+
   private final XceiverClientManager xceiverClientManager;
 
   public ContainerOperationClient(Configuration conf) throws IOException {
diff --git a/hadoop-ozone/dist/src/main/smoketest/basic/ozone-shell.robot b/hadoop-ozone/dist/src/main/smoketest/basic/ozone-shell.robot
index e358ea2..6675fde 100644
--- a/hadoop-ozone/dist/src/main/smoketest/basic/ozone-shell.robot
+++ b/hadoop-ozone/dist/src/main/smoketest/basic/ozone-shell.robot
@@ -18,7 +18,7 @@ Documentation       Test ozone shell CLI usage
 Library             OperatingSystem
 Resource            ../commonlib.robot
 Test Setup          Run Keyword if    '${SECURITY_ENABLED}' == 'true'    Kinit test user     testuser     testuser.keytab
-Test Timeout        2 minute
+Test Timeout        3 minute
 Suite Setup         Generate prefix
 
 *** Variables ***
@@ -120,6 +120,8 @@ Test key handling
                     Should Not Contain  ${result}       NOTICE.txt.1 exists
     ${result} =     Execute             ozone sh key info ${protocol}${server}/${volume}/bb1/key1 | jq -r '. | select(.name=="key1")'
                     Should contain      ${result}       creationTime
+    ${result} =     Execute             ozone debug chunkinfo ${protocol}${server}/${volume}/bb1/key1 | jq -r '.[]'
+                    Should contain      ${result}       chunks
     ${result} =     Execute             ozone sh key list ${protocol}${server}/${volume}/bb1 | jq -r '. | select(.name=="key1") | .name'
                     Should Be Equal     ${result}       key1
                     Execute             ozone sh key rename ${protocol}${server}/${volume}/bb1 key1 key2
diff --git a/hadoop-ozone/dist/src/shell/ozone/ozone b/hadoop-ozone/dist/src/shell/ozone/ozone
index e7ee3d4..f3f9b6b 100755
--- a/hadoop-ozone/dist/src/shell/ozone/ozone
+++ b/hadoop-ozone/dist/src/shell/ozone/ozone
@@ -55,7 +55,7 @@ function hadoop_usage
   hadoop_add_subcommand "dtutil" client "operations related to delegation tokens"
   hadoop_add_subcommand "upgrade" client "HDFS to Ozone in-place upgrade tool"
   hadoop_add_subcommand "admin" client "Ozone admin tool"
-  hadoop_add_subcommand "ratislogparser" client "ozone debug tool, to convert Ratis log files into readable text"
+  hadoop_add_subcommand "debug" client "Ozone debug tool"
 
   hadoop_generate_usage "${HADOOP_SHELL_EXECNAME}" false
 }
@@ -207,8 +207,8 @@ function ozonecmd_case
       HADOOP_CLASSNAME=org.apache.hadoop.ozone.admin.OzoneAdmin
       OZONE_RUN_ARTIFACT_NAME="hadoop-ozone-tools"
     ;;
-    ratislogparser)
-      HADOOP_CLASSNAME=org.apache.hadoop.ozone.segmentparser.RatisLogParser
+    debug)
+      HADOOP_CLASSNAME=org.apache.hadoop.ozone.debug.OzoneDebug
       OZONE_RUN_ARTIFACT_NAME="hadoop-ozone-tools"
     ;;
     *)
diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/ChunkDataNodeDetails.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/ChunkDataNodeDetails.java
new file mode 100644
index 0000000..6019e58
--- /dev/null
+++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/ChunkDataNodeDetails.java
@@ -0,0 +1,43 @@
+/*
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.ozone.debug;
+/**
+ * Class that gives datanode details on which the chunk is present.
+ */
+public class ChunkDataNodeDetails {
+  private String ipAddress;
+  private String hostName;
+
+  public ChunkDataNodeDetails(String ipAddress, String hostName) {
+    this.ipAddress = ipAddress;
+    this.hostName = hostName;
+  }
+
+  @Override
+    public String toString() {
+    return "{"
+            + "ipAddress='"
+            + ipAddress
+            + '\''
+            + ", hostName='"
+            + hostName
+            + '\''
+            + '}';
+  }
+}
diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/ChunkDetails.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/ChunkDetails.java
new file mode 100644
index 0000000..278c2bf
--- /dev/null
+++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/ChunkDetails.java
@@ -0,0 +1,54 @@
+/*
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.ozone.debug;
+
+/**
+ * Class that gives chunkDetails.
+ */
+public class ChunkDetails {
+  private String chunkName;
+  private long chunkOffset;
+
+  public String getChunkName() {
+    return chunkName;
+  }
+
+  public void setChunkName(String chunkName) {
+    this.chunkName = chunkName;
+  }
+
+  @Override
+    public String toString() {
+    return "{"
+            + "chunkName='"
+            + chunkName
+            + '\''
+            + ", chunkOffset="
+            + chunkOffset
+            + '}';
+  }
+
+  public long getChunkOffset() {
+    return chunkOffset;
+  }
+
+  public void setChunkOffset(long chunkOffset) {
+    this.chunkOffset = chunkOffset;
+  }
+}
diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/ChunkKeyHandler.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/ChunkKeyHandler.java
new file mode 100644
index 0000000..fa57636
--- /dev/null
+++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/ChunkKeyHandler.java
@@ -0,0 +1,171 @@
+/*
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.ozone.debug;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.hadoop.hdds.protocol.DatanodeDetails;
+import org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos;
+import org.apache.hadoop.hdds.scm.XceiverClientManager;
+import org.apache.hadoop.hdds.scm.XceiverClientSpi;
+import org.apache.hadoop.hdds.scm.cli.ContainerOperationClient;
+import org.apache.hadoop.hdds.scm.storage.ContainerProtocolCalls;
+import org.apache.hadoop.hdds.security.token.OzoneBlockTokenIdentifier;
+import org.apache.hadoop.hdds.tracing.TracingUtil;
+import org.apache.hadoop.ozone.OzoneConsts;
+import org.apache.hadoop.ozone.client.*;
+import org.apache.hadoop.ozone.om.helpers.OmKeyArgs;
+import org.apache.hadoop.ozone.om.helpers.OmKeyInfo;
+import org.apache.hadoop.ozone.om.helpers.OmKeyLocationInfo;
+import org.apache.hadoop.ozone.om.protocol.OzoneManagerProtocol;
+import org.apache.hadoop.ozone.om.protocolPB.OzoneManagerProtocolClientSideTranslatorPB;
+import org.apache.hadoop.ozone.shell.OzoneAddress;
+import org.apache.hadoop.ozone.shell.keys.KeyHandler;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.hadoop.security.token.Token;
+import org.apache.ratis.protocol.ClientId;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Parameters;
+
+/**
+ * Class that gives chunk location given a specific key.
+ */
+@Command(name = "chunkinfo",
+        description = "returns chunk location"
+                + " information about an existing key")
+public class ChunkKeyHandler  extends KeyHandler {
+
+  @Parameters(arity = "1..1", description = "key to be located")
+    private String uri;
+
+  private ContainerOperationClient containerOperationClient;
+  private  XceiverClientManager xceiverClientManager;
+  private XceiverClientSpi xceiverClient;
+  private final ClientId clientId = ClientId.randomId();
+  private OzoneManagerProtocol ozoneManagerClient;
+
+  private String getChunkLocationPath(String containerLocation) {
+    return containerLocation + File.separator + OzoneConsts.STORAGE_DIR_CHUNKS;
+  }
+
+  @Override
+  protected void execute(OzoneClient client, OzoneAddress address)
+          throws IOException, OzoneClientException {
+    containerOperationClient = new
+            ContainerOperationClient(createOzoneConfiguration());
+    xceiverClientManager = containerOperationClient
+            .getXceiverClientManager();
+    ozoneManagerClient = TracingUtil.createProxy(
+            new OzoneManagerProtocolClientSideTranslatorPB(
+            getConf(), clientId.toString(),
+            null, UserGroupInformation.getCurrentUser()),
+            OzoneManagerProtocol.class, getConf());
+    address.ensureKeyAddress();
+    JsonObject jsonObj = new JsonObject();
+    JsonElement element;
+    String volumeName = address.getVolumeName();
+    String bucketName = address.getBucketName();
+    String keyName = address.getKeyName();
+    List<ContainerProtos.ChunkInfo> tempchunks = null;
+    List<ChunkDetails> chunkDetailsList = new ArrayList<ChunkDetails>();
+    List<String> chunkPaths = new ArrayList<String>();
+    OmKeyArgs keyArgs = new OmKeyArgs.Builder()
+            .setVolumeName(volumeName)
+            .setBucketName(bucketName)
+            .setKeyName(keyName)
+            .setRefreshPipeline(true)
+            .build();
+    OmKeyInfo keyInfo = ozoneManagerClient.lookupKey(keyArgs);
+    List<OmKeyLocationInfo> locationInfos = keyInfo
+            .getLatestVersionLocations().getBlocksLatestVersionOnly();
+    // querying  the keyLocations.The OM is queried to get containerID and
+    // localID pertaining to a given key
+    for (OmKeyLocationInfo keyLocation:locationInfos) {
+      ContainerChunkInfo containerChunkInfoVerbose = new ContainerChunkInfo();
+      ContainerChunkInfo containerChunkInfo = new ContainerChunkInfo();
+      long containerId = keyLocation.getContainerID();
+      Token<OzoneBlockTokenIdentifier> token = keyLocation.getToken();
+      xceiverClient = xceiverClientManager
+              .acquireClient(keyLocation.getPipeline());
+      // Datanode is queried to get chunk information.Thus querying the
+      // OM,SCM and datanode helps us get chunk location information
+      if (token != null) {
+        UserGroupInformation.getCurrentUser().addToken(token);
+      }
+      ContainerProtos.DatanodeBlockID datanodeBlockID = keyLocation.getBlockID()
+              .getDatanodeBlockIDProtobuf();
+      ContainerProtos.GetBlockResponseProto response = ContainerProtocolCalls
+                 .getBlock(xceiverClient, datanodeBlockID);
+      tempchunks = response.getBlockData().getChunksList();
+      ContainerProtos.ContainerDataProto containerData =
+              containerOperationClient.readContainer(
+                      keyLocation.getContainerID(),
+                      keyLocation.getPipeline());
+      for (ContainerProtos.ChunkInfo chunkInfo:tempchunks) {
+        ChunkDetails chunkDetails = new ChunkDetails();
+        chunkDetails.setChunkName(chunkInfo.getChunkName());
+        chunkDetails.setChunkOffset(chunkInfo.getOffset());
+        chunkDetailsList.add(chunkDetails);
+        chunkPaths.add(getChunkLocationPath(containerData.getContainerPath())
+              + File.separator
+              + chunkInfo.getChunkName());
+      }
+      containerChunkInfoVerbose
+              .setContainerPath(containerData.getContainerPath());
+      containerChunkInfoVerbose
+              .setDataNodeList(keyLocation.getPipeline().getNodes());
+      containerChunkInfoVerbose.setPipeline(keyLocation.getPipeline());
+      containerChunkInfoVerbose.setChunkInfos(chunkDetailsList);
+      containerChunkInfo.setChunks(chunkPaths);
+      List<ChunkDataNodeDetails> chunkDataNodeDetails = new
+              ArrayList<ChunkDataNodeDetails>();
+      for (DatanodeDetails datanodeDetails:keyLocation
+              .getPipeline().getNodes()) {
+        chunkDataNodeDetails.add(
+                new ChunkDataNodeDetails(datanodeDetails.getIpAddress(),
+                datanodeDetails.getHostName()));
+      }
+      containerChunkInfo.setChunkDataNodeDetails(chunkDataNodeDetails);
+      containerChunkInfo.setPipelineID(
+              keyLocation.getPipeline().getId().getId());
+      Gson gson = new GsonBuilder().create();
+      if (isVerbose()) {
+        element = gson.toJsonTree(containerChunkInfoVerbose);
+        jsonObj.add("container Id :" + containerId + ""
+                + "blockId :" + keyLocation.getLocalID() + "", element);
+      } else {
+        element = gson.toJsonTree(containerChunkInfo);
+        jsonObj.add("container Id :" + containerId + ""
+                + "blockId :" + keyLocation.getLocalID() + "", element);
+      }
+    }
+    xceiverClientManager.releaseClient(xceiverClient, false);
+    Gson gson = new GsonBuilder().setPrettyPrinting().create();
+    String prettyJson = gson.toJson(jsonObj);
+    System.out.println(prettyJson);
+  }
+
+
+}
diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/ContainerChunkInfo.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/ContainerChunkInfo.java
new file mode 100644
index 0000000..85f0bee
--- /dev/null
+++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/ContainerChunkInfo.java
@@ -0,0 +1,93 @@
+/*
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.ozone.debug;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import java.util.List;
+import java.util.UUID;
+import org.apache.hadoop.hdds.protocol.DatanodeDetails;
+import org.apache.hadoop.hdds.scm.pipeline.Pipeline;
+
+/**
+ * Class that gives container and chunk Information.
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class ContainerChunkInfo {
+  private String containerPath;
+  private List<DatanodeDetails> dataNodeList;
+  private List<ChunkDetails> chunkInfos;
+  private List<String> chunks;
+  private List<ChunkDataNodeDetails> chunkDataNodeDetails;
+  private UUID pipelineID;
+  private Pipeline pipeline;
+
+  public void setChunkDataNodeDetails(List<ChunkDataNodeDetails>
+                                              chunkDataNodeDetails) {
+    this.chunkDataNodeDetails = chunkDataNodeDetails;
+  }
+
+  public void setChunks(List<String> chunks) {
+    this.chunks = chunks;
+  }
+
+  public void setPipelineID(UUID pipelineID) {
+    this.pipelineID = pipelineID;
+  }
+
+  public Pipeline getPipeline() {
+    return pipeline;
+  }
+
+  public void setPipeline(Pipeline pipeline) {
+    this.pipeline = pipeline;
+  }
+
+  public void setContainerPath(String containerPath) {
+    this.containerPath = containerPath;
+  }
+
+  public void setChunkInfos(List<ChunkDetails> chunkInfos) {
+    this.chunkInfos = chunkInfos;
+  }
+
+  public void setDataNodeList(List<DatanodeDetails> dataNodeList) {
+    this.dataNodeList = dataNodeList;
+  }
+
+  @Override
+  public String toString() {
+    return "Container{"
+            + "containerPath='"
+            + containerPath
+            + '\''
+            + ", dataNodeList="
+            + dataNodeList
+            + ", chunkInfos="
+            + chunkInfos
+            + ", pipeline="
+            + pipeline
+            + '}'
+            + "chunks="
+            + chunks
+            + "chunkdatanodeDetails="
+            + chunkDataNodeDetails
+            + "PipelineID="
+            + pipelineID;
+  }
+}
diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/OzoneDebug.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/OzoneDebug.java
new file mode 100644
index 0000000..25295f7
--- /dev/null
+++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/OzoneDebug.java
@@ -0,0 +1,49 @@
+/*
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.ozone.debug;
+
+import org.apache.hadoop.hdds.cli.GenericCli;
+import org.apache.hadoop.hdds.cli.HddsVersionProvider;
+import org.apache.hadoop.ozone.segmentparser.RatisLogParser;
+import picocli.CommandLine;
+
+/**
+ * Ozone Debug Command line tool.
+ */
+@CommandLine.Command(name = "ozone debug",
+        description = "Developer tools for Ozone Debug operations",
+        versionProvider = HddsVersionProvider.class,
+        subcommands = {
+                ChunkKeyHandler.class,
+                RatisLogParser.class
+        },
+        mixinStandardHelpOptions = true)
+public class OzoneDebug extends GenericCli {
+
+  /**
+     * Main for the Ozone Debug shell Command handling.
+     *
+     * @param argv - System Args Strings[]
+     * @throws Exception
+     */
+  public static void main(String[] argv) throws Exception {
+
+    new OzoneDebug().run(argv);
+  }
+}
diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/package-info.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/package-info.java
new file mode 100644
index 0000000..8077bf3
--- /dev/null
+++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/package-info.java
@@ -0,0 +1,24 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.
+ * <p>
+ *
+ */
+
+/**
+ * Ozone Debug tools.
+ */
+package org.apache.hadoop.ozone.debug;


---------------------------------------------------------------------
To unsubscribe, e-mail: ozone-commits-unsubscribe@hadoop.apache.org
For additional commands, e-mail: ozone-commits-help@hadoop.apache.org