Skip to content

Commit

Permalink
unset x-amz-tagging-count header when object tagging is empty. (#96)
Browse files Browse the repository at this point in the history
  • Loading branch information
Robothy authored Jul 8, 2024
1 parent 5f649ed commit 589cf30
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 64 deletions.
2 changes: 1 addition & 1 deletion buildSrc/src/main/resources/version.properties
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ org.apache.commons.commons-lang3=3.12.0
org.junit.jupiter.junit-jupiter-engine=5.8.1
org.junit.jupiter.junit-jupiter=5.8.1
org.mockito.mockito-inline=4.2.0
org.projectlombok.lombok=1.18.24
org.projectlombok.lombok=1.18.30
org.slf4j.slf4j-api=1.7.36
org.testcontainers.testcontainers=1.17.5
org.testcontainers.junit-jupiter=1.17.5
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,11 @@
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.AmazonS3Exception;
import com.amazonaws.services.s3.model.BucketVersioningConfiguration;
import com.amazonaws.services.s3.model.CopyObjectRequest;
import com.amazonaws.services.s3.model.CopyObjectResult;
import com.amazonaws.services.s3.model.DeleteObjectTaggingRequest;
import com.amazonaws.services.s3.model.DeleteObjectsRequest;
import com.amazonaws.services.s3.model.DeleteObjectsResult;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.GetObjectTaggingRequest;
import com.amazonaws.services.s3.model.GetObjectTaggingResult;
import com.amazonaws.services.s3.model.ListObjectsRequest;
import com.amazonaws.services.s3.model.MultiObjectDeleteException;
import com.amazonaws.services.s3.model.ObjectListing;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.ObjectTagging;
import com.amazonaws.services.s3.model.PutObjectResult;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.services.s3.model.S3VersionSummary;
import com.amazonaws.services.s3.model.SetBucketVersioningConfigurationRequest;
import com.amazonaws.services.s3.model.SetObjectTaggingRequest;
import com.amazonaws.services.s3.model.SetObjectTaggingResult;
import com.amazonaws.services.s3.model.Tag;
import com.amazonaws.services.s3.model.VersionListing;
import com.amazonaws.services.s3.model.*;
import com.robothy.s3.jupiter.LocalS3;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
Expand Down Expand Up @@ -259,43 +239,6 @@ void testCopyObject(AmazonS3 s3) throws IOException {
assertEquals(text2, new String(object4.getObjectContent().readAllBytes()));
}

@LocalS3
@Test
void testObjectTagging(AmazonS3 s3) {
String bucketName = "my-bucket";
String key = "key1";

s3.createBucket(bucketName);
s3.putObject(bucketName, key, "Hello");

assertDoesNotThrow(() -> s3.getObjectTagging(new GetObjectTaggingRequest(bucketName, key)));
SetObjectTaggingResult setObjectTaggingResult = s3.setObjectTagging(
new SetObjectTaggingRequest(bucketName, key, new ObjectTagging(List.of(new Tag("K1", "V1"), new Tag("K2", "V2")))));
assertEquals("null", setObjectTaggingResult.getVersionId());

GetObjectTaggingResult objectTagging1 = s3.getObjectTagging(new GetObjectTaggingRequest(bucketName, key));
assertEquals(2, objectTagging1.getTagSet().size());
Tag tag1 = objectTagging1.getTagSet().get(0);
Tag tag2 = objectTagging1.getTagSet().get(1);
assertEquals("K1", tag1.getKey());
assertEquals("V1", tag1.getValue());
assertEquals("K2", tag2.getKey());
assertEquals("V2", tag2.getValue());

s3.setBucketVersioningConfiguration(new SetBucketVersioningConfigurationRequest(bucketName,
new BucketVersioningConfiguration(BucketVersioningConfiguration.ENABLED)));

PutObjectResult putObjectResult1 = s3.putObject(bucketName, key, "World");
assertDoesNotThrow(() -> s3.getObjectTagging(new GetObjectTaggingRequest(bucketName, key)));

SetObjectTaggingResult setObjectTaggingResult1 = s3.setObjectTagging(
new SetObjectTaggingRequest(bucketName, key, putObjectResult1.getVersionId(),
new ObjectTagging(List.of(new Tag("K3", "V3")))));
assertEquals(putObjectResult1.getVersionId(), setObjectTaggingResult1.getVersionId());

assertDoesNotThrow(() -> s3.deleteObjectTagging(new DeleteObjectTaggingRequest(bucketName, key)));
}

@LocalS3
@Test
void testDeleteObjects(AmazonS3 s3) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package com.robothy.s3.test;

import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.*;
import com.robothy.s3.jupiter.LocalS3;
import org.junit.jupiter.api.Test;

import java.io.ByteArrayInputStream;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

public class ObjectTaggingIntegrationTest {

@LocalS3
@Test
void testPutObjectTagging(AmazonS3 s3) {
String bucketName = "my-bucket";
String key = "key1";

s3.createBucket(bucketName);
s3.putObject(bucketName, key, "Hello");

assertDoesNotThrow(() -> s3.getObjectTagging(new GetObjectTaggingRequest(bucketName, key)));
SetObjectTaggingResult setObjectTaggingResult = s3.setObjectTagging(
new SetObjectTaggingRequest(bucketName, key, new ObjectTagging(List.of(new Tag("K1", "V1"), new Tag("K2", "V2")))));
assertEquals("null", setObjectTaggingResult.getVersionId());

GetObjectTaggingResult objectTagging1 = s3.getObjectTagging(new GetObjectTaggingRequest(bucketName, key));
assertEquals(2, objectTagging1.getTagSet().size());
Tag tag1 = objectTagging1.getTagSet().get(0);
Tag tag2 = objectTagging1.getTagSet().get(1);
assertEquals("K1", tag1.getKey());
assertEquals("V1", tag1.getValue());
assertEquals("K2", tag2.getKey());
assertEquals("V2", tag2.getValue());

s3.setBucketVersioningConfiguration(new SetBucketVersioningConfigurationRequest(bucketName,
new BucketVersioningConfiguration(BucketVersioningConfiguration.ENABLED)));

PutObjectResult putObjectResult1 = s3.putObject(bucketName, key, "World");
assertDoesNotThrow(() -> s3.getObjectTagging(new GetObjectTaggingRequest(bucketName, key)));

SetObjectTaggingResult setObjectTaggingResult1 = s3.setObjectTagging(
new SetObjectTaggingRequest(bucketName, key, putObjectResult1.getVersionId(),
new ObjectTagging(List.of(new Tag("K3", "V3")))));
assertEquals(putObjectResult1.getVersionId(), setObjectTaggingResult1.getVersionId());

assertDoesNotThrow(() -> s3.deleteObjectTagging(new DeleteObjectTaggingRequest(bucketName, key)));
}

@LocalS3
@Test
void testPutObjectWithTagging(AmazonS3 s3) throws Exception {

String bucketName = "my-bucket";
s3.createBucket(bucketName);
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, "key1", new ByteArrayInputStream("Hello".getBytes()), new ObjectMetadata())
.withTagging(new ObjectTagging(List.of(new Tag("K1", "V1"), new Tag("K2", "V2"))));
s3.putObject(putObjectRequest);

S3Object s3Object = s3.getObject(bucketName, "key1");
assertEquals(2, s3Object.getTaggingCount());

GetObjectTaggingResult key1Tags = s3.getObjectTagging(new GetObjectTaggingRequest(bucketName, "key1"));
assertEquals(2, key1Tags.getTagSet().size());
assertEquals("K1", key1Tags.getTagSet().get(0).getKey());
assertEquals("V1", key1Tags.getTagSet().get(0).getValue());
assertEquals("K2", key1Tags.getTagSet().get(1).getKey());
assertEquals("V2", key1Tags.getTagSet().get(1).getValue());
}

@LocalS3
@Test
void testPutObjectWithoutTagging(AmazonS3 s3) {
String bucketName = "my-bucket";
s3.createBucket(bucketName);
s3.putObject(bucketName, "key1", "Hello");
GetObjectTaggingResult objectTagging = s3.getObjectTagging(new GetObjectTaggingRequest(bucketName, "key1"));
assertEquals(0, objectTagging.getTagSet().size());

S3Object object = s3.getObject(bucketName, "key1");
assertNull(object.getTaggingCount());
}

@LocalS3
@Test
void testDeleteObjectTagging(AmazonS3 s3) {
String bucketName = "my-bucket";
String key = "key1";

s3.createBucket(bucketName);
s3.putObject(bucketName, key, "Hello");
s3.setObjectTagging(new SetObjectTaggingRequest(bucketName, key, new ObjectTagging(List.of(new Tag("K1", "V1")))));

GetObjectTaggingResult objectTagging = s3.getObjectTagging(new GetObjectTaggingRequest(bucketName, key));
assertEquals(1, objectTagging.getTagSet().size());

DeleteObjectTaggingResult deleteObjectTaggingResult = s3.deleteObjectTagging(new DeleteObjectTaggingRequest(bucketName, key));
assertNull(deleteObjectTaggingResult.getVersionId());

objectTagging = s3.getObjectTagging(new GetObjectTaggingRequest(bucketName, key));
assertEquals(0, objectTagging.getTagSet().size());

S3Object object = s3.getObject(bucketName, key);
assertNull(object.getTaggingCount());


s3.setBucketVersioningConfiguration(new SetBucketVersioningConfigurationRequest(bucketName, new BucketVersioningConfiguration(BucketVersioningConfiguration.ENABLED)));
PutObjectResult putObjectResult = s3.putObject(bucketName, key, "World");
s3.setObjectTagging(new SetObjectTaggingRequest(bucketName, key, putObjectResult.getVersionId(), new ObjectTagging(List.of(new Tag("K1", "V1")))));
s3.deleteObjectTagging(new DeleteObjectTaggingRequest(bucketName, key).withVersionId(putObjectResult.getVersionId()));
objectTagging = s3.getObjectTagging(new GetObjectTaggingRequest(bucketName, key));
assertEquals(0, objectTagging.getTagSet().size());
assertEquals(putObjectResult.getVersionId(), objectTagging.getVersionId());

S3Object object1 = s3.getObject(bucketName, key);
assertNull(object1.getTaggingCount());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import com.robothy.s3.jupiter.LocalS3;
import java.nio.file.Files;
import java.nio.file.Path;
import org.junit.jupiter.api.Assertions;

import org.junit.jupiter.api.Test;

public class TransferManagerIntegrationTest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,13 @@ public void handle(HttpRequest request, HttpResponse response) throws Exception
ResponseUtils.addETag(response, getObjectAns.getEtag());
response.status(HttpResponseStatus.OK)
.write(content)
.putHeader(AmzHeaderNames.X_AMZ_TAGGING_COUNT, getObjectAns.getTaggingCount())
.putHeader(HttpHeaderNames.CONTENT_TYPE.toString(), getObjectAns.getContentType())
.putHeader(HttpHeaderNames.CONTENT_LENGTH.toString(), getObjectAns.getSize());

if (0 != getObjectAns.getTaggingCount()) {
response.putHeader(AmzHeaderNames.X_AMZ_TAGGING_COUNT, getObjectAns.getTaggingCount());
}

getObjectAns.getUserMetadata().forEach((k, v) -> response.putHeader(AmzHeaderNames.X_AMZ_META_PREFIX + k, v));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
import com.robothy.s3.rest.utils.ResponseUtils;
import io.netty.handler.codec.http.HttpResponseStatus;

import java.util.Objects;

class ObjectTaggingController {

private final ObjectTaggingService objectTaggingService;
Expand Down Expand Up @@ -55,9 +57,12 @@ void delete(HttpRequest request, HttpResponse response) throws Exception {
String key = RequestAssertions.assertObjectKeyProvided(request);
String versionId = request.parameter("versionId").orElse(null);
objectTaggingService.deleteObjectTagging(bucketName, key, versionId);
if (Objects.nonNull(versionId)) {
response.putHeader(AmzHeaderNames.X_AMZ_VERSION_ID, versionId);
}

ResponseUtils.addCommonHeaders(response)
.status(HttpResponseStatus.NO_CONTENT);
.status(HttpResponseStatus.NO_CONTENT);
}

}

0 comments on commit 589cf30

Please sign in to comment.