public void Configure( ISubscribeMessageHandlers configuration, IFeatureSelector featureSelector, IDeliverMessages bus, IEventSourcedRepository repository) { this.Repository = repository; configuration.SubscribeCommandHandler <CreateGiftcard>(this.HandleAsync); configuration.SubscribeCommandHandler <ActivateGiftcard>(this.HandleAsync); configuration.SubscribeCommandHandler <RedeemGiftcard>(this.HandleAsync); configuration.SubscribeCommandHandler <LoadGiftcard>(this.HandleAsync); configuration.SubscribeEventHandler <GiftcardCreated>(this.cardNumberEventHandler.HandleAsync); configuration.SubscribeEventHandler <GiftcardCreated>(this.giftcardOverviewEventHandler.HandleAsync); configuration.SubscribeEventHandler <GiftcardActivated>(this.giftcardOverviewEventHandler.HandleAsync); configuration.SubscribeEventHandler <GiftcardRedeemed>(this.giftcardOverviewEventHandler.HandleAsync); configuration.SubscribeEventHandler <GiftcardLoaded>(this.giftcardOverviewEventHandler.HandleAsync); configuration.SubscribeEventHandler <GiftcardCreated>(this.giftcardTransactionEventHandler.HandleAsync); configuration.SubscribeEventHandler <GiftcardActivated>(this.giftcardTransactionEventHandler.HandleAsync); configuration.SubscribeEventHandler <GiftcardRedeemed>(this.giftcardTransactionEventHandler.HandleAsync); configuration.SubscribeEventHandler <GiftcardLoaded>(this.giftcardTransactionEventHandler.HandleAsync); }
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()); }
public static Task SaveAndPublish <T>( this IEventSourcedRepository <T> repository, T source, IEnvelope correlation, CancellationToken cancellationToken = default) where T : class, IEventSourced { if (repository == null) { throw new ArgumentNullException(nameof(repository)); } if (source == null) { throw new ArgumentNullException(nameof(source)); } if (correlation == null) { throw new ArgumentNullException(nameof(correlation)); } return(repository.SaveAndPublish( source, correlation.OperationId, correlation.MessageId, correlation.Contributor, cancellationToken)); }
public CreateOrderService(ICommandBus commandBus, IAccountDao accountDao, IServerSettings serverSettings, ReferenceDataService referenceDataService, IIBSServiceProvider ibsServiceProvider, IRuleCalculator ruleCalculator, IAccountChargeDao accountChargeDao, ICreditCardDao creditCardDao, IOrderDao orderDao, IPromotionDao promotionDao, IEventSourcedRepository <Promotion> promoRepository, ITaxiHailNetworkServiceClient taxiHailNetworkServiceClient, IPaymentService paymentService, IPayPalServiceFactory payPalServiceFactory, IOrderPaymentDao orderPaymentDao, IFeesDao feesDao, ILogger logger, IIbsCreateOrderService ibsCreateOrderService) : base(serverSettings, commandBus, accountChargeDao, paymentService, creditCardDao, ibsServiceProvider, promotionDao, promoRepository, orderPaymentDao, accountDao, payPalServiceFactory, logger, taxiHailNetworkServiceClient, ruleCalculator, feesDao, referenceDataService, orderDao) { _commandBus = commandBus; _accountDao = accountDao; _referenceDataService = referenceDataService; _serverSettings = serverSettings; _orderDao = orderDao; _taxiHailNetworkServiceClient = taxiHailNetworkServiceClient; _logger = logger; _ibsCreateOrderService = ibsCreateOrderService; _resources = new Resources.Resources(_serverSettings); _taxiHailNetworkHelper = new TaxiHailNetworkHelper(_serverSettings, _taxiHailNetworkServiceClient, _commandBus, _logger); }
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 SetUp() { clockName = Any.CamelCaseName(); Clock.Reset(); disposables = new CompositeDisposable { Disposable.Create(Clock.Reset) }; var configuration = new Configuration() .UseSqlEventStore(c => c.UseConnectionString(TestDatabases.EventStore.ConnectionString)) .UseSqlStorageForScheduledCommands(c => c.UseConnectionString(TestDatabases.CommandScheduler.ConnectionString)); Configure(configuration); disposables.Add(ConfigurationContext.Establish(configuration)); disposables.Add(configuration); orderRepository = configuration.Repository<Order>(); accountRepository = configuration.Repository<CustomerAccount>(); clockTrigger = configuration.SchedulerClockTrigger(); clockRepository = configuration.SchedulerClockRepository(); clockRepository.CreateClock(clockName, Clock.Now()); }
public PromotionDao(Func <BookingDbContext> contextFactory, IClock clock, IServerSettings serverSettings, IEventSourcedRepository <Promotion> promoRepository) { _contextFactory = contextFactory; _clock = clock; _serverSettings = serverSettings; _promoRepository = promoRepository; }
public void SaveAndPublish_with_Envelope_relays_correctly() { // Arrange var fixture = new Fixture(); var factory = new MethodInvoker(new GreedyConstructorQuery()); fixture.Customize <Envelope>(c => c.FromFactory(factory)); IEnvelope correlation = fixture.Create <Envelope>(); FakeUser source = fixture.Create <FakeUser>(); CancellationToken cancellationToken = new CancellationTokenSource().Token; IEventSourcedRepository <FakeUser> repository = Mock.Of <IEventSourcedRepository <FakeUser> >(); // Act repository.SaveAndPublish(source, correlation, cancellationToken); // Assert Mock.Get(repository).Verify( x => x.SaveAndPublish( source, correlation.OperationId, correlation.MessageId, correlation.Contributor, cancellationToken), Times.Once()); }
public EventSourcedCommandHandler( IRunCommandOnEventSourced <TEventSourced, TCommand> runner, IEventSourcedRepository repository) { this.runner = runner; this.repository = repository; }
public MovieCommandHandler( IEventSourcedRepository <Movie> movieRepository, IEventSourcedRepository <Theater> theaterRepository) { _movieRepository = movieRepository ?? throw new ArgumentNullException(nameof(movieRepository)); _theaterRepository = theaterRepository ?? throw new ArgumentNullException(nameof(theaterRepository)); }
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); }
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; }
/// <summary> /// Initializes a new instance of the <see cref="DomainApiController{TAggregate}" /> class. /// </summary> /// <param name="repository">The repository.</param> /// <exception cref="System.ArgumentNullException">repository</exception> protected DomainApiController(IEventSourcedRepository <TAggregate> repository) { if (repository == null) { throw new ArgumentNullException("repository"); } this.repository = repository; }
public SideEffectingConsequenter(IEventSourcedRepository <CustomerAccount> customerRepository) { if (customerRepository == null) { throw new ArgumentNullException("customerRepository"); } this.customerRepository = customerRepository; }
public ImmediateCommandScheduler(IEventSourcedRepository <TAggregate> repository) { if (repository == null) { throw new ArgumentNullException("repository"); } this.repository = repository; }
public CommandOnTargetCommandHandler(IEventSourcedRepository <MarcoPoloPlayerWhoIsIt> repository) { if (repository == null) { throw new ArgumentNullException("repository"); } this.repository = repository; }
public static void AssertRepositoryRegistered <T>( this IContainer container) where T : class, IEventSourced { IEventSourcedRepository <T> service = container.ResolveOptional <IEventSourcedRepository <T> >(); service.Should().BeOfType <AzureEventSourcedRepository <T> >(); }
public TodoItemCommandHandler( IEventSourcedRepository <TodoItem> repository) { if (repository == null) { throw new ArgumentNullException(nameof(repository)); } _repository = repository; }
/// <summary> /// Initializes a new instance of the <see cref="InMemoryCommandScheduler{TAggregate}"/> class. /// </summary> /// <param name="repository">The repository.</param> /// <exception cref="System.ArgumentNullException">repository</exception> public InMemoryCommandScheduler(IEventSourcedRepository <TAggregate> repository) { if (repository == null) { throw new ArgumentNullException("repository"); } this.repository = repository; consequenter = Consequenter.Create <IScheduledCommand <TAggregate> >(e => Schedule(e).Wait()); }
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 PaymentRequestsLaterHandler(IEventSourcedRepository <Payment> paymentsRepository, IProvideTimeout timeoutProviderForBankResponseWaiting, ILogger <PaymentRequestsLaterHandler> bankResponseProcessingLogger, IAmCircuitBreakers circuitBreakers, IThrowsException gatewayExceptionSimulator = null) { _paymentsRepository = paymentsRepository; _timeoutProviderForBankResponseWaiting = timeoutProviderForBankResponseWaiting; _bankResponseProcessingLogger = bankResponseProcessingLogger; _circuitBreakers = circuitBreakers; _gatewayExceptionSimulator = gatewayExceptionSimulator; }
public CommandScheduler( IEventSourcedRepository <TAggregate> repository, ICommandPreconditionVerifier preconditionVerifier = null) { if (repository == null) { throw new ArgumentNullException("repository"); } this.repository = repository; this.preconditionVerifier = preconditionVerifier ?? Configuration.Current.Container.Resolve <ICommandPreconditionVerifier>(); }
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 PaymentRequestCommandHandler(IEventSourcedRepository <Payment> repository, IKnowAllPaymentRequests paymentRequestsMemory, IProcessPayment paymentProcessor, IMapMerchantToBankAdapter bankAdapterMapper, IKnowSendRequestToBankSynchrony synchronyMaster, ILogger <PaymentRequestCommandHandler> logger) { _repository = repository; _paymentRequestsMemory = paymentRequestsMemory; _paymentProcessor = paymentProcessor; _bankAdapterMapper = bankAdapterMapper; _synchronyMaster = synchronyMaster; _logger = logger; }
public IntegrationTest() { var factory = new EventStoreFactory(); var configuration = new ContainerLessEventStoreConfiguration(factory); configuration.UseRavenEventStore(this.DocumentStore); var bus = A.Fake <IDeliverMessages>(); var eventStore = factory.Create(configuration, bus); this.repository = new EventStoreRepository(eventStore).WithGlobalSnapshotStrategy(10); }
public async Task CreateTheater_command_handler_creates_Theater_aggregate_root( CreateTheater command) { IEventSourcedRepository <Theater> repository = GetRepository(Theater.Factory); var sut = new TheaterCommandHandler(repository); await sut.Handle(new Envelope(command)); Theater actual = await repository.Find(command.TheaterId); actual.Should().NotBeNull(); }
public PaymentProcessor(IEventSourcedRepository <Payment> paymentsRepository, ILogger <PaymentProcessor> logger, IProvideTimeout timeoutProviderForBankResponseWaiting, IKnowBufferAndReprocessPaymentRequest failureHandler, IAmCircuitBreakers circuitBreakers, IThrowsException gatewayExceptionSimulator = null) { _paymentsRepository = paymentsRepository; _logger = logger; _timeoutProviderForBankResponseWaiting = timeoutProviderForBankResponseWaiting; _failureHandler = failureHandler; _circuitBreakers = circuitBreakers; _gatewayExceptionSimulator = gatewayExceptionSimulator; }
public static async Task UpdateAsync <TEventSourcedAggregate, TId>( this IEventSourcedRepository <TEventSourcedAggregate, TId> repository, TId id, Action <TEventSourcedAggregate> action, CancellationToken token = default) where TEventSourcedAggregate : EventSourcedAggregate <TId> where TId : notnull { var aggregate = await repository.GetAsync(id, token) ?? throw new EntityNotFoundException(typeof(TEventSourcedAggregate).Name, id); action(aggregate); await repository.SaveAsync(aggregate, token); }
public async Task CreateMovie_command_handler_creates_Movie_aggregate_root( CreateMovie command) { IEventSourcedRepository <Movie> repository = GetRepository(Movie.Factory); var sut = new MovieCommandHandler( repository, GetRepository(Theater.Factory)); await sut.Handle(new Envelope(command)); Movie actual = await repository.Find(command.MovieId); actual.Should().NotBeNull(); actual.Title.Should().Be(command.Title); }
public async Task AddScreening_command_handler_adds_Screening_correctly( Guid theaterId, string name, [Range(1, 20)] int seatRowCount, [Range(1, 20)] int seatColumnCount, Movie movie, IFixture builder) { // Arange IEventSourcedRepository <Theater> theaterRepository = GetRepository(Theater.Factory); var theater = new Theater( theaterId, name, seatRowCount, seatColumnCount); await theaterRepository.SaveAndPublish(theater); IEventSourcedRepository <Movie> movieRepository = GetRepository(Movie.Factory); await movieRepository.SaveAndPublish(movie); var sut = new MovieCommandHandler( movieRepository, theaterRepository); AddScreening command = builder.Build <AddScreening>() .With(e => e.MovieId, movie.Id) .With(e => e.TheaterId, theaterId) .Create(); // Act await sut.Handle(new Envelope(command)); // Assert Movie actual = await movieRepository.Find(movie.Id); actual.Screenings .Should().Contain(s => s.Id == command.ScreeningId).Which .Should().BeEquivalentTo(new { Id = command.ScreeningId, command.TheaterId, Seats = from r in Enumerable.Range(0, seatRowCount) from c in Enumerable.Range(0, seatColumnCount) let isReserved = false select new Seat(row: r, column: c, isReserved), command.ScreeningTime, command.DefaultFee, command.ChildrenFee, }); }
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 IHandleBankResponseStrategy Build(IBankResponse bankResponse, IEventSourcedRepository <Payment> paymentsRepository) { switch (bankResponse) { case BankResponse response: return(new RespondedBankStrategy(response, paymentsRepository)); case BankDoesNotRespond _: return(new NotRespondedBankStrategy(paymentsRepository)); case NullBankResponse _: return(new NullBankResponseHandler()); } throw new ArgumentException(); }
public void SetUp() { disposables = new CompositeDisposable { VirtualClock.Start() }; configuration = new Configuration() .UseInMemoryCommandScheduling() .UseInMemoryEventStore(traceEvents: true); itRepo = configuration.Repository<MarcoPoloPlayerWhoIsIt>(); disposables.Add(ConfigurationContext.Establish(configuration)); disposables.Add(configuration); }
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 MailSendingJob(IEventStoreConnection connection, IEventSourcedRepository repo, IJsonSerializer serializer, IEmailSender sender, string queueStreamName, string outboxStreamName) { Ensure.NotNull(connection, nameof(connection)); Ensure.NotNull(repo, nameof(repo)); Ensure.NotNull(serializer, nameof(serializer)); Ensure.NotNull(sender, nameof(sender)); Ensure.NotNullOrWhiteSpace(queueStreamName, nameof(queueStreamName)); Ensure.NotNullOrWhiteSpace(outboxStreamName, nameof(outboxStreamName)); this.connection = connection; this.repo = repo; this.queueStreamName = queueStreamName; this.outboxStreamName = outboxStreamName; this.serializer = serializer; this.sender = sender; }
public AggregateRepository(IEventSourcedRepository eventSourcedRepo, string stream, Dictionary<string, object> metadata) { this.eventSourcedRepo = eventSourcedRepo; this.stream = stream; this.metadata = metadata; }
public AggregateRepositoryFactory(IEventSourcedRepository repository) { this.repository = repository; }