protected virtual void Save(ISaga saga, IEvent by, string bucketId = Bucket.Default)
        {
            if (string.IsNullOrWhiteSpace(saga.Id)) throw new ApplicationException("Saga.Id is not specified");
            if (OnSavedHook != null) OnSavedHook(this, saga, by);
            var byTyped = by as DomainEvent;
            foreach (IEvent e in saga.GetUncommittedEvents())
            {
                var evt = e as DomainEvent;
                if (evt != null)
                {
                    evt.SagaId = new Guid(saga.Id);

                    if (byTyped != null)
                    {
                        if (!evt.TenantId.HasValue) evt.TenantId = byTyped.TenantId;
                        if (!evt.IssuedBy.HasValue) evt.IssuedBy = byTyped.IssuedBy;
                    }
                }
            }
            foreach (DomainCommand cmd in saga.GetUndispatchedMessages())
            {
                cmd.SagaId = new Guid(saga.Id);

                if (byTyped != null)
                {
                    if (!cmd.TenantId.HasValue) cmd.TenantId = byTyped.TenantId;
                    if (!cmd.IssuedBy.HasValue) cmd.IssuedBy = byTyped.IssuedBy;
                }
            }
            sagas.Save(bucketId, saga, Guid.NewGuid(), _ => { });
        }
Beispiel #2
0
        public async Task WHEN_compensationThrowsErrorOnUpdate_THEN_sagaShouldBeInValidState()
        {
            // given
            ISaga saga = await sagaCoordinator.
                         Publish(new ValidCreatedEvent());

            // when
            await Assert.ThrowsAsync <TestCompensationException>(async() =>
            {
                await sagaCoordinator.Publish(new InvalidCompensationEvent()
                {
                    ID = saga.Data.ID
                });
            });

            // then
            ISaga persistedSaga = await sagaPersistance.
                                  Get(saga.Data.ID);

            persistedSaga.ShouldNotBeNull();
            persistedSaga.ExecutionState.CurrentStep.ShouldBe(null);
            persistedSaga.ExecutionState.CurrentState.ShouldBe(nameof(StateCreated));
            persistedSaga.ExecutionState.CurrentError.ShouldNotBeNull();
            persistedSaga.Data.ID.ShouldBe(saga.Data.ID);

            persistedSaga.ExecutionState.History.ShouldContain(item =>
                                                               item.CompensationData != null && item.StepName == "InvalidCompensationEventStep1");

            persistedSaga.ExecutionState.History.ShouldContain(item =>
                                                               item.CompensationData != null && item.StepName == "InvalidCompensationEventStep2");

            persistedSaga.ExecutionState.History.ShouldContain(item =>
                                                               item.CompensationData != null && item.StepName == "InvalidCompensationEventStep3");
        }
 public void Save(ISaga saga)
 {
     lock (StoreLocker)
     {
         Store[saga.CorrelationId] = saga;
     }
 }
