Example #1
0
        public void Given_default_policy()
        {
            _sagaId = Guid.NewGuid();
            var sagaStartEvent = new GotTiredEvent(_sagaId, Guid.NewGuid(), Guid.NewGuid(), _sagaId);

            var waiter = GridNode.NewWaiter()
                         .Expect <SagaCreatedEvent <SoftwareProgrammingSaga.States> >()
                         .Create();

            Publisher.Publish(sagaStartEvent);
            waiter.Wait();

            var sagaContinueEvent = new CoffeMakeFailedEvent(_sagaId,
                                                             sagaStartEvent.PersonId,
                                                             BusinessDateTime.UtcNow,
                                                             _sagaId);

            var waiterB = GridNode.NewWaiter()
                          .Expect <SagaTransitionEvent <SoftwareProgrammingSaga.States, SoftwareProgrammingSaga.Triggers> >()
                          .Create();

            Publisher.Publish(sagaContinueEvent);

            waiterB.Wait();


            //saving snapshot
            Thread.Sleep(200);

            _snapshots = new AggregateSnapshotRepository(AkkaConf.Persistence.JournalConnectionString, GridNode.AggregateFromSnapshotsFactory)
                         .Load <SoftwareProgrammingSagaState>(sagaStartEvent.SagaId);
        }
