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

nanda 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 e5d9c38f6f HDDS-7466. SnapshotDiff Client Code. (#3942)
e5d9c38f6f is described below

commit e5d9c38f6f4a97e607ca5bc486b571807ada73ba
Author: Nandakumar <[email protected]>
AuthorDate: Tue Dec 6 13:42:54 2022 +0530

    HDDS-7466. SnapshotDiff Client Code. (#3942)
---
 .../apache/hadoop/ozone/client/ObjectStore.java    |  6 ++
 .../ozone/client/protocol/ClientProtocol.java      | 15 +++++
 .../apache/hadoop/ozone/client/rpc/RpcClient.java  | 13 +++++
 .../main/java/org/apache/hadoop/ozone/OmUtils.java |  1 +
 .../ozone/om/protocol/OzoneManagerProtocol.java    | 19 ++++++
 ...OzoneManagerProtocolClientSideTranslatorPB.java | 25 ++++++++
 .../hadoop/ozone}/snapshot/SnapshotDiffReport.java | 67 +++++++++++++++++++++-
 .../apache/hadoop/ozone/snapshot/package-info.java | 22 +++++++
 .../src/main/proto/OmClientProtocol.proto          | 35 +++++++++++
 .../apache/hadoop/ozone/om/OmSnapshotManager.java  |  2 +-
 .../org/apache/hadoop/ozone/om/OzoneManager.java   |  8 +++
 .../ozone/om/snapshot/SnapshotDiffManager.java     |  5 +-
 .../protocolPB/OzoneManagerRequestHandler.java     | 17 ++++++
 .../hadoop/ozone/client/ClientProtocolStub.java    |  8 +++
 .../ozone/shell/snapshot/SnapshotCommands.java     |  1 +
 .../ozone/shell/snapshot/SnapshotDiffHandler.java  | 67 ++++++++++++++++++++++
 16 files changed, 307 insertions(+), 4 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 f500763697..cc267d696a 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
@@ -43,6 +43,7 @@ import org.apache.hadoop.ozone.om.helpers.TenantUserList;
 import org.apache.hadoop.ozone.om.protocol.S3Auth;
 import org.apache.hadoop.ozone.security.OzoneTokenIdentifier;
 import org.apache.hadoop.ozone.security.acl.OzoneObj;
+import org.apache.hadoop.ozone.snapshot.SnapshotDiffReport;
 import org.apache.hadoop.security.UserGroupInformation;
 
 import com.google.common.annotations.VisibleForTesting;
@@ -560,4 +561,9 @@ public class ObjectStore {
       throws IOException {
     return proxy.listSnapshot(volumeName, bucketName);
   }
+  public SnapshotDiffReport snapshotDiff(String volumeName, String bucketName,
+                                         String fromSnapshot, String 
toSnapshot)
+      throws IOException {
+    return proxy.snapshotDiff(volumeName, bucketName, fromSnapshot, 
toSnapshot);
+  }
 }
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 1c092a4708..9ecf071b55 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
@@ -62,6 +62,7 @@ import org.apache.hadoop.ozone.om.protocol.S3Auth;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRoleInfo;
 import org.apache.hadoop.ozone.security.OzoneTokenIdentifier;
 import org.apache.hadoop.ozone.security.acl.OzoneObj;
+import org.apache.hadoop.ozone.snapshot.SnapshotDiffReport;
 import org.apache.hadoop.security.KerberosInfo;
 import org.apache.hadoop.security.token.Token;
 
@@ -979,4 +980,18 @@ public interface ClientProtocol {
    */
   List<OzoneSnapshot> listSnapshot(String volumeName, String bucketName)
       throws IOException;
+
+
+  /**
+   * Get the differences between two snapshots.
+   * @param volumeName Name of the volume to which the snapshotted bucket 
belong
+   * @param bucketName Name of the bucket to which the snapshots belong
+   * @param fromSnapshot The name of the starting snapshot
+   * @param toSnapshot The name of the ending snapshot
+   * @return the difference report between two snapshots
+   * @throws IOException in case of any exception while generating snapshot 
diff
+   */
+  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/rpc/RpcClient.java
 
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java
index ef5e377788..f42bdfe711 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
@@ -148,6 +148,7 @@ import 
org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLIdentityType;
 import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLType;
 import org.apache.hadoop.ozone.security.acl.OzoneAclConfig;
 import org.apache.hadoop.ozone.security.acl.OzoneObj;
+import org.apache.hadoop.ozone.snapshot.SnapshotDiffReport;
 import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.hadoop.security.token.Token;
 
@@ -932,6 +933,18 @@ public class RpcClient implements ClientProtocol {
         bucketName, snapshotName);
   }
 
+  @Override
+  public SnapshotDiffReport snapshotDiff(String volumeName, String bucketName,
+                                         String fromSnapshot, String 
toSnapshot)
+      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.");
+    return ozoneManagerClient.snapshotDiff(volumeName, bucketName,
+        fromSnapshot, toSnapshot);
+  }
+
   /**
    * List snapshots in a volume/bucket.
    * @param volumeName volume name
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 72eef66157..39f4d99894 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
@@ -279,6 +279,7 @@ public final class OmUtils {
       // write to OM DB. And therefore it doesn't need a OMClientRequest.
       // Although indirectly the Ranger sync service task could invoke write
       // operation SetRangerServiceVersion.
+    case SnapshotDiff:
       return true;
     case CreateVolume:
     case SetVolumeProperty:
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 aef8d31f4d..948a302c29 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
@@ -61,6 +61,7 @@ import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.CancelP
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.EchoRPCResponse;
 import org.apache.hadoop.ozone.security.OzoneDelegationTokenSelector;
 import org.apache.hadoop.ozone.security.acl.OzoneObj;
+import org.apache.hadoop.ozone.snapshot.SnapshotDiffReport;
 import org.apache.hadoop.ozone.upgrade.UpgradeFinalizer.StatusAndMessages;
 import org.apache.hadoop.security.KerberosInfo;
 import org.apache.hadoop.security.token.TokenInfo;
@@ -635,6 +636,24 @@ public interface OzoneManagerProtocol
         "this to be implemented");
   }
 
+  /**
+   * Get the differences between two snapshots.
+   * @param volumeName Name of the volume to which the snapshotted bucket 
belong
+   * @param bucketName Name of the bucket to which the snapshots belong
+   * @param fromSnapshot The name of the starting snapshot
+   * @param toSnapshot The name of the ending snapshot
+   * @return the difference report between two snapshots
+   * @throws IOException in case of any exception while generating snapshot 
diff
+   */
+  default SnapshotDiffReport snapshotDiff(String volumeName,
+                                          String bucketName,
+                                          String fromSnapshot,
+                                          String toSnapshot)
+      throws IOException {
+    throw new UnsupportedOperationException("OzoneManager does not require " +
+        "this to be implemented");
+  }
+
   /**
    * Assign admin role to a user identified by an accessId in a tenant.
    * @param accessId access ID.
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 09439586fc..e0ce9d6dce 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
@@ -183,6 +183,7 @@ import org.apache.hadoop.ozone.security.acl.OzoneObj;
 import 
org.apache.hadoop.ozone.security.proto.SecurityProtos.CancelDelegationTokenRequestProto;
 import 
org.apache.hadoop.ozone.security.proto.SecurityProtos.GetDelegationTokenRequestProto;
 import 
org.apache.hadoop.ozone.security.proto.SecurityProtos.RenewDelegationTokenRequestProto;
+import org.apache.hadoop.ozone.snapshot.SnapshotDiffReport;
 import org.apache.hadoop.ozone.upgrade.UpgradeFinalizer;
 import org.apache.hadoop.ozone.upgrade.UpgradeFinalizer.StatusAndMessages;
 import org.apache.hadoop.security.token.Token;
@@ -1137,6 +1138,30 @@ public final class 
OzoneManagerProtocolClientSideTranslatorPB
     return snapshotInfos;
   }
 
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public SnapshotDiffReport snapshotDiff(String volumeName, String bucketName,
+                                         String fromSnapshot, String 
toSnapshot)
+      throws IOException {
+    final OzoneManagerProtocolProtos.SnapshotDiffRequest.Builder
+        requestBuilder =
+        OzoneManagerProtocolProtos.SnapshotDiffRequest.newBuilder()
+            .setVolumeName(volumeName)
+            .setBucketName(bucketName)
+            .setFromSnapshot(fromSnapshot)
+            .setToSnapshot(toSnapshot);
+
+    final OMRequest omRequest = createOMRequest(Type.SnapshotDiff)
+        .setSnapshotDiffRequest(requestBuilder)
+        .build();
+    final OMResponse omResponse = submitRequest(omRequest);
+    handleError(omResponse);
+    return SnapshotDiffReport.fromProtobuf(omResponse
+        .getSnapshotDiffResponse().getSnapshotDiffReport());
+  }
+
   /**
    * {@inheritDoc}
    */
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/SnapshotDiffReport.java
 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/snapshot/SnapshotDiffReport.java