Beispiel #4
0
        public async Task WHEN_eventIsSend_THEN_sagaShouldMoveToValidState()
        {
            // given
            ISaga saga = await sagaCoordinator.
                         Publish(new SendCreateEvent());

            // when
            await sagaCoordinator.
            Publish(new TestSendActionEvent()
            {
                ID = saga.Data.ID
            });

            // then
            ISaga orgSaga = await sagaPersistance.
                            Get(saga.Data.ID);

            SendTestsData data = orgSaga.Data as SendTestsData;

            ISaga createdSaga = await sagaPersistance.
                                Get(data.CreatedSagaID);

            orgSaga.ShouldNotBeNull();
            orgSaga.ExecutionState.CurrentState.ShouldBe(nameof(AfterInit));
            orgSaga.ExecutionState.CurrentStep.ShouldBe(null);

            createdSaga.ShouldNotBeNull();
            createdSaga.ExecutionState.CurrentState.ShouldBe(nameof(AkternativeInit));
            createdSaga.ExecutionState.CurrentStep.ShouldBe(null);
        }
        public async Task WHEN_sendingMultipleEventToRunningSaga_THEN_shouldThrowSagaIsBusyException()
        {
            // given
            ISaga saga = await sagaCoordinator.
                         Publish(new CreatedEvent());

            await sagaCoordinator.
            WaitForIdle(saga.Data.ID);

            // when
            await sagaCoordinator.
            Publish(new UpdatedEvent()
            {
                ID = saga.Data.ID
            });

            // then
            await Assert.ThrowsAsync <SagaIsBusyException>(async() =>
            {
                await sagaCoordinator.
                Publish(new UpdatedEvent()
                {
                    ID = saga.Data.ID
                });
            });
        }
        public async Task WHEN_someNextEvent_THEN_sagaShouldBeInValidState()
        {
            // given
            ISaga newSagaState = await sagaCoordinator.
                                 Publish(new OrderCreatedEvent());

            ISagaEvent skompletowanoEvent = new OrderCompletedEvent()
            {
                ID = newSagaState.Data.ID
            };

            // then
            await sagaCoordinator.
            Publish(skompletowanoEvent);

            // then
            ISaga persistedSaga = await sagaPersistance.
                                  Get(newSagaState.Data.ID);

            persistedSaga.ShouldNotBeNull();
            persistedSaga.ExecutionState.CurrentState.ShouldBe(nameof(StateCompleted));
            persistedSaga.ExecutionState.CurrentStep.ShouldBe(null);
            persistedSaga.ExecutionState.History.ShouldNotContain(step => step.StepName == "OrderCreatedEventStep0" && step.CompensationData == null && step.HasSucceeded());
            persistedSaga.ExecutionState.History.ShouldNotContain(step => step.StepName == "OrderCreatedEventStep1" && step.CompensationData == null && step.HasSucceeded());
            persistedSaga.ExecutionState.History.ShouldContain(step => step.StepName == "OrderCompletedEventStep1" && step.CompensationData == null && step.HasSucceeded());
            persistedSaga.ExecutionState.History.ShouldContain(step => step.StepName == "email" && step.CompensationData == null && step.HasSucceeded());
            persistedSaga.ExecutionState.History.ShouldContain(step => step.StepName == "SendMessageToTheManagerEventStep" && step.CompensationData == null && step.HasSucceeded());
            persistedSaga.ExecutionState.History.ShouldContain(step => step.StepName == "OrderCourierEventStep" && step.CompensationData == null && step.HasSucceeded());
            persistedSaga.ExecutionState.History.Count.ShouldBe(6);
        }
Beispiel #7
0
        private async Task UpdateSagaAsync <TMessage>(TMessage message, ISaga saga, ISagaState state)
            where TMessage : class
        {
            var sagaType = saga.GetType();

            var updatedSagaData = sagaType.GetProperty(nameof(ISaga <object> .Data))?.GetValue(saga);

            state.Update(saga.State, updatedSagaData);
            var logData = SagaLogData.Create(saga.Id, sagaType, message);

            if (_configuration.AllowConcurrentWrites)
            {
                var persistenceTasks = new[]
                {
                    _repository.WriteAsync(state),
                    _log.WriteAsync(logData)
                };

                await Task.WhenAll(persistenceTasks).ConfigureAwait(false);
            }
            else
            {
                await _repository.WriteAsync(state);

                await _log.WriteAsync(logData);
            }
        }
        public async Task WHEN_invalidEvent_THEN_sagaShouldIgnoreThatEvent()
        {
            // given
            ISaga newSagaState = await sagaCoordinator.
                                 Publish(new OrderCreatedEvent());

            ISagaEvent invalidEvent = new OrderSendEvent()
            {
                ID = newSagaState.Data.ID
            };

            // then
            await Assert.ThrowsAsync <SagaInvalidEventForStateException>(() =>
                                                                         // when
                                                                         sagaCoordinator.
                                                                         Publish(invalidEvent)
                                                                         );

            // then
            ISaga persistedSaga = await sagaPersistance.
                                  Get(newSagaState.Data.ID);

            persistedSaga.ShouldNotBeNull();
            persistedSaga.ExecutionState.CurrentState.ShouldBe(nameof(StateCreated));
            persistedSaga.ExecutionState.CurrentStep.ShouldBe(null);
            // blad nie powinien zmienic stanu sagi
            persistedSaga.ExecutionState.History.ShouldContain(step => step.StepName == "OrderCreatedEventStep1" && step.CompensationData == null && step.HasSucceeded());
            persistedSaga.ExecutionState.History.Count.ShouldBe(3);
        }