Example #2
0
        public async Task Given_instance_process_When_recovering_from_creation()
        {
            var aggregateFactory = new AggregateFactory();
            var processId        = Guid.NewGuid().ToString();

            var data         = aggregateFactory.Build <ProcessStateAggregate <SoftwareProgrammingState> >(processId);
            var process      = new SoftwareProgrammingProcess();
            var initialState = new SoftwareProgrammingState(processId, process.MakingCoffee.Name);

            var eventsToReplay = new DomainEvent[] { new ProcessManagerCreated <SoftwareProgrammingState>(initialState, processId) };

            data.ApplyEvents(eventsToReplay);

            var processManager = new SoftwareProgrammingProcess();

            //Try to transit process by message, available only in desired state
            var coffeMakeFailedEvent = new CoffeMakeFailedEvent(Guid.NewGuid().ToString(), Guid.NewGuid().ToString());
            var dispatchedCommands   = await processManager.Transit(data.State, coffeMakeFailedEvent);

            //process_produce_commands_only_one_command()
            Assert.Equal(1, dispatchedCommands.Count);
            //Produced_command_has_right_person_id()
            var sleepCommand = dispatchedCommands.OfType <GoSleepCommand>().First();

            Assert.Equal(coffeMakeFailedEvent.ForPersonId, sleepCommand.PersonId);
            //Produced_command_has_right_sofa_id()
            Assert.Equal(data.State.SofaId, sleepCommand.SofaId);
            //process_produce_command_from_given_state()
            Assert.IsAssignableFrom <GoSleepCommand>(dispatchedCommands.FirstOrDefault());
        }
        public async Task When_process_produce_command_and_waiting_for_it_fault()
        {
            var givenProcessStateAggregate = new ProcessStateAggregate <SoftwareProgrammingState>(new SoftwareProgrammingState(Guid.NewGuid().ToString(),
                                                                                                                               nameof(SoftwareProgrammingProcess.MakingCoffee))
            {
                PersonId = Guid.NewGuid().ToString()
            });

            await Node.SaveToJournal(givenProcessStateAggregate);

            var coffeMakeFailedEvent = new CoffeMakeFailedEvent(Guid.NewGuid().ToString(),
                                                                givenProcessStateAggregate.State.PersonId,
                                                                BusinessDateTime.UtcNow,
                                                                givenProcessStateAggregate.Id);

            await Node.NewDebugWaiter()
            .Expect <ProcessReceivedMessage <SoftwareProgrammingState> >(m => m.State.CurrentStateName == nameof(SoftwareProgrammingProcess.Coding))
            .Create()
            .SendToProcessManagers(coffeMakeFailedEvent, MessageMetadata.New(coffeMakeFailedEvent.SourceId, null, null));

            var processStateAggregate = await this.LoadProcessByActor <SoftwareProgrammingState>(givenProcessStateAggregate.Id);

            //Process_should_be_in_correct_state_after_fault_handling()
            Assert.Equal(nameof(SoftwareProgrammingProcess.Coding), processStateAggregate.CurrentStateName);
            //Process_state_should_contain_data_from_fault_message()
            Assert.Equal(coffeMakeFailedEvent.ForPersonId, processStateAggregate.BadSleepPersonId);
        }
        public async Task Given_default_policy()
        {
            var startEvent = new GotTiredEvent(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), Guid.NewGuid().ToString());

            var res = await
                      Node.NewDebugWaiter()
                      .Expect <ProcessManagerCreated <SoftwareProgrammingState> >()
                      .Create()
                      .SendToProcessManagers(startEvent);

            var processId = res.Message <ProcessManagerCreated <SoftwareProgrammingState> >().SourceId;

            var continueEvent = new CoffeMakeFailedEvent(Guid.NewGuid().ToString(), startEvent.PersonId, BusinessDateTime.UtcNow, processId);

            await Node.NewDebugWaiter()
            .Expect <ProcessReceivedMessage <SoftwareProgrammingState> >()
            .Create()
            .SendToProcessManagers(continueEvent);

            //saving snapshot
            await Task.Delay(200);

            var snapshots =
                await
                new AggregateSnapshotRepository(AutoTestNodeDbConfiguration.Default.JournalConnectionString,
                                                new AggregateFactory(),
                                                new AggregateFactory()
                                                ).Load <ProcessStateAggregate <SoftwareProgrammingState> >(
                    startEvent.ProcessId);

            //Snapshot_should_be_saved_one_time()
            Assert.Empty(snapshots);
        }
        public async Task Given_save_on_each_message_policy_and_keep_2_snapshots()
        {
            var startEvent = new GotTiredEvent(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), Guid.NewGuid().ToString());

            var res = await Node.NewDebugWaiter()
                      .Expect <ProcessManagerCreated <SoftwareProgrammingState> >()
                      .Create()
                      .SendToProcessManagers(startEvent);

            var processId = res.Message <ProcessManagerCreated <SoftwareProgrammingState> >()
                            .SourceId;

            var continueEventA = new CoffeMakeFailedEvent(Guid.NewGuid().ToString(),
                                                          startEvent.PersonId,
                                                          BusinessDateTime.UtcNow,
                                                          processId);

            await Node.SendToProcessManagers(continueEventA);

            await Node.KillProcessManager <SoftwareProgrammingProcess, SoftwareProgrammingState>(processId);


            Version <ProcessStateAggregate <SoftwareProgrammingState> >[] snapshots = null;


            //Only_two_Snapshots_should_left()

            AwaitAssert(() =>
            {
                snapshots = AggregateSnapshotRepository.New(AutoTestNodeDbConfiguration.Default.JournalConnectionString)
                            .Load <ProcessStateAggregate <SoftwareProgrammingState> >(processId)
                            .Result;
                Assert.Equal(2, snapshots.Length);

                // Restored_aggregates_should_have_same_ids()
                Assert.True(snapshots.All(s => s.Payload.Id == processId));

                // First_Snapshots_should_have_coding_state_from_first_event()
                Assert.Equal(nameof(SoftwareProgrammingProcess.MakingCoffee),
                             snapshots.First()
                             .Payload.State.CurrentStateName);

                //Last_Snapshots_should_have_coding_state_from_last_event()
                Assert.Equal(nameof(SoftwareProgrammingProcess.Sleeping),
                             snapshots.Last()
                             .Payload.State.CurrentStateName);

                //All_snapshots_should_not_have_uncommited_events()
                Assert.Empty(snapshots.SelectMany(s => s.Payload.GetEvents()));
            },
                        TimeSpan.FromSeconds(10),
                        TimeSpan.FromSeconds(1));
        }
