diff --git a/src/examples/java/com/amazonaws/crypto/examples/v2/RestrictRegionExample.java b/src/examples/java/com/amazonaws/crypto/examples/v2/RestrictRegionExample.java
index 900fcd939..8bc489056 100644
--- a/src/examples/java/com/amazonaws/crypto/examples/v2/RestrictRegionExample.java
+++ b/src/examples/java/com/amazonaws/crypto/examples/v2/RestrictRegionExample.java
@@ -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;
@@ -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,
@@ -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
@@ -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");
+ }
+ }
}
diff --git a/src/main/java/com/amazonaws/encryptionsdk/kms/AwsKmsMrkAwareMasterKeyProvider.java b/src/main/java/com/amazonaws/encryptionsdk/kms/AwsKmsMrkAwareMasterKeyProvider.java
index e502e5b16..823ec2a9d 100644
--- a/src/main/java/com/amazonaws/encryptionsdk/kms/AwsKmsMrkAwareMasterKeyProvider.java
+++ b/src/main/java/com/amazonaws/encryptionsdk/kms/AwsKmsMrkAwareMasterKeyProvider.java
@@ -172,6 +172,10 @@ public AwsKmsMrkAwareMasterKeyProvider.Builder withCredentials(AWSCredentials cr
* This method will overwrite any credentials set using {@link
* #withCredentials(AWSCredentialsProvider)}.
*
+ *
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) {
diff --git a/src/main/java/com/amazonaws/encryptionsdk/kms/KmsMasterKeyProvider.java b/src/main/java/com/amazonaws/encryptionsdk/kms/KmsMasterKeyProvider.java
index 10aa8f985..bbc420e06 100644
--- a/src/main/java/com/amazonaws/encryptionsdk/kms/KmsMasterKeyProvider.java
+++ b/src/main/java/com/amazonaws/encryptionsdk/kms/KmsMasterKeyProvider.java
@@ -173,6 +173,10 @@ public Builder withCredentials(AWSCredentials credentials) {
*
This method will overwrite any credentials set using {@link
* #withCredentials(AWSCredentialsProvider)}.
*
+ *
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
*/
diff --git a/src/main/java/com/amazonaws/encryptionsdk/kmssdkv2/AwsKmsMrkAwareMasterKeyProvider.java b/src/main/java/com/amazonaws/encryptionsdk/kmssdkv2/AwsKmsMrkAwareMasterKeyProvider.java
index 0fcbef2e9..39b015344 100644
--- a/src/main/java/com/amazonaws/encryptionsdk/kmssdkv2/AwsKmsMrkAwareMasterKeyProvider.java
+++ b/src/main/java/com/amazonaws/encryptionsdk/kmssdkv2/AwsKmsMrkAwareMasterKeyProvider.java
@@ -131,6 +131,10 @@ public Builder customRegionalClientSupplier(RegionalClientSupplier regionalClien
*
Note: The AWS Encryption SDK for Java does not support the {@code KmsAsyncClient}
* interface.
*
+ *
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 supplier) {
diff --git a/src/main/java/com/amazonaws/encryptionsdk/kmssdkv2/KmsMasterKeyProvider.java b/src/main/java/com/amazonaws/encryptionsdk/kmssdkv2/KmsMasterKeyProvider.java
index 50923113e..10c662811 100644
--- a/src/main/java/com/amazonaws/encryptionsdk/kmssdkv2/KmsMasterKeyProvider.java
+++ b/src/main/java/com/amazonaws/encryptionsdk/kmssdkv2/KmsMasterKeyProvider.java
@@ -116,6 +116,10 @@ public Builder customRegionalClientSupplier(RegionalClientSupplier regionalClien
* Note: The AWS Encryption SDK for Java does not support the {@code KmsAsyncClient}
* interface.
*
+ *
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
*/