similarity index 63%
rename from 
hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/SnapshotDiffReport.java
rename to 
hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/snapshot/SnapshotDiffReport.java
index 107512c509..24b8af76c5 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/SnapshotDiffReport.java
+++ 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/snapshot/SnapshotDiffReport.java
@@ -16,10 +16,15 @@
  * limitations under the License.
  */
 
-package org.apache.hadoop.ozone.om.snapshot;
+package org.apache.hadoop.ozone.snapshot;
+
+import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.SnapshotDiffReportProto;
+import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DiffReportEntryProto;
+import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DiffReportEntryProto.DiffTypeProto;
 
 import java.util.Collections;
 import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * Snapshot diff report.
@@ -52,6 +57,14 @@ public class SnapshotDiffReport {
     public String getLabel() {
       return label;
     }
+
+    public DiffTypeProto toProtobuf() {
+      return DiffTypeProto.valueOf(this.name());
+    }
+
+    public static DiffType fromProtobuf(final DiffTypeProto type) {
+      return DiffType.valueOf(type.name());
+    }
   }
 
   /**
@@ -125,6 +138,23 @@ public class SnapshotDiffReport {
       return toString().hashCode();
     }
 
+    public DiffReportEntryProto toProtobuf() {
+      final DiffReportEntryProto.Builder builder = DiffReportEntryProto
+          .newBuilder();
+      builder.setDiffType(type.toProtobuf()).setSourcePath(sourcePath);
+      if (targetPath != null) {
+        builder.setTargetPath(targetPath);
+      }
+      return builder.build();
+    }
+
+    public static DiffReportEntry fromProtobuf(
+        final DiffReportEntryProto entry) {
+      return of(DiffType.fromProtobuf(entry.getDiffType()),
+          entry.getSourcePath(),
+          entry.hasTargetPath() ? entry.getTargetPath() : null);
+    }
+
   }
 
 
@@ -165,4 +195,39 @@ public class SnapshotDiffReport {
   public List<DiffReportEntry> getDiffList() {
     return diffList;
   }
+
+  @Override
+  public String toString() {
+    StringBuilder str = new StringBuilder();
+    String from = "snapshot " + fromSnapshot;
+    String to = "snapshot " + toSnapshot;
+    str.append("Difference between ").append(from).append(" and ").append(to)
+        .append(":")
+        .append(LINE_SEPARATOR);
+    for (DiffReportEntry entry : diffList) {
+      str.append(entry.toString()).append(LINE_SEPARATOR);
+    }
+    return str.toString();
+  }
+
+  public SnapshotDiffReportProto toProtobuf() {
+    final SnapshotDiffReportProto.Builder builder = SnapshotDiffReportProto
+        .newBuilder();
+    builder.setVolumeName(volumeName)
+        .setBucketName(bucketName)
+        .setFromSnapshot(fromSnapshot)
+        .setToSnapshot(toSnapshot);
+    builder.addAllDiffList(diffList.stream().map(DiffReportEntry::toProtobuf)
+        .collect(Collectors.toList()));
+    return builder.build();
+  }
+
+  public static SnapshotDiffReport fromProtobuf(
+      final SnapshotDiffReportProto report) {
+    return new SnapshotDiffReport(report.getVolumeName(),
+        report.getBucketName(), report.getFromSnapshot(),
+        report.getToSnapshot(), report.getDiffListList().stream()
+        .map(DiffReportEntry::fromProtobuf).collect(Collectors.toList()));
+  }
+
 }
diff --git 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/snapshot/package-info.java
 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/snapshot/package-info.java
new file mode 100644
index 0000000000..774beea585
--- /dev/null
+++ 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/snapshot/package-info.java
@@ -0,0 +1,22 @@
+/**
+ * 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.snapshot;
+
+/**
+ * Ozone snapshot related classes.
+ */
\ No newline at end of file
diff --git 
a/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto 
b/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
index 9380d35068..37fa9673a1 100644
--- a/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
+++ b/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
@@ -127,6 +127,7 @@ enum Type {
 
   CreateSnapshot = 111;
   ListSnapshot = 112;
+  SnapshotDiff = 113;
 }
 
 message OMRequest {
@@ -236,6 +237,7 @@ message OMRequest {
 
   optional CreateSnapshotRequest            CreateSnapshotRequest          = 
111;
   optional ListSnapshotRequest              ListSnapshotRequest            = 
112;
+  optional SnapshotDiffRequest              snapshotDiffRequest            = 
113;
 
 }
 
@@ -339,6 +341,7 @@ message OMResponse {
 
   optional CreateSnapshotResponse            CreateSnapshotResponse        = 
111;
   optional ListSnapshotResponse              ListSnapshotResponse          = 
112;
+  optional SnapshotDiffResponse              snapshotDiffResponse          = 
113;
 }
 
 enum Status {
@@ -1650,6 +1653,13 @@ message ListSnapshotRequest {
   required string bucketName = 2;
 }
 
+message SnapshotDiffRequest {
+  required string volumeName = 1;
+  required string bucketName = 2;
+  required string fromSnapshot = 3;
+  required string toSnapshot = 4;
+}
+
 message DeleteTenantRequest {
     optional string tenantId = 1;
 }
@@ -1695,6 +1705,31 @@ message ListSnapshotResponse {
   repeated SnapshotInfo snapshotInfo = 1;
 }
 
+
+message SnapshotDiffResponse {
+  required SnapshotDiffReportProto snapshotDiffReport = 1;
+}
+
+message SnapshotDiffReportProto {
+  required string volumeName = 1;
+  required string bucketName = 2;
+  required string fromSnapshot = 3;
+  required string toSnapshot = 4;
+  repeated DiffReportEntryProto diffList = 5;
+}
+
+message DiffReportEntryProto {
+  enum DiffTypeProto {
+    CREATE = 1;
+    MODIFY = 2;
+    DELETE= 3;
+    RENAME = 4;
+  }
+  required DiffTypeProto diffType = 1;
+  required string sourcePath = 2;
+  optional string targetPath = 3;
+}
+
 message DeleteTenantResponse {
     optional string volumeName = 1;
     optional int64 volRefCount = 2;
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmSnapshotManager.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmSnapshotManager.java
index 9691fb366d..a7fa062909 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmSnapshotManager.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmSnapshotManager.java
@@ -33,7 +33,7 @@ import java.io.IOException;
 
 import org.apache.hadoop.hdds.conf.OzoneConfiguration;
 import org.apache.hadoop.ozone.om.snapshot.SnapshotDiffManager;
-import org.apache.hadoop.ozone.om.snapshot.SnapshotDiffReport;
+import org.apache.hadoop.ozone.snapshot.SnapshotDiffReport;
 import org.apache.ozone.rocksdiff.RocksDBCheckpointDiffer;
 import org.rocksdb.RocksDBException;
 import org.slf4j.Logger;
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
index a620d451a7..3ec7fb8c55 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
@@ -77,6 +77,7 @@ import org.apache.hadoop.ozone.OzoneManagerVersion;
 import org.apache.hadoop.ozone.om.helpers.SnapshotInfo;
 import org.apache.hadoop.ozone.om.multitenant.OMRangerBGSyncService;
 import org.apache.hadoop.ozone.om.request.OMClientRequest;
+import org.apache.hadoop.ozone.snapshot.SnapshotDiffReport;
 import org.apache.hadoop.ozone.util.OzoneNetUtils;
 import org.apache.hadoop.ozone.om.helpers.BucketLayout;
 import org.apache.hadoop.hdds.scm.ha.SCMNodeInfo;
@@ -4272,4 +4273,11 @@ public final class OzoneManager extends 
ServiceRuntimeInfoImpl
         ozoneObj.getVolumeName(), ozoneObj.getBucketName(),
         ozoneObj.getKeyName());
   }
+
+  public SnapshotDiffReport snapshotDiff(String volume, String bucket,
+                                         String fromSnapshot, String 
toSnapshot)
+      throws IOException {
+    return omSnapshotManager.getSnapshotDiffReport(volume, bucket,
+        fromSnapshot, toSnapshot);
+  }
 }
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/SnapshotDiffManager.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/SnapshotDiffManager.java
index b0edc18745..c1b811ffa4 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/SnapshotDiffManager.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/SnapshotDiffManager.java
@@ -23,8 +23,9 @@ import org.apache.hadoop.ozone.om.OMMetadataManager;
 import org.apache.hadoop.ozone.om.OmSnapshot;
 import org.apache.hadoop.ozone.om.helpers.BucketLayout;
 import org.apache.hadoop.ozone.om.helpers.OmKeyInfo;
