-
Notifications
You must be signed in to change notification settings - Fork 233
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit bca7fb8
Showing
6 changed files
with
368 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
/dynamodb/bin | ||
/node_modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# Serverless plugin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
"use strict"; | ||
|
||
var spawn = require('child_process').spawn | ||
, fs = require('fs') | ||
, Q = require('q') | ||
, installer = require('./installer'); | ||
|
||
const DOWNLOAD_PATH = 'http://dynamodb-local.s3-website-us-west-2.amazonaws.com/dynamodb_local_latest.tar.gz' | ||
, JAR = 'DynamoDBLocal.jar' | ||
, DB_PATH = './bin'; | ||
|
||
var runningProcesses = {} | ||
, dynamodb = { | ||
/** | ||
* | ||
* @param port | ||
* @param dbPath if omitted will use in memory | ||
* @param additionalArgs | ||
* @returns {Promise.<ChildProcess>} | ||
*/ | ||
launch: function (port, dbPath, additionalArgs) { | ||
if (runningProcesses[port]) { | ||
return Q.fcall(function () { | ||
return runningProcesses[port]; | ||
}); | ||
} | ||
|
||
if (!additionalArgs) { | ||
additionalArgs = []; | ||
} else if (Array.isArray(additionalArgs)) { | ||
additionalArgs = [additionalArgs]; | ||
} | ||
|
||
if (!dbPath) { | ||
additionalArgs.push('-inMemory'); | ||
} else { | ||
additionalArgs.push('-dbPath', dbPath); | ||
} | ||
|
||
return installer.install(DB_PATH, DOWNLOAD_PATH, JAR) | ||
.then(function () { | ||
var args = [ | ||
'-Djava.library.path=./DynamoDBLocal_lib', '-jar', JAR, '-port', port | ||
]; | ||
args = args.concat(additionalArgs); | ||
|
||
var child = spawn('java', args, { | ||
cwd: DB_PATH | ||
, env: process.env | ||
, stdio: ['pipe', 'pipe', process.stderr] | ||
}); | ||
|
||
if (!child.pid) throw new Error("Unable to launch DynamoDBLocal process"); | ||
|
||
child | ||
.on('error', function (err) { | ||
console.log("local DynamoDB start error", err); | ||
throw new Error("Local DynamoDB failed to start. "); | ||
}) | ||
.on('close', function (code) { | ||
if (code !== null && code !== 0) { | ||
console.log('Local DynamoDB failed to start with code', code); | ||
} | ||
}); | ||
|
||
runningProcesses[port] = child; | ||
|
||
console.log("DynamoDbLocal(" + child.pid + ") started on port", port, "via java", args.join(' '), "from CWD", DB_PATH); | ||
|
||
return child; | ||
}); | ||
} | ||
, stop: function (port) { | ||
if (runningProcesses[port]) { | ||
runningProcesses[port].kill('SIGKILL'); | ||
delete runningProcesses[port]; | ||
} | ||
} | ||
, relaunch: function (port, db) { | ||
this.stop(port); | ||
this.launch(port, db); | ||
} | ||
}; | ||
module.exports = dynamodb; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
'use strict'; | ||
|
||
/* TODO: Replace Q with 'bluebird' promise */ | ||
var Q = require('q') | ||
, tar = require('tar') | ||
, zlib = require('zlib') | ||
, path = require('path') | ||
, http = require('http') | ||
, fs = require('fs'); | ||
|
||
var install = function (dbPath, downloadPath, jar) { | ||
console.log("Checking for ", dbPath); | ||
var deferred = Q.defer(); | ||
|
||
try { | ||
if (fs.existsSync(path.join(dbPath, jar))) { | ||
return Q.fcall(function () { | ||
return true; | ||
}); | ||
} | ||
} catch (e) {} | ||
|
||
console.log("DynamoDb Local not installed. Installing..."); | ||
|
||
if (!fs.existsSync(dbPath)) | ||
fs.mkdirSync(dbPath); | ||
|
||
http.get(downloadPath, function (response) { | ||
if (302 != response.statusCode) { | ||
deferred.reject(new Error("Error getting DynamoDb local latest tar.gz location: " + response.statusCode)); | ||
} | ||
|
||
http.get(response.headers['location'], function (redirectResponse) { | ||
if (200 != redirectResponse.statusCode) { | ||
deferred.reject(new Error("Error getting DynamoDb local latest tar.gz location " + response.headers['location'] + ": " + redirectResponse.statusCode)); | ||
} | ||
redirectResponse | ||
.pipe(zlib.Unzip()) | ||
.pipe(tar.Extract({ | ||
path: dbPath | ||
})) | ||
.on('end', function () { | ||
deferred.resolve(); | ||
}) | ||
.on('error', function (err) { | ||
deferred.reject(err); | ||
}); | ||
}) | ||
.on('error', function (e) { | ||
deferred.reject(e); | ||
}); | ||
}) | ||
.on('error', function (e) { | ||
deferred.reject(e); | ||
}); | ||
|
||
return deferred.promise; | ||
} | ||
module.exports.install = install; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
'use strict'; | ||
|
||
/** | ||
* Serverless Plugin Boilerplate | ||
* - Useful example/starter code for writing a plugin for the Serverless Framework. | ||
* - In a plugin, you can: | ||
* - Manipulate Serverless classes | ||
* - Create a Custom Action that can be called via the CLI or programmatically via a function handler. | ||
* - Overwrite a Core Action that is included by default in the Serverless Framework. | ||
* - Add a hook that fires before or after a Core Action or a Custom Action | ||
* - All of the above at the same time :) | ||
* | ||
* - Setup: | ||
* - Make a Serverless Project dedicated for plugin development, or use an existing Serverless Project | ||
* - Make a "plugins" folder in the root of your Project and copy this codebase into it. Title it your custom plugin name with the suffix "-dev", like "myplugin-dev" | ||
* | ||
*/ | ||
|
||
const path = require('path'), | ||
fs = require('fs'), | ||
BbPromise = require('bluebird'); // Serverless uses Bluebird Promises and we recommend you do to because they provide more than your average Promise :) | ||
|
||
module.exports = function(S) { // Always pass in the ServerlessPlugin Class | ||
|
||
/** | ||
* Adding/Manipulating Serverless classes | ||
* - You can add or manipulate Serverless classes like this | ||
*/ | ||
|
||
S.classes.Project.newStaticMethod = function() { console.log("A new method!"); }; | ||
S.classes.Project.prototype.newMethod = function() { S.classes.Project.newStaticMethod(); }; | ||
|
||
/** | ||
* Extending the Plugin Class | ||
* - Here is how you can add custom Actions and Hooks to Serverless. | ||
* - This class is only required if you want to add Actions and Hooks. | ||
*/ | ||
|
||
class PluginBoilerplate extends S.classes.Plugin { | ||
|
||
/** | ||
* Constructor | ||
* - Keep this and don't touch it unless you know what you're doing. | ||
*/ | ||
|
||
constructor() { | ||
super(); | ||
this.name = 'myPlugin'; // Define your plugin's name | ||
} | ||
|
||
/** | ||
* Register Actions | ||
* - If you would like to register a Custom Action or overwrite a Core Serverless Action, add this function. | ||
* - If you would like your Action to be used programatically, include a "handler" which can be called in code. | ||
* - If you would like your Action to be used via the CLI, include a "description", "context", "action" and any options you would like to offer. | ||
* - Your custom Action can be called programatically and via CLI, as in the example provided below | ||
*/ | ||
|
||
registerActions() { | ||
|
||
S.addAction(this._customAction.bind(this), { | ||
handler: 'customAction', | ||
description: 'A custom action from a custom plugin', | ||
context: 'custom', | ||
contextAction: 'run', | ||
options: [{ // These must be specified in the CLI like this "-option true" or "-o true" | ||
option: 'option', | ||
shortcut: 'o', | ||
description: 'test option 1' | ||
}], | ||
parameters: [ // Use paths when you multiple values need to be input (like an array). Input looks like this: "serverless custom run module1/function1 module1/function2 module1/function3. Serverless will automatically turn this into an array and attach it to evt.options within your plugin | ||
{ | ||
parameter: 'paths', | ||
description: 'One or multiple paths to your function', | ||
position: '0->' // Can be: 0, 0-2, 0-> This tells Serverless which params are which. 3-> Means that number and infinite values after it. | ||
} | ||
] | ||
}); | ||
|
||
return BbPromise.resolve(); | ||
} | ||
|
||
/** | ||
* Register Hooks | ||
* - If you would like to register hooks (i.e., functions) that fire before or after a core Serverless Action or your Custom Action, include this function. | ||
* - Make sure to identify the Action you want to add a hook for and put either "pre" or "post" to describe when it should happen. | ||
*/ | ||
|
||
registerHooks() { | ||
|
||
S.addHook(this._hookPre.bind(this), { | ||
action: 'functionRun', | ||
event: 'pre' | ||
}); | ||
|
||
S.addHook(this._hookPost.bind(this), { | ||
action: 'functionRun', | ||
event: 'post' | ||
}); | ||
|
||
return BbPromise.resolve(); | ||
} | ||
|
||
/** | ||
* Custom Action Example | ||
* - Here is an example of a Custom Action. Include this and modify it if you would like to write your own Custom Action for the Serverless Framework. | ||
* - Be sure to ALWAYS accept and return the "evt" object, or you will break the entire flow. | ||
* - The "evt" object contains Action-specific data. You can add custom data to it, but if you change any data it will affect subsequent Actions and Hooks. | ||
* - You can also access other Project-specific data @ this.S Again, if you mess with data on this object, it could break everything, so make sure you know what you're doing ;) | ||
*/ | ||
|
||
_customAction(evt) { | ||
|
||
let _this = this; | ||
|
||
return new BbPromise(function (resolve, reject) { | ||
|
||
// console.log(evt) // Contains Action Specific data | ||
// console.log(_this.S) // Contains Project Specific data | ||
// console.log(_this.S.state) // Contains tons of useful methods for you to use in your plugin. It's the official API for plugin developers. | ||
|
||
console.log('-------------------'); | ||
console.log('YOU JUST RAN YOUR CUSTOM ACTION, NICE!'); | ||
console.log('-------------------'); | ||
|
||
return resolve(evt); | ||
|
||
}); | ||
} | ||
|
||
/** | ||
* Your Custom PRE Hook | ||
* - Here is an example of a Custom PRE Hook. Include this and modify it if you would like to write your a hook that fires BEFORE an Action. | ||
* - Be sure to ALWAYS accept and return the "evt" object, or you will break the entire flow. | ||
* - The "evt" object contains Action-specific data. You can add custom data to it, but if you change any data it will affect subsequent Actions and Hooks. | ||
* - You can also access other Project-specific data @ this.S Again, if you mess with data on this object, it could break everything, so make sure you know what you're doing ;) | ||
*/ | ||
|
||
_hookPre(evt) { | ||
|
||
let _this = this; | ||
|
||
return new BbPromise(function (resolve, reject) { | ||
|
||
console.log('-------------------'); | ||
console.log('YOUR SERVERLESS PLUGIN\'S CUSTOM "PRE" HOOK HAS RUN BEFORE "FunctionRun"'); | ||
console.log('-------------------'); | ||
|
||
return resolve(evt); | ||
|
||
}); | ||
} | ||
|
||
/** | ||
* Your Custom POST Hook | ||
* - Here is an example of a Custom POST Hook. Include this and modify it if you would like to write your a hook that fires AFTER an Action. | ||
* - Be sure to ALWAYS accept and return the "evt" object, or you will break the entire flow. | ||
* - The "evt" object contains Action-specific data. You can add custom data to it, but if you change any data it will affect subsequent Actions and Hooks. | ||
* - You can also access other Project-specific data @ this.S Again, if you mess with data on this object, it could break everything, so make sure you know what you're doing ;) | ||
*/ | ||
|
||
_hookPost(evt) { | ||
|
||
let _this = this; | ||
|
||
return new BbPromise(function (resolve, reject) { | ||
|
||
console.log('-------------------'); | ||
console.log('YOUR SERVERLESS PLUGIN\'S CUSTOM "POST" HOOK HAS RUN AFTER "FunctionRun"'); | ||
console.log('-------------------'); | ||
|
||
return resolve(evt); | ||
|
||
}); | ||
} | ||
} | ||
|
||
// Export Plugin Class | ||
return PluginBoilerplate; | ||
|
||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
{ | ||
"name": "serverless-dynamodb-local", | ||
"version": "0.1.0", | ||
"engines": { | ||
"node": ">=4.0" | ||
}, | ||
"description": "Serverless plugin", | ||
"author": "serverless.com", | ||
"license": "MIT", | ||
"repository": { | ||
"type": "git", | ||
"url": "http://github.com/" | ||
}, | ||
"keywords": [ | ||
"serverless framework plugin", | ||
"serverless applications", | ||
"serverless plugins", | ||
"api gateway", | ||
"lambda", | ||
"aws", | ||
"aws lambda", | ||
"amazon", | ||
"amazon web services", | ||
"serverless.com" | ||
], | ||
"main": "index.js", | ||
"bin": {}, | ||
"scripts": { | ||
"test": "mocha tests/all" | ||
}, | ||
"devDependencies": { | ||
"chai": "^3.2.0", | ||
"mocha": "^2.2.5" | ||
}, | ||
"dependencies": { | ||
"bluebird": "^3.0.6", | ||
"q": "^1.4.1", | ||
"mkdirp": "^0.5.0", | ||
"tar": "^2.0.0" | ||
} | ||
} |