Example #1
0
        /// <inheritdoc />
        void IPublicationBuilder <T> .Configure(
            JustSayingBus bus,
            IAwsClientFactoryProxy proxy,
            ILoggerFactory loggerFactory)
        {
            var logger = loggerFactory.CreateLogger <TopicPublicationBuilder <T> >();

            logger.LogInformation("Adding SNS publisher for message type '{MessageType}'.",
                                  typeof(T));

            var config = bus.Config;

            var readConfiguration  = new SqsReadConfiguration(SubscriptionType.ToTopic);
            var writeConfiguration = new SnsWriteConfiguration();

            ConfigureWrites?.Invoke(writeConfiguration);
            readConfiguration.ApplyTopicNamingConvention <T>(config.TopicNamingConvention);

            bus.SerializationRegister.AddSerializer <T>();

            foreach (var region in config.Regions)
            {
                // TODO pass region down into topic creation for when we have foreign topics so we can generate the arn
                var eventPublisher = new SnsTopicByName(
                    readConfiguration.TopicName,
                    proxy.GetAwsClientFactory().GetSnsClient(RegionEndpoint.GetBySystemName(region)),
                    bus.SerializationRegister,
                    loggerFactory,
                    writeConfiguration,
                    config.MessageSubjectProvider)
                {
                    MessageResponseLogger = config.MessageResponseLogger
                };

                async Task StartupTask()
                {
                    if (writeConfiguration.Encryption != null)
                    {
                        await eventPublisher.CreateWithEncryptionAsync(writeConfiguration.Encryption)
                        .ConfigureAwait(false);
                    }
                    else
                    {
                        await eventPublisher.CreateAsync().ConfigureAwait(false);
                    }

                    await eventPublisher.EnsurePolicyIsUpdatedAsync(config.AdditionalSubscriberAccounts)
                    .ConfigureAwait(false);
                }

                bus.AddStartupTask(StartupTask());

                bus.AddMessagePublisher <T>(eventPublisher, region);
            }

            logger.LogInformation(
                "Created SNS topic publisher on topic '{TopicName}' for message type '{MessageType}'.",
                readConfiguration.TopicName,
                typeof(T));
        }
Example #2
0
        public void EnsureQueueAndErrorQueueExistAndAllAttributesAreUpdated(SqsBasicConfiguration queueConfig)
        {
            if (!Exists())
            {
                Create(queueConfig);
            }
            else
            {
                UpdateQueueAttribute(queueConfig);
            }

            //Create an error queue for existing queues if they don't already have one
            if (ErrorQueue != null)
            {
                var errorQueueConfig = new SqsReadConfiguration(SubscriptionType.ToTopic)
                {
                    ErrorQueueRetentionPeriodSeconds = queueConfig.ErrorQueueRetentionPeriodSeconds,
                    ErrorQueueOptOut = true
                };
                if (!ErrorQueue.Exists())
                {
                    ErrorQueue.Create(errorQueueConfig);
                }
                else
                {
                    ErrorQueue.UpdateQueueAttribute(errorQueueConfig);
                }
            }
            UpdateRedrivePolicy(new RedrivePolicy(queueConfig.RetryCountBeforeSendingToErrorQueue, ErrorQueue.Arn));
        }
 public ISubscriberIntoQueue WithSqsTopicSubscriber(string topicName = null)
 {
     _subscriptionConfig = new SqsReadConfiguration(SubscriptionType.ToTopic)
     {
         BaseTopicName = (topicName ?? string.Empty).ToLower()
     };
     return(this);
 }
