コード例 #1
0
        public async Task Given_Valid_Request_And_Remote_Server_Listening_When_Sending_Then_Remote_Accepts()
        {
            var messageReceivedEvent = new ManualResetEvent(false);
            string content = null;

            var serverBaseUri = new UriBuilder
            {
                Scheme = "http",
                Host = "localhost",
                Port = 52180,
                Path = "/platibus.test/"
            }.Uri;

            var configuration = new HttpServerConfiguration
            {
                BaseUri = serverBaseUri
            };

            configuration.AddHandlingRule<string>(".*", (c, ctx) =>
            {
                content = c;
                messageReceivedEvent.Set();
                ctx.Acknowledge();
            });

            bool messageReceived;
            using (var server = await HttpServer.Start(configuration))
            {
                var endpoint = serverBaseUri;
                var message = new Message(new MessageHeaders
                {
                    {HeaderName.ContentType, "text/plain"},
                    {HeaderName.MessageId, Guid.NewGuid().ToString()},
                    {HeaderName.Destination, endpoint.ToString()},
                    {HeaderName.MessageName, typeof (string).FullName},
                }, "Hello, world!");

                var transportService = await server.GetTransportService();
                await transportService.SendMessage(message);

                messageReceived = await messageReceivedEvent
                    .WaitOneAsync(TimeSpan.FromSeconds(3));
            }

            // Sanity check.  We're really testing the transport to ensure
            // that it doesn't throw.  But if it does throw, then it would
            // be nice to get some info about how the server behaved.
            Assert.That(messageReceived, Is.True);
            Assert.That(content, Is.EqualTo("Hello, world!"));
        }
コード例 #2
0
 /// <summary>
 /// Observes the sent message replies until the first reply is received
 /// or a timeout occurs
 /// </summary>
 /// <param name="sentMessage">The sent message</param>
 /// <param name="timeout">The maximum amount of time to wait for a reply</param>
 /// <returns>Returns a task whose result will be the deserialized content of the 
 /// reply message</returns>
 public static async Task<object> GetReply(this ISentMessage sentMessage, TimeSpan timeout = default(TimeSpan))
 {
     object reply = null;
     using (var replyReceivedEvent = new ManualResetEvent(false))
     using (sentMessage.ObserveReplies().Subscribe(r =>
     {
         reply = r;
         // ReSharper disable once AccessToDisposedClosure
         replyReceivedEvent.Set();
     }))
     {
         await replyReceivedEvent.WaitOneAsync(timeout);    
     }
     return reply;
 }
コード例 #3
0
        public async Task Given_Existing_Queue_When_New_Message_Queued_Then_Listener_Should_Fire()
        {
            var listenerCalledEvent = new ManualResetEvent(false);
            var queueName = new QueueName(Guid.NewGuid().ToString());
            var rmqQueueingService = new RabbitMQMessageQueueingService(RabbitMQUri);

            try
            {
                var mockListener = new Mock<IQueueListener>();
                mockListener.Setup(
                    x =>
                        x.MessageReceived(It.IsAny<Message>(), It.IsAny<IQueuedMessageContext>(),
                            It.IsAny<CancellationToken>()))
                    .Callback<Message, IQueuedMessageContext, CancellationToken>((msg, ctx, ct) =>
                    {
                        ctx.Acknowledge();
                        listenerCalledEvent.Set();
                    })
                    .Returns(Task.FromResult(true));


                await rmqQueueingService.CreateQueue(queueName, mockListener.Object, new QueueOptions {MaxAttempts = 1});

                var message = new Message(new MessageHeaders
                {
                    {HeaderName.ContentType, "text/plain"},
                    {HeaderName.MessageId, Guid.NewGuid().ToString()}
                }, "Hello, world!");

                await rmqQueueingService.EnqueueMessage(queueName, message, Thread.CurrentPrincipal);
                await listenerCalledEvent.WaitOneAsync(TimeSpan.FromSeconds(1));

                var messageEqualityComparer = new MessageEqualityComparer();
                mockListener.Verify(
                    x =>
                        x.MessageReceived(It.Is<Message>(m => messageEqualityComparer.Equals(m, message)),
                            It.IsAny<IQueuedMessageContext>(), It.IsAny<CancellationToken>()), Times.Once());

                Assert.That(GetQueueDepth(queueName), Is.EqualTo(0));
                Assert.That(GetQueueDepth(queueName.GetRetryQueueName()), Is.EqualTo(0));
            }
            finally
            {
                rmqQueueingService.Dispose();
                DeleteQueue(queueName);
            }
        }
