diff --git a/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/searchableencryption/CompoundBeaconSearchableEncryptionExample.java b/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/searchableencryption/CompoundBeaconSearchableEncryptionExample.java index e148d9d7e..fd22569c0 100644 --- a/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/searchableencryption/CompoundBeaconSearchableEncryptionExample.java +++ b/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/searchableencryption/CompoundBeaconSearchableEncryptionExample.java @@ -1,6 +1,7 @@ package software.amazon.cryptography.examples.searchableencryption; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.HashMap; import java.util.Map; @@ -17,16 +18,19 @@ import software.amazon.awssdk.services.dynamodb.model.QueryResponse; import software.amazon.awssdk.services.kms.KmsClient; import software.amazon.cryptography.dbencryptionsdk.dynamodb.model.BeaconKeySource; +import software.amazon.cryptography.dbencryptionsdk.dynamodb.model.BeaconStyle; import software.amazon.cryptography.dbencryptionsdk.dynamodb.model.BeaconVersion; import software.amazon.cryptography.dbencryptionsdk.dynamodb.model.CompoundBeacon; import software.amazon.cryptography.dbencryptionsdk.dynamodb.model.Constructor; import software.amazon.cryptography.dbencryptionsdk.dynamodb.model.ConstructorPart; import software.amazon.cryptography.dbencryptionsdk.dynamodb.model.DynamoDbTableEncryptionConfig; import software.amazon.cryptography.dbencryptionsdk.dynamodb.model.DynamoDbTablesEncryptionConfig; -import software.amazon.cryptography.dbencryptionsdk.dynamodb.model.SearchConfig; import software.amazon.cryptography.dbencryptionsdk.dynamodb.model.EncryptedPart; +import software.amazon.cryptography.dbencryptionsdk.dynamodb.model.PartOnly; +import software.amazon.cryptography.dbencryptionsdk.dynamodb.model.SearchConfig; import software.amazon.cryptography.dbencryptionsdk.dynamodb.model.SingleKeyStore; import software.amazon.cryptography.dbencryptionsdk.dynamodb.model.StandardBeacon; + import software.amazon.cryptography.dbencryptionsdk.dynamodb.transforms.DynamoDbEncryptionTransforms; import software.amazon.cryptography.dbencryptionsdk.dynamodb.transforms.model.ResolveAttributesInput; import software.amazon.cryptography.dbencryptionsdk.dynamodb.transforms.model.ResolveAttributesOutput; @@ -87,45 +91,65 @@ public static void PutItemQueryItemWithCompoundBeacon(String ddbTableName, Strin // While we will not directly query against these beacons, // you must create standard beacons on encrypted fields // that we wish to use in compound beacons. - List standardBeaconList = new ArrayList<>(); - StandardBeacon last4Beacon = StandardBeacon.builder() - .name("inspector_id_last4") - .length(10) - .build(); - standardBeaconList.add(last4Beacon); - StandardBeacon unitBeacon = StandardBeacon.builder() - .name("unit") - .length(30) - .build(); - standardBeaconList.add(unitBeacon); + // We mark them both as PartOnly to enforce the fact that + // we will not directly query against these beacons. + List standardBeaconList = Arrays.asList( + StandardBeacon.builder() + .name("inspector_id_last4") + .length(10) + .style(BeaconStyle.builder().partOnly(PartOnly.builder().build()).build()) + .build(), + StandardBeacon.builder() + .name("unit") + .length(30) + .style(BeaconStyle.builder().partOnly(PartOnly.builder().build()).build()) + .build() + ); // 2. Define encrypted parts. // Encrypted parts define the beacons that can be used to construct a compound beacon, // and how the compound beacon prefixes those beacon values. - List encryptedPartList = new ArrayList<>(); // A encrypted part must receive: // - name: Name of a standard beacon // - prefix: Any string. This is plaintext that prefixes the beaconized value in the compound beacon. // Prefixes must be unique across the configuration, and must not be a prefix of another prefix; // i.e. for all configured prefixes, the first N characters of a prefix must not equal another prefix. // In practice, it is suggested to have a short value distinguishable from other parts served on the prefix. - // For this example, we will choose "L-" as the prefix for "Last 4 digits of inspector ID". - // With this prefix and the standard beacon's bit length definition (10), the beaconized - // version of the inspector ID's last 4 digits will appear as - // `L-000` to `L-3ff` inside a compound beacon. - EncryptedPart last4EncryptedPart = EncryptedPart.builder() + + List encryptedPartList = Arrays.asList( + // For this example, we will choose "L-" as the prefix for "Last 4 digits of inspector ID". + // With this prefix and the standard beacon's bit length definition (10), the beaconized + // version of the inspector ID's last 4 digits will appear as + // `L-000` to `L-3ff` inside a compound beacon. + EncryptedPart.builder() + .name("inspector_id_last4") + .prefix("L-") + .build(), + + // For this example, we will choose "U-" as the prefix for "unit". + // With this prefix and the standard beacon's bit length definition (30), a unit beacon will appear + // as `U-00000000` to `U-3fffffff` inside a compound beacon. + EncryptedPart.builder() + .name("unit") + .prefix("U-") + .build() + ); + + List constructorParts = Arrays.asList( + ConstructorPart.builder() .name("inspector_id_last4") - .prefix("L-") - .build(); - encryptedPartList.add(last4EncryptedPart); - // For this example, we will choose "U-" as the prefix for "unit". - // With this prefix and the standard beacon's bit length definition (30), a unit beacon will appear - // as `U-00000000` to `U-3fffffff` inside a compound beacon. - EncryptedPart unitEncryptedPart = EncryptedPart.builder() + .required(true) + .build(), + ConstructorPart.builder() + // This name comes from the "EmployeeID" standard beacon. .name("unit") - .prefix("U-") - .build(); - encryptedPartList.add(unitEncryptedPart); + .required(true) + .build() + ); + List constructors = Arrays.asList( + Constructor.builder() + .parts(constructorParts) + .build()); // 3. Define compound beacon. // A compound beacon allows one to serve multiple beacons or attributes from a single index. @@ -146,13 +170,13 @@ public static void PutItemQueryItemWithCompoundBeacon(String ddbTableName, Strin // - signed: A list of signed parts, i.e. plaintext attributes. This would be provided if we // wanted to use plaintext values as part of constructing our compound beacon. We do not // provide this here; see the Complex example for an example. - List compoundBeaconList = new ArrayList<>(); - CompoundBeacon last4UnitCompoundBeacon = CompoundBeacon.builder() - .name("last4UnitCompound") - .split(".") - .encrypted(encryptedPartList) - .build(); - compoundBeaconList.add(last4UnitCompoundBeacon); + List compoundBeaconList = Arrays.asList( + CompoundBeacon.builder() + .name("last4UnitCompound") + .constructors(constructors) + .split(".") + .build() + ); // 4. Configure the Keystore // These are the same constructions as in the Basic example, which describes these in more detail. @@ -169,9 +193,9 @@ public static void PutItemQueryItemWithCompoundBeacon(String ddbTableName, Strin // 5. Create BeaconVersion. // This is similar to the Basic example, except we have also provided a compoundBeaconList. // We must also continue to provide all of the standard beacons that compose a compound beacon list. - List beaconVersions = new ArrayList<>(); - beaconVersions.add( + List beaconVersions = Arrays.asList( BeaconVersion.builder() + .encryptedParts(encryptedPartList) .standardBeacons(standardBeaconList) .compoundBeacons(compoundBeaconList) .version(1) // MUST be 1 diff --git a/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/searchableencryption/complexexample/BeaconConfig.java b/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/searchableencryption/complexexample/BeaconConfig.java index 3e0170a7b..291ff4132 100644 --- a/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/searchableencryption/complexexample/BeaconConfig.java +++ b/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/searchableencryption/complexexample/BeaconConfig.java @@ -1,6 +1,7 @@ package software.amazon.cryptography.examples.searchableencryption.complexexample; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -65,229 +66,166 @@ public static DynamoDbClient SetupBeaconConfig(String ddbTableName, String branc // The BasicSearchableEncryptionExample gives a more thorough consideration of beacon length. // For production applications, one should always exercise rigor when deciding beacon length, including // examining population size and considering performance. - StandardBeacon employeeIDStandardBeacon = StandardBeacon.builder() - .name("EmployeeID") - .length(4) - .build(); - StandardBeacon ticketNumberStandardBeacon = StandardBeacon.builder() - .name("TicketNumber") - .length(4) - .build(); - StandardBeacon projectNameStandardBeacon = StandardBeacon.builder() - .name("ProjectName") - .length(4) - .build(); - StandardBeacon employeeEmailStandardBeacon = StandardBeacon.builder() - .name("EmployeeEmail") - .length(4) - .build(); - StandardBeacon creatorEmailStandardBeacon = StandardBeacon.builder() - .name("CreatorEmail") - .length(4) - .build(); - StandardBeacon projectStatusStandardBeacon = StandardBeacon.builder() - .name("ProjectStatus") - .length(4) - .build(); - StandardBeacon organizerEmailStandardBeacon = StandardBeacon.builder() - .name("OrganizerEmail") - .length(4) - .build(); - StandardBeacon managerEmailStandardBeacon = StandardBeacon.builder() - .name("ManagerEmail") - .length(4) - .build(); - StandardBeacon assigneeEmailStandardBeacon = StandardBeacon.builder() - .name("AssigneeEmail") - .length(4) - .build(); - StandardBeacon cityStandardBeacon = StandardBeacon.builder() - .name("City") - .loc("Location.City") - .length(4) - .build(); - StandardBeacon severityStandardBeacon = StandardBeacon.builder() - .name("Severity") - .length(4) - .build(); - StandardBeacon buildingStandardBeacon = StandardBeacon.builder() - .name("Building") - .loc("Location.Building") - .length(4) - .build(); - StandardBeacon floorStandardBeacon = StandardBeacon.builder() - .name("Floor") - .loc("Location.Floor") - .length(4) - .build(); - StandardBeacon roomStandardBeacon = StandardBeacon.builder() - .name("Room") - .loc("Location.Room") - .length(4) - .build(); - StandardBeacon deskStandardBeacon = StandardBeacon.builder() - .name("Desk") - .loc("Location.Desk") - .length(4) - .build(); - - List standardBeaconList = new ArrayList<>(); - standardBeaconList.add(employeeIDStandardBeacon); - standardBeaconList.add(ticketNumberStandardBeacon); - standardBeaconList.add(projectNameStandardBeacon); - standardBeaconList.add(employeeEmailStandardBeacon); - standardBeaconList.add(creatorEmailStandardBeacon); - standardBeaconList.add(projectStatusStandardBeacon); - standardBeaconList.add(organizerEmailStandardBeacon); - standardBeaconList.add(managerEmailStandardBeacon); - standardBeaconList.add(assigneeEmailStandardBeacon); - standardBeaconList.add(cityStandardBeacon); - standardBeaconList.add(severityStandardBeacon); - standardBeaconList.add(buildingStandardBeacon); - standardBeaconList.add(floorStandardBeacon); - standardBeaconList.add(roomStandardBeacon); - standardBeaconList.add(deskStandardBeacon); + List standardBeaconList = Arrays.asList( + StandardBeacon.builder() + .name("EmployeeID") + .length(4) + .build(), + StandardBeacon.builder() + .name("TicketNumber") + .length(4) + .build(), + StandardBeacon.builder() + .name("ProjectName") + .length(4) + .build(), + StandardBeacon.builder() + .name("EmployeeEmail") + .length(4) + .build(), + StandardBeacon.builder() + .name("CreatorEmail") + .length(4) + .build(), + StandardBeacon.builder() + .name("ProjectStatus") + .length(4) + .build(), + StandardBeacon.builder() + .name("OrganizerEmail") + .length(4) + .build(), + StandardBeacon.builder() + .name("ManagerEmail") + .length(4) + .build(), + StandardBeacon.builder() + .name("AssigneeEmail") + .length(4) + .build(), + StandardBeacon.builder() + .name("City") + .loc("Location.City") + .length(4) + .build(), + StandardBeacon.builder() + .name("Severity") + .length(4) + .build(), + StandardBeacon.builder() + .name("Building") + .loc("Location.Building") + .length(4) + .build(), + StandardBeacon.builder() + .name("Floor") + .loc("Location.Floor") + .length(4) + .build(), + StandardBeacon.builder() + .name("Room") + .loc("Location.Room") + .length(4) + .build(), + StandardBeacon.builder() + .name("Desk") + .loc("Location.Desk") + .length(4) + .build() + ); // 3. Define encrypted parts // Note that some of the prefixes are modified from the suggested prefixes in Demo.md. // This is because all prefixes must be unique in a configuration. // Encrypted parts are described in more detail in the CompoundBeaconSearcbaleEncryptionExample. - EncryptedPart employeeIDEncryptedPart = EncryptedPart.builder() - .name("EmployeeID") - .prefix("E-") - .build(); - EncryptedPart ticketNumberEncryptedPart = EncryptedPart.builder() - .name("TicketNumber") - .prefix("T-") - .build(); - EncryptedPart projectNameEncryptedPart = EncryptedPart.builder() - .name("ProjectName") - .prefix("P-") - .build(); - EncryptedPart employeeEmailEncryptedPart = EncryptedPart.builder() - .name("EmployeeEmail") - .prefix("EE-") - .build(); - EncryptedPart creatorEmailEncryptedPart = EncryptedPart.builder() - .name("CreatorEmail") - .prefix("CE-") - .build(); - EncryptedPart projectStatusEncryptedPart = EncryptedPart.builder() - .name("ProjectStatus") - .prefix("PSts-") - .build(); - EncryptedPart organizerEmailEncryptedPart = EncryptedPart.builder() - .name("OrganizerEmail") - .prefix("OE-") - .build(); - EncryptedPart managerEmailEncryptedPart = EncryptedPart.builder() - .name("ManagerEmail") - .prefix("ME-") - .build(); - EncryptedPart assigneeEmailEncryptedPart = EncryptedPart.builder() - .name("AssigneeEmail") - .prefix("AE-") - .build(); - EncryptedPart cityEncryptedPart = EncryptedPart.builder() - .name("City") - .prefix("C-") - .build(); - EncryptedPart severityEncryptedPart = EncryptedPart.builder() - .name("Severity") - .prefix("S-") - .build(); - EncryptedPart buildingEncryptedPart = EncryptedPart.builder() - .name("Building") - .prefix("B-") - .build(); - EncryptedPart floorEncryptedPart = EncryptedPart.builder() - .name("Floor") - .prefix("F-") - .build(); - EncryptedPart roomEncryptedPart = EncryptedPart.builder() - .name("Room") - .prefix("R-") - .build(); - EncryptedPart deskEncryptedPart = EncryptedPart.builder() - .name("Desk") - .prefix("D-") - .build(); + List encryptedPartList = Arrays.asList( + EncryptedPart.builder() + .name("EmployeeID") + .prefix("E-") + .build(), + EncryptedPart.builder() + .name("TicketNumber") + .prefix("T-") + .build(), + EncryptedPart.builder() + .name("ProjectName") + .prefix("P-") + .build(), + EncryptedPart.builder() + .name("EmployeeEmail") + .prefix("EE-") + .build(), + EncryptedPart.builder() + .name("CreatorEmail") + .prefix("CE-") + .build(), + EncryptedPart.builder() + .name("ProjectStatus") + .prefix("PSts-") + .build(), + EncryptedPart.builder() + .name("OrganizerEmail") + .prefix("OE-") + .build(), + EncryptedPart.builder() + .name("ManagerEmail") + .prefix("ME-") + .build(), + EncryptedPart.builder() + .name("AssigneeEmail") + .prefix("AE-") + .build(), + EncryptedPart.builder() + .name("City") + .prefix("C-") + .build(), + EncryptedPart.builder() + .name("Severity") + .prefix("S-") + .build(), + EncryptedPart.builder() + .name("Building") + .prefix("B-") + .build(), + EncryptedPart.builder() + .name("Floor") + .prefix("F-") + .build(), + EncryptedPart.builder() + .name("Room") + .prefix("R-") + .build(), + EncryptedPart.builder() + .name("Desk") + .prefix("D-") + .build() + ); // 4. Define signed parts. // These are unencrypted attributes we would like to use in beacon queries. // In this example, all of these represent dates or times. // Keeping these attributes unencrypted allows us to use them in comparison-based queries. If a signed // part is the first part in a compound beacon, then that part can be used in comparison for sorting. - SignedPart ticketModTimeSignedPart = SignedPart.builder() - .name("TicketModTime") - .prefix("M-") - .build(); - SignedPart meetingStartSignedPart = SignedPart.builder() - .name("MeetingStart") - .prefix("MS-") - .build(); - SignedPart timeCardStartSignedPart = SignedPart.builder() - .name("TimeCardStart") - .prefix("TC-") - .build(); - SignedPart projectStartSignedPart = SignedPart.builder() - .name("ProjectStart") - .prefix("PS-") - .build(); - - // 5. Create lists of encrypted and signed parts for each GSI key - List pk0EncryptedPartList = new ArrayList<>(); - pk0EncryptedPartList.add(employeeIDEncryptedPart); - pk0EncryptedPartList.add(ticketNumberEncryptedPart); - pk0EncryptedPartList.add(projectNameEncryptedPart); - pk0EncryptedPartList.add(buildingEncryptedPart); - - List sk0EncryptedPartList = new ArrayList<>(); - sk0EncryptedPartList.add(employeeIDEncryptedPart); - sk0EncryptedPartList.add(floorEncryptedPart); - sk0EncryptedPartList.add(roomEncryptedPart); - sk0EncryptedPartList.add(projectNameEncryptedPart); - sk0EncryptedPartList.add(employeeEmailEncryptedPart); - - List sk0SignedPartList = new ArrayList<>(); - sk0SignedPartList.add(timeCardStartSignedPart); - sk0SignedPartList.add(ticketModTimeSignedPart); - sk0SignedPartList.add(meetingStartSignedPart); - - List pk1EncryptedPartList = new ArrayList<>(); - pk1EncryptedPartList.add(creatorEmailEncryptedPart); - pk1EncryptedPartList.add(projectStatusEncryptedPart); - pk1EncryptedPartList.add(organizerEmailEncryptedPart); - pk1EncryptedPartList.add(employeeEmailEncryptedPart); - - List sk1EncryptedPartList = new ArrayList<>(); - sk1EncryptedPartList.add(floorEncryptedPart); - sk1EncryptedPartList.add(roomEncryptedPart); - sk1EncryptedPartList.add(employeeIDEncryptedPart); - - List sk1SignedPartList = new ArrayList<>(); - sk1SignedPartList.add(timeCardStartSignedPart); - sk1SignedPartList.add(ticketModTimeSignedPart); - sk1SignedPartList.add(meetingStartSignedPart); - sk1SignedPartList.add(projectStartSignedPart); - - List pk2EncryptedPartList = new ArrayList<>(); - pk2EncryptedPartList.add(managerEmailEncryptedPart); - pk2EncryptedPartList.add(assigneeEmailEncryptedPart); - - List pk3EncryptedPartList = new ArrayList<>(); - pk3EncryptedPartList.add(cityEncryptedPart); - pk3EncryptedPartList.add(severityEncryptedPart); - - List sk3EncryptedPartList = new ArrayList<>(); - sk3EncryptedPartList.add(buildingEncryptedPart); - sk3EncryptedPartList.add(floorEncryptedPart); - sk3EncryptedPartList.add(deskEncryptedPart); - - List sk3SignedPartList = new ArrayList<>(); - sk3SignedPartList.add(ticketModTimeSignedPart); - - // 6. Create constructor parts. + List signedPartList = Arrays.asList( + SignedPart.builder() + .name("TicketModTime") + .prefix("M-") + .build(), + SignedPart.builder() + .name("MeetingStart") + .prefix("MS-") + .build(), + SignedPart.builder() + .name("TimeCardStart") + .prefix("TC-") + .build(), + SignedPart.builder() + .name("ProjectStart") + .prefix("PS-") + .build() + ); + + // 5. Create constructor parts. // Constructor parts are used to assemble constructors (constructors described more in next step). // For each attribute that will be used in a constructor, there must be a corresponding constructor part. // A constructor part must receive: @@ -374,7 +312,7 @@ public static DynamoDbClient SetupBeaconConfig(String ddbTableName, String branc .required(true) .build(); - // 7. Define constructors + // 6. Define constructors // Constructors define how encrypted and signed parts are assembled into compound beacons. // The constructors below are based off of the "PK Constructors", "SK constructors", etc. sections in Demo.md. @@ -382,34 +320,24 @@ public static DynamoDbClient SetupBeaconConfig(String ddbTableName, String branc // If an item has an attribute with name "EmployeeID", it will match this constructor. // If this is the first matching constructor in the constructor list (constructor list described more below), // the compound beacon will use this constructor, and the compound beacon will be written as `E-X`. - List employeeIdConstructorPartList = new ArrayList<>(); - employeeIdConstructorPartList.add(employeeIdConstructorPart); Constructor employeeIdConstructor = Constructor.builder() - .parts(employeeIdConstructorPartList) + .parts(Arrays.asList(employeeIdConstructorPart)) .build(); - List ticketNumberConstructorPartList = new ArrayList<>(); - ticketNumberConstructorPartList.add(ticketNumberConstructorPart); Constructor ticketNumberConstructor = Constructor.builder() - .parts(ticketNumberConstructorPartList) + .parts(Arrays.asList(ticketNumberConstructorPart)) .build(); - List projectNameConstructorPartList = new ArrayList<>(); - projectNameConstructorPartList.add(projectNameConstructorPart); Constructor projectNameConstructor = Constructor.builder() - .parts(projectNameConstructorPartList) + .parts(Arrays.asList(projectNameConstructorPart)) .build(); - List ticketModTimeConstructorPartList = new ArrayList(); - ticketModTimeConstructorPartList.add(ticketModTimeConstructorPart); Constructor ticketModTimeConstructor = Constructor.builder() - .parts(ticketModTimeConstructorPartList) + .parts(Arrays.asList(ticketModTimeConstructorPart)) .build(); - List buildingConstructorPartList = new ArrayList(); - buildingConstructorPartList.add(buildingConstructorPart); Constructor buildingConstructor = Constructor.builder() - .parts(buildingConstructorPartList) + .parts(Arrays.asList(buildingConstructorPart)) .build(); // This constructor requires all of "MeetingStart", "Location.Floor", and "Location.Room" attributes. @@ -419,90 +347,59 @@ public static DynamoDbClient SetupBeaconConfig(String ddbTableName, String branc // In a constructor with multiple constructor parts, the order the constructor parts are added to // the constructor part list defines how the compound beacon is written. // We can rearrange the beacon parts by changing the order the constructors were added to the list. - List meetingStartFloorRoomConstructorPartList = new ArrayList(); - meetingStartFloorRoomConstructorPartList.add(meetingStartConstructorPart); - meetingStartFloorRoomConstructorPartList.add(floorConstructorPart); - meetingStartFloorRoomConstructorPartList.add(roomConstructorPart); Constructor meetingStartFloorRoomConstructor = Constructor.builder() - .parts(meetingStartFloorRoomConstructorPartList) + .parts(Arrays.asList(meetingStartConstructorPart, floorConstructorPart, roomConstructorPart)) .build(); - List timeCardStartEmployeeEmailConstructorPartList = new ArrayList(); - timeCardStartEmployeeEmailConstructorPartList.add(timeCardStartConstructorPart); - timeCardStartEmployeeEmailConstructorPartList.add(employeeEmailConstructorPart); Constructor timeCardStartEmployeeEmailConstructor = Constructor.builder() - .parts(timeCardStartEmployeeEmailConstructorPartList) + .parts(Arrays.asList(timeCardStartConstructorPart, employeeEmailConstructorPart)) .build(); - List timeCardStartConstructorPartList = new ArrayList(); - timeCardStartConstructorPartList.add(timeCardStartConstructorPart); Constructor timeCardStartConstructor = Constructor.builder() - .parts(timeCardStartConstructorPartList) + .parts(Arrays.asList(timeCardStartConstructorPart)) .build(); - List creatorEmailConstructorPartList = new ArrayList(); - creatorEmailConstructorPartList.add(creatorEmailConstructorPart); Constructor creatorEmailConstructor = Constructor.builder() - .parts(creatorEmailConstructorPartList) + .parts(Arrays.asList(creatorEmailConstructorPart)) .build(); - List projectStatusConstructorPartList = new ArrayList(); - projectStatusConstructorPartList.add(projectStatusConstructorPart); Constructor projectStatusConstructor = Constructor.builder() - .parts(projectStatusConstructorPartList) + .parts(Arrays.asList(projectStatusConstructorPart)) .build(); - List employeeEmailConstructorPartList = new ArrayList(); - employeeEmailConstructorPartList.add(employeeEmailConstructorPart); Constructor employeeEmailConstructor = Constructor.builder() - .parts(employeeEmailConstructorPartList) + .parts(Arrays.asList(employeeEmailConstructorPart)) .build(); - List organizerEmailConstructorPartList = new ArrayList(); - organizerEmailConstructorPartList.add(organizerEmailConstructorPart); Constructor organizerEmailConstructor = Constructor.builder() - .parts(organizerEmailConstructorPartList) + .parts(Arrays.asList(organizerEmailConstructorPart)) .build(); - List projectStartConstructorPartList = new ArrayList(); - projectStartConstructorPartList.add(projectStartConstructorPart); Constructor projectStartConstructor = Constructor.builder() - .parts(projectStartConstructorPartList) + .parts(Arrays.asList(projectStartConstructorPart)) .build(); - List managerEmailConstructorPartList = new ArrayList(); - managerEmailConstructorPartList.add(managerEmailConstructorPart); Constructor managerEmailConstructor = Constructor.builder() - .parts(managerEmailConstructorPartList) + .parts(Arrays.asList(managerEmailConstructorPart)) .build(); - List assigneeEmailConstructorPartList = new ArrayList(); - assigneeEmailConstructorPartList.add(assigneeEmailConstructorPart); Constructor assigneeEmailConstructor = Constructor.builder() - .parts(assigneeEmailConstructorPartList) + .parts(Arrays.asList(assigneeEmailConstructorPart)) .build(); - List cityConstructorPartList = new ArrayList(); - cityConstructorPartList.add(cityConstructorPart); Constructor cityConstructor = Constructor.builder() - .parts(cityConstructorPartList) + .parts(Arrays.asList(cityConstructorPart)) .build(); - List severityConstructorPartList = new ArrayList(); - severityConstructorPartList.add(severityConstructorPart); Constructor severityConstructor = Constructor.builder() - .parts(severityConstructorPartList) + .parts(Arrays.asList(severityConstructorPart)) .build(); - List buildingFloorDeskConstructorPartList = new ArrayList(); - buildingFloorDeskConstructorPartList.add(buildingConstructorPart); - buildingFloorDeskConstructorPartList.add(floorConstructorPart); - buildingFloorDeskConstructorPartList.add(deskConstructorPart); Constructor buildingFloorDeskConstructor = Constructor.builder() - .parts(buildingFloorDeskConstructorPartList) + .parts(Arrays.asList(buildingConstructorPart, floorConstructorPart, deskConstructorPart)) .build(); - // 5. Add constructors to the compound beacon constructor list in desired construction order. + // 7. Add constructors to the compound beacon constructor list in desired construction order. // In a compound beacon with multiple constructors, the order the constructors are added to // the constructor list determines their priority. // The first constructor added to a constructor list will be the first constructor that is executed. @@ -549,70 +446,55 @@ public static DynamoDbClient SetupBeaconConfig(String ddbTableName, String branc sk3ConstructorList.add(buildingFloorDeskConstructor); sk3ConstructorList.add(ticketModTimeConstructor); - // 9. Define compound beacons + // 8. Define compound beacons // Compound beacon construction is defined in more detail in CompoundBeaconSearchableEncryptionExample. // Note that the split character must be a character that is not used in any attribute value. - CompoundBeacon pk0CompoundBeacon = CompoundBeacon.builder() - .name("PK") - .split("~") - .encrypted(pk0EncryptedPartList) - .constructors(pk0ConstructorList) - .build(); - CompoundBeacon sk0CompoundBeacon = CompoundBeacon.builder() - .name("SK") - .split("~") - .encrypted(sk0EncryptedPartList) - .signed(sk0SignedPartList) - .constructors(sk0ConstructorList) - .build(); - CompoundBeacon pk1CompoundBeacon = CompoundBeacon.builder() - .name("PK1") - .split("~") - .encrypted(pk1EncryptedPartList) - .constructors(pk1ConstructorList) - .build(); - CompoundBeacon sk1CompoundBeacon = CompoundBeacon.builder() - .name("SK1") - .split("~") - .encrypted(sk1EncryptedPartList) - .signed(sk1SignedPartList) - .constructors(sk1ConstructorList) - .build(); - CompoundBeacon pk2CompoundBeacon = CompoundBeacon.builder() - .name("PK2") - .split("~") - .encrypted(pk2EncryptedPartList) - .constructors(pk2ConstructorList) - .build(); - CompoundBeacon pk3CompoundBeacon = CompoundBeacon.builder() - .name("PK3") - .split("~") - .encrypted(pk3EncryptedPartList) - .constructors(pk3ConstructorList) - .build(); - CompoundBeacon sk3CompoundBeacon = CompoundBeacon.builder() - .name("SK3") - .split("~") - .encrypted(sk3EncryptedPartList) - .signed(sk3SignedPartList) - .constructors(sk3ConstructorList) - .build(); - - List compoundBeaconList = new ArrayList<>(); - compoundBeaconList.add(pk0CompoundBeacon); - compoundBeaconList.add(sk0CompoundBeacon); - compoundBeaconList.add(pk1CompoundBeacon); - compoundBeaconList.add(sk1CompoundBeacon); - compoundBeaconList.add(pk2CompoundBeacon); - compoundBeaconList.add(pk3CompoundBeacon); - compoundBeaconList.add(sk3CompoundBeacon); - - // 10. Create BeaconVersion. + List compoundBeaconList = Arrays.asList( + CompoundBeacon.builder() + .name("PK") + .split("~") + .constructors(pk0ConstructorList) + .build(), + CompoundBeacon.builder() + .name("SK") + .split("~") + .constructors(sk0ConstructorList) + .build(), + CompoundBeacon.builder() + .name("PK1") + .split("~") + .constructors(pk1ConstructorList) + .build(), + CompoundBeacon.builder() + .name("SK1") + .split("~") + .constructors(sk1ConstructorList) + .build(), + CompoundBeacon.builder() + .name("PK2") + .split("~") + .constructors(pk2ConstructorList) + .build(), + CompoundBeacon.builder() + .name("PK3") + .split("~") + .constructors(pk3ConstructorList) + .build(), + CompoundBeacon.builder() + .name("SK3") + .split("~") + .constructors(sk3ConstructorList) + .build() + ); + + // 9. Create BeaconVersion. List beaconVersions = new ArrayList<>(); beaconVersions.add( BeaconVersion.builder() .standardBeacons(standardBeaconList) .compoundBeacons(compoundBeaconList) + .encryptedParts(encryptedPartList) + .signedParts(signedPartList) .version(1) // MUST be 1 .keyStore(keyStore) .keySource(BeaconKeySource.builder() @@ -624,7 +506,7 @@ public static DynamoDbClient SetupBeaconConfig(String ddbTableName, String branc .build() ); - // 11. Create a Hierarchical Keyring + // 10. Create a Hierarchical Keyring final MaterialProviders matProv = MaterialProviders.builder() .MaterialProvidersConfig(MaterialProvidersConfig.builder().build()) .build(); @@ -635,7 +517,7 @@ public static DynamoDbClient SetupBeaconConfig(String ddbTableName, String branc .build(); final IKeyring kmsKeyring = matProv.CreateAwsKmsHierarchicalKeyring(keyringInput); - // 12. Define crypto actions + // 11. Define crypto actions final Map attributeActionsOnEncrypt = new HashMap<>(); // Our partition key must be configured as SIGN_ONLY attributeActionsOnEncrypt.put("partition_key", CryptoAction.SIGN_ONLY); @@ -670,7 +552,7 @@ public static DynamoDbClient SetupBeaconConfig(String ddbTableName, String branc attributeActionsOnEncrypt.put("ProjectStart", CryptoAction.SIGN_ONLY); attributeActionsOnEncrypt.put("Duration", CryptoAction.SIGN_ONLY); - // 13. Set up table config + // 12. Set up table config final Map tableConfigs = new HashMap<>(); final DynamoDbTableEncryptionConfig config = DynamoDbTableEncryptionConfig.builder() .logicalTableName(ddbTableName) @@ -684,14 +566,14 @@ public static DynamoDbClient SetupBeaconConfig(String ddbTableName, String branc .build(); tableConfigs.put(ddbTableName, config); - // 14. Create the DynamoDb Encryption Interceptor + // 13. Create the DynamoDb Encryption Interceptor DynamoDbEncryptionInterceptor encryptionInterceptor = DynamoDbEncryptionInterceptor.builder() .config(DynamoDbTablesEncryptionConfig.builder() .tableEncryptionConfigs(tableConfigs) .build()) .build(); - // 15. Create a new AWS SDK DynamoDb client using the DynamoDb Encryption Interceptor above + // 14. Create a new AWS SDK DynamoDb client using the DynamoDb Encryption Interceptor above final DynamoDbClient ddb = DynamoDbClient.builder() .overrideConfiguration( ClientOverrideConfiguration.builder()