Example #4
0
    public QueueWithAsyncStartup EnsureTopicExistsWithQueueSubscribed(
        string region,
        SqsReadConfiguration queueConfig)
    {
        var regionEndpoint = RegionEndpoint.GetBySystemName(region);
        var sqsClient      = _awsClientFactory.GetAwsClientFactory().GetSqsClient(regionEndpoint);
        var snsClient      = _awsClientFactory.GetAwsClientFactory().GetSnsClient(regionEndpoint);

        var queueWithStartup = EnsureQueueExists(region, queueConfig);

        async Task StartupTask(CancellationToken cancellationToken)
        {
            await queueWithStartup.StartupTask.Invoke(cancellationToken).ConfigureAwait(false);

            var queue = queueWithStartup.Queue;

            if (TopicExistsInAnotherAccount(queueConfig))
            {
                var arnProvider = new ForeignTopicArnProvider(regionEndpoint,
                                                              queueConfig.TopicSourceAccount,
                                                              queueConfig.PublishEndpoint);

                var topicArn = await arnProvider.GetArnAsync().ConfigureAwait(false);
                await SubscribeQueueAndApplyFilterPolicyAsync(snsClient,
                                                              topicArn,
                                                              sqsClient,
                                                              queue.Uri,
                                                              queueConfig.FilterPolicy).ConfigureAwait(false);
            }
            else
            {
#pragma warning disable 618
                var eventTopic = new SnsTopicByName(queueConfig.PublishEndpoint, snsClient, _loggerFactory);
#pragma warning restore 618
                await eventTopic.CreateAsync(cancellationToken).ConfigureAwait(false);

                await SubscribeQueueAndApplyFilterPolicyAsync(snsClient,
                                                              eventTopic.Arn,
                                                              sqsClient,
                                                              queue.Uri,
                                                              queueConfig.FilterPolicy).ConfigureAwait(false);

                var sqsDetails = new SqsPolicyDetails
                {
                    SourceArn = eventTopic.Arn,
                    QueueArn  = queue.Arn,
                    QueueUri  = queue.Uri
                };
                await SqsPolicy
                .SaveAsync(sqsDetails, sqsClient)
                .ConfigureAwait(false);
            }
        }

        return(new QueueWithAsyncStartup(StartupTask, queueWithStartup.Queue));
    }