コード例 #4
0
        public async Task When_New_Message_Queued_Then_Listener_Should_Fire()
        {
            var listenerCalledEvent = new ManualResetEvent(false);
            var connectionStringSettings = GetConnectionStringSettings();
            var sqlQueueingService = new SQLMessageQueueingService(connectionStringSettings);
            sqlQueueingService.Init();

            var mockListener = new Mock<IQueueListener>();
            mockListener.Setup(
                x =>
                    x.MessageReceived(It.IsAny<Message>(), It.IsAny<IQueuedMessageContext>(),
                        It.IsAny<CancellationToken>()))
                .Callback<Message, IQueuedMessageContext, CancellationToken>((msg, ctx, ct) =>
                {
                    ctx.Acknowledge();
                    listenerCalledEvent.Set();
                })
                .Returns(Task.FromResult(true));

            var queueName = new QueueName(Guid.NewGuid().ToString());
            await sqlQueueingService.CreateQueue(queueName, mockListener.Object, new QueueOptions {MaxAttempts = 1});

            var message = new Message(new MessageHeaders
            {
                {HeaderName.ContentType, "text/plain"},
                {HeaderName.MessageId, Guid.NewGuid().ToString()}
            }, "Hello, world!");

            await sqlQueueingService.EnqueueMessage(queueName, message, Thread.CurrentPrincipal);
            await listenerCalledEvent.WaitOneAsync(TimeSpan.FromSeconds(1));

            var messageEqualityComparer = new MessageEqualityComparer();
            mockListener.Verify(
                x =>
                    x.MessageReceived(It.Is<Message>(m => messageEqualityComparer.Equals(m, message)),
                        It.IsAny<IQueuedMessageContext>(), It.IsAny<CancellationToken>()), Times.Once());
        }
コード例 #5
0
        public async Task Given_Message_When_Sending_Then_Reply_Should_Be_Observed()
        {
            await With.RabbitMQHostedBusInstances(async (platibus0, platibus1) =>
            {
                var replyReceivedEvent = new ManualResetEvent(false);
                var repliesCompletedEvent = new ManualResetEvent(false);
                var replies = new ConcurrentQueue<object>();
                var message = new TestMessage
                {
                    GuidData = Guid.NewGuid(),
                    IntData = RNG.Next(0, int.MaxValue),
                    StringData = "Hello, world!",
                    DateData = DateTime.UtcNow
                };

                var sentMessage = await platibus0.Send(message);
                var subscription = sentMessage
                    .ObserveReplies()
                    .Subscribe(r =>
                    {
                        replies.Enqueue(r);
                        replyReceivedEvent.Set();
                    }, () => repliesCompletedEvent.Set());

                var replyReceived = await replyReceivedEvent.WaitOneAsync(TimeSpan.FromSeconds(30));
                var repliesCompleted = await repliesCompletedEvent.WaitOneAsync(TimeSpan.FromSeconds(30));
                subscription.Dispose();

                Assert.That(replyReceived, Is.True);
                Assert.That(repliesCompleted, Is.True);
                Assert.That(replies.Count, Is.EqualTo(1));

                var reply = replies.First();
                Assert.That(reply, Is.InstanceOf<TestReply>());
            });
        }
