示例#1
0
        public void Handle(AssignSeat command)
        {
            var assignments = assignmentsRepo.Get(command.SeatAssignmentsId);

            assignments.AssignSeat(command.Position, command.Attendee);
            assignmentsRepo.Save(assignments, command.Id.ToString());
        }
        public void Handle(AssignRegistrantDetails command)
        {
            var order = repository.Get(command.OrderId);

            order.AssignRegistrant(command.FirstName, command.LastName, command.Email);
            repository.Save(order, command.Id.ToString());
        }
        public void Handle(OrderConfirmed @event)
        {
            var order       = this.ordersRepo.Get(@event.SourceId);
            var assignments = order.CreateSeatAssignments();

            assignmentsRepo.Save(assignments, null);
        }
示例#4
0
        public async Task Consume(ConsumeContext <OrderConfirmed> consumeContext)
        {
            var order = await this.ordersRepository.Get(consumeContext.Message.SourceId);

            var assignments = order.CreateSeatAssignments();
            await assignmentsRepository.Save(assignments, null);
        }
        public async Task Multiple_scheduled_commands_having_the_some_causative_command_etag_have_repeatable_and_unique_etags()
        {
            var scheduled = new List <ICommand>();

            string[] firstPassEtags;
            string[] secondPassEtags;

            configuration.AddToCommandSchedulerPipeline <MarcoPoloPlayerWhoIsIt>(async(cmd, next) =>
            {
                scheduled.Add(cmd.Command);
                await next(cmd);
            });
            configuration.AddToCommandSchedulerPipeline <MarcoPoloPlayerWhoIsNotIt>(async(cmd, next) =>
            {
                scheduled.Add(cmd.Command);
                await next(cmd);
            });

            var it = new MarcoPoloPlayerWhoIsIt()
                     .Apply(new MarcoPoloPlayerWhoIsIt.AddPlayer {
                PlayerId = Any.Guid()
            })
                     .Apply(new MarcoPoloPlayerWhoIsIt.AddPlayer {
                PlayerId = Any.Guid()
            });

            Console.WriteLine("[Saving]");
            await itRepo.Save(it);

            var sourceEtag = Any.Guid().ToString();

            await it.ApplyAsync(new MarcoPoloPlayerWhoIsIt.KeepSayingMarcoOverAndOver
            {
                ETag = sourceEtag
            });

//            VirtualClock.Current.AdvanceBy(TimeSpan.FromSeconds(2));
            firstPassEtags = scheduled.Select(c => c.ETag).ToArray();
            Console.WriteLine(new { firstPassEtags }.ToLogString());

            scheduled.Clear();

            // revert the aggregate and do the same thing again
            it = await itRepo.GetLatest(it.Id);

            await it.ApplyAsync(new MarcoPoloPlayerWhoIsIt.KeepSayingMarcoOverAndOver
            {
                ETag = sourceEtag
            });

            Console.WriteLine("about to advance clock for the second time");

//            VirtualClock.Current.AdvanceBy(TimeSpan.FromSeconds(2));
            secondPassEtags = scheduled.Select(c => c.ETag).ToArray();
            Console.WriteLine(new { secondPassEtags }.ToLogString());

            secondPassEtags.Should()
            .Equal(firstPassEtags);
        }
        public async Task If_renamed_and_saved_When_the_aggregate_is_sourced_then_the_event_is_the_new_name()
        {
            var order = await repository.GetLatest(aggregateId);

            order.Apply(new RenameEvent(order.EventHistory.Last().SequenceNumber, "ItemAdded2"));
            await repository.Save(order);

            (await repository.GetLatest(aggregateId)).EventHistory.Last().Should().BeOfType <Order.ItemAdded2>();
        }
示例#7
0
        public void Handle(CaptureCreditCardPayment command)
        {
            var payment = _repository.Get(command.PaymentId);

            payment.Capture(command.Provider, command.TotalAmount, command.MeterAmount, command.TipAmount,
                            command.TaxAmount, command.TollAmount, command.SurchargeAmount, command.AuthorizationCode, command.TransactionId,
                            command.PromotionUsed, command.AmountSavedByPromotion, command.NewCardToken,
                            command.AccountId, command.IsSettlingOverduePayment, command.IsForPrepaidOrder, command.FeeType, command.BookingFees);
            _repository.Save(payment, command.Id.ToString());
        }