Example #5
0
        /// <inheritdoc />
        void ISubscriptionBuilder <T> .Configure(
            JustSayingBus bus,
            IHandlerResolver resolver,
            IVerifyAmazonQueues creator,
            ILoggerFactory loggerFactory)
        {
            var logger = loggerFactory.CreateLogger <TopicSubscriptionBuilder <T> >();

            var subscriptionConfig = new SqsReadConfiguration(SubscriptionType.ToTopic)
            {
                QueueName = TopicName
            };

            ConfigureReads?.Invoke(subscriptionConfig);

            var config = bus.Config;

            subscriptionConfig.ApplyTopicNamingConvention <T>(config.TopicNamingConvention);
            subscriptionConfig.ApplyQueueNamingConvention <T>(config.QueueNamingConvention);
            subscriptionConfig.SubscriptionGroupName ??= subscriptionConfig.QueueName;
            subscriptionConfig.PublishEndpoint = subscriptionConfig.TopicName;
            subscriptionConfig.Validate();

            var queueWithStartup = creator.EnsureTopicExistsWithQueueSubscribed(
                config.Region,
                bus.SerializationRegister,
                subscriptionConfig,
                config.MessageSubjectProvider);

            bus.AddStartupTask(queueWithStartup.StartupTask);

            bus.AddQueue(subscriptionConfig.SubscriptionGroupName, queueWithStartup.Queue);

            logger.LogInformation(
                "Created SQS topic subscription on topic '{TopicName}' and queue '{QueueName}'.",
                subscriptionConfig.TopicName,
                subscriptionConfig.QueueName);

            var resolutionContext = new HandlerResolutionContext(subscriptionConfig.QueueName);
            var proposedHandler   = resolver.ResolveHandler <T>(resolutionContext);

            if (proposedHandler == null)
            {
                throw new HandlerNotRegisteredWithContainerException(
                          $"There is no handler for '{typeof(T)}' messages.");
            }

            bus.AddMessageHandler(subscriptionConfig.QueueName,
                                  () => resolver.ResolveHandler <T>(resolutionContext));

            logger.LogInformation(
                "Added a message handler for message type for '{MessageType}' on topic '{TopicName}' and queue '{QueueName}'.",
                typeof(T),
                subscriptionConfig.TopicName,
                subscriptionConfig.QueueName);
        }
        /// <inheritdoc />
        void ISubscriptionBuilder <T> .Configure(
            JustSayingBus bus,
            IHandlerResolver resolver,
            IVerifyAmazonQueues creator,
            ILoggerFactory loggerFactory)
        {
            var logger = loggerFactory.CreateLogger <QueueSubscriptionBuilder <T> >();

            var subscriptionConfig = new SqsReadConfiguration(SubscriptionType.PointToPoint)
            {
                QueueName = QueueName
            };

            ConfigureReads?.Invoke(subscriptionConfig);

            var config = bus.Config;

            subscriptionConfig.ApplyTopicNamingConvention <T>(config.TopicNamingConvention);
            subscriptionConfig.ApplyQueueNamingConvention <T>(config.QueueNamingConvention);
            subscriptionConfig.SubscriptionGroupName ??= subscriptionConfig.QueueName;
            subscriptionConfig.Validate();

            var queue = creator.EnsureQueueExists(config.Region, subscriptionConfig);

            bus.AddStartupTask(
                queue.Queue.EnsureQueueAndErrorQueueExistAndAllAttributesAreUpdatedAsync(subscriptionConfig));

            bus.AddQueue(subscriptionConfig.SubscriptionGroupName, queue.Queue);

            logger.LogInformation(
                "Created SQS subscriber for message type '{MessageType}' on queue '{QueueName}'.",
                typeof(T),
                subscriptionConfig.QueueName);

            var resolutionContext = new HandlerResolutionContext(subscriptionConfig.QueueName);
            var proposedHandler   = resolver.ResolveHandler <T>(resolutionContext);

            if (proposedHandler == null)
            {
                throw new HandlerNotRegisteredWithContainerException(
                          $"There is no handler for '{typeof(T)}' messages.");
            }

            bus.AddMessageHandler(subscriptionConfig.QueueName,
                                  () => resolver.ResolveHandler <T>(resolutionContext));

            logger.LogInformation(
                "Added a message handler for message type for '{MessageType}' on topic '{TopicName}' and queue '{QueueName}'.",
                typeof(T),
                subscriptionConfig.TopicName,
                subscriptionConfig.QueueName);
        }
Example #7
0
    public async Task EnsureQueueAndErrorQueueExistAndAllAttributesAreUpdatedAsync(SqsReadConfiguration queueConfig, CancellationToken cancellationToken)
    {
        if (queueConfig == null)
        {
            throw new ArgumentNullException(nameof(queueConfig));
        }

        var exists = await ExistsAsync(cancellationToken).ConfigureAwait(false);

        if (!exists)
        {
            await CreateAsync(queueConfig, cancellationToken : cancellationToken).ConfigureAwait(false);
        }
        else
        {
            await UpdateQueueAttributeAsync(queueConfig, cancellationToken).ConfigureAwait(false);
        }

        await ApplyTagsAsync(this, queueConfig.Tags, cancellationToken).ConfigureAwait(false);

        //Create an error queue for existing queues if they don't already have one
        if (ErrorQueue != null && NeedErrorQueue(queueConfig))
        {
            var errorQueueConfig = new SqsReadConfiguration(SubscriptionType.ToTopic)
            {
                ErrorQueueRetentionPeriod = queueConfig.ErrorQueueRetentionPeriod,
                ErrorQueueOptOut          = true
            };

            var errorQueueExists = await ErrorQueue.ExistsAsync(cancellationToken).ConfigureAwait(false);

            if (!errorQueueExists)
            {
                await ErrorQueue.CreateAsync(errorQueueConfig, cancellationToken : cancellationToken).ConfigureAwait(false);
            }
            else
            {
                await ErrorQueue.UpdateQueueAttributeAsync(errorQueueConfig, cancellationToken).ConfigureAwait(false);
            }

            await UpdateRedrivePolicyAsync(
                new RedrivePolicy(queueConfig.RetryCountBeforeSendingToErrorQueue, ErrorQueue.Arn)).ConfigureAwait(false);

            await ApplyTagsAsync(ErrorQueue, queueConfig.Tags, cancellationToken).ConfigureAwait(false);
        }
    }