Beispiel #9
0
        public async Task WHEN_stoppedSagaIsResumed_THEN_sagaShouldCompensateAndExecuteLastStep()
        {
            // given
            ResumeSagaSettings.StopSagaExecution = true;
            ISaga saga = await sagaCoordinator.Publish(new CreateEvent());

            await Assert.ThrowsAsync <SagaStopException>(async() =>
            {
                await sagaCoordinator.Publish(new ResumeSagaUpdateEvent()
                {
                    ID = saga.Data.ID
                });
            });

            ResumeSagaSettings.StopSagaExecution = false;
            //await sagaLocking.Banish(saga.Data.ID);

            // when
            await sagaCoordinator.
            Resume(saga.Data.ID);

            // then
            ISaga persistedSaga = await sagaPersistance.Get(saga.Data.ID);

            persistedSaga.ExecutionState.History.Where(s => s.ResumeData != null).Count().ShouldBe(1);
            persistedSaga.ExecutionState.History.Where(s => s.CompensationData != null).Count().ShouldBe(0);
            persistedSaga.ExecutionState.History.Where(s => s.ExecutionData != null).Count().ShouldBe(3);
            persistedSaga.IsIdle().ShouldBeTrue();
        }
Beispiel #10
0
        public async Task WHEN_sagaIsStoppedOnCreation_THEN_resumingSagaToInitState()
        {
            // given
            Guid id = Guid.NewGuid();

            ResumeSagaSettings.StopSagaExecution = true;
            await Assert.ThrowsAsync <SagaStopException>(async() =>
            {
                await sagaCoordinator.Publish(new CreateWithBreakEvent()
                {
                    ID = id
                });
            });

            // when
            ResumeSagaSettings.StopSagaExecution = false;
            await sagaCoordinator.
            Resume(id);

            // then
            ISaga persistedSaga = await sagaPersistance.Get(id);

            persistedSaga.IsIdle().ShouldBeTrue();
            persistedSaga.ExecutionState.CurrentState.ShouldBe(nameof(InitState));
            persistedSaga.ExecutionState.History.Count.ShouldBe(3);
        }
Beispiel #11
0
        public async Task WHEN_stoppedSagaIsResumed_THEN_sagaShouldMoveToValidState()
        {
            // given
            ResumeSagaSettings.StopSagaExecution = true;
            ISaga saga = await sagaCoordinator.Publish(new CreateEvent());

            await Assert.ThrowsAsync <SagaStopException>(async() =>
            {
                await sagaCoordinator.Publish(new ResumeSagaUpdateEvent()
                {
                    ID = saga.Data.ID
                });
            });

            ResumeSagaSettings.StopSagaExecution = false;
            //await sagaLocking.Banish(saga.Data.ID);

            // when
            await sagaCoordinator.
            Resume(saga.Data.ID);

            // then
            ISaga persistedSaga = await sagaPersistance.Get(saga.Data.ID);

            persistedSaga.IsIdle().ShouldBeTrue();
        }
Beispiel #12
0
        public async Task WHEN_sagaIsStoppedOnInvalidCreation_THEN_resumingShouldRemoveSaga()
        {
            // given
            Guid id = Guid.NewGuid();

            ResumeSagaSettings.StopSagaExecution = true;
            await Assert.ThrowsAsync <SagaStopException>(async() =>
            {
                await sagaCoordinator.Publish(new CreateWithErrorEvent()
                {
                    ID = id
                });
            });

            //await sagaLocking.Banish(id);

            // when
            await Assert.ThrowsAsync <Exception>(async() =>
            {
                ResumeSagaSettings.StopSagaExecution = false;
                await sagaCoordinator.
                Resume(id);
            });

            // then
            ISaga persistedSaga = await sagaPersistance.Get(id);

            persistedSaga.IsIdle().ShouldBeTrue();
            persistedSaga.ExecutionState.IsDeleted.ShouldBeTrue();
            persistedSaga.ExecutionState.CurrentState.ShouldBe("");
            persistedSaga.ExecutionState.History.Count.ShouldBe(3);
        }
        public async Task Execute(
            IServiceProvider serviceProvider,
            IExecutionContext context,
            ISagaEvent @event,
            IStepData stepData)
        {
            if (typeof(TExecuteEvent) == typeof(EmptyEvent))
            {
                return;
            }

            ISagaInternalCoordinator sagaCoordinator = serviceProvider.
                                                       GetRequiredService <ISagaCoordinator>() as ISagaInternalCoordinator;

            IExecutionContext <TSagaData> contextForAction =
                (IExecutionContext <TSagaData>)context;

            TExecuteEvent executionEvent = new TExecuteEvent();

            if (ActionDelegate != null)
            {
                await ActionDelegate(contextForAction, executionEvent);
            }

            ISaga newSaga = await sagaCoordinator.
                            Publish(executionEvent, contextForAction.ExecutionValues, contextForAction.Data.ID, new SagaRunOptions());
        }
Beispiel #14
0
#pragma warning disable 1591 // Xml Comments
        public void Close(ISaga saga)
        {
            var sagaHolder = _sagaConverter.ToSagaHolder(saga);

            _entityContext.Delete(sagaHolder);
            _entityContext.Commit();
        }
Beispiel #15
0
 private static void CheckIfSagaIsDeleted(ISaga saga)
 {
     if (saga.HasError() && saga.ExecutionState.CurrentState == new SagaStartState().GetStateName())
     {
         saga.ExecutionState.IsDeleted = true;
     }
 }
Beispiel #16
0
        private async Task ExecuteStep(ISaga saga, ISagaStep sagaStep, StepData stepData)
        {
            ISagaEvent @event = stepData.Event;

            if (@event is EmptyEvent)
            {
                @event = null;
            }

            Type executionContextType =
                typeof(ExecutionContext <>).ConstructGenericType(saga.Data.GetType());

            IExecutionContext context = (IExecutionContext)ActivatorUtilities.CreateInstance(serviceProvider,
                                                                                             executionContextType, saga.Data, saga.ExecutionInfo, saga.ExecutionState, saga.ExecutionValues, stepData.ExecutionValues);

            if (saga.ExecutionState.IsResuming)
            {
                await sagaStep.Compensate(serviceProvider, context, @event, stepData);
            }
            else if (saga.ExecutionState.IsCompensating)
            {
                await sagaStep.Compensate(serviceProvider, context, @event, stepData);
            }
            else
            {
                await sagaStep.Execute(serviceProvider, context, @event, stepData);
            }
        }
Beispiel #17
0
 public static Type GetSagaDataType(this ISaga saga)
 => saga
 .GetType()
 .GetInterfaces()
 .FirstOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(ISaga <>))
 ?.GetGenericArguments()
 .FirstOrDefault();
        public async Task Resume(Guid id)
        {
            List <string> invalidModels = new List <string>();

            ISaga saga = await sagaPersistance.Get(id);

            ISagaModel model = sagaRegistrator.FindModelByName(saga.ExecutionInfo.ModelName);

            if (model == null)
            {
                invalidModels.Add(saga.ExecutionInfo.ModelName);
            }

            if (invalidModels.Count > 0)
            {
                throw new Exception($"Saga models {string.Join(", ", invalidModels.Distinct().ToArray())} not found");
            }

            await ExecuteSaga(
                new EmptyEvent(),
                model,
                saga,
                saga.Data.ID,
                null,
                true);
        }
Beispiel #19
0
        public SagaHolder ToSagaHolder(ISaga saga)
        {
            var sagaHolder = new SagaHolder();

            Populate(sagaHolder, saga);
            return(sagaHolder);
        }
Beispiel #20
0
        public TSaga GetById <TSaga>(string bucketId, Guid sagaId) where TSaga : class, ISaga, new()
        {
            ISaga saga = this.GetSaga <TSaga>();

            ApplyEventsToSaga(this.OpenStream(bucketId, sagaId), saga);
            return(saga as TSaga);
        }
        /// <summary>
        /// Dispatches the message to the saga and, based on the saga's state
        /// persists it or notifies of its completion to interested parties.
        /// </summary>
        /// <param name="saga"></param>
        /// <param name="message"></param>
        /// <param name="sagaIsPersistent"></param>
        protected virtual void HaveSagaHandleMessage(ISaga saga, object message, bool sagaIsPersistent)
        {
            if (message.IsTimeoutMessage())
            {
                DispatchTimeoutMessageToSaga(saga, message);
            }
            else
            {
                CallHandleMethodOnSaga(saga, message);
            }

            if (!saga.Completed)
            {
                if (!sagaIsPersistent)
                {
                    Persister.Save(saga.Entity);
                }
                else
                {
                    Persister.Update(saga.Entity);
                }
            }
            else
            {
                if (sagaIsPersistent)
                {
                    Persister.Complete(saga.Entity);
                }

                NotifyTimeoutManagerThatSagaHasCompleted(saga);
            }

            LogIfSagaIsFinished(saga);
        }
Beispiel #22
0
        void DeserializeChapters(SagaHolder sagaHolder, ISaga saga, Type currentChapterType)
        {
            if (!string.IsNullOrEmpty(sagaHolder.SerializedChapters))
            {
                var chapterHolders = new List <ChapterHolder>();
                _serializer.FromJson(chapterHolders, sagaHolder.SerializedChapters);
                foreach (var chapterHolder in chapterHolders)
                {
                    var chapterType = Type.GetType(chapterHolder.Type);
                    var chapter     = _container.Get(chapterType) as IChapter;

                    if (!string.IsNullOrEmpty(chapterHolder.SerializedChapter))
                    {
                        _serializer.FromJson(chapter, chapterHolder.SerializedChapter);
                    }

                    saga.AddChapter(chapter);

                    if (currentChapterType != null &&
                        chapterType == currentChapterType)
                    {
                        saga.SetCurrentChapter(chapter);
                    }
                }
            }
        }