示例#8
0
        public void SetUp()
        {
            Command <Order> .AuthorizeDefault = delegate { return(true); };

            customerName = Any.FullName();
            var order = new Order(new CreateOrder(customerName));

            repository.Save(order).Wait();
            aggregateId = order.Id;
        }
示例#9
0
        // Commands created from events from the conference BC

        public void Handle(AddSeats command)
        {
            var availability = repository.Find(command.ConferenceId);

            if (availability == null)
            {
                availability = new SeatsAvailability(command.ConferenceId);
            }

            availability.AddSeats(command.SeatType, command.Quantity);
            repository.Save(availability, command.Id.ToString());
        }
示例#10
0
        public void Handle(CreatePromotion command)
        {
            var promotion = new Promotion(command.PromoId, command.Name, command.Description, command.StartDate, command.EndDate,
                                          command.StartTime, command.EndTime, command.DaysOfWeek, command.AppliesToCurrentBooking, command.AppliesToFutureBooking,
                                          command.DiscountValue, command.DiscountType, command.MaxUsagePerUser, command.MaxUsage, command.Code,
                                          command.PublishedStartDate, command.PublishedEndDate, command.TriggerSettings);

            _repository.Save(promotion, command.Id.ToString());
        }
示例#11
0
        public Task Handle(
            Envelope <CreateTodoItem> envelope,
            CancellationToken cancellationToken)
        {
            CreateTodoItem command   = envelope.Message;
            Guid           messageId = envelope.MessageId;

            var todoItem = new TodoItem(
                command.TodoItemId,
                command.Description);

            return(_repository.Save(todoItem, messageId, cancellationToken));
        }
        public void SetUp()
        {
            disposables = new CompositeDisposable();
            // disable authorization
            Command <Order> .AuthorizeDefault           = (o, c) => true;
            Command <CustomerAccount> .AuthorizeDefault = (o, c) => true;

            disposables.Add(VirtualClock.Start());

            customerAccountId = Any.Guid();

            configuration = new Configuration()
                            .UseInMemoryCommandScheduling()
                            .UseInMemoryEventStore()
                            .TraceScheduledCommands();

            customerRepository = configuration.Repository <CustomerAccount>();
            orderRepository    = configuration.Repository <Order>();

            customerRepository.Save(new CustomerAccount(customerAccountId)
                                    .Apply(new ChangeEmailAddress(Any.Email())));

            disposables.Add(ConfigurationContext.Establish(configuration));
            disposables.Add(configuration);
        }
示例#13
0
        public void Handle(RegisterToWorkshop command)
        {
            var items = command.Anchors.Select(t => new OrderItem(t.AnchorType, t.Quantity)).ToList();
            var order = repository.Find(command.OrderId);

            if (order == null)
            {
                order = new Order(command.OrderId, command.WorkshopId, items, pricingService);
            }
            else
            {
                order.UpdateAnchors(items, pricingService);
            }

            repository.Save(order, command.Id.ToString());
        }
        public void SetUp()
        {
            // disable authorization
            Command<Order>.AuthorizeDefault = (o, c) => true;
            Command<CustomerAccount>.AuthorizeDefault = (o, c) => true;

            disposables = new CompositeDisposable
            {
                VirtualClock.Start()
            };

            customerAccountId = Any.Guid();

            configuration = new Configuration()
                .UseInMemoryCommandScheduling()
                .UseInMemoryEventStore();

            customerRepository = configuration.Repository<CustomerAccount>();
            orderRepository = configuration.Repository<Order>();

            customerRepository.Save(new CustomerAccount(customerAccountId).Apply(new ChangeEmailAddress(Any.Email())));

            disposables.Add(ConfigurationContext.Establish(configuration));
            disposables.Add(configuration);
        }
        public void Handle(RegisterToConference command)
        {
            var items = command.Seats.Select(t => new OrderItem(t.SeatType, t.Quantity)).ToList();
            var order = repository.Find(command.OrderId);

            if (order == null)
            {
                order = new Order(command.OrderId, command.ConferenceId, items, pricingService);
            }
            else
            {
                order.UpdateSeats(items, pricingService);
            }

            repository.Save(order, command.Id.ToString());
        }
        public async Task Consume(ConsumeContext <RegisterToConference> commandContext)
        {
            var items = commandContext.Message.Seats.Select(t => new OrderItem(t.SeatType, t.Quantity)).ToList();
            var order = await repository.Find(commandContext.Message.OrderId);

            if (order == null)
            {
                order = new Order(commandContext.Message.OrderId, commandContext.Message.ConferenceId, items, pricingService);
            }
            else
            {
                order.UpdateSeats(items, pricingService);
            }

            await repository.Save(order, commandContext.Message.Id.ToString());
        }
