From 594861e73f8fbb7e2e99e70ec8d2373981e94fc9 Mon Sep 17 00:00:00 2001 From: abetomo Date: Tue, 11 Apr 2017 15:21:39 +0900 Subject: [PATCH 1/4] Fix to use authenticated `aws` object in main.js --- lib/schedule_events.js | 56 +++++++++++++++++++++++------------------ test/schedule_events.js | 3 ++- 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/lib/schedule_events.js b/lib/schedule_events.js index 116fb4c7..c24f8ce9 100644 --- a/lib/schedule_events.js +++ b/lib/schedule_events.js @@ -1,14 +1,16 @@ 'use strict'; -const aws = require('aws-sdk'); -const lambda = new aws.Lambda({ - apiVersion: '2015-03-31' -}); -const cloudwatchevents = new aws.CloudWatchEvents({ - apiVersion: '2015-10-07' -}); +const ScheduleEvents = function(aws) { + // Authenticated `aws` object in `lib/main.js` + this.lambda = new aws.Lambda({ + apiVersion: '2015-03-31' + }); + this.cloudwatchevents = new aws.CloudWatchEvents({ + apiVersion: '2015-10-07' + }); +}; -const ScheduleEvents = { +ScheduleEvents.prototype = { _ruleDescription: (params) => { return `${params.ScheduleName} - ${params.ScheduleExpression}`; }, @@ -17,20 +19,21 @@ const ScheduleEvents = { return params.FunctionArnPrefix + params.FunctionName; }, - _putRulePrams: (params) => { + _putRulePrams: function(params) { return { Name: params.ScheduleName, - Description: ScheduleEvents._ruleDescription(params), + Description: this._ruleDescription(params), State: params.ScheduleState, ScheduleExpression: params.ScheduleExpression }; }, - _putRule: (params) => { + _putRule: function(params) { + const _this = this; // return RuleArn if created return new Promise((resolve) => { - const _params = ScheduleEvents._putRulePrams(params); - cloudwatchevents.putRule(_params, (err, rule) => { + const _params = _this._putRulePrams(params); + _this.cloudwatchevents.putRule(_params, (err, rule) => { if (err) throw err; resolve(rule); }); @@ -47,10 +50,11 @@ const ScheduleEvents = { }; }, - _addPermission: (params) => { + _addPermission: function(params) { + const _this = this; return new Promise((resolve) => { - const _params = ScheduleEvents._addPermissionParams(params); - lambda.addPermission(_params, (err, data) => { + const _params = _this._addPermissionParams(params); + _this.lambda.addPermission(_params, (err, data) => { if (err) { if (err.code != 'ResourceConflictException') throw err; // If it exists it will result in an error but there is no problem. @@ -61,20 +65,21 @@ const ScheduleEvents = { }); }, - _putTargetsParams: (params) => { + _putTargetsParams: function(params) { return { Rule: params.ScheduleName, Targets: [{ - Arn: ScheduleEvents._functionArn(params), + Arn: this._functionArn(params), Id: params.FunctionName }] }; }, - _putTargets: (params) => { + _putTargets: function(params) { + const _this = this; return new Promise((resolve) => { - const _params = ScheduleEvents._putTargetsParams(params); - cloudwatchevents.putTargets(_params, (err, data) => { + const _params = _this._putTargetsParams(params); + _this.cloudwatchevents.putTargets(_params, (err, data) => { // even if it is already registered, it will not be an error. if (err) throw(err); resolve(data); @@ -82,13 +87,14 @@ const ScheduleEvents = { }); }, - add: (params) => { + add: function(params) { + const _this = this; return Promise.resolve().then(() => { - return ScheduleEvents._putRule(params); + return _this._putRule(params); }).then((rule) => { - return ScheduleEvents._addPermission(Object.assign(params, rule)); + return _this._addPermission(Object.assign(params, rule)); }).then((data) => { - return ScheduleEvents._putTargets(params); + return _this._putTargets(params); }); }, }; diff --git a/test/schedule_events.js b/test/schedule_events.js index 0f1df1ed..001f9b1a 100644 --- a/test/schedule_events.js +++ b/test/schedule_events.js @@ -4,6 +4,7 @@ const assert = require('chai').assert; const path = require('path'); const aws = require('aws-sdk-mock'); aws.setSDK(path.resolve('node_modules/aws-sdk')); +const ScheduleEvents = require(path.join('..', 'lib', 'schedule_events')); const params = { FunctionName: 'node-lambda-test-function', @@ -49,7 +50,7 @@ describe('schedule_events', () => { callback(null, mockResponse.addPermission); }); - schedule = require(path.join('..', 'lib', 'schedule_events')); + schedule = new ScheduleEvents(require('aws-sdk')); }); describe('_ruleDescription', () => { From 332e780b1bbed8efb5f1ea7c38f6c08f8babf268 Mon Sep 17 00:00:00 2001 From: abetomo Date: Tue, 11 Apr 2017 17:31:41 +0900 Subject: [PATCH 2/4] Fix to enable ScheduleEvents to be specified in event_sources.json --- lib/event_sources.json.example | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/lib/event_sources.json.example b/lib/event_sources.json.example index 8944af9f..6e774869 100644 --- a/lib/event_sources.json.example +++ b/lib/event_sources.json.example @@ -1,8 +1,18 @@ -[ +{ + "EventSourceMappings": [ { - "EventSourceArn": "your event source arn", - "StartingPosition": "LATEST", - "BatchSize": 100, - "Enabled": true + "EventSourceArn": "your event source arn", + "StartingPosition": "LATEST", + "BatchSize": 100, + "Enabled": true } -] \ No newline at end of file + ], + "ScheduleEvents": [ + { + "FunctionArnPrefix": "arn:aws:lambda:us-west-2:XXX:function:", + "ScheduleName": "node-lambda-test-schedule", + "ScheduleState": "ENABLED", + "ScheduleExpression": "rate(1 hour)" + } + ] +} From f276d8d5764cfabd8c05058d9a60f1c964b172ec Mon Sep 17 00:00:00 2001 From: abetomo Date: Tue, 11 Apr 2017 17:42:40 +0900 Subject: [PATCH 3/4] Supports new event_sources.json format --- lib/main.js | 26 ++++++++++++---- test/main.js | 88 +++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 97 insertions(+), 17 deletions(-) diff --git a/lib/main.js b/lib/main.js index 9ddfeb41..0687a059 100644 --- a/lib/main.js +++ b/lib/main.js @@ -147,11 +147,25 @@ Lambda.prototype._eventSourceList = function (program) { if (!program.eventSourceFile) { return []; } - try { - return fs.readJsonSync(program.eventSourceFile); - } catch(err) { - throw err; + const list = (function() { + try { + return fs.readJsonSync(program.eventSourceFile); + } catch(err) { + throw err; + } + })(); + + if (Object.prototype.toString.call(list) === '[object Array]') { + // backward-compatible + return { EventSourceMappings: list }; + } + if (!list.EventSourceMappings) { + list.EventSourceMappings = []; + } + if (!list.ScheduleEvents) { + list.ScheduleEvents = []; } + return list; }; /** @@ -607,7 +621,7 @@ Lambda.prototype.deploy = function (program) { console.log(results); // Updating event source(s) - _this._updateEventSources(lambda, params.FunctionName, [], eventSourceList, function(err, results) { + _this._updateEventSources(lambda, params.FunctionName, [], eventSourceList.EventSourceMappings, function(err, results) { cb(null, results); }); }); @@ -632,7 +646,7 @@ Lambda.prototype.deploy = function (program) { }); }, function(_callback) { - _this._updateEventSources(lambda, params.FunctionName, existingEventSourceList, eventSourceList, function(err, results) { + _this._updateEventSources(lambda, params.FunctionName, existingEventSourceList, eventSourceList.EventSourceMappings, function(err, results) { _callback(err, results); }); } diff --git a/test/main.js b/test/main.js index addc05c7..cf4c5b74 100644 --- a/test/main.js +++ b/test/main.js @@ -510,17 +510,6 @@ describe('node-lambda', function () { assert.deepEqual(lambda._eventSourceList(program), []); }); - it('program.eventSourceFile is valid value', function () { - program.eventSourceFile = 'event_sources.json'; - const expected = [{ - BatchSize: 100, - Enabled: true, - EventSourceArn: 'your event source arn', - StartingPosition: 'LATEST', - }]; - assert.deepEqual(lambda._eventSourceList(program), expected); - }); - it('program.eventSourceFile is invalid value', function () { program.eventSourceFile = '/hoge/fuga'; assert.throws( @@ -529,6 +518,83 @@ describe('node-lambda', function () { "ENOENT: no such file or directory, open '/hoge/fuga'" ); }); + + describe('program.eventSourceFile is valid value', function() { + before(function () { + fs.writeFileSync('only_EventSourceMappings.json', JSON.stringify({ + EventSourceMappings: [{ test: 1 }] + })); + fs.writeFileSync('only_ScheduleEvents.json', JSON.stringify({ + ScheduleEvents: [{ test: 2 }] + })); + }); + + after(function () { + fs.unlinkSync('only_EventSourceMappings.json'); + fs.unlinkSync('only_ScheduleEvents.json'); + }); + + it('only EventSourceMappings', function () { + program.eventSourceFile = 'only_EventSourceMappings.json'; + const expected = { + EventSourceMappings: [{ test: 1 }], + ScheduleEvents: [], + }; + assert.deepEqual(lambda._eventSourceList(program), expected); + }); + + it('only ScheduleEvents', function () { + program.eventSourceFile = 'only_ScheduleEvents.json'; + const expected = { + EventSourceMappings: [], + ScheduleEvents: [{ test: 2 }], + }; + assert.deepEqual(lambda._eventSourceList(program), expected); + }); + + it('EventSourceMappings & ScheduleEvents', function () { + program.eventSourceFile = 'event_sources.json'; + const expected = { + EventSourceMappings: [{ + BatchSize: 100, + Enabled: true, + EventSourceArn: 'your event source arn', + StartingPosition: 'LATEST', + }], + ScheduleEvents: [{ + FunctionArnPrefix: 'arn:aws:lambda:us-west-2:XXX:function:', + ScheduleName: 'node-lambda-test-schedule', + ScheduleState: 'ENABLED', + ScheduleExpression: 'rate(1 hour)', + }], + }; + assert.deepEqual(lambda._eventSourceList(program), expected); + }); + }); + + describe('old style event_sources.json', function () { + const oldStyleValue = [{ + BatchSize: 100, + Enabled: true, + EventSourceArn: 'your event source arn', + StartingPosition: 'LATEST', + }]; + const fileName = 'event_sources_old_style.json'; + + before(function () { + fs.writeFileSync(fileName, JSON.stringify(oldStyleValue)); + }); + + after(function () { + fs.unlinkSync(fileName); + }); + + it('program.eventSourceFile is valid value', function () { + program.eventSourceFile = fileName; + const expected = { EventSourceMappings: oldStyleValue }; + assert.deepEqual(lambda._eventSourceList(program), expected); + }); + }); }); }); From 2436d15c0383afc7276ce5edf19e496ea714b1d6 Mon Sep 17 00:00:00 2001 From: abetomo Date: Wed, 12 Apr 2017 16:05:31 +0900 Subject: [PATCH 4/4] modify default value to new format --- lib/main.js | 5 ++++- test/main.js | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/main.js b/lib/main.js index 0687a059..46df3f8a 100644 --- a/lib/main.js +++ b/lib/main.js @@ -145,7 +145,10 @@ Lambda.prototype._params = function (program, buffer) { Lambda.prototype._eventSourceList = function (program) { if (!program.eventSourceFile) { - return []; + return { + EventSourceMappings: [], + ScheduleEvents: [] + }; } const list = (function() { try { diff --git a/test/main.js b/test/main.js index cf4c5b74..1c8713cd 100644 --- a/test/main.js +++ b/test/main.js @@ -507,7 +507,10 @@ describe('node-lambda', function () { describe('_eventSourceList', function () { it('program.eventSourceFile is empty value', function () { program.eventSourceFile = ''; - assert.deepEqual(lambda._eventSourceList(program), []); + assert.deepEqual( + lambda._eventSourceList(program), + { EventSourceMappings: [], ScheduleEvents: [] } + ); }); it('program.eventSourceFile is invalid value', function () {