Beispiel #1
0
        public void When_ShipOrderCreated_ThrowInvalidOrderStateException()
        {
            var events = InitialEvents.Take(1).ToList();

            Given(events.ToArray());
            WhenThrows <ShipOrder, InvalidOrderStateException>(new ShipOrder(id));
        }
Beispiel #2
0
        /// <summary>
        /// Instantiates aggregates from the events within the scenario, and optionally runs projection catchups through specified handlers.
        /// </summary>
        /// <returns>A Scenario based on the specifications built-up using a <see cref="ScenarioBuilder" />.</returns>
        /// <exception cref="System.InvalidOperationException">Already prepared</exception>
        public virtual Scenario Prepare()
        {
            EnsureScenarioHasNotBeenPrepared();

            beforePrepare.ForEach(@do => @do());

            prepared = true;

            scenario = new Scenario(this);

            var configurationContext = ConfigurationContext.Establish(configuration);

            configurationContext.AllowOverride = true;
            scenario.RegisterForDispose(configurationContext);
            scenario.RegisterForDispose(configuration);

            if (configuration.IsUsingSqlEventStore())
            {
                // capture the highest event id from the event store before the scenario adds new ones
                startCatchupAtEventId = CreateEventStoreDbContext().DisposeAfter(db => db.Events.Max <StorableEvent, long?>(e => e.Id) ?? 0) + 1;
            }

            SourceAggregatesFromInitialEvents();
            SubscribeProjectors();
            RunCatchup();
            SubscribeConsequenters();

            // command scheduling
            InitialEvents.ForEach(ScheduleIfNeeded);

            return(scenario);
        }
Beispiel #3
0
        public void When_CancelCheckedOut_ThrowsInvalidStateException()
        {
            var initialEvents = InitialEvents.ToList();

            initialEvents.Add(new BasketCheckedOut(id, new List <OrderLine>(), shippingAddress));
            Given(initialEvents.ToArray());
            WhenThrows <CancelBasket, InvalidStateException>(new CancelBasket(id));
        }
Beispiel #4
0
        public void When_CancelCancelled_NothingHappens()
        {
            var initialEvents = InitialEvents.ToList();

            initialEvents.Add(new BasketCancelled(id));
            Given(initialEvents.ToArray());
            When(new CancelBasket(id));
            Then(new IEvent[] { });
        }
        public void When_CheckOutCheckedOut_NothingHappens()
        {
            var initialEvents = InitialEvents.ToList();

            initialEvents.Add(new BasketCheckedOut(id, OrderLines, shippingAddress));
            Given(initialEvents.ToArray());
            When(new CheckOutBasket(id, shippingAddress));
            Then(new IEvent[] { });
        }
        public void When_AddOrderLineNotPending_ThowsInvalidOrderStateException()
        {
            Given(InitialEvents.ToArray(), new OrderCancelled(id));

            var command = new AddOrderLine(id, OrderLines[0]);

            command.Metadata.CausationId   = command.Metadata.CommandId;
            command.Metadata.CorrelationId = causationAndCorrelationId;

            WhenThrows <AddOrderLine, InvalidOrderStateException>(command);
        }
        private void When_PrepareForShippingNoOrderLinesAdded_ThrowsInvalidOrderStateException()
        {
            Given(InitialEvents.Take(1).ToArray());

            var command = new PrepareOrderForShipping(id);

            command.Metadata.CausationId   = command.Metadata.CommandId;
            command.Metadata.CorrelationId = causationAndCorrelationId;

            WhenThrows <PrepareOrderForShipping, InvalidOrderStateException>(command);
        }
        public void When_CancelOrderWhenShipped_CancelOrderFailed()
        {
            Given(InitialEvents.Take(3).ToArray());

            var command = new CancelOrder(id);

            command.Metadata.CausationId   = command.Metadata.CommandId;
            command.Metadata.CorrelationId = causationAndCorrelationId;

            WhenThrows <CancelOrder, InvalidOrderStateException>(command);
        }
 private void ProcessAndClearInitialEvents()
 {
     lock (syncContext)
     {
         if (initialEvents != null)
         {
             var aggregateEvents = initialEvents.Value;
             initialEvents = null;
             SaveAggregateEvents(aggregateEvents).Wait();
         }
     }
 }
Beispiel #10
0
        public void When_RemoveItemNotPending_ThrowsInvalidStateException(string checkedOutOrCancelled)
        {
            IEvent evt = new BasketCheckedOut(id, OrderLines, new Address());

            if (checkedOutOrCancelled == "cancelled")
            {
                evt = new BasketCancelled(id);
            }

            InitialEvents.Add(evt);

            Given(InitialEvents.ToArray());

            WhenThrows <RemoveItemFromBasket, InvalidStateException>(new RemoveItemFromBasket(id, productId, 10));
        }
        public void When_AddItemNotPending_ThrowsInvalidStateException(string checkedOutOrCancelled)
        {
            IEvent evt = new BasketCheckedOut(id, new List <OrderLine>(), new Address());

            if (checkedOutOrCancelled == "cancelled")
            {
                evt = new BasketCancelled(id);
            }

            InitialEvents.Add(evt);

            Given(InitialEvents.ToArray());

            WhenThrows <AddItemToBasket, InvalidStateException>(new AddItemToBasket(id, productId, "Test Product", 2, 10));
        }
