diff --git a/hadoop-ozone/dist/src/main/smoketest/s3/bucketlifecycle.robot b/hadoop-ozone/dist/src/main/smoketest/s3/bucketlifecycle.robot index c82e066dab5..02e9f1fd22c 100644 --- a/hadoop-ozone/dist/src/main/smoketest/s3/bucketlifecycle.robot +++ b/hadoop-ozone/dist/src/main/smoketest/s3/bucketlifecycle.robot @@ -55,3 +55,9 @@ Delete bucket lifecycle configuration Should Be Empty ${result} ${result} = Execute AWSS3APICli and checkrc get-bucket-lifecycle-configuration --bucket ${bucket} 255 Should contain ${result} NoSuchLifecycleConfiguration + +Delete bucket lifecycle configuration when none exists + [tags] no-bucket-type + ${bucket} = Create bucket + ${result} = Execute AWSS3APICli delete-bucket-lifecycle --bucket ${bucket} + Should Be Empty ${result} diff --git a/hadoop-ozone/integration-test-s3/src/test/java/org/apache/hadoop/ozone/s3/awssdk/v1/AbstractS3SDKV1Tests.java b/hadoop-ozone/integration-test-s3/src/test/java/org/apache/hadoop/ozone/s3/awssdk/v1/AbstractS3SDKV1Tests.java index fc634a44f78..839c81f152a 100644 --- a/hadoop-ozone/integration-test-s3/src/test/java/org/apache/hadoop/ozone/s3/awssdk/v1/AbstractS3SDKV1Tests.java +++ b/hadoop-ozone/integration-test-s3/src/test/java/org/apache/hadoop/ozone/s3/awssdk/v1/AbstractS3SDKV1Tests.java @@ -2156,8 +2156,8 @@ public void testS3LifecycleConfigurationDelete() { // Test delete lifecycle for a bucket, while doesn't have lifecycle assertNull(s3Client.getBucketLifecycleConfiguration(bucketName)); - assertThrows(AmazonServiceException.class, - () -> s3Client.deleteBucketLifecycleConfiguration(bucketName)); + // Idempotent delete: no exception expected even without an existing config + s3Client.deleteBucketLifecycleConfiguration(bucketName); // First create a lifecycle configuration BucketLifecycleConfiguration configuration = new BucketLifecycleConfiguration(); diff --git a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/BucketCrudHandler.java b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/BucketCrudHandler.java index 23c4da2cfa2..6b716993ef0 100644 --- a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/BucketCrudHandler.java +++ b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/BucketCrudHandler.java @@ -156,11 +156,11 @@ protected void deleteLifecycleConfiguration(S3RequestContext context, String buc try { context.getVolume().getBucket(bucketName).deleteLifecycleConfiguration(); } catch (OMException ex) { - if (ex.getResult() == OMException.ResultCodes.LIFECYCLE_CONFIGURATION_NOT_FOUND) { - throw S3ErrorTable.newError( - S3ErrorTable.NO_SUCH_LIFECYCLE_CONFIGURATION, bucketName); + // DeleteBucketLifecycle is idempotent: deleting a missing config + // must still return 204, not 404 — same as normal key deletion. + if (ex.getResult() != OMException.ResultCodes.LIFECYCLE_CONFIGURATION_NOT_FOUND) { + throw S3ErrorTable.newError(bucketName, ex); } - throw ex; } } diff --git a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestS3LifecycleConfigurationDelete.java b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestS3LifecycleConfigurationDelete.java index 5022320fb22..5080f192b9c 100644 --- a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestS3LifecycleConfigurationDelete.java +++ b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestS3LifecycleConfigurationDelete.java @@ -55,14 +55,10 @@ public void setup() throws Exception { @Test public void testDeleteNonExistentLifecycleConfiguration() throws Exception { - try { - bucketEndpoint.delete("bucket1"); - fail(); - } catch (OS3Exception ex) { - assertEquals(HTTP_NOT_FOUND, ex.getHttpCode()); - assertEquals(NO_SUCH_LIFECYCLE_CONFIGURATION.getCode(), - ex.getCode()); - } + // DeleteBucketLifecycle is idempotent: deleting a non-existent + // configuration must succeed with 204, not fail with 404. + Response r = bucketEndpoint.delete("bucket1"); + assertEquals(HTTP_NO_CONTENT, r.getStatus()); } @Test