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(); }
public void MessageListenerTest() { var mockConnectionFactory = new Mock <RC.IConnectionFactory>(); var mockConnection = new Mock <RC.IConnection>(); var onlyChannel = new Mock <RC.IModel>(); onlyChannel.Setup(m => m.IsOpen).Returns(true); var tooManyModels = new Exception(); var cachingConnectionFactory = new CachingConnectionFactory(mockConnectionFactory.Object); mockConnectionFactory.Setup(m => m.CreateConnection()).Returns(mockConnection.Object); mockConnection.Setup(m => m.IsOpen).Returns(true); Func <RC.IModel> ensureOneModel = EnsureOneModel(onlyChannel.Object, tooManyModels); mockConnection.Setup(m => m.CreateModel()).Returns(onlyChannel.Object); RC.IBasicConsumer consumer; CountdownEvent consumerLatch = new CountdownEvent(1); onlyChannel.Setup(m => m.BasicConsume(It.IsAny <string>(), It.IsAny <bool>(), It.IsAny <string>(), It.IsAny <bool>(), It.IsAny <bool>(), null, It.IsAny <RC.IBasicConsumer>())) .Returns((string queue, bool autoAck, string consumerTag, bool noLocal, bool exclusive, IDictionary <string, object> arguments, RC.IBasicConsumer iConsumer) => { consumer = iConsumer; consumerLatch.Signal(); return("consumerTag"); }); var commitLatch = new CountdownEvent(1); onlyChannel.Setup(m => m.TxCommit()).Callback(() => { commitLatch.Signal(); }); var rollbackEvent = new CountdownEvent(1); onlyChannel.Setup(m => m.TxRollback()).Callback(() => { rollbackEvent.Signal(); }); onlyChannel.Setup(m => m.BasicAck(It.IsAny <ulong>(), It.IsAny <bool>())); var latch = new CountdownEvent(1); var container = new DirectMessageListenerContainer(null, cachingConnectionFactory); var adapter = new MessageListenerAdapter(null, new TestListener(cachingConnectionFactory, latch)); container.SetupMessageListener(adapter); container.SetQueueNames("queue"); container.ShutdownTimeout = 100; container.TransactionManager = new DummyTxManager(); container.TransactionAttribute = new DefaultTransactionAttribute(); container.Initialize(); container.Start(); // Assert.True(consumerLatch.Wait(TimeSpan.FromSeconds(10))); }
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 <RC.IModel>(); var rabbitChannel2 = new Mock <RC.IModel>(); var target = new AtomicReference <RC.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 RC.QueueDeclareOk("test", 0, 0)); var consumer = new AtomicReference <RC.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 <RC.IBasicConsumer>())) .Callback <string, bool, string, bool, bool, IDictionary <string, object>, RC.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(); }
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(RC.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"); } }
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 <RC.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 RC.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 <RC.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); }
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 <RC.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 RC.QueueDeclareOk("test", 0, 0)); var consumer = new AtomicReference <RC.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 <RC.IBasicConsumer>())) .Callback <string, bool, string, bool, bool, IDictionary <string, object>, RC.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)); }
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 <RC.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 RC.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 <RC.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 <RC.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 <RC.IBasicConsumer>()), Times.Exactly(2)); await container.Stop(); }
public ListenFromAutoDeleteQueueTest() { connectionFactory = new CachingConnectionFactory("localhost") { IsPublisherReturns = true }; // Container Admin containerAdmin = new TestAdmin(connectionFactory); // Exchange var directExchange = new DirectExchange("testContainerWithAutoDeleteQueues", true, true); listenerContainer1 = new DirectMessageListenerContainer(null, connectionFactory, "container1"); listenerContainer1.ConsumersPerQueue = 2; listenerContainer1.AddQueueNames(Q1, Q2); containerAdmin.DeclareExchange(directExchange); containerAdmin.DeclareQueue(new Config.Queue(Q1, true, false, true)); containerAdmin.DeclareQueue(new Config.Queue(Q2, true, false, true)); containerAdmin.DeclareBinding(new Binding("b1", Q1, Binding.DestinationType.QUEUE, directExchange.ExchangeName, Q1, null)); containerAdmin.DeclareBinding(new Binding("b2", Q2, Binding.DestinationType.QUEUE, directExchange.ExchangeName, Q2, null)); // Listener listener = new AppendingListener(); var adapter = new MessageListenerAdapter(null, listener); listenerContainer1.MessageListener = adapter; listenerContainer1.Start(); listenerContainer1._startedLatch.Wait(TimeSpan.FromSeconds(10)); // Conditional declarations var otherExchange = new DirectExchange(Exch2, true, true); containerAdmin.DeclareExchange(otherExchange); containerAdmin.DeclareQueue(new Config.Queue(Q3, true, false, true)); containerAdmin.DeclareBinding(new Binding("b3", Q3, Binding.DestinationType.QUEUE, otherExchange.ExchangeName, Q3, null)); listenerContainer2 = new DirectMessageListenerContainer(null, connectionFactory, "container2"); listenerContainer2.IsAutoStartup = false; listenerContainer2.ShutdownTimeout = 50; listenerContainer2.AddQueueNames(Q3); listenerContainer2.MessageListener = adapter; expiringQueue = new Config.Queue(Guid.NewGuid().ToString(), true, false, false, new Dictionary <string, object>() { { "x-expires", 200 } }); containerAdmin.DeclareQueue(expiringQueue); listenerContainer3 = new DirectMessageListenerContainer(null, connectionFactory, "container3"); listenerContainer3.IsAutoStartup = false; listenerContainer3.ShutdownTimeout = 50; listenerContainer3.AddQueueNames(expiringQueue.QueueName); listenerContainer3.MessageListener = adapter; listenerContainer4 = new DirectMessageListenerContainer(null, connectionFactory, "container4"); listenerContainer4.IsAutoStartup = false; listenerContainer4.ShutdownTimeout = 50; listenerContainer4.AddQueueNames(Q2); listenerContainer4.MessageListener = adapter; listenerContainer4.AutoDeclare = false; }