Beispiel #12
0
        /// <summary>
        /// Instantiates aggregates from the events within the scenario, and optionally runs projection catchups through specified handlers.
        /// </summary>
        /// <returns>A Scenario based on the specifications built-up using a <see cref="ScenarioBuilder" />.</returns>
        /// <exception cref="System.InvalidOperationException">Already prepared</exception>
        public virtual Scenario Prepare()
        {
            EnsureScenarioHasNotBeenPrepared();

            beforePrepare.ForEach(@do => @do());

            prepared = true;

            // command scheduling
            if (!configuration.IsUsingInMemoryCommandScheduling())
            {
                var clockName = "TEST-" + Guid.NewGuid().ToString("N").ToETag();
                Configuration.Properties["CommandSchedulerClockName"] = clockName;
                Configuration.Container.Register <GetClockName>(c => e => clockName);
                var clockRepository = Configuration.SchedulerClockRepository();
                clockRepository.CreateClock(clockName, Clock.Now());
            }

            configuration.EnsureCommandSchedulerPipelineTrackerIsInitialized();

            scenario = new Scenario(this);

            var configurationContext = ConfigurationContext.Establish(configuration);

            configurationContext.AllowOverride = true;
            scenario.RegisterForDispose(configurationContext);
            scenario.RegisterForDispose(configuration);

            if (configuration.IsUsingSqlEventStore())
            {
                // capture the highest event id from the event store before the scenario adds new ones
                startCatchupAtEventId = configuration.EventStoreDbContext()
                                        .DisposeAfter(db => db.HighestEventId()) + 1;
            }

            SourceAggregatesFromInitialEvents();
            SubscribeProjectors();
            RunCatchup();
            SubscribeConsequenters();

            InitialEvents.ForEach(ScheduleIfNeeded);

            return(scenario);
        }
Beispiel #13
0
        public void When_RemoveItemBelowZero_ItemRemoved()
        {
            Given(InitialEvents.ToArray());

            var command = new RemoveItemFromBasket(id, productId, 15);

            command.Metadata.CausationId   = command.Metadata.CommandId;
            command.Metadata.CorrelationId = causationAndCorrelationId;

            When(command);

            var expectedEvent = new BasketItemRemoved(id, productId, 10);

            expectedEvent.Metadata.CausationId   = command.Metadata.CommandId;
            expectedEvent.Metadata.CorrelationId = causationAndCorrelationId;
            expectedEvent.Metadata.ProcessId     = command.Metadata.ProcessId;

            Then(expectedEvent);
        }
        public void When_AddItem_BasketAddItemAdded()
        {
            Given(InitialEvents.ToArray());

            var command = new AddItemToBasket(id, productId, "Test Item", 2, 10);

            command.Metadata.CausationId   = command.Metadata.CommandId;
            command.Metadata.CorrelationId = causationAndCorrelationId;

            When(command);

            var expectedEvent = new BasketItemAdded(id, productId, "Test Item", 2, 10);

            expectedEvent.Metadata.CausationId   = command.Metadata.CommandId;
            expectedEvent.Metadata.CorrelationId = causationAndCorrelationId;
            expectedEvent.Metadata.ProcessId     = command.Metadata.ProcessId;

            Then(expectedEvent);
        }
        public void When_CancelOrder_OrderCancelled()
        {
            Given(InitialEvents.Take(2).ToArray());

            var command = new CancelOrder(id);

            command.Metadata.CausationId   = command.Metadata.CommandId;
            command.Metadata.CorrelationId = causationAndCorrelationId;

            When(command);

            var expectedEvent = new OrderCancelled(id);

            expectedEvent.Metadata.CausationId   = command.Metadata.CommandId;
            expectedEvent.Metadata.CorrelationId = causationAndCorrelationId;
            expectedEvent.Metadata.ProcessId     = command.Metadata.ProcessId;

            Then(expectedEvent);
        }
        private void When_PrepareForShipping_OrderReadyForShipping()
        {
            Given(InitialEvents.ToArray());

            var command = new PrepareOrderForShipping(id);

            command.Metadata.CausationId   = command.Metadata.CommandId;
            command.Metadata.CorrelationId = causationAndCorrelationId;

            When(command);

            var expectedEvent = new OrderReadyForShipping(id);

            expectedEvent.Metadata.CausationId   = command.Metadata.CommandId;
            expectedEvent.Metadata.CorrelationId = causationAndCorrelationId;
            expectedEvent.Metadata.ProcessId     = command.Metadata.ProcessId;

            Then(expectedEvent);
        }
        public void When_AddOrderLine_OrderLineAdded()
        {
            Given(InitialEvents.ToArray());

            var command = new AddOrderLine(id, OrderLines[0]);

            command.Metadata.CausationId   = command.Metadata.CommandId;
            command.Metadata.CorrelationId = causationAndCorrelationId;

            When(command);

            var expectedEvent = new OrderLineAdded(id, OrderLines[0]);

            expectedEvent.Metadata.CausationId   = command.Metadata.CommandId;
            expectedEvent.Metadata.CorrelationId = causationAndCorrelationId;
            expectedEvent.Metadata.ProcessId     = command.Metadata.ProcessId;

            Then(expectedEvent);
        }
        public void When_CheckOut_CheckedOut()
        {
            Given(InitialEvents.ToArray());

            var command = new CheckOutBasket(id, shippingAddress);

            command.Metadata.CausationId   = command.Metadata.CommandId;
            command.Metadata.CorrelationId = causationAndCorrelationId;
            command.Metadata.ProcessId     = causationAndCorrelationId;

            When(command);

            var expectedEvent = new BasketCheckedOut(id, OrderLines, shippingAddress);

            expectedEvent.Metadata.CausationId   = command.Metadata.CommandId;
            expectedEvent.Metadata.CorrelationId = causationAndCorrelationId;
            expectedEvent.Metadata.ProcessId     = command.Metadata.ProcessId;

            Then(expectedEvent);
        }