コード例 #6
0
        public async Task Given_Queued_Message_When_Context_Acknowledged_Then_Message_Should_Be_Acknowledged()
        {
            var listenerCalledEvent = new ManualResetEvent(false);
            var connectionStringSettings = GetConnectionStringSettings();
            var queueName = new QueueName(Guid.NewGuid().ToString());

            var sqlQueueingService = new SQLMessageQueueingService(connectionStringSettings);
            sqlQueueingService.Init();

            var mockListener = new Mock<IQueueListener>();
            mockListener.Setup(
                x =>
                    x.MessageReceived(It.IsAny<Message>(), It.IsAny<IQueuedMessageContext>(),
                        It.IsAny<CancellationToken>()))
                .Callback<Message, IQueuedMessageContext, CancellationToken>((msg, ctx, ct) =>
                {
                    ctx.Acknowledge();
                    listenerCalledEvent.Set();
                })
                .Returns(Task.FromResult(true));

            await sqlQueueingService.CreateQueue(queueName, mockListener.Object, new QueueOptions {MaxAttempts = 1});

            var message = new Message(new MessageHeaders
            {
                {HeaderName.ContentType, "text/plain"},
                {HeaderName.MessageId, Guid.NewGuid().ToString()}
            }, "Hello, world!");

            await sqlQueueingService.EnqueueMessage(queueName, message, Thread.CurrentPrincipal);
            await listenerCalledEvent.WaitOneAsync(TimeSpan.FromSeconds(1));

            // The listener is called before the row is updated, so there is a possible
            // race condition here.  Wait for a second to allow the update to take place
            // before enumerating the rows to see that they were actually deleted.
            await Task.Delay(TimeSpan.FromSeconds(1));

            var messageEqualityComparer = new MessageEqualityComparer();
            mockListener.Verify(
                x =>
                    x.MessageReceived(It.Is<Message>(m => messageEqualityComparer.Equals(m, message)),
                        It.IsAny<IQueuedMessageContext>(), It.IsAny<CancellationToken>()), Times.Once());

            var sqlQueueInspector = new SQLMessageQueueInspector(sqlQueueingService, queueName);
            var queuedMessages = (await sqlQueueInspector.EnumerateMessages()).ToList();

            Assert.That(queuedMessages, Is.Empty);
        }
コード例 #7
0
        public async Task Given_Auto_Acknowledge_Queue_When_Listener_Throws_Then_Message_Should_Not_Be_Acknowledged()
        {
            var listenerCalledEvent = new ManualResetEvent(false);
            var connectionStringSettings = GetConnectionStringSettings();
            var queueName = new QueueName(Guid.NewGuid().ToString());

            var sqlQueueingService = new SQLMessageQueueingService(connectionStringSettings);
            sqlQueueingService.Init();

            var mockListener = new Mock<IQueueListener>();
            mockListener.Setup(x =>
                x.MessageReceived(It.IsAny<Message>(), It.IsAny<IQueuedMessageContext>(),
                    It.IsAny<CancellationToken>()))
                .Callback<Message, IQueuedMessageContext, CancellationToken>((msg, ctx, ct) =>
                {
                    listenerCalledEvent.Set();
                    throw new Exception();
                });

            await sqlQueueingService
                .CreateQueue(queueName, mockListener.Object, new QueueOptions
                {
                    AutoAcknowledge = true,
                    MaxAttempts = 2, // So the message doesn't get moved to the DLQ
                    RetryDelay = TimeSpan.FromSeconds(30)
                });

            var message = new Message(new MessageHeaders
            {
                {HeaderName.ContentType, "text/plain"},
                {HeaderName.MessageId, Guid.NewGuid().ToString()}
            }, "Hello, world!");

            await sqlQueueingService.EnqueueMessage(queueName, message, Thread.CurrentPrincipal);

            var listenerCalled = await listenerCalledEvent
                .WaitOneAsync(Debugger.IsAttached ? TimeSpan.FromMinutes(5) : TimeSpan.FromSeconds(3));

            Assert.That(listenerCalled, Is.True);

            // The listener is called before the row is updated, so there is a possible
            // race condition here.  Wait for a second to allow the update to take place
            // before enumerating the rows to see that they were actually not updated.
            await Task.Delay(TimeSpan.FromSeconds(1));

            var messageEqualityComparer = new MessageEqualityComparer();
            mockListener.Verify(x =>
                x.MessageReceived(It.Is<Message>(m => messageEqualityComparer.Equals(m, message)),
                    It.IsAny<IQueuedMessageContext>(), It.IsAny<CancellationToken>()), Times.Once());

            var sqlQueueInspector = new SQLMessageQueueInspector(sqlQueueingService, queueName);
            var queuedMessages = (await sqlQueueInspector.EnumerateMessages()).ToList();

            Assert.That(queuedMessages[0].Message, Is.EqualTo(message).Using(messageEqualityComparer));
        }