Beispiel #23
0
 static void ThrowIfTransitionNotAllowed(ISaga saga, Type to)
 {
     if (saga.CurrentChapter != null && !ChapterTransitionHelper.CanTransition(saga.CurrentChapter.GetType(), to))
     {
         throw new ChapterTransitionNotAllowedException(saga.CurrentChapter.GetType(), to);
     }
 }
Beispiel #24
0
        public async Task WHEN_sendValidStateToSagaWithError_THEN_errorShouldBeNull()
        {
            // given
            ISaga saga = await sagaCoordinator.
                         Publish(new ValidCreatedEvent());

            await Assert.ThrowsAsync <TestCompensationException>(async() =>
            {
                await sagaCoordinator.Publish(new InvalidCompensationEvent()
                {
                    ID = saga.Data.ID
                });
            });

            // when
            await sagaCoordinator.Publish(new ValidUpdateEvent()
            {
                ID = saga.Data.ID
            });

            // then
            ISaga persistedSaga = await sagaPersistance.
                                  Get(saga.Data.ID);

            persistedSaga.ShouldNotBeNull();
            persistedSaga.ExecutionState.CurrentStep.ShouldBe(null);
            persistedSaga.ExecutionState.CurrentState.ShouldBe(nameof(StateUpdated));
            persistedSaga.ExecutionState.CurrentError.ShouldBeNull();
            persistedSaga.Data.ID.ShouldBe(saga.Data.ID);
        }
Beispiel #25
0
 static void ThrowIfChapterAlreadyExist(ISaga saga, IChapter chapter)
 {
     if (saga.Chapters.Any(s => s.GetType() == chapter.GetType()))
     {
         throw new ChapterAlreadyExistException();
     }
 }
        public async Task WHEN_exceptionAfterWhile_THEN_wholeWhileShouldBeCompensated()
        {
            // given
            ISaga saga = await sagaCoordinator.Publish(new CreateWhileSagaEvent());

            // when
            await Assert.ThrowsAsync <Exception>(async() =>
                                                 await sagaCoordinator.Publish(new Test2Event()
            {
                ID = saga.Data.ID, Counter = 2
            }));

            // then
            ISaga persistedSaga = await sagaPersistance.Get(saga.Data.ID);

            WhileSagaData data = persistedSaga.Data as WhileSagaData;

            data.Counter.ShouldBe(0);
            data.Value.ShouldBe(20);
            data.SecondValue.ShouldBe(1);
            persistedSaga.ExecutionState.History.Count.ShouldBe(
                1 +     // event handler
                3 * 2 + // while + steps
                1 +     // last while check
                1 +     // then
                1);     // exception

            persistedSaga.ExecutionState.History.
            Where(s => s.CompensationData == null).Count().ShouldBe(0);

            persistedSaga.ExecutionState.History.
            Where(s => s.ResumeData != null).Count().ShouldBe(0);
        }
Beispiel #27
0
        public async Task WHEN_afterAsynchronousSagaRun_THEN_sagaShouldBeCompleted()
        {
            // given
            ISagaEvent startEvent = new CreatedEvent();

            ISaga saga = await sagaCoordinator.
                         Publish(startEvent);

            // when
            await sagaCoordinator.
            WaitForIdle(saga.Data.ID);

            // then
            ISaga persistedSaga = await sagaPersistance.
                                  Get(saga.Data.ID);

            persistedSaga.ShouldNotBeNull();
            persistedSaga.ExecutionState.CurrentStep.ShouldBe(new SagaFinishState().Name);
            persistedSaga.ExecutionState.CurrentState.ShouldBe(new SagaFinishState().Name);
            persistedSaga.Data.ID.ShouldBe(saga.Data.ID);
            persistedSaga.ExecutionState.History.ShouldContain(step => step.StepName == "CreatedEventStep0" && step.CompensationData == null && step.HasSucceeded());
            persistedSaga.ExecutionState.History.ShouldContain(step => step.StepName == "CreatedEventStep1" && step.CompensationData == null && step.HasSucceeded());
            persistedSaga.ExecutionState.History.ShouldContain(step => step.StepName == "CreatedEventStep2" && step.CompensationData == null && step.HasSucceeded());
            persistedSaga.ExecutionState.History.Count.ShouldBe(4);
        }
        public async Task Set(ISaga saga)
        {
            await weakInMemorySagaPersistance.Set(saga);

            using (SagaStore sagaStore = new SagaStore(sqlServerConnection, dateTimeProvider, sqlServerOptions))
                await sagaStore.Store(saga);
        }
        public async Task <ISaga> Publish(ISagaEvent @event, IDictionary <string, object> executionValues)
        {
            Type   eventType = @event.GetType();
            SagaID sagaId    = SagaID.From(@event.ID);

            ISagaModel model = sagaRegistrator.
                               FindModelForEventType(eventType);

            if (model == null)
            {
                throw new SagaEventNotRegisteredException(eventType);
            }

            ISaga newSaga = await CreateNewSagaIfRequired(model, sagaId, eventType);

            try
            {
                return(await ExecuteSaga(
                           @event,
                           model,
                           newSaga,
                           SagaID.From(newSaga?.Data?.ID ?? sagaId.Value),
                           executionValues,
                           false));
            }
            catch
            {
                //if (newSaga != null)
                //    await sagaPersistance.Remove(newSaga.Data.ID);

                throw;
            }
        }
