30
30
import software .amazon .awssdk .services .s3 .model .PutObjectRequest ;
31
31
import software .amazon .awssdk .services .s3 .model .PutObjectResponse ;
32
32
import software .amazon .awssdk .services .s3 .model .S3Request ;
33
+ import software .amazon .awssdk .services .s3 .multipart .MultipartConfiguration ;
33
34
import software .amazon .encryption .s3 .internal .GetEncryptedObjectPipeline ;
35
+ import software .amazon .encryption .s3 .internal .InstructionFileConfig ;
34
36
import software .amazon .encryption .s3 .internal .NoRetriesAsyncRequestBody ;
35
37
import software .amazon .encryption .s3 .internal .PutEncryptedObjectPipeline ;
36
38
import software .amazon .encryption .s3 .materials .AesKeyring ;
@@ -71,6 +73,7 @@ public class S3AsyncEncryptionClient extends DelegatingS3AsyncClient {
71
73
private final boolean _enableDelayedAuthenticationMode ;
72
74
private final boolean _enableMultipartPutObject ;
73
75
private final long _bufferSize ;
76
+ private InstructionFileConfig _instructionFileConfig ;
74
77
75
78
private S3AsyncEncryptionClient (Builder builder ) {
76
79
super (builder ._wrappedClient );
@@ -81,6 +84,7 @@ private S3AsyncEncryptionClient(Builder builder) {
81
84
_enableDelayedAuthenticationMode = builder ._enableDelayedAuthenticationMode ;
82
85
_enableMultipartPutObject = builder ._enableMultipartPutObject ;
83
86
_bufferSize = builder ._bufferSize ;
87
+ _instructionFileConfig = builder ._instructionFileConfig ;
84
88
}
85
89
86
90
/**
@@ -147,16 +151,16 @@ public CompletableFuture<PutObjectResponse> putObject(PutObjectRequest putObject
147
151
}
148
152
149
153
private CompletableFuture <PutObjectResponse > multipartPutObject (PutObjectRequest putObjectRequest , AsyncRequestBody requestBody ) {
150
- S3AsyncClient crtClient ;
154
+ S3AsyncClient mpuClient ;
151
155
if (_wrappedClient instanceof S3CrtAsyncClient ) {
152
156
// if the wrappedClient is a CRT, use it
153
- crtClient = _wrappedClient ;
157
+ mpuClient = _wrappedClient ;
154
158
} else {
155
- // else create a default one
156
- crtClient = S3AsyncClient .crtCreate ();
159
+ // else create a default CRT client
160
+ mpuClient = S3AsyncClient .crtCreate ();
157
161
}
158
162
PutEncryptedObjectPipeline pipeline = PutEncryptedObjectPipeline .builder ()
159
- .s3AsyncClient (crtClient )
163
+ .s3AsyncClient (mpuClient )
160
164
.cryptoMaterialsManager (_cryptoMaterialsManager )
161
165
.secureRandom (_secureRandom )
162
166
.build ();
@@ -198,6 +202,7 @@ public <T> CompletableFuture<T> getObject(GetObjectRequest getObjectRequest,
198
202
.enableLegacyUnauthenticatedModes (_enableLegacyUnauthenticatedModes )
199
203
.enableDelayedAuthentication (_enableDelayedAuthenticationMode )
200
204
.bufferSize (_bufferSize )
205
+ .instructionFileConfig (_instructionFileConfig )
201
206
.build ();
202
207
203
208
return pipeline .getObject (getObjectRequest , asyncResponseTransformer );
@@ -257,6 +262,7 @@ public CompletableFuture<DeleteObjectsResponse> deleteObjects(DeleteObjectsReque
257
262
@ Override
258
263
public void close () {
259
264
_wrappedClient .close ();
265
+ _instructionFileConfig .closeClient ();
260
266
}
261
267
262
268
// This is very similar to the S3EncryptionClient builder
@@ -275,6 +281,7 @@ public static class Builder implements S3AsyncClientBuilder {
275
281
private Provider _cryptoProvider = null ;
276
282
private SecureRandom _secureRandom = new SecureRandom ();
277
283
private long _bufferSize = -1L ;
284
+ private InstructionFileConfig _instructionFileConfig = null ;
278
285
279
286
// generic AwsClient configuration to be shared by default clients
280
287
private AwsCredentialsProvider _awsCredentialsProvider = null ;
@@ -291,8 +298,12 @@ public static class Builder implements S3AsyncClientBuilder {
291
298
private S3Configuration _serviceConfiguration = null ;
292
299
private Boolean _accelerate = null ;
293
300
private Boolean _disableMultiRegionAccessPoints = null ;
301
+ private Boolean _disableS3ExpressSessionAuth = null ;
294
302
private Boolean _forcePathStyle = null ;
295
303
private Boolean _useArnRegion = null ;
304
+ private Boolean _crossRegionAccessEnabled = null ;
305
+ // private Boolean _multipartEnabled = null;
306
+ // private MultipartConfiguration _multipartConfiguration = null;
296
307
297
308
private Builder () {
298
309
}
@@ -518,6 +529,18 @@ public Builder secureRandom(SecureRandom secureRandom) {
518
529
return this ;
519
530
}
520
531
532
+ /**
533
+ * Sets the Instruction File configuration for the S3 Encryption Client.
534
+ * The InstructionFileConfig can be used to specify an S3 client to use for retrieval of Instruction files,
535
+ * or to disable GetObject requests for the instruction file.
536
+ * @param instructionFileConfig
537
+ * @return
538
+ */
539
+ public Builder instructionFileConfig (InstructionFileConfig instructionFileConfig ) {
540
+ _instructionFileConfig = instructionFileConfig ;
541
+ return this ;
542
+ }
543
+
521
544
/**
522
545
* The credentials provider to use for all inner clients, including KMS, if a KMS key ID is provided.
523
546
* Note that if a wrapped client is configured, the wrapped client will take precedence over this option.
@@ -696,6 +719,16 @@ public Builder disableMultiRegionAccessPoints(Boolean disableMultiRegionAccessPo
696
719
return this ;
697
720
}
698
721
722
+ /**
723
+ * Disables this client's usage of Session Auth for S3Express buckets and reverts to using conventional SigV4 for
724
+ * those.
725
+ */
726
+ @ Override
727
+ public Builder disableS3ExpressSessionAuth (Boolean disableS3ExpressSessionAuth ) {
728
+ _disableS3ExpressSessionAuth = disableS3ExpressSessionAuth ;
729
+ return this ;
730
+ }
731
+
699
732
/**
700
733
* Forces this client to use path-style addressing for buckets.
701
734
*
@@ -719,6 +752,35 @@ public Builder useArnRegion(Boolean useArnRegion) {
719
752
return this ;
720
753
}
721
754
755
+ /**
756
+ * Multipart via the wrapped client is currently NOT supported by the S3 Encryption Client.
757
+ * Use the {@link this.enableMultipartPutObject()} option instead for high-level multipart uploads.
758
+ * Multipart downloads are currently NOT supported.
759
+ */
760
+ @ Override
761
+ public Builder multipartEnabled (Boolean enabled ) {
762
+ throw new UnsupportedOperationException ("The S3 Encryption Client does not support wrapped clients with automatic multipart enabled." );
763
+ }
764
+
765
+ /**
766
+ * Multipart via the wrapped client is currently NOT supported by the S3 Encryption Client.
767
+ * Use the {@link this.enableMultipartPutObject()} option instead for high-level multipart uploads.
768
+ * Multipart downloads are currently NOT supported.
769
+ */
770
+ @ Override
771
+ public Builder multipartConfiguration (MultipartConfiguration multipartConfiguration ) {
772
+ throw new UnsupportedOperationException ("The S3 Encryption Client does not support wrapped clients with automatic multipart enabled." );
773
+ }
774
+
775
+ /**
776
+ * Enables cross-region bucket access for this client
777
+ */
778
+ @ Override
779
+ public Builder crossRegionAccessEnabled (Boolean crossRegionAccessEnabled ) {
780
+ _crossRegionAccessEnabled = crossRegionAccessEnabled ;
781
+ return this ;
782
+ }
783
+
722
784
/**
723
785
* Validates and builds the S3AsyncEncryptionClient according
724
786
* to the configuration options passed to the Builder object.
@@ -751,8 +813,21 @@ public S3AsyncEncryptionClient build() {
751
813
.serviceConfiguration (_serviceConfiguration )
752
814
.accelerate (_accelerate )
753
815
.disableMultiRegionAccessPoints (_disableMultiRegionAccessPoints )
816
+ .disableS3ExpressSessionAuth (_disableS3ExpressSessionAuth )
754
817
.forcePathStyle (_forcePathStyle )
755
818
.useArnRegion (_useArnRegion )
819
+ .crossRegionAccessEnabled (_crossRegionAccessEnabled )
820
+ // If either of these are null, the AWS SDK will throw an exception.
821
+ // Since there is no way to set them without an exception being thrown,
822
+ // this would always result in an exception.
823
+ // .multipartEnabled(_multipartEnabled)
824
+ // .multipartConfiguration(_multipartConfiguration)
825
+ .build ();
826
+ }
827
+
828
+ if (_instructionFileConfig == null ) {
829
+ _instructionFileConfig = InstructionFileConfig .builder ()
830
+ .instructionFileAsyncClient (_wrappedClient )
756
831
.build ();
757
832
}
758
833
0 commit comments