示例#17
0
        private static async Task FailScheduledCommand <TAggregate>(
            IEventSourcedRepository <TAggregate> repository,
            IScheduledCommand <TAggregate> scheduled,
            Exception exception  = null,
            TAggregate aggregate = null)
            where TAggregate : class, IEventSourced
        {
            var failure = (CommandFailed)createMethod
                          .MakeGenericMethod(scheduled.Command.GetType())
                          .Invoke(null, new object[] { scheduled.Command, scheduled, exception });

            var previousAttempts = scheduled.IfHas <int>(s => s.Metadata.NumberOfPreviousAttempts)
                                   .ElseDefault();

            failure.NumberOfPreviousAttempts = previousAttempts;

            if (aggregate != null)
            {
                // TODO: (FailScheduledCommand) refactor so that getting hold of the handler is simpler
                var scheduledCommandOfT = scheduled.Command as Command <TAggregate>;
                if (scheduledCommandOfT != null)
                {
                    if (scheduledCommandOfT.Handler != null)
                    {
                        await scheduledCommandOfT.Handler
                        .HandleScheduledCommandException((dynamic)aggregate,
                                                         (dynamic)failure);
                    }
                }

                if (!(exception is ConcurrencyException))
                {
                    try
                    {
                        await repository.Save(aggregate);
                    }
                    catch (Exception ex)
                    {
                        // TODO: (FailScheduledCommand) surface this more clearly
                        Trace.Write(ex);
                    }
                }
                else if (scheduled.Command is ConstructorCommand <TAggregate> )
                {
                    failure.Cancel();
                    scheduled.Result = failure;
                    return;
                }
            }

            if (!failure.IsCanceled &&
                failure.RetryAfter == null &&
                failure.NumberOfPreviousAttempts < DefaultNumberOfRetriesOnException)
            {
                failure.Retry(TimeSpan.FromMinutes(Math.Pow(failure.NumberOfPreviousAttempts + 1, 2)));
            }

            scheduled.Result = failure;
        }
示例#18
0
        public object Apply(
            [FromUri] Guid id,
            [FromUri] string commandName,
            [FromBody] JObject command)
        {
            var aggregate = GetAggregate(id);

            var existingVersion = aggregate.Version;

            ApplyCommand(aggregate, commandName, command);

            repository.Save(aggregate);

            return(Request.CreateResponse(aggregate.Version == existingVersion
                                              ? HttpStatusCode.NotModified
                                              : HttpStatusCode.OK));
        }
        public async Task Handle(IThrowsException gatewayExceptionSimulator, Guid gatewayPaymentId)
        {
            var knownPayment = await _paymentsRepository.GetById(gatewayPaymentId);

            knownPayment.BankConnectionFails();

            await _paymentsRepository.Save(knownPayment, knownPayment.Version);
        }
        public void Handle(CreateInventoryItem command)
        {
            Trace.TraceInformation("CreateInventory Item message received: For {0} - {1} - {2}", command.Id, command.Name, DateTime.Now);

            var inventoryItem = new InventoryItem(command.Id, command.Name);

            _inventoryItemRepository.Save(inventoryItem, command.Id.ToString());
        }
示例#21
0
        public void Handle(RegisteringUser command)
        {
            Console.ResetColor();
            Console.WriteLine("Add a new user");

            var user = new User(command.LoginId, command.Password, command.UserName, command.Email);

            _repository.Save(user, command.Id);
        }
示例#22
0
            public void HaveConsequences(CustomerAccount.RequestedNoSpam @event)
            {
                var customer = customerRepository.GetLatest(@event.AggregateId).Result;

                customer.Apply(new ChangeEmailAddress
                {
                    NewEmailAddress = "*****@*****.**"
                });
                customerRepository.Save(customer).Wait();
            }
