Exemplo n.º 1
0
        private void SubscribeToTopic(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}");
            }
        }
 public async Task <string> SubscribeQueueAsync(string topicArn, string sqsQueueUrl)
 {
     return(await snsClient.SubscribeQueueAsync(topicArn, this.sqsService.GetSqsClient(), sqsQueueUrl));
 }
Exemplo n.º 3
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);
                        });
                    }
                }
            }
        }