Skip to content

Commit e5aa201

Browse files
authored
chore: write Javadoc comments for public API (#141)
1 parent 5b95d80 commit e5aa201

File tree

3 files changed

+383
-8
lines changed

3 files changed

+383
-8
lines changed

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

+182-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import software.amazon.awssdk.services.s3.model.ObjectIdentifier;
1919
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
2020
import software.amazon.awssdk.services.s3.model.PutObjectResponse;
21+
import software.amazon.awssdk.services.s3.model.S3Request;
2122
import software.amazon.encryption.s3.internal.GetEncryptedObjectPipeline;
2223
import software.amazon.encryption.s3.internal.NoRetriesAsyncRequestBody;
2324
import software.amazon.encryption.s3.internal.PutEncryptedObjectPipeline;
@@ -41,6 +42,10 @@
4142

4243
import static software.amazon.encryption.s3.internal.ApiNameVersion.API_NAME_INTERCEPTOR;
4344

45+
/**
46+
* This client is a drop-in replacement for the S3 Async client. It will automatically encrypt objects
47+
* on putObject and decrypt objects on getObject using the provided encryption key(s).
48+
*/
4449
public class S3AsyncEncryptionClient extends DelegatingS3AsyncClient {
4550

4651
private final S3AsyncClient _wrappedClient;
@@ -60,16 +65,51 @@ private S3AsyncEncryptionClient(Builder builder) {
6065
_enableMultipartPutObject = builder._enableMultipartPutObject;
6166
}
6267

68+
/**
69+
* Creates a builder that can be used to configure and create a {@link S3AsyncEncryptionClient}.
70+
*/
6371
public static Builder builder() {
6472
return new Builder();
6573
}
6674

67-
// Helper function to attach encryption contexts to a request
75+
76+
/**
77+
* Attaches encryption context to a request. Must be used as a parameter to
78+
* {@link S3Request#overrideConfiguration()} in the request.
79+
* Encryption context can be used to enforce authentication of ciphertext.
80+
* The same encryption context used to encrypt MUST be provided on decrypt.
81+
* Encryption context is only supported with KMS keys.
82+
* @param encryptionContext the encryption context to use for the request.
83+
* @return Consumer for use in overrideConfiguration()
84+
*/
6885
public static Consumer<AwsRequestOverrideConfiguration.Builder> withAdditionalEncryptionContext(Map<String, String> encryptionContext) {
6986
return builder ->
7087
builder.putExecutionAttribute(S3EncryptionClient.ENCRYPTION_CONTEXT, encryptionContext);
7188
}
7289

90+
/**
91+
* See {@link S3AsyncClient#putObject(PutObjectRequest, AsyncRequestBody)}.
92+
* <p>
93+
* In the S3AsyncEncryptionClient, putObject encrypts the data in the requestBody as it is
94+
* written to S3.
95+
* </p>
96+
* @param putObjectRequest the request instance
97+
* @param requestBody
98+
* Functional interface that can be implemented to produce the request content in a non-blocking manner. The
99+
* size of the content is expected to be known up front. See {@link AsyncRequestBody} for specific details on
100+
* implementing this interface as well as links to precanned implementations for common scenarios like
101+
* uploading from a file.
102+
* @return A Java Future containing the result of the PutObject operation returned by the service.<br/>
103+
* The CompletableFuture returned by this method can be completed exceptionally with the following
104+
* exceptions.
105+
* <ul>
106+
* <li>SdkException Base class for all exceptions that can be thrown by the SDK (both service and client).
107+
* Can be used for catch all scenarios.</li>
108+
* <li>SdkClientException If any client side error occurs such as an IO related failure, failure to get
109+
* credentials, etc.</li>
110+
* <li>S3EncryptionClientException Base class for all encryption client specific exceptions.</li>
111+
* </ul>
112+
*/
73113
@Override
74114
public CompletableFuture<PutObjectResponse> putObject(PutObjectRequest putObjectRequest, AsyncRequestBody requestBody)
75115
throws AwsServiceException, SdkClientException {
@@ -106,6 +146,29 @@ private CompletableFuture<PutObjectResponse> multipartPutObject(PutObjectRequest
106146
return pipeline.putObject(putObjectRequest, noRetryBody);
107147
}
108148

149+
/**
150+
* See {@link S3AsyncClient#getObject(GetObjectRequest, AsyncResponseTransformer)}
151+
* <p>
152+
* In the S3AsyncEncryptionClient, getObject decrypts the data as it is read from S3.
153+
* </p>
154+
* @param getObjectRequest the request instance.
155+
* @param asyncResponseTransformer
156+
* The response transformer for processing the streaming response in a non-blocking manner. See
157+
* {@link AsyncResponseTransformer} for details on how this callback should be implemented and for links to
158+
* precanned implementations for common scenarios like downloading to a file.
159+
* @return A future to the transformed result of the AsyncResponseTransformer.<br/>
160+
* The CompletableFuture returned by this method can be completed exceptionally with the following
161+
* exceptions.
162+
* <ul>
163+
* <li>NoSuchKeyException The specified key does not exist.</li>
164+
* <li>InvalidObjectStateException Object is archived and inaccessible until restored.</li>
165+
* <li>SdkException Base class for all exceptions that can be thrown by the SDK (both service and client).
166+
* Can be used for catch all scenarios.</li>
167+
* <li>SdkClientException If any client side error occurs such as an IO related failure, failure to get
168+
* credentials, etc.</li>
169+
* <li>S3EncryptionClientException Base class for all encryption client exceptions.</li>
170+
* </ul>
171+
*/
109172
@Override
110173
public <T> CompletableFuture<T> getObject(GetObjectRequest getObjectRequest,
111174
AsyncResponseTransformer<GetObjectResponse, T> asyncResponseTransformer) {
@@ -119,6 +182,15 @@ public <T> CompletableFuture<T> getObject(GetObjectRequest getObjectRequest,
119182
return pipeline.getObject(getObjectRequest, asyncResponseTransformer);
120183
}
121184

185+
/**
186+
* See {@link S3AsyncClient#deleteObject(DeleteObjectRequest)}.
187+
* <p>
188+
* In the S3 Encryption Client, deleteObject also deletes the instruction file,
189+
* if present.
190+
* </p>
191+
* @param deleteObjectRequest the request instance
192+
* @return A Java Future containing the result of the DeleteObject operation returned by the service.
193+
*/
122194
@Override
123195
public CompletableFuture<DeleteObjectResponse> deleteObject(DeleteObjectRequest deleteObjectRequest) {
124196
final DeleteObjectRequest actualRequest = deleteObjectRequest.toBuilder()
@@ -136,6 +208,15 @@ public CompletableFuture<DeleteObjectResponse> deleteObject(DeleteObjectRequest
136208
return instructionResponse.thenApplyAsync(deletion);
137209
}
138210

211+
/**
212+
* See {@link S3AsyncClient#deleteObjects(DeleteObjectsRequest)}.
213+
* <p>
214+
* In the S3 Encryption Client, deleteObjects also deletes the instruction file(s),
215+
* if present.
216+
* </p>
217+
* @param deleteObjectsRequest the request instance
218+
* @return A Java Future containing the result of the DeleteObjects operation returned by the service.
219+
*/
139220
@Override
140221
public CompletableFuture<DeleteObjectsResponse> deleteObjects(DeleteObjectsRequest deleteObjectsRequest) throws AwsServiceException,
141222
SdkClientException {
@@ -149,6 +230,9 @@ public CompletableFuture<DeleteObjectsResponse> deleteObjects(DeleteObjectsReque
149230
.build());
150231
}
151232

233+
/**
234+
* Closes the wrapped {@link S3AsyncClient} instance.
235+
*/
152236
@Override
153237
public void close() {
154238
_wrappedClient.close();
@@ -174,6 +258,14 @@ private Builder() {
174258
}
175259

176260
/**
261+
* Specifies the wrapped client to use for the actual S3 request.
262+
* This client will be used for all async operations.
263+
* You can pass any S3AsyncClient implementation (e.g. the CRT
264+
* client), but you cannot pass an S3AsyncEncryptionClient.
265+
* @param wrappedClient the client to use for S3 operations.
266+
* @return Returns a reference to this object so that method calls can be chained together.
267+
*/
268+
/*
177269
* Note that this does NOT create a defensive clone of S3Client. Any modifications made to the wrapped
178270
* S3Client will be reflected in this Builder.
179271
*/
@@ -187,41 +279,77 @@ public Builder wrappedClient(S3AsyncClient wrappedClient) {
187279
return this;
188280
}
189281

282+
/**
283+
* Specifies the {@link CryptographicMaterialsManager} to use for managing key wrapping keys.
284+
* @param cryptoMaterialsManager the CMM to use
285+
* @return Returns a reference to this object so that method calls can be chained together.
286+
*/
190287
public Builder cryptoMaterialsManager(CryptographicMaterialsManager cryptoMaterialsManager) {
191288
this._cryptoMaterialsManager = cryptoMaterialsManager;
192289
checkKeyOptions();
193290

194291
return this;
195292
}
196293

294+
/**
295+
* Specifies the {@link Keyring} to use for key wrapping and unwrapping.
296+
* @param keyring the Keyring instance to use
297+
* @return Returns a reference to this object so that method calls can be chained together.
298+
*/
197299
public Builder keyring(Keyring keyring) {
198300
this._keyring = keyring;
199301
checkKeyOptions();
200302

201303
return this;
202304
}
203305

306+
/**
307+
* Specifies a "raw" AES key to use for key wrapping/unwrapping.
308+
* @param aesKey the AES key as a {@link SecretKey} instance
309+
* @return Returns a reference to this object so that method calls can be chained together.
310+
*/
204311
public Builder aesKey(SecretKey aesKey) {
205312
this._aesKey = aesKey;
206313
checkKeyOptions();
207314

208315
return this;
209316
}
210317

318+
/**
319+
* Specifies a "raw" RSA key pair to use for key wrapping/unwrapping.
320+
* @param rsaKeyPair the RSA key pair as a {@link KeyPair} instance
321+
* @return Returns a reference to this object so that method calls can be chained together.
322+
*/
211323
public Builder rsaKeyPair(KeyPair rsaKeyPair) {
212324
this._rsaKeyPair = new PartialRsaKeyPair(rsaKeyPair);
213325
checkKeyOptions();
214326

215327
return this;
216328
}
217329

330+
/**
331+
* Specifies a "raw" RSA key pair to use for key wrapping/unwrapping.
332+
* This option takes a {@link PartialRsaKeyPair} instance, which allows
333+
* either a public key (decryption only) or private key (encryption only)
334+
* rather than requiring both parts.
335+
* @param partialRsaKeyPair the RSA key pair as a {@link PartialRsaKeyPair} instance
336+
* @return Returns a reference to this object so that method calls can be chained together.
337+
*/
218338
public Builder rsaKeyPair(PartialRsaKeyPair partialRsaKeyPair) {
219339
this._rsaKeyPair = partialRsaKeyPair;
220340
checkKeyOptions();
221341

222342
return this;
223343
}
224344

345+
/**
346+
* Specifies a KMS key to use for key wrapping/unwrapping. Any valid KMS key
347+
* identifier (including the full ARN or an alias ARN) is permitted. When
348+
* decrypting objects, the key referred to by this KMS key identifier is
349+
* always used.
350+
* @param kmsKeyId the KMS key identifier as a {@link String} instance
351+
* @return Returns a reference to this object so that method calls can be chained together.
352+
*/
225353
public Builder kmsKeyId(String kmsKeyId) {
226354
this._kmsKeyId = kmsKeyId;
227355
checkKeyOptions();
@@ -253,31 +381,79 @@ private boolean onlyOneNonNull(Object... values) {
253381
return haveOneNonNull;
254382
}
255383

384+
/**
385+
* When set to true, decryption of objects using legacy key wrapping
386+
* modes is enabled.
387+
* @param shouldEnableLegacyWrappingAlgorithms true to enable legacy wrapping algorithms
388+
* @return Returns a reference to this object so that method calls can be chained together.
389+
*/
256390
public Builder enableLegacyWrappingAlgorithms(boolean shouldEnableLegacyWrappingAlgorithms) {
257391
this._enableLegacyWrappingAlgorithms = shouldEnableLegacyWrappingAlgorithms;
258392
return this;
259393
}
260394

395+
/**
396+
* When set to true, decryption of content using legacy encryption algorithms
397+
* is enabled. This includes use of GetObject requests with a range, as this
398+
* mode is not authenticated.
399+
* @param shouldEnableLegacyUnauthenticatedModes true to enable legacy content algorithms
400+
* @return Returns a reference to this object so that method calls can be chained together.
401+
*/
261402
public Builder enableLegacyUnauthenticatedModes(boolean shouldEnableLegacyUnauthenticatedModes) {
262403
this._enableLegacyUnauthenticatedModes = shouldEnableLegacyUnauthenticatedModes;
263404
return this;
264405
}
265406

407+
/**
408+
* When set to true, authentication of streamed objects is delayed until the
409+
* entire object is read from the stream. When this mode is enabled, the consuming
410+
* application must support a way to invalidate any data read from the stream as
411+
* the tag will not be validated until the stream is read to completion, as the
412+
* integrity of the data cannot be ensured. See the AWS Documentation for more
413+
* information.
414+
* @param shouldEnableDelayedAuthenticationMode true to enable delayed authentication
415+
* @return Returns a reference to this object so that method calls can be chained together.
416+
*/
266417
public Builder enableDelayedAuthenticationMode(boolean shouldEnableDelayedAuthenticationMode) {
267418
this._enableDelayedAuthenticationMode = shouldEnableDelayedAuthenticationMode;
268419
return this;
269420
}
270421

422+
/**
423+
* When set to true, the putObject method will use multipart upload to perform
424+
* the upload. Disabled by default.
425+
* @param _enableMultipartPutObject true enables the multipart upload implementation of putObject
426+
* @return Returns a reference to this object so that method calls can be chained together.
427+
*/
271428
public Builder enableMultipartPutObject(boolean _enableMultipartPutObject) {
272429
this._enableMultipartPutObject = _enableMultipartPutObject;
273430
return this;
274431
}
275432

433+
/**
434+
* Allows the user to pass an instance of {@link Provider} to be used
435+
* for cryptographic operations. By default, the S3 Encryption Client
436+
* will use the first compatible {@link Provider} in the chain. When this option
437+
* is used, the given provider will be used for all cryptographic operations.
438+
* If the provider is missing a required algorithm suite, e.g. AES-GCM, then
439+
* operations may fail.
440+
* Advanced option. Users who configure a {@link Provider} are responsible
441+
* for the security and correctness of the provider.
442+
* @param cryptoProvider the {@link Provider to always use}
443+
* @return Returns a reference to this object so that method calls can be chained together.
444+
*/
276445
public Builder cryptoProvider(Provider cryptoProvider) {
277446
this._cryptoProvider = cryptoProvider;
278447
return this;
279448
}
280449

450+
/**
451+
* Allows the user to pass an instance of {@link SecureRandom} to be used
452+
* for generating keys and IVs. Advanced option. Users who provide a {@link SecureRandom}
453+
* are responsible for the security and correctness of the {@link SecureRandom} implementation.
454+
* @param secureRandom the {@link SecureRandom} instance to use
455+
* @return Returns a reference to this object so that method calls can be chained together.
456+
*/
281457
public Builder secureRandom(SecureRandom secureRandom) {
282458
if (secureRandom == null) {
283459
throw new S3EncryptionClientException("SecureRandom provided to S3EncryptionClient cannot be null");
@@ -286,6 +462,11 @@ public Builder secureRandom(SecureRandom secureRandom) {
286462
return this;
287463
}
288464

465+
/**
466+
* Validates and builds the S3AsyncEncryptionClient according
467+
* to the configuration options passed to the Builder object.
468+
* @return an instance of the S3AsyncEncryptionClient
469+
*/
289470
public S3AsyncEncryptionClient build() {
290471
if (!onlyOneNonNull(_cryptoMaterialsManager, _keyring, _aesKey, _rsaKeyPair, _kmsKeyId)) {
291472
throw new S3EncryptionClientException("Exactly one must be set of: crypto materials manager, keyring, AES key, RSA key pair, KMS key id");

0 commit comments

Comments
 (0)