UNPKG

@bitblit/epsilon

Version:

Tiny adapter to simplify building API gateway Lambda APIS

185 lines 8.46 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()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.AwsSqsSnsBackgroundManager = void 0; const common_1 = require("@bitblit/ratchet/common"); const client_sqs_1 = require("@aws-sdk/client-sqs"); const epsilon_constants_1 = require("../../epsilon-constants"); const abstract_background_manager_1 = require("./abstract-background-manager"); const background_validator_1 = require("../background-validator"); const client_sns_1 = require("@aws-sdk/client-sns"); /** * Handles all submission of work to the background processing system. * * Note that this does NOT validate the input, it just passes it along. This is * because it creates a circular reference to the processors if we try since they * define the type and validation. */ class AwsSqsSnsBackgroundManager extends abstract_background_manager_1.AbstractBackgroundManager { constructor(_awsConfig, _sqs, _sns) { super(); this._awsConfig = _awsConfig; this._sqs = _sqs; this._sns = _sns; const cfgErrors = background_validator_1.BackgroundValidator.validateAwsConfig(_awsConfig); if (cfgErrors.length) { common_1.ErrorRatchet.throwFormattedErr('Cannot start - invalid AWS config : %j', cfgErrors); } } get backgroundManagerName() { return 'AwsSqsSnsBackgroundManager'; } get awsConfig() { return this._awsConfig; } get sqs() { return this._sqs; } get sns() { return this._sns; } addEntryToQueue(entry, fireStartMessage) { return __awaiter(this, void 0, void 0, function* () { try { const wrapped = yield this.wrapEntryForInternal(entry); const rval = wrapped.guid; // Guard against bad entries up front const params = { DelaySeconds: 0, MessageBody: JSON.stringify(wrapped), MessageGroupId: entry.type, QueueUrl: this.awsConfig.queueUrl, }; common_1.Logger.info('Add entry to queue (remote) : %j : Start : %s', params, fireStartMessage); const result = yield this.sqs.send(new client_sqs_1.SendMessageCommand(params)); if (fireStartMessage) { const fireResult = yield this.fireStartProcessingRequest(); common_1.Logger.silly('FireResult : %s', fireResult); } common_1.Logger.info('Background process %s using message id %s', rval, result.MessageId); return rval; } catch (error) { common_1.Logger.error('Error inserting background entry into SQS queue : %j', error); throw new Error('Error inserting background entry into SQS queue : ' + error['code'] + ' : ' + error['name']); } }); } fireImmediateProcessRequest(entry) { return __awaiter(this, void 0, void 0, function* () { try { const wrapped = yield this.wrapEntryForInternal(entry); const rval = wrapped.guid; // Guard against bad entries up front common_1.Logger.info('Fire immediately (remote) : %j ', entry); const toWrite = { type: epsilon_constants_1.EpsilonConstants.BACKGROUND_SNS_IMMEDIATE_RUN_FLAG, backgroundEntry: wrapped, }; const msg = JSON.stringify(toWrite); const snsId = yield this.writeMessageToSnsTopic(msg); common_1.Logger.debug('Background guid %s Wrote message : %s to SNS : %s', rval, msg, snsId); return rval; } catch (err) { common_1.Logger.error('Failed to fireImmediateProcessRequest : %s', err, err); throw new Error('Failed to fireImmediateProcessRequest : : ' + err['code'] + ' : ' + err['name']); } }); } fireStartProcessingRequest() { return __awaiter(this, void 0, void 0, function* () { let rval = null; try { common_1.Logger.info('Fire start processing request (remote)'); rval = yield this.writeMessageToSnsTopic(epsilon_constants_1.EpsilonConstants.BACKGROUND_SNS_START_MARKER); } catch (err) { common_1.Logger.error('Failed to fireStartProcessingRequest : %s', err, err); } return rval; }); } fetchApproximateNumberOfQueueEntries() { return __awaiter(this, void 0, void 0, function* () { let rval = null; const all = yield this.fetchCurrentQueueAttributes(); rval = common_1.NumberRatchet.safeNumber(all.Attributes['ApproximateNumberOfMessages']); return rval; }); } fetchCurrentQueueAttributes() { return __awaiter(this, void 0, void 0, function* () { let rval = null; const req = { AttributeNames: ['All'], QueueUrl: this.awsConfig.queueUrl, }; rval = yield this.sqs.send(new client_sqs_1.GetQueueAttributesCommand(req)); return rval; }); } writeMessageToSnsTopic(message) { return __awaiter(this, void 0, void 0, function* () { let rval = null; const params = { Message: message, TopicArn: this.awsConfig.notificationArn, }; common_1.Logger.debug('Writing message to SNS topic : j', params); const result = yield this.sns.send(new client_sns_1.PublishCommand(params)); rval = result.MessageId; return rval; }); } takeEntryFromBackgroundQueue() { return __awaiter(this, void 0, void 0, function* () { const rval = []; const params = { MaxNumberOfMessages: 1, QueueUrl: this.awsConfig.queueUrl, VisibilityTimeout: 300, WaitTimeSeconds: 0, }; const message = yield this.sqs.send(new client_sqs_1.ReceiveMessageCommand(params)); if (message && message.Messages && message.Messages.length > 0) { for (let i = 0; i < message.Messages.length; i++) { const m = message.Messages[i]; try { const parsedBody = JSON.parse(m.Body); if (!parsedBody.type) { common_1.Logger.warn('Dropping invalid background entry : %j', parsedBody); } else { rval.push(parsedBody); } common_1.Logger.debug('Removing message from queue'); const delParams = { QueueUrl: this.awsConfig.queueUrl, ReceiptHandle: m.ReceiptHandle, }; const delResult = yield this.sqs.send(new client_sqs_1.DeleteMessageCommand(delParams)); common_1.Logger.silly('Delete result : %j', delResult); } catch (err) { common_1.Logger.warn('Error parsing message, dropping : %j', m); } } } else { common_1.Logger.debug('No messages found (likely end of recursion)'); } return rval; }); } } exports.AwsSqsSnsBackgroundManager = AwsSqsSnsBackgroundManager; //# sourceMappingURL=aws-sqs-sns-background-manager.js.map