Skip to content

Commit 18dbc50

Browse files
chore: add migration examples (#2057)
1 parent 9b7c284 commit 18dbc50

22 files changed

Lines changed: 1617 additions & 6 deletions

File tree

.github/workflows/ci_examples_java.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,3 +108,4 @@ jobs:
108108
# Run migration examples
109109
gradle -p runtimes/java/Migration/PlaintextToAWSDBE test
110110
gradle -p runtimes/java/Migration/DDBECToAWSDBE test
111+
gradle -p runtimes/java/Migration/DDBECv2ToAWSDBE test

DynamoDbEncryption/runtimes/java/src/main/sdkv2/software/amazon/cryptools/dynamodbencryptionclientsdk2/encryption/providers/DirectKmsMaterialsProvider.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,13 +109,24 @@ public DecryptionMaterials getDecryptionMaterials(EncryptionContext context) {
109109
final String providedEncAlg = materialDescription.get(CONTENT_KEY_ALGORITHM);
110110
final String providedSigAlg = materialDescription.get(SIGNING_KEY_ALGORITHM);
111111

112+
final String envelopeKey = materialDescription.get(ENVELOPE_KEY);
113+
114+
// DDBEC with SDK v1 does not do this check and returns NPE
115+
// DDBEC with SDK v2 does not return NPE but return DynamoDbEncryptionException
116+
if (envelopeKey == null) {
117+
throw new DynamoDbEncryptionException(
118+
"Missing " + ENVELOPE_KEY + " in material description. " +
119+
"This item may have been encrypted with a different encryption format."
120+
);
121+
}
122+
112123
ec.put("*" + CONTENT_KEY_ALGORITHM + "*", providedEncAlg);
113124
ec.put("*" + SIGNING_KEY_ALGORITHM + "*", providedSigAlg);
114125

115126
populateKmsEcFromEc(context, ec);
116127

117128
DecryptRequest.Builder request = DecryptRequest.builder();
118-
request.ciphertextBlob(SdkBytes.fromByteArray(Base64.decode(materialDescription.get(ENVELOPE_KEY))));
129+
request.ciphertextBlob(SdkBytes.fromByteArray(Base64.decode(envelopeKey)));
119130
request.encryptionContext(ec);
120131
final DecryptResponse decryptResponse = decrypt(request.build(), context);
121132
validateEncryptionKeyId(decryptResponse.keyId(), context);

Examples/runtimes/java/Migration/DDBECToAWSDBE/src/main/java/software/amazon/cryptography/examples/migration/awsdbe/MigrationExampleStep3.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public static void MigrationStep3(
6363

6464
final List<String> allowedUnsignedAttributes = Arrays.asList("attribute3");
6565

66-
// 3. Create the DynamoDb Encryption Interceptor with the above configuration.
66+
// 2. Create the DynamoDb Encryption Interceptor with the above configuration.
6767
// Do not configure any legacy behavior.
6868
final Map<String, DynamoDbEnhancedTableEncryptionConfig> tableConfigs =
6969
new HashMap<>();
@@ -85,7 +85,7 @@ public static void MigrationStep3(
8585
.build()
8686
);
8787

88-
// 4. Create a new AWS SDK DynamoDb client using the DynamoDb Encryption Interceptor above
88+
// 3. Create a new AWS SDK DynamoDb client using the DynamoDb Encryption Interceptor above
8989
final DynamoDbClient ddb = DynamoDbClient
9090
.builder()
9191
.overrideConfiguration(
@@ -96,7 +96,7 @@ public static void MigrationStep3(
9696
)
9797
.build();
9898

99-
// 5. Create the DynamoDbEnhancedClient using the AWS SDK Client created above,
99+
// 4. Create the DynamoDbEnhancedClient using the AWS SDK Client created above,
100100
// and create a Table with your modelled class
101101
final DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient
102102
.builder()
@@ -107,7 +107,7 @@ public static void MigrationStep3(
107107
schemaOnEncrypt
108108
);
109109

110-
// 6. Put an item into your table using the DynamoDb Enhanced Client.
110+
// 5. Put an item into your table using the DynamoDb Enhanced Client.
111111
// This item will be encrypted in the latest format, using the
112112
// configuration from your modelled class to decide
113113
// which attribute to encrypt and/or sign.
@@ -120,7 +120,7 @@ public static void MigrationStep3(
120120

121121
table.putItem(item);
122122

123-
// 7. Get an item back from the table using the DynamoDb Enhanced Client.
123+
// 6. Get an item back from the table using the DynamoDb Enhanced Client.
124124
// If this is an item written in the old format (e.g. any item written
125125
// during Step 0 or 1), then we fail to return the item.
126126
// If this is an item written in the new format (e.g. any item written
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#
2+
# https://help.github.com/articles/dealing-with-line-endings/
3+
#
4+
# Linux start script should use lf
5+
/gradlew text eol=lf
6+
7+
# These are Windows script files and should use crlf
8+
*.bat text eol=crlf
9+
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Ignore Gradle project-specific cache directory
2+
.gradle
3+
4+
# Ignore Gradle build output directory
5+
build
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import java.io.File
2+
import java.io.FileInputStream
3+
import java.util.Properties
4+
import java.net.URI
5+
import javax.annotation.Nullable
6+
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
7+
import org.gradle.api.tasks.testing.logging.TestLogEvent
8+
9+
plugins {
10+
`java`
11+
`java-library`
12+
}
13+
14+
var props = Properties().apply {
15+
load(FileInputStream(File(rootProject.rootDir, "../../../../../project.properties")))
16+
}
17+
18+
group = "software.amazon.cryptography"
19+
version = "1.0-SNAPSHOT"
20+
description = "AWSDatabaseEncryptionSDKMigrationExamples"
21+
22+
var mplVersion = props.getProperty("mplDependencyJavaVersion")
23+
var ddbecVersion = props.getProperty("projectJavaVersion")
24+
25+
java {
26+
toolchain.languageVersion.set(JavaLanguageVersion.of(8))
27+
sourceSets["main"].java {
28+
srcDir("src/main/java")
29+
}
30+
sourceSets["test"].java {
31+
srcDir("src/test/java")
32+
}
33+
}
34+
35+
var caUrl: URI? = null
36+
@Nullable
37+
val caUrlStr: String? = System.getenv("CODEARTIFACT_REPO_URL")
38+
if (!caUrlStr.isNullOrBlank()) {
39+
caUrl = URI.create(caUrlStr)
40+
}
41+
42+
var caPassword: String? = null
43+
@Nullable
44+
val caPasswordString: String? = System.getenv("CODEARTIFACT_TOKEN")
45+
if (!caPasswordString.isNullOrBlank()) {
46+
caPassword = caPasswordString
47+
}
48+
49+
repositories {
50+
mavenLocal()
51+
maven {
52+
name = "DynamoDB Local Release Repository - US West (Oregon) Region"
53+
url = URI.create("https://s3-us-west-2.amazonaws.com/dynamodb-local/release")
54+
}
55+
mavenCentral()
56+
if (caUrl != null && caPassword != null) {
57+
maven {
58+
name = "CodeArtifact"
59+
url = caUrl!!
60+
credentials {
61+
username = "aws"
62+
password = caPassword!!
63+
}
64+
}
65+
}
66+
}
67+
68+
dependencies {
69+
implementation("software.amazon.cryptography:aws-database-encryption-sdk-dynamodb:${ddbecVersion}")
70+
implementation("software.amazon.cryptography:aws-cryptographic-material-providers:${mplVersion}")
71+
72+
implementation(platform("software.amazon.awssdk:bom:2.19.1"))
73+
implementation("software.amazon.awssdk:dynamodb")
74+
implementation("software.amazon.awssdk:dynamodb-enhanced")
75+
implementation("software.amazon.awssdk:kms")
76+
77+
// https://mvnrepository.com/artifact/org.testng/testng
78+
testImplementation("org.testng:testng:7.5")
79+
}
80+
81+
tasks.withType<JavaCompile>() {
82+
options.encoding = "UTF-8"
83+
}
84+
85+
tasks.test {
86+
useTestNG()
87+
88+
// This will show System.out.println statements
89+
testLogging.showStandardStreams = true
90+
91+
testLogging {
92+
lifecycle {
93+
events = mutableSetOf(TestLogEvent.FAILED, TestLogEvent.PASSED, TestLogEvent.SKIPPED)
94+
exceptionFormat = TestExceptionFormat.FULL
95+
showExceptions = true
96+
showCauses = true
97+
showStackTraces = true
98+
showStandardStreams = true
99+
}
100+
info.events = lifecycle.events
101+
info.exceptionFormat = lifecycle.exceptionFormat
102+
}
103+
104+
// See https://github.com/gradle/kotlin-dsl/issues/836
105+
addTestListener(object : TestListener {
106+
override fun beforeSuite(suite: TestDescriptor) {}
107+
override fun beforeTest(testDescriptor: TestDescriptor) {}
108+
override fun afterTest(testDescriptor: TestDescriptor, result: TestResult) {}
109+
110+
override fun afterSuite(suite: TestDescriptor, result: TestResult) {
111+
if (suite.parent == null) { // root suite
112+
logger.lifecycle("----")
113+
logger.lifecycle("Test result: ${result.resultType}")
114+
logger.lifecycle("Test summary: ${result.testCount} tests, " +
115+
"${result.successfulTestCount} succeeded, " +
116+
"${result.failedTestCount} failed, " +
117+
"${result.skippedTestCount} skipped")
118+
}
119+
}
120+
})
121+
}
Binary file not shown.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
distributionBase=GRADLE_USER_HOME
2+
distributionPath=wrapper/dists
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
4+
networkTimeout=10000
5+
zipStoreBase=GRADLE_USER_HOME
6+
zipStorePath=wrapper/dists

0 commit comments

Comments
 (0)