コード例 #8
0
        public async Task Given_Queued_Message_When_Acknowledged_Then_Message_Should_Be_Deleted()
        {
            var listenerCalledEvent = new ManualResetEvent(false);
            var tempDir = GetTempDirectory();
            var queueName = new QueueName(Guid.NewGuid().ToString());
            var queuePath = Path.Combine(tempDir.FullName, queueName);
            var queueDir = new DirectoryInfo(queuePath);
            if (!queueDir.Exists)
            {
                queueDir.Create();
            }

            var fsQueueingService = new FilesystemMessageQueueingService(tempDir);
            fsQueueingService.Init();

            var mockListener = new Mock<IQueueListener>();
            mockListener.Setup(
                x =>
                    x.MessageReceived(It.IsAny<Message>(), It.IsAny<IQueuedMessageContext>(),
                        It.IsAny<CancellationToken>()))
                .Callback<Message, IQueuedMessageContext, CancellationToken>((msg, ctx, ct) =>
                {
                    ctx.Acknowledge();
                    listenerCalledEvent.Set();
                })
                .Returns(Task.FromResult(true));

            await fsQueueingService.CreateQueue(queueName, mockListener.Object, new QueueOptions {MaxAttempts = 1});

            var message = new Message(new MessageHeaders
            {
                {HeaderName.ContentType, "text/plain"},
                {HeaderName.MessageId, Guid.NewGuid().ToString()}
            }, "Hello, world!");

            await fsQueueingService.EnqueueMessage(queueName, message, Thread.CurrentPrincipal);
            await listenerCalledEvent.WaitOneAsync(TimeSpan.FromSeconds(1));

            // The listener is called before the file is deleted, so there is a possible
            // race condition here.  Wait for a second to allow the delete to take place
            // before enumerating the files to see that they were actually deleted.
            await Task.Delay(TimeSpan.FromSeconds(1));

            var messageEqualityComparer = new MessageEqualityComparer();
            mockListener.Verify(
                x =>
                    x.MessageReceived(It.Is<Message>(m => messageEqualityComparer.Equals(m, message)),
                        It.IsAny<IQueuedMessageContext>(), It.IsAny<CancellationToken>()), Times.Once());

            var queuedMessages = queueDir.EnumerateFiles()
                .Select(f => new MessageFile(f))
                .ToList();

            Assert.That(queuedMessages, Is.Empty);
        }
コード例 #9
0
        public async Task Given_Existing_Message_When_Creating_Queue_Then_Listener_Should_Fire()
        {
            var listenerCalledEvent = new ManualResetEvent(false);
            var tempDir = GetTempDirectory();
            var queueName = new QueueName(Guid.NewGuid().ToString());
            var queuePath = Path.Combine(tempDir.FullName, queueName);
            var queueDir = new DirectoryInfo(queuePath);
            if (!queueDir.Exists)
            {
                queueDir.Create();
            }

            var message = new Message(new MessageHeaders
            {
                {HeaderName.ContentType, "text/plain"},
                {HeaderName.MessageId, Guid.NewGuid().ToString()}
            }, "Hello, world!");

            await MessageFile.Create(queueDir, message, Thread.CurrentPrincipal);

            var fsQueueingService = new FilesystemMessageQueueingService(tempDir);
            fsQueueingService.Init();

            var mockListener = new Mock<IQueueListener>();
            mockListener.Setup(
                x =>
                    x.MessageReceived(It.IsAny<Message>(), It.IsAny<IQueuedMessageContext>(),
                        It.IsAny<CancellationToken>()))
                .Callback<Message, IQueuedMessageContext, CancellationToken>((msg, ctx, ct) =>
                {
                    ctx.Acknowledge();
                    listenerCalledEvent.Set();
                })
                .Returns(Task.FromResult(true));

            await fsQueueingService.CreateQueue(queueName, mockListener.Object, new QueueOptions {MaxAttempts = 1});
            await listenerCalledEvent.WaitOneAsync(TimeSpan.FromSeconds(1));

            var messageEqualityComparer = new MessageEqualityComparer();
            mockListener.Verify(
                x =>
                    x.MessageReceived(It.Is<Message>(m => messageEqualityComparer.Equals(m, message)),
                        It.IsAny<IQueuedMessageContext>(), It.IsAny<CancellationToken>()), Times.Once());
        }
