-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat!: upgrade AWS SDK to v3 #83
base: master
Are you sure you want to change the base?
Conversation
@@ -1,14 +1,14 @@ | |||
# Needed for DynamoDB Local, which is used for unit tests | |||
FROM openjdk:15-alpine3.11 | |||
# Java JDK is needed for DynamoDB Local, which is used for unit tests |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To get AWS SDK v3 support for the local DynamoDB, we have to upgrade jest-dynamodb
, which necessitates upgrading to a newer version of Nodejs, which necessitates switching from the deprecated base Docker image we were using to this one.
@@ -12,8 +12,10 @@ module.exports = async () => { | |||
port, | |||
clientConfig: { | |||
endpoint, | |||
sslEnabled: false, | |||
region: "local", | |||
credentials: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my testing, I got prompts to fetch new AWS SSO credentials unless I provided dummy credentials for the local DynamoDB.
@@ -1,6 +1,6 @@ | |||
{ | |||
"name": "@ginger.io/beyonce", | |||
"version": "0.0.66", | |||
"version": "0.0.67", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR has breaking changes, but since we haven't hit version 1, I'm assuming we're ok with just continuing to bump the version like this instead of going to version 1.0.0 now. LMK if you'd prefer otherwise!
@@ -12,8 +12,9 @@ | |||
"./src" | |||
], | |||
"dependencies": { | |||
"@aws-sdk/client-dynamodb": "3.113.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm pinning to the same versions that @shelf/jest-dynamodb
uses because I was encountering errors with that library before doing so.
private jayz?: JayZ | ||
private consistentReads: boolean | ||
|
||
constructor(private table: Table<string, string>, dynamo: DynamoDB, options: Options = {}) { | ||
this.client = new DynamoDB.DocumentClient({ service: dynamo }) | ||
this.client = DynamoDBDocumentClient.from(dynamo, { | ||
marshallOptions: { removeUndefinedValues: true } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Attempting to write keys with undefined values results in errors unless specifying this option.
@@ -29,6 +30,8 @@ export async function batchWriteItems<T extends TaggedModel>( | |||
deleteItems.forEach((key) => { | |||
requests.push({ | |||
DeleteRequest: { | |||
// @ts-ignore The type is incorrect for `Key`. It expects Record<string, AttributeValue>, but since we're using | |||
// a DynamoDBDocumentClient, it needs to be Record<string, string> instead. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Writes fail if I pass an object in the format Record<string, AttributeValue>
. The type in the underlying library is wrong.
const unprocessedPuts: T[] = [] | ||
const unprocessedDeleteKeys = new UnprocessedKeyCollector(table, deleteItems) | ||
|
||
if (results.UnprocessedItems && results.UnprocessedItems[tableName]) { | ||
results.UnprocessedItems[tableName].forEach(({ PutRequest, DeleteRequest }) => { | ||
if (PutRequest) { | ||
unprocessedPuts.push(PutRequest.Item as T) | ||
} else if (DeleteRequest) { | ||
} else if (DeleteRequest && DeleteRequest.Key) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DeleteRequest.Key
is now undefined.
@@ -33,6 +34,8 @@ export async function transactWriteItems<T extends TaggedModel>(params: Transact | |||
requests.push({ | |||
Delete: { | |||
TableName: table.tableName, | |||
// @ts-ignore The type is incorrect for `Key`. It expects Record<string, AttributeValue>, but since we're using |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here: the type in the underlying lib is wrong.
} else { | ||
throw e | ||
if (e && e.CancellationReasons) { | ||
throw new Error(`${e.message}. Cancellation Reasons: ${JSON.stringify(e.CancellationReasons)}`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's nice that we can skip all the parsing from the httpResponse
now.
} | ||
} | ||
|
||
/** | ||
* The DynamoDB v3 lib returns items with values that are UInt8Array instead of Buffer, so this function |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The response format appears to have changed from Buffer to UInt8Array, so we're converting to keep the expected format for clients.
ConsistentRead: true | ||
}) | ||
expect(mockGet).toHaveBeenCalledWith( | ||
expect.objectContaining({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We use objectContaining
now since there are various other properties on the argument passed to send()
now.
Ticket: https://app.asana.com/0/1200444444072189/1202815880040240
We will not yet merge this because we cannot upgrade Beyonce's AWS SDK to v3 without also upgrading Vault's. Timeboxing Vault's AWS SDK to v3 to 30 minutes indicated that it isn't as quick enough a task that we can take it on right now. We can pick that up (and also merge + test E2E this PR) in the future within one of our teams' tech debt budgets.
This PR upgrades Beyonce from v2 to v3 of the AWS SDK, which involves breaking changes: clients need to instantiate Beyonce with a DynamoDB instance from
@aws-sdk/client-dynamodb
v3 instead ofaws-sdk
v2.Reviewing commit-by-commit will be easiest.
The original motivation for this upgrade was to experiment with the new error responses from DynamoDB when encountering a condition check failure while executing a transaction, to see if the new error messages provide enough detail to determine which condition check failed (so we could distinguish the reason(s) in the case that there were to be multiple condition checks). Related ticket. It turns out that even the new v3 error responses do not contain such detail. For example, here's an error: