public async Task Should_ignore_message_version_on_subscriptions()
        {
            var storage = new InMemorySubscriptionStorage();

            await storage.Subscribe(new Subscriber("subscriberA@server1", "subscriberA"), new MessageType("SomeMessage", "1.0.0"), new ContextBag());

            var subscribers = await storage.GetSubscriberAddressesForMessage(new[]
            {
                new MessageType("SomeMessage", "2.0.0")
            }, new ContextBag());

            Assert.AreEqual("subscriberA", subscribers.Single().Endpoint);
        }
        public async Task Should_ignore_message_version_on_subscriptions()
        {
            var storage = new InMemorySubscriptionStorage();

            await storage.Subscribe(new Subscriber("subscriberA@server1", "subscriberA"), new MessageType("SomeMessage", "1.0.0"), new ContextBag());

            var subscribers = await storage.GetSubscriberAddressesForMessage(new[]
            {
                new MessageType("SomeMessage", "2.0.0")
            }, new ContextBag());

            Assert.AreEqual("subscriberA", subscribers.Single().Endpoint);
        }
        public async Task It_should_deliver_the_message_to_both_subscribers()
        {
            var alphaSubscriptionStore = new InMemorySubscriptionStorage();
            var bravoSubscriptionStore = new InMemorySubscriptionStorage();

            var result = await Scenario.Define <Context>()
                         .WithRouter("Router", cfg =>
            {
                cfg.AddInterface <TestTransport>("A", t => t.BrokerAlpha()).EnableMessageDrivenPublishSubscribe(alphaSubscriptionStore);
                cfg.AddInterface <TestTransport>("B", t => t.BrokerBravo()).EnableMessageDrivenPublishSubscribe(bravoSubscriptionStore);

                cfg.UseStaticRoutingProtocol();
            })
                         .WithEndpoint <Publisher>(c =>
            {
                c.CustomConfig(cfg =>
                {
                    cfg.UsePersistence <InMemoryPersistence, StorageType.Subscriptions>().UseStorage(alphaSubscriptionStore);
                }).When(x => x.EndpointsStarted, async(s, ctx) =>
                {
                    //Need to retry sending because there is no reliable way to figure when the router is subscribed
                    while (!ctx.BaseEventDelivered || !ctx.DerivedEventDelivered)
                    {
                        await s.Publish(new MyDerivedEvent2());
                        await Task.Delay(1000);
                    }
                });
            })
                         .WithEndpoint <BaseEventSubscriber>(c => c.CustomConfig(cfg =>
            {
                cfg.UsePersistence <InMemoryPersistence, StorageType.Subscriptions>().UseStorage(bravoSubscriptionStore);
            }))
                         .WithEndpoint <DerivedEventSubscriber>(c => c.CustomConfig(cfg =>
            {
                cfg.UsePersistence <InMemoryPersistence, StorageType.Subscriptions>().UseStorage(bravoSubscriptionStore);
            }))
                         .Done(c => c.BaseEventDelivered && c.DerivedEventDelivered)
                         .Run();

            Assert.IsTrue(result.BaseEventDelivered);
            Assert.IsTrue(result.DerivedEventDelivered);
        }
Пример #4
0
        public void SubscriptionWorks()
        {
            // arrange
            var subscriptionStorage = new InMemorySubscriptionStorage();

            // publisher
            CreateBus(PublisherInputQueueName, new HandlerActivatorForTesting(), subscriptionStorage, new InMemorySagaPersister(), "error").Start(1);

            // subscriber
            var subscriber = CreateBus(SubscriberInputQueueName, new HandlerActivatorForTesting()).Start(1);

            // act
            subscriber.Subscribe <TheMessage>();

            Thread.Sleep(500);

            // assert
            var subscribers = subscriptionStorage.GetSubscribers(typeof(TheMessage));

            subscribers.Length.ShouldBe(1);
            subscribers[0].ShouldStartWith(SubscriberInputQueueName + "@");
        }