Example #8
0
    public QueueWithAsyncStartup EnsureQueueExists(
        string region,
        SqsReadConfiguration queueConfig)
    {
        var regionEndpoint = RegionEndpoint.GetBySystemName(region);
        var sqsClient      = _awsClientFactory.GetAwsClientFactory().GetSqsClient(regionEndpoint);

#pragma warning disable 618
        var queue = new SqsQueueByName(regionEndpoint,
                                       queueConfig.QueueName,
                                       sqsClient,
                                       queueConfig.RetryCountBeforeSendingToErrorQueue,
                                       _loggerFactory);
#pragma warning restore 618

        var startupTask = new Func <CancellationToken, Task>(ct => queue.EnsureQueueAndErrorQueueExistAndAllAttributesAreUpdatedAsync(
                                                                 queueConfig, ct));

        return(new QueueWithAsyncStartup(startupTask, queue));
    }
        public async Task TagsAreAppliedToParentAndErrorQueues()
        {
            // Arrange
            var sut = new SqsQueueByName(RegionEndpoint.EUWest1, QueueName, _client, 3, NullLoggerFactory.Instance);

            var config = new SqsReadConfiguration(SubscriptionType.ToTopic)
            {
                Tags = new Dictionary <string, string>
                {
                    ["TagOne"] = "tag-one",
                    ["TagTwo"] = "tag-two"
                }
            };

            // Act
            await sut.EnsureQueueAndErrorQueueExistAndAllAttributesAreUpdatedAsync(config, CancellationToken.None);

            // Assert
            await _client.Received(1).TagQueueAsync(Arg.Is <TagQueueRequest>(req => req.QueueUrl == QueueUrl && req.Tags == config.Tags));
        }
Example #10
0
        private IHaveFulfilledPublishRequirements AddSnsMessagePublisher <T>(Action <SnsWriteConfiguration> configBuilder) where T : Message
        {
            _log.LogInformation("Adding SNS publisher for message type '{MessageType}'.",
                                typeof(T));

            _subscriptionConfig = new SqsReadConfiguration(SubscriptionType.ToTopic);

            var snsWriteConfig = new SnsWriteConfiguration();

            configBuilder?.Invoke(snsWriteConfig);

            _subscriptionConfig.TopicName = GetOrUseTopicNamingConvention <T>(_subscriptionConfig.TopicName);

            Bus.SerializationRegister.AddSerializer <T>();

            foreach (var region in Bus.Config.Regions)
            {
                // TODO pass region down into topic creation for when we have foreign topics so we can generate the arn
                var eventPublisher = new SnsTopicByName(
                    _subscriptionConfig.TopicName,
                    _awsClientFactoryProxy.GetAwsClientFactory().GetSnsClient(RegionEndpoint.GetBySystemName(region)),
                    Bus.SerializationRegister,
                    _loggerFactory, snsWriteConfig,
                    Bus.Config.MessageSubjectProvider)
                {
                    MessageResponseLogger = Bus.Config.MessageResponseLogger
                };

                CreatePublisher(eventPublisher, snsWriteConfig);

                eventPublisher.EnsurePolicyIsUpdatedAsync(Bus.Config.AdditionalSubscriberAccounts).GetAwaiter().GetResult();

                Bus.AddMessagePublisher <T>(eventPublisher, region);
            }

            _log.LogInformation("Created SNS topic publisher on topic '{TopicName}' for message type '{MessageType}'.",
                                _subscriptionConfig.TopicName, typeof(T));

            return(this);
        }
