public void Should_Trigger_OnError_When_Domain_Event_Handler_Exception_Occurred() { TestDomainEventHandler handler = new TestDomainEventHandler(_testOutput); IEventPublisher publisher = Factory.CreatePublisher(reg => { reg.Register <TestAggregateCreatedEvent>(() => handler); reg.Register <OperationExecutedEvent>(() => handler); }); publisher.OnError += (e, ex) => { _testOutput.WriteLine($"{ex.GetType().Name} occurred while handling {e.GetType().Name} event: {ex.Message}"); Assert.IsType <TestAggregateDomainEventHandlerException>(ex); }; IEventSourcedAggregateRepository <TestAggregate, Guid> repository = Factory.CreateTestAggregateRepository(publisher); TestAggregate aggregate = new TestAggregate(Guid.NewGuid()); // This would trigger a TestAggregateDomainEventHandlerException when handled by TestDomainEventHandler. aggregate.TriggerExceptionOnEventHandler(); repository.Save(aggregate); }
public void Should_Invoke_Registered_Domain_Event_Handler() { TestDomainEventHandler handler = new TestDomainEventHandler(_testOutput); IEventSourcedAggregateRepository <TestAggregate, Guid> repository = Factory.CreateTestAggregateRepository(reg => { reg.Register <TestAggregateCreatedEvent>(() => handler); reg.Register <OperationExecutedEvent>(() => handler); }); TestAggregate aggregate = new TestAggregate(Guid.NewGuid()); aggregate.ExecuteSomeOperation("Test Operation"); repository.Save(aggregate); // Event may not have yet been handled in background. Thread.Sleep(1000); // Aggregate should be stored. TestAggregate storedAggregate = repository.GetById(aggregate.Id); Assert.Equal(aggregate.Id, storedAggregate.Id); // Aggregate should have 2 events. // 1. TestAggregateCreated // 2. TestAggregateModified Assert.Equal(2, handler.HandledEvents.Count); Assert.Contains(handler.HandledEvents, (e) => e is TestAggregateCreatedEvent); Assert.Contains(handler.HandledEvents, (e) => e is OperationExecutedEvent); }
public void Should_Retrieve_Aggregate() { IEventSourcedAggregateRepository <TestAggregate, Guid> repository = Factory.CreateTestAggregateRepository(); TestAggregate aggregate = new TestAggregate(Guid.NewGuid()); repository.Save(aggregate); TestAggregate fromRepo = repository.GetById(aggregate.Id); Assert.NotNull(fromRepo); Assert.Equal(aggregate.Id, fromRepo.Id); }
public void Submit <TCommand>(TCommand command) { if (_handlers.ContainsKey(command.GetType())) { dynamic handler = _handlers[command.GetType()]; var aggregate = handler.Execute((dynamic)command); var newEvents = aggregate.UncommitedEvents(); _aggregateRepository.Save(aggregate); foreach (var evt in newEvents) { _eventPublisher.PublishEvent(evt); } } else { throw new Exception("No command handler found for command:" + command.GetType()); } }
public async Task <CreatePexaWorkspaceResponse> Handle(CreatePexaWorkspaceCommand command, CancellationToken cancellationToken) { if (command is null) { throw new ArgumentNullException(nameof(command)); } await _validator.ValidateAndThrowAsync(command); // Check that the user has valid Actionstep credentials for the given Actionstep Matter in Subscriber Reference if (!_wCADbContext.ActionstepCredentials.UserHasValidCredentialsForOrg(command.AuthenticatedUser, command.OrgKey)) { throw new UnauthorizedAccessException($"User {command.AuthenticatedUser.Id} does not have valid Actionstep credentials for org {command.OrgKey} which is specified in the PEXA Subscriber Reference field."); } // Load Actionstep matter aggregate. SubscriberReference should already be in correct Aggregate Id format var actionstepMatter = _actionstepMatterRepository.GetById(command.PexaWorkspaceCreationRequest.SubscriberReference); if (actionstepMatter.Id == null) { actionstepMatter = new ActionstepMatter(_clock.GetCurrentInstant(), command.OrgKey, command.MatterId, command.AuthenticatedUser.Id); } PexaWorkspaceCreationRequested pexaWorkspaceCreationRequested = null; try { // Mark request for PEXA workspace creation pexaWorkspaceCreationRequested = actionstepMatter.RequestPexaWorkspaceCreation(_clock.GetCurrentInstant(), command.AuthenticatedUser.Id); _actionstepMatterRepository.Save(actionstepMatter); // Call PEXA and attempt to create workspace var workspaceCreationResponse = await _pexaService.Handle <WorkspaceCreationResponse>( new WorkspaceCreationRequestCommand(command.PexaWorkspaceCreationRequest, command.AccessToken), command.AuthenticatedUser, cancellationToken); var urlSafeId = Uri.EscapeDataString(workspaceCreationResponse.WorkspaceId); if (string.IsNullOrEmpty(urlSafeId)) { throw new PexaUnexpectedErrorResponseException("PEXA Request came back successful but there was no PEXA Workspace ID."); } // If sucessful, save immediately actionstepMatter.MarkPexaWorkspaceCreated(_clock.GetCurrentInstant(), workspaceCreationResponse.WorkspaceId, pexaWorkspaceCreationRequested); _actionstepMatterRepository.Save(actionstepMatter); var workspaceUri = _pexaService.GetWorkspaceUri(workspaceCreationResponse.WorkspaceId, command.PexaWorkspaceCreationRequest.Role); var invitationUri = _pexaService.GetInvitationUri(workspaceCreationResponse.WorkspaceId, command.PexaWorkspaceCreationRequest.Role); return(new CreatePexaWorkspaceResponse(workspaceUri, workspaceCreationResponse.WorkspaceId, invitationUri)); } catch (PexaWorkspaceAlreadyExistsException ex) { var workspaceUri = _pexaService.GetWorkspaceUri(ex.WorkspaceId, command.PexaWorkspaceCreationRequest.Role); var invitationUri = _pexaService.GetInvitationUri(ex.WorkspaceId, command.PexaWorkspaceCreationRequest.Role); return(new CreatePexaWorkspaceResponse(workspaceUri, ex.WorkspaceId, invitationUri, true)); } catch (Exception ex) { actionstepMatter.MarkPexaWorkspaceCreationFailed(_clock.GetCurrentInstant(), ex.Message, pexaWorkspaceCreationRequested); _actionstepMatterRepository.Save(actionstepMatter); throw; } }