Пример #1
0
    public async Task Then_The_Error_Queue_Is_Not_Created()
    {
        // Arrange
        ILoggerFactory    loggerFactory = OutputHelper.ToLoggerFactory();
        IAwsClientFactory clientFactory = CreateClientFactory();

        var client = clientFactory.GetSqsClient(Region);

        var queue = new SqsQueueByName(
            Region,
            UniqueName,
            client,
            1,
            loggerFactory);

        // Act
        await queue.CreateAsync(new SqsBasicConfiguration()
        {
            ErrorQueueOptOut = true
        });

        // Assert
        await Patiently.AssertThatAsync(
            OutputHelper, async() => !await queue.ErrorQueue.ExistsAsync(CancellationToken.None));
    }
Пример #2
0
        public async Task Can_Remove_Encryption()
        {
            // Arrange
            ILoggerFactory    loggerFactory = OutputHelper.ToLoggerFactory();
            IAwsClientFactory clientFactory = CreateClientFactory();

            var client = clientFactory.GetSqsClient(Region);

            var queue = new SqsQueueByName(
                Region,
                UniqueName,
                client,
                1,
                loggerFactory);

            await queue.CreateAsync(
                new SqsBasicConfiguration { ServerSideEncryption = new ServerSideEncryption() });

            // Act
            await queue.UpdateQueueAttributeAsync(
                new SqsBasicConfiguration { ServerSideEncryption = null });

            // Assert
            queue.ServerSideEncryption.ShouldBeNull();
        }
        public async Task Can_Update_Delivery_Delay()
        {
            // Arrange
            var oldDeliveryDelay = TimeSpan.FromMinutes(2);
            var newDeliveryDelay = TimeSpan.FromMinutes(5);

            ILoggerFactory    loggerFactory = OutputHelper.ToLoggerFactory();
            IAwsClientFactory clientFactory = CreateClientFactory();

            var client = clientFactory.GetSqsClient(Region);

            var queue = new SqsQueueByName(
                Region,
                UniqueName,
                client,
                1,
                loggerFactory);

            await queue.CreateAsync(
                new SqsBasicConfiguration()
            {
                DeliveryDelay = oldDeliveryDelay
            });

            // Act
            await queue.UpdateQueueAttributeAsync(
                new SqsBasicConfiguration()
            {
                DeliveryDelay = newDeliveryDelay
            });

            // Assert
            queue.DeliveryDelay.ShouldBe(newDeliveryDelay);
        }
Пример #4
0
    public async Task Can_Update_Redrive_Policy()
    {
        // Arrange
        int maximumReceives = 42;

        ILoggerFactory    loggerFactory = OutputHelper.ToLoggerFactory();
        IAwsClientFactory clientFactory = CreateClientFactory();

        var client = clientFactory.GetSqsClient(Region);

        var queue = new SqsQueueByName(
            Region,
            UniqueName,
            client,
            1,
            loggerFactory);

        await queue.CreateAsync(new SqsBasicConfiguration());

        // Act
        await queue.UpdateRedrivePolicyAsync(
            new RedrivePolicy(maximumReceives, queue.ErrorQueue.Arn));

        // Assert
        queue.RedrivePolicy.ShouldNotBeNull();
        queue.RedrivePolicy.MaximumReceives.ShouldBe(maximumReceives);
    }
