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

siyao pushed a commit to branch HDDS-6517-Snapshot
in repository https://gitbox.apache.org/repos/asf/ozone.git


The following commit(s) were added to refs/heads/HDDS-6517-Snapshot by this 
push:
     new ccc814ee7f HDDS-6857. [Snapshot] Implement Snapshot Delete CLI and API 
(#4175)
ccc814ee7f is described below

commit ccc814ee7f8a7cac70b6d64dcae12056e375199d
Author: Siyao Meng <[email protected]>
AuthorDate: Tue Jan 31 21:09:53 2023 -0800

    HDDS-6857. [Snapshot] Implement Snapshot Delete CLI and API (#4175)
---
 .../apache/hadoop/ozone/client/ObjectStore.java    |  13 ++
 .../ozone/client/protocol/ClientProtocol.java      |  10 ++
 .../apache/hadoop/ozone/client/rpc/RpcClient.java  |  19 ++
 .../main/java/org/apache/hadoop/ozone/OmUtils.java |   1 +
 .../org/apache/hadoop/ozone/audit/OMAction.java    |   2 +
 .../ozone/om/protocol/OzoneManagerProtocol.java    |  13 ++
 ...OzoneManagerProtocolClientSideTranslatorPB.java |  31 +++-
 .../src/main/proto/OmClientProtocol.proto          |  15 +-
 .../java/org/apache/hadoop/ozone/om/OMMetrics.java |  10 ++
 .../om/ratis/utils/OzoneManagerRatisUtils.java     |   3 +
 .../request/snapshot/OMSnapshotCreateRequest.java  |  10 +-
 ...teRequest.java => OMSnapshotDeleteRequest.java} | 185 ++++++++++++--------
 .../snapshot/OMSnapshotCreateResponse.java         |   3 +-
 ...Response.java => OMSnapshotDeleteResponse.java} |  32 ++--
 .../ozone/om/request/OMRequestTestUtils.java       |  25 ++-
 .../snapshot/TestOMSnapshotCreateRequest.java      |  10 +-
 ...quest.java => TestOMSnapshotDeleteRequest.java} | 194 ++++++++++++++-------
 .../snapshot/TestOMSnapshotDeleteResponse.java     | 125 +++++++++++++
 .../hadoop/ozone/client/ClientProtocolStub.java    |   7 +
 .../shell/snapshot/CreateSnapshotHandler.java      |  11 +-
 ...shotHandler.java => DeleteSnapshotHandler.java} |  24 ++-
 .../ozone/shell/snapshot/ListSnapshotHandler.java  |   3 +-
 .../ozone/shell/snapshot/SnapshotCommands.java     |   3 +-
 23 files changed, 556 insertions(+), 193 deletions(-)

diff --git 
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/ObjectStore.java
 
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/ObjectStore.java
index d22ba6061a..3a0a5cd8e8 100644
--- 
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/ObjectStore.java
+++ 
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/ObjectStore.java
@@ -537,6 +537,18 @@ public class ObjectStore {
     return proxy.createSnapshot(volumeName, bucketName, snapshotName);
   }
 
+  /**
+   * Delete snapshot.
+   * @param volumeName vol to be used
+   * @param bucketName bucket to be used
+   * @param snapshotName name of the snapshot to be deleted
+   * @throws IOException
+   */
+  public void deleteSnapshot(String volumeName,
+      String bucketName, String snapshotName) throws IOException {
+    proxy.deleteSnapshot(volumeName, bucketName, snapshotName);
+  }
+
   /**
    * List snapshots in a volume/bucket.
    * @param volumeName volume name
@@ -548,6 +560,7 @@ public class ObjectStore {
       throws IOException {
     return proxy.listSnapshot(volumeName, bucketName);
   }
+
   public SnapshotDiffReport snapshotDiff(String volumeName, String bucketName,
                                          String fromSnapshot, String 
toSnapshot)
       throws IOException {
diff --git 
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/protocol/ClientProtocol.java
 
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/protocol/ClientProtocol.java
index edc5eeb61e..b0400ac328 100644
--- 
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/protocol/ClientProtocol.java
+++ 
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/protocol/ClientProtocol.java
@@ -1030,6 +1030,16 @@ public interface ClientProtocol {
   String createSnapshot(String volumeName,
       String bucketName, String snapshotName) throws IOException;
 
+  /**
+   * Delete snapshot.
+   * @param volumeName vol to be used
+   * @param bucketName bucket to be used
+   * @param snapshotName name of the snapshot to be deleted
+   * @throws IOException
+   */
+  void deleteSnapshot(String volumeName,
+      String bucketName, String snapshotName) throws IOException;
+
   /**
    * List snapshots in a volume/bucket.
    * @param volumeName volume name
diff --git 
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java
 
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java
index b4b9e2aca7..4d1596c216 100644
--- 
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java
+++ 
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java
@@ -952,6 +952,25 @@ public class RpcClient implements ClientProtocol {
         bucketName, snapshotName);
   }
 
+  /**
+   * Delete Snapshot.
+   * @param volumeName vol to be used
+   * @param bucketName bucket to be used
+   * @param snapshotName name of the snapshot to be deleted
+   * @throws IOException
+   */
+  @Override
+  public void deleteSnapshot(String volumeName,
+      String bucketName, String snapshotName) throws IOException {
+    Preconditions.checkArgument(Strings.isNotBlank(volumeName),
+        "volume can't be null or empty.");
+    Preconditions.checkArgument(Strings.isNotBlank(bucketName),
+        "bucket can't be null or empty.");
+    Preconditions.checkArgument(Strings.isNotBlank(snapshotName),
+        "snapshot name can't be null or empty.");
+    ozoneManagerClient.deleteSnapshot(volumeName, bucketName, snapshotName);
+  }
+
   @Override
   public SnapshotDiffReport snapshotDiff(String volumeName, String bucketName,
                                          String fromSnapshot, String 
toSnapshot)
diff --git 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/OmUtils.java 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/OmUtils.java
index 10f3cbc439..1419a4cdab 100644
--- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/OmUtils.java
+++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/OmUtils.java
@@ -325,6 +325,7 @@ public final class OmUtils {
     case TenantRevokeAdmin:
     case SetRangerServiceVersion:
     case CreateSnapshot:
+    case DeleteSnapshot:
       return false;
     default:
       LOG.error("CmdType {} is not categorized as readOnly or not.", cmdType);
diff --git 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/audit/OMAction.java 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/audit/OMAction.java
index c691b18ac0..72c0c8c0f9 100644
--- 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/audit/OMAction.java
+++ 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/audit/OMAction.java
@@ -89,7 +89,9 @@ public enum OMAction implements AuditAction {
   TENANT_ASSIGN_ADMIN,
   TENANT_REVOKE_ADMIN,
   TENANT_LIST_USER,
+
   CREATE_SNAPSHOT,
+  DELETE_SNAPSHOT,
   LIST_SNAPSHOT;
 
   @Override
diff --git 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java
 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java
index f34be56c0d..ed08f66013 100644
--- 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java
+++ 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java
@@ -649,6 +649,19 @@ public interface OzoneManagerProtocol
         "this to be implemented");
   }
 
