public async Task TestDirect()
        {
            var cf        = new CachingConnectionFactory("localhost");
            var container = new DirectMessageListenerContainer(null, cf);

            container.SetQueueNames(Q1, Q2);
            container.ConsumersPerQueue = 2;
            var listener = new ReplyingMessageListener();
            var adapter  = new MessageListenerAdapter(null, listener);

            container.MessageListener     = adapter;
            container.ServiceName         = "simple";
            container.ConsumerTagStrategy = new TestConsumerTagStrategy(testName);
            await container.Start();

            Assert.True(container._startedLatch.Wait(TimeSpan.FromSeconds(10)));
            var template = new RabbitTemplate(cf);

            Assert.Equal("FOO", template.ConvertSendAndReceive <string>(Q1, "foo"));
            Assert.Equal("BAR", template.ConvertSendAndReceive <string>(Q2, "bar"));
            await container.Stop();

            Assert.True(await ConsumersOnQueue(Q1, 0));
            Assert.True(await ConsumersOnQueue(Q2, 0));
            Assert.True(await ActiveConsumerCount(container, 0));
            Assert.Empty(container._consumersByQueue);
            await template.Stop();

            cf.Destroy();
        }
コード例 #2
0
            public SimpleConsumer(DirectMessageListenerContainer container, Connection.IConnection connection, R.IModel channel, string queue, ILogger logger = null)
                : base(channel)
            {
                _container  = container;
                _connection = connection;
                Queue       = queue;
                AckRequired = !_container.AcknowledgeMode.IsAutoAck() && !_container.AcknowledgeMode.IsManual();
                if (channel is IChannelProxy)
                {
                    _targetChannel = ((IChannelProxy)channel).TargetChannel;
                }
                else
                {
                    _targetChannel = null;
                }

                _logger              = logger;
                TransactionManager   = _container.TransactionManager;
                TransactionAttribute = _container.TransactionAttribute;
                IsRabbitTxManager    = TransactionManager is RabbitTransactionManager;
                ConnectionFactory    = _container.ConnectionFactory;
                MessagesPerAck       = _container.MessagesPerAck;
                LastAck              = DateTimeOffset.Now.ToUnixTimeMilliseconds();
                AckTimeout           = _container.AckTimeout;
            }
コード例 #3
0
        public async Task TestMonitorCancelsAfterTargetChannelChanges()
        {
            var connectionFactory = new Mock <Connection.IConnectionFactory>();
            var connection        = new Mock <Connection.IConnection>();
            var channel           = new Mock <IChannelProxy>();
            var rabbitChannel1    = new Mock <R.IModel>();
            var rabbitChannel2    = new Mock <R.IModel>();
            var target            = new AtomicReference <R.IModel>(rabbitChannel1.Object);

            channel.Setup(c => c.TargetChannel).Returns(() => target.Value);

            connectionFactory.Setup((f) => f.CreateConnection()).Returns(connection.Object);
            connection.Setup((c) => c.CreateChannel(It.IsAny <bool>())).Returns(channel.Object);
            connection.Setup((c) => c.IsOpen).Returns(true);
            channel.Setup(c => c.IsOpen).Returns(true);

            rabbitChannel1.Setup(c => c.CreateBasicProperties()).Returns(new MockRabbitBasicProperties());
            rabbitChannel2.Setup(c => c.CreateBasicProperties()).Returns(new MockRabbitBasicProperties());
            channel.Setup(c => c.QueueDeclarePassive(It.IsAny <string>())).Returns(new R.QueueDeclareOk("test", 0, 0));

            var consumer = new AtomicReference <R.IBasicConsumer>();
            var latch1   = new CountdownEvent(1);
            var latch2   = new CountdownEvent(1);

            channel.Setup(c =>
                          c.BasicConsume(It.IsAny <string>(), It.IsAny <bool>(), It.IsAny <string>(), It.IsAny <bool>(), It.IsAny <bool>(), It.IsAny <IDictionary <string, object> >(), It.IsAny <R.IBasicConsumer>()))
            .Callback <string, bool, string, bool, bool, IDictionary <string, object>, R.IBasicConsumer>(
                (queue, autoAck, consumerTag, noLocal, exclusive, args, cons) =>
            {
                consumer.Value = cons;
                latch1.Signal();
            })
            .Returns("consumerTag");

            channel.Setup(c => c.BasicCancel("consumerTag"))
            .Callback(() =>
            {
                consumer.Value.HandleBasicCancelOk("consumerTag");
                latch2.Signal();
            });
            var container = new DirectMessageListenerContainer(null, connectionFactory.Object);

            container.SetQueueNames("test");
            container.PrefetchCount   = 2;
            container.MonitorInterval = 100;
            container.MessageListener = new TestListener2(target, rabbitChannel2.Object);
            container.AcknowledgeMode = AcknowledgeMode.MANUAL;
            container.Initialize();
            await container.Start();

            Assert.True(container._startedLatch.Wait(TimeSpan.FromSeconds(10)));

            Assert.True(latch1.Wait(TimeSpan.FromSeconds(10)));
            var props = new MockRabbitBasicProperties();

            consumer.Value.HandleBasicDeliver("consumerTag", 1ul, false, string.Empty, string.Empty, props, new byte[1]);
            Assert.True(latch2.Wait(TimeSpan.FromSeconds(10)));
            await container.Stop();
        }
