using Amazon.CDK;
using Amazon.CDK.AWS.SNS;
using Amazon.CDK.AWS.SNS.Subscriptions;
using Amazon.CDK.AWS.SQS;
using Constructs;
namespace Cdk
{
using System;
using System.Collections.Generic;
using Cdk.Models;
using Microsoft.Extensions.Configuration;
using Queue = Amazon.CDK.AWS.SQS.Queue;
using Topic = Amazon.CDK.AWS.SNS.Topic;
///
/// Implementation of CDK stack
///
public class CdkStack : Stack
{
///
/// Create CDK stack in the constructor
///
/// Scope of the construct
/// Id of the stack to create
/// Stack properties
internal CdkStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
{
// Read settings from appSettings.json file
IConfigurationRoot configuration = new ConfigurationBuilder().SetBasePath(AppDomain.CurrentDomain.BaseDirectory).AddJsonFile("appSettings.json").Build();
Settings settings = configuration.Get();
if (settings is null)
return;
// Create SNS topic
var topic = new Topic(this, $"{id}-{settings.SnsTopic.Name}", new TopicProps
{
TopicName = $"{id}-{settings.SnsTopic.Name}"
});
// Create Sqs queues based on the settings file
foreach (var sqsQueue in settings.SqsQueues)
{
this.GenerateQueue(
this,
sqsQueue,
topic,
id);
}
}
///
/// Populate Queue object within the stack scope
///
/// Scope of the construct
/// Queues settings provided in the appSettings.json
/// SNS topic created in this stack
/// Name of the stack
private void GenerateQueue(Construct scope, SqsQueue sqsQueue, Topic topicToSubscribe, string stackName)
{
var queue = new Queue(
scope,
$"{stackName}-{sqsQueue.Name}",
new QueueProps { QueueName = $"{stackName}-{sqsQueue.Name}" });
// Subscribe to the Sns topic
topicToSubscribe.AddSubscription(
this.GenerateSubscription(
queue,
sqsQueue));
}
///
/// Populate Sqs subscription
///
/// Queue construct in scope
/// Queue settings from appSettings.json
/// Created Subscription object
private SqsSubscription GenerateSubscription(Queue queue, SqsQueue sqsQueue)
{
SqsSubscriptionProps props = null;
if (sqsQueue.FilterByAttribute)
{
props = new SqsSubscriptionProps
{
FilterPolicy = this.GenerateAttributedBasedFilterPolicy(sqsQueue.Filters)
};
}
else
{
props = new SqsSubscriptionProps
{
FilterPolicyWithMessageBody = this.GenerateMessageBasedFilterPolicy(sqsQueue.Filters)
};
}
return new SqsSubscription(
queue,
props);
}
///
/// Populate Filter policy by message attribute
///
/// Filters provided in appSettings.json
/// Attribute based filter policy
private IDictionary GenerateAttributedBasedFilterPolicy(IList filters)
{
var filterPolicy = new Dictionary();
foreach (var filter in filters)
{
filterPolicy.Add(
filter.Name,
SubscriptionFilter.StringFilter(
new StringConditions
{ Allowlist = filter.Values }));
}
return filterPolicy;
}
///
/// Populate Filter policy by message body
///
/// Filters provided in appSettings.json
/// Message based filter policy
private IDictionary GenerateMessageBasedFilterPolicy(IList filters)
{
var filterPolicy = new Dictionary();
foreach (var filter in filters)
{
filterPolicy.Add(filter.Name,
FilterOrPolicy.Filter(
SubscriptionFilter.StringFilter(
new StringConditions
{ Allowlist = filter.Values })));
}
return filterPolicy;
}
}
}