Beispiel #1
0
        public void NoLog()
        {
            // Arrange
            var topicName = "Consuming.BasicTests.NoLog";
            var subName   = topicName + "_Sub1";
            var topic     = _publisher.AddOrUpdateTopic(new Topic {
                Name = topicName, Log = false
            });                                                                                   // Log-flag should not matter, but just for sure
            var sub1 = _consumer.AddOrUpdateSubscription(new Subscription
            {
                Name               = subName,
                LogConsumed        = false,
                LogFailed          = false,
                TopicSubscriptions = new List <TopicSubscription> {
                    new TopicSubscription {
                        TopicId = topic.Id.Value, Enabled = true
                    }
                },
            });

            _publisher.Publish(topicName);
            _publisher.Publish(topicName);

            var ce1 = _consumer.ConsumeNext(subName).SingleOrDefault();

            Assert.NotNull(ce1);
            _consumer.MarkConsumed(ce1.Id, ce1.DeliveryKey);

            var ce2 = _consumer.ConsumeNext(subName).SingleOrDefault();

            Assert.NotNull(ce2);
            _consumer.MarkFailed(ce2.Id, ce2.DeliveryKey, Reason.Other("Whatever reason"));
        }
        public void ConsumeBatch_NotAllConsumed()
        {
            // Arrange
            var topicName = "ConsumeBatch_NotAllConsumed";
            var subName   = topicName + "_Sub1";
            var topic     = _publisher.AddOrUpdateTopic(new Topic {
                Name = topicName
            });
            var sub1 = _consumer.AddOrUpdateSubscription(new Subscription
            {
                Name = subName, // When ordered not set, delivery should still be ordered on publicationdateutc
                TopicSubscriptions = new List <TopicSubscription> {
                    new TopicSubscription {
                        TopicId = topic.Id.Value, Enabled = true
                    }
                },
            });

            _publisher.Publish(topicName, payload: "1");
            Thread.Sleep(100); // To make sure publicationdateutc is not equal for each item
            _publisher.Publish(topicName, payload: "2");
            Thread.Sleep(100);
            _publisher.Publish(topicName, payload: "3");

            // Consume a batch of 2 items
            var batchSize         = 2;
            var visibilityTimeout = 2; // 2 secs
            var ces = _consumer.ConsumeNext(subName, visibilityTimeout: visibilityTimeout, maxCount: batchSize);

            Assert.Equal(batchSize, ces.Count());
            Assert.True(ces.Any(ce => ce.Payload == "1"));
            Assert.True(ces.Any(ce => ce.Payload == "2"));

            // Mark only 2 consumed
            var ce1 = ces.Single(ce => ce.Payload == "1");

            _consumer.MarkFailed(ce1.Id, ce1.DeliveryKey, Reason.Other("Fail"));
            _consumer.MarkConsumed(ces.Where(ce => ce.Payload == "2").Cast <ConsumableEventId>());

            // Check if they are really marked consumed (can no longer be consumed)
            Thread.Sleep(TimeSpan.FromSeconds(visibilityTimeout + 1)); // Wait until visibilitytimeout of all items (+1) has expired
            ces = _consumer.ConsumeNext(subName, maxCount: batchSize); // Batchsize exceeds nr of events available
            Assert.Equal(1, ces.Count());
            Assert.True(ces.Any(ce => ce.Payload == "3"));
        }