示例#23
0
        private static ScheduledCommandResult FailScheduledCommand <TAggregate>(
            IEventSourcedRepository <TAggregate> repository,
            IScheduledCommand <TAggregate> scheduled,
            Exception exception  = null,
            TAggregate aggregate = null)
            where TAggregate : class, IEventSourced
        {
            var failure = (CommandFailed)createMethod
                          .MakeGenericMethod(scheduled.Command.GetType())
                          .Invoke(null, new object[] { scheduled.Command, scheduled, exception });

            var previousAttempts = scheduled.IfHas <int>(s => s.Metadata.NumberOfPreviousAttempts)
                                   .ElseDefault();

            failure.NumberOfPreviousAttempts = previousAttempts;

            if (aggregate != null)
            {
                // TODO: (FailScheduledCommand) refactor so that getting hold of the handler is simpler
                scheduled.Command
                .IfTypeIs <Command <TAggregate> >()
                .ThenDo(c =>
                {
                    if (c.Handler != null)
                    {
                        Task task = c.Handler
                                    .HandleScheduledCommandException((dynamic)aggregate,
                                                                     (dynamic)failure);
                        task.Wait();
                    }
                });

                if (!(exception is ConcurrencyException))
                {
                    try
                    {
                        repository.Save(aggregate);
                    }
                    catch (Exception ex)
                    {
                        // TODO: (FailScheduledCommand) surface this more clearly
                        Trace.Write(ex);
                    }
                }
            }
            else
            {
                if (failure.NumberOfPreviousAttempts < 5)
                {
                    failure.Retry(TimeSpan.FromMinutes(failure.NumberOfPreviousAttempts + 1));
                }
            }

            return(failure);
        }
        public async Task When_a_scheduled_command_fails_validation_then_a_failure_event_can_be_recorded_in_HandleScheduledCommandException_method()
        {
            // arrange
            var order = CreateOrder(customerAccountId: (await customerRepository.GetLatest(customerAccountId)).Id);

            // by the time Ship is applied, it will fail because of the cancellation
            order.Apply(new ShipOn(shipDate: Clock.Now().AddMonths(1).Date));
            order.Apply(new Cancel());
            await orderRepository.Save(order);

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

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

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

            lastEvent.Should().BeOfType <Order.ShipmentCancelled>();
        }
        public void Handle(AddAnchors command)
        {
            var availability = this.repository.Find(command.WorkshopID);

            if (availability == null)
            {
                availability = new AnchorsAvailability(command.WorkshopID);
            }

            availability.AddAnchors(command.AnchorType, command.Quantity);
            repository.Save(availability, command.Id.ToString());
        }
        public static async Task <ScheduledCommandResult> ApplyScheduledCommand <TAggregate>(
            this IEventSourcedRepository <TAggregate> repository,
            IScheduledCommand <TAggregate> scheduled,
            Func <Task <bool> > verifyPrecondition = null)
            where TAggregate : class, IEventSourced
        {
            TAggregate aggregate = null;
            Exception  exception = null;

            try
            {
                if (verifyPrecondition != null && !await verifyPrecondition())
                {
                    return(await FailScheduledCommand(repository,
                                                      scheduled,
                                                      new PreconditionNotMetException()));
                }

                aggregate = await repository.GetLatest(scheduled.AggregateId);

                if (aggregate == null)
                {
                    if (scheduled.Command is ConstructorCommand <TAggregate> )
                    {
                        var ctor = typeof(TAggregate).GetConstructor(new[] { scheduled.Command.GetType() });
                        aggregate = (TAggregate)ctor.Invoke(new[] { scheduled.Command });
                    }
                    else
                    {
                        // TODO: (ApplyScheduledCommand) this should probably be a different exception type.
                        throw new ConcurrencyException(
                                  string.Format("No {0} was found with id {1} so the command could not be applied.",
                                                typeof(TAggregate).Name, scheduled.AggregateId),
                                  new IEvent[] { scheduled });
                    }
                }
                else
                {
                    await aggregate.ApplyAsync(scheduled.Command);
                }

                await repository.Save(aggregate);

                return(new CommandSucceeded(scheduled));
            }
            catch (Exception ex)
            {
                exception = ex;
            }

            return(await FailScheduledCommand(repository, scheduled, exception, aggregate));
        }
        public async Task Handle(IThrowsException gatewayExceptionSimulator, Guid gatewayPaymentId)
        {
            Payment knownPayment  = null;
            var     bankPaymentId = _bankResponse.BankPaymentId;

            try
            {
                try
                {
                    knownPayment = await _paymentsRepository.GetById(gatewayPaymentId);

                    gatewayExceptionSimulator?.Throws();
                }
                catch (AggregateNotFoundException)
                {
                    return;
                }

                switch (_bankResponse.PaymentStatus)
                {
                case BankPaymentStatus.Accepted:
                    knownPayment.AcceptPayment(bankPaymentId);
                    break;

                case BankPaymentStatus.Rejected:
                    knownPayment.BankRejectPayment(bankPaymentId);
                    break;
                }

                await _paymentsRepository.Save(knownPayment, knownPayment.Version);
            }

            catch (Exception)
            {
                //TODO: log
                knownPayment.FailOnGateway(bankPaymentId);
                await _paymentsRepository.Save(knownPayment, knownPayment.Version);
            }
        }
