2020import software .amazon .cryptography .dbencryptionsdk .dynamodb .model .BeaconVersion ;
2121import software .amazon .cryptography .dbencryptionsdk .dynamodb .model .CompoundBeacon ;
2222import software .amazon .cryptography .dbencryptionsdk .dynamodb .model .BeaconStyle ;
23+ import software .amazon .cryptography .dbencryptionsdk .dynamodb .model .AsSet ;
24+ import software .amazon .cryptography .dbencryptionsdk .dynamodb .model .PartOnly ;
2325import software .amazon .cryptography .dbencryptionsdk .dynamodb .model .SharedSet ;
2426import software .amazon .cryptography .dbencryptionsdk .dynamodb .model .Shared ;
2527
2931import software .amazon .cryptography .dbencryptionsdk .dynamodb .model .DynamoDbTablesEncryptionConfig ;
3032import software .amazon .cryptography .dbencryptionsdk .dynamodb .model .SearchConfig ;
3133import software .amazon .cryptography .dbencryptionsdk .dynamodb .model .EncryptedPart ;
34+ import software .amazon .cryptography .dbencryptionsdk .dynamodb .model .SignedPart ;
3235import software .amazon .cryptography .dbencryptionsdk .dynamodb .model .SingleKeyStore ;
3336import software .amazon .cryptography .dbencryptionsdk .dynamodb .model .StandardBeacon ;
3437import software .amazon .cryptography .keystore .KeyStore ;
6063 - "fruit" stores one type of fruit
6164 - "basket" stores a set of types of fruit
6265 - "dessert" stores one type of dessert
66+ - "veggies" stores a set of types of vegetable
67+ - "work_type" stores a unit inspection category
6368
6469 The example requires the following ordered input command line parameters:
6570 1. DDB table name for table to put/query data from
@@ -117,6 +122,60 @@ public static void PutItemQueryItemWithBeaconStyles(String ddbTableName, String
117122 .build ();
118123 standardBeaconList .add (dessertBeacon );
119124
125+ // The veggieBeacon allows searching on the encrypted veggies attribute
126+ // veggies is used as a Set, and therefore needs a beacon style to reflect that.
127+ StandardBeacon veggieBeacon = StandardBeacon .builder ()
128+ .name ("veggies" )
129+ .length (30 )
130+ .style (
131+ BeaconStyle .builder ()
132+ .asSet (AsSet .builder ().build ())
133+ .build ()
134+ )
135+ .build ();
136+ standardBeaconList .add (veggieBeacon );
137+
138+ // The work_typeBeacon allows searching on the encrypted work_type attribute
139+ // We only use it as part of the compound work_unit beacon,
140+ // so we disable its use as a standalone beacon
141+ StandardBeacon work_typeBeacon = StandardBeacon .builder ()
142+ .name ("work_type" )
143+ .length (30 )
144+ .style (
145+ BeaconStyle .builder ()
146+ .partOnly (PartOnly .builder ().build ())
147+ .build ()
148+ )
149+ .build ();
150+ standardBeaconList .add (work_typeBeacon );
151+
152+ // Here we build a compound beacon from work_id and work_type
153+ // If we had tried to make a StandardBeacon from work_type, we would have seen an error
154+ // because work_type is "PartOnly"
155+ List <EncryptedPart > encryptedPartList = new ArrayList <>();
156+ EncryptedPart work_typePart = EncryptedPart .builder ()
157+ .name ("work_type" )
158+ .prefix ("T-" )
159+ .build ();
160+ encryptedPartList .add (work_typePart );
161+
162+ List <SignedPart > signedPartList = new ArrayList <>();
163+ SignedPart work_idPart = SignedPart .builder ()
164+ .name ("work_id" )
165+ .prefix ("I-" )
166+ .build ();
167+ signedPartList .add (work_idPart );
168+
169+ List <CompoundBeacon > compoundBeaconList = new ArrayList <>();
170+ CompoundBeacon work_unitBeacon = CompoundBeacon .builder ()
171+ .name ("work_unit" )
172+ .split ("." )
173+ .encrypted (encryptedPartList )
174+ .signed (signedPartList )
175+ .build ();
176+ compoundBeaconList .add (work_unitBeacon );
177+
178+
120179 // 2. Configure the Keystore
121180 // These are the same constructions as in the Basic example, which describes these in more detail.
122181 KeyStore keyStore = KeyStore .builder ()
@@ -135,6 +194,7 @@ public static void PutItemQueryItemWithBeaconStyles(String ddbTableName, String
135194 beaconVersions .add (
136195 BeaconVersion .builder ()
137196 .standardBeacons (standardBeaconList )
197+ .compoundBeacons (compoundBeaconList )
138198 .version (1 ) // MUST be 1
139199 .keyStore (keyStore )
140200 .keySource (BeaconKeySource .builder ()
@@ -165,6 +225,8 @@ public static void PutItemQueryItemWithBeaconStyles(String ddbTableName, String
165225 attributeActionsOnEncrypt .put ("dessert" , CryptoAction .ENCRYPT_AND_SIGN ); // Beaconized attributes must be encrypted
166226 attributeActionsOnEncrypt .put ("fruit" , CryptoAction .ENCRYPT_AND_SIGN ); // Beaconized attributes must be encrypted
167227 attributeActionsOnEncrypt .put ("basket" , CryptoAction .ENCRYPT_AND_SIGN ); // Beaconized attributes must be encrypted
228+ attributeActionsOnEncrypt .put ("veggies" , CryptoAction .ENCRYPT_AND_SIGN ); // Beaconized attributes must be encrypted
229+ attributeActionsOnEncrypt .put ("work_type" , CryptoAction .ENCRYPT_AND_SIGN ); // Beaconized attributes must be encrypted
168230
169231 // 6. Create the DynamoDb Encryption configuration for the table we will be writing to.
170232 // The beaconVersions are added to the search configuration.
@@ -199,6 +261,12 @@ public static void PutItemQueryItemWithBeaconStyles(String ddbTableName, String
199261 basket .add ("banana" );
200262 basket .add ("pear" );
201263 item1 .put ("basket" , AttributeValue .builder ().ss (basket ).build ());
264+ ArrayList <String > veggies = new ArrayList <String >();
265+ veggies .add ("beans" );
266+ veggies .add ("carrots" );
267+ veggies .add ("celery" );
268+ item1 .put ("veggies" , AttributeValue .builder ().ss (veggies ).build ());
269+ item1 .put ("work_type" , AttributeValue .builder ().s ("small" ).build ());
202270
203271 // 9. Create item two, specifically with "dessert == fruit", and "fruit not in basket".
204272 final HashMap <String , AttributeValue > item2 = new HashMap <>();
@@ -211,6 +279,12 @@ public static void PutItemQueryItemWithBeaconStyles(String ddbTableName, String
211279 basket .add ("blueberry" );
212280 basket .add ("strawberry" );
213281 item2 .put ("basket" , AttributeValue .builder ().ss (basket ).build ());
282+ veggies = new ArrayList <String >();
283+ veggies .add ("beans" );
284+ veggies .add ("carrots" );
285+ veggies .add ("peas" );
286+ item2 .put ("veggies" , AttributeValue .builder ().ss (veggies ).build ());
287+ item2 .put ("work_type" , AttributeValue .builder ().s ("large" ).build ());
214288
215289 // 10. Create the DynamoDb Encryption Interceptor
216290 DynamoDbEncryptionInterceptor encryptionInterceptor = DynamoDbEncryptionInterceptor .builder ()
@@ -316,6 +390,42 @@ public static void PutItemQueryItemWithBeaconStyles(String ddbTableName, String
316390 // Validate only 1 item was returned: item2
317391 assert scanResponse .items ().size () == 1 ;
318392 assert scanResponse .items ().get (0 ).equals (item2 );
393+
394+ // 16. Test the AsSet attribute 'veggies' :
395+ // Select records where the veggies attribute holds a particular value
396+ expressionAttributeValues .put (":value" , AttributeValue .builder ().s ("peas" ).build ());
397+
398+ scanRequest = ScanRequest .builder ()
399+ .tableName (ddbTableName )
400+ .filterExpression ("contains(veggies, :value)" )
401+ .expressionAttributeValues (expressionAttributeValues )
402+ .build ();
403+
404+ scanResponse = ddb .scan (scanRequest );
405+ // Validate query was returned successfully
406+ assert 200 == scanResponse .sdkHttpResponse ().statusCode ();
407+
408+ // Validate only 1 item was returned: item1
409+ assert scanResponse .items ().size () == 1 ;
410+ assert scanResponse .items ().get (0 ).equals (item2 );
411+
412+ // 17. Test the compound beacon 'work_unit' :
413+ expressionAttributeValues .put (":value" , AttributeValue .builder ().s ("I-1.T-small" ).build ());
414+
415+ scanRequest = ScanRequest .builder ()
416+ .tableName (ddbTableName )
417+ .filterExpression ("work_unit = :value" )
418+ .expressionAttributeValues (expressionAttributeValues )
419+ .build ();
420+
421+ scanResponse = ddb .scan (scanRequest );
422+ // Validate query was returned successfully
423+ assert 200 == scanResponse .sdkHttpResponse ().statusCode ();
424+
425+ // Validate only 1 item was returned: item1
426+ assert scanResponse .items ().size () == 1 ;
427+ assert scanResponse .items ().get (0 ).equals (item1 );
428+
319429}
320430
321431 public static void main (final String [] args ) {
0 commit comments