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; } } }