Beispiel #19
0
        private void RunCatchup()
        {
            // TODO: (RunCatchup) provide trace output here and throughout
            var projectors = handlers.OrEmpty()
                             .Where(h => h.GetType().IsProjectorType())
                             .ToArray();

            if (!projectors.Any())
            {
                return;
            }

            if (configuration.IsUsingSqlEventStore())
            {
                var catchup = new ReadModelCatchup(projectors)
                {
                    CreateEventStoreDbContext = CreateEventStoreDbContext,
                    CreateReadModelDbContext  = CreateReadModelDbContext,
                    StartAtEventId            = startCatchupAtEventId
                };

                using (catchup)
                    using (catchup.EventBus.Errors.Subscribe(scenario.AddEventHandlingError))
                        using (catchup.Progress.Subscribe(s => Console.WriteLine(s)))
                        {
                            catchup.Run();
                        }
            }
            else
            {
                EventBus.PublishAsync(InitialEvents.ToArray()).Wait();
            }

            if (scenario.EventHandlingErrors.Any())
            {
                throw new ScenarioSetupException(
                          "The following event handling errors occurred during projection catchup: " +
                          string.Join("\n", scenario.EventHandlingErrors.Select(e => e.Exception.ToString())));
            }
        }
Beispiel #20
0
        private void SourceAggregatesFromInitialEvents()
        {
            InitialEvents.GroupBy(e => e.AggregateType(),
                                  e => e)
            .ForEach(es =>
            {
                // populate the event stream
                var aggregateType = es.Key;

                var repositoryType = typeof(IEventSourcedRepository <>).MakeGenericType(aggregateType);

                if (!configuration.IsUsingSqlEventStore())
                {
                    var streamName = AggregateType.EventStreamName(aggregateType);

                    var eventStream = Configuration.Container
                                      .Resolve <ConcurrentDictionary <string, IEventStream> >()
                                      .GetOrAdd(streamName, s => new InMemoryEventStream(s));

                    var storableEvents = events.AssignSequenceNumbers()
                                         .Select(e => e.ToStoredEvent());

                    eventStream.Append(storableEvents.ToArray())
                    .Wait();
                }
                else
                {
                    PersistEventsToSql(es);
                }

                dynamic repository = Configuration.Container
                                     .Resolve(repositoryType);

                es.Select(e => e.AggregateId).Distinct().ForEach(id =>
                {
                    var aggregate = repository.GetLatest(id).Result;
                    scenario.aggregates.Add(aggregate);
                });
            });
        }
 public void When_CheckOutCancelled_ThrowsInvalidStateException()
 {
     InitialEvents.Add(new BasketCancelled(id));
     Given(InitialEvents.ToArray());
     WhenThrows <CheckOutBasket, InvalidStateException>(new CheckOutBasket(id, shippingAddress));
 }
 public void When_CheckOutEmpty_NothingHappens()
 {
     Given(InitialEvents.Take(1).ToArray());
     When(new CheckOutBasket(id, shippingAddress));
     Then(new IEvent[] { });
 }
Beispiel #23
0
 public void When_RemoveItemEmptyBasket_NothingHappens()
 {
     Given(InitialEvents.Take(1).ToArray());
     When(new RemoveItemFromBasket(id, productId, 10));
     Then(new IEvent[] { });
 }
 public LastEventsEventStoreDecorator(IEventStore decorated, InitialEvents initialEvents, NewEvents newEvents)
 {
     this.decorated     = decorated;
     this.newEvents     = newEvents;
     this.initialEvents = initialEvents;
 }