-import org.apache.hadoop.ozone.om.snapshot.SnapshotDiffReport.DiffType;
-import org.apache.hadoop.ozone.om.snapshot.SnapshotDiffReport.DiffReportEntry;
+import org.apache.hadoop.ozone.snapshot.SnapshotDiffReport;
+import org.apache.hadoop.ozone.snapshot.SnapshotDiffReport.DiffType;
+import org.apache.hadoop.ozone.snapshot.SnapshotDiffReport.DiffReportEntry;
 
 import org.apache.ozone.rocksdb.util.ManagedSstFileReader;
 import org.apache.ozone.rocksdb.util.RdbUtil;
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerRequestHandler.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerRequestHandler.java
index 4f8b1e5528..932196b54c 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerRequestHandler.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerRequestHandler.java
@@ -102,6 +102,8 @@ import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.Service
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ServiceListResponse;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.GetS3VolumeContextResponse;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.Status;
+import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.SnapshotDiffRequest;
+import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.SnapshotDiffResponse;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.TenantGetUserInfoRequest;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.TenantGetUserInfoResponse;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.TenantListUserRequest;
@@ -283,6 +285,11 @@ public class OzoneManagerRequestHandler implements 
RequestHandler {
             getSnapshots(request.getListSnapshotRequest());
         responseBuilder.setListSnapshotResponse(listSnapshotResponse);
         break;
+      case SnapshotDiff:
+        SnapshotDiffResponse snapshotDiffReport = snapshotDiff(
+            request.getSnapshotDiffRequest());
+        responseBuilder.setSnapshotDiffResponse(snapshotDiffReport);
+        break;
       default:
         responseBuilder.setSuccess(false);
         responseBuilder.setMessage("Unrecognized Command Type: " + cmdType);
@@ -1198,6 +1205,16 @@ public class OzoneManagerRequestHandler implements 
RequestHandler {
     return impl.getS3VolumeContext().getProtobuf();
   }
 
+  private SnapshotDiffResponse snapshotDiff(
+      SnapshotDiffRequest snapshotDiffRequest) throws IOException {
+    return SnapshotDiffResponse.newBuilder().setSnapshotDiffReport(
+        impl.snapshotDiff(snapshotDiffRequest.getVolumeName(),
+            snapshotDiffRequest.getBucketName(),
+            snapshotDiffRequest.getFromSnapshot(),
+            snapshotDiffRequest.getToSnapshot()).toProtobuf()).build();
+  }
+
+
   public OzoneManager getOzoneManager() {
     return impl;
   }
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 97c1338a9a..53c3cb9a22 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
@@ -47,6 +47,7 @@ import org.apache.hadoop.ozone.om.protocol.S3Auth;
 import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
 import org.apache.hadoop.ozone.security.OzoneTokenIdentifier;
 import org.apache.hadoop.ozone.security.acl.OzoneObj;
+import org.apache.hadoop.ozone.snapshot.SnapshotDiffReport;
 import org.apache.hadoop.security.token.Token;
 
 import java.io.IOException;
@@ -583,4 +584,11 @@ public class ClientProtocolStub implements ClientProtocol {
       throws IOException {
     return null;
   }
+
+  public SnapshotDiffReport snapshotDiff(String volumeName, String bucketName,
+                                         String fromSnapshot, String 
toSnapshot)
+      throws IOException {
+    return null;
+  }
+
 }
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 22a4de0414..6d3f8d3a2f 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
@@ -40,6 +40,7 @@ import picocli.CommandLine.ParentCommand;
     subcommands = {
         CreateSnapshotHandler.class,
         ListSnapshotHandler.class,
+        SnapshotDiffHandler.class,
     },
     mixinStandardHelpOptions = true,
     versionProvider = HddsVersionProvider.class)
