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 1ee083178d HDDS-7484. Snapshot ID on followers should match the one on 
the OM Leader (#3985)
1ee083178d is described below

commit 1ee083178df192d48b16c04b663384f7c336c374
Author: Hemant Kumar <[email protected]>
AuthorDate: Wed Dec 7 14:50:34 2022 -0800

    HDDS-7484. Snapshot ID on followers should match the one on the OM Leader 
(#3985)
---
 .../hadoop/ozone/om/helpers/SnapshotInfo.java      |   9 +-
 .../org/apache/hadoop/ozone/om/TestOmSnapshot.java | 245 ++++++++++-----------
 .../src/main/proto/OmClientProtocol.proto          |   1 +
 .../request/snapshot/OMSnapshotCreateRequest.java  |   9 +-
 .../om/request/validation/RequestValidations.java  |  25 ++-
 .../om/request/validation/ValidatorRegistry.java   |   7 +-
 ...OzoneManagerProtocolServerSideTranslatorPB.java |  95 ++++----
 .../hadoop/ozone/om/TestOmSnapshotManager.java     |   7 +-
 .../ozone/om/request/OMRequestTestUtils.java       |  29 ++-
 .../snapshot/TestOMSnapshotCreateResponse.java     |   7 +-
 10 files changed, 236 insertions(+), 198 deletions(-)

diff --git 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/SnapshotInfo.java
 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/SnapshotInfo.java
index 38b3bb5ed2..f15908dcd8 100644
--- 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/SnapshotInfo.java
+++ 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/SnapshotInfo.java
@@ -463,14 +463,15 @@ public final class SnapshotInfo implements Auditable {
    * Factory for making standard instance.
    */
   public static SnapshotInfo newInstance(String volumeName,
-      String bucketName, String snapshotName) {
+                                         String bucketName,
+                                         String snapshotName,
+                                         String snapshotId) {
     SnapshotInfo.Builder builder = new SnapshotInfo.Builder();
-    String id = UUID.randomUUID().toString();
     long initialTime = Time.now();
     if (StringUtils.isBlank(snapshotName)) {
       snapshotName = generateName(initialTime);
     }
-    builder.setSnapshotID(id)
+    builder.setSnapshotID(snapshotId)
         .setName(snapshotName)
         .setCreationTime(initialTime)
         .setDeletionTime(INVALID_TIMESTAMP)
@@ -479,7 +480,7 @@ public final class SnapshotInfo implements Auditable {
         .setSnapshotPath(volumeName + OM_KEY_PREFIX + bucketName)
         .setVolumeName(volumeName)
         .setBucketName(bucketName)
-        .setCheckpointDir(getCheckpointDirName(id));
+        .setCheckpointDir(getCheckpointDirName(snapshotId));
     return builder.build();
   }
 
diff --git 
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestOmSnapshot.java
 
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestOmSnapshot.java
index 8705f9356d..2d62d22879 100644
--- 
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestOmSnapshot.java
+++ 
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestOmSnapshot.java
@@ -16,12 +16,14 @@
  */
 
 package org.apache.hadoop.ozone.om;
+import java.util.List;
 import org.apache.commons.lang3.RandomStringUtils;
 import org.apache.hadoop.hdds.client.StandaloneReplicationConfig;
 import org.apache.hadoop.hdds.conf.OzoneConfiguration;
 import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
 import org.apache.hadoop.hdds.scm.HddsWhiteboxTestUtils;
 import org.apache.hadoop.ozone.MiniOzoneCluster;
+import org.apache.hadoop.ozone.MiniOzoneHAClusterImpl;
 import org.apache.hadoop.ozone.TestDataUtil;
 import org.apache.hadoop.ozone.client.ObjectStore;
 import org.apache.hadoop.ozone.client.OzoneBucket;
@@ -53,14 +55,11 @@ import java.util.Arrays;
 import java.nio.charset.StandardCharsets;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.UUID;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 
-import static org.apache.hadoop.hdds.client.ReplicationFactor.ONE;
-import static org.apache.hadoop.hdds.client.ReplicationType.RATIS;
 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;
@@ -68,11 +67,9 @@ import static 
org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.KEY_
 import static 
org.apache.hadoop.ozone.om.helpers.BucketLayout.FILE_SYSTEM_OPTIMIZED;
 import static org.apache.hadoop.ozone.om.helpers.BucketLayout.OBJECT_STORE;
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static java.nio.charset.StandardCharsets.UTF_8;
 
-
 /**
  * Test OmSnapshot bucket interface.
  */
@@ -86,7 +83,9 @@ public class TestOmSnapshot {
   private static boolean enabledFileSystemPaths;
   private static ObjectStore store;
   private static File metaDir;
-  private static OzoneManager ozoneManager;
+  private static OzoneManager leaderOzoneManager;
+
+  private static OzoneBucket ozoneBucket;
 
   @Rule
   public Timeout timeout = new Timeout(180, TimeUnit.SECONDS);
@@ -122,38 +121,43 @@ public class TestOmSnapshot {
 
   /**
    * Create a MiniDFSCluster for testing.
-   * <p>
-   *
    */
   private void init() throws Exception {
     OzoneConfiguration conf = new OzoneConfiguration();
     String clusterId = UUID.randomUUID().toString();
     String scmId = UUID.randomUUID().toString();
-    String omId = UUID.randomUUID().toString();
     conf.setBoolean(OMConfigKeys.OZONE_OM_ENABLE_FILESYSTEM_PATHS,
         enabledFileSystemPaths);
     conf.set(OMConfigKeys.OZONE_DEFAULT_BUCKET_LAYOUT,
         bucketLayout.name());
-    cluster = MiniOzoneCluster.newBuilder(conf).setClusterId(clusterId)
-      .setScmId(scmId).setOmId(omId).build();
+
+    cluster = MiniOzoneCluster.newOMHABuilder(conf)
+        .setClusterId(clusterId)
+        .setScmId(scmId)
+        .setOMServiceId("om-service-test1")
+        .setNumOfOzoneManagers(3)
+        .build();
     cluster.waitForClusterToBeReady();
     // create a volume and a bucket to be used by OzoneFileSystem
-    OzoneBucket bucket = TestDataUtil
+    ozoneBucket = TestDataUtil
         .createVolumeAndBucket(cluster, bucketLayout);
-    volumeName = bucket.getVolumeName();
-    bucketName = bucket.getName();
+    volumeName = ozoneBucket.getVolumeName();
+    bucketName = ozoneBucket.getName();
+
+    leaderOzoneManager = ((MiniOzoneHAClusterImpl) cluster).getOMLeader();
+    OzoneConfiguration leaderConfig = leaderOzoneManager.getConfiguration();
+    cluster.setConf(leaderConfig);
 
     OzoneClient client = cluster.getClient();
     store = client.getObjectStore();
     writeClient = store.getClientProxy().getOzoneManagerClient();
-    ozoneManager = cluster.getOzoneManager();
+
     KeyManagerImpl keyManager = (KeyManagerImpl) HddsWhiteboxTestUtils
-        .getInternalState(ozoneManager, "keyManager");
+        .getInternalState(leaderOzoneManager, "keyManager");
 
     // stop the deletion services so that keys can still be read
     keyManager.stop();
-    metaDir = OMStorage.getOmDbDir(conf);
-
+    metaDir = OMStorage.getOmDbDir(leaderConfig);
   }
 
   @AfterClass
@@ -210,65 +214,43 @@ public class TestOmSnapshot {
     }
 
     String snapshotKeyPrefix = createSnapshot(volumeA, bucketA);
-    Iterator<? extends OzoneKey> volABucketAIter =
-        volAbucketA.listKeys(snapshotKeyPrefix + "key-");
-    int volABucketAKeyCount = 0;
-    while (volABucketAIter.hasNext()) {
-      volABucketAIter.next();
-      volABucketAKeyCount++;
-    }
+
+    int volABucketAKeyCount = keyCount(volAbucketA,
+        snapshotKeyPrefix + "key-");
     Assert.assertEquals(20, volABucketAKeyCount);
 
     snapshotKeyPrefix = createSnapshot(volumeA, bucketB);
     deleteKeys(volAbucketB);
-    Iterator<? extends OzoneKey> volABucketBIter =
-        volAbucketB.listKeys(snapshotKeyPrefix + "key-");
-    int volABucketBKeyCount = 0;
-    while (volABucketBIter.hasNext()) {
-      volABucketBIter.next();
-      volABucketBKeyCount++;
-    }
+
+    int volABucketBKeyCount = keyCount(volAbucketB,
+        snapshotKeyPrefix + "key-");
     Assert.assertEquals(20, volABucketBKeyCount);
 
     snapshotKeyPrefix = createSnapshot(volumeB, bucketA);
     deleteKeys(volBbucketA);
-    Iterator<? extends OzoneKey> volBBucketAIter =
-        volBbucketA.listKeys(snapshotKeyPrefix + "key-");
-    int volBBucketAKeyCount = 0;
-    while (volBBucketAIter.hasNext()) {
-      volBBucketAIter.next();
-      volBBucketAKeyCount++;
-    }
+
+    int volBBucketAKeyCount = keyCount(volBbucketA,
+        snapshotKeyPrefix + "key-");
     Assert.assertEquals(20, volBBucketAKeyCount);
 
     snapshotKeyPrefix = createSnapshot(volumeB, bucketB);
     deleteKeys(volBbucketB);
-    Iterator<? extends OzoneKey> volBBucketBIter =
-        volBbucketB.listKeys(snapshotKeyPrefix + "key-");
-    int volBBucketBKeyCount = 0;
-    while (volBBucketBIter.hasNext()) {
-      volBBucketBIter.next();
-      volBBucketBKeyCount++;
-    }
+
+    int volBBucketBKeyCount = keyCount(volBbucketB,
+        snapshotKeyPrefix + "key-");
     Assert.assertEquals(20, volBBucketBKeyCount);
 
     snapshotKeyPrefix = createSnapshot(volumeA, bucketA);
     deleteKeys(volAbucketA);
-    Iterator<? extends OzoneKey> volABucketAKeyAIter =
-        volAbucketA.listKeys(snapshotKeyPrefix + "key-a-");
-    int volABucketAKeyACount = 0;
-    while (volABucketAKeyAIter.hasNext()) {
-      volABucketAKeyAIter.next();
-      volABucketAKeyACount++;
-    }
+
+    int volABucketAKeyACount = keyCount(volAbucketA,
+        snapshotKeyPrefix + "key-a-");
     Assert.assertEquals(10, volABucketAKeyACount);
-    Iterator<? extends OzoneKey> volABucketAKeyBIter =
-        volAbucketA.listKeys(snapshotKeyPrefix + "key-b-");
-    for (int i = 0; i < 10; i++) {
-      Assert.assertTrue(volABucketAKeyBIter.next().getName()
-          .startsWith(snapshotKeyPrefix + "key-b-" + i + "-"));
-    }
-    Assert.assertFalse(volABucketBIter.hasNext());
+
+
+    int volABucketAKeyBCount = keyCount(volAbucketA,
+        snapshotKeyPrefix + "key-b-");
+    Assert.assertEquals(10, volABucketAKeyBCount);
   }
 
   @Test
@@ -302,23 +284,19 @@ public class TestOmSnapshot {
 
   @Test
   public void checkKey() throws Exception {
-    OzoneVolume ozoneVolume = store.getVolume(volumeName);
-    assertTrue(ozoneVolume.getName().equals(volumeName));
-    OzoneBucket ozoneBucket = ozoneVolume.getBucket(bucketName);
-    assertTrue(ozoneBucket.getName().equals(bucketName));
-
     String s = "testData";
     String dir1 = "dir1";
     String key1 = dir1 + "/key1";
 
     // create key1
-    OzoneOutputStream ozoneOutputStream =
-            ozoneBucket.createKey(key1, s.length());
+    OzoneOutputStream ozoneOutputStream = ozoneBucket.createKey(key1,
+        s.length());
     byte[] input = s.getBytes(StandardCharsets.UTF_8);
     ozoneOutputStream.write(input);
     ozoneOutputStream.close();
 
-    String snapshotKeyPrefix = createSnapshot();
+
+    String snapshotKeyPrefix = createSnapshot(volumeName, bucketName);
     ozoneBucket.deleteKey(key1);
     try {
       ozoneBucket.deleteKey(dir1);
@@ -349,25 +327,19 @@ public class TestOmSnapshot {
     store.createVolume(volume);
     OzoneVolume vol = store.getVolume(volume);
     vol.createBucket(bucket);
-    OzoneBucket volbucket = vol.getBucket(bucket);
+    OzoneBucket volBucket = vol.getBucket(bucket);
 
     String key = "key-";
-    createFileKey(volbucket, key);
+    createFileKey(volBucket, key);
     String snapshotKeyPrefix = createSnapshot(volume, bucket);
-    deleteKeys(volbucket);
-
-    Iterator<? extends OzoneKey> volBucketIter =
-            volbucket.listKeys(snapshotKeyPrefix + "key-");
-    int volBucketKeyCount = 0;
-    while (volBucketIter.hasNext()) {
-      volBucketIter.next();
-      volBucketKeyCount++;
-    }
+    deleteKeys(volBucket);
+
+    int volBucketKeyCount = keyCount(volBucket, snapshotKeyPrefix + "key-");
     Assert.assertEquals(1, volBucketKeyCount);
 
     snapshotKeyPrefix = createSnapshot(volume, bucket);
     Iterator<? extends OzoneKey> volBucketIter2 =
-            volbucket.listKeys(snapshotKeyPrefix);
+            volBucket.listKeys(snapshotKeyPrefix);
     while (volBucketIter2.hasNext()) {
       fail("The last snapshot should not have any keys in it!");
     }
@@ -381,41 +353,39 @@ public class TestOmSnapshot {
     store.createVolume(volume);
     OzoneVolume vol = store.getVolume(volume);
     vol.createBucket(bucket);
-    OzoneBucket volbucket = vol.getBucket(bucket);
+    OzoneBucket bucket1 = vol.getBucket(bucket);
 
     String key1 = "key-1-";
-    createFileKey(volbucket, key1);
+    createFileKey(bucket1, key1);
     String snapshotKeyPrefix1 = createSnapshot(volume, bucket);
 
     String key2 = "key-2-";
-    createFileKey(volbucket, key2);
+    createFileKey(bucket1, key2);
     String snapshotKeyPrefix2 = createSnapshot(volume, bucket);
 
-    Iterator<? extends OzoneKey> volBucketIter =
-            volbucket.listKeys(snapshotKeyPrefix1 + "key-");
-    int volBucketKeyCount = 0;
-    while (volBucketIter.hasNext()) {
-      volBucketIter.next();
-      volBucketKeyCount++;
-    }
+    int volBucketKeyCount = keyCount(bucket1, snapshotKeyPrefix1 + "key-");
     Assert.assertEquals(1, volBucketKeyCount);
 
-    Iterator<? extends OzoneKey> volBucketIter2 =
-            volbucket.listKeys(snapshotKeyPrefix2 + "key-");
-    int volBucketKeyCount2 = 0;
-    while (volBucketIter2.hasNext()) {
-      volBucketIter2.next();
-      volBucketKeyCount2++;
-    }
+
+    int volBucketKeyCount2 = keyCount(bucket1, snapshotKeyPrefix2 + "key-");
     Assert.assertEquals(2, volBucketKeyCount2);
 
-    deleteKeys(volbucket);
+    deleteKeys(bucket1);
+  }
 
+  private int keyCount(OzoneBucket bucket, String keyPrefix)
+      throws IOException {
+    Iterator<? extends OzoneKey> iterator = bucket.listKeys(keyPrefix);
+    int keyCount = 0;
+    while (iterator.hasNext()) {
+      iterator.next();
+      keyCount++;
+    }
+    return keyCount;
   }
 
   @Test
-  public void testNonExistentBucket()
-          throws Exception {
+  public void testNonExistentBucket() throws Exception {
     String volume = "vol-" + RandomStringUtils.randomNumeric(5);
     String bucket = "buc-" + RandomStringUtils.randomNumeric(5);
     //create volume but not bucket
@@ -426,50 +396,79 @@ public class TestOmSnapshot {
             () -> createSnapshot(volume, bucket));
   }
 
-  private String createSnapshot()
-      throws IOException, InterruptedException, TimeoutException {
-    return createSnapshot(volumeName, bucketName);
-  }
-  private String createSnapshot(String vname, String bname)
+  private String createSnapshot(String volName, String buckName)
       throws IOException, InterruptedException, TimeoutException {
     String snapshotName = UUID.randomUUID().toString();
-    writeClient = store.getClientProxy().getOzoneManagerClient();
-    writeClient.createSnapshot(vname, bname, snapshotName);
+    store.createSnapshot(volName, buckName, snapshotName);
     String snapshotKeyPrefix = OmSnapshotManager
         .getSnapshotPrefix(snapshotName);
-    SnapshotInfo snapshotInfo = ozoneManager
-        .getMetadataManager().getSnapshotInfoTable()
-        .get(SnapshotInfo.getTableKey(vname, bname, snapshotName));
+    SnapshotInfo snapshotInfo = leaderOzoneManager
+        .getMetadataManager()
+        .getSnapshotInfoTable()
+        .get(SnapshotInfo.getTableKey(volName, buckName, snapshotName));
     String snapshotDirName = metaDir + OM_KEY_PREFIX +
         OM_SNAPSHOT_DIR + OM_KEY_PREFIX + OM_DB_NAME +
         snapshotInfo.getCheckpointDirName() + OM_KEY_PREFIX + "CURRENT";
     GenericTestUtils.waitFor(() -> new File(snapshotDirName).exists(),
         1000, 120000);
-
     return snapshotKeyPrefix;
 
   }
 
-
   private void deleteKeys(OzoneBucket bucket) throws IOException {
-    Iterator<? extends OzoneKey> bucketIter =
-        bucket.listKeys(null);
-    while (bucketIter.hasNext()) {
-      OzoneKey key = bucketIter.next();
+    Iterator<? extends OzoneKey> bucketIterator = bucket.listKeys(null);
+    while (bucketIterator.hasNext()) {
+      OzoneKey key = bucketIterator.next();
       bucket.deleteKey(key.getName());
     }
   }
 
-  private void createFileKey(OzoneBucket bucket, String keyprefix)
-          throws IOException {
+  private void createFileKey(OzoneBucket bucket, String keyPrefix)
+      throws IOException {
     byte[] value = RandomStringUtils.randomAscii(10240).getBytes(UTF_8);
-    OzoneOutputStream fileKey = bucket.createKey(
-            keyprefix + RandomStringUtils.randomNumeric(5),
-            value.length, RATIS, ONE,
-            new HashMap<>());
+    String key = keyPrefix + RandomStringUtils.randomNumeric(5);
+    OzoneOutputStream fileKey = bucket.createKey(key, value.length);
     fileKey.write(value);
     fileKey.close();
   }
 
-}
+  @Test
+  public void testUniqueSnapshotId()
+      throws IOException, InterruptedException, TimeoutException {
+    createFileKey(ozoneBucket, "key");
 
+    String snapshotName = UUID.randomUUID().toString();
+    store.createSnapshot(volumeName, bucketName, snapshotName);
+
+    List<OzoneManager> ozoneManagers = ((MiniOzoneHAClusterImpl) cluster)
+        .getOzoneManagersList();
+    List<String> snapshotIds = new ArrayList<>();
+
+    for (OzoneManager ozoneManager : ozoneManagers) {
+      GenericTestUtils.waitFor(
+          () -> {
+            SnapshotInfo snapshotInfo;
+            try {
+              snapshotInfo = ozoneManager.getMetadataManager()
+                  .getSnapshotInfoTable()
+                  .get(
+                      SnapshotInfo.getTableKey(volumeName,
+                          bucketName,
+                          snapshotName)
+                  );
+            } catch (IOException e) {
+              throw new RuntimeException(e);
+            }
+
+            if (snapshotInfo != null) {
+              snapshotIds.add(snapshotInfo.getSnapshotID());
+            }
+            return snapshotInfo != null;
+          },
+          1000,
+          120000);
+    }
+
+    assertEquals(1, snapshotIds.stream().distinct().count());
+  }
+}
diff --git 
a/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto 
b/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
index 37fa9673a1..49ea0cf6b3 100644
--- a/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
+++ b/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
@@ -1646,6 +1646,7 @@ message CreateSnapshotRequest {
   required string volumeName = 1;
   required string bucketName = 2;
   optional string snapshotName = 3;
+  optional string snapshotId = 4;
 }
 
 message ListSnapshotRequest {
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 3c36845e19..4b9f636811 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
@@ -64,6 +64,7 @@ public class OMSnapshotCreateRequest extends OMClientRequest {
   private final String volumeName;
   private final String bucketName;
   private final String snapshotName;
+  private final String snapshotId;
   private final SnapshotInfo snapshotInfo;
 
   public OMSnapshotCreateRequest(OMRequest omRequest) {
@@ -72,9 +73,13 @@ public class OMSnapshotCreateRequest extends OMClientRequest 
{
         .getCreateSnapshotRequest();
     volumeName = createSnapshotRequest.getVolumeName();
     bucketName = createSnapshotRequest.getBucketName();
+    snapshotId = createSnapshotRequest.getSnapshotId();
+
     String possibleName = createSnapshotRequest.getSnapshotName();
-    snapshotInfo =
-        SnapshotInfo.newInstance(volumeName, bucketName, possibleName);
+    snapshotInfo = SnapshotInfo.newInstance(volumeName,
+        bucketName,
+        possibleName,
+        snapshotId);
     snapshotName = snapshotInfo.getName();
     snapshotPath = snapshotInfo.getSnapshotPath();
   }
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/validation/RequestValidations.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/validation/RequestValidations.java
index feb3b299ed..a85e80bec6 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/validation/RequestValidations.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/validation/RequestValidations.java
@@ -17,7 +17,9 @@
 package org.apache.hadoop.ozone.om.request.validation;
 
 import com.google.protobuf.ServiceException;
+import java.util.UUID;
 import org.apache.hadoop.ozone.om.exceptions.OMException;
+import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRequest;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMResponse;
 import org.slf4j.Logger;
@@ -31,6 +33,7 @@ import java.util.stream.Collectors;
 
 import static 
org.apache.hadoop.ozone.om.request.validation.RequestProcessingPhase.POST_PROCESS;
 import static 
org.apache.hadoop.ozone.om.request.validation.RequestProcessingPhase.PRE_PROCESS;
+import static 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.Type.CreateSnapshot;
 
 /**
  * Main class to configure and set up and access the request/response
@@ -65,7 +68,7 @@ public class RequestValidations {
     List<Method> validations = registry.validationsFor(
         conditions(request), request.getCmdType(), PRE_PROCESS);
 
-    OMRequest validatedRequest = request.toBuilder().build();
+    OMRequest validatedRequest = createValidationRequest(request);
     try {
       for (Method m : validations) {
         LOG.debug("Running the {} request pre-process validation from {}.{}",
@@ -111,4 +114,24 @@ public class RequestValidations {
         .collect(Collectors.toList());
   }
 
+  /**
+   * Clones client request with updated parameters needed at server side.
+   * <p>
+   * e.g. For CreateSnapshot request, it clones the client request and adds
+   * snapshotId to a create snapshot request to make sure that all the OM
+   * nodes (leader and followers) have the same snapshotId.
+   */
+  private OMRequest createValidationRequest(OMRequest clientRequest) {
+    if (clientRequest.getCmdType() == CreateSnapshot) {
+      OzoneManagerProtocolProtos.CreateSnapshotRequest requestWithSnapshotId =
+          clientRequest.getCreateSnapshotRequest().toBuilder()
+              .setSnapshotId(UUID.randomUUID().toString())
+              .build();
+      return clientRequest.toBuilder()
+          .setCreateSnapshotRequest(requestWithSnapshotId)
+          .build();
+    } else {
+      return clientRequest.toBuilder().build();
+    }
+  }
 }
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/validation/ValidatorRegistry.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/validation/ValidatorRegistry.java
index 72bd0bbfc6..8eeb7bf0e4 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/validation/ValidatorRegistry.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/validation/ValidatorRegistry.java
@@ -98,11 +98,10 @@ public class ValidatorRegistry {
       return Collections.emptyList();
     }
 
-    Set<Method> returnValue =
-        new HashSet<>(validationsFor(conditions.get(0), requestType, phase));
+    Set<Method> returnValue = new HashSet<>();
 
-    for (int i = 1; i < conditions.size(); i++) {
-      returnValue.addAll(validationsFor(conditions.get(i), requestType, 
phase));
+    for (ValidationCondition condition: conditions) {
+      returnValue.addAll(validationsFor(condition, requestType, phase));
     }
     return new ArrayList<>(returnValue);
   }
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerProtocolServerSideTranslatorPB.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerProtocolServerSideTranslatorPB.java
index a21cef363e..0b21668d26 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerProtocolServerSideTranslatorPB.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerProtocolServerSideTranslatorPB.java
@@ -125,6 +125,7 @@ public class OzoneManagerProtocolServerSideTranslatorPB 
implements
                 ValidationContext.of(ozoneManager.getVersionManager(),
                     ozoneManager.getMetadataManager()))
             .load();
+
   }
 
   /**
@@ -143,67 +144,63 @@ public class OzoneManagerProtocolServerSideTranslatorPB 
implements
       throw new ServiceException(e);
     }
 
-    OMResponse response = 
-        dispatcher.processRequest(validatedRequest, this::processRequest,
-        request.getCmdType(), request.getTraceID());
-    
+    OMResponse response = dispatcher.processRequest(validatedRequest,
+        this::processRequest,
+        request.getCmdType(),
+        request.getTraceID());
+
     return requestValidations.validateResponse(request, response);
   }
 
-  private OMResponse processRequest(OMRequest request) throws
-      ServiceException {
+  private OMResponse processRequest(OMRequest request) throws ServiceException 
{
     OMClientRequest omClientRequest = null;
-
     boolean s3Auth = false;
+
     try {
       if (request.hasS3Authentication()) {
         OzoneManager.setS3Auth(request.getS3Authentication());
         try {
           s3Auth = true;
-          // If Request has S3Authentication validate S3 credentials
-          // if current OM is leader and then proceed with
-          // processing the request.
+          // If request has S3Authentication, validate S3 credentials.
+          // If current OM is leader and then proceed with the request.
           S3SecurityUtil.validateS3Credential(request, ozoneManager);
         } catch (IOException ex) {
-          // If validate credentials fail return error OM Response.
           return createErrorResponse(request, ex);
         }
       }
-      if (isRatisEnabled) {
-        // Check if the request is a read only request
-        if (OmUtils.isReadOnly(request)) {
-          return submitReadRequestToOM(request);
-        } else {
-          // To validate credentials we have already verified leader status.
-          // This will skip of checking leader status again if request has
-          // S3Auth.
-          if (!s3Auth) {
-            OzoneManagerRatisUtils.checkLeaderStatus(ozoneManager);
-          }
-          try {
-            omClientRequest =
-                createClientRequest(request, ozoneManager);
-            // TODO: Note: Due to HDDS-6055, createClientRequest() could now
-            //  return null, which triggered the findbugs warning.
-            //  Added the assertion.
-            assert (omClientRequest != null);
-            request = omClientRequest.preExecute(ozoneManager);
-          } catch (IOException ex) {
-            // As some of the preExecute returns error. So handle here.
-            if (omClientRequest != null) {
-              omClientRequest.handleRequestFailure(ozoneManager);
-            }
-            return createErrorResponse(request, ex);
-          }
-          OMResponse response = submitRequestToRatis(request);
-          if (!response.getSuccess()) {
-            omClientRequest.handleRequestFailure(ozoneManager);
-          }
-          return response;
-        }
-      } else {
+
+      if (!isRatisEnabled) {
         return submitRequestDirectlyToOM(request);
       }
+
+      if (OmUtils.isReadOnly(request)) {
+        return submitReadRequestToOM(request);
+      }
+
+      // To validate credentials we have already verified leader status.
+      // This will skip of checking leader status again if request has S3Auth.
+      if (!s3Auth) {
+        OzoneManagerRatisUtils.checkLeaderStatus(ozoneManager);
+      }
+      try {
+        omClientRequest = createClientRequest(request, ozoneManager);
+        // TODO: Note: Due to HDDS-6055, createClientRequest() could now
+        //  return null, which triggered the findbugs warning.
+        //  Added the assertion.
+        assert (omClientRequest != null);
+        request = omClientRequest.preExecute(ozoneManager);
+      } catch (IOException ex) {
+        if (omClientRequest != null) {
+          omClientRequest.handleRequestFailure(ozoneManager);
+        }
+        return createErrorResponse(request, ex);
+      }
+
+      OMResponse response = submitRequestToRatis(request);
+      if (!response.getSuccess()) {
+        omClientRequest.handleRequestFailure(ozoneManager);
+      }
+      return response;
     } finally {
       OzoneManager.setS3Auth(null);
     }
@@ -267,10 +264,8 @@ public class OzoneManagerProtocolServerSideTranslatorPB 
implements
   /**
    * Submits request directly to OM.
    */
-  private OMResponse submitRequestDirectlyToOM(OMRequest request) throws
-      ServiceException {
-    OMClientResponse omClientResponse = null;
-    long index = 0L;
+  private OMResponse submitRequestDirectlyToOM(OMRequest request) {
+    OMClientResponse omClientResponse;
     try {
       if (OmUtils.isReadOnly(request)) {
         return handler.handleReadRequest(request);
@@ -278,11 +273,11 @@ public class OzoneManagerProtocolServerSideTranslatorPB 
implements
         OMClientRequest omClientRequest =
             createClientRequest(request, ozoneManager);
         request = omClientRequest.preExecute(ozoneManager);
-        index = transactionIndex.incrementAndGet();
+        long index = transactionIndex.incrementAndGet();
         omClientResponse = handler.handleWriteRequest(request, index);
       }
     } catch (IOException ex) {
-      // As some of the preExecute returns error. So handle here.
+      // As some preExecute returns error. So handle here.
       return createErrorResponse(request, ex);
     }
     try {
diff --git 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestOmSnapshotManager.java
 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestOmSnapshotManager.java
index 3a89ed6973..9b300d86fe 100644
--- 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestOmSnapshotManager.java
+++ 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestOmSnapshotManager.java
@@ -118,8 +118,11 @@ public class TestOmSnapshotManager {
     String snapshotName = UUID.randomUUID().toString();
     String volumeName = UUID.randomUUID().toString();
     String bucketName = UUID.randomUUID().toString();
-    return SnapshotInfo.newInstance(
-        volumeName, bucketName, snapshotName);
+    String snapshotId = UUID.randomUUID().toString();
+    return SnapshotInfo.newInstance(volumeName,
+        bucketName,
+        snapshotName,
+        snapshotId);
   }
 
 }
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 c6c2c4a7df..e86cb78c12 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
@@ -344,7 +344,7 @@ public final class OMRequestTestUtils {
       String volumeName, String bucketName, String snapshotName,
       OMMetadataManager omMetadataManager) throws IOException {
     SnapshotInfo snapshotInfo = SnapshotInfo.newInstance(volumeName,
-        bucketName, snapshotName);
+        bucketName, snapshotName, UUID.randomUUID().toString());
     addSnapshotToTable(false, 0L, snapshotInfo, omMetadataManager);
   }
 
@@ -355,7 +355,7 @@ public final class OMRequestTestUtils {
       String volumeName, String bucketName, String snapshotName,
       OMMetadataManager omMetadataManager) throws IOException {
     SnapshotInfo snapshotInfo = SnapshotInfo.newInstance(volumeName, 
bucketName,
-        snapshotName);
+        snapshotName, UUID.randomUUID().toString());
     addSnapshotToTable(true, 0L, snapshotInfo, omMetadataManager);
   }
 
@@ -1102,17 +1102,26 @@ public final class OMRequestTestUtils {
 
   /**
    * Create OMRequest for Create Snapshot.
-   * @param name
-   * @param snapshotPath
+   * @param volumeName vol to be used
+   * @param bucketName bucket to be used
+   * @param snapshotName name to be used
    */
   public static OMRequest createSnapshotRequest(String volumeName,
-      String bucketName, String snapshotName) {
-    return OMRequest.newBuilder().setCreateSnapshotRequest(
-            OzoneManagerProtocolProtos.CreateSnapshotRequest.newBuilder()
-                .setVolumeName(volumeName).setBucketName(bucketName)
-                .setSnapshotName(snapshotName))
+                                                String bucketName,
+                                                String snapshotName) {
+    OzoneManagerProtocolProtos.CreateSnapshotRequest createSnapshotRequest =
+        OzoneManagerProtocolProtos.CreateSnapshotRequest.newBuilder()
+            .setVolumeName(volumeName)
+            .setBucketName(bucketName)
+            .setSnapshotId(UUID.randomUUID().toString())
+            .setSnapshotName(snapshotName)
+            .build();
+
+    return OMRequest.newBuilder()
+        .setCreateSnapshotRequest(createSnapshotRequest)
         .setCmdType(OzoneManagerProtocolProtos.Type.CreateSnapshot)
-        .setClientId(UUID.randomUUID().toString()).build();
+        .setClientId(UUID.randomUUID().toString())
+        .build();
   }
 
   /**
diff --git 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/response/snapshot/TestOMSnapshotCreateResponse.java
 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/response/snapshot/TestOMSnapshotCreateResponse.java
index 755fed158b..09d6849ee1 100644
--- 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/response/snapshot/TestOMSnapshotCreateResponse.java
+++ 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/response/snapshot/TestOMSnapshotCreateResponse.java
@@ -79,8 +79,11 @@ public class TestOMSnapshotCreateResponse {
     String volumeName = UUID.randomUUID().toString();
     String bucketName = UUID.randomUUID().toString();
     String snapshotName = UUID.randomUUID().toString();
-    SnapshotInfo snapshotInfo =
-        SnapshotInfo.newInstance(volumeName, bucketName, snapshotName);
+    String snapshotId = UUID.randomUUID().toString();
+    SnapshotInfo snapshotInfo = SnapshotInfo.newInstance(volumeName,
+        bucketName,
+        snapshotName,
+        snapshotId);
 
     // confirm table is empty
     Assert.assertEquals(0,


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


Reply via email to