Beispiel #30
0
        private string CalculateNextStepName(
            ISaga saga,
            ISagaStep sagaStep,
            ISagaAction sagaAction,
            StepData stepData,
            Exception executionError)
        {
            if (saga.ExecutionState.IsBreaked)
            {
                return(null);
            }

            if (executionError != null)
            {
                saga.ExecutionState.IsResuming     = false;
                saga.ExecutionState.IsCompensating = true;
                saga.ExecutionState.CurrentError   = executionError.ToSagaStepException();
                return(CalculateNextCompensationStep(saga));
            }
            else
            {
                string nextStepName = CalculateNextStep(saga, sagaAction, sagaStep, stepData);
                saga.ExecutionState.IsResuming = false;
                return(nextStepName);
            }
        }
Beispiel #31
0
 void LogIfSagaIsFinished(ISaga saga)
 {
     if (saga.Completed)
     {
         logger.Debug(string.Format("{0} {1} has completed.", saga.GetType().FullName, saga.Entity.Id));
     }
 }
Beispiel #32
0
        public ChapterTransition TransitionTo <T>(ISaga saga) where T : IChapter
        {
            var chapterTransition = new ChapterTransition();

            if (saga.CurrentChapter != null && saga.CurrentChapter.GetType().Equals(typeof(T)))
            {
                saga.CurrentChapter.OnTransitionedTo();
                chapterTransition.TransitionedTo = (T)saga.CurrentChapter;
                return(chapterTransition);
            }

            chapterTransition.ValidationResults = _chapterValidationService.Validate(saga.CurrentChapter);

            if (chapterTransition.Invalid)
            {
                return(chapterTransition);
            }

            ThrowIfTransitionNotAllowed(saga, typeof(T));
            var chapter = GetExistingChapterIfAnyFrom(saga, typeof(T));

            if (chapter == null)
            {
                chapter = _container.Get <T>();
                saga.AddChapter(chapter);
            }

            saga.SetCurrentChapter(chapter);
            chapter.OnTransitionedTo();
            _librarian.Catalogue(saga);

            chapterTransition.TransitionedTo = (T)chapter;
            return(chapterTransition);
        }
Beispiel #33
0
        public ActiveSagaInstance(ISaga saga, LoadedMessageHandlers.LoadedHandler messageHandler, LogicalMessage message)
        {
            Instance = saga;
            SagaType = saga.GetType();
            MessageToProcess = message;
            Handler = messageHandler;

            //default the invocation to disabled until we have a entity attached
            Handler.InvocationDisabled = true;
        }
Beispiel #34
0
        public ICommandContext EstablishForSaga(ISaga saga, ICommand command)
        {
            if (!IsInContext(command))
            {
                var commandContext = _factory.Build(saga,command);

                _currentContext = commandContext;
            }
            return _currentContext;
        }
 public ICommandContext Build(ISaga saga, ICommand command)
 {
     return new SagaCommandContext(
         saga,
         command,
         _executionContextManager.Current,
         _eventStore,
         _uncommittedEventStreamCoordinator,
         _processMethodInvoker,
         _sagaLibrarian
         );
 }
