Skip to content
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(idempotency): Add persistence layer and DynamoDB implementation #1110

Merged
merged 51 commits into from
Nov 11, 2022
Merged
Changes from 1 commit
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
51104f6
feat: initial idempotency classes
vgphoenixcampos Sep 2, 2022
d54e22e
feat: refactor persistence layer classes into their own folder
vgphoenixcampos Sep 8, 2022
6ea753e
feat: rename idempotency config to differentiate from idempotency opt…
vgphoenixcampos Sep 8, 2022
c5f2144
feat: added type for a generic function
vgphoenixcampos Sep 8, 2022
ab254c6
feat: remove idempotency configuration for this FR
vgphoenixcampos Sep 8, 2022
8677376
feat: refactored type of function to accept any combo of parameters
vgphoenixcampos Sep 8, 2022
b955ac4
feat: adding PersistenceLayer
jeffrey-baker-vg Oct 6, 2022
c8776d2
feat: PersistenceLayer unit tests for saveInProgress
jeffrey-baker-vg Oct 14, 2022
f258d55
feat: added saveSuccess
jeffrey-baker-vg Oct 14, 2022
edc9b33
feat: added getRecord
jeffrey-baker-vg Oct 17, 2022
dfc72c0
feat: added delete record
jeffrey-baker-vg Oct 18, 2022
4d63218
feat: branch coverage and cleaning up imports
jeffrey-baker-vg Oct 18, 2022
d92efb1
feat: added more tests
jeffrey-baker-vg Oct 18, 2022
5258d10
feat: deleted unused methods
jeffrey-baker-vg Oct 18, 2022
5d82215
feat: added comments
jeffrey-baker-vg Oct 18, 2022
95004c2
feat: implement get command for dynamo persistence layer
KevenFuentes9 Sep 14, 2022
c5a9335
feat: implement get command for dynamo persistence layer
KevenFuentes9 Sep 14, 2022
3d1f52c
feat: allow for data attr to be passed and return in persistence laye…
KevenFuentes9 Sep 14, 2022
0a6e839
feat: added implementation for delete, update, put
vgphoenixcampos Sep 23, 2022
b9ae754
feat: create condition on put for not in progress status
vgphoenixcampos Sep 23, 2022
2cd4390
feat: use inprogress enum for status
vgphoenixcampos Sep 23, 2022
01bcc99
feat: added error when unable to get record for idempotency key
vgphoenixcampos Sep 23, 2022
c1a6c60
feat: added error for conditional write of an existing record
vgphoenixcampos Sep 23, 2022
1011002
feat: tests added for put record on dynamo persistence layer
vgphoenixcampos Sep 23, 2022
adcfab3
feat: implemented the idempotency record functions for status, expiry…
KevenFuentes9 Sep 23, 2022
9f0535e
test: check if the status is expired
KevenFuentes9 Sep 23, 2022
9bf7885
test: idempotency record is not expired and status maintained
KevenFuentes9 Sep 23, 2022
ffb2c22
feat: added tests for get record
vgphoenixcampos Sep 23, 2022
ec31dbb
feat: add aws-sdk-client-mock jest assertion library
vgphoenixcampos Sep 30, 2022
48dfdec
feat: add unit tests for update record and delete record
vgphoenixcampos Sep 30, 2022
f666dfa
feat: remove optional chaining from item made unnecessary with error …
vgphoenixcampos Sep 30, 2022
0945801
feat: remove unused block
vgphoenixcampos Sep 30, 2022
e161521
feat: refactored mock child class to be shared amongst dynamo persist…
vgphoenixcampos Sep 30, 2022
9efeae0
test: add path to get the response data from the data record
KevenFuentes9 Sep 30, 2022
0fea9f3
feat: added branch to handle conditional check failure
vgphoenixcampos Oct 7, 2022
b4165bd
feat: add configuration option to dynamo client creation to remove un…
vgphoenixcampos Oct 7, 2022
d1dad17
feat: change how time is measured to seconds
vgphoenixcampos Oct 26, 2022
b9afc2a
feat: change type of the response/result to a record
vgphoenixcampos Oct 26, 2022
0ec8301
feat:updated imports
jeffrey-baker-vg Oct 28, 2022
8e97a61
refactor: create constructor object for dynamo persistence layer
vgphoenixcampos Nov 4, 2022
afb9523
fix: remove temp eslint disable
vgphoenixcampos Nov 4, 2022
8a031ca
fix: adjust verbiage on test blocks
vgphoenixcampos Nov 4, 2022
f476e21
style: put constructor parameters onto one line for readability
vgphoenixcampos Nov 4, 2022
a044fa6
fix: update dynamo persistence layer tests to use new construtor opt…
vgphoenixcampos Nov 4, 2022
cefae2d
Merge branch 'main' of github.com:jeffrey-baker-vg/aws-lambda-powerto…
vgphoenixcampos Nov 4, 2022
dd979a8
fix: remove unneeded eslint ignore from persistence layer
vgphoenixcampos Nov 4, 2022
b290d19
style: put parameters for dynamo client command object onto one line …
vgphoenixcampos Nov 4, 2022
f76c720
fix: move lib-dynamo dep under the correct package
vgphoenixcampos Nov 4, 2022
b4931bf
refactor: change idempotency record to use options object in contructor
vgphoenixcampos Nov 4, 2022
9b4787a
feat: add consistent read to dynamo persistence layer
vgphoenixcampos Nov 4, 2022
08598f9
fix: revert changes to layer-publisher package-lock
vgphoenixcampos Nov 4, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat: added implementation for delete, update, put
  • Loading branch information
