public void Should_not_ack_if_not_auto_ack()
        {
            // Arrange
            var waitHandler = new ManualResetEvent(false);
            var queue = Substitute.For<IInMemoryPriorityQueue<GenericPriorityMessage<BasicDeliverEventArgs>>>();
            queue.When(x => x.Dequeue()).Do(callInfo => waitHandler.WaitOne());

            var model = Substitute.For<IModel>();
            model.IsOpen.Returns(true);

            var handler = Substitute.For<IMessageHandler>();
            var subscription = new CompositeSubscription();
            subscription.AddSubscription(new Subscription(model) { ConsumerTag = "ConsumerTag" });

            var consumer = new PriorityBurrowConsumer(model, handler, Substitute.For<IRabbitWatcher>(), false, 1);
            consumer.Init(queue, subscription, 1, Guid.NewGuid().ToString());
            consumer.Ready();

            // Action
            handler.HandlingComplete += Raise.Event<MessageHandlingEvent>(new BasicDeliverEventArgs { ConsumerTag = "ConsumerTag" });
            
            // Assert
            model.DidNotReceive().BasicAck(Arg.Any<ulong>(), Arg.Any<bool>());
            waitHandler.Set();
            consumer.Dispose();
        }
Beispiel #2
0
        public void Should_call_Nack_on_nested_subscriptions_with_all_delivery_tag()
        {
            // Arrange
            var channel = Substitute.For<IModel>();
            channel.IsOpen.Returns(true);
            var subs = new CompositeSubscription();
            var subscription = new Subscription
            {
                ConsumerTag = "ConsumerTag",
                QueueName = "QueueName",
                SubscriptionName = "SubscriptionName"
            };
            subscription.SetChannel(channel);
            subs.AddSubscription(subscription);

            // Action
            subs.Nack("ConsumerTag", new[] { (ulong)1, (ulong)2, (ulong)3, (ulong)4, (ulong)5 }, false);

            // Assert
            channel.Received().BasicNack(1, false, false);
            channel.Received().BasicNack(2, false, false);
            channel.Received().BasicNack(3, false, false);
            channel.Received().BasicNack(4, false, false);
            channel.Received().BasicNack(5, false, false);
        }
// ReSharper disable InconsistentNaming
        public void Should_throw_exception_if_privided_null_object()