Beispiel #36
0
		public void Catalogue(ISaga saga)
		{
			var sagaHolder = GetExistingIfAny(saga.Id);
			if (sagaHolder == null)
			{
				sagaHolder = _sagaConverter.ToSagaHolder(saga);
				_entityContext.Insert(sagaHolder);
			}
			else
			{
				_sagaConverter.Populate(sagaHolder, saga);
				_entityContext.Update(sagaHolder);
			}
			_entityContext.Commit();
		}
        /// <summary>
        /// Initializes an instance of the <see cref="SagaCommandContext"/> for a saga
        /// </summary>
        /// <param name="saga"><see cref="ISaga"/> to start the context for</param>
        /// <param name="command"><see cref="ICommand"/> that will be applied </param>
        /// <param name="executionContext">A <see cref="IExecutionContext"/> that is the context of execution for the <see cref="ICommand"/></param>
        /// <param name="eventStore">A <see cref="IEventStore"/> that will receive any events generated</param>
        /// <param name="processMethodInvoker">A <see cref="IProcessMethodInvoker"/> for processing events on the <see cref="ISaga"/></param>
        /// <param name="sagaLibrarian">A <see cref="ISagaLibrarian"/> for dealing with the <see cref="ISaga"/> and persistence</param>
        public SagaCommandContext(
            ISaga saga,
            ICommand command,
            IExecutionContext executionContext,
            IEventStore eventStore,
            IProcessMethodInvoker processMethodInvoker,
            ISagaLibrarian sagaLibrarian)
        {
            Command = command;
            ExecutionContext = executionContext;
            _saga = saga;
            _eventStore = eventStore;
            _processMethodInvoker = processMethodInvoker;
            _sagaLibrarian = sagaLibrarian;

            EventStores = new[] {_eventStore, saga};
        }
Beispiel #38
0
 /// <summary>
 /// Initializes an instance of the <see cref="SagaCommandContext"/> for a saga
 /// </summary>
 /// <param name="saga"><see cref="ISaga"/> to start the context for</param>
 /// <param name="command"><see cref="ICommand"/> that will be applied </param>
 /// <param name="executionContext">A <see cref="IExecutionContext"/> that is the context of execution for the <see cref="ICommand"/></param>
 /// <param name="eventStore">A <see cref="IEventStore"/> that will receive any events generated</param>
 /// <param name="uncommittedEventStreamCoordinator">A <see cref="IUncommittedEventStreamCoordinator"/> to use for coordinating a <see cref="UncommittedEventStream"/></param>
 /// <param name="processMethodInvoker">A <see cref="IProcessMethodInvoker"/> for processing events on the <see cref="ISaga"/></param>
 /// <param name="sagaLibrarian">A <see cref="ISagaLibrarian"/> for dealing with the <see cref="ISaga"/> and persistence</param>
 public SagaCommandContext(
     ISaga saga,
     ICommand command,
     IExecutionContext executionContext,
     IEventStore eventStore,
     IUncommittedEventStreamCoordinator uncommittedEventStreamCoordinator,
     IProcessMethodInvoker processMethodInvoker,
     ISagaLibrarian sagaLibrarian)
 {
     Command = command;
     ExecutionContext = executionContext;
     _saga = saga;
     _eventStore = eventStore;
     _uncommittedEventStreamCoordinator = uncommittedEventStreamCoordinator;
     _processMethodInvoker = processMethodInvoker;
     _sagaLibrarian = sagaLibrarian;
 }
		public Task CreateAsync(ISaga saga)
		{
			sagas.Add(saga.Id, saga);

			return Task.FromResult(0);
		}
		public Task UpdateAsync(ISaga saga)
		{
			return Task.FromResult(0);
		}
		public Task CompleteAsync(ISaga saga)
		{
			sagas.Remove(saga.Id);

			return Task.FromResult(0);
		}
Beispiel #42
0
 public CommandResult Handle(ISaga saga, ICommand command)
 {
     throw new System.NotImplementedException();
 }
 void NotifyTimeoutManagerThatSagaHasCompleted(ISaga saga)
 {
     Bus.ClearTimeoutsFor(saga.Entity.Id);
 }
Beispiel #44
0
#pragma warning disable 1591 // Xml Comments
        public void Close(ISaga saga)
		{
			var sagaHolder = _sagaConverter.ToSagaHolder(saga);
			_entityContext.Delete(sagaHolder);
			_entityContext.Commit();
		}
