From 312f55b669cecf80f28126e8571339ca86767d26 Mon Sep 17 00:00:00 2001 From: Jeison Azevedo Date: Wed, 12 May 2021 15:25:40 -0300 Subject: [PATCH 1/2] Adds creation of dlq from resources --- packages/serverless-offline-sqs/README.md | 11 +++++++ packages/serverless-offline-sqs/src/index.js | 3 ++ packages/serverless-offline-sqs/src/sqs.js | 30 +++++++++++++++++++- 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/packages/serverless-offline-sqs/README.md b/packages/serverless-offline-sqs/README.md index 52aff3ab..42f4398e 100644 --- a/packages/serverless-offline-sqs/README.md +++ b/packages/serverless-offline-sqs/README.md @@ -74,6 +74,12 @@ resources: Type: AWS::SQS::Queue Properties: QueueName: MyFourthQueue + RedrivePolicy: + deadLetterTargetArn: # Support only this format for autoCreate + Fn::GetAtt: + - MyFourthQueueDlq + - Arn + maxReceiveCount: 6 MyFifthQueue: # Support for Fifo queue creation starts from 3.1 only Type: AWS::SQS::Queue @@ -81,6 +87,11 @@ resources: QueueName: MyFifthQueue.fifo FifoQueue: true ContentBasedDeduplication: true + + MyFourthQueueDlq: + Type: AWS::SQS::Queue + Properties: + QueueName: MyFourthQueueDlq ``` ### SQS diff --git a/packages/serverless-offline-sqs/src/index.js b/packages/serverless-offline-sqs/src/index.js index 1e1ff7d4..3f673fb6 100644 --- a/packages/serverless-offline-sqs/src/index.js +++ b/packages/serverless-offline-sqs/src/index.js @@ -130,6 +130,9 @@ class ServerlessOfflineSQS { this.sqs = new SQS(this.lambda, resources, this.options); + await this.sqs.createDlq( + get(['service', 'resources', 'Resources'], this.serverless)); + await this.sqs.create(events); if (!skipStart) { diff --git a/packages/serverless-offline-sqs/src/sqs.js b/packages/serverless-offline-sqs/src/sqs.js index 6bd9b347..78be33bf 100644 --- a/packages/serverless-offline-sqs/src/sqs.js +++ b/packages/serverless-offline-sqs/src/sqs.js @@ -1,7 +1,7 @@ const {default: PQueue} = require('p-queue'); const SQSClient = require('aws-sdk/clients/sqs'); // eslint-disable-next-line no-shadow -const {pipe, get, values, matches, find, mapValues, isPlainObject, toString} = require('lodash/fp'); +const {pipe, get, values, matches, find, mapValues, isPlainObject, toString, map, compact} = require('lodash/fp'); const {logWarning} = require('serverless-offline/dist/serverlessLog'); const SQSEventDefinition = require('./sqs-event-definition'); const SQSEvent = require('./sqs-event'); @@ -30,6 +30,10 @@ class SQS { return Promise.all(events.map(({functionKey, sqs}) => this._create(functionKey, sqs))); } + createDlq(resources) { + return this._createDlq(resources); + } + start() { this.queue.start(); } @@ -48,6 +52,30 @@ class SQS { return this._sqsEvent(functionKey, sqsEvent); } + _createDlq(resources) { + if (!this.options.autoCreate) return + const dlqNames = this._getDlqNames(resources); + return Promise.all(dlqNames.map((queueName) => { + return this._createQueue({ queueName }); + })) + } + + _getDlqNames(resources) { + return pipe( + values, + map((value) => { + const dlq = get(['Properties', 'RedrivePolicy', 'deadLetterTargetArn'], value) + if (!dlq) return + const [resourceName, attribute] = dlq["Fn::GetAtt"]; + const type = get(["Type"], resources[resourceName]); + if (attribute !== "Arn") return; + if (type !== "AWS::SQS::Queue") return; + return get(["Properties", "QueueName"], resources[resourceName]) + }), + compact, + )(resources); + } + async _getQueueUrl(queueName) { try { return await this.client.getQueueUrl({QueueName: queueName}).promise(); From 3fe6ba0d91e7e4a1cfec4a079ca7964aae7d7510 Mon Sep 17 00:00:00 2001 From: Jeison Azevedo Date: Mon, 17 May 2021 15:20:43 -0300 Subject: [PATCH 2/2] fix: linting fix --- packages/serverless-offline-sqs/src/index.js | 3 +- packages/serverless-offline-sqs/src/sqs.js | 44 +++++++++++++------- 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/packages/serverless-offline-sqs/src/index.js b/packages/serverless-offline-sqs/src/index.js index 3f673fb6..c7c03c6d 100644 --- a/packages/serverless-offline-sqs/src/index.js +++ b/packages/serverless-offline-sqs/src/index.js @@ -130,8 +130,7 @@ class ServerlessOfflineSQS { this.sqs = new SQS(this.lambda, resources, this.options); - await this.sqs.createDlq( - get(['service', 'resources', 'Resources'], this.serverless)); + await this.sqs.createDlq(get(['service', 'resources', 'Resources'], this.serverless)); await this.sqs.create(events); diff --git a/packages/serverless-offline-sqs/src/sqs.js b/packages/serverless-offline-sqs/src/sqs.js index 78be33bf..fba4b862 100644 --- a/packages/serverless-offline-sqs/src/sqs.js +++ b/packages/serverless-offline-sqs/src/sqs.js @@ -1,7 +1,18 @@ const {default: PQueue} = require('p-queue'); const SQSClient = require('aws-sdk/clients/sqs'); -// eslint-disable-next-line no-shadow -const {pipe, get, values, matches, find, mapValues, isPlainObject, toString, map, compact} = require('lodash/fp'); +const { + pipe, + get, + values, + matches, + find, + mapValues, + isPlainObject, + // eslint-disable-next-line no-shadow + toString, + map, + compact +} = require('lodash/fp'); const {logWarning} = require('serverless-offline/dist/serverlessLog'); const SQSEventDefinition = require('./sqs-event-definition'); const SQSEvent = require('./sqs-event'); @@ -53,26 +64,29 @@ class SQS { } _createDlq(resources) { - if (!this.options.autoCreate) return + if (!this.options.autoCreate) return; const dlqNames = this._getDlqNames(resources); - return Promise.all(dlqNames.map((queueName) => { - return this._createQueue({ queueName }); - })) + return Promise.all( + dlqNames.map(queueName => { + return this._createQueue({queueName}); + }) + ); } + // eslint-disable-next-line class-methods-use-this _getDlqNames(resources) { return pipe( values, - map((value) => { - const dlq = get(['Properties', 'RedrivePolicy', 'deadLetterTargetArn'], value) - if (!dlq) return - const [resourceName, attribute] = dlq["Fn::GetAtt"]; - const type = get(["Type"], resources[resourceName]); - if (attribute !== "Arn") return; - if (type !== "AWS::SQS::Queue") return; - return get(["Properties", "QueueName"], resources[resourceName]) + map(value => { + const dlq = get(['Properties', 'RedrivePolicy', 'deadLetterTargetArn'], value); + if (!dlq) return; + const [resourceName, attribute] = dlq['Fn::GetAtt']; + const type = get(['Type'], resources[resourceName]); + if (attribute !== 'Arn') return; + if (type !== 'AWS::SQS::Queue') return; + return get(['Properties', 'QueueName'], resources[resourceName]); }), - compact, + compact )(resources); }