From 3f90948ce11101d76f3f75b058d7ebbd20d099c7 Mon Sep 17 00:00:00 2001 From: Symious Date: Fri, 14 Feb 2025 23:03:52 +0800 Subject: [PATCH 1/3] HDDS-12329. Specify S3 error for Quota Exceeded --- .../org/apache/hadoop/ozone/s3/endpoint/ObjectEndpoint.java | 2 ++ .../org/apache/hadoop/ozone/s3/exception/S3ErrorTable.java | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/ObjectEndpoint.java b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/ObjectEndpoint.java index 9311fb7fa4b5..bf9bb6db8176 100644 --- a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/ObjectEndpoint.java +++ b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/ObjectEndpoint.java @@ -366,6 +366,8 @@ public Response put( throw os3Exception; } else if (isAccessDenied(ex)) { throw newError(S3ErrorTable.ACCESS_DENIED, keyPath, ex); + } else if (ex.getResult() == ResultCodes.QUOTA_EXCEEDED) { + throw newError(S3ErrorTable.QUOTA_EXCEEDED, keyPath, ex); } else if (ex.getResult() == ResultCodes.BUCKET_NOT_FOUND) { throw newError(S3ErrorTable.NO_SUCH_BUCKET, bucketName, ex); } else if (ex.getResult() == ResultCodes.FILE_ALREADY_EXISTS) { diff --git a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/exception/S3ErrorTable.java b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/exception/S3ErrorTable.java index 49761f89a3a8..5913a41676bd 100644 --- a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/exception/S3ErrorTable.java +++ b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/exception/S3ErrorTable.java @@ -149,6 +149,12 @@ private S3ErrorTable() { "MalformedXML", "The XML you provided was not well-formed or did not " + "validate against our published schema", HTTP_BAD_REQUEST); + public static final OS3Exception QUOTA_EXCEEDED = new OS3Exception( + "QuotaExceeded", "The quota has been exceeded. " + + "Please review your disk space or namespace usage and adjust accordingly.", + HTTP_FORBIDDEN + ); + public static OS3Exception newError(OS3Exception e, String resource) { return newError(e, resource, null); } From 35eebf028f84b58b3e4856dc02f7e671eb5c83b9 Mon Sep 17 00:00:00 2001 From: Symious Date: Mon, 17 Feb 2025 10:40:17 +0800 Subject: [PATCH 2/3] HDDS-12329. Add unit test --- .../s3/awssdk/v1/AbstractS3SDKV1Tests.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/s3/awssdk/v1/AbstractS3SDKV1Tests.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/s3/awssdk/v1/AbstractS3SDKV1Tests.java index 661afaf07723..f33d699c1e83 100644 --- a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/s3/awssdk/v1/AbstractS3SDKV1Tests.java +++ b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/s3/awssdk/v1/AbstractS3SDKV1Tests.java @@ -60,6 +60,7 @@ import com.amazonaws.services.s3.transfer.Upload; import com.amazonaws.services.s3.transfer.model.UploadResult; import org.apache.commons.lang3.RandomStringUtils; +import org.apache.hadoop.hdds.client.OzoneQuota; import org.apache.hadoop.hdds.client.ReplicationConfig; import org.apache.hadoop.hdds.client.ReplicationFactor; import org.apache.hadoop.hdds.client.ReplicationType; @@ -814,6 +815,28 @@ public void testListPartsNotFound() { assertEquals("NoSuchUpload", ase.getErrorCode()); } + @Test + public void testQuotaExceeded() throws IOException { + final String bucketName = getBucketName(); + final String keyName = getKeyName(); + + s3Client.createBucket(bucketName); + + cluster.newClient().getObjectStore() + .getVolume("s3v") + .getBucket(bucketName) + .setQuota(OzoneQuota.parseQuota("1", "10")); + + // Upload some objects to the bucket + AmazonServiceException ase = assertThrows(AmazonServiceException.class, + () -> s3Client.putObject(bucketName, "key", + RandomStringUtils.randomAlphanumeric(1024))); + + assertEquals(ErrorType.Client, ase.getErrorType()); + assertEquals(403, ase.getStatusCode()); + assertEquals("QuotaExceeded", ase.getErrorCode()); + } + private boolean isBucketEmpty(Bucket bucket) { ObjectListing objectListing = s3Client.listObjects(bucket.getName()); return objectListing.getObjectSummaries().isEmpty(); From 360c1e6eea6ea7ee28be556403a8cf99ad07ce6d Mon Sep 17 00:00:00 2001 From: Symious Date: Mon, 17 Feb 2025 11:05:26 +0800 Subject: [PATCH 3/3] HDDS-12329. Fix findbugs --- .../apache/hadoop/ozone/s3/awssdk/v1/AbstractS3SDKV1Tests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/s3/awssdk/v1/AbstractS3SDKV1Tests.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/s3/awssdk/v1/AbstractS3SDKV1Tests.java index f33d699c1e83..44785bd97f05 100644 --- a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/s3/awssdk/v1/AbstractS3SDKV1Tests.java +++ b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/s3/awssdk/v1/AbstractS3SDKV1Tests.java @@ -829,7 +829,7 @@ public void testQuotaExceeded() throws IOException { // Upload some objects to the bucket AmazonServiceException ase = assertThrows(AmazonServiceException.class, - () -> s3Client.putObject(bucketName, "key", + () -> s3Client.putObject(bucketName, keyName, RandomStringUtils.randomAlphanumeric(1024))); assertEquals(ErrorType.Client, ase.getErrorType());