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); }
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 + "@"); }
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); }