Skip to content

Commit d95bd4a

Browse files
committed
chore: bump AWS SDK dependencies
1 parent 5e03842 commit d95bd4a

File tree

4 files changed

+134
-13
lines changed

4 files changed

+134
-13
lines changed

pom.xml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,22 +41,25 @@
4141
<maven.compiler.target>8</maven.compiler.target>
4242
<maven.compiler.release>8</maven.compiler.release>
4343
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
44+
<aws.java.sdk.version>2.29.0</aws.java.sdk.version>
45+
<aws.java.crt.version>0.31.3</aws.java.crt.version>
46+
<com.amazonaws.version>1.12.777</com.amazonaws.version>
4447
</properties>
4548

4649
<dependencyManagement>
4750
<dependencies>
4851
<dependency>
4952
<groupId>com.amazonaws</groupId>
5053
<artifactId>aws-java-sdk-bom</artifactId>
51-
<version>1.12.441</version>
54+
<version>${com.amazonaws.version}</version>
5255
<type>pom</type>
5356
<scope>import</scope>
5457
</dependency>
5558

5659
<dependency>
5760
<groupId>software.amazon.awssdk</groupId>
5861
<artifactId>bom</artifactId>
59-
<version>2.20.38</version>
62+
<version>${aws.java.sdk.version}</version>
6063
<optional>true</optional>
6164
<type>pom</type>
6265
<scope>import</scope>
@@ -68,21 +71,19 @@
6871
<dependency>
6972
<groupId>software.amazon.awssdk</groupId>
7073
<artifactId>s3</artifactId>
71-
<version>2.20.38</version>
7274
</dependency>
7375

7476
<dependency>
7577
<groupId>software.amazon.awssdk</groupId>
7678
<artifactId>kms</artifactId>
77-
<version>2.20.38</version>
7879
<optional>true</optional>
7980
</dependency>
8081

8182
<!-- Used when enableMultipartPutObject is configured -->
8283
<dependency>
8384
<groupId>software.amazon.awssdk.crt</groupId>
8485
<artifactId>aws-crt</artifactId>
85-
<version>0.29.24</version>
86+
<version>${aws.java.crt.version}</version>
8687
<optional>true</optional>
8788
</dependency>
8889

@@ -164,7 +165,6 @@
164165
<dependency>
165166
<groupId>software.amazon.awssdk</groupId>
166167
<artifactId>sts</artifactId>
167-
<version>2.20.38</version>
168168
<optional>true</optional>
169169
<scope>test</scope>
170170
</dependency>