Пример #5
0
    public async Task Can_Update_Retention_Period()
    {
        // Arrange
        var oldRetentionPeriod = TimeSpan.FromSeconds(600);
        var newRetentionPeriod = TimeSpan.FromSeconds(700);

        ILoggerFactory    loggerFactory = OutputHelper.ToLoggerFactory();
        IAwsClientFactory clientFactory = CreateClientFactory();

        var client = clientFactory.GetSqsClient(Region);

        var queue = new SqsQueueByName(
            Region,
            UniqueName,
            client,
            1,
            loggerFactory);

        await queue.CreateAsync(
            new SqsBasicConfiguration { MessageRetention = oldRetentionPeriod });

        // Act
        await queue.UpdateQueueAttributeAsync(
            new SqsBasicConfiguration { MessageRetention = newRetentionPeriod }, CancellationToken.None);

        // Assert
        queue.MessageRetentionPeriod.ShouldBe(newRetentionPeriod);
    }
        /// <inheritdoc />
        void IPublicationBuilder <T> .Configure(
            JustSayingBus bus,
            IAwsClientFactoryProxy proxy,
            ILoggerFactory loggerFactory)
        {
            var logger = loggerFactory.CreateLogger <QueuePublicationBuilder <T> >();

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

            var config = bus.Config;
            var region = config.Region ?? throw new InvalidOperationException($"Config cannot have a blank entry for the {nameof(config.Region)} property.");

            var writeConfiguration = new SqsWriteConfiguration();

            ConfigureWrites?.Invoke(writeConfiguration);
            writeConfiguration.ApplyQueueNamingConvention <T>(config.QueueNamingConvention);

            bus.SerializationRegister.AddSerializer <T>();

            var regionEndpoint = RegionEndpoint.GetBySystemName(region);
            var sqsClient      = proxy.GetAwsClientFactory().GetSqsClient(regionEndpoint);

            var eventPublisher = new SqsMessagePublisher(
                sqsClient,
                bus.SerializationRegister,
                loggerFactory)
            {
                MessageResponseLogger = config.MessageResponseLogger
            };

#pragma warning disable 618
            var sqsQueue = new SqsQueueByName(
                regionEndpoint,
                writeConfiguration.QueueName,
                sqsClient,
                writeConfiguration.RetryCountBeforeSendingToErrorQueue,
                loggerFactory);
#pragma warning restore 618

            async Task StartupTask(CancellationToken cancellationToken)
            {
                if (!await sqsQueue.ExistsAsync(cancellationToken).ConfigureAwait(false))
                {
                    await sqsQueue.CreateAsync(writeConfiguration, cancellationToken : cancellationToken).ConfigureAwait(false);
                }

                eventPublisher.QueueUrl = sqsQueue.Uri;
            }

            bus.AddStartupTask(StartupTask);

            bus.AddMessagePublisher <T>(eventPublisher);

            logger.LogInformation(
                "Created SQS publisher for message type '{MessageType}' on queue '{QueueName}'.",
                typeof(T),
                writeConfiguration.QueueName);
        }
        public async Task Then_The_Error_Queue_Is_Created()
        {
            // Arrange
            ILoggerFactory    loggerFactory = OutputHelper.ToLoggerFactory();
            IAwsClientFactory clientFactory = CreateClientFactory();

            var client = clientFactory.GetSqsClient(Region);

            var queue = new SqsQueueByName(
                Region,
                UniqueName,
                client,
                1,
                loggerFactory);

            // Act
            await queue.CreateAsync(new SqsBasicConfiguration());

            // Assert
            await Patiently.AssertThatAsync(
                async() => await queue.ErrorQueue.ExistsAsync(),
                40.Seconds());
        }
