Skip to content

Commit 7ab7fd9

Browse files
committed
Rework EncryptionContextOverride example to cleanup properly
shutdown must be called on ddb and kms to threads to exit when using mvn exec:java to run commands, otherwise maven will pause for a configurable (by default 15s) timeout to join daemon threads.
1 parent cfb0fa0 commit 7ab7fd9

File tree

1 file changed

+54
-14
lines changed

1 file changed

+54
-14
lines changed

examples/com/amazonaws/examples/EncryptionContextOverridesWithDynamoDBMapper.java

Lines changed: 54 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,18 @@
1010
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBRangeKey;
1111
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable;
1212
import com.amazonaws.services.dynamodbv2.datamodeling.encryption.DynamoDBEncryptor;
13+
import com.amazonaws.services.dynamodbv2.datamodeling.encryption.EncryptionContext;
14+
import com.amazonaws.services.dynamodbv2.datamodeling.encryption.EncryptionFlags;
1315
import com.amazonaws.services.dynamodbv2.datamodeling.encryption.providers.DirectKmsMaterialProvider;
1416
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
1517
import com.amazonaws.services.kms.AWSKMS;
1618
import com.amazonaws.services.kms.AWSKMSClientBuilder;
1719

1820
import java.security.GeneralSecurityException;
21+
import java.util.EnumSet;
1922
import java.util.HashMap;
2023
import java.util.Map;
24+
import java.util.Set;
2125

2226
import static com.amazonaws.services.dynamodbv2.datamodeling.encryption.utils.EncryptionContextOperators.overrideEncryptionContextTableNameUsingMap;
2327

@@ -27,30 +31,41 @@ public static void main(String[] args) throws GeneralSecurityException {
2731
final String region = args[1];
2832
final String encryptionContextTableName = args[2];
2933

30-
encryptRecord(cmkArn, region, encryptionContextTableName);
34+
AmazonDynamoDB ddb = null;
35+
AWSKMS kms = null;
36+
try {
37+
ddb = AmazonDynamoDBClientBuilder.standard().withRegion(region).build();
38+
kms = AWSKMSClientBuilder.standard().withRegion(region).build();
39+
encryptRecord(cmkArn, encryptionContextTableName, ddb, kms);
40+
} finally {
41+
if (ddb != null) {
42+
ddb.shutdown();
43+
}
44+
if (kms != null) {
45+
kms.shutdown();
46+
}
47+
}
3148
}
3249

3350
public static void encryptRecord(final String cmkArn,
34-
final String region,
35-
final String newEncryptionContextTableName) {
51+
final String newEncryptionContextTableName,
52+
AmazonDynamoDB ddb,
53+
AWSKMS kms) throws GeneralSecurityException {
3654
// Sample object to be encrypted
3755
ExampleItem record = new ExampleItem();
3856
record.setPartitionAttribute("is this");
3957
record.setSortAttribute(55);
4058
record.setExample("my data");
4159

4260
// Set up our configuration and clients
43-
final AmazonDynamoDB ddb = AmazonDynamoDBClientBuilder.standard().withRegion(region).build();
44-
final AWSKMS kms = AWSKMSClientBuilder.standard().withRegion(region).build();
4561
final DirectKmsMaterialProvider cmp = new DirectKmsMaterialProvider(kms, cmkArn);
46-
// Encryptor creation
4762
final DynamoDBEncryptor encryptor = DynamoDBEncryptor.getInstance(cmp);
4863

4964
Map<String, String> tableNameEncryptionContextOverrides = new HashMap<>();
5065
tableNameEncryptionContextOverrides.put("ExampleTableForEncryptionContextOverrides", newEncryptionContextTableName);
5166
tableNameEncryptionContextOverrides.put("AnotherExampleTableForEncryptionContextOverrides", "this table doesn't exist");
5267

53-
// Here we supply an operator to override the table name used in the encryption context
68+
// Supply an operator to override the table name used in the encryption context
5469
encryptor.setEncryptionContextOverrideOperator(
5570
overrideEncryptionContextTableNameUsingMap(tableNameEncryptionContextOverrides)
5671
);
@@ -62,20 +77,40 @@ public static void encryptRecord(final String cmkArn,
6277
.withSaveBehavior(DynamoDBMapperConfig.SaveBehavior.CLOBBER).build();
6378
DynamoDBMapper mapper = new DynamoDBMapper(ddb, mapperConfig, new AttributeEncryptor(encryptor));
6479

65-
System.out.println("Plaintext Record: " + record);
80+
System.out.println("Plaintext Record: " + record.toString());
6681
// Save the record to the DynamoDB table
6782
mapper.save(record);
6883

69-
// Retrieve the encrypted record (directly without decrypting) from Dynamo so we can see it in our example
84+
// Retrieve (and decrypt) it from DynamoDB
85+
ExampleItem decrypted_record = mapper.load(ExampleItem.class, "is this", 55);
86+
System.out.println("Decrypted Record: " + decrypted_record.toString());
87+
88+
// Setup new configuration to decrypt without using an overridden EncryptionContext
7089
final Map<String, AttributeValue> itemKey = new HashMap<>();
7190
itemKey.put("partition_attribute", new AttributeValue().withS("is this"));
7291
itemKey.put("sort_attribute", new AttributeValue().withN("55"));
73-
System.out.println("Encrypted Record: " + ddb.getItem("ExampleTableForEncryptionContextOverrides",
74-
itemKey).getItem());
7592

76-
// Retrieve (and decrypt) it from DynamoDB
77-
ExampleItem decrypted_record = mapper.load(ExampleItem.class, "is this", 55);
78-
System.out.println("Decrypted Record: " + decrypted_record);
93+
final EnumSet<EncryptionFlags> signOnly = EnumSet.of(EncryptionFlags.SIGN);
94+
final EnumSet<EncryptionFlags> encryptAndSign = EnumSet.of(EncryptionFlags.ENCRYPT, EncryptionFlags.SIGN);
95+
final Map<String, AttributeValue> encryptedItem = ddb.getItem("ExampleTableForEncryptionContextOverrides", itemKey)
96+
.getItem();
97+
System.out.println("Encrypted Record: " + encryptedItem);
98+
99+
Map<String, Set<EncryptionFlags>> encryptionFlags = new HashMap<>();
100+
encryptionFlags.put("partition_attribute", signOnly);
101+
encryptionFlags.put("sort_attribute", signOnly);
102+
encryptionFlags.put("example", encryptAndSign);
103+
104+
final DynamoDBEncryptor encryptorWithoutOverrides = DynamoDBEncryptor.getInstance(cmp);
105+
106+
// Decrypt the record without using an overridden EncryptionContext
107+
encryptorWithoutOverrides.decryptRecord(encryptedItem,
108+
encryptionFlags,
109+
new EncryptionContext.Builder().withHashKeyName("partition_attribute")
110+
.withRangeKeyName("sort_attribute")
111+
.withTableName(newEncryptionContextTableName)
112+
.build());
113+
System.out.printf("The example item was encrypted using the table name '%s' in the EncryptionContext%n", newEncryptionContextTableName);
79114
}
80115

81116
@DynamoDBTable(tableName = "ExampleTableForEncryptionContextOverrides")
@@ -110,6 +145,11 @@ public String getExample() {
110145
public void setExample(String example) {
111146
this.example = example;
112147
}
148+
149+
public String toString() {
150+
return String.format("{partition_attribute: %s, sort_attribute: %s, example: %s}",
151+
partitionAttribute, sortAttribute, example);
152+
}
113153
}
114154

115155
}

0 commit comments

Comments
 (0)