cloud-red
Version:
Serverless Node-RED for your cloud integration needs
159 lines (147 loc) • 5.24 kB
JavaScript
;
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const compression = require('compression');
const awsServerlessExpress = require('./extra/lambdify');
const awsServerlessExpressMiddleware = require('./extra/lambdify/middleware');
const router = express.Router();
const RED = require('./core/lib/red');
const settings = {
disableEditor: true,
httpAdminRoot: true,
httpNodeRoot: '/',
httpAdminRoot: '/admin',
// httpStatic: 'public',
awsRegion: 'ap-southeast-2',
awsS3Bucket: 'cloud-red-flows',
awsS3FlowName: 'awshandler-flow.json',
//storageModule: require('./cloud-red/extra/storage-s3'),
// flowFilePath: 'default-flow.json',
storageModule: require('./extra/storage-ephemeral'),
functionGlobalContext: {},
credentialSecret: process.env.NODE_RED_SECRET || 'a-secret-key',
logging: {
// Only console logging is currently supported
console: {
// Level of logging to be recorded. Options are:
// fatal - only those errors which make the application unusable should be recorded
// error - record errors which are deemed fatal for a particular request + fatal errors
// warn - record problems which are non fatal + errors + fatal errors
// info - record information about the general running of the application + warn + error + fatal errors
// debug - record information which is more verbose than info + info + warn + error + fatal errors
// trace - record very detailed logging + debug + info + warn + error + fatal errors
level: 'debug',
// Whether or not to include metric events in the log output
metrics: false,
// Whether or not to include audit events in the log output
audit: false
}
}
};
// NOTE: If you get ERR_CONTENT_DECODING_FAILED in your browser, this is likely
// due to a compressed response (e.g. gzip) which has not been handled correctly
// by aws-serverless-express and/or API Gateway. Add the necessary MIME types to
// binaryMimeTypes below, then redeploy (`npm run package-deploy`)
// TODO: aws-serverless-express will encode64 if any ot the types below is found
// https://github.com/awslabs/aws-serverless-express/issues/99
const binaryMimeTypes = [
'application/javascript',
//'application/json',
'application/octet-stream',
// 'application/xml',
'font/eot',
'font/opentype',
'font/otf',
'image/jpeg',
'image/png',
'image/svg+xml',
'text/comma-separated-values',
// 'text/css',
// 'text/html',
'text/javascript'
// 'text/plain',
// 'text/text',
// 'text/xml'
];
// (function() {
// console.log('[lambda.js] Initializing HttpNode');
// app.use(cors());
// app.use(bodyParser.json());
// app.use(bodyParser.urlencoded({ extended: true }));
// app.use(awsServerlessExpressMiddleware.eventContext());
// server = awsServerlessExpress.createServer(app, null, binaryMimeTypes);
// })();
class FlowBuilder {
constructor(flow) {
if (!flow) {
console.log(
'[ERROR] Flow is not defined. Make sure you pass the flow file to the constructor of FlowBuilder'
);
os.exit(1);
}
this.flow = flow;
this.initialized = false;
this.server = null;
this.app = null;
this.initServer();
}
initServer() {
let app = express();
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(awsServerlessExpressMiddleware.eventContext());
this.app = app;
this.server = awsServerlessExpress.createServer(
this.app,
null,
binaryMimeTypes
);
}
async initFlow(flowFilePath) {
console.log('[lambda.js] Initializing runtime ...');
settings.basePath = __dirname;
settings.flowFilePath = flowFilePath;
RED.init(this.server, settings);
// The aws-serverless-express library creates a server and listens on a Unix
// Domain Socket for you, so you can remove the usual call to app.listen.
// app.listen(3000)
this.app.use(settings.httpAdminRoot, RED.httpAdmin);
this.app.use(settings.httpNodeRoot, RED.httpNode);
return new Promise((resolve, reject) => {
let deployed;
RED.events.on(
'runtime-event',
(deployed = data => {
if (data.id === 'runtime-deploy') {
RED.events.removeListener('runtime-event', deployed);
console.log('[lambda.js] Flow deployed successfully.');
this.initialized = true;
resolve();
}
})
);
console.log('[lambda.js] Runtime starting ...');
RED.start();
});
}
async proxyEventToFlow(flow, event, context) {
if (!this.initialized) {
console.log('[lambda.js] Initializing flow ...');
await this.initFlow(flow);
}
return new Promise(resolve => {
// Workaround to be able to return promises from handler:
// https://github.com/awslabs/aws-serverless-express/issues/134
awsServerlessExpress.proxy(this.server, event, {
...context,
succeed: resolve
});
});
}
handleEvent(event, context) {
return this.proxyEventToFlow(this.flow, event, context);
}
}
module.exports.FlowBuilder = FlowBuilder;