From d95bd4a362c999950450a0b245906225713973a4 Mon Sep 17 00:00:00 2001 From: texastony <5892063+texastony@users.noreply.github.com> Date: Thu, 24 Oct 2024 15:13:47 -0700 Subject: [PATCH 1/6] chore: bump AWS SDK dependencies --- pom.xml | 12 ++-- .../s3/S3AsyncEncryptionClient.java | 58 ++++++++++++++++--- .../encryption/s3/S3EncryptionClient.java | 30 ++++++++++ .../s3/S3AsyncEncryptionClientTest.java | 47 +++++++++++++++ 4 files changed, 134 insertions(+), 13 deletions(-) diff --git a/pom.xml b/pom.xml index f33beb9ef..b2290618a 100644 --- a/pom.xml +++ b/pom.xml @@ -41,6 +41,9 @@ 8 8 UTF-8 + 2.29.0 + 0.31.3 + 1.12.777 @@ -48,7 +51,7 @@ com.amazonaws aws-java-sdk-bom - 1.12.441 + ${com.amazonaws.version} pom import @@ -56,7 +59,7 @@ software.amazon.awssdk bom - 2.20.38 + ${aws.java.sdk.version} true pom import @@ -68,13 +71,11 @@ software.amazon.awssdk s3 - 2.20.38 software.amazon.awssdk kms - 2.20.38 true @@ -82,7 +83,7 @@ software.amazon.awssdk.crt aws-crt - 0.29.24 + ${aws.java.crt.version} true @@ -164,7 +165,6 @@ software.amazon.awssdk sts - 2.20.38 true test diff --git a/src/main/java/software/amazon/encryption/s3/S3AsyncEncryptionClient.java b/src/main/java/software/amazon/encryption/s3/S3AsyncEncryptionClient.java index 2ed1ba3f5..f44c57545 100644 --- a/src/main/java/software/amazon/encryption/s3/S3AsyncEncryptionClient.java +++ b/src/main/java/software/amazon/encryption/s3/S3AsyncEncryptionClient.java @@ -30,6 +30,7 @@ import software.amazon.awssdk.services.s3.model.PutObjectRequest; import software.amazon.awssdk.services.s3.model.PutObjectResponse; import software.amazon.awssdk.services.s3.model.S3Request; +import software.amazon.awssdk.services.s3.multipart.MultipartConfiguration; import software.amazon.encryption.s3.internal.GetEncryptedObjectPipeline; import software.amazon.encryption.s3.internal.NoRetriesAsyncRequestBody; import software.amazon.encryption.s3.internal.PutEncryptedObjectPipeline; @@ -71,6 +72,7 @@ public class S3AsyncEncryptionClient extends DelegatingS3AsyncClient { private final boolean _enableDelayedAuthenticationMode; private final boolean _enableMultipartPutObject; private final long _bufferSize; + private final boolean _clientMultipartEnabled; private S3AsyncEncryptionClient(Builder builder) { super(builder._wrappedClient); @@ -81,6 +83,7 @@ private S3AsyncEncryptionClient(Builder builder) { _enableDelayedAuthenticationMode = builder._enableDelayedAuthenticationMode; _enableMultipartPutObject = builder._enableMultipartPutObject; _bufferSize = builder._bufferSize; + _clientMultipartEnabled = builder._multipartEnabled != null && builder._multipartEnabled; } /** @@ -147,16 +150,19 @@ public CompletableFuture putObject(PutObjectRequest putObject } private CompletableFuture multipartPutObject(PutObjectRequest putObjectRequest, AsyncRequestBody requestBody) { - S3AsyncClient crtClient; - if (_wrappedClient instanceof S3CrtAsyncClient) { + S3AsyncClient mpuClient; + if (_wrappedClient instanceof S3CrtAsyncClient && !_clientMultipartEnabled) { // if the wrappedClient is a CRT, use it - crtClient = _wrappedClient; - } else { - // else create a default one - crtClient = S3AsyncClient.crtCreate(); + mpuClient = _wrappedClient; + } else if (_clientMultipartEnabled) { + mpuClient = _wrappedClient; + } + else { + // else create a default CRT client + mpuClient = S3AsyncClient.crtCreate(); } PutEncryptedObjectPipeline pipeline = PutEncryptedObjectPipeline.builder() - .s3AsyncClient(crtClient) + .s3AsyncClient(mpuClient) .cryptoMaterialsManager(_cryptoMaterialsManager) .secureRandom(_secureRandom) .build(); @@ -291,8 +297,12 @@ public static class Builder implements S3AsyncClientBuilder { private S3Configuration _serviceConfiguration = null; private Boolean _accelerate = null; private Boolean _disableMultiRegionAccessPoints = null; + private Boolean _disableS3ExpressSessionAuth = null; private Boolean _forcePathStyle = null; private Boolean _useArnRegion = null; + private Boolean _crossRegionAccessEnabled = null; + private Boolean _multipartEnabled = null; + private MultipartConfiguration _multipartConfiguration = null; private Builder() { } @@ -696,6 +706,12 @@ public Builder disableMultiRegionAccessPoints(Boolean disableMultiRegionAccessPo return this; } + @Override + public S3AsyncClientBuilder disableS3ExpressSessionAuth(Boolean disableS3ExpressSessionAuth) { + _disableS3ExpressSessionAuth = disableS3ExpressSessionAuth; + return this; + } + /** * Forces this client to use path-style addressing for buckets. * @@ -719,6 +735,24 @@ public Builder useArnRegion(Boolean useArnRegion) { return this; } + @Override + public Builder multipartEnabled(Boolean enabled) { + _multipartEnabled = enabled; + return this; + } + + @Override + public S3AsyncClientBuilder multipartConfiguration(MultipartConfiguration multipartConfiguration) { + _multipartConfiguration = multipartConfiguration; + return this; + } + + @Override + public Builder crossRegionAccessEnabled(Boolean crossRegionAccessEnabled) { + _crossRegionAccessEnabled = crossRegionAccessEnabled; + return this; + } + /** * Validates and builds the S3AsyncEncryptionClient according * to the configuration options passed to the Builder object. @@ -737,6 +771,12 @@ public S3AsyncEncryptionClient build() { _bufferSize = DEFAULT_BUFFER_SIZE_BYTES; } + // The S3 Async Client has its own multipart setting, + // we enforce that the S3EC multipart PutObject setting is enabled as well. + if (_multipartEnabled != null && _multipartEnabled && !_enableMultipartPutObject) { + throw new S3EncryptionClientException("EnableMultipartPutObject MUST be enabled when the MultipartEnabled option is set to true."); + } + if (_wrappedClient == null) { _wrappedClient = S3AsyncClient.builder() .credentialsProvider(_awsCredentialsProvider) @@ -751,8 +791,12 @@ public S3AsyncEncryptionClient build() { .serviceConfiguration(_serviceConfiguration) .accelerate(_accelerate) .disableMultiRegionAccessPoints(_disableMultiRegionAccessPoints) + .disableS3ExpressSessionAuth(_disableS3ExpressSessionAuth) .forcePathStyle(_forcePathStyle) .useArnRegion(_useArnRegion) + .crossRegionAccessEnabled(_crossRegionAccessEnabled) + .multipartEnabled(_multipartEnabled) + .multipartConfiguration(_multipartConfiguration) .build(); } diff --git a/src/main/java/software/amazon/encryption/s3/S3EncryptionClient.java b/src/main/java/software/amazon/encryption/s3/S3EncryptionClient.java index 1c3f6c27a..7f3f1f6be 100644 --- a/src/main/java/software/amazon/encryption/s3/S3EncryptionClient.java +++ b/src/main/java/software/amazon/encryption/s3/S3EncryptionClient.java @@ -544,8 +544,10 @@ public static class Builder implements S3BaseClientBuilder encryptionContext = new HashMap<>(); + encryptionContext.put("user-metadata-key", "user-metadata-value-v3-to-v3"); + + ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); + + CompletableFuture futurePut = v3Client.putObject(builder -> builder + .bucket(BUCKET) + .overrideConfiguration(withAdditionalConfiguration(encryptionContext)) + .key(objectKey), AsyncRequestBody.fromInputStream(inputStream, fileSizeLimit, singleThreadExecutor)); + futurePut.join(); + singleThreadExecutor.shutdown(); + + // Asserts + CompletableFuture> getFuture = v3Client.getObject(builder -> builder + .bucket(BUCKET) + .overrideConfiguration(S3EncryptionClient.withAdditionalConfiguration(encryptionContext)) + .key(objectKey), AsyncResponseTransformer.toBlockingInputStream()); + ResponseInputStream output = getFuture.join(); + + assertTrue(IOUtils.contentEquals(objectStreamForResult, output)); + + deleteObject(BUCKET, objectKey, v3Client); + v3Client.close(); + } } From 9bb6d83855ae2e1c8dbe8389efc6acbc8c8d8925 Mon Sep 17 00:00:00 2001 From: texastony <5892063+texastony@users.noreply.github.com> Date: Thu, 24 Oct 2024 15:59:29 -0700 Subject: [PATCH 2/6] try 2.20.162 --- pom.xml | 2 +- .../encryption/s3/S3AsyncEncryptionClient.java | 12 ++++++------ .../amazon/encryption/s3/S3EncryptionClient.java | 14 +++++++------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/pom.xml b/pom.xml index b2290618a..ae6b3689e 100644 --- a/pom.xml +++ b/pom.xml @@ -41,7 +41,7 @@ 8 8 UTF-8 - 2.29.0 + 2.20.162 0.31.3 1.12.777 diff --git a/src/main/java/software/amazon/encryption/s3/S3AsyncEncryptionClient.java b/src/main/java/software/amazon/encryption/s3/S3AsyncEncryptionClient.java index f44c57545..372243e9b 100644 --- a/src/main/java/software/amazon/encryption/s3/S3AsyncEncryptionClient.java +++ b/src/main/java/software/amazon/encryption/s3/S3AsyncEncryptionClient.java @@ -706,11 +706,11 @@ public Builder disableMultiRegionAccessPoints(Boolean disableMultiRegionAccessPo return this; } - @Override - public S3AsyncClientBuilder disableS3ExpressSessionAuth(Boolean disableS3ExpressSessionAuth) { - _disableS3ExpressSessionAuth = disableS3ExpressSessionAuth; - return this; - } + // @Override + // public S3AsyncClientBuilder disableS3ExpressSessionAuth(Boolean disableS3ExpressSessionAuth) { + // _disableS3ExpressSessionAuth = disableS3ExpressSessionAuth; + // return this; + // } /** * Forces this client to use path-style addressing for buckets. @@ -791,7 +791,7 @@ public S3AsyncEncryptionClient build() { .serviceConfiguration(_serviceConfiguration) .accelerate(_accelerate) .disableMultiRegionAccessPoints(_disableMultiRegionAccessPoints) - .disableS3ExpressSessionAuth(_disableS3ExpressSessionAuth) + // .disableS3ExpressSessionAuth(_disableS3ExpressSessionAuth) .forcePathStyle(_forcePathStyle) .useArnRegion(_useArnRegion) .crossRegionAccessEnabled(_crossRegionAccessEnabled) diff --git a/src/main/java/software/amazon/encryption/s3/S3EncryptionClient.java b/src/main/java/software/amazon/encryption/s3/S3EncryptionClient.java index 7f3f1f6be..c72dacc94 100644 --- a/src/main/java/software/amazon/encryption/s3/S3EncryptionClient.java +++ b/src/main/java/software/amazon/encryption/s3/S3EncryptionClient.java @@ -926,11 +926,11 @@ public Builder disableMultiRegionAccessPoints(Boolean disableMultiRegionAccessPo * * @param disableS3ExpressSessionAuth */ - @Override - public Builder disableS3ExpressSessionAuth(Boolean disableS3ExpressSessionAuth) { - _disableS3ExpressSessionAuth = disableS3ExpressSessionAuth; - return this; - } + // @Override + // public Builder disableS3ExpressSessionAuth(Boolean disableS3ExpressSessionAuth) { + // _disableS3ExpressSessionAuth = disableS3ExpressSessionAuth; + // return this; + // } /** * Forces this client to use path-style addressing for buckets. @@ -1077,7 +1077,7 @@ public S3EncryptionClient build() { .useArnRegion(_useArnRegion) .httpClient(_httpClient) .httpClientBuilder(_httpClientBuilder) - .disableS3ExpressSessionAuth(_disableS3ExpressSessionAuth) + // .disableS3ExpressSessionAuth(_disableS3ExpressSessionAuth) .crossRegionAccessEnabled(_crossRegionAccessEnabled) .build(); } @@ -1097,7 +1097,7 @@ public S3EncryptionClient build() { .useArnRegion(_useArnRegion) .httpClient(_asyncHttpClient) .httpClientBuilder(_asyncHttpClientBuilder) - .disableS3ExpressSessionAuth(_disableS3ExpressSessionAuth) + // .disableS3ExpressSessionAuth(_disableS3ExpressSessionAuth) .crossRegionAccessEnabled(_crossRegionAccessEnabled) // TODO: Add MPU stuff here too .build(); From 3a50cc89ce12b3bdaffbe1b36a20589643537b46 Mon Sep 17 00:00:00 2001 From: texastony <5892063+texastony@users.noreply.github.com> Date: Thu, 24 Oct 2024 16:18:14 -0700 Subject: [PATCH 3/6] only bump SDK V2 --- pom.xml | 4 +- .../s3/S3AsyncEncryptionClientTest.java | 80 +++++++++---------- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/pom.xml b/pom.xml index ae6b3689e..2eff615dc 100644 --- a/pom.xml +++ b/pom.xml @@ -42,8 +42,8 @@ 8 UTF-8 2.20.162 - 0.31.3 - 1.12.777 + 0.29.24 + 1.12.441 diff --git a/src/test/java/software/amazon/encryption/s3/S3AsyncEncryptionClientTest.java b/src/test/java/software/amazon/encryption/s3/S3AsyncEncryptionClientTest.java index 60b7819d5..0f8f49ceb 100644 --- a/src/test/java/software/amazon/encryption/s3/S3AsyncEncryptionClientTest.java +++ b/src/test/java/software/amazon/encryption/s3/S3AsyncEncryptionClientTest.java @@ -762,44 +762,44 @@ public void tinyBufferTest() throws IOException { exec.shutdown(); } - @Test - public void wrappedClientMultipartUpload() throws IOException { - final String objectKey = appendTestSuffix("multipart-put-object-async-wrapped-client"); - - final long fileSizeLimit = 1024 * 1024 * 100; - final InputStream inputStream = new BoundedInputStream(fileSizeLimit); - final InputStream objectStreamForResult = new BoundedInputStream(fileSizeLimit); - - S3AsyncClient v3Client = S3AsyncEncryptionClient.builder() - .kmsKeyId(KMS_KEY_ID) - .enableMultipartPutObject(true) -// .multipartEnabled(true) - .enableDelayedAuthenticationMode(true) - .cryptoProvider(PROVIDER) - .build(); - - Map encryptionContext = new HashMap<>(); - encryptionContext.put("user-metadata-key", "user-metadata-value-v3-to-v3"); - - ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); - - CompletableFuture futurePut = v3Client.putObject(builder -> builder - .bucket(BUCKET) - .overrideConfiguration(withAdditionalConfiguration(encryptionContext)) - .key(objectKey), AsyncRequestBody.fromInputStream(inputStream, fileSizeLimit, singleThreadExecutor)); - futurePut.join(); - singleThreadExecutor.shutdown(); - - // Asserts - CompletableFuture> getFuture = v3Client.getObject(builder -> builder - .bucket(BUCKET) - .overrideConfiguration(S3EncryptionClient.withAdditionalConfiguration(encryptionContext)) - .key(objectKey), AsyncResponseTransformer.toBlockingInputStream()); - ResponseInputStream output = getFuture.join(); - - assertTrue(IOUtils.contentEquals(objectStreamForResult, output)); - - deleteObject(BUCKET, objectKey, v3Client); - v3Client.close(); - } +// @Test +// public void wrappedClientMultipartUpload() throws IOException { +// final String objectKey = appendTestSuffix("multipart-put-object-async-wrapped-client"); + +// final long fileSizeLimit = 1024 * 1024 * 100; +// final InputStream inputStream = new BoundedInputStream(fileSizeLimit); +// final InputStream objectStreamForResult = new BoundedInputStream(fileSizeLimit); + +// S3AsyncClient v3Client = S3AsyncEncryptionClient.builder() +// .kmsKeyId(KMS_KEY_ID) +// .enableMultipartPutObject(true) +// // .multipartEnabled(true) +// .enableDelayedAuthenticationMode(true) +// .cryptoProvider(PROVIDER) +// .build(); + +// Map encryptionContext = new HashMap<>(); +// encryptionContext.put("user-metadata-key", "user-metadata-value-v3-to-v3"); + +// ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); + +// CompletableFuture futurePut = v3Client.putObject(builder -> builder +// .bucket(BUCKET) +// .overrideConfiguration(withAdditionalConfiguration(encryptionContext)) +// .key(objectKey), AsyncRequestBody.fromInputStream(inputStream, fileSizeLimit, singleThreadExecutor)); +// futurePut.join(); +// singleThreadExecutor.shutdown(); + +// // Asserts +// CompletableFuture> getFuture = v3Client.getObject(builder -> builder +// .bucket(BUCKET) +// .overrideConfiguration(S3EncryptionClient.withAdditionalConfiguration(encryptionContext)) +// .key(objectKey), AsyncResponseTransformer.toBlockingInputStream()); +// ResponseInputStream output = getFuture.join(); + +// assertTrue(IOUtils.contentEquals(objectStreamForResult, output)); + +// deleteObject(BUCKET, objectKey, v3Client); +// v3Client.close(); +// } } From d133ddc3f047e8c9dfd836e0aadb9544bb8add23 Mon Sep 17 00:00:00 2001 From: texastony <5892063+texastony@users.noreply.github.com> Date: Thu, 24 Oct 2024 16:28:47 -0700 Subject: [PATCH 4/6] try 2.21.46 --- pom.xml | 2 +- .../encryption/s3/S3AsyncEncryptionClient.java | 12 ++++++------ .../amazon/encryption/s3/S3EncryptionClient.java | 14 +++++++------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/pom.xml b/pom.xml index 2eff615dc..f504c79ca 100644 --- a/pom.xml +++ b/pom.xml @@ -41,7 +41,7 @@ 8 8 UTF-8 - 2.20.162 + 2.21.46 0.29.24 1.12.441 diff --git a/src/main/java/software/amazon/encryption/s3/S3AsyncEncryptionClient.java b/src/main/java/software/amazon/encryption/s3/S3AsyncEncryptionClient.java index 372243e9b..f44c57545 100644 --- a/src/main/java/software/amazon/encryption/s3/S3AsyncEncryptionClient.java +++ b/src/main/java/software/amazon/encryption/s3/S3AsyncEncryptionClient.java @@ -706,11 +706,11 @@ public Builder disableMultiRegionAccessPoints(Boolean disableMultiRegionAccessPo return this; } - // @Override - // public S3AsyncClientBuilder disableS3ExpressSessionAuth(Boolean disableS3ExpressSessionAuth) { - // _disableS3ExpressSessionAuth = disableS3ExpressSessionAuth; - // return this; - // } + @Override + public S3AsyncClientBuilder disableS3ExpressSessionAuth(Boolean disableS3ExpressSessionAuth) { + _disableS3ExpressSessionAuth = disableS3ExpressSessionAuth; + return this; + } /** * Forces this client to use path-style addressing for buckets. @@ -791,7 +791,7 @@ public S3AsyncEncryptionClient build() { .serviceConfiguration(_serviceConfiguration) .accelerate(_accelerate) .disableMultiRegionAccessPoints(_disableMultiRegionAccessPoints) - // .disableS3ExpressSessionAuth(_disableS3ExpressSessionAuth) + .disableS3ExpressSessionAuth(_disableS3ExpressSessionAuth) .forcePathStyle(_forcePathStyle) .useArnRegion(_useArnRegion) .crossRegionAccessEnabled(_crossRegionAccessEnabled) diff --git a/src/main/java/software/amazon/encryption/s3/S3EncryptionClient.java b/src/main/java/software/amazon/encryption/s3/S3EncryptionClient.java index c72dacc94..7f3f1f6be 100644 --- a/src/main/java/software/amazon/encryption/s3/S3EncryptionClient.java +++ b/src/main/java/software/amazon/encryption/s3/S3EncryptionClient.java @@ -926,11 +926,11 @@ public Builder disableMultiRegionAccessPoints(Boolean disableMultiRegionAccessPo * * @param disableS3ExpressSessionAuth */ - // @Override - // public Builder disableS3ExpressSessionAuth(Boolean disableS3ExpressSessionAuth) { - // _disableS3ExpressSessionAuth = disableS3ExpressSessionAuth; - // return this; - // } + @Override + public Builder disableS3ExpressSessionAuth(Boolean disableS3ExpressSessionAuth) { + _disableS3ExpressSessionAuth = disableS3ExpressSessionAuth; + return this; + } /** * Forces this client to use path-style addressing for buckets. @@ -1077,7 +1077,7 @@ public S3EncryptionClient build() { .useArnRegion(_useArnRegion) .httpClient(_httpClient) .httpClientBuilder(_httpClientBuilder) - // .disableS3ExpressSessionAuth(_disableS3ExpressSessionAuth) + .disableS3ExpressSessionAuth(_disableS3ExpressSessionAuth) .crossRegionAccessEnabled(_crossRegionAccessEnabled) .build(); } @@ -1097,7 +1097,7 @@ public S3EncryptionClient build() { .useArnRegion(_useArnRegion) .httpClient(_asyncHttpClient) .httpClientBuilder(_asyncHttpClientBuilder) - // .disableS3ExpressSessionAuth(_disableS3ExpressSessionAuth) + .disableS3ExpressSessionAuth(_disableS3ExpressSessionAuth) .crossRegionAccessEnabled(_crossRegionAccessEnabled) // TODO: Add MPU stuff here too .build(); From 2862f018aeb3ce25d0b0e2195cf1f85faa03497c Mon Sep 17 00:00:00 2001 From: texastony <5892063+texastony@users.noreply.github.com> Date: Thu, 24 Oct 2024 16:36:44 -0700 Subject: [PATCH 5/6] try 2.22.13 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f504c79ca..c99d280be 100644 --- a/pom.xml +++ b/pom.xml @@ -41,7 +41,7 @@ 8 8 UTF-8 - 2.21.46 + 2.22.13 0.29.24 1.12.441 From 71b54705d77d7b7aec84a0022e7b1181fb078172 Mon Sep 17 00:00:00 2001 From: texastony <5892063+texastony@users.noreply.github.com> Date: Thu, 24 Oct 2024 17:10:24 -0700 Subject: [PATCH 6/6] investigate V1453286179 --- pom.xml | 2 +- .../s3/S3AsyncEncryptionClientTest.java | 87 ++++++++++--------- 2 files changed, 48 insertions(+), 41 deletions(-) diff --git a/pom.xml b/pom.xml index c99d280be..f504c79ca 100644 --- a/pom.xml +++ b/pom.xml @@ -41,7 +41,7 @@ 8 8 UTF-8 - 2.22.13 + 2.21.46 0.29.24 1.12.441 diff --git a/src/test/java/software/amazon/encryption/s3/S3AsyncEncryptionClientTest.java b/src/test/java/software/amazon/encryption/s3/S3AsyncEncryptionClientTest.java index 0f8f49ceb..e98b75c8e 100644 --- a/src/test/java/software/amazon/encryption/s3/S3AsyncEncryptionClientTest.java +++ b/src/test/java/software/amazon/encryption/s3/S3AsyncEncryptionClientTest.java @@ -40,6 +40,7 @@ import software.amazon.awssdk.services.s3.model.ObjectIdentifier; import software.amazon.awssdk.services.s3.model.PutObjectResponse; import software.amazon.awssdk.services.s3.model.S3Exception; +import software.amazon.awssdk.services.s3.multipart.MultipartConfiguration; import software.amazon.encryption.s3.materials.KmsKeyring; import software.amazon.encryption.s3.utils.BoundedInputStream; import software.amazon.encryption.s3.utils.S3EncryptionClientTestResources; @@ -762,44 +763,50 @@ public void tinyBufferTest() throws IOException { exec.shutdown(); } -// @Test -// public void wrappedClientMultipartUpload() throws IOException { -// final String objectKey = appendTestSuffix("multipart-put-object-async-wrapped-client"); - -// final long fileSizeLimit = 1024 * 1024 * 100; -// final InputStream inputStream = new BoundedInputStream(fileSizeLimit); -// final InputStream objectStreamForResult = new BoundedInputStream(fileSizeLimit); - -// S3AsyncClient v3Client = S3AsyncEncryptionClient.builder() -// .kmsKeyId(KMS_KEY_ID) -// .enableMultipartPutObject(true) -// // .multipartEnabled(true) -// .enableDelayedAuthenticationMode(true) -// .cryptoProvider(PROVIDER) -// .build(); - -// Map encryptionContext = new HashMap<>(); -// encryptionContext.put("user-metadata-key", "user-metadata-value-v3-to-v3"); - -// ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); - -// CompletableFuture futurePut = v3Client.putObject(builder -> builder -// .bucket(BUCKET) -// .overrideConfiguration(withAdditionalConfiguration(encryptionContext)) -// .key(objectKey), AsyncRequestBody.fromInputStream(inputStream, fileSizeLimit, singleThreadExecutor)); -// futurePut.join(); -// singleThreadExecutor.shutdown(); - -// // Asserts -// CompletableFuture> getFuture = v3Client.getObject(builder -> builder -// .bucket(BUCKET) -// .overrideConfiguration(S3EncryptionClient.withAdditionalConfiguration(encryptionContext)) -// .key(objectKey), AsyncResponseTransformer.toBlockingInputStream()); -// ResponseInputStream output = getFuture.join(); - -// assertTrue(IOUtils.contentEquals(objectStreamForResult, output)); - -// deleteObject(BUCKET, objectKey, v3Client); -// v3Client.close(); -// } + @Test + public void wrappedClientMultipartUpload() throws IOException { + final String objectKey = appendTestSuffix("multipart-put-object-async-wrapped-client"); + + final long fileSizeLimit = 1024 * 1024 * 100; + final InputStream inputStream = new BoundedInputStream(fileSizeLimit); + final InputStream objectStreamForResult = new BoundedInputStream(fileSizeLimit); + + S3AsyncClient v3Client = S3AsyncEncryptionClient.builder() + .kmsKeyId(KMS_KEY_ID) + .enableDelayedAuthenticationMode(true) + .cryptoProvider(PROVIDER) + // .enableMultipartPutObject(true) + // .multipartEnabled(true) + .multipartConfiguration( + MultipartConfiguration.builder() + .thresholdInBytes((long)100000000) + .minimumPartSizeInBytes((long)500000) + .build() + ) + .build(); + + Map encryptionContext = new HashMap<>(); + encryptionContext.put("user-metadata-key", "user-metadata-value-v3-to-v3"); + + ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); + + CompletableFuture futurePut = v3Client.putObject(builder -> builder + .bucket(BUCKET) + .overrideConfiguration(withAdditionalConfiguration(encryptionContext)) + .key(objectKey), AsyncRequestBody.fromInputStream(inputStream, fileSizeLimit, singleThreadExecutor)); + futurePut.join(); + singleThreadExecutor.shutdown(); + + // Asserts + CompletableFuture> getFuture = v3Client.getObject(builder -> builder + .bucket(BUCKET) + .overrideConfiguration(S3EncryptionClient.withAdditionalConfiguration(encryptionContext)) + .key(objectKey), AsyncResponseTransformer.toBlockingInputStream()); + ResponseInputStream output = getFuture.join(); + + assertTrue(IOUtils.contentEquals(objectStreamForResult, output)); + + deleteObject(BUCKET, objectKey, v3Client); + v3Client.close(); + } }