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..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 @@ -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, keyName, + 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(); 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); }