Example #6
0
        public void Given_save_on_each_message_policy_and_keep_2_snapshots()
        {
            _sagaId = Guid.NewGuid();
            var sagaStartEvent = new GotTiredEvent(_sagaId, Guid.NewGuid(), Guid.NewGuid(), _sagaId);

            var wait = GridNode.NewWaiter()
                       .Expect <SagaCreatedEvent <SoftwareProgrammingSagaData> >()
                       .Create();

            Publisher.Publish(sagaStartEvent);

            wait.Wait();

            var sagaActorRef = LookupInstanceSagaActor <SoftwareProgrammingSaga, SoftwareProgrammingSagaData>(_sagaId);

            sagaActorRef.Tell(new NotifyOnPersistenceEvents(TestActor), TestActor);

            var sagaContinueEventA = new CoffeMakeFailedEvent(_sagaId,
                                                              sagaStartEvent.PersonId,
                                                              BusinessDateTime.UtcNow,
                                                              _sagaId);

            var sagaContinueEventB = new SleptWellEvent(_sagaId,
                                                        sagaStartEvent.LovelySofaId,
                                                        _sagaId);

            var waiter = GridNode.NewWaiter()
                         .Expect <SagaMessageReceivedEvent <SoftwareProgrammingSagaData> >(e => (e.Message as CoffeMakeFailedEvent)?.SourceId == _sagaId)
                         .And <SagaMessageReceivedEvent <SoftwareProgrammingSagaData> >(e => (e.Message as SleptWellEvent)?.SourceId == _sagaId)
                         .Create();

            Publisher.Publish(sagaContinueEventA);
            Publisher.Publish(sagaContinueEventB);

            waiter.Wait();

            Watch(sagaActorRef);
            sagaActorRef.Tell(GracefullShutdownRequest.Instance, TestActor);

            FishForMessage <Terminated>(m => true, TimeSpan.FromDays(1));
            Thread.Sleep(1000);
            _snapshots = new AggregateSnapshotRepository(AkkaConf.Persistence.JournalConnectionString,
                                                         GridNode.AggregateFromSnapshotsFactory)
                         .Load <SagaDataAggregate <SoftwareProgrammingSagaData> >(_sagaId);

            Console.WriteLine(_snapshotsPersistencePolicy.ToPropsString());
        }
        public void Given_save_on_each_message_policy_and_keep_2_snapshots()
        {
            _sagaId = Guid.NewGuid();
            var sagaStartEvent = new GotTiredEvent(_sagaId, Guid.NewGuid(), Guid.NewGuid(), _sagaId);

            var w = GridNode.NewWaiter()
                    .Expect <SagaCreatedEvent <SoftwareProgrammingSaga.States> >()
                    .Create();

            Publisher.Publish(sagaStartEvent);
            w.Wait();

            var sagaActorRef = LookupStateSagaActor <SoftwareProgrammingSaga, SoftwareProgrammingSagaState>(_sagaId);

            Watch(sagaActorRef);
            sagaActorRef.Tell(new NotifyOnPersistenceEvents(TestActor), TestActor);



            var sagaContinueEventA = new CoffeMakeFailedEvent(_sagaId,
                                                              sagaStartEvent.PersonId,
                                                              BusinessDateTime.UtcNow,
                                                              _sagaId);

            var sagaContinueEventB = new SleptWellEvent(_sagaId,
                                                        sagaStartEvent.LovelySofaId,
                                                        _sagaId);

            var waiter = GridNode.NewWaiter()
                         .Expect <SagaTransitionEvent <SoftwareProgrammingSaga.States, SoftwareProgrammingSaga.Triggers> >(e => e.State == SoftwareProgrammingSaga.States.Coding)
                         .And <SagaTransitionEvent <SoftwareProgrammingSaga.States, SoftwareProgrammingSaga.Triggers> >(e => e.State == SoftwareProgrammingSaga.States.Sleeping)
                         .Create();

            Publisher.Publish(sagaContinueEventA);
            Publisher.Publish(sagaContinueEventB);

            waiter.Wait();

            sagaActorRef.Tell(GracefullShutdownRequest.Instance, TestActor);

            FishForMessage <Terminated>(m => true);

            _snapshots = new AggregateSnapshotRepository(AkkaConf.Persistence.JournalConnectionString,
                                                         GridNode.AggregateFromSnapshotsFactory)
                         .Load <SoftwareProgrammingSagaState>(_sagaId);
        }
        public async Task When_saga_receives_a_message_that_case_saga_exception()
        {
            var sagaId   = Guid.NewGuid();
            var personId = Guid.NewGuid();

            //prepare initial saga state

            var sagaDataEvent = new SagaCreatedEvent <SoftwareProgrammingSaga.States>(SoftwareProgrammingSaga.States.MakingCoffee, sagaId);

            SaveInJournal <SoftwareProgrammingSagaState>(sagaId, sagaDataEvent);

            var sagaTransitEvent = new CoffeMakeFailedEvent(Guid.Empty, personId).CloneWithSaga(sagaId);

            var waitResults = await GridNode.NewDebugWaiter()
                              .Expect <IFault <CoffeMakeFailedEvent> >()
                              .Create()
                              .Publish(sagaTransitEvent);

            _fault = waitResults.Message <IFault <CoffeMakeFailedEvent> >();
        }
        public void Given_instance_saga_When_recovering_from_creation()
        {
            var aggregateFactory = new AggregateFactory();
            var sagaId           = Guid.NewGuid();

            _data = aggregateFactory.Build <SagaDataAggregate <SoftwareProgrammingSagaData> >(sagaId);
            var saga         = new SoftwareProgrammingSaga();
            var initialState = new SoftwareProgrammingSagaData(saga.MakingCoffee.Name);

            var eventsToReplay = new DomainEvent[]
            {
                new SagaCreatedEvent <SoftwareProgrammingSagaData>(initialState, sagaId)
            };

            _data.ApplyEvents(eventsToReplay);

            _sagaInstance = SagaInstance.New(saga, _data);

            //Try to transit saga by message, available only in desired state
            _coffeMakeFailedEvent = new CoffeMakeFailedEvent(Guid.NewGuid(), Guid.NewGuid());
            _sagaInstance.Transit(_coffeMakeFailedEvent);
            _dispatchedCommands = _sagaInstance.CommandsToDispatch;
        }