// ReSharper restore InconsistentNaming
        {
            // Arrange
            var subs = new CompositeSubscription();

            // Action
            subs.AddSubscription(null);
            // Assert
        }
        public void Should_return_subscription_by_consumer_tag()
        {
            // Arrange
            var subs = new CompositeSubscription();
            var subscription = new Subscription
            {
                ConsumerTag = "ConsumerTag",
                QueueName = "QueueName",
                SubscriptionName = "SubscriptionName"
            };
            subs.AddSubscription(subscription);

            // Action & Assert
            Assert.AreSame(subscription, subs.GetByConsumerTag("ConsumerTag"));
            Assert.IsNull(subs.GetByConsumerTag("ConsumerTag2"));
        }
        public void Should_throw_SubscriptionNotFoundException_if_subscription_not_found()
        {
            // Arrange
            var channel = Substitute.For<IModel>();
            channel.IsOpen.Returns(true);
            var subs = new CompositeSubscription();
            var subscription = new Subscription
            {
                ConsumerTag = "ConsumerTag",
                QueueName = "QueueName",
                SubscriptionName = "SubscriptionName"
            };
            subscription.SetChannel(channel);
            subs.AddSubscription(subscription);

            // Action
            subs.NackAllOutstandingMessages("ConsumerTagNotFound", true);
        }
        public void Should_call_Nack_on_nested_subscriptions()
        {
            // Arrange
            var channel = Substitute.For<IModel>();
            var subs = new CompositeSubscription();
            var subscription = new Subscription
            {
                ConsumerTag = "ConsumerTag",
                QueueName = "QueueName",
                SubscriptionName = "SubscriptionName"
            };
            subscription.SetChannel(channel);
            subs.AddSubscription(subscription);

            // Action
            subs.Nack("ConsumerTag", 1, false);

            // Assert
            channel.Received().BasicNack(1, false, false);
        }
        public void Should_call_AckAllOutstandingMessages_on_nested_subscription()
        {
            // Arrange
            var channel = Substitute.For<IModel>();
            var subs = new CompositeSubscription();
            var subscription = new Subscription
            {
                ConsumerTag = "ConsumerTag",
                QueueName = "QueueName",
                SubscriptionName = "SubscriptionName"
            };
            subscription.SetChannel(channel);
            subs.AddSubscription(subscription);

            // Action
            subs.AckAllOutstandingMessages("ConsumerTag");

            // Assert
            channel.Received().BasicAck(0, true);
        }
        public void Should_call_ack_on_nested_subscriptions_with_the_max_value_of_delivery_tag()
        {
            // Arrange
            var channel = Substitute.For<IModel>();
            var subs = new CompositeSubscription();
            var subscription = new Subscription
            {
                ConsumerTag = "ConsumerTag",
                QueueName = "QueueName",
                SubscriptionName = "SubscriptionName"
            };
            subscription.SetChannel(channel);
            subs.AddSubscription(subscription);

            // Action
            subs.Ack("ConsumerTag", new[] { (ulong)1, (ulong)2, (ulong)3, (ulong)4, (ulong)5 });

            // Assert
            channel.Received().BasicAck(5, true);
        }
        public void Init(IInMemoryPriorityQueue<GenericPriorityMessage<BasicDeliverEventArgs>> priorityQueue, CompositeSubscription subscription, uint priority, string sharedSemaphore)
        {
            if (priorityQueue == null)
            {
                throw new ArgumentNullException("priorityQueue");
            }
            if (subscription == null)
            {
                throw new ArgumentNullException("subscription");
            }
            if (string.IsNullOrEmpty(sharedSemaphore))
            {
                throw new ArgumentNullException("sharedSemaphore");
            }

            _queuePriorirty = priority;
            _subscription = subscription;
            _sharedSemaphore = sharedSemaphore;
            PriorityQueue = priorityQueue;
            PriorityQueue.DeleteAll(msg => msg.Priority == priority);
        }
Beispiel #10
0
        public void Should_Nack_with_provided_delivery_tag_with_multiple_flag()
        {
            // Arrange
            var channel = Substitute.For<IModel>();
            channel.IsOpen.Returns(true);
            var subs = new CompositeSubscription();
            var subscription = new Subscription
            {
                ConsumerTag = "ConsumerTag",
                QueueName = "QueueName",
                SubscriptionName = "SubscriptionName"
            };
            subscription.SetChannel(channel);
            subs.AddSubscription(subscription);

            // Action
            subs.NackAllUpTo("ConsumerTag", 10, false);

            // Assert
            channel.Received(1).BasicNack(10, true, false);
        }
Beispiel #11
0
        public void Should_call_cancel_on_nested_subscriptions()
        {
            // Arrange
            var channel = Substitute.For<IModel>();
            channel.IsOpen.Returns(true);
            var subs = new CompositeSubscription();
            var subscription = new Subscription
            {
                ConsumerTag = "ConsumerTag",
                QueueName = "QueueName",
                SubscriptionName = "SubscriptionName"
            };
            subscription.SetChannel(channel);
            subs.AddSubscription(subscription);

            // Action
            subs.CancelAll();

            // Assert
            channel.Received().BasicCancel(subscription.ConsumerTag);
        }