+  /**
+   * Delete snapshot.
+   * @param volumeName vol to be used
+   * @param bucketName bucket to be used
+   * @param snapshotName name of the snapshot to be deleted
+   * @throws IOException
+   */
+  default void deleteSnapshot(String volumeName,
+      String bucketName, String snapshotName) throws IOException {
+    throw new UnsupportedOperationException("OzoneManager does not require " +
+        "this to be implemented");
+  }
+
   /**
    * List snapshots in a volume/bucket.
    * @param volumeName volume name
diff --git 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java
 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java
index 47c8b8e12e..998bca29d8 100644
--- 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java
+++ 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java
@@ -84,6 +84,7 @@ import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.CreateF
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.CreateFileResponse;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.CreateKeyRequest;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.CreateKeyResponse;
+import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.CreateSnapshotRequest;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.CreateTenantRequest;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.CreateVolumeRequest;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DBUpdatesRequest;
@@ -92,6 +93,7 @@ import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DeleteB
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DeleteKeyArgs;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DeleteKeyRequest;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DeleteKeysRequest;
+import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DeleteSnapshotRequest;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DeleteTenantRequest;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DeleteTenantResponse;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DeleteVolumeRequest;
@@ -1108,9 +1110,8 @@ public final class 
OzoneManagerProtocolClientSideTranslatorPB
       String bucketName, String snapshotName)
       throws IOException {
 
-    final OzoneManagerProtocolProtos.CreateSnapshotRequest.Builder
-        requestBuilder =
-        OzoneManagerProtocolProtos.CreateSnapshotRequest.newBuilder()
+    final CreateSnapshotRequest.Builder requestBuilder =
+        CreateSnapshotRequest.newBuilder()
             .setVolumeName(volumeName)
             .setBucketName(bucketName);
     if (!StringUtils.isBlank(snapshotName)) {
@@ -1127,6 +1128,30 @@ public final class 
OzoneManagerProtocolClientSideTranslatorPB
     return snapshotInfo.getName();
   }
 
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void deleteSnapshot(String volumeName,
+      String bucketName, String snapshotName)
+      throws IOException {
+
+    final DeleteSnapshotRequest.Builder requestBuilder =
+        DeleteSnapshotRequest.newBuilder()
+            .setVolumeName(volumeName)
+            .setBucketName(bucketName)
+            .setSnapshotName(snapshotName);
+
+    final OMRequest omRequest = createOMRequest(Type.DeleteSnapshot)
+        .setDeleteSnapshotRequest(requestBuilder)
+        .build();
+    final OMResponse omResponse = submitRequest(omRequest);
+    handleError(omResponse);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
   @Override
   public List<SnapshotInfo> listSnapshot(String volumeName, String bucketName)
       throws IOException {
diff --git 
a/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto 
b/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
index 8fba86d714..81e776d6b4 100644
--- a/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
+++ b/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
@@ -129,6 +129,7 @@ enum Type {
   CreateSnapshot = 112;
   ListSnapshot = 113;
   SnapshotDiff = 114;
+  DeleteSnapshot = 115;
 }
 
 message OMRequest {
@@ -240,6 +241,7 @@ message OMRequest {
   optional CreateSnapshotRequest            CreateSnapshotRequest          = 
112;
   optional ListSnapshotRequest              ListSnapshotRequest            = 
113;
   optional SnapshotDiffRequest              snapshotDiffRequest            = 
114;
+  optional DeleteSnapshotRequest            DeleteSnapshotRequest          = 
115;
 
 }
 
@@ -345,6 +347,7 @@ message OMResponse {
   optional CreateSnapshotResponse            CreateSnapshotResponse        = 
112;
   optional ListSnapshotResponse              ListSnapshotResponse          = 
113;
   optional SnapshotDiffResponse              snapshotDiffResponse          = 
114;
+  optional DeleteSnapshotResponse            DeleteSnapshotResponse        = 
115;
 }
 
 enum Status {
@@ -1680,6 +1683,13 @@ message SnapshotDiffRequest {
   optional string toSnapshot = 4;
 }
 
+message DeleteSnapshotRequest {
+  optional string volumeName = 1;
+  optional string bucketName = 2;
+  optional string snapshotName = 3;
+  optional uint64 deletionTime = 4;
+}
+
 message DeleteTenantRequest {
     optional string tenantId = 1;
 }
@@ -1725,11 +1735,14 @@ message ListSnapshotResponse {
   repeated SnapshotInfo snapshotInfo = 1;
 }
 
-
 message SnapshotDiffResponse {
   optional SnapshotDiffReportProto snapshotDiffReport = 1;
 }
 
+message DeleteSnapshotResponse {
+
+}
+
 message SnapshotDiffReportProto {
   optional string volumeName = 1;
   optional string bucketName = 2;
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMetrics.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMetrics.java
index e85a033d18..d194360130 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMetrics.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OMMetrics.java
@@ -69,6 +69,7 @@ public class OMMetrics implements OmMetadataReaderMetrics {
   private @Metric MutableCounterLong numInitiateMultipartUploads;
   private @Metric MutableCounterLong numCompleteMultipartUploads;
   private @Metric MutableCounterLong numSnapshotCreates;
+  private @Metric MutableCounterLong numSnapshotDeletes;
   private @Metric MutableCounterLong numSnapshotLists;
 
   private @Metric MutableCounterLong numGetFileStatus;
@@ -119,6 +120,7 @@ public class OMMetrics implements OmMetadataReaderMetrics {
   private @Metric MutableCounterLong numListMultipartUploadPartFails;
   private @Metric MutableCounterLong numOpenKeyDeleteRequestFails;
   private @Metric MutableCounterLong numSnapshotCreateFails;
+  private @Metric MutableCounterLong numSnapshotDeleteFails;
   private @Metric MutableCounterLong numSnapshotListFails;
   private @Metric MutableCounterLong numSnapshotActive;
   private @Metric MutableCounterLong numSnapshotDeleted;
@@ -443,6 +445,14 @@ public class OMMetrics implements OmMetadataReaderMetrics {
     numSnapshotCreateFails.incr();
   }
 
+  public void incNumSnapshotDeletes() {
+    numSnapshotDeletes.incr();
+  }
+
+  public void incNumSnapshotDeleteFails() {
+    numSnapshotDeleteFails.incr();
+  }
+
   public void incNumSnapshotLists() {
     numSnapshotLists.incr();
   }
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/utils/OzoneManagerRatisUtils.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/utils/OzoneManagerRatisUtils.java
index ad730cd5bc..e556fb5065 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/utils/OzoneManagerRatisUtils.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/ratis/utils/OzoneManagerRatisUtils.java
@@ -71,6 +71,7 @@ import 
org.apache.hadoop.ozone.om.request.security.OMCancelDelegationTokenReques
 import org.apache.hadoop.ozone.om.request.security.OMGetDelegationTokenRequest;
 import 
org.apache.hadoop.ozone.om.request.security.OMRenewDelegationTokenRequest;
 import org.apache.hadoop.ozone.om.request.snapshot.OMSnapshotCreateRequest;
+import org.apache.hadoop.ozone.om.request.snapshot.OMSnapshotDeleteRequest;
 import org.apache.hadoop.ozone.om.request.upgrade.OMCancelPrepareRequest;
 import org.apache.hadoop.ozone.om.request.upgrade.OMFinalizeUpgradeRequest;
 import org.apache.hadoop.ozone.om.request.upgrade.OMPrepareRequest;
@@ -212,6 +213,8 @@ public final class OzoneManagerRatisUtils {
       return new OMSetRangerServiceVersionRequest(omRequest);
     case CreateSnapshot:
       return new OMSnapshotCreateRequest(omRequest);
+    case DeleteSnapshot:
+      return new OMSnapshotDeleteRequest(omRequest);
     case DeleteOpenKeys:
       BucketLayout bktLayout = BucketLayout.DEFAULT;
       if (omRequest.getDeleteOpenKeysRequest().hasBucketLayout()) {
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/snapshot/OMSnapshotCreateRequest.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/snapshot/OMSnapshotCreateRequest.java
index 3f1af514c1..60e3e2c7ca 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/snapshot/OMSnapshotCreateRequest.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/snapshot/OMSnapshotCreateRequest.java
@@ -96,7 +96,7 @@ public class OMSnapshotCreateRequest extends OMClientRequest {
     if (!ozoneManager.isAdmin(ugi) &&
         !ozoneManager.isOwner(ugi, bucketOwner)) {
       throw new OMException(
-          "Only bucket owners/admins can create snapshots",
+          "Only bucket owners and Ozone admins can create snapshots",
           OMException.ResultCodes.PERMISSION_DENIED);
     }
     return omRequest;
@@ -135,7 +135,7 @@ public class OMSnapshotCreateRequest extends 
OMClientRequest {
 
       //Check if snapshot already exists
       if (omMetadataManager.getSnapshotInfoTable().isExist(key)) {
-        LOG.debug("snapshot: {} already exists ", key);
+        LOG.debug("Snapshot '{}' already exists under '{}'", key, 
snapshotPath);
         throw new OMException("Snapshot already exists", FILE_ALREADY_EXISTS);
       }
 
@@ -177,11 +177,11 @@ public class OMSnapshotCreateRequest extends 
OMClientRequest {
         snapshotInfo.toAuditMap(), exception, userInfo));
     
     if (exception == null) {
-      LOG.info("created snapshot: name {} in snapshotPath: {}", snapshotName,
-          snapshotPath);
+      LOG.info("Created snapshot '{}' under path '{}'",
+          snapshotName, snapshotPath);
     } else {
       omMetrics.incNumSnapshotCreateFails();
-      LOG.error("Snapshot creation failed for name:{} in snapshotPath:{}",
+      LOG.error("Failed to create snapshot '{}' under path '{}'",
           snapshotName, snapshotPath);
     }
     return omClientResponse;
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/snapshot/OMSnapshotCreateRequest.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/snapshot/OMSnapshotDeleteRequest.java
similarity index 51%
copy from 
hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/snapshot/OMSnapshotCreateRequest.java
copy to 
hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/snapshot/OMSnapshotDeleteRequest.java
index 3f1af514c1..833c7c8429 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/snapshot/OMSnapshotCreateRequest.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/snapshot/OMSnapshotDeleteRequest.java
@@ -19,7 +19,6 @@
 package org.apache.hadoop.ozone.om.request.snapshot;
 
 import com.google.common.base.Optional;
-import org.apache.hadoop.hdds.utils.db.RDBStore;
 import org.apache.hadoop.hdds.utils.db.cache.CacheKey;
 import org.apache.hadoop.hdds.utils.db.cache.CacheValue;
 import org.apache.hadoop.ozone.OmUtils;
@@ -34,130 +33,161 @@ import 
org.apache.hadoop.ozone.om.ratis.utils.OzoneManagerDoubleBufferHelper;
 import org.apache.hadoop.ozone.om.request.OMClientRequest;
 import org.apache.hadoop.ozone.om.request.util.OmResponseUtil;
 import org.apache.hadoop.ozone.om.response.OMClientResponse;
-import org.apache.hadoop.ozone.om.response.snapshot.OMSnapshotCreateResponse;
-import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
-import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.CreateSnapshotRequest;
-import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.CreateSnapshotResponse;
+import org.apache.hadoop.ozone.om.response.snapshot.OMSnapshotDeleteResponse;
+import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DeleteSnapshotRequest;
+import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DeleteSnapshotResponse;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRequest;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMResponse;
+import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.UserInfo;
 import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer;
 import org.apache.hadoop.ozone.security.acl.OzoneObj;
 import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.hadoop.util.Time;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.io.IOException;
 
-import static 
org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.FILE_ALREADY_EXISTS;
+import static 
org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.FILE_NOT_FOUND;
 import static 
org.apache.hadoop.ozone.om.lock.OzoneManagerLock.Resource.BUCKET_LOCK;
 import static 
org.apache.hadoop.ozone.om.lock.OzoneManagerLock.Resource.SNAPSHOT_LOCK;
 
-
 /**
- * Handles CreateSnapshot Request.
+ * Handles DeleteSnapshot Request.
  */
