Beispiel #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");
        }
Beispiel #2
0
        public async Task Advancing_the_clock_blocks_until_triggered_commands_on_the_InMemoryCommandScheduler_are_completed()
        {
            VirtualClock.Start();

            var repository = new InMemoryEventSourcedRepository <Order>();

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

            var aggregateId = Any.Guid();
            await scheduler.Schedule(new CommandScheduled <Order>
            {
                Command = new CreateOrder(Any.FullName())
                {
                    AggregateId = aggregateId
                },
                DueTime     = Clock.Now().AddHours(1),
                AggregateId = aggregateId
            });

            VirtualClock.Current.AdvanceBy(TimeSpan.FromDays(1));

            var order = await repository.GetLatest(aggregateId);

            order.Should().NotBeNull();
        }
        private void Set(Func <IConfigureUpconverter, IBuildConfiguration> upconverterSetup)
        {
            if (isAlreadySetup)
            {
                return;
            }
            streamInfoContainer.ResetToNew();

            var upconverterConfig = Configuration.Begin()
                                    .WithDefaultCollection()
                                    .WithDefaultStateFactory()
                                    .WithInterceptor(interceptorContext)
                                    .NeverUseThreadSafe()
                                    .WithNoEventPublisher()
                                    .WithAnyAppliersFrom(Assembly.GetExecutingAssembly())
                                    .AndNoMoreAppliers();

            var configuration = upconverterSetup(upconverterConfig)
                                .Build();

            var tempInMemRepo    = new InMemoryEventSourcedRepository <int, IHoldHigherOrder>(configuration);
            var defaultValidator = tempInMemRepo.StateValidator;

            passThroughValidator.CurrentValidator = defaultValidator;

            sessionContainer.Setup(passThroughValidator, configuration);
            isAlreadySetup = true;
        }
        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");
        }
        public void Submit_CallsHandlerSavesAndPublishesEvents()
        {
            var repo      = new InMemoryEventSourcedRepository();
            var handler   = new FakeCommandHandler(repo);
            var publisher = new Mock <IEventPublisher>();

            var dispatcher = new CommandDispatcher(new[] { handler }, repo, publisher.Object);

            var id = Guid.NewGuid();

            var updatedText = Guid.NewGuid().ToString();

            dispatcher.Submit(new CreateFakeAggregate {
                Id = id
            });
            dispatcher.Submit(new UpdateFakeAggregate {
                Id = id, Text = updatedText
            });

            var aggreate = repo.GetById <FakeAggregate>(id);

            Assert.AreEqual(updatedText, aggreate.Text);

            publisher.Verify(f => f.PublishEvent(It.Is <IEvent>(e => e.GetType() == typeof(FakeAggregateCreated))), Times.Once);
            publisher.Verify(f => f.PublishEvent(It.Is <IEvent>(e => e.GetType() == typeof(FakeAggregateUpdated))), Times.Once);
        }
Beispiel #6
0
        public void Setup(IHoldAllConfiguration configuration)
        {
            if (repository != null)
            {
                throw new Exception($"{nameof(repository)} already setup");
            }

            repository = new InMemoryEventSourcedRepository <string, IHoldHigherOrder>(configuration);
        }
        public static InMemoryEventSourcedRepository <TId, TState> WithEventInStream <TState, TId>(
            this InMemoryEventSourcedRepository <TId, TState> sut,
            object @event,
            TId streamId)
        {
            var currentEvents = sut[streamId]?.ToList() ?? new List <ItemWithType>();

            currentEvents.Add(new ItemWithType(@event));
            sut[streamId] = currentEvents.ToArray();
            return(sut);
        }
