Example #1
0
        public async Task Scheduled_commands_are_reserialized_and_invoked_by_a_command_scheduler()
        {
            // arrange
            var bus        = new FakeEventBus();
            var shipmentId = Any.AlphanumericString(10);
            var repository = new InMemoryEventSourcedRepository <Order>(bus: bus);

            var scheduler = new InMemoryCommandScheduler <Order>(repository);

            bus.Subscribe(scheduler);
            var order = CreateOrder();

            order.Apply(new ShipOn(shipDate: Clock.Now().AddMonths(1).Date)
            {
                ShipmentId = shipmentId
            });
            await repository.Save(order);

            // act
            VirtualClock.Current.AdvanceBy(TimeSpan.FromDays(32));

            //assert
            order = await repository.GetLatest(order.Id);

            var lastEvent = order.Events().Last();

            lastEvent.Should().BeOfType <Order.Shipped>();
            order.ShipmentId.Should().Be(shipmentId, "Properties should be transferred correctly from the serialized command");
        }
Example #2
0
        public async Task EventBus_Should_Invoke_Event_Handlers_Implicit_Topic()
        {
            // Create handlers
            var state = new FakeState {
                Data = "A"
            };
            var fakeHandler1 = new FakeEventHandler1(state);
            var fakeHandler2 = new FakeEventHandler2(state);

            // Create message broker
            var messageBroker = new FakeMessageBroker();

            messageBroker.Subscribe(fakeHandler1);
            messageBroker.Subscribe(fakeHandler2);

            // Create service bus
            var eventBus = new FakeEventBus(messageBroker);

            eventBus.Subscribe(fakeHandler1);
            eventBus.Subscribe(fakeHandler2);

            // Publish to service bus
            var @event = new FakeIntegrationEvent("B");
            await eventBus.PublishAsync(@event);

            // Assert
            Assert.Equal(@event.CreationDate, state.Date);
            Assert.Equal("B", state.Data);
        }
Example #3
0
        public override void When_storage_fails_then_no_events_are_published()
        {
            var order = new Order();
            var bus   = new FakeEventBus();

            bus.Events <IEvent>().Subscribe(e => { throw new Exception("oops"); });
            var repository = CreateRepository <Order>(() => { throw new Exception("oops!"); });

            order
            .Apply(new AddItem
            {
                ProductName = "Widget",
                Price       = 10m,
                Quantity    = 2
            });

            try
            {
                repository.Save(order);
            }
            catch
            {
            }

            using (var db = new EventStoreDbContext())
            {
                var events = db.Events.Where(e => e.AggregateId == order.Id).ToArray();
                events.Count().Should().Be(0);
            }
        }
        public void SetUp()
        {
            eventStoreDbTest = new EventStoreDbTest();
            clockName = Any.CamelCaseName();

            Clock.Reset();

            disposables = new CompositeDisposable
            {
                Disposable.Create(() => eventStoreDbTest.TearDown()),
                Disposable.Create(Clock.Reset)
            };

            var bus = new FakeEventBus();
            orderRepository = new SqlEventSourcedRepository<Order>(bus);
            accountRepository = new SqlEventSourcedRepository<CustomerAccount>(bus);

            var configuration = new Configuration();
            configuration.UseEventBus(bus)
                         .UseDependency<IEventSourcedRepository<Order>>(t => orderRepository)
                         .UseDependency<IEventSourcedRepository<CustomerAccount>>(t => accountRepository);

            ConfigureScheduler(configuration);

            disposables.Add(ConfigurationContext.Establish(configuration));

            Console.WriteLine(new { clockName });

            clockTrigger = configuration.Container.Resolve<ISchedulerClockTrigger>();
            clockRepository = configuration.Container.Resolve<ISchedulerClockRepository>();
            clockRepository.CreateClock(clockName, Clock.Now());
        }