diff --git 
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/snapshot/SnapshotDiffHandler.java
 
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/snapshot/SnapshotDiffHandler.java
new file mode 100644
index 0000000000..508bda5cc7
--- /dev/null
+++ 
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/snapshot/SnapshotDiffHandler.java
@@ -0,0 +1,67 @@
+/*
+ * 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.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;
+import org.apache.hadoop.ozone.shell.bucket.BucketUri;
+import picocli.CommandLine;
+
+import java.io.IOException;
+import java.io.PrintStream;
+
+/**
+ * ozone snapshot create.
+ */
[email protected](name = "snapshotDiff",
+    description = "Get the differences between two snapshots")
+public class SnapshotDiffHandler extends Handler {
+
+  @CommandLine.Mixin
+  private BucketUri snapshotPath;
+
+  @CommandLine.Parameters(description = "from snapshot name",
+      index = "1")
+  private String fromSnapshot;
+
+  @CommandLine.Parameters(description = "to snapshot name",
+      index = "2")
+  private String toSnapshot;
+
+  @Override
+  protected OzoneAddress getAddress() {
+    return snapshotPath.getValue();
+  }
+
+  @Override
+  protected void execute(OzoneClient client, OzoneAddress address)
+      throws IOException {
+
+    String volumeName = snapshotPath.getValue().getVolumeName();
+    String bucketName = snapshotPath.getValue().getBucketName();
+    OmUtils.validateSnapshotName(fromSnapshot);
+    OmUtils.validateSnapshotName(toSnapshot);
+
+    try (PrintStream stream = out()) {
+      stream.print(client.getObjectStore()
+          .snapshotDiff(volumeName, bucketName, fromSnapshot, toSnapshot));
+    }
+  }
+}


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

Reply via email to