public void Consume_Continues_When_Node_We_Are_Not_Connected_To_Is_Blocked() { var _publisherBusConfigurationBuilder = new BusConfigurationBuilder(Accessories.Configuration.ConnectionSettingsString.Replace("myTestConnection", "publisher")); _publisherBusConfigurationBuilder .RegisterPublication <Accessories.MyEvent>(Accessories.Configuration.ExchangeName1, typeof(Accessories.MyEvent).Name, MessageDeliveryMode.Persistent, message => "test.queue.1"); var _publisherBus = new Bus(_publisherBusConfigurationBuilder.Build()); _publisherBus.Connect(); // Let node that we are connected to = NodeA // Let other node = NodeB // Before blocking rabbitmq service on NodeB, verify cluster is in working order // We publish 50,000 messages and verify that these are on the queue // We continuously consume the 50,000 messages // During consumption, block NodeB for a period of time, then unblock // rabbitmqctl set_vm_memory_high_watermark 0.0000001 // rabbitmqctl set_vm_memory_high_watermark 0.4 // Verify 0 messages exist on queue // Verify consumed message count is at least 50,000 for (int count = 0; count < 50000; count++) { var _messageId = Guid.NewGuid(); var _message = new Accessories.MyEvent(_messageId, null, "R1", 1, "09:00", "DDD...."); _publisherBus.PublishAsync(_message); } Console.WriteLine("Verify exactly 50000 messages in the queue"); // Note that we see that a number of messages seem to get delivered more than once. This however is expected behaviour as we are using acknowledgements // See link: https://groups.google.com/forum/#!topic/rabbitmq-users/PODU8wIYmQs Console.ReadKey(); var _consumedMessageCount = 0; var _consumerBusConfigurationBuilder = new BusConfigurationBuilder(Accessories.Configuration.ConnectionSettingsString.Replace("myTestConnection", "consumer")); _consumerBusConfigurationBuilder.NumberOfConsumers = 5; _consumerBusConfigurationBuilder .RegisterConsumer <Accessories.MyEvent>( Accessories.Configuration.QueueName1, typeof(Accessories.MyEvent).Name, message => { Interlocked.Increment(ref _consumedMessageCount); return(ConsumerHandlerResult.Completed); }); var _consumerBus = new Bus(_consumerBusConfigurationBuilder.Build()); _consumerBus.Connect(); for (int _counter = 0; _counter < 60; _counter++) { Thread.Sleep(1000); Console.WriteLine(string.Format("{0} seconds completed", _counter)); } Console.WriteLine("Ensure there are no messages in the queue"); Console.WriteLine(string.Format("Consumed message count expected(at least): (50000), actual: ({0})", _consumedMessageCount)); Console.ReadKey(); }
public void Publish_Connection_Closed_By_Application_Never_Recovers() { var _busConfigurationBuilder = new BusConfigurationBuilder(Accessories.Configuration.ConnectionSettingsString); _busConfigurationBuilder .RegisterPublication <Accessories.MyEvent>(Accessories.Configuration.ExchangeName1, typeof(Accessories.MyEvent).Name, MessageDeliveryMode.Persistent, message => Accessories.Configuration.QueueName1); var _SUT = new Bus(_busConfigurationBuilder.Build()); _SUT.Connect(); Console.WriteLine("Verify connection exists. Press enter to close connection ..."); Console.ReadKey(); // Close the connection explicitly _SUT.Close(); // Attempt to publish after closing the connection from the application, this should never happen in reality ... var _message = new Accessories.MyEvent(Guid.NewGuid(), "", "R1", 1, "09:00", "DDD...."); var _result = _SUT.PublishAsync(_message); Console.WriteLine("Should keep retrying to publish every second indefinitely"); Console.WriteLine("This is due to the fact that the application initiated the close"); Console.WriteLine("Normally, close is only called when application is closing down"); Console.Read(); }
public void Publish_A_Message_And_Consume_For_The_Same_Message_With_Nack_And_Dead_Letter_Queue() { var _capturedMessageId = string.Empty; var _busConfigurationBuilder = new BusConfigurationBuilder(Accessories.Configuration.ConnectionSettingsString); _busConfigurationBuilder.NumberOfConsumers = 2; _busConfigurationBuilder .RegisterPublication <Accessories.MyEvent>(Accessories.Configuration.ExchangeName2, typeof(Accessories.MyEvent).Name, MessageDeliveryMode.Persistent, message => "test.queue.2") .RegisterConsumer <Accessories.MyEvent>( Accessories.Configuration.QueueName2, typeof(Accessories.MyEvent).Name, message => { _capturedMessageId = message.Id.ToString(); return(ConsumerHandlerResult.Errored); }); var _SUT = new Bus(_busConfigurationBuilder.Build()); _SUT.Connect(); var _messageId = Guid.NewGuid(); var _message = new Accessories.MyEvent(_messageId, null, "R1", 1, "09:00", "DDD...."); _SUT.PublishAsync(_message); Thread.Sleep(2000); Console.WriteLine(string.Format("Captured message id expected: ({0}), actual: ({1})", _messageId, _capturedMessageId)); Console.WriteLine(string.Format("Ensure message with id: ({0}) no longer exists in the queue", _messageId)); Console.WriteLine(string.Format("Ensure message with id: ({0}) exists in the dead letter queue - rejected", _messageId)); Console.Read(); }
public void Publish_1000_Messages_To_A_Queue_Using_Custom_Exchange() { var _busConfigurationBuilder = new BusConfigurationBuilder(Accessories.Configuration.ConnectionSettingsString); _busConfigurationBuilder .RegisterPublication <Accessories.MyEvent>(Accessories.Configuration.ExchangeName1, typeof(Accessories.MyEvent).Name, MessageDeliveryMode.Persistent, message => Accessories.Configuration.QueueName1); var _SUT = new Bus(_busConfigurationBuilder.Build()); _SUT.Connect(); var _tasks = new ConcurrentBag <Task <PMCG.Messaging.PublicationResult> >(); for (int count = 0; count < 1000; count++) { var _message = new Accessories.MyEvent(Guid.NewGuid(), "", "R1", 1, "09:00", "DDD...."); _tasks.Add(_SUT.PublishAsync(_message)); } Task.WhenAll(_tasks).ContinueWith(a => { var _taskStatusCount = _tasks.Count(result => result.Status == TaskStatus.RanToCompletion); var _messagePublishedCount = _tasks.Count(result => result.Result.Status == Messaging.PublicationResultStatus.Published); Console.WriteLine(string.Format("RanToCompletionTaskCount expected: (1000), actual: ({0})", _taskStatusCount)); Console.WriteLine(string.Format("MessagePublishedCount expected: (1000), actual: ({0})", _messagePublishedCount)); Console.WriteLine("Verify that 1000 messages on queue on management ui"); }); Console.Read(); }
public void Publish_1000_Messages_And_Consume_For_The_Same_Messsage_On_A_Transient_Queue() { var _busConfigurationBuilder = new BusConfigurationBuilder(Accessories.Configuration.ConnectionSettingsString); _busConfigurationBuilder .RegisterPublication <Accessories.MyEvent>(Accessories.Configuration.ExchangeName1, typeof(Accessories.MyEvent).Name) .RegisterConsumer <Accessories.MyEvent>( typeof(Accessories.MyEvent).Name, message => { return(ConsumerHandlerResult.Completed); }, Accessories.Configuration.ExchangeName1); var _SUT = new Bus(_busConfigurationBuilder.Build()); _SUT.Connect(); Console.WriteLine("Wait for transient queue to appear on management ui"); Console.ReadKey(); var _message = new Accessories.MyEvent(Guid.NewGuid(), "Correlation Id", "R1", 1, "09:00", "...."); for (int count = 0; count < 1000; count++) { _SUT.PublishAsync(_message); } Console.WriteLine("Ensure there are no messages in the queue"); Console.WriteLine("Ensure transient queue appears and disappears"); Console.ReadKey(); }
public void Publish_10000_Messages_And_Consume_For_The_Same_Messages_With_Ack_Connection_Closed_By_Server_Recovers_Automatically() { var _busConfigurationBuilder = new BusConfigurationBuilder(Accessories.Configuration.ConnectionSettingsString); _busConfigurationBuilder.NumberOfConsumers = 2; _busConfigurationBuilder .RegisterPublication <Accessories.MyEvent>(Accessories.Configuration.ExchangeName2, typeof(Accessories.MyEvent).Name, MessageDeliveryMode.Persistent, message => "test.queue.2") .RegisterConsumer <Accessories.MyEvent>( Accessories.Configuration.QueueName2, typeof(Accessories.MyEvent).Name, message => { return(ConsumerHandlerResult.Completed); }); var _SUT = new Bus(_busConfigurationBuilder.Build()); _SUT.Connect(); Console.WriteLine("Close connection via rabbitmq management ui while loop is executing"); for (int count = 0; count < 10000; count++) { var _messageId = Guid.NewGuid(); var _message = new Accessories.MyEvent(_messageId, null, "R1", 1, "09:00", "DDD...."); _SUT.PublishAsync(_message); } Console.WriteLine("Ensure there are no messages in the queue"); Console.WriteLine("Ensure there are some messages in the dead letter queue(reason expired)"); Console.ReadKey(); }
public void Publish_1000_Messages_And_Consume_For_The_Same_Messages_With_Half_Acked_Half_Nacked() { var _busConfigurationBuilder = new BusConfigurationBuilder(Accessories.Configuration.ConnectionSettingsString); _busConfigurationBuilder.NumberOfConsumers = 2; _busConfigurationBuilder .RegisterPublication <Accessories.MyEvent>(Accessories.Configuration.ExchangeName2, typeof(Accessories.MyEvent).Name, MessageDeliveryMode.Persistent, message => "test.queue.2") .RegisterConsumer <Accessories.MyEvent>( Accessories.Configuration.QueueName2, typeof(Accessories.MyEvent).Name, message => { return(bool.Parse(message.RunIdentifier) ? ConsumerHandlerResult.Completed : ConsumerHandlerResult.Errored); }); var _SUT = new Bus(_busConfigurationBuilder.Build()); _SUT.Connect(); for (int count = 0; count < 1000; count++) { var _messageId = Guid.NewGuid(); var _runIdentifier = (count % 2 == 0); var _message = new Accessories.MyEvent(_messageId, null, _runIdentifier.ToString(), 1, "09:00", "DDD...."); _SUT.PublishAsync(_message); } Console.WriteLine("Ensure there are no messages in the queue"); Console.WriteLine("Ensure 500 messages exists in the dead letter queue - rejected"); Console.Read(); }
public void Consume_Continues_When_Node_We_Are_Connected_To_Is_Rebooted() { var _publisherBusConfigurationBuilder = new BusConfigurationBuilder(Accessories.Configuration.ConnectionSettingsString.Replace("myTestConnection", "publisher")); _publisherBusConfigurationBuilder .RegisterPublication <Accessories.MyEvent>(Accessories.Configuration.ExchangeName1, typeof(Accessories.MyEvent).Name, MessageDeliveryMode.Persistent, message => "test.queue.1"); var _publisherBus = new Bus(_publisherBusConfigurationBuilder.Build()); _publisherBus.Connect(); // Let node that we are connected to = NodeA // Let other node = NodeB // Before rebooting NodeA, verify cluster is in working order // We publish 50,000 messages and verify that these are on the queue // We continuously consume the 50,000 messages // During consumption, reboot NodeA // Verify 0 messages exist on queue // Verify consumed message count is nearly 50,000 for (int count = 0; count < 50000; count++) { var _messageId = Guid.NewGuid(); var _message = new Accessories.MyEvent(_messageId, null, "R1", 1, "09:00", "DDD...."); _publisherBus.PublishAsync(_message); } Console.WriteLine("Verify at least 50000 messages in the queue"); Console.ReadKey(); var _consumedMessageCount = 0; var _consumerBusConfigurationBuilder = new BusConfigurationBuilder(Accessories.Configuration.ConnectionSettingsString.Replace("myTestConnection", "consumer")); _consumerBusConfigurationBuilder.NumberOfConsumers = 5; _consumerBusConfigurationBuilder .RegisterConsumer <Accessories.MyEvent>( Accessories.Configuration.QueueName1, typeof(Accessories.MyEvent).Name, message => { Interlocked.Increment(ref _consumedMessageCount); return(ConsumerHandlerResult.Completed); }); var _consumerBus = new Bus(_consumerBusConfigurationBuilder.Build()); _consumerBus.Connect(); for (int _counter = 0; _counter < 60; _counter++) { Thread.Sleep(1000); Console.WriteLine(string.Format("{0} seconds completed", _counter)); } Console.WriteLine("Ensure there are no messages in the queue"); Console.WriteLine(string.Format("Consumed message count expected(nearly): (50000), actual: ({0})", _consumedMessageCount)); Console.ReadKey(); }
public void Publish_Continues_When_Both_Nodes_Are_Rebooted_Consecutively_Simulating_Ubuntu_Updates() { var _busConfigurationBuilder = new BusConfigurationBuilder(Accessories.Configuration.ConnectionSettingsString); _busConfigurationBuilder .RegisterPublication <Accessories.MyEvent>(Accessories.Configuration.ExchangeName1, typeof(Accessories.MyEvent).Name, MessageDeliveryMode.Persistent, message => Accessories.Configuration.QueueName1); var _SUT = new Bus(_busConfigurationBuilder.Build()); _SUT.Connect(); // Let node that we are connected to = NodeA // Let other node = NodeB // Before rebooting NodeA, verify cluster is in working order // We publish continuously for 15,000 messages // During publication, reboot NodeA // reboot // Wait for the reboot to finish, verify cluster is in working order // Synchronize the queue (if required, otherwise this may result in lost messages) // During publication, reboot NodeB // reboot // Wait for the reboot to finish, verify cluster is in working order // Verify 15,000 messages exist on queue var _tasks = new ConcurrentBag <Task <PMCG.Messaging.PublicationResult> >(); for (int count = 0; count < 15000; count++) { var _message = new Accessories.MyEvent(Guid.NewGuid(), "", "R1", 1, "09:00", "DDD...."); _tasks.Add(_SUT.PublishAsync(_message)); Console.WriteLine(count); Thread.Sleep(10); } Task.WhenAll(_tasks).ContinueWith(a => { var _taskStatusCount = _tasks.Count(result => result.Status == TaskStatus.RanToCompletion); var _messagePublishedCount = _tasks.Count(result => result.Result.Status == Messaging.PublicationResultStatus.Published); Console.WriteLine(string.Format("RanToCompletionTaskCount expected: (10000), actual: ({0})", _taskStatusCount)); Console.WriteLine(string.Format("MessagePublishedCount expected: (10000), actual: ({0})", _messagePublishedCount)); }); Console.Read(); }
public void Publish_Continues_When_Node_We_Are_Connected_To_Is_Blocked() { var _busConfigurationBuilder = new BusConfigurationBuilder(Accessories.Configuration.ConnectionSettingsString); _busConfigurationBuilder .RegisterPublication <Accessories.MyEvent>(Accessories.Configuration.ExchangeName1, typeof(Accessories.MyEvent).Name, MessageDeliveryMode.Persistent, message => Accessories.Configuration.QueueName1); var _SUT = new Bus(_busConfigurationBuilder.Build()); _SUT.Connect(); // Let node that we are connected to = NodeA // Let other node = NodeB // Before blocking NodeA, verify cluster is in working order // We publish continuously for 10,000 messages // During publication, block NodeA for a period of time, then unblock // rabbitmqctl set_vm_memory_high_watermark 0.0000001 // rabbitmqctl set_vm_memory_high_watermark 0.4 // Verify 10,000 messages exist on queue // Verify cluster is in working order // NOTE: When we run high volume very fast we see messages go missing, we do not think this is worth chasing up on // We also know that for some edge cases, channel.BasicPublish can execute where the messages simply go missing, this is simply another one of these use cases var _tasks = new ConcurrentBag <Task <PMCG.Messaging.PublicationResult> >(); for (int count = 0; count < 10000; count++) { var _message = new Accessories.MyEvent(Guid.NewGuid(), "", "R1", 1, "09:00", "DDD...."); _tasks.Add(_SUT.PublishAsync(_message)); Console.WriteLine(count); Thread.Sleep(1); } Task.WhenAll(_tasks).ContinueWith(a => { var _taskStatusCount = _tasks.Count(result => result.Status == TaskStatus.RanToCompletion); var _messagePublishedCount = _tasks.Count(result => result.Result.Status == Messaging.PublicationResultStatus.Published); Console.WriteLine(string.Format("RanToCompletionTaskCount expected(nearly): (10000), actual: ({0})", _taskStatusCount)); Console.WriteLine(string.Format("MessagePublishedCount expected(nearly): (10000), actual: ({0})", _messagePublishedCount)); }); Console.Read(); }
public void Publish_50000_Messages_And_Then_Consume_On_Separate_Bus_For_The_Same_Messages() { var _publisherBusConfigurationBuilder = new BusConfigurationBuilder(Accessories.Configuration.ConnectionSettingsString.Replace("myTestConnection", "publisher")); _publisherBusConfigurationBuilder .RegisterPublication <Accessories.MyEvent>(Accessories.Configuration.ExchangeName1, typeof(Accessories.MyEvent).Name, MessageDeliveryMode.Persistent, message => "test.queue.1"); var _publisherBus = new Bus(_publisherBusConfigurationBuilder.Build()); _publisherBus.Connect(); for (int count = 0; count < 50000; count++) { var _messageId = Guid.NewGuid(); var _message = new Accessories.MyEvent(_messageId, null, "R1", 1, "09:00", "DDD...."); _publisherBus.PublishAsync(_message); } Console.WriteLine("Verify 50000 messages in the queue"); Console.ReadKey(); var _consumedMessageCount = 0; var _consumerBusConfigurationBuilder = new BusConfigurationBuilder(Accessories.Configuration.ConnectionSettingsString.Replace("myTestConnection", "consumer")); _consumerBusConfigurationBuilder.NumberOfConsumers = 2; _consumerBusConfigurationBuilder .RegisterConsumer <Accessories.MyEvent>( Accessories.Configuration.QueueName1, typeof(Accessories.MyEvent).Name, message => { Interlocked.Increment(ref _consumedMessageCount); return(ConsumerHandlerResult.Completed); }); var _consumerBus = new Bus(_consumerBusConfigurationBuilder.Build()); _consumerBus.Connect(); Thread.Sleep(20000); Console.WriteLine("Ensure there are no messages in the queue"); Console.WriteLine("Ensure there are some messages in the dead letter queue(reason expired)"); Console.WriteLine(string.Format("Consumed message count expected: (50000), actual: ({0})", _consumedMessageCount)); Console.ReadKey(); }
public void Publish_A_Message_To_A_Queue_Using_Custom_Exchange() { var _busConfigurationBuilder = new BusConfigurationBuilder(Accessories.Configuration.ConnectionSettingsString); _busConfigurationBuilder .RegisterPublication <Accessories.MyEvent>(Accessories.Configuration.ExchangeName1, typeof(Accessories.MyEvent).Name, MessageDeliveryMode.Persistent, message => Accessories.Configuration.QueueName1); var _SUT = new Bus(_busConfigurationBuilder.Build()); _SUT.Connect(); var _message = new Accessories.MyEvent(Guid.NewGuid(), "", "R1", 1, "09:00", "DDD...."); var _result = _SUT.PublishAsync(_message); _result.Wait(TimeSpan.FromSeconds(1)); Console.WriteLine(string.Format("TaskStatus expected: (RanToCompletion), actual: ({0})", _result.Status)); Console.WriteLine(string.Format("PublicationResultStatus expected: (Published), actual: ({0})", _result.Result.Status)); Console.WriteLine("Verify a message is on the queue in management ui"); Console.Read(); }
public void Publish_Continues_When_Node_We_Are_Connected_To_Has_RabbitMQ_Service_Stopped() { var _busConfigurationBuilder = new BusConfigurationBuilder(Accessories.Configuration.ConnectionSettingsString); _busConfigurationBuilder .RegisterPublication <Accessories.MyEvent>(Accessories.Configuration.ExchangeName1, typeof(Accessories.MyEvent).Name, MessageDeliveryMode.Persistent, message => Accessories.Configuration.QueueName1); var _SUT = new Bus(_busConfigurationBuilder.Build()); _SUT.Connect(); // Let node that we are connected to = NodeA // Let other node = NodeB // Before stopping rabbitmq service on NodeA, verify cluster is in working order // We publish continuously for 10,000 messages // During publication, stop rabbitmq service on NodeA // service rabbitmq-server stop // Verify 10,000 messages exist on queue // Verify we are now connected to NodeB (via automatic recovery) // Start rabbitmq service on NodeA var _tasks = new ConcurrentBag <Task <PMCG.Messaging.PublicationResult> >(); for (int count = 0; count < 10000; count++) { var _message = new Accessories.MyEvent(Guid.NewGuid(), "", "R1", 1, "09:00", "DDD...."); _tasks.Add(_SUT.PublishAsync(_message)); Console.WriteLine(count); Thread.Sleep(1); } Task.WhenAll(_tasks).ContinueWith(a => { var _taskStatusCount = _tasks.Count(result => result.Status == TaskStatus.RanToCompletion); var _messagePublishedCount = _tasks.Count(result => result.Result.Status == Messaging.PublicationResultStatus.Published); Console.WriteLine(string.Format("RanToCompletionTaskCount expected: (10000), actual: ({0})", _taskStatusCount)); Console.WriteLine(string.Format("MessagePublishedCount expected: (10000), actual: ({0})", _messagePublishedCount)); }); Console.Read(); }
public void Publish_With_Timeout() { var _busConfigurationBuilder = new BusConfigurationBuilder(Accessories.Configuration.ConnectionSettingsString); _busConfigurationBuilder .RegisterPublication <Accessories.MyEvent>(Accessories.Configuration.ExchangeName1, typeof(Accessories.MyEvent).Name, MessageDeliveryMode.Persistent, message => Accessories.Configuration.QueueName1); var _SUT = new Bus(_busConfigurationBuilder.Build()); _SUT.Connect(); var _message = new Accessories.MyEvent(Guid.NewGuid(), "", "R1", 1, "09:00", "DDD...."); var _result = _SUT.PublishAsync(_message); if (!_result.Wait(TimeSpan.FromMilliseconds(1))) { Console.WriteLine(string.Format("TaskStatus expected: (WaitingForActivation), actual: ({0})", _result.Status)); } Console.WriteLine("Verify that 1 message on queue on management ui"); Console.Read(); }
public void Publish_Continues_When_Node_We_Are_Connected_To_Has_Connection_Forced_Closed_Via_Management_UI() { var _busConfigurationBuilder = new BusConfigurationBuilder(Accessories.Configuration.ConnectionSettingsString); _busConfigurationBuilder .RegisterPublication <Accessories.MyEvent>(Accessories.Configuration.ExchangeName1, typeof(Accessories.MyEvent).Name, MessageDeliveryMode.Persistent, message => Accessories.Configuration.QueueName1); var _SUT = new Bus(_busConfigurationBuilder.Build()); _SUT.Connect(); // Let node that we are connected to = NodeA // Let other node = NodeB // Before forcing the connection to be closed on NodeA, verify cluster is in working order // We publish continuously for 10,000 messages // During publication, force connection closed on NodeA via management UI // Verify nearly all 10,000 messages exist on queue // - we expect some messages to go missing here as not all messages may get published when a network failure occurs // Verify we reconnect via automatic recovery var _tasks = new ConcurrentBag <Task <PMCG.Messaging.PublicationResult> >(); for (int count = 0; count < 10000; count++) { var _message = new Accessories.MyEvent(Guid.NewGuid(), "", "R1", 1, "09:00", "DDD...."); _tasks.Add(_SUT.PublishAsync(_message)); Console.WriteLine(count); Thread.Sleep(1); } Task.WhenAll(_tasks).ContinueWith(a => { var _taskStatusCount = _tasks.Count(result => result.Status == TaskStatus.RanToCompletion); var _messagePublishedCount = _tasks.Count(result => result.Result.Status == Messaging.PublicationResultStatus.Published); Console.WriteLine(string.Format("RanToCompletionTaskCount expected(nearly): (10000), actual: ({0})", _taskStatusCount)); Console.WriteLine(string.Format("MessagePublishedCount expected(nearly): (10000), actual: ({0})", _messagePublishedCount)); }); Console.Read(); }
public void Publish_Connection_Blocked_Then_Unblocked_Unpublished_Messages_Are_Republished_Successfully() { var _busConfigurationBuilder = new BusConfigurationBuilder(Accessories.Configuration.ConnectionSettingsString); _busConfigurationBuilder .RegisterPublication <Accessories.MyEvent>(Accessories.Configuration.ExchangeName1, typeof(Accessories.MyEvent).Name, MessageDeliveryMode.Persistent, message => Accessories.Configuration.QueueName1); var _SUT = new Bus(_busConfigurationBuilder.Build()); _SUT.Connect(); // This test manually takes the following steps: // 1 - We publish every second for 1 minute // 2 - We block connection by setting memory high watermark to a very low setting // ./rabbitmqctl.bat set_vm_memory_high_watermark 0.0000001 // 3 - Observe that for a period of time it fails to publish , retrying every second (via logs) // 4 - We unblock connection by setting memory high watermark back to normal setting // ./rabbitmqctl.bat set_vm_memory_high_watermark 0.4 // 5 - Observe that the connection is automatically recovered after a period of time (via UI) // 6 - Observe that all failed messages have since published successfully (via logs) var _tasks = new ConcurrentBag <Task <PMCG.Messaging.PublicationResult> >(); for (int count = 0; count < 60; count++) { Thread.Sleep(1000); var _message = new Accessories.MyEvent(Guid.NewGuid(), "", "R1", 1, "09:00", "DDD...."); _tasks.Add(_SUT.PublishAsync(_message)); } Task.WhenAll(_tasks).ContinueWith(a => { var _taskStatusCount = _tasks.Count(result => result.Status == TaskStatus.RanToCompletion); var _messagePublishedCount = _tasks.Count(result => result.Result.Status == Messaging.PublicationResultStatus.Published); Console.WriteLine(string.Format("RanToCompletionTaskCount expected: (60), actual: ({0})", _taskStatusCount)); Console.WriteLine(string.Format("MessagePublishedCount expected: (60), actual: ({0})", _messagePublishedCount)); Console.WriteLine("Verify that 60 message on queue on management ui"); }); Console.Read(); }
public void Publish_10000_Messages_And_Consume_For_The_Same_Messages_With_Ack_Blocked_Then_Unblocked() { var _busConfigurationBuilder = new BusConfigurationBuilder(Accessories.Configuration.ConnectionSettingsString); _busConfigurationBuilder.NumberOfConsumers = 2; _busConfigurationBuilder .RegisterPublication <Accessories.MyEvent>(Accessories.Configuration.ExchangeName2, typeof(Accessories.MyEvent).Name, MessageDeliveryMode.Persistent, message => "test.queue.2") .RegisterConsumer <Accessories.MyEvent>( Accessories.Configuration.QueueName2, typeof(Accessories.MyEvent).Name, message => { return(ConsumerHandlerResult.Completed); }); var _SUT = new Bus(_busConfigurationBuilder.Build()); _SUT.Connect(); for (int count = 0; count < 10000; count++) { if (count == 300) { Console.WriteLine("Set high water mark to very low value (i.e. block)"); Console.WriteLine("\t rabbitmqctl.bat set_vm_memory_high_watermark 0.0000001"); Console.ReadKey(); } if (count == 9800) { Console.WriteLine("Set high water mark to very low value (i.e. unblock)"); Console.WriteLine("\t rabbitmqctl.bat set_vm_memory_high_watermark 0.4"); Console.ReadKey(); } var _messageId = Guid.NewGuid(); var _message = new Accessories.MyEvent(_messageId, null, "R1", 1, "09:00", "DDD...."); _SUT.PublishAsync(_message); } Console.WriteLine("Ensure there are no messages in the queue"); Console.WriteLine("Ensure there are some messages in the dead letter queue (reason expired)"); Console.ReadKey(); }
public void Publish_A_Message_To_An_Exchange_That_Doesnt_Exist() { // The channel shutdown event is invoked by RabbitMQ server as the exchange does not exist. // This is an unrecoverable scenario that we cannot cater for, however it should never happen anyway as there should never be an incorrectly configured exchange var _busConfigurationBuilder = new BusConfigurationBuilder(Accessories.Configuration.ConnectionSettingsString); _busConfigurationBuilder .RegisterPublication <Accessories.MyEvent>("exchange_that_doesnt_exist", typeof(Accessories.MyEvent).Name, MessageDeliveryMode.Persistent, message => Accessories.Configuration.QueueName1); var _SUT = new Bus(_busConfigurationBuilder.Build()); _SUT.Connect(); var _message = new Accessories.MyEvent(Guid.NewGuid(), "", "R1", 1, "09:00", "DDD...."); var _result = _SUT.PublishAsync(_message); _result.Wait(TimeSpan.FromSeconds(1)); Console.WriteLine(string.Format("TaskStatus expected: (RanToCompletion), actual: ({0})", _result.Status)); Console.WriteLine(string.Format("PublicationResultStatus expected: (NotPublished), actual: ({0})", _result.Result.Status)); Console.Read(); }
public void Publish_A_Message_That_Expires_Ends_Up_In_Dead_Letter_Queue() { var _capturedMessageId = string.Empty; var _busConfigurationBuilder = new BusConfigurationBuilder(Accessories.Configuration.ConnectionSettingsString); _busConfigurationBuilder.NumberOfConsumers = 2; _busConfigurationBuilder .RegisterPublication <Accessories.MyEvent>(Accessories.Configuration.ExchangeName2, "test.queue.2", MessageDeliveryMode.Persistent, message => "test.queue.2"); var _SUT = new Bus(_busConfigurationBuilder.Build()); _SUT.Connect(); var _messageId = Guid.NewGuid(); var _message = new Accessories.MyEvent(_messageId, null, "R1", 1, "09:00", "DDD...."); _SUT.PublishAsync(_message); Console.WriteLine(string.Format("Ensure message with id: ({0}) no longer exists in the queue", _messageId)); Console.WriteLine(string.Format("Ensure message with id: ({0}) exists in the dead letter queue - expired", _messageId)); Console.Read(); }
public void Publish_Connection_Closed_By_Server_Recovers_Automatically() { var _busConfigurationBuilder = new BusConfigurationBuilder(Accessories.Configuration.ConnectionSettingsString); _busConfigurationBuilder .RegisterPublication <Accessories.MyEvent>(Accessories.Configuration.ExchangeName1, typeof(Accessories.MyEvent).Name, MessageDeliveryMode.Persistent, message => Accessories.Configuration.QueueName1); var _SUT = new Bus(_busConfigurationBuilder.Build()); _SUT.Connect(); // This test manually takes the following steps: // 1 - We publish continuously for 40,000 messages // 2 - We close the connection via the UI by clicking on connections, forcing close // 3 - Observe that for a period of time it fails to publish , retrying every second (via logs) // 4 - Observe that the connection is automatically recovered after a period of time (via management ui) // 5 - Observe that all failed messages have since published successfully (via logs) var _tasks = new ConcurrentBag <Task <PMCG.Messaging.PublicationResult> >(); for (int count = 0; count < 10000; count++) { var _message = new Accessories.MyEvent(Guid.NewGuid(), "", "R1", 1, "09:00", "DDD...."); _tasks.Add(_SUT.PublishAsync(_message)); Console.WriteLine(count); System.Threading.Thread.Sleep(1); } Task.WhenAll(_tasks).ContinueWith(a => { var _taskStatusCount = _tasks.Count(result => result.Status == TaskStatus.RanToCompletion); var _messagePublishedCount = _tasks.Count(result => result.Result.Status == Messaging.PublicationResultStatus.Published); Console.WriteLine(string.Format("RanToCompletionTaskCount expected: (10000), actual: ({0})", _taskStatusCount)); Console.WriteLine(string.Format("MessagePublishedCount expected: (10000), actual: ({0})", _messagePublishedCount)); }); Console.Read(); }
public void Publish_Invalid_Message_Is_Null() { var _busConfigurationBuilder = new BusConfigurationBuilder(Accessories.Configuration.ConnectionSettingsString); _busConfigurationBuilder .RegisterPublication <Accessories.MyEvent>(Accessories.Configuration.ExchangeName1, typeof(Accessories.MyEvent).Name, MessageDeliveryMode.Persistent, message => Accessories.Configuration.QueueName1); var _SUT = new Bus(_busConfigurationBuilder.Build()); _SUT.Connect(); // This is an unrecoverable scenario that we cannot cater for, however it should never happen anyway as there should never be a null message try { Accessories.MyEvent _message = null; var _result = _SUT.PublishAsync(_message); _result.Wait(TimeSpan.FromSeconds(1)); } catch (Exception exception) { Console.WriteLine(string.Format("Exception expected: (Value cannot be null.Parameter name: message), actual: ({0})", exception.Message)); } Console.Read(); }
public void Consume_Continues_When_Node_We_Are_Connected_To_Has_RabbitMQ_Service_Stopped() { var _publisherBusConfigurationBuilder = new BusConfigurationBuilder(Accessories.Configuration.ConnectionSettingsString.Replace("myTestConnection", "publisher")); _publisherBusConfigurationBuilder .RegisterPublication <Accessories.MyEvent>(Accessories.Configuration.ExchangeName1, typeof(Accessories.MyEvent).Name, MessageDeliveryMode.Persistent, message => "test.queue.1"); var _publisherBus = new Bus(_publisherBusConfigurationBuilder.Build()); _publisherBus.Connect(); // Let node that we are connected to = NodeA // Let other node = NodeB // Before stopping rabbitmq service on NodeA, verify cluster is in working order // We publish 50,000 messages and verify that these are on the queue // We continuously consume the 50,000 messages // During consumption, stop rabbitmq service on NodeA // service rabbitmq-server stop // Verify 0 messages exist on queue // Verify consumed message count is at least 50,000 // Start rabbitmq service on NodeA // Note that sometimes we see that the queue does not failover to a slave due to queues being in an unsynchronized state // This will only ever happen if the rabbitmq server is manually stopped. This is not applicable to server reboot for example // that can occur during Ubuntu updates. If you upgrade the cluster in situ (for minor version upgrades), this has a possibility // of occurring albeit its highly unlikely. The outcome of this is that the queue does not get back to normality until the node is restarted. // See section "Stopping master nodes with only unsynchronised slaves": https://rabbitmq.docs.pivotal.io/36/rabbit-web-docs/ha.html#start-stop for (int count = 0; count < 50000; count++) { var _messageId = Guid.NewGuid(); var _message = new Accessories.MyEvent(_messageId, null, "R1", 1, "09:00", "DDD...."); _publisherBus.PublishAsync(_message); } Console.WriteLine("Verify at least 50000 messages in the queue"); // Note that we see that a number of messages seem to get delivered more than once. This however is expected behaviour as we are using acknowledgements // See link: https://groups.google.com/forum/#!topic/rabbitmq-users/PODU8wIYmQs Console.ReadKey(); var _consumedMessageCount = 0; var _consumerBusConfigurationBuilder = new BusConfigurationBuilder(Accessories.Configuration.ConnectionSettingsString.Replace("myTestConnection", "consumer")); _consumerBusConfigurationBuilder.NumberOfConsumers = 2; _consumerBusConfigurationBuilder .RegisterConsumer <Accessories.MyEvent>( Accessories.Configuration.QueueName1, typeof(Accessories.MyEvent).Name, message => { Interlocked.Increment(ref _consumedMessageCount); return(ConsumerHandlerResult.Completed); }); var _consumerBus = new Bus(_consumerBusConfigurationBuilder.Build()); _consumerBus.Connect(); for (int _counter = 0; _counter < 60; _counter++) { Thread.Sleep(1000); Console.WriteLine(string.Format("{0} seconds completed", _counter)); } Console.WriteLine("Ensure there are no messages in the queue"); Console.WriteLine(string.Format("Consumed message count expected(at least): (50000), actual: ({0})", _consumedMessageCount)); Console.ReadKey(); }