UNPKG

lemon-core

Version:
127 lines 7.08 kB
"use strict"; 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