Skip to content

Commit ae68fb7

Browse files
authored
feat: more beacon style examples (#814)
* feat: more beacon style examples
1 parent 5662be4 commit ae68fb7

File tree

2 files changed

+214
-4
lines changed

2 files changed

+214
-4
lines changed

Diff for: Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/searchableencryption/BeaconStylesSearchableEncryptionExample.java

+110
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import software.amazon.cryptography.dbencryptionsdk.dynamodb.model.BeaconVersion;
2121
import software.amazon.cryptography.dbencryptionsdk.dynamodb.model.CompoundBeacon;
2222
import 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;
2325
import software.amazon.cryptography.dbencryptionsdk.dynamodb.model.SharedSet;
2426
import software.amazon.cryptography.dbencryptionsdk.dynamodb.model.Shared;
2527

@@ -29,6 +31,7 @@
2931
import software.amazon.cryptography.dbencryptionsdk.dynamodb.model.DynamoDbTablesEncryptionConfig;
3032
import software.amazon.cryptography.dbencryptionsdk.dynamodb.model.SearchConfig;
3133
import software.amazon.cryptography.dbencryptionsdk.dynamodb.model.EncryptedPart;
34+
import software.amazon.cryptography.dbencryptionsdk.dynamodb.model.SignedPart;
3235
import software.amazon.cryptography.dbencryptionsdk.dynamodb.model.SingleKeyStore;
3336
import software.amazon.cryptography.dbencryptionsdk.dynamodb.model.StandardBeacon;
3437
import software.amazon.cryptography.keystore.KeyStore;
@@ -60,6 +63,8 @@
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) {

Diff for: Examples/runtimes/net/src/searchableencryption/BeaconStylesSearchableEncryptionExample.cs

+104-4
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ Running this example requires access to a DDB table with the
2929
- "fruit" stores one type of fruit
3030
- "basket" stores a set of types of fruit
3131
- "dessert" stores one type of dessert
32+
- "veggies" stores a set of types of vegetable
33+
- "work_type" stores a unit inspection category
3234
3335
The example requires the following ordered input command line parameters:
3436
1. DDB table name for table to put/query data from
@@ -86,6 +88,59 @@ public static async Task PutItemQueryItemWithBeaconStyles(String branchKeyId)
8688
{
8789
Shared = new Shared { Other = "fruit" }
8890
}
91+
},
92+
93+
// The veggieBeacon allows searching on the encrypted veggies attribute
94+
// veggies is used as a Set, and therefore needs a beacon style to reflect that.
95+
new StandardBeacon
96+
{
97+
Name = "veggies",
98+
Length = 30,
99+
Style = new BeaconStyle
100+
{
101+
AsSet = new AsSet()
102+
}
103+
},
104+
105+
// The work_typeBeacon allows searching on the encrypted work_type attribute
106+
// We only use it as part of the compound work_unit beacon,
107+
// so we disable its use as a standalone beacon
108+
new StandardBeacon
109+
{
110+
Name = "work_type",
111+
Length = 30,
112+
Style = new BeaconStyle
113+
{
114+
PartOnly = new PartOnly()
115+
}
116+
}
117+
};
118+
119+
// Here we build a compound beacon from work_id and work_type
120+
// If we had tried to make a StandardBeacon from work_type, we would have seen an error
121+
// because work_type is "PartOnly"
122+
var encryptedPartList = new List<EncryptedPart>
123+
{
124+
new EncryptedPart {
125+
Name = "work_type",
126+
Prefix = "T-"
127+
}
128+
};
129+
130+
var signedPartList = new List<SignedPart> {
131+
new SignedPart {
132+
Name = "work_id",
133+
Prefix = "I-"
134+
}
135+
};
136+
137+
var compoundBeaconList = new List<CompoundBeacon>
138+
{
139+
new CompoundBeacon {
140+
Name = "work_unit",
141+
Split = ".",
142+
Encrypted = encryptedPartList,
143+
Signed = signedPartList
89144
}
90145
};
91146

@@ -107,6 +162,7 @@ public static async Task PutItemQueryItemWithBeaconStyles(String branchKeyId)
107162
new BeaconVersion
108163
{
109164
StandardBeacons = standardBeaconList,
165+
CompoundBeacons = compoundBeaconList,
110166
Version = 1, // MUST be 1
111167
KeyStore = keyStore,
112168
KeySource = new BeaconKeySource
@@ -138,10 +194,11 @@ public static async Task PutItemQueryItemWithBeaconStyles(String branchKeyId)
138194
["inspection_date"] = CryptoAction.SIGN_ONLY, // Our sort attribute must be SIGN_ONLY
139195
["dessert"] = CryptoAction.ENCRYPT_AND_SIGN, // Beaconized attributes must be encrypted
140196
["fruit"] = CryptoAction.ENCRYPT_AND_SIGN, // Beaconized attributes must be encrypted
141-
["basket"] = CryptoAction.ENCRYPT_AND_SIGN // Beaconized attributes must be encrypted
197+
["basket"] = CryptoAction.ENCRYPT_AND_SIGN, // Beaconized attributes must be encrypted
198+
["veggies"] = CryptoAction.ENCRYPT_AND_SIGN, // Beaconized attributes must be encrypted
199+
["work_type"] = CryptoAction.ENCRYPT_AND_SIGN // Beaconized attributes must be encrypted
142200
};
143201