示例#28
0
        public async Task <ICommandResult> Handle(RequestPaymentCommand command)
        {
            Payment payment;

            try
            {
                var paymentRequestId = new PaymentRequestId(command.RequestId);
                if (await _paymentRequestsMemory.AlreadyHandled(paymentRequestId))
                {
                    //payment request already handled
                    return(this.Invalid(command.RequestId, "Identical payment request will not be handled more than once"));
                }

                var bankAdapter = _bankAdapterMapper.FindBankAdapter(command.MerchantId);

                payment = new Payment(command.GatewayPaymentId, command.MerchantId, command.RequestId, command.Card, command.Amount);
                await _repository.Save(payment, Stream.NotCreatedYet);

                await _paymentRequestsMemory.Remember(paymentRequestId);


                //TODO: Add cancellation with a timeout
                if (_synchronyMaster.SendPaymentRequestAsynchronously())
                {
                    _paymentProcessor.AttemptPaying(bankAdapter, payment).ContinueWith((task) =>
                    {
                        if (task.IsFaulted)
                        {
                            _logger.LogError($"Payment request '{command.RequestId}' with exception {task.Exception}");
                        }
                    });
                }
                else
                {
                    var requestHandlingResult = await _paymentProcessor.AttemptPaying(bankAdapter, payment);

                    if (requestHandlingResult.Status == RequestHandlingStatus.Fail)
                    {
                        return(this.Failure($"{requestHandlingResult.Identifier} {requestHandlingResult} "));
                    }
                }
            }
            catch (BankOnboardMissingException e)
            {
                return(this.Invalid(command.RequestId, e.Message));
            }

            return(this.Success(payment));
        }
示例#29
0
 public void Handle(AddOrUpdateNotificationSettings command)
 {
     if (command.AccountId.HasValue)
     {
         var account = _accountRepository.Get(command.AccountId.Value);
         account.AddOrUpdateNotificationSettings(command.NotificationSettings);
         _accountRepository.Save(account, command.Id.ToString());
     }
     else
     {
         var company = _repository.Get(command.CompanyId);
         company.AddOrUpdateNotificationSettings(command.NotificationSettings);
         _repository.Save(company, command.Id.ToString());
     }
 }
        public void SetUp()
        {
            Command<Order>.AuthorizeDefault = delegate { return true; };
            repository = CreateRepository();

            var order = new Order().Apply(new AddItem
            {
                ProductName = "Widget",
                Price = 10m,
                Quantity = 2
            });
            repository.Save(order).Wait();
            aggregateId = order.Id;

            repository.GetLatest(aggregateId).Result.EventHistory.Last().Should().BeOfType<Order.ItemAdded>();
        }
        public static Task Save <T>(
            this IEventSourcedRepository <T> repository,
            T source)
            where T : class, IEventSourced
        {
            if (repository == null)
            {
                throw new ArgumentNullException(nameof(repository));
            }

            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            return(repository.Save(source, null, CancellationToken.None));
        }
        public void SetUp()
        {
            Command <Order> .AuthorizeDefault = delegate { return(true); };
            repository = CreateRepository();

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

            repository.Save(order).Wait();
            aggregateId = order.Id;

            repository.GetLatest(aggregateId).Result.EventHistory.Last().Should().BeOfType <Order.ItemAdded>();
        }