Skip to content

chore(JavaDocs): detail thread saftey of SDK Client Builders #2048

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!-- Uncomment the next block for development with TestVectorsAwsCryptographicMaterialProviders in local mvn -->
<!-- <repositories>-->
<!-- <repository>-->
<!-- <id>localRepository</id>-->
<!-- <name>localRepository</name>-->
<!-- <url>file://${user.home}/.m2/repository/</url>-->
<!-- </repository>-->
<!-- </repositories>-->

<dependencyManagement>
<dependencies>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import com.amazonaws.encryptionsdk.kmssdkv2.KmsMasterKeyProvider;
import com.amazonaws.encryptionsdk.CommitmentPolicy;
import com.amazonaws.encryptionsdk.kms.DiscoveryFilter;
import com.amazonaws.encryptionsdk.kmssdkv2.RegionalClientSupplier;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.kms.KmsClient;

Expand Down Expand Up @@ -48,6 +49,8 @@ public static void main(final String[] args) {
encryptAndDecrypt(keyName, partition, accountId, region);
}



static void encryptAndDecrypt(final String keyName, final String partition, final String accountId, final Region region) {
// Instantiate the SDK.
// This builds the AwsCrypto client with the RequireEncryptRequireDecrypt commitment policy,
Expand Down Expand Up @@ -101,15 +104,7 @@ static void encryptAndDecrypt(final String keyName, final String partition, fina
// This example also configures the AWS KMS master key provider with a Discovery Filter to limit
// the attempted AWS KMS CMKs to a particular partition and account.
final KmsMasterKeyProvider decryptingKeyProvider = KmsMasterKeyProvider.builder()
.customRegionalClientSupplier(cmkRegion -> {
if(cmkRegion.equals(region)) {
// return the previously built AWS KMS client so that we do
// not create a new client on every decrypt call.
return kmsClient;
}

throw new AwsCryptoException("Only " + region.id() + " is supported");
})
.customRegionalClientSupplier(new ARegionalClientSupplier(region, kmsClient))
.buildDiscovery(discoveryFilter);

// 8. Decrypt the data
Expand All @@ -127,4 +122,30 @@ static void encryptAndDecrypt(final String keyName, final String partition, fina
// 10. Verify that the decrypted plaintext matches the original plaintext
assert Arrays.equals(decryptResult.getResult(), EXAMPLE_DATA);
}


/**
* This class is Thread Safe, as both of its members are thread safe.
* KMS Client Builders are NOT thread safe, and can lead to unexpected behavior if concurrently used.
*/
private static class ARegionalClientSupplier implements RegionalClientSupplier {
private final Region region;
private final KmsClient kmsClient;

public ARegionalClientSupplier(Region region, KmsClient kmsClient) {
this.region = region;
this.kmsClient = kmsClient;
}

@Override
public KmsClient getClient(Region cmkRegion) {
if (cmkRegion.equals(region)) {
// return the previously built AWS KMS client so that we do
// not create a new client on every decrypt call.
return kmsClient;
}

throw new AwsCryptoException("Only " + region.id() + " is supported");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,10 @@ public AwsKmsMrkAwareMasterKeyProvider.Builder withCredentials(AWSCredentials cr
* <p>This method will overwrite any credentials set using {@link
* #withCredentials(AWSCredentialsProvider)}.
*
* <p>WARNING: {@link AWSKMSClientBuilder}s are NOT thread safe. If {@link KmsMasterKeyProvider}
* is going to be used concurrently, a proper supplier MUST be provided, or use a {@link
* #withCustomClientFactory(KmsMasterKeyProvider.RegionalClientSupplier)}
*
* @see KmsMasterKeyProvider.Builder#withClientBuilder(AWSKMSClientBuilder)
*/
public AwsKmsMrkAwareMasterKeyProvider.Builder withClientBuilder(AWSKMSClientBuilder builder) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,10 @@ public Builder withCredentials(AWSCredentials credentials) {
* <p>This method will overwrite any credentials set using {@link
* #withCredentials(AWSCredentialsProvider)}.
*
* <p>WARNING: {@link AWSKMSClientBuilder}s are NOT thread safe. If {@link KmsMasterKeyProvider}
* is going to be used concurrently, a proper supplier MUST be provided, or use a {@link
* #withCustomClientFactory(KmsMasterKeyProvider.RegionalClientSupplier)}
*
* @param builder
* @return
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ public Builder customRegionalClientSupplier(RegionalClientSupplier regionalClien
* <p>Note: The AWS Encryption SDK for Java does not support the {@code KmsAsyncClient}
* interface.
*
* <p>WARNING: {@link KmsClientBuilder}s are NOT thread safe. If {@link KmsMasterKeyProvider} is
* going to be used concurrently, a proper supplier MUST be provided, or use a {@link
* #customRegionalClientSupplier(RegionalClientSupplier)}
*
* @see KmsMasterKeyProvider.Builder#builderSupplier(Supplier)
*/
public Builder builderSupplier(Supplier<KmsClientBuilder> supplier) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ public Builder customRegionalClientSupplier(RegionalClientSupplier regionalClien
* <p>Note: The AWS Encryption SDK for Java does not support the {@code KmsAsyncClient}
* interface.
*
* <p>WARNING: {@link KmsClientBuilder}s are NOT thread safe. If {@link KmsMasterKeyProvider} is
* going to be used concurrently, a proper supplier MUST be provided, or use a {@link
* #customRegionalClientSupplier(RegionalClientSupplier)}
*
* @param supplier Should return a new {@link KmsClientBuilder} on each invocation.
* @return
*/
Expand Down
Loading