Пример #8
0
        public async Task HandlingManyMessages(int throttleMessageCount)
        {
            // Arrange
            var fixture = new JustSayingFixture(OutputHelper);
            var client  = fixture.CreateSqsClient();

            var queue = new SqsQueueByName(fixture.Region, fixture.UniqueName, client, 1, fixture.LoggerFactory);

            if (!await queue.ExistsAsync())
            {
                await queue.CreateAsync(new SqsBasicConfiguration());

                if (!fixture.IsSimulator)
                {
                    // Wait for up to 60 secs for queue creation to be guaranteed completed by AWS
                    using (var cts = new CancellationTokenSource(TimeSpan.FromMinutes(1)))
                    {
                        while (!cts.IsCancellationRequested)
                        {
                            await Task.Delay(TimeSpan.FromSeconds(2));

                            if (await queue.ExistsAsync())
                            {
                                break;
                            }
                        }
                    }
                }
            }

            Assert.True(await queue.ExistsAsync(), "The queue was not created.");

            OutputHelper.WriteLine($"{DateTime.Now} - Adding {throttleMessageCount} messages to the queue.");

            var entriesAdded = 0;

            // Add some messages
            do
            {
                var entries = new List <SendMessageBatchRequestEntry>();

                for (var j = 0; j < 10; j++)
                {
                    var batchEntry = new SendMessageBatchRequestEntry
                    {
                        MessageBody = $"{{\"Subject\":\"GenericMessage\", \"Message\": \"{entriesAdded}\"}}",
                        Id          = Guid.NewGuid().ToString()
                    };

                    entries.Add(batchEntry);
                    entriesAdded++;
                }

                await client.SendMessageBatchAsync(queue.Url, entries);
            }while (entriesAdded < throttleMessageCount);

            OutputHelper.WriteLine($"{DateTime.Now} - Done adding messages.");

            var handleCount    = 0;
            var serialisations = Substitute.For <IMessageSerialisationRegister>();
            var monitor        = Substitute.For <IMessageMonitor>();
            var handler        = Substitute.For <IHandlerAsync <SimpleMessage> >();

            handler.Handle(null).ReturnsForAnyArgs(true).AndDoes(_ => Interlocked.Increment(ref handleCount));

            serialisations.DeserializeMessage(string.Empty).ReturnsForAnyArgs(new SimpleMessage());
            var listener = new SqsNotificationListener(queue, serialisations, monitor, fixture.LoggerFactory);

            listener.AddMessageHandler(() => handler);

            // Act
            var stopwatch = Stopwatch.StartNew();

            listener.Listen();

            using (var cts = new CancellationTokenSource(TimeSpan.FromMinutes(5)))
            {
                do
                {
                    if (!fixture.IsSimulator)
                    {
                        await Task.Delay(TimeSpan.FromSeconds(5));
                    }

                    OutputHelper.WriteLine($"{DateTime.Now} - Handled {handleCount} messages. Waiting for completion.");
                }while (handleCount < throttleMessageCount && !cts.IsCancellationRequested);
            }

            listener.StopListening();
            stopwatch.Stop();

            OutputHelper.WriteLine($"{DateTime.Now} - Handled {handleCount:N0} messages.");
            OutputHelper.WriteLine($"{DateTime.Now} - Took {stopwatch.ElapsedMilliseconds} ms");
            OutputHelper.WriteLine($"{DateTime.Now} - Throughput {(float)handleCount / stopwatch.ElapsedMilliseconds * 1000} messages/second");

            // Assert
            Assert.Equal(throttleMessageCount, handleCount);
        }
