diff --git a/hadoop-hdds/docs/content/feature/PrefixFSO.md b/hadoop-hdds/docs/content/feature/PrefixFSO.md index 894f36a48f1d..dfdeccaa9a24 100644 --- a/hadoop-hdds/docs/content/feature/PrefixFSO.md +++ b/hadoop-hdds/docs/content/feature/PrefixFSO.md @@ -66,7 +66,7 @@ Following picture describes the OM metadata changes while performing a rename The following configuration can be configured in `ozone-site.xml` to define the default value for bucket layout during bucket creation if the client has not specified the bucket layout argument. -Supported values are `OBJECT_STORE` and `FILE_SYSTEM_OPTIMIZED`. +Supported values are `OBJECT_STORE`, `FILE_SYSTEM_OPTIMIZED` and `LEGACY`. By default, this config value is empty. Ozone will default to `LEGACY` bucket layout if it finds an empty config value. diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/shell/TestOzoneShellHA.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/shell/TestOzoneShellHA.java index 69977648a1e4..d22e4cad48e3 100644 --- a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/shell/TestOzoneShellHA.java +++ b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/shell/TestOzoneShellHA.java @@ -1088,4 +1088,38 @@ public void testListVolumeBucketKeyShouldPrintValidJsonArray() testVolumes.forEach(vol -> execute(ozoneShell, new String[] { "volume", "delete", vol})); } + + @Test + public void testClientBucketLayoutValidation() { + String volName = "/vol-" + UUID.randomUUID(); + String[] args = + new String[]{"volume", "create", "o3://" + omServiceId + volName}; + execute(ozoneShell, args); + + args = new String[]{ + "bucket", "create", "o3://" + omServiceId + volName + "/buck-1", + "--layout", "" + }; + try { + execute(ozoneShell, args); + Assert.fail("Should throw exception on unsupported bucket layouts!"); + } catch (Exception e) { + GenericTestUtils.assertExceptionContains( + "expected one of [FILE_SYSTEM_OPTIMIZED, OBJECT_STORE, LEGACY] ", + e); + } + + args = new String[]{ + "bucket", "create", "o3://" + omServiceId + volName + "/buck-2", + "--layout", "INVALID" + }; + try { + execute(ozoneShell, args); + Assert.fail("Should throw exception on unsupported bucket layouts!"); + } catch (Exception e) { + GenericTestUtils.assertExceptionContains( + "expected one of [FILE_SYSTEM_OPTIMIZED, OBJECT_STORE, LEGACY] ", + e); + } + } } diff --git a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/bucket/CreateBucketHandler.java b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/bucket/CreateBucketHandler.java index 3423b5a4eb67..277c5afff217 100644 --- a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/bucket/CreateBucketHandler.java +++ b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/shell/bucket/CreateBucketHandler.java @@ -59,28 +59,10 @@ public class CreateBucketHandler extends BucketHandler { " user if not specified") private String ownerName; - enum AllowedBucketLayouts { - FILE_SYSTEM_OPTIMIZED("FILE_SYSTEM_OPTIMIZED"), - OBJECT_STORE("OBJECT_STORE"), - DEFAULT(""); - - // Assigning a value to each enum - private final String layout; - AllowedBucketLayouts(String layout) { - this.layout = layout; - } - - // Overriding toString() method to return the value passed to the - // constructor. - @Override - public String toString() { - return this.layout; - } - } + enum AllowedBucketLayouts { FILE_SYSTEM_OPTIMIZED, OBJECT_STORE, LEGACY } @Option(names = { "--layout", "-l" }, - description = "Allowed Bucket Layouts: ${COMPLETION-CANDIDATES}", - defaultValue = "") + description = "Allowed Bucket Layouts: ${COMPLETION-CANDIDATES}") private AllowedBucketLayouts allowedBucketLayout; @CommandLine.Mixin @@ -100,12 +82,14 @@ public void execute(OzoneClient client, OzoneAddress address) ownerName = UserGroupInformation.getCurrentUser().getShortUserName(); } - BucketArgs.Builder bb; - BucketLayout bucketLayout = - BucketLayout.fromString(allowedBucketLayout.toString()); - bb = new BucketArgs.Builder().setStorageType(StorageType.DEFAULT) - .setVersioning(false).setBucketLayout(bucketLayout) - .setOwner(ownerName); + BucketArgs.Builder bb = + new BucketArgs.Builder().setStorageType(StorageType.DEFAULT) + .setVersioning(false).setOwner(ownerName); + if (allowedBucketLayout != null) { + BucketLayout bucketLayout = + BucketLayout.fromString(allowedBucketLayout.toString()); + bb.setBucketLayout(bucketLayout); + } // TODO: New Client talking to old server, will it create a LEGACY bucket? if (isGdprEnforced != null) {