Skip to content

Commit e34799e

Browse files
starlightsloDeviaVir
authored andcommitted
Added event source mapping feature. (#189)
1 parent 80564ea commit e34799e

File tree

3 files changed

+161
-5
lines changed

3 files changed

+161
-5
lines changed

bin/node-lambda

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ dotenv.load();
1212

1313
var AWS_ENVIRONMENT = process.env.AWS_ENVIRONMENT || '';
1414
var CONFIG_FILE = process.env.CONFIG_FILE || '';
15+
var EVENT_SOURCE_FILE = process.env.EVENT_SOURCE_FILE || 'event_sources.json';
1516
var EXCLUDE_GLOBS = process.env.EXCLUDE_GLOBS || '';
1617
var AWS_ACCESS_KEY_ID = process.env.AWS_ACCESS_KEY_ID;
1718
var AWS_SECRET_ACCESS_KEY = process.env.AWS_SECRET_ACCESS_KEY;
@@ -61,6 +62,8 @@ program
6162
.option('-A, --packageDirectory [' + PACKAGE_DIRECTORY + ']', 'Local Package Directory', PACKAGE_DIRECTORY)
6263
.option('-f, --configFile [' + CONFIG_FILE + ']',
6364
'Path to file holding secret environment variables (e.g. "deploy.env")', CONFIG_FILE)
65+
.option('-S, --eventSourceFile [' + EVENT_SOURCE_FILE + ']',
66+
'Path to file holding event source mapping variables (e.g. "event_sources.json")', EVENT_SOURCE_FILE)
6467
.option('-x, --excludeGlobs [' + EXCLUDE_GLOBS + ']',
6568
'Space-separated glob pattern(s) for additional exclude files (e.g. "event.json dotenv.sample")', EXCLUDE_GLOBS)
6669
.option('-D, --prebuiltDirectory [' + PREBUILT_DIRECTORY + ']', 'Prebuilt directory', PREBUILT_DIRECTORY)

lib/event_sources.json.example

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[
2+
{
3+
"EventSourceArn": "your event source arn",
4+
"StartingPosition": "LATEST",
5+
"BatchSize": 100,
6+
"Enabled": true
7+
}
8+
]

lib/main.js

Lines changed: 150 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ Lambda.prototype.setup = function (program) {
3434
this._createSampleFile(program.eventFile, 'event.json');
3535
this._createSampleFile('deploy.env', 'deploy.env');
3636
this._createSampleFile(program.contextFile, 'context.json');
37+
this._createSampleFile('event_sources.json', 'event_sources.json');
3738
console.log('Setup done. Edit the .env, deploy.env, ' + program.contextFile + ' and ' + program.eventFile +
3839
' files as needed.');
3940
};
@@ -133,6 +134,20 @@ Lambda.prototype._params = function (program, buffer) {
133134
return params;
134135
};
135136

137+
Lambda.prototype._eventSourceList = function (program) {
138+
var eventSourceList = []
139+
if (program.eventSourceFile) {
140+
try {
141+
eventSourceList = fs.readJsonSync(program.eventSourceFile);
142+
} catch(err) {
143+
eventSourceList = [];
144+
throw err;
145+
}
146+
}
147+
148+
return eventSourceList;
149+
};
150+
136151
/**
137152
* @deprecated
138153
*/
@@ -395,6 +410,93 @@ Lambda.prototype._buildAndArchive = function (program, archive_callback) {
395410
});
396411
};
397412

