Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ protected MultipartUpload doInitiateMultipartUpload(final MultipartUploadRequest
.key(createMultipartUploadResponse.key())
.id(createMultipartUploadResponse.uploadId())
.metadata(request.getMetadata())
.tags(request.getTags())
.kmsKeyId(request.getKmsKeyId())
.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,13 @@ public CreateMultipartUploadRequest toCreateMultipartUploadRequest(MultipartUplo
.key(request.getKey())
.metadata(request.getMetadata());

if (request.getTags() != null && !request.getTags().isEmpty()) {
List<Tag> tags = request.getTags().entrySet().stream()
.map(entry -> Tag.builder().key(entry.getKey()).value(entry.getValue()).build())
.collect(Collectors.toList());
builder.tagging(Tagging.builder().tagSet(tags).build());
}

if (request.getKmsKeyId() != null && !request.getKmsKeyId().isEmpty()) {
builder.serverSideEncryption(ServerSideEncryption.AWS_KMS)
.ssekmsKeyId(request.getKmsKeyId());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ protected CompletableFuture<MultipartUpload> doInitiateMultipartUpload(Multipart
.key(response.key())
.id(response.uploadId())
.metadata(request.getMetadata())
.tags(request.getTags())
.build());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,41 @@ void testDoInitiateMultipartUploadWithKms() {
assertEquals(kmsKeyId, response.getKmsKeyId());
}

@Test
void testDoInitiateMultipartUploadWithTags() {
CreateMultipartUploadResponse mockResponse = mock(CreateMultipartUploadResponse.class);
doReturn("bucket-1").when(mockResponse).bucket();
doReturn("object-1").when(mockResponse).key();
doReturn("mpu-id").when(mockResponse).uploadId();
when(mockS3Client.createMultipartUpload((CreateMultipartUploadRequest) any())).thenReturn(mockResponse);
Map<String, String> metadata = Map.of("key-1", "value-1");
Map<String, String> tags = Map.of("tag-1", "tag-value-1", "tag-2", "tag-value-2");
MultipartUploadRequest request = new MultipartUploadRequest.Builder()
.withKey("object-1")
.withMetadata(metadata)
.withTags(tags)
.build();

MultipartUpload response = aws.initiateMultipartUpload(request);

// Verify the request is mapped to the SDK with tags
ArgumentCaptor<CreateMultipartUploadRequest> requestCaptor = ArgumentCaptor.forClass(CreateMultipartUploadRequest.class);
verify(mockS3Client, times(1)).createMultipartUpload(requestCaptor.capture());
CreateMultipartUploadRequest actualRequest = requestCaptor.getValue();
assertEquals("object-1", actualRequest.key());
assertEquals("bucket-1", actualRequest.bucket());
assertEquals(metadata, actualRequest.metadata());
// Verify tagging header is set (tagging() returns String in AWS SDK)
assertNotNull(actualRequest.tagging());
assertFalse(actualRequest.tagging().isEmpty());

// Verify the response is mapped back properly with tags
assertEquals("object-1", response.getKey());
assertEquals("bucket-1", response.getBucket());
assertEquals("mpu-id", response.getId());
assertEquals(tags, response.getTags());
}

@Test
void testDoUploadMultipartPart() {
UploadPartResponse mockResponse = mock(UploadPartResponse.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,24 @@ void testToCreateMultipartUploadRequest() {
assertEquals(metadata, request.metadata());
}

@Test
void testToCreateMultipartUploadRequestWithTags() {
Map<String, String> metadata = Map.of("key1", "value1", "key2", "value2");
Map<String, String> tags = Map.of("tag1", "value1", "tag2", "value2");
MultipartUploadRequest mpuRequest = new MultipartUploadRequest.Builder()
.withKey("object-1")
.withMetadata(metadata)
.withTags(tags)
.build();
CreateMultipartUploadRequest request = transformer.toCreateMultipartUploadRequest(mpuRequest);
assertEquals("object-1", request.key());
assertEquals(BUCKET, request.bucket());
assertEquals(metadata, request.metadata());
// Verify tagging header is set (tagging() returns String in AWS SDK)
assertNotNull(request.tagging());
assertFalse(request.tagging().isEmpty());
}

@Test
void testToUploadPartRequest() {
Map<String, String> metadata = Map.of("key1", "value1", "key2", "value2");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -866,6 +866,41 @@ void testDoInitiateMultipartUpload() throws ExecutionException, InterruptedExcep
assertEquals(metadata, response.getMetadata());
}

@Test
void testDoInitiateMultipartUploadWithTags() throws ExecutionException, InterruptedException {
CreateMultipartUploadResponse mockResponse = mock(CreateMultipartUploadResponse.class);
doReturn("bucket-1").when(mockResponse).bucket();
doReturn("object-1").when(mockResponse).key();
doReturn("mpu-id").when(mockResponse).uploadId();
doReturn(future(mockResponse)).when(mockS3Client).createMultipartUpload((CreateMultipartUploadRequest) any());
Map<String, String> metadata = Map.of("key-1", "value-1");
Map<String, String> tags = Map.of("tag-1", "tag-value-1", "tag-2", "tag-value-2");
MultipartUploadRequest request = new MultipartUploadRequest.Builder()
.withKey("object-1")
.withMetadata(metadata)
.withTags(tags)
.build();

MultipartUpload response = aws.initiateMultipartUpload(request).get();

// Verify the request is mapped to the SDK with tags
ArgumentCaptor<CreateMultipartUploadRequest> requestCaptor = ArgumentCaptor.forClass(CreateMultipartUploadRequest.class);
verify(mockS3Client, times(1)).createMultipartUpload(requestCaptor.capture());
CreateMultipartUploadRequest actualRequest = requestCaptor.getValue();
assertEquals("object-1", actualRequest.key());
assertEquals("bucket-1", actualRequest.bucket());
assertEquals(metadata, actualRequest.metadata());
// Verify tagging header is set (tagging() returns String in AWS SDK)
assertNotNull(actualRequest.tagging());
assertFalse(actualRequest.tagging().isEmpty());

// Verify the response is mapped back properly with tags
assertEquals("object-1", response.getKey());
assertEquals("bucket-1", response.getBucket());
assertEquals("mpu-id", response.getId());
assertEquals(tags, response.getTags());
}

@Test
void testDoUploadMultipartPart() throws ExecutionException, InterruptedException {
UploadPartResponse mockResponse = mock(UploadPartResponse.class);
Expand Down
20 changes: 20 additions & 0 deletions blob/blob-aws/src/test/resources/mappings/delete-6toelc0tmn.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"id" : "497327cb-e6c0-46e4-9abb-6a4a91f2ba99",
"name" : "chameleon-jcloud_conformance-tests_multipart-withtags",
"request" : {
"url" : "/chameleon-jcloud/conformance-tests/multipart-withTags",
"method" : "DELETE"
},
"response" : {
"status" : 204,
"headers" : {
"Server" : "AmazonS3",
"x-amz-request-id" : "A8PHN0N3QMRKK5WV",
"x-amz-id-2" : "/D6voNhR/pf8jgzLGxaBGIVC7qGFKjy4S/kfpLMNIjBNO0N9tVnj3+d0l+3Os9NzGmDFF0REqr8=",
"Date" : "Wed, 26 Nov 2025 06:07:05 GMT"
}
},
"uuid" : "497327cb-e6c0-46e4-9abb-6a4a91f2ba99",
"persistent" : true,
"insertionIndex" : 572
}
20 changes: 20 additions & 0 deletions blob/blob-aws/src/test/resources/mappings/delete-jmtgmhaiu0.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"id" : "680f68cb-7950-4bf7-afc9-73e35faf3945",
"name" : "chameleon-jcloud_conformance-tests_multipart-withtags",
"request" : {
"url" : "/chameleon-jcloud/conformance-tests/multipart-withTags?uploadId=HDOoXyIE1BO4feFEYcL3Lau7OMvXmhnu.OK5sLEOZyNnMGgBH1xE19f9gL22M2lG5KF2.Ouf6LVM6WS0oUqPwSwYj4EIz3FsP4ZE9O_k_LTQO4tbf8eV6fgoiXY4Z1IJglocI1LPy7BISMs.I8MX5KP5QsazuVTPxvCmbmvlTKT7riX3BYZQeu0H9bFN8xW9",
"method" : "DELETE"
},
"response" : {
"status" : 204,
"headers" : {
"Server" : "AmazonS3",
"x-amz-request-id" : "0QNG1ZBYKXTK3RXV",
"x-amz-id-2" : "qjsLnL7oZfG2rddrzlP12lg6XBecof/FNKgAo7imRai2245tUq45US9UoZZIWfS/Jk8BSv+sT3Q=",
"Date" : "Wed, 26 Nov 2025 06:07:06 GMT"
}
},
"uuid" : "680f68cb-7950-4bf7-afc9-73e35faf3945",
"persistent" : true,
"insertionIndex" : 571
}
21 changes: 21 additions & 0 deletions blob/blob-aws/src/test/resources/mappings/get-5mgtesclbh.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"id" : "64c9b07b-9ccb-46f7-8d0e-435e9f8d41a1",
"name" : "chameleon-jcloud_conformance-tests_multipart-withtags",
"request" : {
"url" : "/chameleon-jcloud/conformance-tests/multipart-withTags?tagging",
"method" : "GET"
},
"response" : {
"status" : 200,
"base64Body" : "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPFRhZ2dpbmcgeG1sbnM9Imh0dHA6Ly9zMy5hbWF6b25hd3MuY29tL2RvYy8yMDA2LTAzLTAxLyI+PFRhZ1NldD48VGFnPjxLZXk+dGFnMTwvS2V5PjxWYWx1ZT52YWx1ZTE8L1ZhbHVlPjwvVGFnPjxUYWc+PEtleT50YWcyPC9LZXk+PFZhbHVlPnZhbHVlMjwvVmFsdWU+PC9UYWc+PC9UYWdTZXQ+PC9UYWdnaW5nPg==",
"headers" : {
"Server" : "AmazonS3",
"x-amz-request-id" : "A8PTYAHQCC64837G",
"x-amz-id-2" : "IEmxvMHvTPHb1kJGZuNqf67quVJHUO33+nsEhfmzkhhehzV72AwHwPFZXgRg/S0Bi/6pt5mtIrs=",
"Date" : "Wed, 26 Nov 2025 06:07:05 GMT"
}
},
"uuid" : "64c9b07b-9ccb-46f7-8d0e-435e9f8d41a1",
"persistent" : true,
"insertionIndex" : 573
}
22 changes: 22 additions & 0 deletions blob/blob-aws/src/test/resources/mappings/get-nvkpw2yli7.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"id" : "0aebf9df-6c06-4ba1-b3b5-eb98952d9d4a",
"name" : "chameleon-jcloud_conformance-tests_multipart-withtags",
"request" : {
"url" : "/chameleon-jcloud/conformance-tests/multipart-withTags?uploadId=HDOoXyIE1BO4feFEYcL3Lau7OMvXmhnu.OK5sLEOZyNnMGgBH1xE19f9gL22M2lG5KF2.Ouf6LVM6WS0oUqPwSwYj4EIz3FsP4ZE9O_k_LTQO4tbf8eV6fgoiXY4Z1IJglocI1LPy7BISMs.I8MX5KP5QsazuVTPxvCmbmvlTKT7riX3BYZQeu0H9bFN8xW9",
"method" : "GET"
},
"response" : {
"status" : 200,
"body" : "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ListPartsResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"><Bucket>chameleon-jcloud</Bucket><Key>conformance-tests/multipart-withTags</Key><UploadId>HDOoXyIE1BO4feFEYcL3Lau7OMvXmhnu.OK5sLEOZyNnMGgBH1xE19f9gL22M2lG5KF2.Ouf6LVM6WS0oUqPwSwYj4EIz3FsP4ZE9O_k_LTQO4tbf8eV6fgoiXY4Z1IJglocI1LPy7BISMs.I8MX5KP5QsazuVTPxvCmbmvlTKT7riX3BYZQeu0H9bFN8xW9</UploadId><Initiator><ID>arn:aws:sts::654654370895:assumed-role/PCSKAdministratorAccessRole/PCSK-barry.liu@d991383f-2686-4df5-8465-9027dc410bfd</ID><DisplayName>PCSKAdministratorAccessRole/PCSK-barry.liu@d991383f-2686-4df5-8465-9027dc410bfd</DisplayName></Initiator><Owner><ID>b6eaab2af32ba61bce00b8c9aceaa1c649844388ec2c3827bbd3e2b06f798cf1</ID></Owner><StorageClass>STANDARD</StorageClass><PartNumberMarker>0</PartNumberMarker><NextPartNumberMarker>2</NextPartNumberMarker><MaxParts>1000</MaxParts><IsTruncated>false</IsTruncated><Part><PartNumber>1</PartNumber><LastModified>2025-11-26T06:06:58.000Z</LastModified><ETag>&quot;2b5c91ad399409ec9b409b66f5bb00fb&quot;</ETag><Size>5242880</Size></Part><Part><PartNumber>2</PartNumber><LastModified>2025-11-26T06:06:59.000Z</LastModified><ETag>&quot;267c038cc2ec32ffd0ee2512ff5da5a5&quot;</ETag><Size>5242880</Size></Part></ListPartsResult>",
"headers" : {
"Server" : "AmazonS3",
"x-amz-request-id" : "0RC82VMFVZK08MFT",
"x-amz-id-2" : "WcbLM/bTdmysu94c6uvDi55TfKHuN8vdnGsKSUiddurOBh3SK5Gf7xG5kMFAOBAG2V6wWMZuCTY=",
"Date" : "Wed, 26 Nov 2025 06:07:03 GMT",
"Content-Type" : "application/xml"
}
},
"uuid" : "0aebf9df-6c06-4ba1-b3b5-eb98952d9d4a",
"persistent" : true,
"insertionIndex" : 576
}
27 changes: 27 additions & 0 deletions blob/blob-aws/src/test/resources/mappings/head-jrqn0thyrr.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"id" : "8fe857df-1652-4e04-b158-5669e6e94ea0",
"name" : "chameleon-jcloud_conformance-tests_multipart-withtags",
"request" : {
"url" : "/chameleon-jcloud/conformance-tests/multipart-withTags",
"method" : "HEAD"
},
"response" : {
"status" : 200,
"headers" : {
"Accept-Ranges" : "bytes",
"x-amz-meta-key1" : "value1",
"Server" : "AmazonS3",
"ETag" : "\"63a814bc1f352d8149b1dd9f3747e89e-2\"",
"Last-Modified" : "Wed, 26 Nov 2025 06:06:57 GMT",
"x-amz-request-id" : "WZSVMPPE0W0BHTVV",
"x-amz-server-side-encryption" : "AES256",
"x-amz-id-2" : "i55klOETtel+AEcWwtmY39lsP8BhNZLjVWpO+VGoroB2hbTThH7AAV36IDu/0wrDWF8SosZAo/4=",
"x-amz-tagging-count" : "2",
"Date" : "Wed, 26 Nov 2025 06:07:04 GMT",
"Content-Type" : "binary/octet-stream"
}
},
"uuid" : "8fe857df-1652-4e04-b158-5669e6e94ea0",
"persistent" : true,
"insertionIndex" : 574
}
22 changes: 22 additions & 0 deletions blob/blob-aws/src/test/resources/mappings/post-pckdj0ogrh.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"id" : "f1231c98-37ac-460f-8948-e24623ef4069",
"name" : "chameleon-jcloud_conformance-tests_multipart-withtags",
"request" : {
"url" : "/chameleon-jcloud/conformance-tests/multipart-withTags?uploads",
"method" : "POST"
},
"response" : {
"status" : 200,
"base64Body" : "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEluaXRpYXRlTXVsdGlwYXJ0VXBsb2FkUmVzdWx0IHhtbG5zPSJodHRwOi8vczMuYW1hem9uYXdzLmNvbS9kb2MvMjAwNi0wMy0wMS8iPjxCdWNrZXQ+Y2hhbWVsZW9uLWpjbG91ZDwvQnVja2V0PjxLZXk+Y29uZm9ybWFuY2UtdGVzdHMvbXVsdGlwYXJ0LXdpdGhUYWdzPC9LZXk+PFVwbG9hZElkPkhET29YeUlFMUJPNGZlRkVZY0wzTGF1N09NdlhtaG51Lk9LNXNMRU9aeU5uTUdnQkgxeEUxOWY5Z0wyMk0ybEc1S0YyLk91ZjZMVk02V1Mwb1VxUHdTd1lqNEVJejNGc1A0WkU5T19rX0xUUU80dGJmOGVWNmZnb2lYWTRaMUlKZ2xvY0kxTFB5N0JJU01zLkk4TVg1S1A1UXNhenVWVFB4dkNtYm12bFRLVDdyaVgzQllaUWV1MEg5YkZOOHhXOTwvVXBsb2FkSWQ+PC9Jbml0aWF0ZU11bHRpcGFydFVwbG9hZFJlc3VsdD4=",
"headers" : {
"Server" : "AmazonS3",
"x-amz-request-id" : "6Y5C4Q6876WQ5JTK",
"x-amz-server-side-encryption" : "AES256",
"x-amz-id-2" : "X3V7sdKdFF436FPFj2erk8O9+LmCsFAhqfNwFC3nkp299Jfu925S9JvorS82DGJEQHqagGuul5c=",
"Date" : "Wed, 26 Nov 2025 06:06:57 GMT"
}
},
"uuid" : "f1231c98-37ac-460f-8948-e24623ef4069",
"persistent" : true,
"insertionIndex" : 579
}
26 changes: 26 additions & 0 deletions blob/blob-aws/src/test/resources/mappings/post-s5fewyoabb.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"id" : "6626ed6c-29bf-4b76-8db9-891bc89bdcbf",
"name" : "chameleon-jcloud_conformance-tests_multipart-withtags",
"request" : {
"url" : "/chameleon-jcloud/conformance-tests/multipart-withTags?uploadId=HDOoXyIE1BO4feFEYcL3Lau7OMvXmhnu.OK5sLEOZyNnMGgBH1xE19f9gL22M2lG5KF2.Ouf6LVM6WS0oUqPwSwYj4EIz3FsP4ZE9O_k_LTQO4tbf8eV6fgoiXY4Z1IJglocI1LPy7BISMs.I8MX5KP5QsazuVTPxvCmbmvlTKT7riX3BYZQeu0H9bFN8xW9",
"method" : "POST",
"bodyPatterns" : [ {
"equalToXml" : "<?xml version=\"1.0\" encoding=\"UTF-8\"?><CompleteMultipartUpload xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"><Part><ETag>&quot;2b5c91ad399409ec9b409b66f5bb00fb&quot;</ETag><PartNumber>1</PartNumber></Part><Part><ETag>&quot;267c038cc2ec32ffd0ee2512ff5da5a5&quot;</ETag><PartNumber>2</PartNumber></Part></CompleteMultipartUpload>"
} ]
},
"response" : {
"status" : 200,
"body" : "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<CompleteMultipartUploadResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"><Location>https://s3.us-west-2.amazonaws.com/chameleon-jcloud/conformance-tests%2Fmultipart-withTags</Location><Bucket>chameleon-jcloud</Bucket><Key>conformance-tests/multipart-withTags</Key><ETag>\"63a814bc1f352d8149b1dd9f3747e89e-2\"</ETag><ChecksumCRC64NVME>xd07QWveTJk=</ChecksumCRC64NVME><ChecksumType>FULL_OBJECT</ChecksumType></CompleteMultipartUploadResult>",
"headers" : {
"Server" : "AmazonS3",
"x-amz-request-id" : "WZSMWCRV4VJ0HVV7",
"x-amz-server-side-encryption" : "AES256",
"x-amz-id-2" : "SPka4esm9Ls6/Ft/0gv/tp+qdL9wi+MlcXnegYMSwFKzpCrgo6Igkm638utLfZNi7ZmD0txPqU4=",
"Date" : "Wed, 26 Nov 2025 06:07:04 GMT",
"Content-Type" : "application/xml"
}
},
"uuid" : "6626ed6c-29bf-4b76-8db9-891bc89bdcbf",
"persistent" : true,
"insertionIndex" : 575
}
Loading
Loading