Пример #9
0
        public async Task Messages_Are_Throttled_But_Still_Delivered(int throttleMessageCount)
        {
            // Arrange
            ILoggerFactory    loggerFactory = OutputHelper.ToLoggerFactory();
            IAwsClientFactory clientFactory = CreateClientFactory();

            int retryCountBeforeSendingToErrorQueue = 1;
            var client = clientFactory.GetSqsClient(Region);

            var queue = new SqsQueueByName(
                Region,
                UniqueName,
                client,
                retryCountBeforeSendingToErrorQueue,
                loggerFactory);

            if (!await queue.ExistsAsync(CancellationToken.None))
            {
                await queue.CreateAsync(new SqsBasicConfiguration());

                if (!IsSimulator)
                {
                    // Wait for up to 60 secs for queue creation to be guaranteed completed by AWS
                    using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(1));

                    while (!cts.IsCancellationRequested)
                    {
                        await Task.Delay(TimeSpan.FromSeconds(2));

                        if (await queue.ExistsAsync(CancellationToken.None))
                        {
                            break;
                        }
                    }
                }
            }

            Assert.True(await queue.ExistsAsync(CancellationToken.None), "The queue was not created.");

            OutputHelper.WriteLine($"{DateTime.Now} - Adding {throttleMessageCount} messages to the queue.");

            var entriesAdded = 0;

            // Add some messages
            do
            {
                var entries = new List <SendMessageBatchRequestEntry>();

                for (int j = 0; j < 10; j++)
                {
                    var batchEntry = new SendMessageBatchRequestEntry
                    {
                        MessageBody = $"{{\"Subject\":\"SimpleMessage\", \"Message\": {{ \"Content\": \"{entriesAdded}\"}}}}",
                        Id          = Guid.NewGuid().ToString()
                    };

                    entries.Add(batchEntry);
                    entriesAdded++;
                }

                await client.SendMessageBatchAsync(queue.Uri.AbsoluteUri, entries);
            }while (entriesAdded < throttleMessageCount);

            OutputHelper.WriteLine($"{DateTime.Now} - Done adding messages.");

            int count   = 0;
            var handler = Substitute.For <IHandlerAsync <SimpleMessage> >();

            handler.Handle(Arg.Any <SimpleMessage>())
            .ReturnsForAnyArgs(true)
            .AndDoes((_) => Interlocked.Increment(ref count));

            IServiceCollection services = GivenJustSaying(LogLevel.Warning)
                                          .ConfigureJustSaying((builder) => builder.WithLoopbackQueue <SimpleMessage>(UniqueName))
                                          .AddSingleton(handler);

            TimeSpan timeToProcess = TimeSpan.Zero;

            // Act
            await WhenAsync(
                services,
                async (publisher, listener, cancellationToken) =>
            {
                var stopwatch = Stopwatch.StartNew();
                var delay     = IsSimulator ? TimeSpan.FromMilliseconds(100) : TimeSpan.FromSeconds(5);

                await listener.StartAsync(cancellationToken);

                do
                {
                    await Task.Delay(delay, cancellationToken);

                    OutputHelper.WriteLine($"{DateTime.Now} - Handled {count} messages. Waiting for completion.");
                }while (count < throttleMessageCount && !cancellationToken.IsCancellationRequested);

                stopwatch.Stop();
                timeToProcess = stopwatch.Elapsed;
            });

            // Assert
            OutputHelper.WriteLine($"{DateTime.Now} - Handled {count:N0} messages.");
            OutputHelper.WriteLine($"{DateTime.Now} - Took {timeToProcess.TotalMilliseconds} ms");
            OutputHelper.WriteLine($"{DateTime.Now} - Throughput {(float)count / timeToProcess.TotalMilliseconds * 1000} messages/second");

            Assert.Equal(throttleMessageCount, count);
        }
        // Use this to manually test the performance / throttling of getting messages out of the queue.
        public async Task HandlingManyMessages(int throttleMessageCount)
        {
            var locker         = new object();
            var awsQueueClient = CreateMeABus.DefaultClientFactory().GetSqsClient(RegionEndpoint.EUWest1);

            var q = new SqsQueueByName(RegionEndpoint.EUWest1, "throttle_test", awsQueueClient, 1, new LoggerFactory());

            if (!await q.ExistsAsync())
            {
                await q.CreateAsync(new SqsBasicConfiguration());

                await Task.Delay(TimeSpan.FromMinutes(1));  // wait 60 secs for queue creation to be guaranteed completed by aws. :(
            }

            Assert.True(await q.ExistsAsync());

            Console.WriteLine($"{DateTime.Now} - Adding {throttleMessageCount} messages to the queue.");

            var entriesAdded = 0;

            // Add some messages
            do
            {
                var entries = new List <SendMessageBatchRequestEntry>();
                for (var j = 0; j < 10; j++)
                {
                    var batchEntry = new SendMessageBatchRequestEntry
                    {
                        MessageBody = "{\"Subject\":\"GenericMessage\", \"Message\": \"" + entriesAdded.ToString() + "\"}",
                        Id          = Guid.NewGuid().ToString()
                    };
                    entries.Add(batchEntry);
                    entriesAdded++;
                }
                await awsQueueClient.SendMessageBatchAsync(new SendMessageBatchRequest { QueueUrl = q.Url, Entries = entries });
            }while (entriesAdded < throttleMessageCount);

            Console.WriteLine($"{DateTime.Now} - Done adding messages.");

            var handleCount    = 0;
            var serialisations = Substitute.For <IMessageSerialisationRegister>();
            var monitor        = Substitute.For <IMessageMonitor>();
            var handler        = Substitute.For <IHandlerAsync <GenericMessage> >();

            handler.Handle(null).ReturnsForAnyArgs(true).AndDoes(x => { lock (locker) { handleCount++; } });

            serialisations.DeserializeMessage(string.Empty).ReturnsForAnyArgs(new GenericMessage());
            var listener = new SqsNotificationListener(q, serialisations, monitor, new LoggerFactory());

            listener.AddMessageHandler(() => handler);

            var stopwatch = new Stopwatch();

            stopwatch.Start();
            listener.Listen();
            var waitCount = 0;

            do
            {
                await Task.Delay(TimeSpan.FromSeconds(5));

                Console.WriteLine($"{DateTime.Now} - Handled {handleCount} messages. Waiting for completion.");
                waitCount++;
            }while (handleCount < throttleMessageCount && waitCount < 100);

            listener.StopListening();
            stopwatch.Stop();

            Console.WriteLine($"{DateTime.Now} - Handled {handleCount} messages.");
            Console.WriteLine($"{DateTime.Now} - Took {stopwatch.ElapsedMilliseconds} ms");
            Console.WriteLine(
                $"{DateTime.Now} - Throughput {(float) handleCount/stopwatch.ElapsedMilliseconds*1000} msg/sec");
            Assert.Equal(throttleMessageCount, handleCount);
        }