Beispiel #45
0
		void DeserializeChapters(SagaHolder sagaHolder, ISaga saga, Type currentChapterType)
		{
			if (!string.IsNullOrEmpty(sagaHolder.SerializedChapters))
			{
				var chapterHolders = new List<ChapterHolder>();
				_serializer.FromJson(chapterHolders,sagaHolder.SerializedChapters);
				foreach (var chapterHolder in chapterHolders)
				{
					var chapterType = Type.GetType(chapterHolder.Type);
					var chapter = _container.Get(chapterType) as IChapter;

					if (!string.IsNullOrEmpty(chapterHolder.SerializedChapter))
						_serializer.FromJson(chapter, chapterHolder.SerializedChapter);

					saga.AddChapter(chapter);

					if (currentChapterType != null &&
						chapterType == currentChapterType)
						saga.SetCurrentChapter(chapter);
				}
			}
		}
 public static void Save(this ISagaRepository repository, ISaga saga, Guid commitId, object sourceMessage)
 {
     repository.Save(saga, commitId, (d) => Add_Source_Message_To_Headers(d, sourceMessage) );
 }
Beispiel #47
0
		public SagaHolder ToSagaHolder(ISaga saga)
		{
			var sagaHolder = new SagaHolder();
			Populate(sagaHolder, saga);
			return sagaHolder;
		}
Beispiel #48
0
		public void Populate(SagaHolder sagaHolder, ISaga saga)
		{
			sagaHolder.Id = saga.Id;
			sagaHolder.Name = saga.GetType().Name;
			sagaHolder.Type = saga.GetType().AssemblyQualifiedName;
			sagaHolder.Key = saga.Key;
			sagaHolder.Partition = saga.Partition;
		    sagaHolder.State = saga.CurrentState.ToString();
			sagaHolder.SerializedSaga = _serializer.ToJson(saga, SerializationOptions);
			sagaHolder.UncommittedEvents = _serializer.ToJson(_eventConverter.ToEventHolders(saga.GetUncommittedEvents()));

			var chapterHolders = (from c in saga.Chapters
			                      select GetChapterHolderFromChapter(c)).ToArray();

			sagaHolder.SerializedChapters = _serializer.ToJson(chapterHolders);

			if (saga.CurrentChapter != null)
				sagaHolder.CurrentChapterType = saga.CurrentChapter.GetType().AssemblyQualifiedName;
		}
Beispiel #49
0
#pragma warning disable 1591 // Xml Comments
        public void Close(ISaga saga)
        {
        }
Beispiel #50
0
 public void Catalogue(ISaga saga)
 {
 }
Beispiel #51
0
 protected virtual void SaveSaga(ISaga saga)
 {
     var uncommittedMessages = saga.GetUncommittedChanges();
     sagaStreamPersister.PersistMessages(saga.Id, uncommittedMessages);
     saga.ClearUncommittedChanges();
 }
 public ActiveSagaInstance(ISaga saga)
 {
     Instance = saga;
     SagaType = saga.GetType();
 }
        public ICommandContext EstablishForSaga(ISaga saga, ICommand command)
        {
            if (!IsInContext(command))
            {
                var commandContext = new SagaCommandContext(
                        saga,
                        command,
                        _executionContextManager.Current,
                        _eventStore,
                        _processMethodInvoker,
                        _sagaLibrarian
                    );

                _currentContext = commandContext;
            }
            return _currentContext;
        }
Beispiel #54
0
#pragma warning disable 1591 // Xml Comments
		public CommandResult Handle(ISaga saga, ICommand command)
		{
            return Handle(_commandContextManager.EstablishForSaga(saga,command), command);
		}
 void LogIfSagaIsFinished(ISaga saga)
 {
     if (saga.Completed)
         logger.Debug(string.Format("{0} {1} has completed.", saga.GetType().FullName, saga.Entity.Id));
 }
        IContainSagaData TryLoadSagaEntity(ISaga saga, LogicalMessage message)
        {
            var sagaType = saga.GetType();

            var sagaEntityType = Features.Sagas.GetSagaEntityTypeForSagaType(sagaType);

            var finders = GetFindersFor(message.MessageType, sagaEntityType);

            foreach (var finder in finders)
            {
                var sagaEntity = UseFinderToFindSaga(finder, message.Instance);

                if (sagaEntity != null)
                    return sagaEntity;
            }

            return null;
        }
 void NotifyTimeoutManagerThatSagaHasCompleted(ISaga saga)
 {
     MessageDeferrer.ClearDeferredMessages(Headers.SagaId, saga.Entity.Id.ToString());
 }
Beispiel #58
0
		public void Close(ISaga saga)
		{
			HttpContext.Current.Session.Remove(saga.Id.ToString());
		}
Beispiel #59
0
		public void Catalogue(ISaga saga)
		{
			var sagaHolder = _sagaConverter.ToSagaHolder(saga);
			HttpContext.Current.Session[saga.Id.ToString()] = sagaHolder;
		}