From 271d7eebdac841c47269a341ab10e99053bd2493 Mon Sep 17 00:00:00 2001 From: Barry Liu Date: Wed, 26 Nov 2025 00:07:43 -0500 Subject: [PATCH 1/2] Support tagging for multipart upload in AWS and GCP --- .../multicloudj/blob/aws/AwsBlobStore.java | 1 + .../multicloudj/blob/aws/AwsTransformer.java | 7 +++ .../blob/aws/async/AwsAsyncBlobStore.java | 1 + .../blob/aws/AwsBlobStoreTest.java | 35 ++++++++++++ .../blob/aws/AwsTransformerTest.java | 18 ++++++ .../blob/aws/async/AwsAsyncBlobStoreTest.java | 35 ++++++++++++ .../blob/driver/MultipartUpload.java | 1 + .../blob/driver/MultipartUploadRequest.java | 19 ++++++- .../blob/client/AbstractBlobStoreIT.java | 56 ++++++++++++++++++- .../multicloudj/blob/gcp/GcpBlobStore.java | 1 + .../multicloudj/blob/gcp/GcpTransformer.java | 12 +++- .../blob/gcp/GcpBlobStoreTest.java | 45 +++++++++++++++ .../blob/gcp/GcpTransformerTest.java | 17 ++++++ 13 files changed, 243 insertions(+), 5 deletions(-) diff --git a/blob/blob-aws/src/main/java/com/salesforce/multicloudj/blob/aws/AwsBlobStore.java b/blob/blob-aws/src/main/java/com/salesforce/multicloudj/blob/aws/AwsBlobStore.java index 0fd295f87..10eb7af3c 100644 --- a/blob/blob-aws/src/main/java/com/salesforce/multicloudj/blob/aws/AwsBlobStore.java +++ b/blob/blob-aws/src/main/java/com/salesforce/multicloudj/blob/aws/AwsBlobStore.java @@ -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(); } diff --git a/blob/blob-aws/src/main/java/com/salesforce/multicloudj/blob/aws/AwsTransformer.java b/blob/blob-aws/src/main/java/com/salesforce/multicloudj/blob/aws/AwsTransformer.java index 2f8f248dd..49086d432 100644 --- a/blob/blob-aws/src/main/java/com/salesforce/multicloudj/blob/aws/AwsTransformer.java +++ b/blob/blob-aws/src/main/java/com/salesforce/multicloudj/blob/aws/AwsTransformer.java @@ -300,6 +300,13 @@ public CreateMultipartUploadRequest toCreateMultipartUploadRequest(MultipartUplo .key(request.getKey()) .metadata(request.getMetadata()); + if (request.getTags() != null && !request.getTags().isEmpty()) { + List 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()); diff --git a/blob/blob-aws/src/main/java/com/salesforce/multicloudj/blob/aws/async/AwsAsyncBlobStore.java b/blob/blob-aws/src/main/java/com/salesforce/multicloudj/blob/aws/async/AwsAsyncBlobStore.java index dd3e67493..118255de3 100644 --- a/blob/blob-aws/src/main/java/com/salesforce/multicloudj/blob/aws/async/AwsAsyncBlobStore.java +++ b/blob/blob-aws/src/main/java/com/salesforce/multicloudj/blob/aws/async/AwsAsyncBlobStore.java @@ -275,6 +275,7 @@ protected CompletableFuture doInitiateMultipartUpload(Multipart .key(response.key()) .id(response.uploadId()) .metadata(request.getMetadata()) + .tags(request.getTags()) .build()); } diff --git a/blob/blob-aws/src/test/java/com/salesforce/multicloudj/blob/aws/AwsBlobStoreTest.java b/blob/blob-aws/src/test/java/com/salesforce/multicloudj/blob/aws/AwsBlobStoreTest.java index 6eed92c81..5396be67c 100644 --- a/blob/blob-aws/src/test/java/com/salesforce/multicloudj/blob/aws/AwsBlobStoreTest.java +++ b/blob/blob-aws/src/test/java/com/salesforce/multicloudj/blob/aws/AwsBlobStoreTest.java @@ -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 metadata = Map.of("key-1", "value-1"); + Map 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 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); diff --git a/blob/blob-aws/src/test/java/com/salesforce/multicloudj/blob/aws/AwsTransformerTest.java b/blob/blob-aws/src/test/java/com/salesforce/multicloudj/blob/aws/AwsTransformerTest.java index 3c3d7679d..df7607917 100644 --- a/blob/blob-aws/src/test/java/com/salesforce/multicloudj/blob/aws/AwsTransformerTest.java +++ b/blob/blob-aws/src/test/java/com/salesforce/multicloudj/blob/aws/AwsTransformerTest.java @@ -391,6 +391,24 @@ void testToCreateMultipartUploadRequest() { assertEquals(metadata, request.metadata()); } + @Test + void testToCreateMultipartUploadRequestWithTags() { + Map metadata = Map.of("key1", "value1", "key2", "value2"); + Map 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 metadata = Map.of("key1", "value1", "key2", "value2"); diff --git a/blob/blob-aws/src/test/java/com/salesforce/multicloudj/blob/aws/async/AwsAsyncBlobStoreTest.java b/blob/blob-aws/src/test/java/com/salesforce/multicloudj/blob/aws/async/AwsAsyncBlobStoreTest.java index 3eb28156b..307ae8f53 100644 --- a/blob/blob-aws/src/test/java/com/salesforce/multicloudj/blob/aws/async/AwsAsyncBlobStoreTest.java +++ b/blob/blob-aws/src/test/java/com/salesforce/multicloudj/blob/aws/async/AwsAsyncBlobStoreTest.java @@ -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 metadata = Map.of("key-1", "value-1"); + Map 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 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); diff --git a/blob/blob-client/src/main/java/com/salesforce/multicloudj/blob/driver/MultipartUpload.java b/blob/blob-client/src/main/java/com/salesforce/multicloudj/blob/driver/MultipartUpload.java index 472b42a12..3665f1ab9 100644 --- a/blob/blob-client/src/main/java/com/salesforce/multicloudj/blob/driver/MultipartUpload.java +++ b/blob/blob-client/src/main/java/com/salesforce/multicloudj/blob/driver/MultipartUpload.java @@ -16,5 +16,6 @@ public class MultipartUpload { private final String key; private final String id; private final Map metadata; + private final Map tags; private final String kmsKeyId; } diff --git a/blob/blob-client/src/main/java/com/salesforce/multicloudj/blob/driver/MultipartUploadRequest.java b/blob/blob-client/src/main/java/com/salesforce/multicloudj/blob/driver/MultipartUploadRequest.java index 38e503c62..edcfe8c61 100644 --- a/blob/blob-client/src/main/java/com/salesforce/multicloudj/blob/driver/MultipartUploadRequest.java +++ b/blob/blob-client/src/main/java/com/salesforce/multicloudj/blob/driver/MultipartUploadRequest.java @@ -2,6 +2,7 @@ import lombok.Getter; +import java.util.Collections; import java.util.Map; import static java.util.Collections.unmodifiableMap; @@ -14,17 +15,28 @@ public class MultipartUploadRequest { private final String key; private Map metadata; + private final Map tags; private final String kmsKeyId; private MultipartUploadRequest(final Builder builder){ this.key = builder.key; this.metadata = builder.metadata; + this.tags = builder.tags; this.kmsKeyId = builder.kmsKeyId; } + public Map getMetadata() { + return metadata == null ? Map.of() : unmodifiableMap(metadata); + } + + public Map getTags() { + return tags == null ? Map.of() : unmodifiableMap(tags); + } + public static class Builder { private String key; - private Map metadata; + private Map metadata = Collections.emptyMap(); + private Map tags = Collections.emptyMap(); private String kmsKeyId; public Builder withKey(String key) { @@ -37,6 +49,11 @@ public Builder withMetadata(final Map metadata) { return this; } + public Builder withTags(final Map tags) { + this.tags = unmodifiableMap(tags); + return this; + } + public Builder withKmsKeyId(String kmsKeyId) { this.kmsKeyId = kmsKeyId; return this; diff --git a/blob/blob-client/src/test/java/com/salesforce/multicloudj/blob/client/AbstractBlobStoreIT.java b/blob/blob-client/src/test/java/com/salesforce/multicloudj/blob/client/AbstractBlobStoreIT.java index 871e77ef6..f92be6712 100644 --- a/blob/blob-client/src/test/java/com/salesforce/multicloudj/blob/client/AbstractBlobStoreIT.java +++ b/blob/blob-client/src/test/java/com/salesforce/multicloudj/blob/client/AbstractBlobStoreIT.java @@ -1638,6 +1638,7 @@ static class MultipartUploadTestConfig { final boolean abortUpload; final boolean wantCompletionError; final String kmsKeyId; + final Map tags; public MultipartUploadTestConfig(String testName, String key, @@ -1646,7 +1647,7 @@ public MultipartUploadTestConfig(String testName, List partsToComplete, boolean abortUpload, boolean wantCompletionError) { - this(testName, key, metadata, partsToUpload, partsToComplete, abortUpload, wantCompletionError, null); + this(testName, key, metadata, partsToUpload, partsToComplete, abortUpload, wantCompletionError, null, null); } public MultipartUploadTestConfig(String testName, @@ -1657,6 +1658,18 @@ public MultipartUploadTestConfig(String testName, boolean abortUpload, boolean wantCompletionError, String kmsKeyId) { + this(testName, key, metadata, partsToUpload, partsToComplete, abortUpload, wantCompletionError, kmsKeyId, null); + } + + public MultipartUploadTestConfig(String testName, + String key, + Map metadata, + List partsToUpload, + List partsToComplete, + boolean abortUpload, + boolean wantCompletionError, + String kmsKeyId, + Map tags) { this.testName = testName; this.key = key; this.metadata = metadata; @@ -1665,6 +1678,7 @@ public MultipartUploadTestConfig(String testName, this.abortUpload = abortUpload; this.wantCompletionError = wantCompletionError; this.kmsKeyId = kmsKeyId; + this.tags = tags; } } @@ -1684,6 +1698,9 @@ private void runMultipartUploadTest(MultipartUploadTestConfig testConfig) throws if (testConfig.kmsKeyId != null) { requestBuilder.withKmsKeyId(testConfig.kmsKeyId); } + if (testConfig.tags != null && !testConfig.tags.isEmpty()) { + requestBuilder.withTags(testConfig.tags); + } MultipartUploadRequest multipartUploadRequest = requestBuilder.build(); mpu = bucketClient.initiateMultipartUpload(multipartUploadRequest); @@ -1739,7 +1756,24 @@ private void runMultipartUploadTest(MultipartUploadTestConfig testConfig) throws } BlobMetadata blobMetadata = bucketClient.getMetadata(testConfig.key, null); - Assertions.assertEquals(testConfig.metadata, blobMetadata.getMetadata(), testConfig.testName + ": Downloaded metadata did not match"); + Map actualMetadata = blobMetadata.getMetadata(); + + // For GCP, tags are stored as metadata with "gcp-tag-" prefix, so we need to filter them out + // when comparing metadata + if (GCP_PROVIDER_ID.equals(harness.getProviderId()) && testConfig.tags != null && !testConfig.tags.isEmpty()) { + String tagPrefix = "gcp-tag-"; + actualMetadata = actualMetadata.entrySet().stream() + .filter(entry -> !entry.getKey().startsWith(tagPrefix)) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + } + + Assertions.assertEquals(testConfig.metadata, actualMetadata, testConfig.testName + ": Downloaded metadata did not match"); + + // Verify tags if they were provided + if (testConfig.tags != null && !testConfig.tags.isEmpty()) { + Map tagResults = bucketClient.getTags(testConfig.key); + Assertions.assertEquals(testConfig.tags, tagResults, testConfig.testName + ": Tags did not match what was uploaded"); + } } finally { // Now delete all blobs that were created @@ -2004,7 +2038,23 @@ public void testMultipartUpload_withKms() throws IOException { } @Test - @Disabled + public void testMultipartUpload_withTags() throws IOException { + // Exclude Ali provider as it doesn't support tags in multipart upload + Assumptions.assumeFalse("ali".equals(harness.getProviderId())); + Map tags = Map.of("tag1", "value1", "tag2", "value2"); + runMultipartUploadTest(new MultipartUploadTestConfig( + "multipart with tags", DEFAULT_MULTIPART_KEY_PREFIX + "withTags", + Map.of("key1", "value1"), + List.of( + new MultipartUploadTestPart(1, multipartBytes1), + new MultipartUploadTestPart(2, multipartBytes2)), + List.of( + new MultipartUploadPartResult(1, true), + new MultipartUploadPartResult(2, true)), + false, false, null, tags)); + } + + @Test public void testTagging() throws IOException { AbstractBlobStore blobStore = harness.createBlobStore(true, true, false); diff --git a/blob/blob-gcp/src/main/java/com/salesforce/multicloudj/blob/gcp/GcpBlobStore.java b/blob/blob-gcp/src/main/java/com/salesforce/multicloudj/blob/gcp/GcpBlobStore.java index d40446cf4..ed0b6e499 100644 --- a/blob/blob-gcp/src/main/java/com/salesforce/multicloudj/blob/gcp/GcpBlobStore.java +++ b/blob/blob-gcp/src/main/java/com/salesforce/multicloudj/blob/gcp/GcpBlobStore.java @@ -326,6 +326,7 @@ protected MultipartUpload doInitiateMultipartUpload(MultipartUploadRequest reque .key(request.getKey()) .id(uploadId) .metadata(request.getMetadata()) + .tags(request.getTags()) .kmsKeyId(request.getKmsKeyId()) .build(); } diff --git a/blob/blob-gcp/src/main/java/com/salesforce/multicloudj/blob/gcp/GcpTransformer.java b/blob/blob-gcp/src/main/java/com/salesforce/multicloudj/blob/gcp/GcpTransformer.java index b6cfb20d8..3dabccdd6 100644 --- a/blob/blob-gcp/src/main/java/com/salesforce/multicloudj/blob/gcp/GcpTransformer.java +++ b/blob/blob-gcp/src/main/java/com/salesforce/multicloudj/blob/gcp/GcpTransformer.java @@ -268,7 +268,17 @@ public UploadRequest toUploadRequest(MultipartUpload mpu, MultipartPart mpp) { } public BlobInfo toBlobInfo(MultipartUpload mpu) { - return toBlobInfo(mpu.getKey(), mpu.getMetadata()); + Map metadata = new HashMap<>(); + if(mpu.getMetadata() != null) { + metadata.putAll(mpu.getMetadata()); + } + + // Add tags to metadata with TAG_PREFIX + if(mpu.getTags() != null && !mpu.getTags().isEmpty()) { + mpu.getTags().forEach((tagName, tagValue) -> metadata.put(TAG_PREFIX + tagName, tagValue)); + } + + return toBlobInfo(mpu.getKey(), metadata); } public List toBlobIdList(Page blobs) { diff --git a/blob/blob-gcp/src/test/java/com/salesforce/multicloudj/blob/gcp/GcpBlobStoreTest.java b/blob/blob-gcp/src/test/java/com/salesforce/multicloudj/blob/gcp/GcpBlobStoreTest.java index 35e1da604..650d74119 100644 --- a/blob/blob-gcp/src/test/java/com/salesforce/multicloudj/blob/gcp/GcpBlobStoreTest.java +++ b/blob/blob-gcp/src/test/java/com/salesforce/multicloudj/blob/gcp/GcpBlobStoreTest.java @@ -1033,6 +1033,23 @@ void testDoInitiateMultipartUploadWithKms() { assertNotNull(mpu.getId()); } + @Test + void testDoInitiateMultipartUploadWithTags() { + Map tags = Map.of("tag1", "value1", "tag2", "value2"); + MultipartUploadRequest request = new MultipartUploadRequest.Builder() + .withKey(TEST_KEY) + .withMetadata(Map.of("key1","value1","key2","value2")) + .withTags(tags) + .build(); + + MultipartUpload mpu = gcpBlobStore.doInitiateMultipartUpload(request); + + assertEquals(TEST_BUCKET, mpu.getBucket()); + assertEquals(TEST_KEY, mpu.getKey()); + assertEquals(tags, mpu.getTags()); + assertNotNull(mpu.getId()); + } + @Test void testDoUploadMultipartPart() { try (MockedStatic mockedStatic = Mockito.mockStatic(ByteStreams.class)) { @@ -1086,6 +1103,34 @@ void testDoCompleteMultipartUpload() { assertEquals(TEST_ETAG, response.getEtag()); } + @Test + void testDoCompleteMultipartUploadWithTags() { + Map tags = Map.of("tag1", "value1", "tag2", "value2"); + MultipartUpload mpu = MultipartUpload.builder() + .bucket(TEST_BUCKET) + .key(TEST_KEY) + .id("id") + .tags(tags) + .build(); + List parts = List.of(new UploadPartResponse(1,"etag", 100)); + Blob mockBlob = mock(Blob.class); + doReturn(TEST_ETAG).when(mockBlob).getEtag(); + doReturn(mockBlob).when(mockStorage).compose(any()); + when(mockTransformer.toPartName(any(MultipartUpload.class), anyInt())).thenCallRealMethod(); + BlobInfo blobInfoWithTags = BlobInfo.newBuilder(TEST_BUCKET, TEST_KEY) + .setMetadata(Map.of("gcp-tag-tag1", "value1", "gcp-tag-tag2", "value2")) + .build(); + when(mockTransformer.toBlobInfo(mpu)).thenReturn(blobInfoWithTags); + + ArgumentCaptor composeRequestCaptor = ArgumentCaptor.forClass(Storage.ComposeRequest.class); + MultipartUploadResponse response = gcpBlobStore.doCompleteMultipartUpload(mpu, parts); + + verify(mockStorage).compose(composeRequestCaptor.capture()); + Storage.ComposeRequest composeRequest = composeRequestCaptor.getValue(); + assertEquals(blobInfoWithTags, composeRequest.getTarget()); + assertEquals(TEST_ETAG, response.getEtag()); + } + @Test void testDoListMultipartUpload() { MultipartUpload mpu = MultipartUpload.builder() diff --git a/blob/blob-gcp/src/test/java/com/salesforce/multicloudj/blob/gcp/GcpTransformerTest.java b/blob/blob-gcp/src/test/java/com/salesforce/multicloudj/blob/gcp/GcpTransformerTest.java index 7b45875e6..17b195d48 100644 --- a/blob/blob-gcp/src/test/java/com/salesforce/multicloudj/blob/gcp/GcpTransformerTest.java +++ b/blob/blob-gcp/src/test/java/com/salesforce/multicloudj/blob/gcp/GcpTransformerTest.java @@ -817,6 +817,23 @@ public void testToBlobInfo_multipartUpload() { assertEquals(0, blobInfo.getMetadata().size()); } + @Test + public void testToBlobInfo_multipartUploadWithTags() { + Map tags = Map.of("tag1", "value1", "tag2", "value2"); + MultipartUpload mpu = MultipartUpload.builder() + .bucket(TEST_BUCKET) + .key(TEST_KEY) + .id("uuid1") + .tags(tags) + .build(); + BlobInfo blobInfo = transformer.toBlobInfo(mpu); + assertEquals(TEST_BUCKET, blobInfo.getBucket()); + assertEquals(TEST_KEY, blobInfo.getName()); + assertEquals(2, blobInfo.getMetadata().size()); + assertEquals("value1", blobInfo.getMetadata().get("gcp-tag-tag1")); + assertEquals("value2", blobInfo.getMetadata().get("gcp-tag-tag2")); + } + @Test public void testToBlobIdList() { Page page = mock(Page.class); From ca475db4206bf184074f584f8c28a1d08947e55b Mon Sep 17 00:00:00 2001 From: Barry Liu Date: Wed, 26 Nov 2025 01:07:59 -0500 Subject: [PATCH 2/2] Add record files for test testMultipartUpload_withTags for aws --- .../resources/mappings/delete-6toelc0tmn.json | 20 ++++++++++++++ .../resources/mappings/delete-jmtgmhaiu0.json | 20 ++++++++++++++ .../resources/mappings/get-5mgtesclbh.json | 21 +++++++++++++++ .../resources/mappings/get-nvkpw2yli7.json | 22 +++++++++++++++ .../resources/mappings/head-jrqn0thyrr.json | 27 +++++++++++++++++++ .../resources/mappings/post-pckdj0ogrh.json | 22 +++++++++++++++ .../resources/mappings/post-s5fewyoabb.json | 26 ++++++++++++++++++ .../resources/mappings/put-3noppe3w9k.json | 25 +++++++++++++++++ .../resources/mappings/put-ap0aqfewiq.json | 25 +++++++++++++++++ 9 files changed, 208 insertions(+) create mode 100644 blob/blob-aws/src/test/resources/mappings/delete-6toelc0tmn.json create mode 100644 blob/blob-aws/src/test/resources/mappings/delete-jmtgmhaiu0.json create mode 100644 blob/blob-aws/src/test/resources/mappings/get-5mgtesclbh.json create mode 100644 blob/blob-aws/src/test/resources/mappings/get-nvkpw2yli7.json create mode 100644 blob/blob-aws/src/test/resources/mappings/head-jrqn0thyrr.json create mode 100644 blob/blob-aws/src/test/resources/mappings/post-pckdj0ogrh.json create mode 100644 blob/blob-aws/src/test/resources/mappings/post-s5fewyoabb.json create mode 100644 blob/blob-aws/src/test/resources/mappings/put-3noppe3w9k.json create mode 100644 blob/blob-aws/src/test/resources/mappings/put-ap0aqfewiq.json diff --git a/blob/blob-aws/src/test/resources/mappings/delete-6toelc0tmn.json b/blob/blob-aws/src/test/resources/mappings/delete-6toelc0tmn.json new file mode 100644 index 000000000..b6e310509 --- /dev/null +++ b/blob/blob-aws/src/test/resources/mappings/delete-6toelc0tmn.json @@ -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 +} \ No newline at end of file diff --git a/blob/blob-aws/src/test/resources/mappings/delete-jmtgmhaiu0.json b/blob/blob-aws/src/test/resources/mappings/delete-jmtgmhaiu0.json new file mode 100644 index 000000000..5d46a0c19 --- /dev/null +++ b/blob/blob-aws/src/test/resources/mappings/delete-jmtgmhaiu0.json @@ -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 +} \ No newline at end of file diff --git a/blob/blob-aws/src/test/resources/mappings/get-5mgtesclbh.json b/blob/blob-aws/src/test/resources/mappings/get-5mgtesclbh.json new file mode 100644 index 000000000..c58ce83bf --- /dev/null +++ b/blob/blob-aws/src/test/resources/mappings/get-5mgtesclbh.json @@ -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 +} \ No newline at end of file diff --git a/blob/blob-aws/src/test/resources/mappings/get-nvkpw2yli7.json b/blob/blob-aws/src/test/resources/mappings/get-nvkpw2yli7.json new file mode 100644 index 000000000..527990cb4 --- /dev/null +++ b/blob/blob-aws/src/test/resources/mappings/get-nvkpw2yli7.json @@ -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" : "\nchameleon-jcloudconformance-tests/multipart-withTagsHDOoXyIE1BO4feFEYcL3Lau7OMvXmhnu.OK5sLEOZyNnMGgBH1xE19f9gL22M2lG5KF2.Ouf6LVM6WS0oUqPwSwYj4EIz3FsP4ZE9O_k_LTQO4tbf8eV6fgoiXY4Z1IJglocI1LPy7BISMs.I8MX5KP5QsazuVTPxvCmbmvlTKT7riX3BYZQeu0H9bFN8xW9arn:aws:sts::654654370895:assumed-role/PCSKAdministratorAccessRole/PCSK-barry.liu@d991383f-2686-4df5-8465-9027dc410bfdPCSKAdministratorAccessRole/PCSK-barry.liu@d991383f-2686-4df5-8465-9027dc410bfdb6eaab2af32ba61bce00b8c9aceaa1c649844388ec2c3827bbd3e2b06f798cf1STANDARD021000false12025-11-26T06:06:58.000Z"2b5c91ad399409ec9b409b66f5bb00fb"524288022025-11-26T06:06:59.000Z"267c038cc2ec32ffd0ee2512ff5da5a5"5242880", + "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 +} \ No newline at end of file diff --git a/blob/blob-aws/src/test/resources/mappings/head-jrqn0thyrr.json b/blob/blob-aws/src/test/resources/mappings/head-jrqn0thyrr.json new file mode 100644 index 000000000..8a22187c5 --- /dev/null +++ b/blob/blob-aws/src/test/resources/mappings/head-jrqn0thyrr.json @@ -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 +} \ No newline at end of file diff --git a/blob/blob-aws/src/test/resources/mappings/post-pckdj0ogrh.json b/blob/blob-aws/src/test/resources/mappings/post-pckdj0ogrh.json new file mode 100644 index 000000000..4fd4b4bab --- /dev/null +++ b/blob/blob-aws/src/test/resources/mappings/post-pckdj0ogrh.json @@ -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 +} \ No newline at end of file diff --git a/blob/blob-aws/src/test/resources/mappings/post-s5fewyoabb.json b/blob/blob-aws/src/test/resources/mappings/post-s5fewyoabb.json new file mode 100644 index 000000000..40b137700 --- /dev/null +++ b/blob/blob-aws/src/test/resources/mappings/post-s5fewyoabb.json @@ -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" : ""2b5c91ad399409ec9b409b66f5bb00fb"1"267c038cc2ec32ffd0ee2512ff5da5a5"2" + } ] + }, + "response" : { + "status" : 200, + "body" : "\n\nhttps://s3.us-west-2.amazonaws.com/chameleon-jcloud/conformance-tests%2Fmultipart-withTagschameleon-jcloudconformance-tests/multipart-withTags\"63a814bc1f352d8149b1dd9f3747e89e-2\"xd07QWveTJk=FULL_OBJECT", + "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 +} \ No newline at end of file diff --git a/blob/blob-aws/src/test/resources/mappings/put-3noppe3w9k.json b/blob/blob-aws/src/test/resources/mappings/put-3noppe3w9k.json new file mode 100644 index 000000000..8667e8cfd --- /dev/null +++ b/blob/blob-aws/src/test/resources/mappings/put-3noppe3w9k.json @@ -0,0 +1,25 @@ +{ + "id" : "e2f7c89c-c226-4851-a2e2-54089efe9a2c", + "name" : "chameleon-jcloud_conformance-tests_multipart-withtags", + "request" : { + "url" : "/chameleon-jcloud/conformance-tests/multipart-withTags?partNumber=2&uploadId=HDOoXyIE1BO4feFEYcL3Lau7OMvXmhnu.OK5sLEOZyNnMGgBH1xE19f9gL22M2lG5KF2.Ouf6LVM6WS0oUqPwSwYj4EIz3FsP4ZE9O_k_LTQO4tbf8eV6fgoiXY4Z1IJglocI1LPy7BISMs.I8MX5KP5QsazuVTPxvCmbmvlTKT7riX3BYZQeu0H9bFN8xW9", + "method" : "PUT", + "bodyPatterns" : [ { + "matches" : "^MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy*" + } ] + }, + "response" : { + "status" : 200, + "headers" : { + "Server" : "AmazonS3", + "ETag" : "\"267c038cc2ec32ffd0ee2512ff5da5a5\"", + "x-amz-request-id" : "0HVV1VKY27S8TSY1", + "x-amz-server-side-encryption" : "AES256", + "x-amz-id-2" : "OGvN/0gZVsjgJnHBDpMp7lkqZEd63tuuHrKxy7GsRUSQnCOkbQCyZ2iBA+ky109J9JLLJVcFUXE=", + "Date" : "Wed, 26 Nov 2025 06:06:59 GMT" + } + }, + "uuid" : "e2f7c89c-c226-4851-a2e2-54089efe9a2c", + "persistent" : true, + "insertionIndex" : 577 +} \ No newline at end of file diff --git a/blob/blob-aws/src/test/resources/mappings/put-ap0aqfewiq.json b/blob/blob-aws/src/test/resources/mappings/put-ap0aqfewiq.json new file mode 100644 index 000000000..213de4718 --- /dev/null +++ b/blob/blob-aws/src/test/resources/mappings/put-ap0aqfewiq.json @@ -0,0 +1,25 @@ +{ + "id" : "8d5b29e5-0cef-4fff-ba9b-40739c470456", + "name" : "chameleon-jcloud_conformance-tests_multipart-withtags", + "request" : { + "url" : "/chameleon-jcloud/conformance-tests/multipart-withTags?partNumber=1&uploadId=HDOoXyIE1BO4feFEYcL3Lau7OMvXmhnu.OK5sLEOZyNnMGgBH1xE19f9gL22M2lG5KF2.Ouf6LVM6WS0oUqPwSwYj4EIz3FsP4ZE9O_k_LTQO4tbf8eV6fgoiXY4Z1IJglocI1LPy7BISMs.I8MX5KP5QsazuVTPxvCmbmvlTKT7riX3BYZQeu0H9bFN8xW9", + "method" : "PUT", + "bodyPatterns" : [ { + "matches" : "^MTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTEx*" + } ] + }, + "response" : { + "status" : 200, + "headers" : { + "Server" : "AmazonS3", + "ETag" : "\"2b5c91ad399409ec9b409b66f5bb00fb\"", + "x-amz-request-id" : "GGW0SCSBC26TAA2K", + "x-amz-server-side-encryption" : "AES256", + "x-amz-id-2" : "FAJylsAkvOVDfGvFhXDARw28H9iMXM4j/K3GdBZ/KT8KvAnPoIBHaHdlrpQXJ3wWyr05tw+2aP0=", + "Date" : "Wed, 26 Nov 2025 06:06:58 GMT" + } + }, + "uuid" : "8d5b29e5-0cef-4fff-ba9b-40739c470456", + "persistent" : true, + "insertionIndex" : 578 +} \ No newline at end of file