@bitblit/epsilon
Version:
Tiny adapter to simplify building API gateway Lambda APIS
185 lines • 8.46 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());
});
};
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