vgphoenixcampos authored and jeffrey-baker-vg committed Oct 27, 2022
commit 0a6e83982f08231a3861fbe5010196cf86f0f0c4
56 changes: 46 additions & 10 deletions packages/idempotency/src/persistence/DynamoDbPersistenceLayer.ts
Original file line number Diff line number Diff line change
@@ -3,26 +3,62 @@ import { PersistenceLayer } from './PersistenceLayer';
import { IdempotencyRecord } from './IdempotencyRecord';

class DynamoDBPersistenceLayer extends PersistenceLayer {
public constructor(private tableName: string, private key_attr: string = 'id',
private status_attr: string = 'status', private expiry_attr: string = 'expiration',
private _table: DynamoDBDocument | undefined;

public constructor(private tableName: string, private key_attr: string = 'id',
private status_attr: string = 'status', private expiry_attr: string = 'expiration',
private in_progress_expiry_attr: string = 'in_progress_expiry_attr',
private data_attr: string = 'data' ) {
private data_attr: string = 'data') {
super();
}
protected async _deleteRecord(): Promise<void> {}

protected async _deleteRecord(record: IdempotencyRecord): Promise<void> {
const table: DynamoDBDocument = this.getTable();
await table.delete({
TableName: this.tableName, Key: { [this.key_attr]: record.idempotencyKey }
});
}

protected async _getRecord(idempotencyKey: string): Promise<IdempotencyRecord> {
const ddbDocClient: DynamoDBDocument = DynamoDBDocument.from(new DynamoDB({}));
const output: GetCommandOutput = await ddbDocClient.get(
{ TableName: this.tableName, Key: { [this.key_attr]: idempotencyKey }
const table: DynamoDBDocument = this.getTable();
const output: GetCommandOutput = await table.get(
{
TableName: this.tableName, Key: { [this.key_attr]: idempotencyKey }
}
);

return new IdempotencyRecord(output.Item?.[this.key_attr], output.Item?.[this.status_attr], output.Item?.[this.expiry_attr], output.Item?.[this.in_progress_expiry_attr], output.Item?.[this.data_attr], undefined);
}
protected async _putRecord(_record: IdempotencyRecord): Promise<void> {}
protected async _updateRecord(): Promise<void> {}

protected async _putRecord(_record: IdempotencyRecord): Promise<void> {
const table: DynamoDBDocument = this.getTable();

const item = { [this.key_attr]: _record.idempotencyKey, [this.expiry_attr]: _record.expiryTimestamp, [this.status_attr]: _record.getStatus() };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we break this into multiple lines for readability?


const idempotencyKeyDoesNotExist = 'attribute_not_exists(#id)';
const idempotencyKeyExpired = '#expiry < :now';
const conditionalExpression = `${idempotencyKeyDoesNotExist} OR ${idempotencyKeyExpired}`;
await table.put({ TableName: this.tableName, Item: item, ExpressionAttributeNames: { '#id': this.key_attr, '#expiry': this.expiry_attr, '#status': this.status_attr }, ExpressionAttributeValues: { ':now': 0, ':now_in_millis': 0, ':inprogress': 'INPROGRESS' }, ConditionExpression: conditionalExpression });
}

protected async _updateRecord(record: IdempotencyRecord): Promise<void> {
const table: DynamoDBDocument = this.getTable();
await table.update(
{
TableName: this.tableName, Key: { [this.key_attr]: record.idempotencyKey },
UpdateExpression: 'SET #status = :status, #expiry = :expiry', ExpressionAttributeNames: { '#status': this.status_attr, '#expiry': this.expiry_attr }, ExpressionAttributeValues: { ':status': record.getStatus(), ':expiry': record.expiryTimestamp }
}
);
}

private getTable(): DynamoDBDocument {
if (!this._table)
this._table = DynamoDBDocument.from(new DynamoDB({}));

return this._table;
}
}

export {
DynamoDBPersistenceLayer
};
};