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

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


The following commit(s) were added to refs/heads/master by this push:
     new 4f56b1a  HDDS-6043. Buckets created via link command do not mirror 
layout of s… (#2867)
4f56b1a is described below

commit 4f56b1ad47319ff9f94710c34da685dd16575956
Author: Jyotinder Singh <[email protected]>
AuthorDate: Mon Nov 29 10:17:01 2021 +0530

    HDDS-6043. Buckets created via link command do not mirror layout of s… 
(#2867)
---
 .../apache/hadoop/ozone/client/OzoneBucket.java    |  10 +-
 .../apache/hadoop/ozone/om/TestObjectStore.java    | 128 +++++++++++++++++++++
 .../apache/hadoop/ozone/om/BucketManagerImpl.java  |  58 ++++++++++
 .../om/ratis/utils/OzoneManagerRatisUtils.java     |  64 ++++++++---
 .../protocolPB/OzoneManagerRequestHandler.java     |   2 +-
 .../hadoop/ozone/protocolPB/RequestHandler.java    |   4 +-
 .../apache/hadoop/ozone/debug/PrefixParser.java    |   8 +-
 7 files changed, 256 insertions(+), 18 deletions(-)

diff --git 
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/OzoneBucket.java
 
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/OzoneBucket.java
index 8a8cde9..4993ced 100644
--- 
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/OzoneBucket.java
+++ 
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/OzoneBucket.java
@@ -604,6 +604,14 @@ public class OzoneBucket extends WithMetadata {
   }
 
   /**
+   * Checks if the bucket is a Link Bucket.
+   * @return True if bucket is a link, False otherwise.
+   */
+  public boolean isLink() {
+    return sourceVolume != null && sourceBucket != null;
+  }
+
+  /**
    * Deletes key from the bucket.
    * @param key Name of the key to be deleted.
    * @throws IOException
@@ -1208,7 +1216,7 @@ public class OzoneBucket extends WithMetadata {
   private class KeyIteratorFactory {
     KeyIterator getKeyIterator(String keyPrefix, String prevKey,
         BucketLayout bType) throws IOException {
-      if (bType.equals(BucketLayout.FILE_SYSTEM_OPTIMIZED)) {
+      if (bType.isFileSystemOptimized()) {
         return new KeyIteratorWithFSO(keyPrefix, prevKey);
       } else {
         return new KeyIterator(keyPrefix, prevKey);
diff --git 
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestObjectStore.java
 
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestObjectStore.java
index 8432d8c..7ddfc3d 100644
--- 
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestObjectStore.java
+++ 
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/TestObjectStore.java
@@ -19,6 +19,7 @@ package org.apache.hadoop.ozone.om;
 import org.apache.hadoop.hdds.conf.OzoneConfiguration;
 import org.apache.hadoop.ozone.MiniOzoneCluster;
 import org.apache.hadoop.ozone.client.*;
+import org.apache.hadoop.ozone.om.exceptions.OMException;
 import org.apache.hadoop.ozone.om.helpers.BucketLayout;
 import org.junit.*;
 import org.junit.rules.Timeout;
@@ -100,4 +101,131 @@ public class TestObjectStore {
     Assert.assertEquals(sampleBucketName, bucket.getName());
     Assert.assertNotEquals(BucketLayout.LEGACY, bucket.getBucketLayout());
   }
+
+  /**
+   * Ensure Link Buckets have same BucketLayout as source buckets.
+   * @throws Exception
+   */
+  @Test
+  public void testCreateLinkBucketWithBucketLayout() throws Exception {
+    String volumeName = UUID.randomUUID().toString();
+
+    String sourceBucket1Name = UUID.randomUUID().toString();
+    BucketLayout sourceBucket1Layout = BucketLayout.FILE_SYSTEM_OPTIMIZED;
+
+    String sourceBucket2Name = UUID.randomUUID().toString();
+    BucketLayout sourceBucket2Layout = BucketLayout.OBJECT_STORE;
+
+    String linkBucket1Name = UUID.randomUUID().toString();
+    String linkBucket2Name = UUID.randomUUID().toString();
+    // Chained link bucket
+    String linkBucket3Name = UUID.randomUUID().toString();
+
+    OzoneClient client = cluster.getClient();
+    ObjectStore store = client.getObjectStore();
+
+    // Create volume
+    store.createVolume(volumeName);
+    OzoneVolume volume = store.getVolume(volumeName);
+
+    // Create source buckets
+    BucketArgs.Builder builder = BucketArgs.newBuilder();
+    builder.setBucketLayout(sourceBucket1Layout);
+    volume.createBucket(sourceBucket1Name, builder.build());
+    builder.setBucketLayout(sourceBucket2Layout);
+    volume.createBucket(sourceBucket2Name, builder.build());
+
+    // Create link buckets
+    createLinkBucket(volume, sourceBucket1Name, linkBucket1Name);
+    createLinkBucket(volume, sourceBucket2Name, linkBucket2Name);
+    // linkBucket3 is chained onto linkBucket1
+    createLinkBucket(volume, linkBucket1Name, linkBucket3Name);
+
+    // Check that Link Buckets' layouts match source bucket layouts
+    OzoneBucket bucket = volume.getBucket(linkBucket1Name);
+    Assert.assertEquals(sourceBucket1Layout, bucket.getBucketLayout());
+
+    bucket = volume.getBucket(linkBucket2Name);
+    Assert.assertEquals(sourceBucket2Layout, bucket.getBucketLayout());
+
+    // linkBucket3 is chained onto linkBucket1, hence its bucket layout matches
+    // linkBucket1's source bucket.
+    bucket = volume.getBucket(linkBucket3Name);
+    Assert.assertEquals(sourceBucket1Layout, bucket.getBucketLayout());
+    Assert.assertEquals(linkBucket1Name, bucket.getSourceBucket());
+  }
+
+  @Test
+  public void testCreateDanglingLinkBucket() throws Exception {
+    String volumeName = UUID.randomUUID().toString();
+    // Does not exist
+    String sourceBucketName = UUID.randomUUID().toString();
+
+    OzoneClient client = cluster.getClient();
+    ObjectStore store = client.getObjectStore();
+
+    // Create volume
+    store.createVolume(volumeName);
+    OzoneVolume volume = store.getVolume(volumeName);
+
+    // Dangling link bucket
+    String danglingLinkBucketName = UUID.randomUUID().toString();
+
+    // danglingLinkBucket is a dangling link over a source bucket that doesn't
+    // exist.
+    createLinkBucket(volume, sourceBucketName, danglingLinkBucketName);
+
+    // since sourceBucket does not exist, layout depends on
+    // OZONE_DEFAULT_BUCKET_LAYOUT config.
+    OzoneBucket bucket = volume.getBucket(danglingLinkBucketName);
+    Assert.assertEquals(BucketLayout.fromString(
+            conf.get(OMConfigKeys.OZONE_DEFAULT_BUCKET_LAYOUT)),
+        bucket.getBucketLayout());
+    Assert.assertEquals(sourceBucketName, bucket.getSourceBucket());
+  }
+
+  @Test
+  public void testLoopInLinkBuckets() throws Exception {
+    String volumeName = UUID.randomUUID().toString();
+
+    OzoneClient client = cluster.getClient();
+    ObjectStore store = client.getObjectStore();
+
+    // Create volume
+    store.createVolume(volumeName);
+    OzoneVolume volume = store.getVolume(volumeName);
+
+    String linkBucket1Name = UUID.randomUUID().toString();
+    String linkBucket2Name = UUID.randomUUID().toString();
+    String linkBucket3Name = UUID.randomUUID().toString();
+
+    // Create a loop in the link buckets
+    createLinkBucket(volume, linkBucket1Name, linkBucket2Name);
+    createLinkBucket(volume, linkBucket2Name, linkBucket3Name);
+    createLinkBucket(volume, linkBucket3Name, linkBucket1Name);
+
+    try {
+      volume.getBucket(linkBucket1Name);
+      Assert.fail("Should throw Exception due to loop in Link Buckets");
+    } catch (OMException oe) {
+      // Expected exception
+    }
+  }
+
+  /**
+   * Helper method to create Link Buckets.
+   *
+   * @param sourceVolume Name of source volume for Link Bucket.
+   * @param sourceBucket Name of source bucket for Link Bucket.
+   * @param linkBucket   Name of Link Bucket
+   * @throws IOException
+   */
+  private void createLinkBucket(OzoneVolume sourceVolume, String sourceBucket,
+                                String linkBucket) throws IOException {
+    BucketArgs.Builder builder = BucketArgs.newBuilder();
+    builder.setBucketLayout(BucketLayout.DEFAULT)
+        .setSourceVolume(sourceVolume.getName())
+        .setSourceBucket(sourceBucket);
+    sourceVolume.createBucket(linkBucket, builder.build());
+  }
 }
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/BucketManagerImpl.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/BucketManagerImpl.java
index 068c629..dcbb158 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/BucketManagerImpl.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/BucketManagerImpl.java
@@ -17,9 +17,12 @@
 package org.apache.hadoop.ozone.om;
 
 import java.io.IOException;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Objects;
+import java.util.Set;
 
+import org.apache.commons.lang3.tuple.Pair;
 import org.apache.hadoop.crypto.CipherSuite;
 import org.apache.hadoop.crypto.CryptoProtocolVersion;
 import org.apache.hadoop.crypto.key.KeyProvider;
@@ -45,6 +48,7 @@ import org.slf4j.LoggerFactory;
 
 import static 
org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.BUCKET_NOT_FOUND;
 import static 
org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.INTERNAL_ERROR;
+import static 
org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.DETECTED_LOOP_IN_BUCKET_LINKS;
 import static 
org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.VOLUME_NOT_FOUND;
 import static 
org.apache.hadoop.ozone.om.lock.OzoneManagerLock.Resource.BUCKET_LOCK;
 import static 
org.apache.hadoop.ozone.om.lock.OzoneManagerLock.Resource.VOLUME_LOCK;
@@ -268,6 +272,9 @@ public class BucketManagerImpl implements BucketManager {
           throw new OMException("Bucket not found", BUCKET_NOT_FOUND);
         }
       }
