Skip to content
This repository was archived by the owner on Nov 5, 2024. It is now read-only.

Commit 1865f90

Browse files
committed
Dead Letter Queue with properties. (gmetzker#29)
* Added ability to specify sqs as an object along with properties gmetzker#12 * Updated readme gmetzker#12
1 parent 3cb4971 commit 1865f90

3 files changed

Lines changed: 100 additions & 30 deletions

File tree

README.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,19 @@ Use the `deadLetter.sqs` to create a new dead letter queue for the function.
4949

5050
The resulting cloudformation stack will contain an SQS Queue and it's respective QueuePolicy.
5151

52+
#### Create new dead-letter queue by name
53+
```YAML
54+
# 'functions' in serverless.yml
55+
56+
functions:
57+
createUser: # Function name
58+
handler: handler.createUser # Reference to function 'createUser' in code
59+
60+
deadLetter:
61+
sqs: createUser-dl-queue # New Queue with this name
62+
```
5263

64+
#### Create new dead-letter queue with properties
5365
```YAML
5466
# 'functions' in serverless.yml
5567
@@ -58,7 +70,13 @@ functions:
5870
handler: handler.createUser # Reference to function 'createUser' in code
5971
6072
deadLetter:
61-
sqs: createUser-dl-queue
73+
sqs: # New Queue with these properties
74+
queueName: createUser-dl-queue
75+
delaySeconds: 60
76+
maximumMessageSize: 2048
77+
messageRetentionPeriod: 200000
78+
receiveMessageWaitTimeSeconds: 15
79+
visibilityTimeout: 300
6280
```
6381

6482
#### DeadLetter Topic

src/index.js

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -262,16 +262,35 @@ class Plugin {
262262
return `${this.normalizeFunctionName(functionName)}DeadLetterTopic`;
263263
}
264264

265+
static capitalizeFirstLetter(string) {
266+
return string.charAt(0).toUpperCase() + string.slice(1);
267+
}
268+
265269
compileFunctionDeadLetterQueue(functionName, queueConfig) {
266270

267-
if (typeof queueConfig !== 'string' && queueConfig !== null) {
268-
throw new Error(`Function property ${functionName}.deadLetter.sqs is an unexpected type. This must be a or string.`);
271+
const queueProps = { QueueName: '' };
272+
273+
if (typeof queueConfig === 'string' || queueConfig === null) {
274+
275+
queueProps.QueueName = (queueConfig || '').trim();
276+
277+
} else if (typeof queueConfig === 'object') {
278+
279+
Object.keys(queueConfig).forEach((key) => {
280+
if (Object.prototype.hasOwnProperty.call(queueConfig, key)) {
281+
queueProps[Plugin.capitalizeFirstLetter(key)] = queueConfig[key];
282+
}
283+
});
284+
285+
} else {
286+
287+
throw new Error(`Function property ${functionName}.deadLetter.sqs is an unexpected type. This must be an object or a string.`);
288+
269289
}
270290

271-
const queueName = (queueConfig || '').trim();
272291

273-
if (queueName.length < 1) {
274-
throw new Error(`Function property ${functionName}.deadLetter.sqs must contain one or more characters.`);
292+
if (queueProps.QueueName.length < 1) {
293+
throw new Error(`Function property ${functionName}.deadLetter.sqs queueName must contain one or more characters.`);
275294
}
276295

277296
const functionLogicalId = this.provider.naming.getLambdaLogicalId(functionName);
@@ -281,9 +300,7 @@ class Plugin {
281300

282301
const queueResource = {
283302
Type: 'AWS::SQS::Queue',
284-
Properties: {
285-
QueueName: queueName
286-
}
303+
Properties: queueProps
287304
};
288305

289306
const queuePolicyResource = {

tests/index.test.js

Lines changed: 56 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,28 @@ const BbPromise = require('bluebird');
77

88
describe('serverless-plugin-lambda-dead-letter', () => {
99

10+
function getNormalizedFunctionName(functionName) {
11+
12+
// Copied from https://github.com/serverless/serverless/blob/master/lib/plugins/aws/lib/naming.js
13+
// See: serverless/lib/plugins/aws/lib/naming.js/getNormalizedFunctionName
14+
let result = functionName
15+
.replace(/-/g, 'Dash')
16+
.replace(/_/g, 'Underscore');
17+
18+
if (result !== '') {
19+
result = result[0].toUpperCase() + result.substr(1);
20+
}
21+
return result;
22+
}
1023

1124
function createMockServerless(requestFunc) {
1225

1326
const provider = {
1427
request: requestFunc,
1528
naming: {
1629
getStackName: () => 'MyCoolStack',
17-
getNormalizedFunctionName: getNormalizedFunctionName,
18-
getLambdaLogicalId: (functionName) => `${getNormalizedFunctionName(functionName)}LambdaFunction`
30+
getNormalizedFunctionName,
31+
getLambdaLogicalId: functionName => `${getNormalizedFunctionName(functionName)}LambdaFunction`
1932
}
2033
};
2134

@@ -46,20 +59,6 @@ describe('serverless-plugin-lambda-dead-letter', () => {
4659

4760
}
4861

49-
function getNormalizedFunctionName(functionName) {
50-
51-
// Copied from https://github.com/serverless/serverless/blob/master/lib/plugins/aws/lib/naming.js
52-
// See: serverless/lib/plugins/aws/lib/naming.js/getNormalizedFunctionName
53-
let result = functionName
54-
.replace(/-/g, 'Dash')
55-
.replace(/_/g, 'Underscore');
56-
57-
if (result !== '') {
58-
result = result[0].toUpperCase() + result.substr(1);
59-
}
60-
return result;
61-
}
62-
6362
function createMockRequest(requestStub) {
6463

6564
return () => {
@@ -1291,7 +1290,7 @@ describe('serverless-plugin-lambda-dead-letter', () => {
12911290
});
12921291

12931292
describe('compileFunctionDeadLetterQueue', () => {
1294-
it('throws an error of deadLetter.sqs is not a string', () => {
1293+
it('throws an error of deadLetter.sqs is not a string or object', () => {
12951294

12961295
// ARRANGE:
12971296
const stage = 'test1';
@@ -1301,11 +1300,11 @@ describe('serverless-plugin-lambda-dead-letter', () => {
13011300
const plugin = new Plugin(mockServerless, { stage, region });
13021301

13031302
// ACT:
1304-
const act = () => plugin.compileFunctionDeadLetterQueue('f1', { });
1303+
const act = () => plugin.compileFunctionDeadLetterQueue('f1', 123);
13051304

13061305
// ASSERT:
13071306
expect(act).throwException((e) => {
1308-
expect(e.message).to.contain('deadLetter.sqs is an unexpected type. This must be a or string.');
1307+
expect(e.message).to.contain('deadLetter.sqs is an unexpected type. This must be an object or a string.');
13091308
});
13101309

13111310
});
@@ -1328,13 +1327,13 @@ describe('serverless-plugin-lambda-dead-letter', () => {
13281327

13291328
// ASSERT:
13301329
expect(act).throwException((e) => {
1331-
expect(e.message).to.contain('deadLetter.sqs must contain one or more characters');
1330+
expect(e.message).to.contain('deadLetter.sqs queueName must contain one or more characters');
13321331
});
13331332

13341333
});
13351334

13361335
});
1337-
it('assigns SQS resource', () => {
1336+
it('can compile SQS resource when sqs is a string', () => {
13381337

13391338
// ARRANGE:
13401339
const stage = 'test1';
@@ -1358,6 +1357,42 @@ describe('serverless-plugin-lambda-dead-letter', () => {
13581357
});
13591358
});
13601359

1360+
it('can compile SQS resource when sqs is an object', () => {
1361+
1362+
// ARRANGE:
1363+
const stage = 'test1';
1364+
const region = 'us-west-42';
1365+
1366+
const mockServerless = createMockServerless(createMockRequest(sinon.stub()));
1367+
const plugin = new Plugin(mockServerless, { stage, region });
1368+
1369+
// ACT:
1370+
plugin.compileFunctionDeadLetterQueue('f1', {
1371+
queueName: 'MySqs',
1372+
delaySeconds: 60,
1373+
maximumMessageSize: 2048,
1374+
messageRetentionPeriod: 200000,
1375+
receiveMessageWaitTimeSeconds: 15,
1376+
visibilityTimeout: 300
1377+
});
1378+
1379+
// ASSERT:
1380+
const resources = mockServerless.service.provider.compiledCloudFormationTemplate.Resources;
1381+
1382+
expect(resources).to.have.key('F1DeadLetterQueue');
1383+
expect(resources.F1DeadLetterQueue).to.eql({
1384+
Type: 'AWS::SQS::Queue',
1385+
Properties: {
1386+
QueueName: 'MySqs',
1387+
DelaySeconds: 60,
1388+
MaximumMessageSize: 2048,
1389+
MessageRetentionPeriod: 200000,
1390+
ReceiveMessageWaitTimeSeconds: 15,
1391+
VisibilityTimeout: 300
1392+
}
1393+
});
1394+
});
1395+
13611396
it('assigns SQS Policy resource', () => {
13621397

13631398
// ARRANGE:

0 commit comments

Comments
 (0)