Example #11
0
        public async Task EnsureQueueAndErrorQueueExistAndAllAttributesAreUpdatedAsync(SqsBasicConfiguration queueConfig)
        {
            var exists = await ExistsAsync();

            if (!exists)
            {
                await CreateAsync(queueConfig);
            }
            else
            {
                await UpdateQueueAttributeAsync(queueConfig);
            }

            //Create an error queue for existing queues if they don't already have one
            if (ErrorQueue != null && NeedErrorQueue(queueConfig))
            {
                var errorQueueConfig = new SqsReadConfiguration(SubscriptionType.ToTopic)
                {
                    ErrorQueueRetentionPeriodSeconds = queueConfig.ErrorQueueRetentionPeriodSeconds,
                    ErrorQueueOptOut = true
                };

                var errorQueueExists = await ErrorQueue.ExistsAsync();

                if (!errorQueueExists)
                {
                    await ErrorQueue.CreateAsync(errorQueueConfig);
                }
                else
                {
                    await ErrorQueue.UpdateQueueAttributeAsync(errorQueueConfig);
                }

                await UpdateRedrivePolicyAsync(
                    new RedrivePolicy(queueConfig.RetryCountBeforeSendingToErrorQueue, ErrorQueue.Arn));
            }
        }
Example #12
0
 public string GetQueueName(SqsReadConfiguration sqsConfig, string messageType)
 {
     return($"{messageType}-{_env}");
 }
 public string GetQueueName(SqsReadConfiguration sqsConfig, string messageType)
 => string.IsNullOrWhiteSpace(sqsConfig.BaseQueueName)
         ? messageType.ToLower()
         : sqsConfig.BaseQueueName.ToLower();
 public string GetQueueName(SqsReadConfiguration sqsConfig, Type messageType)
 => string.IsNullOrWhiteSpace(sqsConfig.BaseQueueName)
         ? messageType.ToTopicName().ToLowerInvariant()
         : sqsConfig.BaseQueueName.ToLowerInvariant();
 public string GetQueueName(SqsReadConfiguration sqsConfig, Type messageType)
 {
     return((sqsConfig.BaseQueueName + ticks).ToLower());
 }
Example #16
0
 public string GetQueueName(SqsReadConfiguration sqsConfig, string messageType)
 {
     throw new NotImplementedException();
 }
 public ISubscriberIntoQueue WithSqsPointToPointSubscriber()
 {
     _subscriptionConfig = new SqsReadConfiguration(SubscriptionType.PointToPoint);
     return(this);
 }
Example #18
0
 private static bool TopicExistsInAnotherAccount(SqsReadConfiguration queueConfig)
 {
     return(!string.IsNullOrWhiteSpace(queueConfig.TopicSourceAccount));
 }
Example #19
0
 public string GetQueueName(SqsReadConfiguration sqsConfig, string messageType)
 {
     return("test-" + messageType);
 }
Example #20
0
 public virtual IPublishEndpointProvider CreatePublisherEndpointProvider(SqsReadConfiguration subscriptionConfig)
 {
     return(new SnsPublishEndpointProvider(subscriptionConfig.Topic));
 }
Example #21
0
 public virtual IPublishSubscribtionEndpointProvider CreateSqsSubscriptionEndpointProvider(SqsReadConfiguration subscriptionConfig)
 {
     return(new SqsSubscribtionEndpointProvider(subscriptionConfig));
 }
Example #22
0
 public ISubscriberIntoQueue WithSqsTopicSubscriber()
 {
     _subscriptionConfig = new SqsReadConfiguration(SubscriptionType.ToTopic);
     return(this);
 }
Example #23
0
 private static void ReadConfig(SqsReadConfiguration readConfig) => readConfig.QueueName = QueueName;
Example #24
0
 public string GetQueueName(SqsReadConfiguration sqsConfig, Type messageType)
 {
     return("test-" + messageType.ToTopicName());
 }
Example #25
0
 public SqsSubscribtionEndpointProvider(SqsReadConfiguration config)
 {
     _config = config;
 }