Example #5
0
        public async Task EventBus_Should_Invoke_Event_Handlers(TopicType topicType, string prefix)
        {
            // Topic name
            var topicName = topicType == TopicType.Explicit ? "my-topic" : null;

            // Create handlers
            var state = new FakeState {
                Data = "A"
            };
            var fakeHandler1 = new FakeEventHandler1(state);
            var fakeHandler2 = new FakeEventHandler2(state);

            // Create message broker
            var messageBroker = new FakeMessageBroker();

            messageBroker.Subscribe(fakeHandler1, topicName, prefix);
            messageBroker.Subscribe(fakeHandler2, topicName, prefix);

            // Create service bus
            var eventBus = new FakeEventBus(messageBroker);

            eventBus.Subscribe(fakeHandler1, topicName, prefix);
            eventBus.Subscribe(fakeHandler2, topicName, prefix);

            // Publish to service bus
            var @event = new FakeIntegrationEvent("B");
            await eventBus.PublishAsync(@event, topicName, prefix);

            // Assert
            Assert.Equal(@event.CreationDate, state.Date);
            Assert.Equal("B", state.Data);
        }
        public void When_the_aggregate_is_saved_then_the_reservation_is_confirmed()
        {
            // arrange
            var username = Any.Email();

            var account = new CustomerAccount();

            account.Apply(new RequestUserName
            {
                UserName  = username,
                Principal = new Customer(username)
            });
            var bus = new FakeEventBus();

            bus.Subscribe(new UserNameConfirmer());
            var repository = new SqlEventSourcedRepository <CustomerAccount>(bus);

            // act
            repository.Save(account);

            // assert
            using (var db = new ReservationServiceDbContext())
            {
                db.Set <ReservedValue>()
                .Single(v => v.Value == username && v.Scope == "UserName")
                .Expiration
                .Should()
                .BeNull();
            }
        }
        public async Task Scheduled_commands_are_reserialized_and_invoked_by_a_command_scheduler()
        {
            // arrange
            var bus = new FakeEventBus();
            var shipmentId = Any.AlphanumericString(10);
            var repository = new InMemoryEventSourcedRepository<Order>(bus: bus);

            var scheduler = new InMemoryCommandScheduler<Order>(repository);
            bus.Subscribe(scheduler);
            var order = CreateOrder();

            order.Apply(new ShipOn(shipDate: Clock.Now().AddMonths(1).Date)
            {
                ShipmentId = shipmentId
            });
            await repository.Save(order);

            // act
            VirtualClock.Current.AdvanceBy(TimeSpan.FromDays(32));

            //assert 
            order = await repository.GetLatest(order.Id);
            var lastEvent = order.Events().Last();
            lastEvent.Should().BeOfType<Order.Shipped>();
            order.ShipmentId.Should().Be(shipmentId, "Properties should be transferred correctly from the serialized command");
        }
Example #8
0
        public void When_Subscribe_is_called_each_handler_interface_is_subscribed_once()
        {
            var bus = new FakeEventBus();

            bus.Subscribe(new Handler_of_5_more_event_types());

            bus.SubscribedEventTypes().Count().Should().Be(9);
        }
Example #9
0
        public void When_Subscribe_is_called_then_redundant_implementations_are_not_subscribed_more_than_once()
        {
            var bus = new FakeEventBus();

            bus.Subscribe(new Handler_of_redundant_event_types());

            bus.SubscribedEventTypes().Count().Should().Be(9);
        }
Example #10
0
        public void IProjectFrom_and_ITriggerProcessOn_interfaces_for_different_event_types_are_subscribed_on_the_same_handler_instance()
        {
            var bus = new FakeEventBus();

            bus.Subscribe(new Projector_and_Trigger_from_different_event_types());

            bus.SubscribedEventTypes().Count().Should().Be(2);
        }
Example #11
0
        public void When_Subscribe_is_called_with_a_handler_having_no_event_handler_implementations_then_it_throws()
        {
            var bus = new FakeEventBus();

            bus.Invoking(b => b.Subscribe(new object()))
            .ShouldThrow <ArgumentException>()
            .And
            .Message.Should().Contain("does not implement any event handler interfaces");
        }
Example #12
0
        public void IProjectFrom_and_ITriggerProcessOn_interfaces_for_same_event_type_are_subscribed_on_the_same_handler_instance()
        {
            var bus = new FakeEventBus();

            bus.Subscribe(new Projector_and_Trigger_from_same_event_type());
            bus.PublishAsync(new Order.Placed()).Wait();

            bus.SubscribedEventTypes().Count().Should().Be(2);
            recordedEvents.Count().Should().Be(2);
        }
        public void When_a_subscriber_subscribes_to_IEvent_then_they_receive_all_events()
        {
            var bus    = new FakeEventBus();
            var events = new List <object>();

            bus.Events <IEvent>().Subscribe(events.Add);
            bus.PublishAsync(new Order.Cancelled()).Wait();

            events.Last().Should().BeOfType <Order.Cancelled>();
        }
        public void When_a_subscriber_subscribes_to_events_for_one_aggregate_then_they_do_not_receive_events_for_other_aggregates()
        {
            var bus    = new FakeEventBus();
            var events = new List <object>();

            bus.Events <Event <Order> >().Subscribe(events.Add);
            bus.PublishAsync(new Order.Cancelled(), new TestAggregate.SomeEvent()).Wait();

            events.Last().Should().BeOfType <Order.Cancelled>();
        }
