Exemplo n.º 1
0
        public void SendAndAsyncReceive()
        {
            SimpleMessageListenerContainer container =
                (SimpleMessageListenerContainer)applicationContext["SimpleMessageListenerContainer"];
            SimpleMessageListener listener = applicationContext["SimpleMessageListener"] as SimpleMessageListener;

            Assert.IsNotNull(container);
            Assert.IsNotNull(listener);

            Admin admin = new Admin("tcp://localhost:7222", "admin", null);

            admin.PurgeQueue("test.queue");

            EmsTemplate emsTemplate = (EmsTemplate)applicationContext["MessageTemplate"] as EmsTemplate;

            Assert.IsNotNull(emsTemplate);

            Assert.AreEqual(0, listener.MessageCount);
            emsTemplate.ConvertAndSend("Hello World 1");

            int waitInMillis = 2000;

            Thread.Sleep(waitInMillis);
            Assert.AreEqual(1, listener.MessageCount);

            container.Stop();
            Console.WriteLine("container stopped.");
            emsTemplate.ConvertAndSend("Hello World 2");
            Thread.Sleep(waitInMillis);
            Assert.AreEqual(1, listener.MessageCount);

            container.Start();
            Console.WriteLine("container started.");
            Thread.Sleep(waitInMillis);
            Assert.AreEqual(2, listener.MessageCount);

            container.Shutdown();

            Thread.Sleep(waitInMillis);
        }
        public void SendAndAsyncReceive()
        {
            SimpleMessageListenerContainer container =
                (SimpleMessageListenerContainer)applicationContext["SimpleMessageListenerContainer"];
            SimpleMessageListener listener = applicationContext["SimpleMessageListener"] as SimpleMessageListener;

            Assert.IsNotNull(container);
            Assert.IsNotNull(listener);


            NmsTemplate nmsTemplate = (NmsTemplate)applicationContext["MessageTemplate"] as NmsTemplate;

            Assert.IsNotNull(nmsTemplate);

            Assert.AreEqual(0, listener.MessageCount);
            nmsTemplate.ConvertAndSend("Hello World 1");

            int waitInMillis = 2000;

            Thread.Sleep(waitInMillis);
            Assert.AreEqual(1, listener.MessageCount);

            container.Stop();
            Console.WriteLine("container stopped.");
            nmsTemplate.ConvertAndSend("Hello World 2");
            Thread.Sleep(waitInMillis);
            Assert.AreEqual(1, listener.MessageCount);

            container.Start();
            Console.WriteLine("container started.");
            Thread.Sleep(waitInMillis);
            Assert.AreEqual(2, listener.MessageCount);

            container.Shutdown();

            Thread.Sleep(waitInMillis);
        }
        /// <summary>Does the test.</summary>
        /// <param name="level">The level.</param>
        /// <param name="concurrency">The concurrency.</param>
        /// <param name="transactionMode">The transaction mode.</param>
        private void DoTest(MessageCount level, Concurrency concurrency, TransactionModeUtils.TransactionMode transactionMode)
        {
            var messageCount        = (int)level;
            var concurrentConsumers = (int)concurrency;
            var transactional       = transactionMode.IsTransactional();

            var template = this.CreateTemplate(concurrentConsumers);

            var latch = new CountdownEvent(messageCount);

            for (var i = 0; i < messageCount; i++)
            {
                template.ConvertAndSend(queue.Name, i + "foo");
            }

            var container = new SimpleMessageListenerContainer(template.ConnectionFactory);
            var listener  = new LifecyclePocoListener(latch);

            container.MessageListener     = new MessageListenerAdapter(listener);
            container.AcknowledgeMode     = transactionMode.AcknowledgeMode();
            container.ChannelTransacted   = transactionMode.IsTransactional();
            container.ConcurrentConsumers = concurrentConsumers;

            if (transactionMode.Prefetch() > 0)
            {
                container.PrefetchCount = transactionMode.Prefetch();
                container.TxSize        = transactionMode.TxSize();
            }

            container.QueueNames = new[] { queue.Name };
            container.AfterPropertiesSet();
            container.Start();

            try
            {
                var waited = latch.Wait(50);
                Logger.Info("All messages received before stop: " + waited);
                if (messageCount > 1)
                {
                    Assert.False(waited, "Expected not to receive all messages before stop");
                }

                Assert.AreEqual(concurrentConsumers, container.ActiveConsumerCount);
                container.Stop();
                Thread.Sleep(500);
                Assert.AreEqual(0, container.ActiveConsumerCount);
                if (!transactional)
                {
                    var messagesReceivedAfterStop = listener.Count;
                    waited = latch.Wait(500);
                    Logger.Info("All messages received after stop: " + waited);
                    if (messageCount < 100)
                    {
                        Assert.True(waited, "Expected to receive all messages after stop");
                    }

                    Assert.AreEqual(messagesReceivedAfterStop, listener.Count, "Unexpected additional messages received after stop");

                    for (var i = 0; i < messageCount; i++)
                    {
                        template.ConvertAndSend(queue.Name, i + "bar");
                    }

                    latch = new CountdownEvent(messageCount);
                    listener.Reset(latch);
                }

                var messagesReceivedBeforeStart = listener.Count;
                container.Start();
                var timeout = Math.Min(1 + messageCount / (4 * concurrentConsumers), 30);

                Logger.Debug("Waiting for messages with timeout = " + timeout + " (s)");
                waited = latch.Wait(timeout * 1000);
                Logger.Info("All messages received after start: " + waited);
                Assert.AreEqual(concurrentConsumers, container.ActiveConsumerCount);
                if (transactional)
                {
                    Assert.True(waited, "Timed out waiting for message");
                }
                else
                {
                    var count = listener.Count;
                    Assert.True(messagesReceivedBeforeStart < count, "Expected additional messages received after start: " + messagesReceivedBeforeStart + ">=" + count);
                    Assert.Null(template.Receive(queue.Name), "Messages still available");
                }

                Assert.AreEqual(concurrentConsumers, container.ActiveConsumerCount);
            }
            finally
            {
                // Wait for broker communication to finish before trying to stop
                // container
                Thread.Sleep(500);
                container.Shutdown();
                Assert.AreEqual(0, container.ActiveConsumerCount);
            }

            Assert.Null(template.ReceiveAndConvert(queue.Name));
        }
        public void TestMessageListener()
        {
            var mockConnectionFactory = new Mock <ConnectionFactory>();
            var mockConnection        = new Mock <IConnection>();
            var onlyChannel           = new Mock <IModel>();

            onlyChannel.Setup(m => m.IsOpen).Returns(true);
            onlyChannel.Setup(m => m.CreateBasicProperties()).Returns(() => new BasicProperties());

            var cachingConnectionFactory = new CachingConnectionFactory(mockConnectionFactory.Object);

            mockConnectionFactory.Setup(m => m.CreateConnection()).Returns(mockConnection.Object);
            mockConnection.Setup(m => m.IsOpen).Returns(true);

            var tooManyChannels = new AtomicReference <Exception>();
            var done            = false;

            mockConnection.Setup(m => m.CreateModel()).Returns(
                () =>
            {
                if (!done)
                {
                    done = true;
                    return(onlyChannel.Object);
                }

                tooManyChannels.LazySet(new Exception("More than one channel requested"));
                var channel = new Mock <IModel>();
                channel.Setup(m => m.IsOpen).Returns(true);
                return(channel.Object);
            });

            var consumer = new BlockingCollection <IBasicConsumer>(1);

            onlyChannel.Setup(m => m.BasicConsume(It.IsAny <string>(), It.IsAny <bool>(), It.IsAny <IBasicConsumer>())).Callback <string, bool, IBasicConsumer>(
                (a1, a2, a3) => consumer.Add(a3));

            var commitLatch = new CountdownEvent(1);

            onlyChannel.Setup(m => m.TxCommit()).Callback(
                () =>
            {
                if (commitLatch.CurrentCount > 0)
                {
                    commitLatch.Signal();
                }
            });

            var latch     = new CountdownEvent(1);
            var container = new SimpleMessageListenerContainer(cachingConnectionFactory);

            container.MessageListener = new Action <Message>(
                message =>
            {
                var rabbitTemplate = new RabbitTemplate(cachingConnectionFactory);
                rabbitTemplate.ChannelTransacted = true;

                // should use same channel as container
                rabbitTemplate.ConvertAndSend("foo", "bar", "baz");
                if (latch.CurrentCount > 0)
                {
                    latch.Signal();
                }
            });

            container.QueueNames         = new[] { "queue" };
            container.ChannelTransacted  = true;
            container.ShutdownTimeout    = 100;
            container.TransactionManager = DummyTxManager.Instance();
            container.AfterPropertiesSet();
            container.Start();

            IBasicConsumer currentConsumer;

            consumer.TryTake(out currentConsumer, this.timeout);
            Assert.IsNotNull(currentConsumer, "Timed out getting consumer.");
            currentConsumer.HandleBasicDeliver("qux", 1, false, "foo", "bar", new BasicProperties(), new byte[] { 0 });

            Assert.IsTrue(latch.Wait(new TimeSpan(0, 0, 10)));

            var e = tooManyChannels.Value;

            if (e != null)
            {
                throw e;
            }

            mockConnection.Verify(m => m.CreateModel(), Times.Once());
            Assert.True(commitLatch.Wait(new TimeSpan(0, 0, 10)));
            onlyChannel.Verify(m => m.TxCommit(), Times.Once());
            onlyChannel.Verify(m => m.BasicPublish(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <bool>(), It.IsAny <bool>(), It.IsAny <IBasicProperties>(), It.IsAny <byte[]>()), Times.Once());

            // verify close() was never called on the channel
            var cachedChannelsTransactionalField = typeof(CachingConnectionFactory).GetField("cachedChannelsTransactional", BindingFlags.NonPublic | BindingFlags.Instance);
            var channels = (LinkedList <IChannelProxy>)cachedChannelsTransactionalField.GetValue(cachingConnectionFactory);

            Assert.AreEqual(0, channels.Count);

            container.Stop();
            container.Dispose();
            container = null;
        }
        public void TestChannelAwareMessageListenerDontExpose()
        {
            var mockConnectionFactory = new Mock <ConnectionFactory>();
            var mockConnection        = new Mock <IConnection>();
            var firstChannel          = new Mock <IModel>();

            firstChannel.Setup(m => m.IsOpen).Returns(true);
            firstChannel.Setup(m => m.CreateBasicProperties()).Returns(() => new BasicProperties());

            var secondChannel = new Mock <IModel>();

            secondChannel.Setup(m => m.IsOpen).Returns(true);
            secondChannel.Setup(m => m.CreateBasicProperties()).Returns(() => new BasicProperties());

            var singleConnectionFactory = new SingleConnectionFactory(mockConnectionFactory.Object);

            mockConnectionFactory.Setup(m => m.CreateConnection()).Returns(mockConnection.Object);
            mockConnection.Setup(m => m.IsOpen).Returns(true);

            var tooManyChannels = new BlockingCollection <Exception>(1);
            var done            = false;

            mockConnection.Setup(m => m.CreateModel()).Returns(
                () =>
            {
                if (!done)
                {
                    done = true;
                    return(firstChannel.Object);
                }

                return(secondChannel.Object);
            });

            var consumer = new BlockingCollection <IBasicConsumer>(1);

            firstChannel.Setup(m => m.BasicConsume(It.IsAny <string>(), It.IsAny <bool>(), It.IsAny <IBasicConsumer>())).Callback <string, bool, IBasicConsumer>(
                (a1, a2, a3) => consumer.Add(a3));

            var commitLatch = new CountdownEvent(1);

            firstChannel.Setup(m => m.TxCommit()).Callback(() => commitLatch.Signal());

            var latch        = new CountdownEvent(1);
            var exposed      = new AtomicReference <IModel>();
            var container    = new SimpleMessageListenerContainer(singleConnectionFactory);
            var mockListener = new Mock <IChannelAwareMessageListener>();

            mockListener.Setup(m => m.OnMessage(It.IsAny <Message>(), It.IsAny <IModel>())).Callback <Message, IModel>(
                (message, channel) =>
            {
                exposed.LazySet(channel);
                var rabbitTemplate = new RabbitTemplate(singleConnectionFactory);
                rabbitTemplate.ChannelTransacted = true;

                // should use same channel as container
                rabbitTemplate.ConvertAndSend("foo", "bar", "baz");
                latch.Signal();
            });
            container.MessageListener = mockListener.Object;

            container.QueueNames            = new[] { "queue" };
            container.ChannelTransacted     = true;
            container.ExposeListenerChannel = false;
            container.ShutdownTimeout       = 100;
            container.AfterPropertiesSet();
            container.Start();

            IBasicConsumer currentConsumer;

            consumer.TryTake(out currentConsumer, timeout);
            Assert.IsNotNull(currentConsumer, "Timed out getting consumer.");
            currentConsumer.HandleBasicDeliver("qux", 1, false, "foo", "bar", new BasicProperties(), new byte[] { 0 });

            Assert.IsTrue(latch.Wait(new TimeSpan(0, 0, 10)));

            var e = tooManyChannels.Count;

            if (e > 0)
            {
                throw tooManyChannels.Take();
            }

            // once for listener, once for exposed + 0 for template (used bound)
            mockConnection.Verify(m => m.CreateModel(), Times.Exactly(2));
            Assert.IsTrue(commitLatch.Wait(new TimeSpan(0, 0, 10)));
            firstChannel.Verify(m => m.TxCommit(), Times.Once());
            secondChannel.Verify(m => m.TxCommit(), Times.Once());
            secondChannel.Verify(m => m.BasicPublish(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <bool>(), It.IsAny <bool>(), It.IsAny <IBasicProperties>(), It.IsAny <byte[]>()), Times.Once());

            Assert.AreSame(secondChannel.Object, exposed.Value);

            firstChannel.Verify(m => m.Close(), Times.Never());
            secondChannel.Verify(m => m.Close(), Times.Once());
            container.Stop();
        }