Example #10
0
        public void Process_Faults_Should_be_deserializable()
        {
            //CoffeMakeFailedEvent
            var coffeMakeFailedEvent = new CoffeMakeFailedEvent(Guid.NewGuid().ToString(), Guid.NewGuid().ToString());

            CheckDeserialize(coffeMakeFailedEvent, nameof(coffeMakeFailedEvent));

            var undefinedCoffeMachineException = new UndefinedCoffeMachineException();

            CheckDeserialize(undefinedCoffeMachineException, nameof(undefinedCoffeMachineException));

            var processTransitionException = new ProcessTransitionException(coffeMakeFailedEvent, undefinedCoffeMachineException);

            CheckDeserialize(processTransitionException, nameof(processTransitionException));

            var eventExecutionException = new EventExecutionException("test", processTransitionException);

            CheckDeserialize(eventExecutionException, nameof(eventExecutionException));

            var msg = new Akka.Actor.Status.Failure(new AggregateException(eventExecutionException));

            CheckDeserialize(msg, nameof(msg));
        }
        public void When_publishing_start_message()
        {
            var sagaId = Guid.NewGuid();

            _sagaData = new SoftwareProgrammingSagaData(nameof(SoftwareProgrammingSaga.MakingCoffee))
            {
                PersonId = Guid.NewGuid()
            };

            var sagaDataEvent = new SagaCreatedEvent <SoftwareProgrammingSagaData>(_sagaData, sagaId);

            SaveInJournal <SagaDataAggregate <SoftwareProgrammingSagaData> >(sagaId, sagaDataEvent);

            Thread.Sleep(100);
            _coffeMakeFailedEvent = new CoffeMakeFailedEvent(Guid.NewGuid(), Guid.NewGuid(), BusinessDateTime.UtcNow, sagaId);

            GridNode.Transport.Publish(_coffeMakeFailedEvent, new MessageMetadata(_coffeMakeFailedEvent.SourceId));

            //WaitFor<SagaTransitionEvent<SoftwareProgrammingSagaData>>();
            //WaitFor<SagaTransitionEvent<SoftwareProgrammingSagaData>>();
            Thread.Sleep(1000);
            _sagaDataAggregate = LoadAggregate <SagaDataAggregate <SoftwareProgrammingSagaData> >(sagaId);
        }