コード例 #10
0
        public async Task Given_Existing_Message_When_Creating_Queue_Then_Listener_Should_Fire()
        {
            var listenerCalledEvent = new ManualResetEvent(false);
            var baseDirectory = GetTempDirectory();
            var queueName = new QueueName(Guid.NewGuid().ToString());

            var message = new Message(new MessageHeaders
            {
                {HeaderName.ContentType, "text/plain"},
                {HeaderName.MessageId, Guid.NewGuid().ToString()}
            }, "Hello, world!");

            var sqlQueueingService = new SQLiteMessageQueueingService(baseDirectory);
            sqlQueueingService.Init();

            // Insert a test message before creating queue
            var sqlQueueInspector = new SQLiteMessageQueueInspector(baseDirectory, queueName);
            await sqlQueueInspector.InsertMessage(message, Thread.CurrentPrincipal);

            var mockListener = new Mock<IQueueListener>();
            mockListener.Setup(x =>
                    x.MessageReceived(It.IsAny<Message>(), It.IsAny<IQueuedMessageContext>(),
                        It.IsAny<CancellationToken>()))
                .Callback<Message, IQueuedMessageContext, CancellationToken>((msg, ctx, ct) =>
                {
                    ctx.Acknowledge();
                    listenerCalledEvent.Set();
                })
                .Returns(Task.FromResult(true));

            // Create the queue, which should trigger the inserted message to be enqueued
            // and processed
            await sqlQueueingService.CreateQueue(queueName, mockListener.Object, new QueueOptions {MaxAttempts = 1});
            await listenerCalledEvent.WaitOneAsync(TimeSpan.FromSeconds(1));

            var messageEqualityComparer = new MessageEqualityComparer();
            mockListener.Verify(x =>
                x.MessageReceived(It.Is<Message>(m => messageEqualityComparer.Equals(m, message)),
                    It.IsAny<IQueuedMessageContext>(), It.IsAny<CancellationToken>()), Times.Once());
        }
コード例 #11
0
        public async Task Given_Auto_Acknowledge_Queue_When_Not_Acknowledged_Then_Message_Should_Be_Deleted()
        {
            var queueName = new QueueName(Guid.NewGuid().ToString());
            var rmqQueueingService = new RabbitMQMessageQueueingService(RabbitMQUri);

            try
            {
                var listenerCalledEvent = new ManualResetEvent(false);
                var mockListener = new Mock<IQueueListener>();
                mockListener.Setup(x =>
                    x.MessageReceived(It.IsAny<Message>(), It.IsAny<IQueuedMessageContext>(),
                        It.IsAny<CancellationToken>()))
                    .Callback<Message, IQueuedMessageContext, CancellationToken>(
                        (msg, ctx, ct) => { listenerCalledEvent.Set(); })
                    .Returns(Task.FromResult(true));

                await rmqQueueingService.CreateQueue(queueName, mockListener.Object, new QueueOptions {AutoAcknowledge = true});

                var message = new Message(new MessageHeaders
                {
                    {HeaderName.ContentType, "text/plain"},
                    {HeaderName.MessageId, Guid.NewGuid().ToString()}
                }, "Hello, world!");

                await rmqQueueingService.EnqueueMessage(queueName, message, Thread.CurrentPrincipal);
                await listenerCalledEvent.WaitOneAsync(TimeSpan.FromSeconds(1));

                // The listener is called before the file is deleted, so there is a possible
                // race condition here.  Wait for a second to allow the delete to take place
                // before enumerating the files to see that they were actually deleted.
                await Task.Delay(TimeSpan.FromSeconds(1));

                var messageEqualityComparer = new MessageEqualityComparer();
                mockListener.Verify(x =>
                    x.MessageReceived(It.Is<Message>(m => messageEqualityComparer.Equals(m, message)),
                        It.IsAny<IQueuedMessageContext>(), It.IsAny<CancellationToken>()), Times.Once());

                Assert.That(GetQueueDepth(queueName), Is.EqualTo(0));
                Assert.That(GetQueueDepth(queueName.GetRetryQueueName()), Is.EqualTo(0));
            }
            finally
            {
                rmqQueueingService.Dispose();
                DeleteQueue(queueName);
            }
        }