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(), _ => { }); }
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; } }
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); }
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); }
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(); }
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); }
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(); }
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()); }
#pragma warning disable 1591 // Xml Comments public void Close(ISaga saga) { var sagaHolder = _sagaConverter.ToSagaHolder(saga); _entityContext.Delete(sagaHolder); _entityContext.Commit(); }
private static void CheckIfSagaIsDeleted(ISaga saga) { if (saga.HasError() && saga.ExecutionState.CurrentState == new SagaStartState().GetStateName()) { saga.ExecutionState.IsDeleted = true; } }
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); } }
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); }
public SagaHolder ToSagaHolder(ISaga saga) { var sagaHolder = new SagaHolder(); Populate(sagaHolder, saga); return(sagaHolder); }
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); }
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); } } } }
static void ThrowIfTransitionNotAllowed(ISaga saga, Type to) { if (saga.CurrentChapter != null && !ChapterTransitionHelper.CanTransition(saga.CurrentChapter.GetType(), to)) { throw new ChapterTransitionNotAllowedException(saga.CurrentChapter.GetType(), to); } }
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); }
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); }
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; } }
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); } }
void LogIfSagaIsFinished(ISaga saga) { if (saga.Completed) { logger.Debug(string.Format("{0} {1} has completed.", saga.GetType().FullName, saga.Entity.Id)); } }
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); }
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; }
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 ); }
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}; }
/// <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); }
public CommandResult Handle(ISaga saga, ICommand command) { throw new System.NotImplementedException(); }
void NotifyTimeoutManagerThatSagaHasCompleted(ISaga saga) { Bus.ClearTimeoutsFor(saga.Entity.Id); }
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) ); }
public SagaHolder ToSagaHolder(ISaga saga) { var sagaHolder = new SagaHolder(); Populate(sagaHolder, saga); return sagaHolder; }
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; }
#pragma warning disable 1591 // Xml Comments public void Close(ISaga saga) { }
public void Catalogue(ISaga saga) { }
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; }
#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()); }
public void Close(ISaga saga) { HttpContext.Current.Session.Remove(saga.Id.ToString()); }
public void Catalogue(ISaga saga) { var sagaHolder = _sagaConverter.ToSagaHolder(saga); HttpContext.Current.Session[saga.Id.ToString()] = sagaHolder; }