コード例 #4
0
        public void TestUninterruptibleListenerDMLC()
        {
            var cf    = new CachingConnectionFactory("localhost");
            var admin = new RabbitAdmin(cf);

            admin.DeclareQueue(new Config.Queue("test.shutdown"));

            var container = new DirectMessageListenerContainer(null, cf)
            {
                ShutdownTimeout = 500
            };

            container.SetQueueNames("test.shutdown");
            var latch     = new CountdownEvent(1);
            var testEnded = new CountdownEvent(1);
            var listener  = new TestListener(latch, testEnded);

            container.MessageListener = listener;
            var connection = cf.CreateConnection() as ChannelCachingConnectionProxy;

            // var channels = TestUtils.getPropertyValue(connection, "target.delegate._channelManager._channelMap");
            var field = typeof(RabbitMQ.Client.Framing.Impl.Connection)
                        .GetField("m_sessionManager", BindingFlags.Instance | BindingFlags.NonPublic);

            Assert.NotNull(field);
            var channels = (SessionManager)field.GetValue(connection.Target.Connection);

            Assert.NotNull(channels);

            container.Start();
            Assert.True(container._startedLatch.Wait(TimeSpan.FromSeconds(10)));

            try
            {
                var template = new RabbitTemplate(cf);
                template.Execute(c =>
                {
                    var properties = c.CreateBasicProperties();
                    var bytes      = EncodingUtils.GetDefaultEncoding().GetBytes("foo");
                    c.BasicPublish(string.Empty, "test.shutdown", false, properties, bytes);
                    RabbitUtils.SetPhysicalCloseRequired(c, false);
                });
                Assert.True(latch.Wait(TimeSpan.FromSeconds(30)));
                Assert.Equal(2, channels.Count);
            }
            finally
            {
                container.Stop();
                Assert.Equal(1, channels.Count);

                cf.Destroy();
                testEnded.Signal();
                admin.DeleteQueue("test.shutdown");
            }
        }
