public async Task RegisterSubscriber(string topic, string subscriberAddress) { m_log.Debug("Adding sqs subscriber {0} to sns topic {1}", subscriberAddress, topic); using (var rebusTransactionScope = new RebusTransactionScope()) { var topicArn = await m_AmazonInternalSettings.GetTopicArn(topic, rebusTransactionScope); var destinationQueueUrlByName = m_amazonSQSQueueContext.GetDestinationQueueUrlByName(subscriberAddress, rebusTransactionScope.TransactionContext); var sqsInformation = m_amazonSQSQueueContext.GetSqsInformationFromUri(destinationQueueUrlByName); var snsClient = m_AmazonInternalSettings.CreateSnsClient(rebusTransactionScope.TransactionContext); var listSubscriptionsByTopicResponse = await snsClient.ListSubscriptionsByTopicAsync(topicArn); var subscriptions = listSubscriptionsByTopicResponse?.Subscriptions; var subscription = subscriptions?.FirstOrDefault(s => s.SubscriptionArn == sqsInformation.Arn); if (subscription == null) { var subscribeResponse = await snsClient.SubscribeAsync(topicArn, "sqs", sqsInformation.Arn); if (subscribeResponse.HttpStatusCode != HttpStatusCode.OK) { throw new SnsRebusException($"Error creating subscription {subscriberAddress} on topic {topic}.", subscribeResponse.CreateAmazonExceptionFromResponse()); } await m_AmazonInternalSettings.CheckSqsPolicy(rebusTransactionScope.TransactionContext, destinationQueueUrlByName, sqsInformation, topicArn); await snsClient.SetSubscriptionAttributesAsync(subscribeResponse.SubscriptionArn, "RawMessageDelivery", bool.TrueString); } else { await snsClient.SetSubscriptionAttributesAsync(subscription.SubscriptionArn, "RawMessageDelivery", bool.TrueString); } } m_log.Debug("Added sqs subscriber {0} to sns topic {1}", subscriberAddress, topic); }
public static async Task <string> GetTopicArn(this IAmazonInternalSettings amazonInternalSettings, string topic, RebusTransactionScope scope = null) { var result = await Task.FromResult(s_topicArnCache.GetOrAdd(topic, s => { var rebusTransactionScope = scope ?? new RebusTransactionScope(); try { var logger = amazonInternalSettings.RebusLoggerFactory.GetLogger(); var snsClient = amazonInternalSettings.CreateSnsClient(rebusTransactionScope.TransactionContext); var formatedTopicName = amazonInternalSettings.TopicFormatter.FormatTopic(topic); var findTopicAsync = snsClient.FindTopicAsync(formatedTopicName); AsyncHelpers.RunSync(() => findTopicAsync); var findTopicResult = findTopicAsync.Result; string topicArn = findTopicResult?.TopicArn; if (findTopicResult == null) { logger.Debug($"Did not find sns topic {0}", formatedTopicName); var task = snsClient.CreateTopicAsync(new CreateTopicRequest(formatedTopicName)); AsyncHelpers.RunSync(() => task); topicArn = task.Result?.TopicArn; logger.Debug($"Created sns topic {0} => {1}", formatedTopicName, topicArn); } logger.Debug($"Using sns topic {0} => {1}", formatedTopicName, topicArn); return(topicArn); } finally { if (scope == null) { rebusTransactionScope.Dispose(); } } })); return(result); }
public async Task SendAsync(TransportMessage message, ITransactionContext context) { var snsClient = _amazonInternalSettings.CreateSnsClient(context); var sqsMessage = new AmazonTransportMessage(message.Headers, StringHelper.GetBody(message.Body)); var msg = _amazonInternalSettings.MessageSerializer.Serialize(sqsMessage); var pubRequest = new PublishRequest(_destinationAddress, msg); var messageAttributeValues = context.GetOrNull <IDictionary <string, MessageAttributeValue> >(SnsAttributeMapperOutBoundStep.SnsAttributeKey) ?? new Dictionary <string, MessageAttributeValue>(); foreach (var messageAttributeValue in messageAttributeValues) { pubRequest.MessageAttributes.Add(messageAttributeValue.Key, messageAttributeValue.Value); } var publishResponse = await snsClient.PublishAsync(pubRequest); if (publishResponse.HttpStatusCode != HttpStatusCode.OK) { throw new SnsRebusException($"Error publishing message to topic {_destinationAddress}.", publishResponse.CreateAmazonExceptionFromResponse()); } }