-public class OMSnapshotCreateRequest extends OMClientRequest {
+public class OMSnapshotDeleteRequest extends OMClientRequest {
   private static final Logger LOG =
-      LoggerFactory.getLogger(OMSnapshotCreateRequest.class);
-
-  private final String snapshotPath;
-  private final String volumeName;
-  private final String bucketName;
-  private final String snapshotName;
-  private final String snapshotId;
-  private final SnapshotInfo snapshotInfo;
+      LoggerFactory.getLogger(OMSnapshotDeleteRequest.class);
 
-  public OMSnapshotCreateRequest(OMRequest omRequest) {
+  public OMSnapshotDeleteRequest(OMRequest omRequest) {
     super(omRequest);
-    CreateSnapshotRequest createSnapshotRequest = omRequest
-        .getCreateSnapshotRequest();
-    volumeName = createSnapshotRequest.getVolumeName();
-    bucketName = createSnapshotRequest.getBucketName();
-    snapshotId = createSnapshotRequest.getSnapshotId();
-
-    String possibleName = createSnapshotRequest.getSnapshotName();
-    snapshotInfo = SnapshotInfo.newInstance(volumeName,
-        bucketName,
-        possibleName,
-        snapshotId);
-    snapshotName = snapshotInfo.getName();
-    snapshotPath = snapshotInfo.getSnapshotPath();
   }
 
   @Override
   public OMRequest preExecute(OzoneManager ozoneManager) throws IOException {
+
     final OMRequest omRequest = super.preExecute(ozoneManager);
-    // Verify name
+
+    final DeleteSnapshotRequest deleteSnapshotRequest =
+        omRequest.getDeleteSnapshotRequest();
+
+    final String snapshotName = deleteSnapshotRequest.getSnapshotName();
+    // Verify snapshot name. TODO: Can remove
     OmUtils.validateSnapshotName(snapshotName);
 
+    String volumeName = deleteSnapshotRequest.getVolumeName();
+    String bucketName = deleteSnapshotRequest.getBucketName();
+
+    // Permission check
     UserGroupInformation ugi = createUGI();
     String bucketOwner = ozoneManager.getBucketOwner(volumeName, bucketName,
         IAccessAuthorizer.ACLType.READ, OzoneObj.ResourceType.BUCKET);
     if (!ozoneManager.isAdmin(ugi) &&
         !ozoneManager.isOwner(ugi, bucketOwner)) {
       throw new OMException(
-          "Only bucket owners/admins can create snapshots",
+          "Only bucket owners and Ozone admins can delete snapshots",
           OMException.ResultCodes.PERMISSION_DENIED);
     }
-    return omRequest;
+
+    // Set deletion time here so OM leader and follower would have the
+    // exact same timestamp.
+    OMRequest.Builder omRequestBuilder = omRequest.toBuilder()
+        .setDeleteSnapshotRequest(
+            DeleteSnapshotRequest.newBuilder()
+                .setVolumeName(volumeName)
+                .setBucketName(bucketName)
+                .setSnapshotName(snapshotName)
+                .setDeletionTime(Time.now()));
+
+    return omRequestBuilder.build();
   }
-  
+
   @Override
   public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager,
       long transactionLogIndex,
       OzoneManagerDoubleBufferHelper ozoneManagerDoubleBufferHelper) {
 
     OMMetrics omMetrics = ozoneManager.getMetrics();
-    omMetrics.incNumSnapshotCreates();
-    omMetrics.incNumSnapshotActive();
+    omMetrics.incNumSnapshotDeletes();
 
-    boolean acquiredBucketLock = false, acquiredSnapshotLock = false;
+    boolean acquiredBucketLock = false;
+    boolean acquiredSnapshotLock = false;
     IOException exception = null;
     OMMetadataManager omMetadataManager = ozoneManager.getMetadataManager();
-    
+
     OMResponse.Builder omResponse = OmResponseUtil.getOMResponseBuilder(
         getOmRequest());
     OMClientResponse omClientResponse = null;
     AuditLogger auditLogger = ozoneManager.getAuditLogger();
 
-    OzoneManagerProtocolProtos.UserInfo userInfo = 
getOmRequest().getUserInfo();
-    String key = snapshotInfo.getTableKey();
+    UserInfo userInfo = getOmRequest().getUserInfo();
+
+    final DeleteSnapshotRequest request =
+        getOmRequest().getDeleteSnapshotRequest();
+
+    final String volumeName = request.getVolumeName();
+    final String bucketName = request.getBucketName();
+    final String snapshotName = request.getSnapshotName();
+    final long deletionTime = request.getDeletionTime();
+
+    SnapshotInfo snapshotInfo = null;
+
     try {
-      // Lock bucket so it doesn't
-      //  get deleted while creating snapshot
+      // Acquire bucket lock
       acquiredBucketLock =
-          omMetadataManager.getLock().acquireReadLock(BUCKET_LOCK,
+          omMetadataManager.getLock().acquireWriteLock(BUCKET_LOCK,
               volumeName, bucketName);
 
       acquiredSnapshotLock =
           omMetadataManager.getLock().acquireWriteLock(SNAPSHOT_LOCK,
               volumeName, bucketName, snapshotName);
 
-      //Check if snapshot already exists
-      if (omMetadataManager.getSnapshotInfoTable().isExist(key)) {
-        LOG.debug("snapshot: {} already exists ", key);
-        throw new OMException("Snapshot already exists", FILE_ALREADY_EXISTS);
+      // Retrieve SnapshotInfo from the table
+      String tableKey = SnapshotInfo.getTableKey(volumeName, bucketName,
+          snapshotName);
+      snapshotInfo =
+          omMetadataManager.getSnapshotInfoTable().get(tableKey);
+
+      if (snapshotInfo == null) {
+        // Snapshot does not exist
+        throw new OMException("Snapshot does not exist", FILE_NOT_FOUND);
+      }
+
+      if (!snapshotInfo.getSnapshotStatus().equals(
+          SnapshotInfo.SnapshotStatus.SNAPSHOT_ACTIVE)) {
+        // If the snapshot is not in active state, throw exception as well
+        switch (snapshotInfo.getSnapshotStatus()) {
+        case SNAPSHOT_DELETED:
+          throw new OMException("Snapshot is already deleted. "
+              + "Pending reclamation.", FILE_NOT_FOUND);
+        case SNAPSHOT_RECLAIMED:
+          throw new OMException("Snapshot is already deleted and reclaimed.",
+              FILE_NOT_FOUND);
+        default:
+          // Unknown snapshot non-active state
+          throw new OMException("Snapshot exists but no longer in active 
state",
+              FILE_NOT_FOUND);
+        }
       }
 
-      // Note down RDB latest transaction sequence number, which is used
-      // as snapshot generation in the differ.
-      final long dbLatestSequenceNumber =
-          ((RDBStore) omMetadataManager.getStore()).getDb()
-              .getLatestSequenceNumber();
-      snapshotInfo.setDbTxSequenceNumber(dbLatestSequenceNumber);
-
-      omMetadataManager.getSnapshotInfoTable()
-          .addCacheEntry(new CacheKey<>(key),
-            new CacheValue<>(Optional.of(snapshotInfo), transactionLogIndex));
-
-      omResponse.setCreateSnapshotResponse(
-          CreateSnapshotResponse.newBuilder()
-          .setSnapshotInfo(snapshotInfo.getProtobuf()));
-      omClientResponse = new OMSnapshotCreateResponse(
-          omResponse.build(), volumeName, bucketName, snapshotName);
+      // Mark snapshot as deleted
+      snapshotInfo.setSnapshotStatus(
+          SnapshotInfo.SnapshotStatus.SNAPSHOT_DELETED);
+      snapshotInfo.setDeletionTime(deletionTime);
+
+      // Update table cache first
+      omMetadataManager.getSnapshotInfoTable().addCacheEntry(
+          new CacheKey<>(tableKey),
+          new CacheValue<>(Optional.of(snapshotInfo), transactionLogIndex));
+
+      omResponse.setDeleteSnapshotResponse(
+          DeleteSnapshotResponse.newBuilder());
+      omClientResponse = new OMSnapshotDeleteResponse(
+          omResponse.build(), tableKey, snapshotInfo);
+
     } catch (IOException ex) {
       exception = ex;
-      omClientResponse = new OMSnapshotCreateResponse(
+      omClientResponse = new OMSnapshotDeleteResponse(
           createErrorOMResponse(omResponse, exception));
     } finally {
       addResponseToDoubleBuffer(transactionLogIndex, omClientResponse,
@@ -167,24 +197,31 @@ public class OMSnapshotCreateRequest extends 
OMClientRequest {
             bucketName, snapshotName);
       }
       if (acquiredBucketLock) {
-        omMetadataManager.getLock().releaseReadLock(BUCKET_LOCK, volumeName,
+        omMetadataManager.getLock().releaseWriteLock(BUCKET_LOCK, volumeName,
             bucketName);
       }
     }
 
-    // Performing audit logging outside the lock.
-    auditLog(auditLogger, buildAuditMessage(OMAction.CREATE_SNAPSHOT,
+    if (snapshotInfo == null) {
+      // Dummy SnapshotInfo for logging and audit logging when erred
+      snapshotInfo = SnapshotInfo.newInstance(volumeName, bucketName,
+          snapshotName, null);
+    }
+
+    // Perform audit logging outside the lock
+    auditLog(auditLogger, buildAuditMessage(OMAction.DELETE_SNAPSHOT,
         snapshotInfo.toAuditMap(), exception, userInfo));
-    
+
+    final String snapshotPath = snapshotInfo.getSnapshotPath();
     if (exception == null) {
-      LOG.info("created snapshot: name {} in snapshotPath: {}", snapshotName,
-          snapshotPath);
+      LOG.info("Deleted snapshot '{}' under path '{}'",
+          snapshotName, snapshotPath);
     } else {
-      omMetrics.incNumSnapshotCreateFails();
-      LOG.error("Snapshot creation failed for name:{} in snapshotPath:{}",
+      omMetrics.incNumSnapshotDeleteFails();
+      LOG.error("Failed to delete snapshot '{}' under path '{}'",
           snapshotName, snapshotPath);
     }
     return omClientResponse;
   }
-  
+
 }
\ No newline at end of file
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/snapshot/OMSnapshotCreateResponse.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/snapshot/OMSnapshotCreateResponse.java
index f59588ba0f..e5ba1c0511 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/snapshot/OMSnapshotCreateResponse.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/snapshot/OMSnapshotCreateResponse.java
@@ -31,12 +31,11 @@ import java.io.IOException;
 import static 
org.apache.hadoop.ozone.om.OmMetadataManagerImpl.SNAPSHOT_INFO_TABLE;
 
 /**
- * Response for OMSnapshotCreateResponse.
+ * Response for OMSnapshotCreateRequest.
  */
 @CleanupTableInfo(cleanupTables = {SNAPSHOT_INFO_TABLE})
 public class OMSnapshotCreateResponse extends OMClientResponse {
 
-  @SuppressWarnings("checkstyle:parameternumber")
   public OMSnapshotCreateResponse(@Nonnull OMResponse omResponse,
       @Nonnull String volumeName, @Nonnull String bucketName,
                                   @Nonnull String snapshotName) {
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/snapshot/OMSnapshotCreateResponse.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/snapshot/OMSnapshotDeleteResponse.java
similarity index 70%
copy from 
hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/snapshot/OMSnapshotCreateResponse.java
copy to 
hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/snapshot/OMSnapshotDeleteResponse.java
index f59588ba0f..654d62bb4b 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/snapshot/OMSnapshotCreateResponse.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/snapshot/OMSnapshotDeleteResponse.java
@@ -20,7 +20,6 @@ package org.apache.hadoop.ozone.om.response.snapshot;
 
 import org.apache.hadoop.hdds.utils.db.BatchOperation;
 import org.apache.hadoop.ozone.om.OMMetadataManager;
-import org.apache.hadoop.ozone.om.OmSnapshotManager;
 import org.apache.hadoop.ozone.om.helpers.SnapshotInfo;
 import org.apache.hadoop.ozone.om.response.CleanupTableInfo;
 import org.apache.hadoop.ozone.om.response.OMClientResponse;
@@ -28,26 +27,31 @@ import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRespo
 
 import javax.annotation.Nonnull;
 import java.io.IOException;
+
 import static 
org.apache.hadoop.ozone.om.OmMetadataManagerImpl.SNAPSHOT_INFO_TABLE;
 
 /**
- * Response for OMSnapshotCreateResponse.
+ * Response for OMSnapshotDeleteRequest.
  */
 @CleanupTableInfo(cleanupTables = {SNAPSHOT_INFO_TABLE})
-public class OMSnapshotCreateResponse extends OMClientResponse {
+public class OMSnapshotDeleteResponse extends OMClientResponse {
+
+  private String tableKey;
+  private SnapshotInfo snapshotInfo;
 
-  @SuppressWarnings("checkstyle:parameternumber")
-  public OMSnapshotCreateResponse(@Nonnull OMResponse omResponse,
-      @Nonnull String volumeName, @Nonnull String bucketName,
-                                  @Nonnull String snapshotName) {
+  public OMSnapshotDeleteResponse(@Nonnull OMResponse omResponse,
+      @Nonnull String tableKey,
+      @Nonnull SnapshotInfo snapshotInfo) {
     super(omResponse);
+    this.tableKey = tableKey;
+    this.snapshotInfo = snapshotInfo;
   }
 
   /**
    * For when the request is not successful.
    * For a successful request, the other constructor should be used.
    */
-  public OMSnapshotCreateResponse(@Nonnull OMResponse omResponse) {
+  public OMSnapshotDeleteResponse(@Nonnull OMResponse omResponse) {
     super(omResponse);
     checkStatusNotOK();
   }
@@ -56,18 +60,8 @@ public class OMSnapshotCreateResponse extends 
OMClientResponse {
   public void addToDBBatch(OMMetadataManager omMetadataManager,
       BatchOperation batchOperation) throws IOException {
 
-    SnapshotInfo snapshotInfo =
-        SnapshotInfo.getFromProtobuf(
-        getOMResponse().getCreateSnapshotResponse().getSnapshotInfo());
-
-    // Create the snapshot checkpoint
-    OmSnapshotManager.createOmSnapshotCheckpoint(omMetadataManager,
-        snapshotInfo);
-
-    String key = snapshotInfo.getTableKey();
-
     // Add to db
     omMetadataManager.getSnapshotInfoTable().putWithBatch(batchOperation,
-        key, snapshotInfo);
+        tableKey, snapshotInfo);
   }
 }
diff --git 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/OMRequestTestUtils.java
 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/OMRequestTestUtils.java
index 9549f746e5..2dbe188180 100644
--- 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/OMRequestTestUtils.java
+++ 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/OMRequestTestUtils.java
@@ -1134,7 +1134,30 @@ public final class OMRequestTestUtils {
 
     return OMRequest.newBuilder()
         .setCreateSnapshotRequest(createSnapshotRequest)
-        .setCmdType(OzoneManagerProtocolProtos.Type.CreateSnapshot)
+        .setCmdType(Type.CreateSnapshot)
+        .setClientId(UUID.randomUUID().toString())
+        .build();
+  }
+
+  /**
+   * Create OMRequest for Delete Snapshot.
+   * @param volumeName vol to be used
+   * @param bucketName bucket to be used
+   * @param snapshotName name of the snapshot to be deleted
+   */
+  public static OMRequest deleteSnapshotRequest(String volumeName,
+      String bucketName, String snapshotName) {
+    OzoneManagerProtocolProtos.DeleteSnapshotRequest deleteSnapshotRequest =
+        OzoneManagerProtocolProtos.DeleteSnapshotRequest.newBuilder()
+            .setVolumeName(volumeName)
+            .setBucketName(bucketName)
+            .setSnapshotName(snapshotName)
+            .setDeletionTime(Time.now())
+            .build();
+
+    return OMRequest.newBuilder()
+        .setDeleteSnapshotRequest(deleteSnapshotRequest)
+        .setCmdType(Type.DeleteSnapshot)
         .setClientId(UUID.randomUUID().toString())
         .build();
   }
diff --git 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/snapshot/TestOMSnapshotCreateRequest.java
 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/snapshot/TestOMSnapshotCreateRequest.java
index 35f51bf1d5..972920e46d 100644
--- 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/snapshot/TestOMSnapshotCreateRequest.java
+++ 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/snapshot/TestOMSnapshotCreateRequest.java
@@ -132,7 +132,7 @@ public class TestOMSnapshotCreateRequest {
         volumeName, bucketName, snapshotName);
     // Check bad owner
     LambdaTestUtils.intercept(OMException.class,
-        "Only bucket owners/admins can create snapshots",
+        "Only bucket owners and Ozone admins can create snapshots",
         () -> doPreExecute(omRequest));
   }
 
@@ -258,6 +258,14 @@ public class TestOMSnapshotCreateRequest {
 
   private OMSnapshotCreateRequest doPreExecute(
       OMRequest originalRequest) throws Exception {
+    return doPreExecute(originalRequest, ozoneManager);
+  }
+
+  /**
+   * Static helper method so this could be used in TestOMSnapshotDeleteRequest.
+   */
+  static OMSnapshotCreateRequest doPreExecute(
+      OMRequest originalRequest, OzoneManager ozoneManager) throws Exception {
     OMSnapshotCreateRequest omSnapshotCreateRequest =
         new OMSnapshotCreateRequest(originalRequest);
 
diff --git 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/snapshot/TestOMSnapshotCreateRequest.java
 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/snapshot/TestOMSnapshotDeleteRequest.java
similarity index 57%
copy from 
hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/snapshot/TestOMSnapshotCreateRequest.java
copy to 
hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/snapshot/TestOMSnapshotDeleteRequest.java
index 35f51bf1d5..14b7955cbe 100644
--- 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/snapshot/TestOMSnapshotCreateRequest.java
+++ 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/snapshot/TestOMSnapshotDeleteRequest.java
@@ -20,12 +20,12 @@
 
 package org.apache.hadoop.ozone.om.request.snapshot;
 
-import java.util.UUID;
-
+import com.google.common.base.Optional;
 import org.apache.hadoop.hdds.conf.OzoneConfiguration;
+import org.apache.hadoop.hdds.utils.db.cache.CacheKey;
+import org.apache.hadoop.hdds.utils.db.cache.CacheValue;
 import org.apache.hadoop.ozone.audit.AuditLogger;
 import org.apache.hadoop.ozone.audit.AuditMessage;
-
 import org.apache.hadoop.ozone.om.OMConfigKeys;
 import org.apache.hadoop.ozone.om.OMMetadataManager;
 import org.apache.hadoop.ozone.om.OMMetrics;
@@ -34,33 +34,34 @@ import org.apache.hadoop.ozone.om.OzoneManager;
 import org.apache.hadoop.ozone.om.exceptions.OMException;
 import org.apache.hadoop.ozone.om.helpers.SnapshotInfo;
 import org.apache.hadoop.ozone.om.ratis.utils.OzoneManagerDoubleBufferHelper;
+import org.apache.hadoop.ozone.om.request.OMRequestTestUtils;
+import org.apache.hadoop.ozone.om.response.OMClientResponse;
 import org.apache.hadoop.ozone.om.upgrade.OMLayoutVersionManager;
+import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRequest;
+import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMResponse;
+import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.Status;
+import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.Type;
 import org.apache.ozone.test.LambdaTestUtils;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
-
-
-import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
-    .OMRequest;
-import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
-    .OMResponse;
-import org.apache.hadoop.ozone.om.request.OMRequestTestUtils;
-import org.apache.hadoop.ozone.om.response.OMClientResponse;
-import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
 import org.junit.rules.TemporaryFolder;
 import org.mockito.Mockito;
 
+import java.util.UUID;
+
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 /**
- * Tests OMSnapshotCreateRequest class, which handles CreateSnapshot request.
+ * Tests OMSnapshotDeleteRequest class, which handles DeleteSnapshot request.
+ * Mostly mirrors TestOMSnapshotCreateRequest.
+ * testEntryNotExist() and testEntryExists() are unique.
  */
-public class TestOMSnapshotCreateRequest {
+public class TestOMSnapshotDeleteRequest {
   @Rule
   public TemporaryFolder folder = new TemporaryFolder();
 
@@ -118,7 +119,7 @@ public class TestOMSnapshotCreateRequest {
     // set the owner
     when(ozoneManager.isOwner(any(), any())).thenReturn(true);
     OMRequest omRequest =
-        OMRequestTestUtils.createSnapshotRequest(
+        OMRequestTestUtils.deleteSnapshotRequest(
         volumeName, bucketName, snapshotName);
     // should not throw
     doPreExecute(omRequest);
@@ -128,11 +129,11 @@ public class TestOMSnapshotCreateRequest {
   public void testPreExecuteBadOwner() throws Exception {
     // owner not set
     OMRequest omRequest =
-        OMRequestTestUtils.createSnapshotRequest(
+        OMRequestTestUtils.deleteSnapshotRequest(
         volumeName, bucketName, snapshotName);
     // Check bad owner
     LambdaTestUtils.intercept(OMException.class,
-        "Only bucket owners/admins can create snapshots",
+        "Only bucket owners and Ozone admins can delete snapshots",
         () -> doPreExecute(omRequest));
   }
 
@@ -141,7 +142,7 @@ public class TestOMSnapshotCreateRequest {
     // check invalid snapshot name
     String badName = "a?b";
     OMRequest omRequest =
-        OMRequestTestUtils.createSnapshotRequest(
+        OMRequestTestUtils.deleteSnapshotRequest(
         volumeName, bucketName, badName);
     LambdaTestUtils.intercept(OMException.class,
         "Invalid snapshot name: " + badName,
@@ -152,12 +153,11 @@ public class TestOMSnapshotCreateRequest {
   public void testPreExecuteNameOnlyNumbers() throws Exception {
     // check invalid snapshot name containing only numbers
     String badNameON = "1234";
-    OMRequest omRequest =
-            OMRequestTestUtils.createSnapshotRequest(
-                    volumeName, bucketName, badNameON);
+    OMRequest omRequest = OMRequestTestUtils.deleteSnapshotRequest(
+        volumeName, bucketName, badNameON);
     LambdaTestUtils.intercept(OMException.class,
-            "Invalid snapshot name: " + badNameON,
-            () -> doPreExecute(omRequest));
+        "Invalid snapshot name: " + badNameON,
+        () -> doPreExecute(omRequest));
   }
 
   @Test
@@ -170,26 +170,26 @@ public class TestOMSnapshotCreateRequest {
 
     // name length = 63
     when(ozoneManager.isOwner(any(), any())).thenReturn(true);
-    OMRequest omRequest = OMRequestTestUtils.createSnapshotRequest(
-                    volumeName, bucketName, name63);
+    OMRequest omRequest = OMRequestTestUtils.deleteSnapshotRequest(
+        volumeName, bucketName, name63);
     // should not throw any error
     doPreExecute(omRequest);
 
     // name length = 64
-    OMRequest omRequest2 = OMRequestTestUtils.createSnapshotRequest(
-                    volumeName, bucketName, name64);
+    OMRequest omRequest2 = OMRequestTestUtils.deleteSnapshotRequest(
+        volumeName, bucketName, name64);
     LambdaTestUtils.intercept(OMException.class,
-            "Invalid snapshot name: " + name64,
-            () -> doPreExecute(omRequest2));
+        "Invalid snapshot name: " + name64,
+        () -> doPreExecute(omRequest2));
   }
 
   @Test
   public void testValidateAndUpdateCache() throws Exception {
     when(ozoneManager.isAdmin(any())).thenReturn(true);
     OMRequest omRequest =
-        OMRequestTestUtils.createSnapshotRequest(
+        OMRequestTestUtils.deleteSnapshotRequest(
         volumeName, bucketName, snapshotName);
-    OMSnapshotCreateRequest omSnapshotCreateRequest =
+    OMSnapshotDeleteRequest omSnapshotDeleteRequest =
         doPreExecute(omRequest);
     String key = SnapshotInfo.getTableKey(volumeName,
         bucketName, snapshotName);
@@ -199,71 +199,133 @@ public class TestOMSnapshotCreateRequest {
     Assert.assertNull(omMetadataManager.getSnapshotInfoTable().get(key));
 
     // add key to cache
+    SnapshotInfo snapshotInfo = SnapshotInfo.newInstance(
+        volumeName, bucketName, snapshotName, null);
+    Assert.assertEquals(SnapshotInfo.SnapshotStatus.SNAPSHOT_ACTIVE,
+        snapshotInfo.getSnapshotStatus());
+    omMetadataManager.getSnapshotInfoTable().addCacheEntry(
+        new CacheKey<>(key),
+        new CacheValue<>(Optional.of(snapshotInfo), 1L));
+
+    // Trigger validateAndUpdateCache
     OMClientResponse omClientResponse =
-        omSnapshotCreateRequest.validateAndUpdateCache(ozoneManager, 1,
+        omSnapshotDeleteRequest.validateAndUpdateCache(ozoneManager, 2L,
             ozoneManagerDoubleBufferHelper);
-    
+
     // check cache
-    SnapshotInfo snapshotInfo =
-        omMetadataManager.getSnapshotInfoTable().get(key);
+    snapshotInfo = omMetadataManager.getSnapshotInfoTable().get(key);
     Assert.assertNotNull(snapshotInfo);
+    Assert.assertEquals(SnapshotInfo.SnapshotStatus.SNAPSHOT_DELETED,
+        snapshotInfo.getSnapshotStatus());
+
+    OMResponse omResponse = omClientResponse.getOMResponse();
+
+    // check response success flag
+    Assert.assertTrue(omResponse.getSuccess());
+
+    Assert.assertNotNull(omResponse.getDeleteSnapshotResponse());
+    Assert.assertEquals(Type.DeleteSnapshot, omResponse.getCmdType());
+    Assert.assertEquals(Status.OK, omResponse.getStatus());
+  }
+
+  /**
+   * Expect snapshot deletion failure when snapshot entry does not exist.
+   */
+  @Test
+  public void testEntryNotExist() throws Exception {
+    when(ozoneManager.isAdmin(any())).thenReturn(true);
+    OMRequest omRequest = OMRequestTestUtils.deleteSnapshotRequest(
+        volumeName, bucketName, snapshotName);
+    OMSnapshotDeleteRequest omSnapshotDeleteRequest = doPreExecute(omRequest);
+    String key = SnapshotInfo.getTableKey(volumeName, bucketName, 
snapshotName);
 
-    // verify table data with response data.
-    SnapshotInfo snapshotInfoFromProto = SnapshotInfo.getFromProtobuf(
-        omClientResponse.getOMResponse()
-        .getCreateSnapshotResponse().getSnapshotInfo());
-    Assert.assertEquals(snapshotInfoFromProto, snapshotInfo);
+    // Entry does not exist
+    Assert.assertNull(omMetadataManager.getSnapshotInfoTable().get(key));
+
+    // Trigger delete snapshot validateAndUpdateCache
+    OMClientResponse omClientResponse =
+        omSnapshotDeleteRequest.validateAndUpdateCache(ozoneManager, 1L,
+            ozoneManagerDoubleBufferHelper);
 
     OMResponse omResponse = omClientResponse.getOMResponse();
-    Assert.assertNotNull(omResponse.getCreateSnapshotResponse());
-    Assert.assertEquals(OzoneManagerProtocolProtos.Type.CreateSnapshot,
-        omResponse.getCmdType());
-    Assert.assertEquals(OzoneManagerProtocolProtos.Status.OK,
-        omResponse.getStatus());
+    Assert.assertNotNull(omResponse.getDeleteSnapshotResponse());
+    Assert.assertEquals(Status.FILE_NOT_FOUND, omResponse.getStatus());
   }
 
+  /**
+   * Expect successful snapshot deletion when snapshot entry exists.
+   * But a second deletion would result in an error.
+   */
   @Test
   public void testEntryExists() throws Exception {
     when(ozoneManager.isAdmin(any())).thenReturn(true);
-    OMRequest omRequest =
-        OMRequestTestUtils.createSnapshotRequest(
+    String key = SnapshotInfo.getTableKey(volumeName, bucketName, 
snapshotName);
+
+    OMRequest omRequest1 = OMRequestTestUtils.createSnapshotRequest(
         volumeName, bucketName, snapshotName);
-    OMSnapshotCreateRequest omSnapshotCreateRequest = doPreExecute(omRequest);
-    String key = SnapshotInfo.getTableKey(volumeName,
-        bucketName, snapshotName);
+    OMSnapshotCreateRequest omSnapshotCreateRequest =
+        TestOMSnapshotCreateRequest.doPreExecute(omRequest1, ozoneManager);
 
     Assert.assertNull(omMetadataManager.getSnapshotInfoTable().get(key));
 
-    //create entry
-    omSnapshotCreateRequest.validateAndUpdateCache(ozoneManager, 1,
+    // Create snapshot entry
+    omSnapshotCreateRequest.validateAndUpdateCache(ozoneManager, 1L,
         ozoneManagerDoubleBufferHelper);
     SnapshotInfo snapshotInfo =
         omMetadataManager.getSnapshotInfoTable().get(key);
     Assert.assertNotNull(snapshotInfo);
+    Assert.assertEquals(SnapshotInfo.SnapshotStatus.SNAPSHOT_ACTIVE,
+        snapshotInfo.getSnapshotStatus());
 
-    // Now try to create again to verify error
-    omRequest =
-        OMRequestTestUtils.createSnapshotRequest(
+    OMRequest omRequest2 = OMRequestTestUtils.deleteSnapshotRequest(
         volumeName, bucketName, snapshotName);
-    omSnapshotCreateRequest = doPreExecute(omRequest);
+    OMSnapshotDeleteRequest omSnapshotDeleteRequest = doPreExecute(omRequest2);
+
+    // Delete snapshot entry
     OMClientResponse omClientResponse =
-        omSnapshotCreateRequest.validateAndUpdateCache(ozoneManager, 2,
+        omSnapshotDeleteRequest.validateAndUpdateCache(ozoneManager, 2L,
             ozoneManagerDoubleBufferHelper);
-    
+
+    snapshotInfo = omMetadataManager.getSnapshotInfoTable().get(key);
+    // The snapshot entry should still exist in the table,
+    // but marked as DELETED.
+    Assert.assertNotNull(snapshotInfo);
+    Assert.assertEquals(SnapshotInfo.SnapshotStatus.SNAPSHOT_DELETED,
+        snapshotInfo.getSnapshotStatus());
+    Assert.assertTrue(snapshotInfo.getDeletionTime() > 0L);
+
+    // Response should be successful
     OMResponse omResponse = omClientResponse.getOMResponse();
-    Assert.assertNotNull(omResponse.getCreateSnapshotResponse());
-    Assert.assertEquals(OzoneManagerProtocolProtos.Status.FILE_ALREADY_EXISTS,
-        omResponse.getStatus());
+    Assert.assertNotNull(omResponse.getDeleteSnapshotResponse());
+    Assert.assertEquals(Status.OK, omResponse.getStatus());
+
+    // Now delete snapshot entry again, expect error
+    omRequest2 = OMRequestTestUtils.deleteSnapshotRequest(
+        volumeName, bucketName, snapshotName);
+    omSnapshotDeleteRequest = doPreExecute(omRequest2);
+    omClientResponse =
+        omSnapshotDeleteRequest.validateAndUpdateCache(ozoneManager, 3L,
+            ozoneManagerDoubleBufferHelper);
+
+    // Snapshot entry should still be there.
+    snapshotInfo = omMetadataManager.getSnapshotInfoTable().get(key);
+    Assert.assertNotNull(snapshotInfo);
+    Assert.assertEquals(SnapshotInfo.SnapshotStatus.SNAPSHOT_DELETED,
+        snapshotInfo.getSnapshotStatus());
+
+    omResponse = omClientResponse.getOMResponse();
+    Assert.assertNotNull(omResponse.getDeleteSnapshotResponse());
+    Assert.assertEquals(Status.FILE_NOT_FOUND, omResponse.getStatus());
   }
 
-  private OMSnapshotCreateRequest doPreExecute(
+  private OMSnapshotDeleteRequest doPreExecute(
       OMRequest originalRequest) throws Exception {
-    OMSnapshotCreateRequest omSnapshotCreateRequest =
-        new OMSnapshotCreateRequest(originalRequest);
+    OMSnapshotDeleteRequest omSnapshotDeleteRequest =
+        new OMSnapshotDeleteRequest(originalRequest);
 
     OMRequest modifiedRequest =
-        omSnapshotCreateRequest.preExecute(ozoneManager);
-    return new OMSnapshotCreateRequest(modifiedRequest);
+        omSnapshotDeleteRequest.preExecute(ozoneManager);
+    return new OMSnapshotDeleteRequest(modifiedRequest);
   }
 
 }
diff --git 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/response/snapshot/TestOMSnapshotDeleteResponse.java
 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/response/snapshot/TestOMSnapshotDeleteResponse.java
new file mode 100644
index 0000000000..67a2afeea7
--- /dev/null
+++ 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/response/snapshot/TestOMSnapshotDeleteResponse.java
@@ -0,0 +1,125 @@
+/*
+ * 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.ozone.om.response.snapshot;
+
+import org.apache.hadoop.hdds.conf.OzoneConfiguration;
+import org.apache.hadoop.hdds.utils.db.BatchOperation;
+import org.apache.hadoop.hdds.utils.db.Table;
+import org.apache.hadoop.ozone.om.OMConfigKeys;
+import org.apache.hadoop.ozone.om.OMMetadataManager;
+import org.apache.hadoop.ozone.om.OmMetadataManagerImpl;
+import org.apache.hadoop.ozone.om.helpers.SnapshotInfo;
+import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
+import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.CreateSnapshotResponse;
+import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMResponse;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import java.io.File;
+import java.util.UUID;
+
+import static org.apache.hadoop.ozone.OzoneConsts.OM_DB_NAME;
+import static org.apache.hadoop.ozone.OzoneConsts.OM_KEY_PREFIX;
+import static org.apache.hadoop.ozone.OzoneConsts.OM_SNAPSHOT_DIR;
+
+/**
+ * This class tests OMSnapshotDeleteResponse.
+ * TODO: WIP
+ */
+public class TestOMSnapshotDeleteResponse {
+
+  @Rule
+  public TemporaryFolder folder = new TemporaryFolder();
+  
+  private OMMetadataManager omMetadataManager;
+  private BatchOperation batchOperation;
+  private String fsPath;
+
+  @Before
+  public void setup() throws Exception {
+    OzoneConfiguration ozoneConfiguration = new OzoneConfiguration();
+    fsPath = folder.newFolder().getAbsolutePath();
+    ozoneConfiguration.set(OMConfigKeys.OZONE_OM_DB_DIRS,
+        fsPath);
+    omMetadataManager = new OmMetadataManagerImpl(ozoneConfiguration);
+    batchOperation = omMetadataManager.getStore().initBatchOperation();
+  }
+
+  @After
+  public void tearDown() {
+    if (batchOperation != null) {
+      batchOperation.close();
+    }
+  }
+
+  @Test
+  public void testAddToDBBatch() throws Exception {
+    String volumeName = UUID.randomUUID().toString();
+    String bucketName = UUID.randomUUID().toString();
+    String snapshotName = UUID.randomUUID().toString();
+    String snapshotId = UUID.randomUUID().toString();
+    SnapshotInfo snapshotInfo = SnapshotInfo.newInstance(volumeName,
+        bucketName,
+        snapshotName,
+        snapshotId);
+
+    // confirm table is empty
+    Assert.assertEquals(0,
+        omMetadataManager
+        .countRowsInTable(omMetadataManager.getSnapshotInfoTable()));
+
+    // Prepare the table, write an entry with SnapshotCreate
+    OMSnapshotCreateResponse omSnapshotCreateResponse =
+        new OMSnapshotCreateResponse(OMResponse.newBuilder()
+            .setCmdType(OzoneManagerProtocolProtos.Type.CreateSnapshot)
+            .setStatus(OzoneManagerProtocolProtos.Status.OK)
+            .setCreateSnapshotResponse(
+                CreateSnapshotResponse.newBuilder()
+                .setSnapshotInfo(snapshotInfo.getProtobuf())
+                .build()).build(), volumeName, bucketName, snapshotName);
+    omSnapshotCreateResponse.addToDBBatch(omMetadataManager, batchOperation);
+    omMetadataManager.getStore().commitBatchOperation(batchOperation);
+
+    // Confirm snapshot directory was created
+    String snapshotDir = fsPath + OM_KEY_PREFIX +
+        OM_SNAPSHOT_DIR + OM_KEY_PREFIX + OM_DB_NAME +
+        snapshotInfo.getCheckpointDirName();
+    Assert.assertTrue((new File(snapshotDir)).exists());
+
+    // Confirm table has 1 entry
+    Assert.assertEquals(1, omMetadataManager
+        .countRowsInTable(omMetadataManager.getSnapshotInfoTable()));
+
+    // Check contents of entry
+    Table.KeyValue<String, SnapshotInfo> keyValue =
+        omMetadataManager.getSnapshotInfoTable().iterator().next();
+    SnapshotInfo storedInfo = keyValue.getValue();
+    Assert.assertEquals(snapshotInfo.getTableKey(), keyValue.getKey());
+    Assert.assertEquals(snapshotInfo, storedInfo);
+
+    // TODO: OMSnapshotDeleteResponse
+    // Confirm that the snapshot directory is gone
+    // Confirm that the table still has 1 entry, and its content
+  }
+}
diff --git 
a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/client/ClientProtocolStub.java
 
b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/client/ClientProtocolStub.java
index e876b7fec1..aa1cb345df 100644
--- 
a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/client/ClientProtocolStub.java
+++ 
b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/client/ClientProtocolStub.java
@@ -616,6 +616,13 @@ public class ClientProtocolStub implements ClientProtocol {
     return "";
   }
 
+  @Override
+  public void deleteSnapshot(String volumeName,
+      String bucketName, String snapshotName)
+      throws IOException {
+
+  }
+
   @Override
   public List<OzoneSnapshot> listSnapshot(String volumeName, String bucketName)
       throws IOException {
diff --git 
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/snapshot/CreateSnapshotHandler.java
 
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/snapshot/CreateSnapshotHandler.java
index c92ffec40e..71ce63f75d 100644
--- 
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/snapshot/CreateSnapshotHandler.java
+++ 
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/snapshot/CreateSnapshotHandler.java
@@ -27,17 +27,16 @@ import picocli.CommandLine;
 import java.io.IOException;
 
 /**
- * ozone snapshot create.
+ * ozone sh snapshot create.
  */
 @CommandLine.Command(name = "create",
-    description = "create snapshot")
+    description = "Create a snapshot")
 public class CreateSnapshotHandler extends Handler {
 
   @CommandLine.Mixin
   private BucketUri snapshotPath;
 
-
-  @CommandLine.Parameters(description = "optional snapshot name",
+  @CommandLine.Parameters(description = "Snapshot name (Optional)",
       index = "1", arity = "0..1")
   private String snapshotName;
 
@@ -56,8 +55,8 @@ public class CreateSnapshotHandler extends Handler {
     String newName = client.getObjectStore()
         .createSnapshot(volumeName, bucketName, snapshotName);
     if (isVerbose()) {
-      out().format("created snapshot '%s/%s %s'.%n", volumeName, bucketName,
-          newName);
+      out().format("Created snapshot '%s' under '%s/%s'.%n",
+          newName, volumeName, bucketName);
     }
   }
 }
diff --git 
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/snapshot/CreateSnapshotHandler.java
 
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/snapshot/DeleteSnapshotHandler.java
similarity index 74%
copy from 
hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/snapshot/CreateSnapshotHandler.java
copy to 
hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/snapshot/DeleteSnapshotHandler.java
index c92ffec40e..86faac229f 100644
--- 
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/snapshot/CreateSnapshotHandler.java
+++ 
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/snapshot/DeleteSnapshotHandler.java
@@ -17,7 +17,6 @@
  */
 package org.apache.hadoop.ozone.shell.snapshot;
 
-import org.apache.hadoop.ozone.OmUtils;
 import org.apache.hadoop.ozone.client.OzoneClient;
 import org.apache.hadoop.ozone.shell.Handler;
 import org.apache.hadoop.ozone.shell.OzoneAddress;
@@ -27,18 +26,17 @@ import picocli.CommandLine;
 import java.io.IOException;
 
 /**
- * ozone snapshot create.
+ * ozone snapshot delete.
  */
[email protected](name = "create",
-    description = "create snapshot")
-public class CreateSnapshotHandler extends Handler {
[email protected](name = "delete",
+    description = "Delete a snapshot")
+public class DeleteSnapshotHandler extends Handler {
 
   @CommandLine.Mixin
   private BucketUri snapshotPath;
 
-
-  @CommandLine.Parameters(description = "optional snapshot name",
-      index = "1", arity = "0..1")
+  @CommandLine.Parameters(description = "Snapshot name",
+      index = "1", arity = "1")
   private String snapshotName;
 
   @Override
@@ -52,12 +50,12 @@ public class CreateSnapshotHandler extends Handler {
 
     String volumeName = snapshotPath.getValue().getVolumeName();
     String bucketName = snapshotPath.getValue().getBucketName();
-    OmUtils.validateSnapshotName(snapshotName);
-    String newName = client.getObjectStore()
-        .createSnapshot(volumeName, bucketName, snapshotName);
+
+    client.getObjectStore()
+        .deleteSnapshot(volumeName, bucketName, snapshotName);
     if (isVerbose()) {
-      out().format("created snapshot '%s/%s %s'.%n", volumeName, bucketName,
-          newName);
+      out().format("Deleted snapshot '%s' under '%s/%s'.%n",
+          snapshotName, volumeName, bucketName);
     }
   }
 }
diff --git 
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/snapshot/ListSnapshotHandler.java
 
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/snapshot/ListSnapshotHandler.java
index e3440d04e5..7ad4041bef 100644
--- 
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/snapshot/ListSnapshotHandler.java
+++ 
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/snapshot/ListSnapshotHandler.java
@@ -28,11 +28,12 @@ import java.io.IOException;
 import java.util.List;
 
 /**
+ * ozone sh snapshot list.
  * a handler for Ozone shell CLI command 'list snapshot'.
  */
 @CommandLine.Command(name = "list",
     aliases = "ls",
-    description = "list snapshot for the buckets.")
+    description = "List snapshots for the buckets.")
 public class ListSnapshotHandler extends Handler {
 
   @CommandLine.Mixin
diff --git 
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/snapshot/SnapshotCommands.java
 
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/snapshot/SnapshotCommands.java
index 6d3f8d3a2f..a2169e04dc 100644
--- 
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/snapshot/SnapshotCommands.java
+++ 
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/snapshot/SnapshotCommands.java
@@ -39,8 +39,9 @@ import picocli.CommandLine.ParentCommand;
     description = "Snapshot specific operations",
     subcommands = {
         CreateSnapshotHandler.class,
+        DeleteSnapshotHandler.class,
         ListSnapshotHandler.class,
-        SnapshotDiffHandler.class,
+        SnapshotDiffHandler.class
     },
     mixinStandardHelpOptions = true,
     versionProvider = HddsVersionProvider.class)


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to