lemon-core
Version:
Lemon Serverless Micro-Service Platform
127 lines • 7.08 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.LambdaSNSHandler = void 0;
/**
* `lambda-sns-handler.ts`
* - lambda handler to process SNS event.
*
*
* @author Steve Jung <steve@lemoncloud.io>
* @date 2019-11-20 initial version via backbone
*
* @copyright (C) 2019 LemonCloud Co Ltd. - All Rights Reserved.
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const engine_1 = require("../../engine/");
const lambda_handler_1 = require("./lambda-handler");
const protocol_1 = __importDefault(require("../protocol/"));
const NS = engine_1.$U.NS('HSNS', 'yellow'); // NAMESPACE TO BE PRINTED.
/**
* class: LambdaSNSHandler
* - default SNS Handler w/ event-listeners.
*/
class LambdaSNSHandler extends lambda_handler_1.LambdaSubHandler {
/**
* default constructor w/ registering self.
*/
constructor(lambda, register) {
super(lambda, register ? 'sns' : undefined);
this.listeners = [];
//* for debugging. save last result
this.$lastResult = null;
/**
* Default SNS Handler.
*/
this.handle = (event) => __awaiter(this, void 0, void 0, function* () {
//* for each records.
const records = event.Records || [];
(0, engine_1._log)(NS, `handle(len=${records.length})...`);
// _log(NS, '> event =', $U.json(event));
const $doReportError = (0, lambda_handler_1.buildReportError)(LambdaSNSHandler.REPORT_ERROR);
//* handle sqs record data.
const onSNSRecord = (record, index) => __awaiter(this, void 0, void 0, function* () {
(0, engine_1._log)(NS, `onSNSRecord(${(record && record.EventSource) || ''}, ${index})...`);
//* check if via protocol-service.
const $msg = record.Sns;
const { Subject } = $msg;
if (Subject == 'x-protocol-service') {
const param = protocol_1.default.service.asTransformer('sns').transformToParam($msg);
const context = param.context;
const callback = param.callback || '';
const result = yield this.lambda
.handleProtocol(param)
.then(body => {
// _log(NS, `! res[${index}] =`, $U.json(body));
callback && (0, engine_1._log)(NS, `> callback[${index}] =`, callback); // ex) api://lemon-queue-api-dev/batch/test11/callback#2.2.1
context && (0, engine_1._log)(NS, `> context[${index}] =`, engine_1.$U.json(context)); // ex) {"source":"express","domain":"localhost"}
//* report call back.
const proto = callback ? protocol_1.default.service.fromURL(context, callback, null, body || {}) : null;
proto && (0, engine_1._log)(NS, `> protocol[${index}] =`, engine_1.$U.json(proto));
(0, engine_1._log)(NS, `> config.service =`, this.lambda.config && this.lambda.config.getService());
//* check if service is in same..
if (proto && this.lambda.config && proto.service == this.lambda.config.getService()) {
proto.context.depth = engine_1.$U.N(proto.context.depth, 1) + 1;
proto.body = body;
(0, engine_1._log)(NS, `! body[${index}] =`, engine_1.$U.json(body));
return this.lambda.handleProtocol(proto).then(body => {
(0, engine_1._log)(NS, `>> body[${index}].callback =`, engine_1.$U.json(body));
return body;
});
}
//* call the remote service if callback.
return proto ? protocol_1.default.service.execute(proto) : body;
})
.catch(e => $doReportError(e, param.context, null, { protocol: param }));
(0, engine_1._log)(NS, `> sns[${index}].res =`, engine_1.$U.json(result));
return typeof result == 'string' ? result : engine_1.$U.json(result);
}
else {
//* retrieve message-attributes as `param`
const param = Object.keys($msg.MessageAttributes || {}).reduce((O, key) => {
const V = $msg.MessageAttributes[key];
if (!V)
return O;
O[key] = V.Type == 'Number' ? Number(V.Value) : V.Value;
return O;
}, { subject: Subject });
//* load data as `body`
const body = typeof $msg.Message == 'string' && $msg.Message.startsWith('{') && $msg.Message.endsWith('}')
? JSON.parse($msg.Message)
: { data: $msg.Message };
(0, engine_1._log)(NS, `> sns[${index}].param =`, engine_1.$U.json(param));
(0, engine_1._log)(NS, `> sns[${index}].body =`, engine_1.$U.json(body));
//* call all listeners in parrallel.
const asyncNext = (fn, j) => new Promise(resolve => {
resolve(fn('SNS', param, body, null));
}).catch(e => $doReportError(e, null, null, { param, body, i: index, j }));
const res = yield Promise.all(this.listeners.map(asyncNext));
return res.join(',');
}
});
//* serialize each records.
this.$lastResult = yield (0, engine_1.do_parrallel)(records, (record, i) => onSNSRecord(record, i).catch(e => $doReportError(e, null, null, { record, i })), 5);
//* returns.
return;
});
// _log(NS, `LambdaSNSHandler()..`);
}
addListener(handler) {
this.listeners.push(handler);
}
}
exports.LambdaSNSHandler = LambdaSNSHandler;
//* shared config.
LambdaSNSHandler.REPORT_ERROR = lambda_handler_1.LambdaHandler.REPORT_ERROR;
//# sourceMappingURL=lambda-sns-handler.js.map
;