src/main/java/software/amazon/encryption/s3/S3AsyncEncryptionClient.java

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
3131
import software.amazon.awssdk.services.s3.model.PutObjectResponse;
3232
import software.amazon.awssdk.services.s3.model.S3Request;
33+
import software.amazon.awssdk.services.s3.multipart.MultipartConfiguration;
3334
import software.amazon.encryption.s3.internal.GetEncryptedObjectPipeline;
3435
import software.amazon.encryption.s3.internal.NoRetriesAsyncRequestBody;
3536
import software.amazon.encryption.s3.internal.PutEncryptedObjectPipeline;
@@ -71,6 +72,7 @@ public class S3AsyncEncryptionClient extends DelegatingS3AsyncClient {
7172
private final boolean _enableDelayedAuthenticationMode;
7273
private final boolean _enableMultipartPutObject;
7374
private final long _bufferSize;
75+
private final boolean _clientMultipartEnabled;
7476

7577
private S3AsyncEncryptionClient(Builder builder) {
7678
super(builder._wrappedClient);
@@ -81,6 +83,7 @@ private S3AsyncEncryptionClient(Builder builder) {
8183
_enableDelayedAuthenticationMode = builder._enableDelayedAuthenticationMode;
8284
_enableMultipartPutObject = builder._enableMultipartPutObject;
8385
_bufferSize = builder._bufferSize;
86+
_clientMultipartEnabled = builder._multipartEnabled != null && builder._multipartEnabled;
8487
}
8588

8689
/**
@@ -147,16 +150,19 @@ public CompletableFuture<PutObjectResponse> putObject(PutObjectRequest putObject
147150
}
148151

149152
private CompletableFuture<PutObjectResponse> multipartPutObject(PutObjectRequest putObjectRequest, AsyncRequestBody requestBody) {
150-
S3AsyncClient crtClient;
151-
if (_wrappedClient instanceof S3CrtAsyncClient) {
153+
S3AsyncClient mpuClient;
154+
if (_wrappedClient instanceof S3CrtAsyncClient && !_clientMultipartEnabled) {
152155
// if the wrappedClient is a CRT, use it
153-
crtClient = _wrappedClient;
154-
} else {
155-
// else create a default one
156-
crtClient = S3AsyncClient.crtCreate();
156+
mpuClient = _wrappedClient;
157+
} else if (_clientMultipartEnabled) {
158+
mpuClient = _wrappedClient;
159+
}
160+
else {
161+
// else create a default CRT client
162+
mpuClient = S3AsyncClient.crtCreate();
157163
}
158164
PutEncryptedObjectPipeline pipeline = PutEncryptedObjectPipeline.builder()
159-
.s3AsyncClient(crtClient)
165+
.s3AsyncClient(mpuClient)
160166
.cryptoMaterialsManager(_cryptoMaterialsManager)
161167
.secureRandom(_secureRandom)
162168
.build();
@@ -291,8 +297,12 @@ public static class Builder implements S3AsyncClientBuilder {
291297
private S3Configuration _serviceConfiguration = null;
292298
private Boolean _accelerate = null;
293299
private Boolean _disableMultiRegionAccessPoints = null;
300+
private Boolean _disableS3ExpressSessionAuth = null;
294301
private Boolean _forcePathStyle = null;
295302
private Boolean _useArnRegion = null;
303+
private Boolean _crossRegionAccessEnabled = null;
304+
private Boolean _multipartEnabled = null;
305+
private MultipartConfiguration _multipartConfiguration = null;
296306

297307
private Builder() {
298308
}
@@ -696,6 +706,12 @@ public Builder disableMultiRegionAccessPoints(Boolean disableMultiRegionAccessPo
696706
return this;
697707
}
698708

709+
@Override
710+
public S3AsyncClientBuilder disableS3ExpressSessionAuth(Boolean disableS3ExpressSessionAuth) {
711+
_disableS3ExpressSessionAuth = disableS3ExpressSessionAuth;
712+
return this;
713+
}
714+
699715
/**
700716
* Forces this client to use path-style addressing for buckets.
701717
*
@@ -719,6 +735,24 @@ public Builder useArnRegion(Boolean useArnRegion) {
719735
return this;
720736
}
721737

738+
@Override
739+
public Builder multipartEnabled(Boolean enabled) {
740+
_multipartEnabled = enabled;
741+
return this;
742+
}
743+
744+
@Override
745+
public S3AsyncClientBuilder multipartConfiguration(MultipartConfiguration multipartConfiguration) {
746+
_multipartConfiguration = multipartConfiguration;
747+
return this;
748+
}
749+
750+
@Override
751+
public Builder crossRegionAccessEnabled(Boolean crossRegionAccessEnabled) {
752+
_crossRegionAccessEnabled = crossRegionAccessEnabled;
753+
return this;
754+
}
755+
722756
/**
723757
* Validates and builds the S3AsyncEncryptionClient according
724758
* to the configuration options passed to the Builder object.
@@ -737,6 +771,12 @@ public S3AsyncEncryptionClient build() {
737771
_bufferSize = DEFAULT_BUFFER_SIZE_BYTES;
738772
}
739773

774+
// The S3 Async Client has its own multipart setting,
775+
// we enforce that the S3EC multipart PutObject setting is enabled as well.
776+
if (_multipartEnabled != null && _multipartEnabled && !_enableMultipartPutObject) {
777+
throw new S3EncryptionClientException("EnableMultipartPutObject MUST be enabled when the MultipartEnabled option is set to true.");
778+
}
779+
740780
if (_wrappedClient == null) {
741781
_wrappedClient = S3AsyncClient.builder()
742782
.credentialsProvider(_awsCredentialsProvider)
@@ -751,8 +791,12 @@ public S3AsyncEncryptionClient build() {
751791
.serviceConfiguration(_serviceConfiguration)
752792
.accelerate(_accelerate)
753793
.disableMultiRegionAccessPoints(_disableMultiRegionAccessPoints)
794+
.disableS3ExpressSessionAuth(_disableS3ExpressSessionAuth)
754795
.forcePathStyle(_forcePathStyle)
755796
.useArnRegion(_useArnRegion)
797+
.crossRegionAccessEnabled(_crossRegionAccessEnabled)
798+
.multipartEnabled(_multipartEnabled)
799+
.multipartConfiguration(_multipartConfiguration)
756800
.build();
757801
}
758802

src/main/java/software/amazon/encryption/s3/S3EncryptionClient.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,8 +544,10 @@ public static class Builder implements S3BaseClientBuilder<Builder, S3Encryption
544544
private S3Configuration _serviceConfiguration = null;
545545
private Boolean _accelerate = null;
546546
private Boolean _disableMultiRegionAccessPoints = null;
547+
private Boolean _disableS3ExpressSessionAuth = null;
547548
private Boolean _forcePathStyle = null;
548549
private Boolean _useArnRegion = null;
550+
private Boolean _crossRegionAccessEnabled = null;
549551
private SdkHttpClient _httpClient = null;
550552
private SdkHttpClient.Builder _httpClientBuilder = null;
551553
private SdkAsyncHttpClient _asyncHttpClient = null;
@@ -918,6 +920,18 @@ public Builder disableMultiRegionAccessPoints(Boolean disableMultiRegionAccessPo
918920
return this;
919921
}
920922

923+
/**
924+
* Disables this client's usage of Session Auth for S3Express buckets and reverts to using conventional SigV4 for
925+
* those.
926+
*
927+
* @param disableS3ExpressSessionAuth
928+
*/
929+
@Override
930+
public Builder disableS3ExpressSessionAuth(Boolean disableS3ExpressSessionAuth) {
931+
_disableS3ExpressSessionAuth = disableS3ExpressSessionAuth;
932+
return this;
933+
}
934+
921935
/**
922936
* Forces this client to use path-style addressing for buckets.
923937
*
@@ -941,6 +955,17 @@ public Builder useArnRegion(Boolean useArnRegion) {
941955
return this;
942956
}
943957

958+
/**
959+
* Enables cross-region bucket access for this client
960+
*
961+
* @param crossRegionAccessEnabled
962+
*/
963+
@Override
964+
public Builder crossRegionAccessEnabled(Boolean crossRegionAccessEnabled) {
965+
_crossRegionAccessEnabled = crossRegionAccessEnabled;
966+
return this;
967+
}
968+
944969
/**
945970
* Sets the {@link SdkHttpClient} that the SDK service client will use to make HTTP calls. This HTTP client may be
946971
* shared between multiple SDK service clients to share a common connection pool. To create a client you must use an
@@ -1052,6 +1077,8 @@ public S3EncryptionClient build() {
10521077
.useArnRegion(_useArnRegion)
10531078
.httpClient(_httpClient)
10541079
.httpClientBuilder(_httpClientBuilder)
1080+
.disableS3ExpressSessionAuth(_disableS3ExpressSessionAuth)
1081+
.crossRegionAccessEnabled(_crossRegionAccessEnabled)
10551082
.build();
10561083
}
10571084

@@ -1070,6 +1097,9 @@ public S3EncryptionClient build() {
10701097
.useArnRegion(_useArnRegion)
10711098
.httpClient(_asyncHttpClient)
10721099
.httpClientBuilder(_asyncHttpClientBuilder)
1100+
.disableS3ExpressSessionAuth(_disableS3ExpressSessionAuth)
1101+
.crossRegionAccessEnabled(_crossRegionAccessEnabled)
1102+
// TODO: Add MPU stuff here too
10731103
.build();
10741104
}
10751105

src/test/java/software/amazon/encryption/s3/S3AsyncEncryptionClientTest.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
2121
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
2222
import software.amazon.awssdk.core.ResponseBytes;
23+
import software.amazon.awssdk.core.ResponseInputStream;
2324
import software.amazon.awssdk.core.async.AsyncRequestBody;
2425
import software.amazon.awssdk.core.async.AsyncResponseTransformer;
2526
import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
@@ -52,7 +53,9 @@
5253
import java.security.Provider;
5354
import java.security.Security;
5455
import java.util.ArrayList;
56+
import java.util.HashMap;
5557
import java.util.List;
58+
import java.util.Map;
5659
import java.util.concurrent.CompletableFuture;
5760
import java.util.concurrent.CompletionException;
5861
import java.util.concurrent.ExecutorService;
@@ -63,6 +66,7 @@
6366
import static org.junit.jupiter.api.Assertions.assertThrows;
6467
import static org.junit.jupiter.api.Assertions.assertTrue;
6568
import static org.junit.jupiter.api.Assertions.fail;
69+
import static software.amazon.encryption.s3.S3EncryptionClient.withAdditionalConfiguration;
6670
import static software.amazon.encryption.s3.utils.S3EncryptionClientTestResources.ALTERNATE_KMS_KEY;
6771
import static software.amazon.encryption.s3.utils.S3EncryptionClientTestResources.BUCKET;
6872
import static software.amazon.encryption.s3.utils.S3EncryptionClientTestResources.KMS_KEY_ID;
@@ -74,12 +78,15 @@
7478
public class S3AsyncEncryptionClientTest {
7579

7680
private static SecretKey AES_KEY;
81+
private static Provider PROVIDER;
7782

7883
@BeforeAll
7984
public static void setUp() throws NoSuchAlgorithmException {
8085
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
8186
keyGen.init(256);
8287
AES_KEY = keyGen.generateKey();
88+
Security.addProvider(new BouncyCastleProvider());
89+
PROVIDER = Security.getProvider("BC");
8390
}
8491

8592
@Test
@@ -755,4 +762,44 @@ public void tinyBufferTest() throws IOException {
755762
exec.shutdown();
756763
}
757764

765+
@Test
766+
public void wrappedClientMultipartUpload() throws IOException {
767+
final String objectKey = appendTestSuffix("multipart-put-object-async-wrapped-client");
768+
769+
final long fileSizeLimit = 1024 * 1024 * 100;
770+
final InputStream inputStream = new BoundedInputStream(fileSizeLimit);
771+
final InputStream objectStreamForResult = new BoundedInputStream(fileSizeLimit);
772+
773+
S3AsyncClient v3Client = S3AsyncEncryptionClient.builder()
774+
.kmsKeyId(KMS_KEY_ID)
775+
.enableMultipartPutObject(true)
776+
// .multipartEnabled(true)
777+
.enableDelayedAuthenticationMode(true)
778+
.cryptoProvider(PROVIDER)
779+
.build();
780+
781+
Map<String, String> encryptionContext = new HashMap<>();
782+
encryptionContext.put("user-metadata-key", "user-metadata-value-v3-to-v3");
783+
784+
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
785+
786+
CompletableFuture<PutObjectResponse> futurePut = v3Client.putObject(builder -> builder
787+
.bucket(BUCKET)
788+
.overrideConfiguration(withAdditionalConfiguration(encryptionContext))
789+
.key(objectKey), AsyncRequestBody.fromInputStream(inputStream, fileSizeLimit, singleThreadExecutor));
790+
futurePut.join();
791+
singleThreadExecutor.shutdown();
792+
793+
// Asserts
794+
CompletableFuture<ResponseInputStream<GetObjectResponse>> getFuture = v3Client.getObject(builder -> builder
795+
.bucket(BUCKET)
796+
.overrideConfiguration(S3EncryptionClient.withAdditionalConfiguration(encryptionContext))
797+
.key(objectKey), AsyncResponseTransformer.toBlockingInputStream());
798+
ResponseInputStream<GetObjectResponse> output = getFuture.join();
799+
800+
assertTrue(IOUtils.contentEquals(objectStreamForResult, output));
801+
802+
deleteObject(BUCKET, objectKey, v3Client);
803+
v3Client.close();
804+
}
758805
}

0 commit comments

Comments
 (0)