+
+      value = resolveLinkBucketLayout(value, new HashSet<>());
+
       return value;
     } catch (IOException ex) {
       if (!(ex instanceof OMException)) {
@@ -282,6 +289,57 @@ public class BucketManagerImpl implements BucketManager {
   }
 
   /**
+   * Get the source bucket layout for a link bucket.
+   *
+   * @param bucketInfo
+   * @return {@code OmBucketInfo} with
+   * @throws IOException
+   */
+  public OmBucketInfo resolveLinkBucketLayout(OmBucketInfo bucketInfo,
+                                               Set<Pair<String,
+                                                   String>> visited)
+      throws IOException {
+
+    if (bucketInfo.isLink()) {
+      if (!visited.add(Pair.of(bucketInfo.getVolumeName(),
+          bucketInfo.getBucketName()))) {
+        throw new OMException("Detected loop in bucket links. Bucket name: " +
+            bucketInfo.getBucketName() + ", Volume name: " +
+            bucketInfo.getVolumeName(),
+            DETECTED_LOOP_IN_BUCKET_LINKS);
+      }
+      String sourceBucketKey = metadataManager
+          .getBucketKey(bucketInfo.getSourceVolume(),
+              bucketInfo.getSourceBucket());
+      OmBucketInfo sourceBucketInfo =
+          metadataManager.getBucketTable().get(sourceBucketKey);
+
+      // If the Link Bucket's source bucket exists, we get its layout.
+      if (sourceBucketInfo != null) {
+
+        /** If the source bucket is again a link, we recursively resolve the
+         * link bucket.
+         *
+         * For example:
+         * buck-link1 -> buck-link2 -> buck-link3 -> buck-src
+         * buck-src has the actual BucketLayout that will be used by the links.
+         *
+         * Finally - we return buck-link1's OmBucketInfo, with buck-src's
+         * bucket layout.
+         */
+        if (sourceBucketInfo.isLink()) {
+          sourceBucketInfo = resolveLinkBucketLayout(sourceBucketInfo, 
visited);
+        }
+
+        OmBucketInfo.Builder buckInfoBuilder = bucketInfo.toBuilder();
+        buckInfoBuilder.setBucketLayout(sourceBucketInfo.getBucketLayout());
+        bucketInfo = buckInfoBuilder.build();
+      }
+    }
+    return bucketInfo;
+  }
+
+  /**
    * Sets bucket property from args.
    *
    * @param args - BucketArgs.
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 90746c2..7205881 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
@@ -22,6 +22,8 @@ import com.google.common.base.Strings;
 import com.google.protobuf.ServiceException;
 import java.io.File;
 import java.nio.file.Paths;
+
+import org.apache.commons.lang3.tuple.Pair;
 import org.apache.hadoop.hdds.conf.ConfigurationSource;
 import org.apache.hadoop.hdds.conf.OzoneConfiguration;
 import org.apache.hadoop.hdds.server.ServerUtils;
@@ -104,12 +106,16 @@ import org.rocksdb.RocksDBException;
 
 import java.io.IOException;
 import java.nio.file.Path;
+import java.util.HashSet;
+import java.util.Set;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import static org.apache.hadoop.hdds.HddsConfigKeys.OZONE_METADATA_DIRS;
 import static org.apache.hadoop.ozone.OzoneConsts.OM_RATIS_SNAPSHOT_DIR;
 import static 
org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_OM_RATIS_SNAPSHOT_DIR;
+import static 
org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.DETECTED_LOOP_IN_BUCKET_LINKS;
 
 /**
  * Utility class used by OzoneManager HA.
@@ -129,7 +135,7 @@ public final class OzoneManagerRatisUtils {
    */
   @SuppressWarnings("checkstyle:methodlength")
   public static OMClientRequest createClientRequest(OMRequest omRequest,
-      OzoneManager ozoneManager) {
+      OzoneManager ozoneManager) throws IOException {
 
     // Handling of exception by createClientRequest(OMRequest, OzoneManger):
     // Either the code will take FSO or non FSO path, both classes has a
@@ -169,7 +175,7 @@ public final class OzoneManagerRatisUtils {
     case AllocateBlock:
       keyArgs = omRequest.getAllocateBlockRequest().getKeyArgs();
       bucketLayout = getBucketLayout(keyArgs.getVolumeName(),
-          keyArgs.getBucketName(), ozoneManager);
+          keyArgs.getBucketName(), ozoneManager, new HashSet<>());
       if (bucketLayout.isFileSystemOptimized()) {
         return new OMAllocateBlockRequestWithFSO(omRequest, bucketLayout);
       }
@@ -177,7 +183,7 @@ public final class OzoneManagerRatisUtils {
     case CreateKey:
       keyArgs = omRequest.getCreateKeyRequest().getKeyArgs();
       bucketLayout = getBucketLayout(keyArgs.getVolumeName(),
-          keyArgs.getBucketName(), ozoneManager);
+          keyArgs.getBucketName(), ozoneManager, new HashSet<>());
       if (bucketLayout.isFileSystemOptimized()) {
         return new OMKeyCreateRequestWithFSO(omRequest, bucketLayout);
       }
@@ -185,7 +191,7 @@ public final class OzoneManagerRatisUtils {
     case CommitKey:
       keyArgs = omRequest.getCommitKeyRequest().getKeyArgs();
       bucketLayout = getBucketLayout(keyArgs.getVolumeName(),
-          keyArgs.getBucketName(), ozoneManager);
+          keyArgs.getBucketName(), ozoneManager, new HashSet<>());
       if (bucketLayout.isFileSystemOptimized()) {
         return new OMKeyCommitRequestWithFSO(omRequest, bucketLayout);
       }
@@ -193,7 +199,7 @@ public final class OzoneManagerRatisUtils {
     case DeleteKey:
       keyArgs = omRequest.getDeleteKeyRequest().getKeyArgs();
       bucketLayout = getBucketLayout(keyArgs.getVolumeName(),
-          keyArgs.getBucketName(), ozoneManager);
+          keyArgs.getBucketName(), ozoneManager, new HashSet<>());
       if (bucketLayout.isFileSystemOptimized()) {
         return new OMKeyDeleteRequestWithFSO(omRequest, bucketLayout);
       }
@@ -203,7 +209,7 @@ public final class OzoneManagerRatisUtils {
     case RenameKey:
       keyArgs = omRequest.getRenameKeyRequest().getKeyArgs();
       bucketLayout = getBucketLayout(keyArgs.getVolumeName(),
-          keyArgs.getBucketName(), ozoneManager);
+          keyArgs.getBucketName(), ozoneManager, new HashSet<>());
       if (bucketLayout.isFileSystemOptimized()) {
         return new OMKeyRenameRequestWithFSO(omRequest, bucketLayout);
       }
@@ -213,7 +219,7 @@ public final class OzoneManagerRatisUtils {
     case CreateDirectory:
       keyArgs = omRequest.getCreateDirectoryRequest().getKeyArgs();
       bucketLayout = getBucketLayout(keyArgs.getVolumeName(),
-          keyArgs.getBucketName(), ozoneManager);
+          keyArgs.getBucketName(), ozoneManager, new HashSet<>());
       if (bucketLayout.isFileSystemOptimized()) {
         return new OMDirectoryCreateRequestWithFSO(omRequest, bucketLayout);
       }
@@ -221,7 +227,7 @@ public final class OzoneManagerRatisUtils {
     case CreateFile:
       keyArgs = omRequest.getCreateFileRequest().getKeyArgs();
       bucketLayout = getBucketLayout(keyArgs.getVolumeName(),
-          keyArgs.getBucketName(), ozoneManager);
+          keyArgs.getBucketName(), ozoneManager, new HashSet<>());
       if (bucketLayout.isFileSystemOptimized()) {
         return new OMFileCreateRequestWithFSO(omRequest, bucketLayout);
       }
@@ -234,7 +240,7 @@ public final class OzoneManagerRatisUtils {
     case InitiateMultiPartUpload:
       keyArgs = omRequest.getInitiateMultiPartUploadRequest().getKeyArgs();
       bucketLayout = getBucketLayout(keyArgs.getVolumeName(),
-          keyArgs.getBucketName(), ozoneManager);
+          keyArgs.getBucketName(), ozoneManager, new HashSet<>());
       if (bucketLayout.isFileSystemOptimized()) {
         return new S3InitiateMultipartUploadRequestWithFSO(omRequest,
             bucketLayout);
@@ -243,7 +249,7 @@ public final class OzoneManagerRatisUtils {
     case CommitMultiPartUpload:
       keyArgs = omRequest.getCommitMultiPartUploadRequest().getKeyArgs();
       bucketLayout = getBucketLayout(keyArgs.getVolumeName(),
-          keyArgs.getBucketName(), ozoneManager);
+          keyArgs.getBucketName(), ozoneManager, new HashSet<>());
       if (bucketLayout.isFileSystemOptimized()) {
         return new S3MultipartUploadCommitPartRequestWithFSO(omRequest,
             bucketLayout);
@@ -252,7 +258,7 @@ public final class OzoneManagerRatisUtils {
     case AbortMultiPartUpload:
       keyArgs = omRequest.getAbortMultiPartUploadRequest().getKeyArgs();
       bucketLayout = getBucketLayout(keyArgs.getVolumeName(),
-          keyArgs.getBucketName(), ozoneManager);
+          keyArgs.getBucketName(), ozoneManager, new HashSet<>());
       if (bucketLayout.isFileSystemOptimized()) {
         return new S3MultipartUploadAbortRequestWithFSO(omRequest,
             bucketLayout);
@@ -261,7 +267,7 @@ public final class OzoneManagerRatisUtils {
     case CompleteMultiPartUpload:
       keyArgs = omRequest.getCompleteMultiPartUploadRequest().getKeyArgs();
       bucketLayout = getBucketLayout(keyArgs.getVolumeName(),
-          keyArgs.getBucketName(), ozoneManager);
+          keyArgs.getBucketName(), ozoneManager, new HashSet<>());
       if (bucketLayout.isFileSystemOptimized()) {
         return new S3MultipartUploadCompleteRequestWithFSO(omRequest,
             bucketLayout);
@@ -499,14 +505,44 @@ public final class OzoneManagerRatisUtils {
   }
 
   private static BucketLayout getBucketLayout(String volName,
-      String buckName, OzoneManager ozoneManager) {
+      String buckName, OzoneManager ozoneManager, Set<Pair<String,
+      String>> visited) throws IOException {
     OmBucketInfo buckInfo = getOmBucketInfo(ozoneManager, volName, buckName);
+
     if (buckInfo != null) {
+      // If this is a link bucket, we fetch the BucketLayout from the
+      // source bucket.
+      if (buckInfo.isLink()) {
+        // Check if this bucket was already visited - to avoid loops
+        if (!visited.add(Pair.of(volName, buckName))) {
+          throw new OMException("Detected loop in bucket links. Bucket name: " 
+
+              buckName + ", Volume name: " + volName,
+              DETECTED_LOOP_IN_BUCKET_LINKS);
+        }
+        OmBucketInfo sourceBuckInfo =
+            getOmBucketInfo(ozoneManager, buckInfo.getSourceVolume(),
+                buckInfo.getSourceBucket());
+        if (sourceBuckInfo != null) {
+          /** If the source bucket is again a link, we recursively resolve the
+           * link bucket.
+           *
+           * For example:
+           * buck-link1 -> buck-link2 -> buck-link3 -> buck-src
+           * buck-src has the actual BucketLayout that will be used by the
+           * links.
+           */
+          if (sourceBuckInfo.isLink()) {
+            return getBucketLayout(sourceBuckInfo.getVolumeName(),
+                sourceBuckInfo.getBucketName(), ozoneManager, visited);
+          }
+          return sourceBuckInfo.getBucketLayout();
+        }
+      }
       return buckInfo.getBucketLayout();
     } else {
       LOG.error("Bucket not found: {}/{} ", volName, buckName);
       // TODO: Handle bucket validation
     }
-    return BucketLayout.LEGACY;
+    return BucketLayout.DEFAULT;
   }
 }
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 6459e43..7ee8e67 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
@@ -235,7 +235,7 @@ public class OzoneManagerRequestHandler implements 
RequestHandler {
 
   @Override
   public OMClientResponse handleWriteRequest(OMRequest omRequest,
-      long transactionLogIndex) {
+      long transactionLogIndex) throws IOException {
     OMClientRequest omClientRequest = null;
     OMClientResponse omClientResponse = null;
     omClientRequest =
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/RequestHandler.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/RequestHandler.java
index f5d2d2b..d1a2587 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/RequestHandler.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/RequestHandler.java
@@ -25,6 +25,8 @@ import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.
 import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.
     OMResponse;
 
+import java.io.IOException;
+
 /**
  * Handler to handleRequest the OmRequests.
  */
@@ -56,7 +58,7 @@ public interface RequestHandler {
    * @return OMClientResponse
    */
   OMClientResponse handleWriteRequest(OMRequest omRequest,
-      long transactionLogIndex);
+      long transactionLogIndex) throws IOException;
 
   /**
    * Update the OzoneManagerDoubleBuffer. This will be called when
diff --git 
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/PrefixParser.java
 
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/PrefixParser.java
index 64b27b4..ed8d0e8 100644
--- 
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/PrefixParser.java
+++ 
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/debug/PrefixParser.java
@@ -21,6 +21,7 @@ package org.apache.hadoop.ozone.debug;
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Paths;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.concurrent.Callable;
@@ -34,6 +35,7 @@ import org.apache.hadoop.hdds.utils.db.Table;
 import org.apache.hadoop.hdds.utils.db.Table.KeyValue;
 import org.apache.hadoop.ozone.om.OMConfigKeys;
 import org.apache.hadoop.ozone.om.OmMetadataManagerImpl;
+import org.apache.hadoop.ozone.om.BucketManagerImpl;
 import org.apache.hadoop.ozone.om.helpers.*;
 import org.kohsuke.MetaInfServices;
 import picocli.CommandLine;
@@ -148,7 +150,11 @@ public class PrefixParser implements Callable<Void>, 
SubcommandWithParent {
       return;
     }
 
-    BucketLayout bucketLayout = info.getBucketLayout();
+    BucketLayout bucketLayout =
+        new BucketManagerImpl(metadataManager)
+            .resolveLinkBucketLayout(info, new HashSet<>())
+            .getBucketLayout();
+
     if (!bucketLayout.isFileSystemOptimized()) {
       System.out.println("Prefix tool only works for FileSystem Optimized" +
               "bucket. Bucket Layout is:" + bucketLayout);

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

Reply via email to