Skip to content

Commit 248b684

Browse files
feat(Examples): Add example for migrating from plaintext to encrypted DB (#195)
1 parent 250c65d commit 248b684

24 files changed

+1518
-2
lines changed

.github/workflows/ci_examples_java.yml

+1
Original file line numberDiff line numberDiff line change
@@ -92,5 +92,6 @@ jobs:
9292
# Run simple examples
9393
gradle -p runtimes/java/DynamoDbEncryption test
9494
# Run migration examples
95+
gradle -p runtimes/java/Migration/PlaintextToAWSDBE test
9596
gradle -p runtimes/java/Migration/DDBECToAWSDBE test
9697
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+
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
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# DyanmoDb Encryption Client to AWS Database Encryption SDK for DynamoDb Migration
2+
3+
This projects demonstrates the steps necessary
4+
to migrate to the AWS Database Encryption SDK for DynamoDb
5+
from a plaintext database.
6+
7+
[Step 0](Desktop/workplace/aws-dynamodb-encryption-dafny/Examples/runtimes/java/Migration/PlaintextToAWSDBE/DDBEC/README.md) demonstrates the starting state for your system.
8+
9+
## Step 1
10+
11+
In Step 1, you update your system to do the following:
12+
- continue to read plaintext items
13+
- continue to write plaintext items
14+
- prepare to read encrypted items
15+
16+
When you deploy changes in Step 1,
17+
you should not expect any behavior change in your system,
18+
and your dataset still consists of plaintext data.
19+
20+
You must ensure that the changes in Step 1 make it to all your readers before you proceed to Step 2.
21+
22+
## Step 2
23+
24+
In Step 2, you update your system to do the following:
25+
- continue to read plaintext items
26+
- start writing encrypted items
27+
- continue to read encrypted items
28+
29+
When you deploy changes in Step 2,
30+
you are introducing encrypted items to your system,
31+
and must make sure that all your readers are updated with the changes from Step 1.
32+
33+
Before you move onto the next step, you will need to encrypt all plaintext items in your dataset.
34+
Once you have completed this step,
35+
while new items are being encrypted using the new format and will be authenticated on read,
36+
your system will still accept reading plaintext, unauthenticated items.
37+
In order to complete migration to a system where you always authenticate your items,
38+
you should prioritize moving on to Step 3.
39+
40+
## Step 3
41+
42+
Once all old items are encrypted,
43+
update your system to do the following:
44+
- continue to write encrypted items
45+
- continue to read encrypted items
46+
- do not accept reading plaintext items
47+
48+
Once you have deployed these changes to your system, you have completed migration.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import java.net.URI
2+
import javax.annotation.Nullable
3+
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
4+
import org.gradle.api.tasks.testing.logging.TestLogEvent
5+
6+
plugins {
7+
`java`
8+
`java-library`
9+
}
10+
11+
group = "software.amazon.cryptography"
12+
version = "1.0-SNAPSHOT"
13+
description = "AWSDatabaseEncryptionSDKMigrationExamples"
14+
15+
java {
16+
toolchain.languageVersion.set(JavaLanguageVersion.of(8))
17+
sourceSets["main"].java {
18+
srcDir("src/main/java")
19+
}
20+
sourceSets["test"].java {
21+
srcDir("src/test/java")
22+
}
23+
}
24+
25+
var caUrl: URI? = null
26+
@Nullable
27+
val caUrlStr: String? = System.getenv("CODEARTIFACT_URL_JAVA_CONVERSION")
28+
if (!caUrlStr.isNullOrBlank()) {
29+
caUrl = URI.create(caUrlStr)
30+
}
31+
32+
var caPassword: String? = null
33+
@Nullable
34+
val caPasswordString: String? = System.getenv("CODEARTIFACT_AUTH_TOKEN")
35+
if (!caPasswordString.isNullOrBlank()) {
36+
caPassword = caPasswordString
37+
}
38+
39+
repositories {
40+
maven {
41+
name = "DynamoDB Local Release Repository - US West (Oregon) Region"
42+
url = URI.create("https://s3-us-west-2.amazonaws.com/dynamodb-local/release")
43+
}
44+
mavenCentral()
45+
mavenLocal()
46+
if (caUrl != null && caPassword != null) {
47+
maven {
48+
name = "CodeArtifact"
49+
url = caUrl!!
50+
credentials {
51+
username = "aws"
52+
password = caPassword!!
53+
}
54+
}
55+
}
56+
}
57+
58+
dependencies {
59+
implementation("software.amazon.cryptography:aws-database-encryption-sdk-dynamodb:1.0-SNAPSHOT")
60+
implementation("software.amazon.cryptography:AwsCryptographicMaterialProviders:1.0-SNAPSHOT")
61+
62+
implementation(platform("software.amazon.awssdk:bom:2.19.1"))
63+
implementation("software.amazon.awssdk:dynamodb")
64+
implementation("software.amazon.awssdk:dynamodb-enhanced")
65+
implementation("software.amazon.awssdk:kms")
66+
67+
// https://mvnrepository.com/artifact/org.testng/testng
68+
testImplementation("org.testng:testng:7.5")
69+
}
70+
71+
tasks.withType<JavaCompile>() {
72+
options.encoding = "UTF-8"
73+
}
74+
75+
tasks.test {
76+
useTestNG()
77+
78+
// This will show System.out.println statements
79+
testLogging.showStandardStreams = true
80+
81+
testLogging {
82+
lifecycle {
83+
events = mutableSetOf(TestLogEvent.FAILED, TestLogEvent.PASSED, TestLogEvent.SKIPPED)
84+
exceptionFormat = TestExceptionFormat.FULL
85+
showExceptions = true
86+
showCauses = true
87+
showStackTraces = true
88+
showStandardStreams = true
89+
}
90+
info.events = lifecycle.events
91+
info.exceptionFormat = lifecycle.exceptionFormat
92+
}
93+
94+
// See https://github.com/gradle/kotlin-dsl/issues/836
95+
addTestListener(object : TestListener {
96+
override fun beforeSuite(suite: TestDescriptor) {}
97+
override fun beforeTest(testDescriptor: TestDescriptor) {}
98+
override fun afterTest(testDescriptor: TestDescriptor, result: TestResult) {}
99+
100+
override fun afterSuite(suite: TestDescriptor, result: TestResult) {
101+
if (suite.parent == null) { // root suite
102+
logger.lifecycle("----")
103+
logger.lifecycle("Test result: ${result.resultType}")
104+
logger.lifecycle("Test summary: ${result.testCount} tests, " +
105+
"${result.successfulTestCount} succeeded, " +
106+
"${result.failedTestCount} failed, " +
107+
"${result.skippedTestCount} skipped")
108+
}
109+
}
110+
})
111+
}
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)