144-
145202
// 6. Create the DynamoDb Encryption configuration for the table we will be writing to.
146203
// The beaconVersions are added to the search configuration.
147204
var tableConfigs = new Dictionary<String, DynamoDbTableEncryptionConfig>
@@ -171,7 +228,9 @@ public static async Task PutItemQueryItemWithBeaconStyles(String branchKeyId)
171228
["inspection_date"] = new AttributeValue("2023-06-13"),
172229
["dessert"] = new AttributeValue("cake"),
173230
["fruit"] = new AttributeValue("banana"),
174-
["basket"] = new AttributeValue { SS = new List<String> { "banana", "apple", "pear" } }
231+
["basket"] = new AttributeValue { SS = new List<String> { "banana", "apple", "pear" } },
232+
["veggies"] = new AttributeValue { SS = new List<String> { "beans", "carrots", "celery" } },
233+
["work_type"] = new AttributeValue("small")
175234
};
176235

177236
// 9. Create item two, specifically with "dessert == fruit", and "fruit not in basket".
@@ -181,7 +240,9 @@ public static async Task PutItemQueryItemWithBeaconStyles(String branchKeyId)
181240
["inspection_date"] = new AttributeValue("2023-06-13"),
182241
["dessert"] = new AttributeValue("orange"),
183242
["fruit"] = new AttributeValue("orange"),
184-
["basket"] = new AttributeValue { SS = new List<String> { "strawberry", "blueberry", "blackberry" } }
243+
["basket"] = new AttributeValue { SS = new List<String> { "strawberry", "blueberry", "blackberry" } },
244+
["veggies"] = new AttributeValue { SS = new List<String> { "beans", "carrots", "peas" } },
245+
["work_type"] = new AttributeValue("large")
185246
};
186247

187248
// 10. Create a new AWS SDK DynamoDb client using the DynamoDb Config above
@@ -283,5 +344,44 @@ public static async Task PutItemQueryItemWithBeaconStyles(String branchKeyId)
283344
// Validate only 1 item was returned: item2
284345
Debug.Assert(scanResponse.Items.Count == 1);
285346
Debug.Assert(scanResponse.Items[0]["work_id"].S == item2["work_id"].S);
347+
348+
349+
// 16. Test the AsSet attribute 'veggies' :
350+
// Select records where the veggies attribute holds a particular value
351+
expressionAttributeValues[":value"] = new AttributeValue { S = "peas" };
352+
353+
scanRequest = new ScanRequest
354+
{
355+
TableName = ddbTableName,
356+
FilterExpression = "contains(veggies, :value)",
357+
ExpressionAttributeValues = expressionAttributeValues
358+
};
359+
360+
scanResponse = await ddb.ScanAsync(scanRequest);
361+
// Validate query was returned successfully
362+
Debug.Assert(scanResponse.HttpStatusCode == HttpStatusCode.OK);
363+
364+
// Validate only 1 item was returned: item1
365+
Debug.Assert(scanResponse.Items.Count == 1);
366+
Debug.Assert(scanResponse.Items[0]["work_id"].S == item2["work_id"].S);
367+
368+
// 17. Test the compound beacon 'work_unit' :
369+
expressionAttributeValues[":value"] = new AttributeValue { S = "I-1.T-small" };
370+
371+
scanRequest = new ScanRequest
372+
{
373+
TableName = ddbTableName,
374+
FilterExpression = "work_unit = :value",
375+
ExpressionAttributeValues = expressionAttributeValues
376+
};
377+
378+
scanResponse = await ddb.ScanAsync(scanRequest);
379+
// Validate query was returned successfully
380+
Debug.Assert(scanResponse.HttpStatusCode == HttpStatusCode.OK);
381+
382+
// Validate only 1 item was returned: item1
383+
Debug.Assert(scanResponse.Items.Count == 1);
384+
Debug.Assert(scanResponse.Items[0]["work_id"].S == item1["work_id"].S);
385+
286386
}
287387
}

0 commit comments

Comments
 (0)