public void ShouldWaitForWorkCompleteWhereAllWorkersAreBlockedOnRingBuffer()
        {
            long expectedNumberMessages = 10;

            fillRingBuffer(expectedNumberMessages);

            var workers = new StubConsumer[3];

            for (int i = 0, size = workers.Length; i < size; i++)
            {
                workers[i]          = new StubConsumer(0);
                workers[i].Sequence = (expectedNumberMessages - 1);
            }

            IConsumerBarrier consumerBarrier = ringBuffer.CreateConsumerBarrier(workers);
            ThreadStart      runnable        = () =>
            {
                StubEntry entry = producerBarrier.NextEntry();
                entry.Value = ((int)entry.Sequence);
                producerBarrier.Commit(entry);

                foreach (StubConsumer stubWorker in workers)
                {
                    stubWorker.Sequence = (entry.Sequence);
                }
            };


            new Thread(runnable).Start();

            long expectedWorkSequence  = expectedNumberMessages;
            long completedWorkSequence = consumerBarrier.WaitFor(expectedNumberMessages);

            Assert.IsTrue(completedWorkSequence >= expectedWorkSequence);
        }
        public void ShouldWaitForWorkCompleteWhereCompleteWorkThresholdIsBehind()
        {
            long expectedNumberMessages = 10;

            fillRingBuffer(expectedNumberMessages);

            var entryConsumers = new StubConsumer[3];

            for (int i = 0, size = entryConsumers.Length; i < size; i++)
            {
                entryConsumers[i]          = new StubConsumer(0);
                entryConsumers[i].Sequence = (expectedNumberMessages - 2);
            }

            IConsumerBarrier consumerBarrier = ringBuffer.CreateConsumerBarrier(entryConsumers);

            ThreadStart runnable = () =>
            {
                foreach (StubConsumer stubWorker in entryConsumers)
                {
                    stubWorker.Sequence += 1;
                }
            };


            new Thread(runnable).Start();

            long expectedWorkSequence  = expectedNumberMessages - 1;
            long completedWorkSequence = consumerBarrier.WaitFor(expectedWorkSequence);

            Assert.IsTrue(completedWorkSequence >= expectedWorkSequence);
        }
		public void ShouldWaitForWorkCompleteWhereAllWorkersAreBlockedOnRingBuffer()
		{
			long expectedNumberMessages = 10;
			fillRingBuffer(expectedNumberMessages);

			var workers = new StubConsumer[3];
			for (int i = 0, size = workers.Length; i < size; i++)
			{
				workers[i] = new StubConsumer(0);
				workers[i].Sequence = (expectedNumberMessages - 1);
			}

			IConsumerBarrier consumerBarrier = ringBuffer.CreateConsumerBarrier(workers);
			ThreadStart runnable = () =>
			{
				StubEntry entry = producerBarrier.NextEntry();
				entry.Value = ((int) entry.Sequence);
				producerBarrier.Commit(entry);

				foreach (StubConsumer stubWorker in workers)
				{
					stubWorker.Sequence = (entry.Sequence);
				}
			};


			new Thread(runnable).Start();

			long expectedWorkSequence = expectedNumberMessages;
			long completedWorkSequence = consumerBarrier.WaitFor(expectedNumberMessages);
			Assert.IsTrue(completedWorkSequence >= expectedWorkSequence);
		}
        public async Task Subscriber_MalformedMessage_MessageMustBeMovedToGlobalDeadLetterQueue(string caseName, string messageBody)
        {
            var testName = $"{nameof(Subscriber_MalformedMessage_MessageMustBeMovedToGlobalDeadLetterQueue)}_{caseName}";
            //prepare
            IConfiguration configuration = ConfigurationHelper.ProvideConfiguration();
            var            exchangeName  =
                $"{testName}.exchangename";

            configuration["rabbitmq:exchangename"]     = exchangeName;
            configuration["rabbitmq:waitexchangename"] = exchangeName.Replace("exchangename", "waitexchangename");

            var maxretrycount = 2;

            IContainer container = ConfigurationHelper.ConfigureContainer(configuration);

            //create Subscriber
            var         bookingCreatedSubscriberFactory = container.Resolve <ISubscriberFactory>();
            ISubscriber typedSubscriber =
                await bookingCreatedSubscriberFactory
                .CreateSubscriberAsync(testName +
                                       ".stubconsumer", new List <string> {
                "*.entity.create.booking"
            },
                                       maxretrycount);

            var consumer = new StubConsumer();

            typedSubscriber.Subscribe(SubscriptionBuilder.Create().AddDefaultSubscription(() => consumer).Build());

            //create Bus
            var    bus        = container.Resolve <IAdvancedBus>();
            string routingKey = "changetracker.entity.create.booking";

            //act
            var body       = Encoding.UTF8.GetBytes(messageBody);
            var properties = new MessageProperties
            {
                DeliveryMode = 2//persistent
            };
            await bus.PublishAsync(await bus.ExchangeDeclareAsync(exchangeName, ExchangeType.Topic), routingKey, false, properties, body);

            await Task.Delay(3000);

            //check
            var             deadleterqueue = bus.QueueDeclare($"{exchangeName}.defaultTombQueue");
            IBasicGetResult result         = bus.Get(deadleterqueue);

            var     message    = Encoding.UTF8.GetString(result.Body);
            JObject errorEvent = JObject.Parse(message);

            errorEvent["RoutingKey"].Value <string>().Should().Be("changetracker.entity.create.booking");
            errorEvent["Exchange"]
            .Value <string>().Should().Be(exchangeName);
            errorEvent["Queue"]
            .Value <string>().Should().Be($"{exchangeName}.{testName}.stubconsumer");

            //check bindings
            var managementClient = new ManagementClient(configuration["rabbitmqmanagement:hostUrl"], configuration["rabbitmqmanagement:username"], configuration["rabbitmqmanagement:password"], configuration.GetValue <int>("rabbitmqmanagement:portNumber"));
            var virtualHostName  = new ConnectionStringParser().Parse(configuration["rabbitmq:connectionstring"]).VirtualHost;
            var virtualhost      = await managementClient.GetVhostAsync(virtualHostName);

            var deadleterq = await managementClient.GetQueueAsync(deadleterqueue.Name, virtualhost);

            var deadleterqbindings = (await managementClient.GetBindingsForQueueAsync(deadleterq)).ToList();

            deadleterqbindings.Should().HaveCount(2);//one is default
            deadleterqbindings.Where(x => x.Source == $"{exchangeName}_error" && x.RoutingKey == routingKey).Should().HaveCount(1);

            container.Dispose();
        }
        public void ShouldWaitForWorkCompleteWhereCompleteWorkThresholdIsBehind()
        {
            long expectedNumberMessages = 10;
            fillRingBuffer(expectedNumberMessages);

            var entryConsumers = new StubConsumer[3];
            for (int i = 0, size = entryConsumers.Length; i < size; i++)
            {
                entryConsumers[i] = new StubConsumer(0);
                entryConsumers[i].Sequence = (expectedNumberMessages - 2);
            }

            IConsumerBarrier consumerBarrier = ringBuffer.CreateConsumerBarrier(entryConsumers);

            ThreadStart runnable = () =>
                                       {
                                           foreach (StubConsumer stubWorker in entryConsumers)
                                           {
                                               stubWorker.Sequence += 1;
                                           }
                                       };


            new Thread(runnable).Start();

            long expectedWorkSequence = expectedNumberMessages - 1;
            long completedWorkSequence = consumerBarrier.WaitFor(expectedWorkSequence);
            Assert.IsTrue(completedWorkSequence >= expectedWorkSequence);
        }