3030import software .amazon .awssdk .services .s3 .model .PutObjectRequest ;
3131import software .amazon .awssdk .services .s3 .model .PutObjectResponse ;
3232import software .amazon .awssdk .services .s3 .model .S3Request ;
33+ import software .amazon .awssdk .services .s3 .multipart .MultipartConfiguration ;
3334import software .amazon .encryption .s3 .internal .GetEncryptedObjectPipeline ;
35+ import software .amazon .encryption .s3 .internal .InstructionFileConfig ;
3436import software .amazon .encryption .s3 .internal .NoRetriesAsyncRequestBody ;
3537import software .amazon .encryption .s3 .internal .PutEncryptedObjectPipeline ;
3638import software .amazon .encryption .s3 .materials .AesKeyring ;
@@ -71,6 +73,7 @@ public class S3AsyncEncryptionClient extends DelegatingS3AsyncClient {
7173 private final boolean _enableDelayedAuthenticationMode ;
7274 private final boolean _enableMultipartPutObject ;
7375 private final long _bufferSize ;
76+ private InstructionFileConfig _instructionFileConfig ;
7477
7578 private S3AsyncEncryptionClient (Builder builder ) {
7679 super (builder ._wrappedClient );
@@ -81,6 +84,7 @@ private S3AsyncEncryptionClient(Builder builder) {
8184 _enableDelayedAuthenticationMode = builder ._enableDelayedAuthenticationMode ;
8285 _enableMultipartPutObject = builder ._enableMultipartPutObject ;
8386 _bufferSize = builder ._bufferSize ;
87+ _instructionFileConfig = builder ._instructionFileConfig ;
8488 }
8589
8690 /**
@@ -147,16 +151,16 @@ public CompletableFuture<PutObjectResponse> putObject(PutObjectRequest putObject
147151 }
148152
149153 private CompletableFuture <PutObjectResponse > multipartPutObject (PutObjectRequest putObjectRequest , AsyncRequestBody requestBody ) {
150- S3AsyncClient crtClient ;
154+ S3AsyncClient mpuClient ;
151155 if (_wrappedClient instanceof S3CrtAsyncClient ) {
152156 // if the wrappedClient is a CRT, use it
153- crtClient = _wrappedClient ;
157+ mpuClient = _wrappedClient ;
154158 } else {
155- // else create a default one
156- crtClient = S3AsyncClient .crtCreate ();
159+ // else create a default CRT client
160+ mpuClient = S3AsyncClient .crtCreate ();
157161 }
158162 PutEncryptedObjectPipeline pipeline = PutEncryptedObjectPipeline .builder ()
159- .s3AsyncClient (crtClient )
163+ .s3AsyncClient (mpuClient )
160164 .cryptoMaterialsManager (_cryptoMaterialsManager )
161165 .secureRandom (_secureRandom )
162166 .build ();
@@ -198,6 +202,7 @@ public <T> CompletableFuture<T> getObject(GetObjectRequest getObjectRequest,
198202 .enableLegacyUnauthenticatedModes (_enableLegacyUnauthenticatedModes )
199203 .enableDelayedAuthentication (_enableDelayedAuthenticationMode )
200204 .bufferSize (_bufferSize )
205+ .instructionFileConfig (_instructionFileConfig )
201206 .build ();
202207
203208 return pipeline .getObject (getObjectRequest , asyncResponseTransformer );
@@ -257,6 +262,7 @@ public CompletableFuture<DeleteObjectsResponse> deleteObjects(DeleteObjectsReque
257262 @ Override
258263 public void close () {
259264 _wrappedClient .close ();
265+ _instructionFileConfig .closeClient ();
260266 }
261267
262268 // This is very similar to the S3EncryptionClient builder
@@ -275,6 +281,7 @@ public static class Builder implements S3AsyncClientBuilder {
275281 private Provider _cryptoProvider = null ;
276282 private SecureRandom _secureRandom = new SecureRandom ();
277283 private long _bufferSize = -1L ;
284+ private InstructionFileConfig _instructionFileConfig = null ;
278285
279286 // generic AwsClient configuration to be shared by default clients
280287 private AwsCredentialsProvider _awsCredentialsProvider = null ;
@@ -291,8 +298,12 @@ public static class Builder implements S3AsyncClientBuilder {
291298 private S3Configuration _serviceConfiguration = null ;
292299 private Boolean _accelerate = null ;
293300 private Boolean _disableMultiRegionAccessPoints = null ;
301+ private Boolean _disableS3ExpressSessionAuth = null ;
294302 private Boolean _forcePathStyle = null ;
295303 private Boolean _useArnRegion = null ;
304+ private Boolean _crossRegionAccessEnabled = null ;
305+ // private Boolean _multipartEnabled = null;
306+ // private MultipartConfiguration _multipartConfiguration = null;
296307
297308 private Builder () {
298309 }
@@ -518,6 +529,18 @@ public Builder secureRandom(SecureRandom secureRandom) {
518529 return this ;
519530 }
520531
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+
521544 /**
522545 * The credentials provider to use for all inner clients, including KMS, if a KMS key ID is provided.
523546 * 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
696719 return this ;
697720 }
698721
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+
699732 /**
700733 * Forces this client to use path-style addressing for buckets.
701734 *
@@ -719,6 +752,35 @@ public Builder useArnRegion(Boolean useArnRegion) {
719752 return this ;
720753 }
721754
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+
722784 /**
723785 * Validates and builds the S3AsyncEncryptionClient according
724786 * to the configuration options passed to the Builder object.
@@ -751,8 +813,21 @@ public S3AsyncEncryptionClient build() {
751813 .serviceConfiguration (_serviceConfiguration )
752814 .accelerate (_accelerate )
753815 .disableMultiRegionAccessPoints (_disableMultiRegionAccessPoints )
816+ .disableS3ExpressSessionAuth (_disableS3ExpressSessionAuth )
754817 .forcePathStyle (_forcePathStyle )
755818 .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 )
756831 .build ();
757832 }
758833
0 commit comments