Beispiel #12
0
        public void Should_call_ack_on_nested_subscriptions_with_all_delivery_tag()
        {
            // Arrange
            var channel = Substitute.For<IModel>();
            channel.IsOpen.Returns(true);
            var subs = new CompositeSubscription();
            var subscription = new Subscription
            {
                ConsumerTag = "ConsumerTag",
                QueueName = "QueueName",
                SubscriptionName = "SubscriptionName"
            };
            subscription.SetChannel(channel);
            subs.AddSubscription(subscription);

            // Action
            Subscription.OutstandingDeliveryTags["ConsumerTag"] = new List<ulong>();
            Subscription.OutstandingDeliveryTags["ConsumerTag"].AddRange(new ulong[] { 1, 2, 3, 4, 5 });
            subs.Ack("ConsumerTag", new[] { (ulong)1, (ulong)2, (ulong)3, (ulong)4, (ulong)5 });
            

            // Assert
            channel.Received().BasicAck(5, true);
        }
        private CompositeSubscription CreateSubscription <T>(IPrioritySubscriptionOption subscriptionOption, Func <IModel, IBasicConsumer> createConsumer)
        {
            var comparer = TryGetComparer(subscriptionOption.ComparerType);
            var compositeSubscription = new CompositeSubscription();

            uint maxSize = 0;

            for (uint level = 0; level <= subscriptionOption.MaxPriorityLevel; level++)
            {
                maxSize += GetProperPrefetchSize(subscriptionOption, level);
            }
            var priorityQueue = new InMemoryPriorityQueue <GenericPriorityMessage <BasicDeliverEventArgs> >(maxSize, comparer);

            var sharedSemaphore = string.Format("{0}{1}", subscriptionOption.SubscriptionName, Guid.NewGuid());

            for (uint level = 0; level <= subscriptionOption.MaxPriorityLevel; level++)
            {
                var subscription = new Subscription {
                    SubscriptionName = subscriptionOption.SubscriptionName
                };
                uint priority = level;
                var  id       = Guid.NewGuid();

                Action subscriptionAction = () =>
                {
                    subscription.QueueName = GetPriorityQueueName <T>(subscriptionOption, priority);
                    if (string.IsNullOrEmpty(subscription.ConsumerTag))
                    {
                        // Keep the key here because it's used for the key indexes of internal cache
                        subscription.ConsumerTag = string.Format("{0}-{1}", subscriptionOption.SubscriptionName, Guid.NewGuid());
                    }
                    var channel = _connection.CreateChannel();
                    channel.ModelShutdown += (o, reason) =>
                    {
                        RaiseConsumerDisconnectedEvent(subscription);
                        TryReconnect((IModel)o, id, reason);
                    };

                    var prefetchSize = GetProperPrefetchSize(subscriptionOption, priority);
                    channel.BasicQos(0, prefetchSize, false);

                    _createdChannels.Add(channel);

                    var consumer         = createConsumer(channel);
                    var priorityConsumer = consumer as PriorityBurrowConsumer;
                    if (priorityConsumer == null)
                    {
                        throw new NotSupportedException(string.Format("Expected PriorityBurrowConsumer but was {0}", consumer == null ? "NULL" : consumer.GetType().Name));
                    }

                    priorityConsumer.Init(priorityQueue, compositeSubscription, priority, sharedSemaphore);
                    priorityConsumer.ConsumerTag = subscription.ConsumerTag;
                    Subscription.OutstandingDeliveryTags[subscription.ConsumerTag] = new List <ulong>();
                    subscription.SetChannel(channel);

                    //NOTE: The message will still be on the Unacknowledged list until it's processed and the method
                    //      DoAck is call.
                    channel.BasicConsume(subscription.QueueName,
                                         false /* noAck, must be false */,
                                         subscription.ConsumerTag, priorityConsumer);
                    _watcher.InfoFormat("Subscribed to: {0} with subscriptionName: {1}",
                                        subscription.QueueName,
                                        subscription.SubscriptionName);
                    priorityConsumer.Ready();
                };

                _subscribeActions[id] = subscriptionAction;
                TrySubscribe(subscriptionAction);
                compositeSubscription.AddSubscription(subscription);
            }
            return(compositeSubscription);
        }