@message-queue-toolkit/sns
Version:
SNS adapter for message-queue-toolkit
87 lines • 4.21 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.subscribeToTopic = subscribeToTopic;
const client_sns_1 = require("@aws-sdk/client-sns");
const sqs_1 = require("@message-queue-toolkit/sqs");
const TopicTypes_1 = require("../types/TopicTypes");
const snsUtils_1 = require("./snsUtils");
async function resolveTopicArnToSubscribeTo(snsClient, stsClient, topicConfiguration, extraParams) {
//If topicArn is present, let's use it and return early.
if ((0, TopicTypes_1.isSNSTopicLocatorType)(topicConfiguration) && topicConfiguration.topicArn) {
return topicConfiguration.topicArn;
}
//If input configuration is capable of creating a topic, let's create it and return its ARN.
if ((0, TopicTypes_1.isCreateTopicCommand)(topicConfiguration)) {
return await (0, snsUtils_1.assertTopic)(snsClient, stsClient, topicConfiguration, {
queueUrlsWithSubscribePermissionsPrefix: extraParams?.queueUrlsWithSubscribePermissionsPrefix,
allowedSourceOwner: extraParams?.allowedSourceOwner,
forceTagUpdate: extraParams?.forceTagUpdate,
});
}
//Last option: let's not create a topic but resolve a ARN based on the desired topic name.
return await (0, snsUtils_1.getTopicArnByName)(snsClient, topicConfiguration.topicName);
}
async function subscribeToTopic(sqsClient, snsClient, stsClient, queueConfiguration, topicConfiguration, subscriptionConfiguration, extraParams) {
const topicArn = await resolveTopicArnToSubscribeTo(snsClient, stsClient, topicConfiguration, extraParams);
const { queueUrl, queueArn } = await (0, sqs_1.assertQueue)(sqsClient, queueConfiguration, {
topicArnsWithPublishPermissionsPrefix: extraParams?.topicArnsWithPublishPermissionsPrefix,
updateAttributesIfExists: extraParams?.updateAttributesIfExists,
forceTagUpdate: extraParams?.forceTagUpdate,
});
const subscribeCommand = new client_sns_1.SubscribeCommand({
TopicArn: topicArn,
Endpoint: queueArn,
Protocol: 'sqs',
ReturnSubscriptionArn: true,
...subscriptionConfiguration,
});
try {
const subscriptionResult = await snsClient.send(subscribeCommand);
return {
subscriptionArn: subscriptionResult.SubscriptionArn,
topicArn,
queueUrl,
queueArn,
};
}
catch (err) {
const logger = extraParams?.logger ?? console;
// @ts-ignore
logger.error(`Error while creating subscription for queue "${queueConfiguration.QueueName}", topic "${(0, TopicTypes_1.isCreateTopicCommand)(topicConfiguration)
? topicConfiguration.Name
: topicConfiguration.topicName}": ${err.message}`);
if (subscriptionConfiguration.updateAttributesIfExists &&
err.message.indexOf('Subscription already exists with different attributes') !== -1) {
const result = await tryToUpdateSubscription(snsClient, topicArn, queueArn, subscriptionConfiguration);
if (!result) {
logger.error('Failed to update subscription');
throw err;
}
return {
subscriptionArn: result.SubscriptionArn,
topicArn,
queueUrl,
queueArn,
};
}
throw err;
}
}
async function tryToUpdateSubscription(snsClient, topicArn, queueArn, subscriptionConfiguration) {
const subscription = await (0, snsUtils_1.findSubscriptionByTopicAndQueue)(snsClient, topicArn, queueArn);
if (!subscription || !subscriptionConfiguration.Attributes) {
return undefined;
}
const setSubscriptionAttributesCommands = Object.entries(subscriptionConfiguration.Attributes).map(([key, value]) => {
return new client_sns_1.SetSubscriptionAttributesCommand({
SubscriptionArn: subscription.SubscriptionArn,
AttributeName: key,
AttributeValue: value,
});
});
for (const command of setSubscriptionAttributesCommands) {
await snsClient.send(command);
}
return subscription;
}
//# sourceMappingURL=snsSubscriber.js.map
;