Example #15
0
        public void GivenNoPreviousState_WhenPublishingSingleEvent_ThenEventsShouldBeStored()
        {
            // Arrange
            var eventBus = new FakeEventBus();

            // Act
            eventBus.Publish(new SomethingHappened(1));

            // Assert
            CollectionAssert.AreEqual(new object[] { new SomethingHappened(1) }, eventBus.Events);
        }
Example #16
0
        public void GivenNoPreviousState_WhenPublishingEvents_ThenEventsShouldBeStored()
        {
            // Arrange
            var eventBus = new FakeEventBus();

            // Act
            eventBus.Publish((IEnumerable <IEvent>)(new IEvent[] { new SomethingHappened(1), new SomethingElseHappened(2) }));

            // Assert
            CollectionAssert.AreEqual(new object[] { new SomethingHappened(1), new SomethingElseHappened(2) }, eventBus.Events.ToArray());
        }
        public void All_commands_can_be_configured_for_SQL_scheduling_using_ScheduleCommandsUsingSqlScheduler()
        {
            var eventBus = new FakeEventBus();

            eventBus.Subscribe(new SqlCommandScheduler(new Configuration().UseSqlEventStore()));

            eventBus.SubscribedEventTypes()
            .Should()
            .Contain(new[]
            {
                typeof(IScheduledCommand <Order>),
                typeof(IScheduledCommand <CustomerAccount>)
            });
        }
        public void All_commands_can_be_configured_for_SQL_scheduling_using_ScheduleCommandsUsingSqlScheduler()
        {
            var eventBus = new FakeEventBus();

            eventBus.Subscribe(new SqlCommandScheduler(new Configuration().UseSqlEventStore()));

            eventBus.SubscribedEventTypes()
                    .Should()
                    .Contain(new[]
                    {
                        typeof (CommandScheduled<Order>),
                        typeof (CommandScheduled<CustomerAccount>)
                    });
        }
        public async Task ReadModelCatchup_only_queries_events_since_the_last_consumed_event_id()
        {
            var bus        = new FakeEventBus();
            var repository = new SqlEventSourcedRepository <Order>(bus);

            // save the order with no projectors running
            var order = new Order();

            order.Apply(new AddItem
            {
                Price       = 1m,
                ProductName = "Widget"
            });
            await repository.Save(order);

            // subscribe one projector for catchup
            var projector1 = new Projector1();

            using (var catchup = CreateReadModelCatchup(projector1))
            {
                catchup.Progress.ForEachAsync(s => Console.WriteLine(s));
                await catchup.Run();
            }

            order.Apply(new AddItem
            {
                Price       = 1m,
                ProductName = "Widget"
            });
            await repository.Save(order);

            // subscribe both projectors
            var projector2 = new Projector2();

            using (var catchup = CreateReadModelCatchup(projector1, projector2))
            {
                catchup.Progress.ForEachAsync(s => Console.WriteLine(s));
                await catchup.Run();
            }

            projector1.CallCount.Should().Be(2, "A given event should only be passed to a given projector once");
            projector2.CallCount.Should().Be(2, "A projector should be passed events it has not previously seen.");
        }