Beispiel #8
0
        public async Task When_one_command_triggers_another_command_via_a_consequenter_then_the_second_command_acquires_the_first_commands_clock()
        {
            // arrange
            var orderId         = Any.Guid();
            var customerId      = Any.Guid();
            var bus             = new InProcessEventBus();
            var orderRepository = new InMemoryEventSourcedRepository <Order>(bus: bus);
            await orderRepository.Save(new Order(new CreateOrder(Any.FullName())
            {
                AggregateId = orderId,
                CustomerId = customerId
            }).Apply(new AddItem
            {
                ProductName = Any.Word(),
                Quantity    = 1,
                Price       = Any.Decimal(.01m, 10m)
            }));

            var customerRepository = new InMemoryEventSourcedRepository <CustomerAccount>();
            await customerRepository.Save(new CustomerAccount(customerId).Apply(new ChangeEmailAddress(Any.Email())));

#pragma warning disable 618
            bus.Subscribe(Consequenter.Create <Order.Shipped>(e =>
#pragma warning restore 618
            {
                var order    = orderRepository.GetLatest(e.AggregateId).Result;
                var customer = customerRepository.GetLatest(order.CustomerId).Result;
                customer.Apply(new SendOrderConfirmationEmail(order.OrderNumber));
                customerRepository.Save(customer).Wait();
            }));
            var shipDate = DateTimeOffset.Parse("2014-05-15 01:01:01");
            var ship     = new Ship();

            // act
            using (CommandContext.Establish(ship, Clock.Create(() => shipDate)))
            {
                var order = await orderRepository.GetLatest(orderId);

                order.Apply(ship);
                await orderRepository.Save(order);
            }

            // assert
            var last = (await customerRepository.GetLatest(customerId)).Events().Last();
            last.Should()
            .BeOfType <CustomerAccount.OrderShipConfirmationEmailSent>();
            last.Timestamp.Should().Be(shipDate);
        }
Beispiel #9
0
        public void InMemoryCommandScheduler_executes_scheduled_commands_immediately_if_no_due_time_is_specified()
        {
            // arrange
            var bus        = new InProcessEventBus();
            var repository = new InMemoryEventSourcedRepository <Order>(bus: bus);
            var scheduler  = new InMemoryCommandScheduler <Order>(repository);

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

            // act
            order.Apply(new ShipOn(Clock.Now().Subtract(TimeSpan.FromDays(2))));
            repository.Save(order);

            //assert
            order = repository.GetLatest(order.Id);
            var lastEvent = order.Events().Last();

            lastEvent.Should().BeOfType <Order.Shipped>();
        }
