Skip to content

Commit 86d5b62

Browse files
authored
chore(JavaDocs): detail thread saftey of SDK Client Builders (#2048)
1 parent 1695a39 commit 86d5b62

File tree

6 files changed

+54
-9
lines changed

6 files changed

+54
-9
lines changed

pom.xml

+8
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,14 @@
3737
<properties>
3838
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
3939
</properties>
40+
<!-- Uncomment the next block for development with TestVectorsAwsCryptographicMaterialProviders in local mvn -->
41+
<!-- <repositories>-->
42+
<!-- <repository>-->
43+
<!-- <id>localRepository</id>-->
44+
<!-- <name>localRepository</name>-->
45+
<!-- <url>file://${user.home}/.m2/repository/</url>-->
46+
<!-- </repository>-->
47+
<!-- </repositories>-->
4048

4149
<dependencyManagement>
4250
<dependencies>

src/examples/java/com/amazonaws/crypto/examples/v2/RestrictRegionExample.java

+30-9
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import com.amazonaws.encryptionsdk.kmssdkv2.KmsMasterKeyProvider;
1616
import com.amazonaws.encryptionsdk.CommitmentPolicy;
1717
import com.amazonaws.encryptionsdk.kms.DiscoveryFilter;
18+
import com.amazonaws.encryptionsdk.kmssdkv2.RegionalClientSupplier;
1819
import software.amazon.awssdk.regions.Region;
1920
import software.amazon.awssdk.services.kms.KmsClient;
2021

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

52+
53+
5154
static void encryptAndDecrypt(final String keyName, final String partition, final String accountId, final Region region) {
5255
// Instantiate the SDK.
5356
// This builds the AwsCrypto client with the RequireEncryptRequireDecrypt commitment policy,
@@ -101,15 +104,7 @@ static void encryptAndDecrypt(final String keyName, final String partition, fina
101104
// This example also configures the AWS KMS master key provider with a Discovery Filter to limit
102105
// the attempted AWS KMS CMKs to a particular partition and account.
103106
final KmsMasterKeyProvider decryptingKeyProvider = KmsMasterKeyProvider.builder()
104-
.customRegionalClientSupplier(cmkRegion -> {
105-
if(cmkRegion.equals(region)) {
106-
// return the previously built AWS KMS client so that we do
107-
// not create a new client on every decrypt call.
108-
return kmsClient;
109-
}
110-
111-
throw new AwsCryptoException("Only " + region.id() + " is supported");
112-
})
107+
.customRegionalClientSupplier(new ARegionalClientSupplier(region, kmsClient))
113108
.buildDiscovery(discoveryFilter);
114109

115110
// 8. Decrypt the data
@@ -127,4 +122,30 @@ static void encryptAndDecrypt(final String keyName, final String partition, fina
127122
// 10. Verify that the decrypted plaintext matches the original plaintext
128123
assert Arrays.equals(decryptResult.getResult(), EXAMPLE_DATA);
129124
}
125+
126+
127+
/**
128+
* This class is Thread Safe, as both of its members are thread safe.
129+
* KMS Client Builders are NOT thread safe, and can lead to unexpected behavior if concurrently used.
130+
*/
131+
private static class ARegionalClientSupplier implements RegionalClientSupplier {
132+
private final Region region;
133+
private final KmsClient kmsClient;
134+
135+
public ARegionalClientSupplier(Region region, KmsClient kmsClient) {
136+
this.region = region;
137+
this.kmsClient = kmsClient;
138+
}
139+
140+
@Override
141+
public KmsClient getClient(Region cmkRegion) {
142+
if (cmkRegion.equals(region)) {
143+
// return the previously built AWS KMS client so that we do
144+
// not create a new client on every decrypt call.
145+
return kmsClient;
146+
}
147+
148+
throw new AwsCryptoException("Only " + region.id() + " is supported");
149+
}
150+
}
130151
}

src/main/java/com/amazonaws/encryptionsdk/kms/AwsKmsMrkAwareMasterKeyProvider.java

+4
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,10 @@ public AwsKmsMrkAwareMasterKeyProvider.Builder withCredentials(AWSCredentials cr
172172
* <p>This method will overwrite any credentials set using {@link
173173
* #withCredentials(AWSCredentialsProvider)}.
174174
*
175+
* <p>WARNING: {@link AWSKMSClientBuilder}s are NOT thread safe. If {@link KmsMasterKeyProvider}
176+
* is going to be used concurrently, a proper supplier MUST be provided, or use a {@link
177+
* #withCustomClientFactory(KmsMasterKeyProvider.RegionalClientSupplier)}
178+
*
175179
* @see KmsMasterKeyProvider.Builder#withClientBuilder(AWSKMSClientBuilder)
176180
*/
177181
public AwsKmsMrkAwareMasterKeyProvider.Builder withClientBuilder(AWSKMSClientBuilder builder) {

src/main/java/com/amazonaws/encryptionsdk/kms/KmsMasterKeyProvider.java

+4
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,10 @@ public Builder withCredentials(AWSCredentials credentials) {
173173
* <p>This method will overwrite any credentials set using {@link
174174
* #withCredentials(AWSCredentialsProvider)}.
175175
*
176+
* <p>WARNING: {@link AWSKMSClientBuilder}s are NOT thread safe. If {@link KmsMasterKeyProvider}
177+
* is going to be used concurrently, a proper supplier MUST be provided, or use a {@link
178+
* #withCustomClientFactory(KmsMasterKeyProvider.RegionalClientSupplier)}
179+
*
176180
* @param builder
177181
* @return
178182
*/

src/main/java/com/amazonaws/encryptionsdk/kmssdkv2/AwsKmsMrkAwareMasterKeyProvider.java

+4
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,10 @@ public Builder customRegionalClientSupplier(RegionalClientSupplier regionalClien
131131
* <p>Note: The AWS Encryption SDK for Java does not support the {@code KmsAsyncClient}
132132
* interface.
133133
*
134+
* <p>WARNING: {@link KmsClientBuilder}s are NOT thread safe. If {@link KmsMasterKeyProvider} is
135+
* going to be used concurrently, a proper supplier MUST be provided, or use a {@link
136+
* #customRegionalClientSupplier(RegionalClientSupplier)}
137+
*
134138
* @see KmsMasterKeyProvider.Builder#builderSupplier(Supplier)
135139
*/
136140
public Builder builderSupplier(Supplier<KmsClientBuilder> supplier) {

src/main/java/com/amazonaws/encryptionsdk/kmssdkv2/KmsMasterKeyProvider.java

+4
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,10 @@ public Builder customRegionalClientSupplier(RegionalClientSupplier regionalClien
116116
* <p>Note: The AWS Encryption SDK for Java does not support the {@code KmsAsyncClient}
117117
* interface.
118118
*
119+
* <p>WARNING: {@link KmsClientBuilder}s are NOT thread safe. If {@link KmsMasterKeyProvider} is
120+
* going to be used concurrently, a proper supplier MUST be provided, or use a {@link
121+
* #customRegionalClientSupplier(RegionalClientSupplier)}
122+
*
119123
* @param supplier Should return a new {@link KmsClientBuilder} on each invocation.
120124
* @return
121125
*/

0 commit comments

Comments
 (0)