Example #12
0
        public async Task Given_default_policy()
        {
            var startEvent = new GotTiredEvent(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), Guid.NewGuid().ToString());

            var resTask = Node.NewDebugWaiter()
                          .Expect <ProcessReceivedMessage <SoftwareProgrammingState> >()
                          .Create()
                          .SendToProcessManagers(startEvent, MessageMetadata.New(startEvent.Id, null, null));

            var processId = (await resTask).Message <ProcessReceivedMessage <SoftwareProgrammingState> >().SourceId;

            var continueEvent = new CoffeMakeFailedEvent(processId, startEvent.PersonId, BusinessDateTime.UtcNow, processId);

            //to avoid racy state receiving expected message from processing GotTiredEvent
            await Node.NewDebugWaiter()
            .Expect <ProcessReceivedMessage <SoftwareProgrammingState> >(e => e.MessageId == continueEvent.Id)
            .Create()
            .SendToProcessManagers(continueEvent, processId);

            Log.Info("Testcase enforce additional snapshot save & delete, will kill process manager");
            await Node.KillProcessManager <SoftwareProgrammingProcess, SoftwareProgrammingState>(processId);

            var snapshots = await AggregateSnapshotRepository.New(AutoTestNodeDbConfiguration.Default.JournalConnectionString,
                                                                  AggregateFactory.Default)
                            .Load <ProcessStateAggregate <SoftwareProgrammingState> >(processId);

            //Snapshot_should_be_saved_one_time
            Assert.Single(snapshots);
            //Restored_process_state_should_have_correct_ids
            Assert.True(snapshots.All(s => s.Payload.Id == processId));
            //Snapshot_should_have_parameters_from_first_event = created event
            Assert.Equal(nameof(SoftwareProgrammingProcess.Coding),
                         snapshots.First().Payload.State.CurrentStateName);
            //All_snapshots_should_not_have_uncommited_events
            Assert.Empty(snapshots.SelectMany(s => s.Payload.GetEvents()));
        }
Example #13
0
 public void Handle(CoffeMakeFailedEvent msg)
 {
     TransitState(msg);
 }
        public async Task Given_default_policy()
        {
            var startEvent = new GotTiredEvent(Guid.NewGuid().ToString(), Guid.NewGuid().ToString(), Guid.NewGuid().ToString());

            var res = await Node.NewDebugWaiter()
                      .Expect <ProcessManagerCreated <SoftwareProgrammingState> >()
                      .Create()
                      .SendToProcessManagers(startEvent);

            var processId = res.Message <ProcessManagerCreated <SoftwareProgrammingState> >()
                            .SourceId;

            var continueEvent = new CoffeMakeFailedEvent(processId, startEvent.PersonId, BusinessDateTime.UtcNow, processId);

            await Node.NewDebugWaiter()
            .Expect <ProcessReceivedMessage <SoftwareProgrammingState> >()
            .Create()
            .SendToProcessManagers(continueEvent);

            var continueEventB =
                new Fault <GoSleepCommand>(new GoSleepCommand(startEvent.PersonId, startEvent.LovelySofaId),
                                           new Exception(),
                                           typeof(object),
                                           processId,
                                           BusinessDateTime.Now);

            await Node.NewDebugWaiter()
            .Expect <ProcessReceivedMessage <SoftwareProgrammingState> >()
            .Create()
            .SendToProcessManagers(continueEventB);

            await Node.KillProcessManager <SoftwareProgrammingProcess, SoftwareProgrammingState>(continueEvent.ProcessId);

            Version <ProcessStateAggregate <SoftwareProgrammingState> >[] snapshots = null;


            AwaitAssert(() =>
            {
                snapshots = new AggregateSnapshotRepository(AutoTestNodeDbConfiguration.Default.JournalConnectionString,
                                                            AggregateFactory.Default,
                                                            AggregateFactory.Default)
                            .Load <ProcessStateAggregate <SoftwareProgrammingState> >(processId)
                            .Result;

                //saving on each message, maximum on each command
                //Snapshots_should_be_saved_two_times
                //4 events in total, two saves of snapshots due to policy saves on each two events
                //1 event and 3
                Assert.Equal(2, snapshots.Length);


                //First_snapshot_should_have_state_from_first_event
                Assert.Equal(nameof(SoftwareProgrammingProcess.Coding),
                             snapshots.First()
                             .Payload.State.CurrentStateName);
                //Last_snapshot_should_have_parameters_from_last_command()
                Assert.Equal(nameof(SoftwareProgrammingProcess.Sleeping),
                             snapshots.Last()
                             .Payload.State.CurrentStateName);
                //Restored_process_state_should_have_correct_ids
                Assert.True(snapshots.All(s => s.Payload.Id == processId));
                //All_snapshots_should_not_have_uncommited_events()
                Assert.Empty(snapshots.SelectMany(s => s.Payload.GetEvents()));
            },
                        TimeSpan.FromSeconds(10),
                        TimeSpan.FromSeconds(1));
        }