コード例 #5
0
        public async Task TestAlwaysCancelAutoRecoverConsumer()
        {
            var connectionFactory = new Mock <Connection.IConnectionFactory>();
            var connection        = new Mock <Connection.IConnection>();
            var channel           = new Mock <IChannelProxy>();
            var rabbitChannel     = new Mock <R.IModel>();

            channel.Setup(c => c.TargetChannel).Returns(rabbitChannel.Object);

            connectionFactory.Setup((f) => f.CreateConnection()).Returns(connection.Object);
            connection.Setup((c) => c.CreateChannel(It.IsAny <bool>())).Returns(channel.Object);

            connection.Setup((c) => c.IsOpen).Returns(true);
            var isOpen = new AtomicBoolean(true);

            channel.Setup((c) => c.IsOpen).Returns(() => isOpen.Value);
            rabbitChannel.Setup(c => c.CreateBasicProperties()).Returns(new MockRabbitBasicProperties());

            channel.Setup(c => c.QueueDeclarePassive(It.IsAny <string>())).Returns(new R.QueueDeclareOk("test", 0, 0));
            channel.Setup(c =>
                          c.BasicConsume(It.IsAny <string>(), It.IsAny <bool>(), It.IsAny <string>(), It.IsAny <bool>(), It.IsAny <bool>(), It.IsAny <IDictionary <string, object> >(), It.IsAny <R.IBasicConsumer>()))
            .Returns("consumerTag");

            var latch1 = new CountdownEvent(1);
            var qos    = new AtomicInteger();

            channel.Setup(c => c.BasicQos(It.IsAny <uint>(), It.IsAny <ushort>(), It.IsAny <bool>()))
            .Callback <uint, ushort, bool>((size, count, global) =>
            {
                qos.Value = count;
                latch1.Signal();
            });

            var latch2 = new CountdownEvent(1);

            channel.Setup(c => c.BasicCancel("consumerTag"))
            .Callback(() => latch2.Signal());
            var container = new DirectMessageListenerContainer(null, connectionFactory.Object);

            container.SetQueueNames("test");
            container.PrefetchCount   = 2;
            container.MonitorInterval = 100;
            container.Initialize();
            await container.Start();

            Assert.True(container._startedLatch.Wait(TimeSpan.FromSeconds(10)));

            Assert.True(latch1.Wait(TimeSpan.FromSeconds(10)));
            Assert.Equal(2, qos.Value);

            isOpen.Value = false;

            Assert.True(latch2.Wait(TimeSpan.FromSeconds(10)));
            await container.Stop();
        }
        private async Task <bool> ActiveConsumerCount(DirectMessageListenerContainer container, int expected)
        {
            var n         = 0;
            var consumers = container._consumers;

            while (n++ < 600 && consumers.Count != expected)
            {
                await Task.Delay(100);
            }

            return(consumers.Count == expected);
        }