Example #20
0
        public override void SetUp()
        {
            base.SetUp();

            using (VirtualClock.Start(DateTimeOffset.Now.AddMonths(1)))
            {
                disposables      = new CompositeDisposable();
                Settings.Sources = new ISettingsSource[] { new ConfigDirectorySettings(@"c:\dev\.config") }.Concat(Settings.Sources);

                serviceBusSettings                = Settings.Get <ServiceBusSettings>();
                serviceBusSettings.NamePrefix     = "itscqrstests";
                serviceBusSettings.ConfigureQueue = q =>
                {
                    q.AutoDeleteOnIdle = TimeSpan.FromMinutes(15);
                };

                bus             = new FakeEventBus();
                orderRepository = new SqlEventSourcedRepository <Order>(bus);

                var configuration = new Configuration()
                                    .UseSqlEventStore(() => new EventStoreDbContext())
                                    .UseEventBus(bus)
                                    .UseSqlCommandScheduling()
                                    .UseDependency <IEventSourcedRepository <Order> >(t => orderRepository);

                var clockName = Any.Paragraph(4);
                scheduler = new SqlCommandScheduler(configuration)
                {
                    GetClockName = @event => clockName
                };

                queueSender = new ServiceBusCommandQueueSender(serviceBusSettings)
                {
                    MessageDeliveryOffsetFromCommandDueTime = TimeSpan.FromSeconds(30)
                };

                disposables.Add(scheduler.Activity.Subscribe(s => Console.WriteLine("SqlCommandScheduler: " + s.ToJson())));
                disposables.Add(queueSender.Messages.Subscribe(s => Console.WriteLine("ServiceBusCommandQueueSender: " + s.ToJson())));
                disposables.Add(bus.Subscribe(scheduler));
                disposables.Add(configuration);
                disposables.Add(ConfigurationContext.Establish(configuration));
            }
        }
        public override void SetUp()
        {
            base.SetUp();

            using (VirtualClock.Start(DateTimeOffset.Now.AddMonths(1)))
            {
                disposables = new CompositeDisposable();
                Settings.Sources = new ISettingsSource[] { new ConfigDirectorySettings(@"c:\dev\.config") }.Concat(Settings.Sources);

                serviceBusSettings = Settings.Get<ServiceBusSettings>();
                serviceBusSettings.NamePrefix = "itscqrstests";
                serviceBusSettings.ConfigureQueue = q =>
                {
                    q.AutoDeleteOnIdle = TimeSpan.FromMinutes(15);
                };

                bus = new FakeEventBus();
                orderRepository = new SqlEventSourcedRepository<Order>(bus);

                var configuration = new Configuration()
                    .UseSqlEventStore(() => new EventStoreDbContext())
                    .UseEventBus(bus)
                    .UseSqlCommandScheduling()
                    .UseDependency<IEventSourcedRepository<Order>>(t => orderRepository);

                var clockName = Any.Paragraph(4);
                scheduler = new SqlCommandScheduler(configuration) { GetClockName = @event => clockName };

                queueSender = new ServiceBusCommandQueueSender(serviceBusSettings)
                {
                    MessageDeliveryOffsetFromCommandDueTime = TimeSpan.FromSeconds(30)
                };

                disposables.Add(scheduler.Activity.Subscribe(s => Console.WriteLine("SqlCommandScheduler: " + s.ToJson())));
                disposables.Add(queueSender.Messages.Subscribe(s => Console.WriteLine("ServiceBusCommandQueueSender: " + s.ToJson())));
                disposables.Add(bus.Subscribe(scheduler));
                disposables.Add(configuration);
                disposables.Add(ConfigurationContext.Establish(configuration));
            }
        }
Example #22
0
        public void EventBus_Should_Remove_Event_Handlers(TopicType topicType, string prefix)
        {
            // Topic name
            var topicName = topicType == TopicType.Explicit ? "my-topic" : null;

            // Create handlers
            var state = new FakeState {
                Data = "A"
            };
            var fakeHandler1 = new FakeEventHandler1(state);
            var fakeHandler2 = new FakeEventHandler2(state);

            // Create message broker
            var messageBroker = new FakeMessageBroker();

            messageBroker.Subscribe(fakeHandler1, topicName, prefix);
            messageBroker.Subscribe(fakeHandler2, topicName, prefix);

            // Create service bus
            var eventBus = new FakeEventBus(messageBroker);

            eventBus.Subscribe(fakeHandler1, topicName, prefix);
            eventBus.Subscribe(fakeHandler2, topicName, prefix);

            // Remove handler
            eventBus.UnSubscribe(fakeHandler1, topicName, prefix);

            // Assert
            Assert.Single(eventBus.Topics);
            Assert.Single(eventBus.Topics.First().Value);

            // Remove handler
            eventBus.UnSubscribe(fakeHandler2, topicName, prefix);

            // Assert
            Assert.Empty(eventBus.Topics);
        }
 public void Setup()
 {
     bus            = new FakeEventBus();
     aquirePrice    = 100;
     processManager = new TrailingStopLossProcessManager(bus, aquirePrice);
 }
Example #24
0
 public void SetUp()
 {
     bus            = new FakeEventBus();
     recordedEvents = new List <RecordedEvent>();
 }