Beispiel #10
0
        public AggregateFixture(string name, object[] appliers = null)
        {
            var configuration = Configuration.Begin()
                                .WithDefaultCollection()
                                .WithDefaultStateFactory()
                                .AlwaysUseThreadSafe()
                                .WithNoEventPublisher()
                                .WithAnyAppliersFromInstances((IEnumerable <object>)appliers ?? new List <object>())
                                .WithAnyAppliersFrom(Assembly.GetAssembly(typeof(CinemaAggregateState)))
                                .AndNoMoreAppliers()
                                .WithNoUpconverters()
                                .Build();

            this.name             = name;
            correlationId         = Guid.NewGuid();
            CinemaFunctionalRepo  = new InMemoryEventSourcedRepository <CinemaAggregateRootId, CinemaAggregateState>(configuration);
            ViewingFunctionalRepo = new InMemoryEventSourcedRepository <ViewingId, IViewingState>(configuration);

            cinemaId      = new CinemaAggregateRootId(name);
            dateOfViewing = DateTime.Now.AddDays(3);
        }
        public void Submit_CallsHandlerSavesAndPublishesEvents()
        {
            var repo = new InMemoryEventSourcedRepository();
            var handler = new FakeCommandHandler(repo);
            var publisher = new Mock<IEventPublisher>();

            var dispatcher = new CommandDispatcher(new[] { handler }, repo, publisher.Object);

            var id = Guid.NewGuid();

            var updatedText = Guid.NewGuid().ToString();

            dispatcher.Submit(new CreateFakeAggregate { Id = id });
            dispatcher.Submit(new UpdateFakeAggregate { Id = id, Text = updatedText });

            var aggreate = repo.GetById<FakeAggregate>(id);

            Assert.AreEqual(updatedText, aggreate.Text);

            publisher.Verify(f => f.PublishEvent(It.Is<IEvent>(e => e.GetType() == typeof(FakeAggregateCreated))), Times.Once);
            publisher.Verify(f => f.PublishEvent(It.Is<IEvent>(e => e.GetType() == typeof(FakeAggregateUpdated))), Times.Once);
        }
        public async Task When_one_command_triggers_another_command_via_a_consequenter_then_the_second_command_acquires_the_first_commands_clock()
        {
            // arrange
            var orderId = Any.Guid();
            var customerId = Any.Guid();
            var bus = new InProcessEventBus();
            var orderRepository = new InMemoryEventSourcedRepository<Order>(bus: bus);
            await orderRepository.Save(new Order(new CreateOrder(Any.FullName())
            {
                AggregateId = orderId,
                CustomerId = customerId
            }).Apply(new AddItem
            {
                ProductName = Any.Word(),
                Quantity = 1,
                Price = Any.Decimal(.01m, 10m)
            }));
            var customerRepository = new InMemoryEventSourcedRepository<CustomerAccount>();
            await customerRepository.Save(new CustomerAccount(customerId).Apply(new ChangeEmailAddress(Any.Email())));
            bus.Subscribe(Consequenter.Create<Order.Shipped>(e =>
            {
                var order = orderRepository.GetLatest(e.AggregateId).Result;
                var customer = customerRepository.GetLatest(order.CustomerId).Result;
                customer.Apply(new SendOrderConfirmationEmail(order.OrderNumber));
                customerRepository.Save(customer).Wait();
            }));
            var shipDate = DateTimeOffset.Parse("2014-05-15 01:01:01");
            var ship = new Ship();

            // act
            using (CommandContext.Establish(ship, Clock.Create(() => shipDate)))
            {
                var order = await orderRepository.GetLatest(orderId);
                order.Apply(ship);
                await orderRepository.Save(order);
            }

            // assert
            var last = (await customerRepository.GetLatest(customerId)).Events().Last();
            last.Should()
                .BeOfType<CustomerAccount.OrderShipConfirmationEmailSent>();
            last.Timestamp.Should().Be(shipDate);
        }
Beispiel #13
0
        public async Task Advancing_the_clock_blocks_until_triggered_commands_on_the_InMemoryCommandScheduler_are_completed()
        {
            VirtualClock.Start();

            var repository = new InMemoryEventSourcedRepository<Order>();

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

            var aggregateId = Any.Guid();
            await scheduler.Schedule(new CommandScheduled<Order>
            {
                Command = new CreateOrder(Any.FullName())
                {
                    AggregateId = aggregateId
                },
                DueTime = Clock.Now().AddHours(1),
                AggregateId = aggregateId
            });

            VirtualClock.Current.AdvanceBy(TimeSpan.FromDays(1));

            var order = await repository.GetLatest(aggregateId);

            order.Should().NotBeNull();
        }
        public async Task InMemoryCommandScheduler_executes_scheduled_commands_immediately_if_no_due_time_is_specified()
        {
            // arrange
            var bus = new InProcessEventBus();
            var repository = new InMemoryEventSourcedRepository<Order>(bus: bus);
            var scheduler = new InMemoryCommandScheduler<Order>(repository);
            bus.Subscribe(scheduler);
            var order = CreateOrder();

            // act
            order.Apply(new ShipOn(Clock.Now().Subtract(TimeSpan.FromDays(2))));
            await repository.Save(order);

            await scheduler.Done();

            //assert 
            order = await repository.GetLatest(order.Id);
            var lastEvent = order.Events().Last();
            lastEvent.Should().BeOfType<Order.Shipped>();
        }