コード例 #7
0
        public async Task TestDeferredAcks()
        {
            var connectionFactory = new Mock <Connection.IConnectionFactory>();
            var connection        = new Mock <Connection.IConnection>();
            var channel           = new Mock <IChannelProxy>();
            var rabbitChannel     = new Mock <R.IModel>();

            channel.Setup(c => c.TargetChannel).Returns(rabbitChannel.Object);
            connectionFactory.Setup((f) => f.CreateConnection()).Returns(connection.Object);
            connection.Setup((c) => c.CreateChannel(It.IsAny <bool>())).Returns(channel.Object);
            connection.Setup((c) => c.IsOpen).Returns(true);
            channel.Setup((c) => c.IsOpen).Returns(true);
            rabbitChannel.Setup(c => c.CreateBasicProperties()).Returns(new MockRabbitBasicProperties());
            channel.Setup(c => c.QueueDeclarePassive(It.IsAny <string>())).Returns(new R.QueueDeclareOk("test", 0, 0));

            var consumer = new AtomicReference <R.IBasicConsumer>();
            var latch1   = new CountdownEvent(1);

            channel.Setup(c =>
                          c.BasicConsume(It.IsAny <string>(), It.IsAny <bool>(), It.IsAny <string>(), It.IsAny <bool>(), It.IsAny <bool>(), It.IsAny <IDictionary <string, object> >(), It.IsAny <R.IBasicConsumer>()))
            .Callback <string, bool, string, bool, bool, IDictionary <string, object>, R.IBasicConsumer>(
                (queue, autoAck, consumerTag, noLocal, exclusive, args, cons) =>
            {
                consumer.Value = cons;
                cons.HandleBasicConsumeOk("consumerTag");
                latch1.Signal();
            })
            .Returns("consumerTag");
            var qos = new AtomicInteger();

            channel.Setup(c => c.BasicQos(It.IsAny <uint>(), It.IsAny <ushort>(), It.IsAny <bool>()))
            .Callback <uint, ushort, bool>((size, count, global) =>
            {
                qos.Value = count;
            });
            var latch2 = new CountdownEvent(1);
            var latch3 = new CountdownEvent(1);

            channel.Setup(c => c.BasicAck(It.IsAny <ulong>(), It.IsAny <bool>()))
            .Callback <ulong, bool>((tag, multi) =>
            {
                if (tag == 10ul || tag == 16ul)
                {
                    latch2.Signal();
                }
                else if (tag == 17ul)
                {
                    latch3.Signal();
                }
            });
            var latch4 = new CountdownEvent(1);

            channel.Setup(c => c.BasicNack(It.IsAny <ulong>(), It.IsAny <bool>(), It.IsAny <bool>()))
            .Callback <ulong, bool, bool>((tag, multi, re) =>
            {
                latch4.Signal();
            });
            var container = new DirectMessageListenerContainer(null, connectionFactory.Object);

            container.SetQueueNames("test");
            container.PrefetchCount   = 2;
            container.MonitorInterval = 100;
            container.MessagesPerAck  = 10;
            container.AckTimeout      = 100;
            container.MessageListener = new TestListener();
            container.Initialize();
            await container.Start();

            Assert.True(container._startedLatch.Wait(TimeSpan.FromSeconds(10)));

            Assert.True(latch1.Wait(TimeSpan.FromSeconds(10)));
            Assert.Equal(10, qos.Value);
            var props = new MockRabbitBasicProperties();

            var body = new byte[1];

            for (long i = 1; i < 16; i++)
            {
                consumer.Value.HandleBasicDeliver("consumerTag", (ulong)i, false, string.Empty, string.Empty, props, body);
            }

            Thread.Sleep(200);

            consumer.Value.HandleBasicDeliver("consumerTag", 16ul, false, string.Empty, string.Empty, props, body);

            // should get 2 acks #10 and #16 (timeout)
            Assert.True(latch2.Wait(TimeSpan.FromSeconds(10)));
            consumer.Value.HandleBasicDeliver("consumerTag", 17ul, false, string.Empty, string.Empty, props, body);
            channel.Verify(c => c.BasicAck(10ul, true));
            channel.Verify(c => c.BasicAck(15ul, true));

            Assert.True(latch3.Wait(TimeSpan.FromSeconds(10)));

            // monitor task timeout
            channel.Verify(c => c.BasicAck(17ul, true));
            consumer.Value.HandleBasicDeliver("consumerTag", 18ul, false, string.Empty, string.Empty, props, body);
            consumer.Value.HandleBasicDeliver("consumerTag", 19ul, false, string.Empty, string.Empty, props, body);
            Assert.True(latch4.Wait(TimeSpan.FromSeconds(10)));

            // pending acks before nack
            channel.Verify(c => c.BasicAck(18ul, true));
            channel.Verify(c => c.BasicNack(19ul, true, true));
            consumer.Value.HandleBasicDeliver("consumerTag", 20ul, false, string.Empty, string.Empty, props, body);
            var latch5 = new CountdownEvent(1);

            channel.Setup(c => c.BasicCancel("consumerTag"))
            .Callback(() =>
            {
                consumer.Value.HandleBasicCancelOk("consumerTag");
                latch5.Signal();
            });

            await container.Stop();

            Assert.True(latch5.Wait(TimeSpan.FromSeconds(10)));
            channel.Verify((c) => c.BasicAck(20ul, true));
        }