Пример #5
0
 public static void UseStorage(this PersistenceExtensions <InMemoryPersistence> extensions, InMemorySubscriptionStorage storageInstance)
 {
     extensions.GetSettings().Set("InMemoryPersistence.StorageInstance", storageInstance);
 }
        public async Task Should_not_lose_events()
        {
            var subscriptionStorage = new InMemorySubscriptionStorage();

            var beforeMigration = await Scenario.Define <Context>(c => c.Step = "Before migration")
                                  .WithEndpoint <Publisher>(c => c.CustomConfig(config =>
            {
                config.UsePersistence <InMemoryPersistence, StorageType.Subscriptions>().UseStorage(subscriptionStorage);
            }).When(ctx => ctx.Subscribed, s => s.Publish(new MyEvent())))
                                  .WithEndpoint <Subscriber>(c => c.When(ctx => ctx.EndpointsStarted, s => s.Subscribe(typeof(MyEvent))))
                                  .Done(c => c.EventReceivedByNonMigratedSubscriber)
                                  .Run(TimeSpan.FromSeconds(30));

            Assert.IsTrue(beforeMigration.EventReceivedByNonMigratedSubscriber);

            //After the publisher is migrated we should not need to re-subscribe to be able to receive events
            //To prove that we don't call subscribe in this test run
            var publisherMigrated = await Scenario.Define <Context>(c => c.Step = "Publisher migrated")
                                    .WithEndpoint <MigratedPublisher>(c => c.CustomConfig(config =>
            {
                config.UsePersistence <InMemoryPersistence, StorageType.Subscriptions>().UseStorage(subscriptionStorage);
            }).When(ctx => ctx.EndpointsStarted, s =>
            {
                return(s.Publish(new MyEvent()));
            }))
                                    .WithEndpoint <Subscriber>()
                                    .Done(c => c.EventReceivedByNonMigratedSubscriber)
                                    .Run(TimeSpan.FromSeconds(30));

            Assert.IsTrue(publisherMigrated.EventReceivedByNonMigratedSubscriber);

            //After restarting the subscriber it sends the subscribe message to a migrated publisher
            //To prove that a subscribe message can reach to publisher via the router we use a brand new subscription store

            subscriptionStorage = new InMemorySubscriptionStorage();
            var subscriberResubscribed = await Scenario.Define <Context>(c => c.Step = "Resubscribed after publisher migrated")
                                         .WithEndpoint <MigratedPublisher>(c => c.CustomConfig(config =>
            {
                config.UsePersistence <InMemoryPersistence, StorageType.Subscriptions>().UseStorage(subscriptionStorage);
            }).When(ctx => ctx.Subscribed, s => s.Publish(new MyEvent())))
                                         .WithEndpoint <Subscriber>(c => c.When(ctx => ctx.EndpointsStarted, s => s.Subscribe(typeof(MyEvent))))
                                         .Done(c => c.EventReceivedByNonMigratedSubscriber)
                                         .Run(TimeSpan.FromSeconds(30));

            Assert.IsTrue(subscriberResubscribed.EventReceivedByNonMigratedSubscriber);

            //Migrate subscriber
            var subscriberMigrated = await Scenario.Define <Context>(c => c.Step = "Subscriber migrated")
                                     .WithEndpoint <MigratedPublisher>(c => c.CustomConfig(config =>
            {
                config.UsePersistence <InMemoryPersistence, StorageType.Subscriptions>().UseStorage(subscriptionStorage);
            }).When(ctx => ctx.EndpointsStarted, s => s.Publish(new MyEvent())))
                                     .WithEndpoint <MigratedSubscriber>()
                                     .Done(c => c.EventsReceivedByMigratedSubscriber >= 1)
                                     .Run(TimeSpan.FromSeconds(30));

            Assert.AreEqual(1, subscriberMigrated.EventsReceivedByMigratedSubscriber);

            var resubscribedNativeAfterMigration = await Scenario.Define <Context>(c => c.Step = "Resubscribed native after subscriber migrated")
                                                   .WithEndpoint <MigratedPublisher>(c => c.CustomConfig(config =>
            {
                config.UsePersistence <InMemoryPersistence, StorageType.Subscriptions>().UseStorage(subscriptionStorage);
                config.Pipeline.Register(new UnsubscribeWhenMigratedSuppressingBehavior(), "Disables the unsubscribe behavior");
            }).When(ctx => ctx.Subscribed, s => s.Publish(new MyEvent())))
                                                   .WithEndpoint <MigratedSubscriber>(c => c.When(ctx => ctx.EndpointsStarted, async(s, ctx) =>
            {
                await s.Subscribe(typeof(MyEvent));
                ctx.Subscribed = true;
            }))
                                                   .Done(c => c.EventsReceivedByMigratedSubscriber >= 1 && c.EventsReceivedAtTransportLevel >= 2)
                                                   .Run(TimeSpan.FromSeconds(30));

            Assert.AreEqual(2, resubscribedNativeAfterMigration.EventsReceivedAtTransportLevel);
            Assert.AreEqual(1, resubscribedNativeAfterMigration.EventsReceivedByMigratedSubscriber);

            //Re-subscribe after migration. This will send a subscribe message that will trigger removal of old subscription -- Unsubscribed will be set
            var resubscribedAfterMigration = await Scenario.Define <Context>(c => c.Step = "Resubscribed after subscriber migrated")
                                             .WithEndpoint <MigratedPublisher>(c => c.CustomConfig(config =>
            {
                config.UsePersistence <InMemoryPersistence, StorageType.Subscriptions>().UseStorage(subscriptionStorage);
            }).When(ctx => ctx.Unsubscribed, s => s.Publish(new MyEvent())))
                                             .WithEndpoint <MigratedSubscriber>(c => c.When(ctx => ctx.EndpointsStarted, (s, ctx) => s.Subscribe(typeof(MyEvent))))
                                             .Done(c => c.EventsReceivedByMigratedSubscriber >= 1)
                                             .Run(TimeSpan.FromSeconds(30));

            Assert.AreEqual(1, resubscribedAfterMigration.EventsReceivedByMigratedSubscriber);

            //Compatibility mode disabled after all endpoints are migrated
            var compatModeDisabled = await Scenario.Define <Context>(c => c.Step = "Compatibility mode disabled")
                                     .WithEndpoint <MigratedPublisherNoCompatMode>(c => c.When(ctx => ctx.EndpointsStarted, s => s.Publish(new MyEvent())))
                                     .WithEndpoint <MigratedSubscriberNoCompatMode>()
                                     .Done(c => c.EventsReceivedByMigratedSubscriber >= 1)
                                     .Run(TimeSpan.FromSeconds(30));

            Assert.IsTrue(compatModeDisabled.EventsReceivedByMigratedSubscriber >= 1);
        }
        public async Task Should_not_lose_events()
        {
            var subscriptionStorage = new InMemorySubscriptionStorage();

            var beforeMigration = await Scenario.Define <Context>(c => c.Step = "Before migration")
                                  .WithEndpoint <Publisher>(c => c.CustomConfig(config =>
            {
                config.UsePersistence <InMemoryPersistence, StorageType.Subscriptions>().UseStorage(subscriptionStorage);
            }).When(ctx => ctx.Subscribed, s => s.Publish(new MyEvent())))
                                  .WithEndpoint <Subscriber>(c => c.When(ctx => ctx.EndpointsStarted, s => s.Subscribe(typeof(MyEvent))))
                                  .Done(c => c.EventReceivedByNonMigratedSubscriber)
                                  .Run(TimeSpan.FromSeconds(30));

            Assert.IsTrue(beforeMigration.EventReceivedByNonMigratedSubscriber);

            //Migrate subscriber
            //After the subscriber is migrated we should not need to re-subscribe to be able to receive events
            //To prove that we don't call subscribe in this test run
            var subscriberMigrated = await Scenario.Define <Context>(c => c.Step = "Subscriber migrated")
                                     .WithEndpoint <Publisher>(c => c.CustomConfig(config =>
            {
                config.UsePersistence <InMemoryPersistence, StorageType.Subscriptions>().UseStorage(subscriptionStorage);
            }).When(ctx => ctx.EndpointsStarted, s => s.Publish(new MyEvent())))
                                     .WithEndpoint <MigratedSubscriber>()
                                     .Done(c => c.EventsReceivedByMigratedSubscriber >= 1)
                                     .Run(TimeSpan.FromSeconds(30));

            Assert.IsTrue(subscriberMigrated.EventsReceivedByMigratedSubscriber >= 1);

            //After restarting the subscriber it sends the subscribe message to the publisher
            //To prove that a subscribe message can reach to publisher via the router we use a brand new subscription store
            subscriptionStorage = new InMemorySubscriptionStorage();
            var subscriberResubscribed = await Scenario.Define <Context>(c => c.Step = "Resubscribed after migration")
                                         .WithEndpoint <Publisher>(c => c.CustomConfig(config =>
            {
                config.UsePersistence <InMemoryPersistence, StorageType.Subscriptions>().UseStorage(subscriptionStorage);
            }).When(ctx => ctx.Subscribed, s => s.Publish(new MyEvent())))
                                         .WithEndpoint <MigratedSubscriber>(c => c.When(ctx => ctx.EndpointsStarted, s => s.Subscribe(typeof(MyEvent))))
                                         .Done(c => c.EventsReceivedByMigratedSubscriber >= 1)
                                         .Run(TimeSpan.FromSeconds(30));

            Assert.IsTrue(subscriberResubscribed.EventsReceivedByMigratedSubscriber >= 1);

            //After migrating but prior to resubscribing we should detect that the published messages gets through two routers and drop it
            var publisherMigrated = await Scenario.Define <Context>(c => c.Step = "Publisher migrated")
                                    .WithEndpoint <MigratedPublisher>(c => c.CustomConfig(config =>
            {
                config.UsePersistence <InMemoryPersistence, StorageType.Subscriptions>().UseStorage(subscriptionStorage);
            }).When(ctx => ctx.EndpointsStarted, s => s.Publish(new MyEvent())))
                                    .WithEndpoint <MigratedSubscriber>()
                                    .Done(c => c.EventsReceivedByMigratedSubscriber >= 1 && c.EventsReceivedAtTransportLevel >= 2)
                                    .Run(TimeSpan.FromSeconds(30));

            Assert.IsTrue(publisherMigrated.EventsReceivedByMigratedSubscriber >= 1);
            Assert.IsTrue(publisherMigrated.EventsReceivedAtTransportLevel >= 1);

            //After resubscribing we should detect that the subscribe messages gets through two routers and drop the old subscription
            var resubscribedAfterPublisherMigrated = await Scenario.Define <Context>(c => c.Step = "Resubscribed after publisher migrated")
                                                     .WithEndpoint <MigratedPublisher>(c => c.CustomConfig(config =>
            {
                config.UsePersistence <InMemoryPersistence, StorageType.Subscriptions>().UseStorage(subscriptionStorage);
            }).When(ctx => ctx.Unsubscribed, s => s.Publish(new MyEvent())))
                                                     .WithEndpoint <MigratedSubscriber>(c => c.When(ctx => ctx.EndpointsStarted, s => s.Subscribe(typeof(MyEvent))))
                                                     .Done(c => c.EventsReceivedByMigratedSubscriber >= 1 && c.Unsubscribed)
                                                     .Run(TimeSpan.FromSeconds(30));

            Assert.IsTrue(resubscribedAfterPublisherMigrated.EventsReceivedByMigratedSubscriber >= 1);

            //Compatibility mode disabled after all endpoints are migrated
            var compatModeDisabled = await Scenario.Define <Context>(c => c.Step = "Compatibility mode disabled")
                                     .WithEndpoint <MigratedPublisherNoCompatMode>(c => c.When(ctx => ctx.EndpointsStarted, s => s.Publish(new MyEvent())))
                                     .WithEndpoint <MigratedSubscriberNoCompatMode>()
                                     .Done(c => c.EventsReceivedByMigratedSubscriber >= 1)
                                     .Run(TimeSpan.FromSeconds(30));

            Assert.IsTrue(compatModeDisabled.EventsReceivedByMigratedSubscriber >= 1);
        }