From deec40b721ad3bb1a1ff1575897ce9228f486250 Mon Sep 17 00:00:00 2001 From: Sam Marks Date: Tue, 6 Aug 2019 11:29:21 -0400 Subject: [PATCH] fix: use DynamoDB scans instead of query --- serverless.yml | 6 +----- src/ingest.js | 4 +--- src/schedule.js | 6 ++---- test/ingest.test.js | 4 +--- test/schedule.test.js | 20 +++++++++----------- 5 files changed, 14 insertions(+), 26 deletions(-) diff --git a/serverless.yml b/serverless.yml index eed319d..bdc2830 100644 --- a/serverless.yml +++ b/serverless.yml @@ -16,7 +16,7 @@ provider: - Effect: Allow Action: - dynamodb:UpdateItem - - dynamodb:Query + - dynamodb:Scan - dynamodb:DeleteItem Resource: Fn::GetAtt: ['tasksTable', 'Arn'] @@ -44,13 +44,9 @@ resources: KeySchema: - AttributeName: taskId KeyType: HASH - - AttributeName: executeTime - KeyType: RANGE AttributeDefinitions: - AttributeName: taskId AttributeType: 'S' - - AttributeName: executeTime - AttributeType: 'N' ProvisionedThroughput: ReadCapacityUnits: Ref: ReadCapacityUnits diff --git a/src/ingest.js b/src/ingest.js index b66b9fb..1e589d7 100644 --- a/src/ingest.js +++ b/src/ingest.js @@ -8,16 +8,14 @@ module.exports.handler = async (event) => { await documentClient.update({ TableName: process.env.TASKS_TABLE, Key: { taskId }, - UpdateExpression: 'SET #executeTime = :executeTime, #taskId = :taskId, #topicArn = :topicArn, #payload = :payload', + UpdateExpression: 'SET #executeTime = :executeTime, #topicArn = :topicArn, #payload = :payload', ExpressionAttributeNames: { '#executeTime': 'executeTime', - '#taskId': 'taskId', '#topicArn': 'topicArn', '#payload': 'payload' }, ExpressionAttributeValues: { ':executeTime': executeTime, - ':taskId': taskId, ':topicArn': topicArn, ':payload': payload } diff --git a/src/schedule.js b/src/schedule.js index 610daab..322bfc7 100644 --- a/src/schedule.js +++ b/src/schedule.js @@ -3,15 +3,13 @@ const AWS = require('aws-sdk') module.exports.handler = async () => { const sns = new AWS.SNS() const documentClient = new AWS.DynamoDB.DocumentClient() - const { Items } = await documentClient.query({ + const { Items } = await documentClient.scan({ TableName: process.env.TASKS_TABLE, - KeyConditionExpression: '#taskId != :taskId AND #executeTime <= :executeTime', + FilterExpression: '#executeTime <= :executeTime', ExpressionAttributeNames: { - '#taskId': 'taskId', '#executeTime': 'executeTime' }, ExpressionAttributeValues: { - ':taskId': '', ':executeTime': (new Date()).getTime() / 1000 } }).promise() diff --git a/test/ingest.test.js b/test/ingest.test.js index 03af554..b13ba7a 100644 --- a/test/ingest.test.js +++ b/test/ingest.test.js @@ -39,16 +39,14 @@ describe('ingest handler', () => { expect(updateStub.mock.calls[0][0]).toEqual({ TableName: 'tasks-table', Key: { taskId: 'test-task-id' }, - UpdateExpression: 'SET #executeTime = :executeTime, #taskId = :taskId, #topicArn = :topicArn, #payload = :payload', + UpdateExpression: 'SET #executeTime = :executeTime, #topicArn = :topicArn, #payload = :payload', ExpressionAttributeNames: { '#executeTime': 'executeTime', - '#taskId': 'taskId', '#topicArn': 'topicArn', '#payload': 'payload' }, ExpressionAttributeValues: { ':executeTime': 20, - ':taskId': 'test-task-id', ':topicArn': 'arn:aws:sns:us-east-1:123456789:test-topic', ':payload': { foo: 'bar' } } diff --git a/test/schedule.test.js b/test/schedule.test.js index 4cbcd85..80545fb 100644 --- a/test/schedule.test.js +++ b/test/schedule.test.js @@ -12,7 +12,7 @@ afterEach(() => { }) describe('schedule handler', () => { - let publishStub, queryStub, deleteStub + let publishStub, scanStub, deleteStub beforeEach(() => { process.env.TASKS_TABLE = 'tasks-table' publishStub = jest.fn((params, callback) => callback(null, 'Success')) @@ -22,7 +22,7 @@ describe('schedule handler', () => { }) describe('when there are tasks in the past that need to be executed', () => { beforeEach(() => { - queryStub = jest.fn((params, callback) => callback(null, { + scanStub = jest.fn((params, callback) => callback(null, { Items: [ { taskId: 'test-task-one', @@ -36,20 +36,18 @@ describe('schedule handler', () => { } ] })) - AWS.mock('DynamoDB.DocumentClient', 'query', queryStub) + AWS.mock('DynamoDB.DocumentClient', 'scan', scanStub) return handler() }) - it('queries for the items properly', () => { - expect(queryStub.mock.calls.length).toEqual(1) - expect(queryStub.mock.calls[0][0]).toEqual({ + it('scans for the items properly', () => { + expect(scanStub.mock.calls.length).toEqual(1) + expect(scanStub.mock.calls[0][0]).toEqual({ TableName: 'tasks-table', - KeyConditionExpression: '#taskId != :taskId AND #executeTime <= :executeTime', + FilterExpression: '#executeTime <= :executeTime', ExpressionAttributeNames: { - '#taskId': 'taskId', '#executeTime': 'executeTime' }, ExpressionAttributeValues: { - ':taskId': '', ':executeTime': 20 } }) @@ -79,10 +77,10 @@ describe('schedule handler', () => { }) describe('when there are no tasks in the past that need to be executed', () => { beforeEach(() => { - queryStub = jest.fn((params, callback) => callback(null, { + scanStub = jest.fn((params, callback) => callback(null, { Items: [] })) - AWS.mock('DynamoDB.DocumentClient', 'query', queryStub) + AWS.mock('DynamoDB.DocumentClient', 'scan', scanStub) return handler() }) it('does nothing', () => {