コード例 #8
0
        public async Task TestRemoveQueuesWhileNotConnected()
        {
            var connectionFactory = new Mock <Connection.IConnectionFactory>();
            var connection        = new Mock <Connection.IConnection>();
            var channel           = new Mock <IChannelProxy>();
            var rabbitChannel     = new Mock <R.IModel>();

            channel.Setup(c => c.TargetChannel).Returns(rabbitChannel.Object);

            connectionFactory.Setup((f) => f.CreateConnection()).Returns(connection.Object);
            connection.Setup((c) => c.CreateChannel(It.IsAny <bool>())).Returns(channel.Object);
            connection.Setup((c) => c.IsOpen).Returns(true);
            var isOpen = new AtomicBoolean(true);

            channel.Setup((c) => c.IsOpen).Returns(
                () =>
                isOpen.Value);
            rabbitChannel.Setup(c => c.CreateBasicProperties()).Returns(new MockRabbitBasicProperties());

            var declare = new AtomicReference <string>();

            channel.Setup(c => c.QueueDeclarePassive(It.IsAny <string>()))
            .Callback <string>(
                (name) =>
                declare.Value = name)
            .Returns(() =>
                     new R.QueueDeclareOk(declare.Value, 0, 0));

            var latch1 = new CountdownEvent(2);
            var latch3 = new CountdownEvent(3);

            channel.Setup(c =>
                          c.BasicConsume(It.IsAny <string>(), It.IsAny <bool>(), It.IsAny <string>(), It.IsAny <bool>(), It.IsAny <bool>(), It.IsAny <IDictionary <string, object> >(), It.IsAny <R.IBasicConsumer>()))
            .Callback(
                () =>
            {
                if (!latch3.IsSet)
                {
                    latch3.Signal();
                }
            })
            .Returns("consumerTag");
            var qos = new AtomicInteger();

            channel.Setup(c => c.BasicQos(It.IsAny <uint>(), It.IsAny <ushort>(), It.IsAny <bool>()))
            .Callback <uint, ushort, bool>((size, count, global) =>
            {
                qos.Value = count;
                if (!latch1.IsSet)
                {
                    latch1.Signal();
                }
            });

            var latch2 = new CountdownEvent(2);

            channel.Setup(
                c => c.BasicCancel("consumerTag"))
            .Callback(
                () =>
            {
                if (!latch2.IsSet)
                {
                    latch2.Signal();
                }
            });

            var container = new DirectMessageListenerContainer(null, connectionFactory.Object);

            container.SetQueueNames("test1", "test2");
            container.PrefetchCount   = 2;
            container.MonitorInterval = 100;
            container.FailedDeclarationRetryInterval = 100;
            container.RecoveryInterval = 100;
            container.ShutdownTimeout  = 1;
            container.Initialize();
            await container.Start();

            Assert.True(container._startedLatch.Wait(TimeSpan.FromSeconds(10)));

            Assert.True(latch1.Wait(TimeSpan.FromSeconds(10)));
            Assert.Equal(2, qos.Value);
            isOpen.Value = false;
            container.RemoveQueueNames("test1");
            Assert.True(latch2.Wait(TimeSpan.FromSeconds(20))); // Basic Cancels from isOpen = false
            isOpen.Value = true;                                // Consumers should restart, but only test2,
            Assert.True(latch3.Wait(TimeSpan.FromSeconds(10)));

            channel.Verify(
                c =>
                c.BasicConsume("test1", It.IsAny <bool>(), It.IsAny <string>(), It.IsAny <bool>(), It.IsAny <bool>(), It.IsAny <IDictionary <string, object> >(), It.IsAny <R.IBasicConsumer>()),
                Times.Once());
            channel.Verify(
                c =>
                c.BasicConsume("test2", It.IsAny <bool>(), It.IsAny <string>(), It.IsAny <bool>(), It.IsAny <bool>(), It.IsAny <IDictionary <string, object> >(), It.IsAny <R.IBasicConsumer>()),
                Times.Exactly(2));
            await container.Stop();
        }