Creating powerful cloud-based systems in C# and the .Net framework are possible for a long time now. Architecting a messages based cloud-computing solution that can handle millions of requests per day is not an easy undertaking but much easier when you use Amazon AWS services.
I recently needed to create an Amazon AWS SQS queue programmatically that subscribes to an SNS Topic that was also created programmatically. I could not find any examples in C# so I decided to post this code from one of my cloud-computing systems that I had designed and hope others find it useful. This particular code was used to test the dynamic nature of a messages based backend that can expand and contract the number of SQS queues based on how many active EC2 instances (nodes) in the cluster are available.
This code also shows how to create a policy for the SQS queue so that it will receive the messages from the SNS service. If you do not set a correct policy, the queue won’t receive any messages nor any exceptions are thrown.
Declaration code:
private AmazonSimpleNotificationServiceClient _sns;
private const string SNS_TOPIC = "YourTopicHere";
private string _AWSSNSArn;
Core C# code:
// 1. Create an Amazon SNS topic
AmazonSimpleNotificationService sns = new AmazonSimpleNotificationServiceClient(RegionEndpoint.USWest1);
_AWSSNSArn = sns.CreateTopic(new CreateTopicRequest
{
Name = SNS_TOPIC
}).CreateTopicResult.TopicArn;
// 2. Create the Amazon SQS In-Queue, will ignore it if it already exists
AmazonSQS sqs = AWSClientFactory.CreateAmazonSQSClient(RegionEndpoint.USWest1);
CreateQueueRequest sqsRequest = new CreateQueueRequest();
sqsRequest.QueueName = General.IpAddressAWSFriendly;
string queueUrl = sqs.CreateQueue(sqsRequest).CreateQueueResult.QueueUrl;
GetQueueAttributesRequest getQueueAttributesRequest = new GetQueueAttributesRequest();
List list = new List();
list.Add("QueueArn");
getQueueAttributesRequest.AttributeName = list;
getQueueAttributesRequest.QueueUrl = queueUrl;
GetQueueAttributesResponse response = sqs.GetQueueAttributes(getQueueAttributesRequest);
string queueArn = response.GetQueueAttributesResult.QueueARN;
// 3. Configure the Amazon SNS topic to publish to the SQS queue
sns.Subscribe(new SubscribeRequest
{
TopicArn = _AWSSNSArn,
Protocol = "sqs",
Endpoint = queueArn
});
// 4. Set the queue policy to allow SNS to publish messages
ActionIdentifier[] actions = new ActionIdentifier[2];
actions[0] = SQSActionIdentifiers.SendMessage;
actions[1] = SQSActionIdentifiers.ReceiveMessage;
Policy sqsPolicy = new Policy()
.WithStatements(new Statement(Statement.StatementEffect.Allow)
.WithPrincipals(Principal.AllUsers)
.WithResources(new Resource(queueArn))
.WithConditions(ConditionFactory.NewSourceArnCondition(_AWSSNSArn))
.WithActionIdentifiers(actions));
SetQueueAttributesRequest setQueueAttributesRequest = new SetQueueAttributesRequest();
List attributes = new List();
Amazon.SQS.Model.Attribute attribute = new Amazon.SQS.Model.Attribute();
attribute.Name = "Policy";
attribute.Value = sqsPolicy.ToJson();
attributes.Add(attribute);
setQueueAttributesRequest.QueueUrl = queueUrl;
setQueueAttributesRequest.Attribute = attributes;
sqs.SetQueueAttributes(setQueueAttributesRequest);