Beispiel #3
0
        public void SerialDelivery()
        {
            // Arrange
            var topicName = "FunctionalOrderingTests.SerialDelivery";
            var subName   = topicName + "_Sub1"; // Substring to prevent too long sub-names
            var topic     = _publisher.AddOrUpdateTopic(new Topic {
                Name = topicName
            });
            var sub1 = _consumer.AddOrUpdateSubscription(new Subscription
            {
                Name               = subName,
                Ordered            = true,
                MaxDeliveries      = 2,
                TopicSubscriptions = new List <TopicSubscription> {
                    new TopicSubscription {
                        TopicId = topic.Id.Value, Enabled = true
                    }
                },
            });

            var publishedDateUtcBaseLine = DateTime.UtcNow.AddSeconds(-60); // Explicitly setting publicationdates to make sure none are the same!

            _publisher.Publish(topicName, payload: "1", functionalKey: "f1", publicationDateUtc: publishedDateUtcBaseLine.AddSeconds(1));
            _publisher.Publish(topicName, payload: "2", functionalKey: "f1", publicationDateUtc: publishedDateUtcBaseLine.AddSeconds(2));
            _publisher.Publish(topicName, payload: "3", functionalKey: "f2", publicationDateUtc: publishedDateUtcBaseLine.AddSeconds(3));
            _publisher.Publish(topicName, payload: "4", functionalKey: "f1", publicationDateUtc: publishedDateUtcBaseLine.AddSeconds(4));
            _publisher.Publish(topicName, payload: "5", functionalKey: "f2", publicationDateUtc: publishedDateUtcBaseLine.AddSeconds(5));

            var visibilityTimeout = 5;
            var p1 = _consumer.ConsumeNext(subName, visibilityTimeout: visibilityTimeout).SingleOrDefault(); // p1 stands for payload "1"
            var p3 = _consumer.ConsumeNext(subName, visibilityTimeout: visibilityTimeout).SingleOrDefault();
            var p2 = _consumer.ConsumeNext(subName, visibilityTimeout: visibilityTimeout).SingleOrDefault();

            Assert.Equal("1", p1.Payload);
            Assert.Equal("3", p3.Payload);
            Assert.Null(p2);                               // p(ayload) 2 has same functional key as p1 and should not be delivered yet

            _consumer.MarkConsumed(p1.Id, p1.DeliveryKey); // p1 should be gone, so p2 can be delivered
            p2 = _consumer.ConsumeNext(subName, visibilityTimeout: visibilityTimeout).SingleOrDefault();
            var p4 = _consumer.ConsumeNext(subName, visibilityTimeout: visibilityTimeout).SingleOrDefault();

            Assert.Equal("2", p2.Payload);
            Assert.Null(p4);                                           // Again: same functional key as p2, so should not be delivered (and p3 is still locked)
            Thread.Sleep(TimeSpan.FromSeconds(visibilityTimeout + 1)); // Wait until visibilitytimeout of all items has expired

            p2 = _consumer.ConsumeNext(subName, visibilityTimeout: visibilityTimeout).SingleOrDefault();
            p3 = _consumer.ConsumeNext(subName, visibilityTimeout: visibilityTimeout).SingleOrDefault();
            p4 = _consumer.ConsumeNext(subName, visibilityTimeout: visibilityTimeout).SingleOrDefault();
            Assert.Equal("2", p2.Payload); // p2 should be redelivered, since it had expired
            Assert.Equal("3", p3.Payload); // p3 should be redelivered, since it had expired
            Assert.Null(p4);               // p4 still has same functional key as p2, so should not be delivered

            _consumer.MarkFailed(p2.Id, p2.DeliveryKey, Reason.Other("test"));
            p4 = _consumer.ConsumeNext(subName, visibilityTimeout: visibilityTimeout).SingleOrDefault();
            Assert.Equal("4", p4.Payload);

            Thread.Sleep(TimeSpan.FromSeconds(visibilityTimeout + 1)); // Wait until visibilitytimeout of all items has expired
            p4 = _consumer.ConsumeNext(subName, visibilityTimeout: visibilityTimeout).SingleOrDefault();
            var p5 = _consumer.ConsumeNext(subName, visibilityTimeout: visibilityTimeout).SingleOrDefault();

            Assert.Equal("4", p4.Payload); // p4 should be redeliverd (it was only delivered once)
            Assert.Equal("5", p5.Payload); // p3 has reached maxDeliveries, so p5 should now be delivered
        }
        public void SubscriptionStatistics()
        {
            // Arrange
            var topicName = "SubStats";
            var subName   = topicName + "_Sub1";
            var topic     = _publisher.AddOrUpdateTopic(new Topic {
                Name = topicName
            });
            var sub1 = _consumer.AddOrUpdateSubscription(new Subscription
            {
                Name               = subName,
                Ordered            = true,
                MaxDeliveries      = 1,
                TopicSubscriptions = new List <TopicSubscription> {
                    new TopicSubscription {
                        TopicId = topic.Id.Value, Enabled = true
                    }
                },
            });

            var utcNow  = DateTime.UtcNow;
            var funcKey = "A";

            // Create situation: failed-other (marked)
            _publisher.Publish(topicName, eventName: topicName + "0", functionalKey: funcKey);
            var ce = _consumer.ConsumeNext(sub1.Name).SingleOrDefault();

            _consumer.MarkFailed(ce.Id, ce.DeliveryKey, Reason.Other("Some other reason"));
            // Create situation: expired
            _publisher.Publish(topicName, eventName: topicName + "1", functionalKey: funcKey, expirationDateUtc: utcNow);
            Thread.Sleep(TimeSpan.FromSeconds(1)); // Expired for sure
            // Create situation: maxDeliveriesReached
            _publisher.Publish(topicName, eventName: topicName + "2", functionalKey: funcKey);
            ce = _consumer.ConsumeNext(sub1.Name, visibilityTimeout: 1).SingleOrDefault();
            Assert.Equal(topicName + "2", ce.EventName);
            Thread.Sleep(TimeSpan.FromSeconds(1 + 1)); // Becomes visible again, but has reached maxDeliveries
            // Create situation: overtaken
            _publisher.Publish(topicName, eventName: topicName + "3", functionalKey: funcKey, publicationDateUtc: utcNow.AddSeconds(2));
            ce = _consumer.ConsumeNext(sub1.Name).SingleOrDefault();
            Assert.Equal(topicName + "3", ce.EventName);
            _publisher.Publish(topicName, eventName: topicName + "4", functionalKey: funcKey, publicationDateUtc: utcNow.AddSeconds(-1));
            _consumer.MarkConsumed(ce.Id, ce.DeliveryKey); // #4 is now overtaken
            _publisher.Publish(topicName, eventName: topicName + "5", functionalKey: funcKey);

            var statsBeforeHouseKeeping = _consumer.GetSubscriptionStatistics(utcNow.AddMinutes(-10), utcNow.AddMinutes(+10));

            Assert.Equal(statsBeforeHouseKeeping.Single(s => s.Subscription.Id.Value == sub1.Id).Open, 4); // 4 open, since housekeeping has not yet moved them (3) to failed
            Assert.Equal(statsBeforeHouseKeeping.Single(s => s.Subscription.Id.Value == sub1.Id).Consumed, 1);
            Assert.Equal(statsBeforeHouseKeeping.Single(s => s.Subscription.Id.Value == sub1.Id).FailedExpired, 0);
            Assert.Equal(statsBeforeHouseKeeping.Single(s => s.Subscription.Id.Value == sub1.Id).FailedMaxDeliveriesReached, 0);
            Assert.Equal(statsBeforeHouseKeeping.Single(s => s.Subscription.Id.Value == sub1.Id).FailedOvertaken, 0);
            Assert.Equal(statsBeforeHouseKeeping.Single(s => s.Subscription.Id.Value == sub1.Id).FailedOther, 1); // Does not need housekeeping to move it
            _consumer.PerformHouseKeepingTasks();
            var statsAfterHouseKeeping = _consumer.GetSubscriptionStatistics(utcNow.AddMinutes(-10), utcNow.AddMinutes(+10));

            Assert.Equal(statsAfterHouseKeeping.Single(s => s.Subscription.Id.Value == sub1.Id).Open, 1);
            Assert.Equal(statsAfterHouseKeeping.Single(s => s.Subscription.Id.Value == sub1.Id).Consumed, 1);
            Assert.Equal(statsAfterHouseKeeping.Single(s => s.Subscription.Id.Value == sub1.Id).FailedExpired, 1);
            Assert.Equal(statsAfterHouseKeeping.Single(s => s.Subscription.Id.Value == sub1.Id).FailedMaxDeliveriesReached, 1);
            Assert.Equal(statsAfterHouseKeeping.Single(s => s.Subscription.Id.Value == sub1.Id).FailedOvertaken, 1);
            Assert.Equal(statsAfterHouseKeeping.Single(s => s.Subscription.Id.Value == sub1.Id).FailedOther, 1);
        }