413+
Lambda.prototype._listEventSourceMappings = function (lambda, params, cb) {
414+
return lambda.listEventSourceMappings(params, function (err, data) {
415+
var eventSourceMappings = [];
416+
if (!err && data && data.EventSourceMappings) {
417+
eventSourceMappings = data.EventSourceMappings;
418+
}
419+
return cb(err, eventSourceMappings);
420+
});
421+
};
422+
423+
Lambda.prototype._updateEventSources = function (lambda, functionName, existingEventSourceList, eventSourceList, cb) {
424+
var updateEventSourceList = [];
425+
// Checking new and update event sources
426+
for (var i in eventSourceList) {
427+
var isExisting = false;
428+
for (var j in existingEventSourceList) {
429+
if (eventSourceList[i]['EventSourceArn'] === existingEventSourceList[j]['EventSourceArn']) {
430+
isExisting = true;
431+
updateEventSourceList.push({
432+
'type': 'update',
433+
'FunctionName': functionName,
434+
'Enabled': eventSourceList[i]['Enabled'],
435+
'BatchSize': eventSourceList[i]['BatchSize'],
436+
'UUID': existingEventSourceList[j]['UUID']
437+
});
438+
break;
439+
}
440+
}
441+
442+
// If it is new source
443+
if (!isExisting) {
444+
updateEventSourceList.push({
445+
'type': 'create',
446+
'FunctionName': functionName,
447+
'EventSourceArn': eventSourceList[i]['EventSourceArn'],
448+
'Enabled': eventSourceList[i]['Enabled'] ? eventSourceList[i]['Enabled'] : false,
449+
'BatchSize': eventSourceList[i]['BatchSize'] ? eventSourceList[i]['BatchSize'] : 100,
450+
'StartingPosition': eventSourceList[i]['StartingPosition'] ? eventSourceList[i]['StartingPosition'] : 'LATEST',
451+
});
452+
}
453+
}
454+
455+
// Checking delete event sources
456+
for (var i in existingEventSourceList) {
457+
var isExisting = false;
458+
for (var j in eventSourceList) {
459+
if (eventSourceList[j]['EventSourceArn'] === existingEventSourceList[i]['EventSourceArn']) {
460+
isExisting = true;
461+
break;
462+
}
463+
}
464+
465+
// If delete the source
466+
if (!isExisting) {
467+
updateEventSourceList.push({
468+
'type': 'delete',
469+
'UUID': existingEventSourceList[i]['UUID']
470+
});
471+
}
472+
}
473+
474+
return async.map(updateEventSourceList, function (updateEventSource, _cb) {
475+
switch(updateEventSource['type']) {
476+
case 'create':
477+
delete updateEventSource['type'];
478+
lambda.createEventSourceMapping(updateEventSource, function (err, data) {
479+
return _cb(err, data);
480+
});
481+
break;
482+
case 'update':
483+
delete updateEventSource['type'];
484+
lambda.updateEventSourceMapping(updateEventSource, function (err, data) {
485+
return _cb(err, data);
486+
});
487+
break;
488+
case 'delete':
489+
delete updateEventSource['type'];
490+
lambda.deleteEventSourceMapping(updateEventSource, function (err, data) {
491+
return _cb(err, data);
492+
});
493+
break;
494+
}
495+
}, function(err, results) {
496+
return cb(err, results);
497+
});
498+
};
499+
398500
Lambda.prototype.package = function (program) {
399501
var _this = this;
400502
if (!program.packageDirectory) {
@@ -444,6 +546,9 @@ Lambda.prototype.deploy = function (program) {
444546
console.log('=> Reading zip file to memory');
445547
var params = _this._params(program, buffer);
446548

549+
console.log('=> Reading event source file to memory');
550+
var eventSourceList = _this._eventSourceList(program);
551+
447552
async.map(regions, function (region, cb) {
448553
console.log('=> Uploading zip file to AWS Lambda ' + region + ' with parameters:');
449554
console.log(params);
@@ -471,20 +576,60 @@ Lambda.prototype.deploy = function (program) {
471576
apiVersion: '2015-03-31'
472577
});
473578

579+
// Checking function
474580
return lambda.getFunction({
475581
'FunctionName': params.FunctionName
476582
}, function (err) {
477-
if(err) {
478-
return _this._uploadNew(lambda, params, cb);
583+
if (err) {
584+
return _this._uploadNew(lambda, params, function(err, results) {
585+
if (err) {
586+
throw err;
587+
} else {
588+
console.log('=> Zip file(s) done uploading. Results follow: ');
589+
console.log(results);
590+
591+
// Updating event source(s)
592+
_this._updateEventSources(lambda, params.FunctionName, [], eventSourceList, function(err, results) {
593+
cb(null, results);
594+
});
595+
}
596+
});
597+
} else {
598+
_this._listEventSourceMappings(lambda, {
599+
'FunctionName': params.FunctionName
600+
}, function(err, existingEventSourceList) {
601+
if (err) {
602+
throw err;
603+
} else {
604+
return async.parallel([
605+
function(_callback) {
606+
_this._uploadExisting(lambda, params, function(err, results) {
607+
if (err) {
608+
throw err;
609+
} else {
610+
console.log('=> Zip file(s) done uploading. Results follow: ');
611+
console.log(results);
612+
_callback(err, results);
613+
}
614+
})
615+
},
616+
function(_callback) {
617+
_this._updateEventSources(lambda, params.FunctionName, existingEventSourceList, eventSourceList, function(err, results) {
618+
_callback(err, results)
619+
})
620+
}
621+
], function(err, results) {
622+
cb(err, results);
623+
});
624+
}
625+
});
479626
}
480-
481-
return _this._uploadExisting(lambda, params, cb);
482627
});
483628
}, function (err, results) {
484629
if (err) {
485630
throw err;
486631
} else {
487-
console.log('=> Zip file(s) done uploading. Results follow: ');
632+
console.log('=> All tasks done. Results follow: ');
488633
console.log(results);
489634
}
490635
});

0 commit comments

Comments
 (0)