/// <summary>
        ///
        /// </summary>
        /// <param name="topicArn"></param>
        /// <param name="sqsClient"></param>
        /// <param name="sqsQueueUrl"></param>
        public async Task SubscribeSQS(string topicArn, ICoreAmazonSQS sqsClient, string sqsQueueUrl)
        {
            using (var client = new AmazonSimpleNotificationServiceClient(accessKey, secretKey, region))
            {
                var subscriptionArn = await client.SubscribeQueueAsync(topicArn, sqsClient, sqsQueueUrl);

                await client.SetSubscriptionAttributesAsync(subscriptionArn, "RawMessageDelivery", "true");
            }
        }
Example #2
0
        private void CreateTopicsAndQueues()
        {
            var topicAndQueueName = $"toll-amount-threshold-breached-{Guid.NewGuid().ToString().Substring(0,8)}";

            var createTopicResponse = _snsClient.CreateTopicAsync(new CreateTopicRequest {
                Name = topicAndQueueName
            }).Result;
            var createQueueResponse = _sqsClient.CreateQueueAsync(new CreateQueueRequest {
                QueueName = topicAndQueueName
            }).Result;

            TopicArn = createTopicResponse.TopicArn;
            QueueUrl = createQueueResponse.QueueUrl;

            var subscriptionArn = _snsClient.SubscribeAsync(new SubscribeRequest {
                TopicArn = createTopicResponse.TopicArn, Endpoint = createQueueResponse.QueueUrl, Protocol = "sqs"
            }).Result;
            var r = _snsClient.SetSubscriptionAttributesAsync(subscriptionArn.SubscriptionArn, "RawMessageDelivery", "true").Result;
        }
Example #3
0
        private void BindSubscription(AmazonSQSClient sqsClient,
                                      AmazonSimpleNotificationServiceClient snsClient)
        {
            var subscription = snsClient.SubscribeQueueAsync(_channelTopicARN, sqsClient, _queueUrl).Result;

            if (!string.IsNullOrEmpty(subscription))
            {
                //We need to support raw messages to allow the use of message attributes
                var response = snsClient.SetSubscriptionAttributesAsync(new SetSubscriptionAttributesRequest(subscription, "RawMessageDelivery", "true")).Result;
                if (response.HttpStatusCode != HttpStatusCode.OK)
                {
                    throw new InvalidOperationException($"Unable to set subscription attribute for raw message delivery");
                }
            }
            else
            {
                throw new InvalidOperationException($"Could not subscribe to topic: {_channelTopicARN} from queue: {_queueUrl} in region {_awsConnection.Region}");
            }
        }
Example #4
0
        private void EnsureQueue(Connection connection)
        {
            using (var sqsClient = new AmazonSQSClient(_awsConnection.Credentials, _awsConnection.Region))
            {
                //Does the queue exist - this is an HTTP call, we should cache the results for a period of time
                (bool exists, string name)queueExists = QueueExists(sqsClient, connection.ChannelName.ToValidSQSQueueName());
                if (!queueExists.exists)
                {
                    try
                    {
                        var request = new CreateQueueRequest(connection.ChannelName.ToValidSQSQueueName())
                        {
                            Attributes =
                            {
                                { "VisibilityTimeout",             connection.VisibilityTimeout.ToString()            },
                                { "ReceiveMessageWaitTimeSeconds", ToSecondsAsString(connection.TimeoutInMiliseconds) }
                            }
                        };
                        var response = sqsClient.CreateQueueAsync(request).Result;
                        var queueUrl = response.QueueUrl;
                        if (!string.IsNullOrEmpty(queueUrl))
                        {
                            //topic might not exist
                            using (var snsClient = new AmazonSimpleNotificationServiceClient(_awsConnection.Credentials, _awsConnection.Region))
                            {
                                var exists = snsClient.ListTopicsAsync().Result.Topics.SingleOrDefault(topic => topic.TopicArn == connection.RoutingKey);
                                if (exists == null)
                                {
                                    var createTopic = snsClient.CreateTopicAsync(new CreateTopicRequest(connection.RoutingKey.ToValidSNSTopicName())).Result;
                                    if (!string.IsNullOrEmpty(createTopic.TopicArn))
                                    {
                                        var subscription = snsClient.SubscribeQueueAsync(createTopic.TopicArn, sqsClient, queueUrl).Result;
                                        //We need to support raw messages to allow the use of message attributes
                                        snsClient.SetSubscriptionAttributesAsync(new SetSubscriptionAttributesRequest(subscription, "RawMessageDelivery", "true"));
                                    }
                                }
                            }
                        }
                    }
                    catch (AggregateException ae)
                    {
                        //TODO: We need some retry semantics here
                        //TODO: We need to flatten the ae and handle some of these with ae.Handle((x) => {})
                        ae.Handle(ex =>
                        {
                            if (ex is QueueDeletedRecentlyException)
                            {
                                //QueueDeletedRecentlyException - wait 30 seconds then retry
                                //Although timeout is 60s, we could be partway through that, so apply Copernican Principle
                                //and assume we are halfway through
                                var error = $"Could not create queue {connection.ChannelName.ToValidSQSQueueName()} because {ae.Message} waiting 60s to retry";
                                _logger.Value.Error(error);
                                Task.Delay(TimeSpan.FromSeconds(30));
                                throw new ChannelFailureException(error, ae);
                            }

                            return(false);
                        });
                    }
                }
            }
        }