Skip to content
This repository has been archived by the owner on Apr 13, 2023. It is now read-only.

Commit

Permalink
feat: support update as create in bundle service (#80)
Browse files Browse the repository at this point in the history
Co-authored-by: Justinus Menzel <justinus.menzel@abacusinsights.com>
  • Loading branch information
justinusmenzel and Justinus Menzel committed Jun 1, 2021
1 parent b6e6b80 commit bf1366d
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 4 deletions.
53 changes: 52 additions & 1 deletion src/dataServices/dynamoDbBundleService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import * as AWSMock from 'aws-sdk-mock';

import { QueryInput, TransactWriteItemsInput } from 'aws-sdk/clients/dynamodb';
import AWS from 'aws-sdk';
import { BundleResponse, BatchReadWriteRequest } from 'fhir-works-on-aws-interface';
import { BundleResponse, BatchReadWriteRequest, TypeOperation } from 'fhir-works-on-aws-interface';
import { DynamoDbBundleService } from './dynamoDbBundleService';
import { DynamoDBConverter } from './dynamoDb';
import { timeFromEpochInMsRegExp, utcTimeRegExp, uuidRegExp } from '../../testUtilities/regExpressions';
Expand Down Expand Up @@ -450,4 +450,55 @@ describe('atomicallyReadWriteResources', () => {
await runUpdateTest(true);
});
});

describe('Update as Create Cases', () => {
const runTest = async (supportUpdateCreate: boolean, operation: TypeOperation, isLockSuccessful: boolean) => {
// READ items (Failure)
AWSMock.mock('DynamoDB', 'query', (params: QueryInput, callback: Function) => {
callback(null, { Items: [] });
});

const dynamoDb = new AWS.DynamoDB();
const bundleService = new DynamoDbBundleService(dynamoDb, supportUpdateCreate);

const batchRequest: BatchReadWriteRequest = {
operation,
resourceType: 'Patient',
id,
resource: `Patient/${id}`,
};
// @ts-ignore
const actualResponse = await bundleService.lockItems([batchRequest]);
if (isLockSuccessful) {
expect(actualResponse).toStrictEqual({
lockedItems: [],
successfulLock: true,
});
} else {
expect(actualResponse).toStrictEqual({
errorMessage: `Failed to find resources: Patient/${id}`,
errorType: 'USER_ERROR',
lockedItems: [],
successfulLock: false,
});
}
};

const testCases = [
// ['supportUpdateCreate', 'operation', 'isLockSuccessful'],
[true, 'create', true],
[true, 'update', true],
[true, 'read', false],
[false, 'create', true],
[false, 'update', false],
[false, 'read', false],
];

// eslint-disable-next-line no-restricted-syntax
for (const [supportUpdateCreate, operation, isLockSuccessful] of testCases) {
test('lock update ', async () => {
await runTest(supportUpdateCreate as boolean, operation as TypeOperation, isLockSuccessful as boolean);
});
}
});
});
11 changes: 9 additions & 2 deletions src/dataServices/dynamoDbBundleService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ export class DynamoDbBundleService implements Bundle {
private readonly ELAPSED_TIME_WARNING_MESSAGE =
'Transaction time is greater than max allowed code execution time. Please reduce your bundle size by sending fewer Bundle entries.';

readonly updateCreateSupported: boolean;

private dynamoDbHelper: DynamoDbHelper;

private dynamoDb: DynamoDB;
Expand All @@ -40,9 +42,10 @@ export class DynamoDbBundleService implements Bundle {
private static readonly dynamoDbMaxBatchSize = 25;

// Allow Mocking DDB
constructor(dynamoDb: DynamoDB, maxExecutionTimeMs?: number) {
constructor(dynamoDb: DynamoDB, supportUpdateCreate: boolean = false, maxExecutionTimeMs?: number) {
this.dynamoDbHelper = new DynamoDbHelper(dynamoDb);
this.dynamoDb = dynamoDb;
this.updateCreateSupported = supportUpdateCreate;
this.maxExecutionTimeMs = maxExecutionTimeMs || 26 * 1000;
}

Expand Down Expand Up @@ -190,7 +193,11 @@ export class DynamoDbBundleService implements Bundle {
const idItemsFailedToRead: string[] = [];
for (let i = 0; i < itemResponses.length; i += 1) {
const itemResponse = itemResponses[i];
if (itemResponse instanceof ResourceNotFoundError) {
// allow for update as create scenario
if (
itemResponse instanceof ResourceNotFoundError &&
!(itemsToLock[i].operation === 'update' && this.updateCreateSupported)
) {
idItemsFailedToRead.push(`${itemsToLock[i].resourceType}/${itemsToLock[i].id}`);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/dataServices/dynamoDbDataService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export class DynamoDbDataService implements Persistence, BulkDataAccess {

constructor(dynamoDb: DynamoDB, supportUpdateCreate: boolean = false) {
this.dynamoDbHelper = new DynamoDbHelper(dynamoDb);
this.transactionService = new DynamoDbBundleService(dynamoDb);
this.transactionService = new DynamoDbBundleService(dynamoDb, supportUpdateCreate);
this.dynamoDb = dynamoDb;
this.updateCreateSupported = supportUpdateCreate;
}
Expand Down

0 comments on commit bf1366d

Please sign in to comment.