/// <summary>
        /// Initializes a new instance of the <see cref="TransactionStepAdapter<TStepIdTo, TDataTo, TStepIdFrom, TDataFrom>"/>class.
        /// </summary>
        /// <param name="original">The original step.</param>
        /// <param name="stepConverter">The step converter.</param>
        /// <param name="reverseStepConverter">The reversed step converter.</param>
        /// <param name="dataConverter">The data converter.</param>
        public TransactionStepAdapter(
            ITransactionStep <TStepIdFrom, TDataFrom> original,
            Func <TStepIdFrom, TStepIdTo> stepConverter,
            Func <TStepIdTo, TStepIdFrom> reverseStepConverter,
            Func <TDataTo, TDataFrom> dataConverter)
        {
            this.original             = original ?? throw new ArgumentNullException(nameof(original));
            this.stepConverter        = stepConverter ?? throw new ArgumentNullException(nameof(stepConverter));
            this.reverseStepConverter = reverseStepConverter ?? throw new ArgumentNullException(nameof(reverseStepConverter));
            this.dataConverter        = dataConverter ?? throw new ArgumentNullException(nameof(dataConverter));
            this.stepAction           = this.original.StepAction == null
                               ? null
                               : new Action <TDataTo, IStepTransactionSessionInfo <TStepIdTo> >((data, info) => this.original.StepAction(this.dataConverter(data), new TransactionSessionInfoAdapter <TStepIdTo, TStepIdFrom>(info, null, null, this.stepConverter, this.reverseStepConverter)));
            this.undoAction = this.original.UndoAction == null
                               ? null
                               : new Action <TDataTo, IUndoTransactionSessionInfo <TStepIdTo> >((data, info) => this.original.UndoAction(this.dataConverter(data), new TransactionSessionInfoAdapter <TStepIdTo, TStepIdFrom>(null, info, null, this.stepConverter, this.reverseStepConverter)));
            this.postAction = this.original.PostAction == null
                              ? null
                              : new Action <TDataTo, IPostTransactionSessionInfo <TStepIdTo> >((data, info) => this.original.PostAction(this.dataConverter(data), new TransactionSessionInfoAdapter <TStepIdTo, TStepIdFrom>(null, null, info, this.stepConverter, this.reverseStepConverter)));
#if !NET35 && !NOASYNC
            this.asyncStepAction = this.original.AsyncStepAction == null
                                     ? null
                                     : new Func <TDataTo, IStepTransactionSessionInfo <TStepIdTo>, Task>(async(data, info) => await this.original.AsyncStepAction(this.dataConverter(data), new TransactionSessionInfoAdapter <TStepIdTo, TStepIdFrom>(info, null, null, this.stepConverter, this.reverseStepConverter)));
            this.asyncUndoAction = this.original.AsyncUndoAction == null
                                     ? null
                                     : new Func <TDataTo, IUndoTransactionSessionInfo <TStepIdTo>, Task>(async(data, info) => await this.original.AsyncUndoAction(this.dataConverter(data), new TransactionSessionInfoAdapter <TStepIdTo, TStepIdFrom>(null, info, null, this.stepConverter, this.reverseStepConverter)));
            this.asyncPostAction = this.original.AsyncPostAction == null
                                     ? null
                                     : new  Func <TDataTo, IPostTransactionSessionInfo <TStepIdTo>, Task>(async(data, info) => await this.original.AsyncPostAction(this.dataConverter(data), new TransactionSessionInfoAdapter <TStepIdTo, TStepIdFrom>(null, null, info, this.stepConverter, this.reverseStepConverter)));
#endif
        }
Example #2
0
 /// <summary>
 /// Inserts a step at an index.
 /// </summary>
 /// <param name="index">The index.</param>
 /// <param name="step">The step.</param>
 public void InsertAtIndex(int index, ITransactionStep <TStepId, TData> step)
 {
     lock (this.syncLock)
     {
         this.AssertCanAddStep();
         this.steps.Insert(index, step);
     }
 }
Example #3
0
 /// <summary>
 /// Adds a step.
 /// </summary>
 /// <param name="step">The step to add.</param>
 /// <returns>The definition.</returns>
 public void Add(ITransactionStep <TStepId, TData> step)
 {
     lock (this.syncLock)
     {
         this.AssertCanAddStep();
         this.steps.Add(step.Validate());
     }
 }
 /// <summary>
 /// Creates an adapter for the step.
 /// </summary>
 /// <typeparam name="TStepIdTo">The type of the destination step id.</typeparam>
 /// <typeparam name="TDataTo">The type of the destination data.</typeparam>
 /// <typeparam name="TStepIdFrom">The type of the original step id.</typeparam>
 /// <typeparam name="TDataFrom">The type of the source data.</typeparam>
 /// <param name="original">The original step.</param>
 /// <param name="stepConverter">The step converter.</param>
 /// <param name="reverseStepConverter">The reversed step converter.</param>
 /// <param name="dataConverter">The data converter.</param>
 /// <returns>The adapter for the step.</returns>
 public static ITransactionStep <TStepIdTo, TDataTo> Adapter <TStepIdTo, TDataTo, TStepIdFrom, TDataFrom>(
     this ITransactionStep <TStepIdFrom, TDataFrom> step,
     Func <TStepIdFrom, TStepIdTo> stepConverter,
     Func <TStepIdTo, TStepIdFrom> reverseStepConverter,
     Func <TDataTo, TDataFrom> dataConverter)
 {
     return(new TransactionStepAdapter <TStepIdTo, TDataTo, TStepIdFrom, TDataFrom>(step, stepConverter, reverseStepConverter, dataConverter));
 }
Example #5
0
 /// <summary>
 /// Inserts a step after a specific step id.
 /// </summary>
 /// <param name="id">The step id.</param>
 /// <param name="step">The comparer.</param>
 /// <param name="idComparer">The step id comparer.</param>
 public void InsertAfter(TStepId id, ITransactionStep <TStepId, TData> step, IEqualityComparer <TStepId> idComparer = null)
 {
     lock (this.syncLock)
     {
         this.AssertCanAddStep();
         int index = this.GetIndex(id, idComparer);
         this.steps.Insert(Math.Max(0, index + 1), step);
     }
 }
Example #6
0
 /// <summary>
 /// Adds an adapter for the step to the transaction.
 /// </summary>
 /// <typeparam name="TStepIdTo">The type of the destination step id.</typeparam>
 /// <typeparam name="TDataTo">The type of the destination data.</typeparam>
 /// <typeparam name="TStepIdFrom">The type of the original step id.</typeparam>
 /// <typeparam name="TDataFrom">The type of the source data.</typeparam>
 /// <param name="step">The original step.</param>
 /// <param name="stepConverter">The step converter.</param>
 /// <param name="reverseStepConverter">The reversed step converter.</param>
 /// <param name="dataConverter">The data converter.</param>
 /// <returns>The transaction.</returns>
 public static ITransaction <TStepIdTo, TDataTo> AddAdapter <TStepIdTo, TDataTo, TStepIdFrom, TDataFrom>(
     this ITransaction <TStepIdTo, TDataTo> transaction,
     ITransactionStep <TStepIdFrom, TDataFrom> step,
     Func <TStepIdFrom, TStepIdTo> stepConverter,
     Func <TStepIdTo, TStepIdFrom> reverseStepConverter,
     Func <TDataTo, TDataFrom> dataConverter)
 {
     return(transaction.Add(step.Adapter(stepConverter, reverseStepConverter, dataConverter)));
 }
Example #7
0
 /// <summary>
 /// Inserts a step adapter at an index.
 /// </summary>
 /// <typeparam name="TStepIdTo">The type of the destination step id.</typeparam>
 /// <typeparam name="TDataTo">The type of the destination data.</typeparam>
 /// <typeparam name="TStepIdFrom">The type of the original step id.</typeparam>
 /// <typeparam name="TDataFrom">The type of the source data.</typeparam>
 /// <param name="index">The index.</param>
 /// <param name="step">The step.</param>
 /// <param name="stepConverter">The step converter.</param>
 /// <param name="reverseStepConverter">The reversed step converter.</param>
 /// <param name="dataConverter">The data converter.</param>
 /// <returns>The transaction.</returns>
 public static ITransaction <TStepIdTo, TDataTo> InsertAdapterAtIndex <TStepIdTo, TDataTo, TStepIdFrom, TDataFrom>(
     this ITransaction <TStepIdTo, TDataTo> transaction,
     int index,
     ITransactionStep <TStepIdFrom, TDataFrom> step,
     Func <TStepIdFrom, TStepIdTo> stepConverter,
     Func <TStepIdTo, TStepIdFrom> reverseStepConverter,
     Func <TDataTo, TDataFrom> dataConverter)
 {
     return(transaction.InsertAtIndex(index, step.Adapter(stepConverter, reverseStepConverter, dataConverter)));
 }
Example #8
0
 public TransactionProcessor(ITransactionRepository transactionRepository, IAccountRepository accountRepository)
 {
     this.transactionSteps =
         new AccountNumberAValidation()
         .SetNext(new AccountNumberBValidation())
         .SetNext(new AccountAValidation(accountRepository))
         .SetNext(new AccountBValidation(accountRepository))
         .SetNext(new TransactionCountValidation(transactionRepository))
         .SetNext(new DuplicateTransactionValidation(transactionRepository))
         .SetNext(new SaveTransaction(transactionRepository));
 }
Example #9
0
 /// <summary>
 /// Inserts a step adapter after a specific step id.
 /// </summary>
 /// <typeparam name="TStepIdTo">The type of the destination step id.</typeparam>
 /// <typeparam name="TDataTo">The type of the destination data.</typeparam>
 /// <typeparam name="TStepIdFrom">The type of the original step id.</typeparam>
 /// <typeparam name="TDataFrom">The type of the source data.</typeparam>
 /// <param name="id">The step id.</param>
 /// <param name="step">The step.</param>
 /// <param name="stepConverter">The step converter.</param>
 /// <param name="reverseStepConverter">The reversed step converter.</param>
 /// <param name="dataConverter">The data converter.</param>
 /// <param name="idComparer">The step id comparer.</param>
 /// <returns>The transaction.</returns>
 public static ITransaction <TStepIdTo, TDataTo> InsertAdapterAfter <TStepIdTo, TDataTo, TStepIdFrom, TDataFrom>(
     this ITransaction <TStepIdTo, TDataTo> transaction,
     TStepIdTo id,
     ITransactionStep <TStepIdFrom, TDataFrom> step,
     Func <TStepIdFrom, TStepIdTo> stepConverter,
     Func <TStepIdTo, TStepIdFrom> reverseStepConverter,
     Func <TDataTo, TDataFrom> dataConverter,
     IEqualityComparer <TStepIdTo> idComparer = null)
 {
     return(transaction.InsertAfter(id, step.Adapter(stepConverter, reverseStepConverter, dataConverter), idComparer));
 }
Example #10
0
        public static async Task ProcessPost <TStepId, TData>(SessionEndContext <TStepId, TData> context)
#endif
        {
            ITransactionStep <TStepId, TData>    currentStep = context.Session.StepEnumerator.CurrentStep;
            ITransactionSession <TStepId, TData> session     = context.Session;
            Stopwatch watch = new Stopwatch();

            try
            {
                watch.Start();
#if NET35 || NOASYNC
                currentStep.PostAction(session.StepEnumerator.Data, context.Session);
#else
                if (currentStep.PostAction != null)
                {
                    currentStep.PostAction(session.StepEnumerator.Data, context.Session);
                }
                else
                {
                    await currentStep.AsyncPostAction(session.StepEnumerator.Data, context.Session);
                }
#endif
                watch.Stop();

                if (session.ShouldLogStepExecution())
                {
                    session.TransactionContext
                    .Logger
                    .LogExecutionTime(
                        watch.Elapsed,
                        "Transaction '{0}': execution time for post step action for step '{1}' with id '{2}'.",
                        session.TransactionContext.Info.Name,
                        session.StepEnumerator.CurrentStepIndex,
                        currentStep.Id);
                }
            }
            catch (Exception e)
            {
                watch.Stop();
                string info = string.Format(
                    "Transaction '{0}': an error occurred during processing post step action for step '{1}' with id '{2}', execution time '{3}'.",
                    session.TransactionContext.Info.Name,
                    session.StepEnumerator.CurrentStepIndex,
                    currentStep.Id,
                    watch.Elapsed);
                session.TransactionContext.Logger.ErrorFormat(e, info);
#if NET35 || NOASYNC
                SessionEndOperation.EndSession(context.AddError(e));
#else
                await SessionEndOperation.EndSession(context.AddError(e));
#endif
            }
        }
Example #11
0
        /// <summary>
        /// Gets an index of the step with a specific id.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <param name="idComparer">The comparer.</param>
        /// <returns>The index of the step with the id, if not found returns <c>-1</c>.</returns>
        private int GetIndex(TStepId id, IEqualityComparer <TStepId> idComparer)
        {
            IEqualityComparer <TStepId> comparer = idComparer ?? EqualityComparer <TStepId> .Default;

            for (int i = 0; i < this.steps.Count; ++i)
            {
                ITransactionStep <TStepId, TData> step = this.steps[i];

                if (comparer.Equals(step.Id, id))
                {
                    return(i);
                }
            }

            return(-1);
        }
Example #12
0
        /// <summary>
        /// Validates a transaction step.
        /// </summary>
        /// <typeparam name="TStepId">The type of the step id.</typeparam>
        /// <typeparam name="TData">The type of the transaction data.</typeparam>
        /// <param name="step">The step to validate.</param>
        public static ITransactionStep <TStepId, TData> Validate <TStepId, TData>(this ITransactionStep <TStepId, TData> step)
        {
            if (step == null)
            {
                throw new ArgumentNullException(nameof(step));
            }

            if (step.StepAction == null
#if !NET35 && !NOASYNC
                && step.AsyncStepAction == null
#endif
                )
            {
                throw new NotSupportedException(string.Format("Improper step data for id '{0}': No step action.", step.Id));
            }

#if !NET35 && !NOASYNC
            if (step.StepAction != null &&
                step.AsyncStepAction != null)
            {
                throw new NotSupportedException(string.Format("Improper step data for id '{0}': '{1}' and '{2}' cannot be set simultaneously.", step.Id, nameof(step.StepAction), nameof(step.AsyncStepAction)));
            }

            if (step.UndoAction != null &&
                step.AsyncUndoAction != null)
            {
                throw new NotSupportedException(string.Format("Improper step data for id '{0}': '{1}' and '{2}' cannot be set simultaneously.", step.Id, nameof(step.UndoAction), nameof(step.AsyncUndoAction)));
            }

            if (step.PostAction != null &&
                step.AsyncPostAction != null)
            {
                throw new NotSupportedException(string.Format("Improper step data for id '{0}': '{1}' and '{2}' cannot be set simultaneously.", step.Id, nameof(step.PostAction), nameof(step.AsyncPostAction)));
            }
#endif

            return(step);
        }
Example #13
0
 public void addStep(ITransactionStep step)
 {
     _steps.Add(step);
 }
Example #14
0
 /// <summary>
 /// Inserts a step before a specific step id.
 /// </summary>
 /// <param name="id">The step id.</param>
 /// <param name="step">The step.</param>
 /// <param name="idComparer">The step id comparer.</param>
 public ITransaction <TStepId, TData> InsertBefore(TStepId id, ITransactionStep <TStepId, TData> step, IEqualityComparer <TStepId> idComparer = null)
 {
     this.context.Definition.InsertBefore(id, step, idComparer);
     return(this);
 }
Example #15
0
 /// <summary>
 /// Inserts a step at an index.
 /// </summary>
 /// <param name="index">The index.</param>
 /// <param name="step">The step.</param>
 public ITransaction <TStepId, TData> InsertAtIndex(int index, ITransactionStep <TStepId, TData> step)
 {
     this.context.Definition.InsertAtIndex(index, step);
     return(this);
 }
Example #16
0
 /// <summary>
 /// Adds a step.
 /// </summary>
 /// <param name="step">The step to add.</param>
 /// <returns>The transaction.</returns>
 public ITransaction <TStepId, TData> Add(ITransactionStep <TStepId, TData> step)
 {
     this.context.Definition.Add(step);
     return(this);
 }
Example #17
0
 /// <summary>
 /// Fills the current step.
 /// </summary>
 public void FillStep()
 {
     this.CurrentStep = this.session.TransactionContext.Definition.GetByIndex(this.CurrentStepIndex);
 }
Example #18
0
        public static async Task ProcessUndo <TStepId, TData>(RunUndoContext <TStepId, TData> context)
#endif
        {
            ITransactionStep <TStepId, TData>    currentStep = context.Session.StepEnumerator.CurrentStep;
            ITransactionSession <TStepId, TData> session     = context.Session;
            Stopwatch watch = new Stopwatch();

            try
            {
                watch.Start();
#if NET35 || NOASYNC
                currentStep.UndoAction(session.StepEnumerator.Data, session);
#else
                if (currentStep.UndoAction != null)
                {
                    currentStep.UndoAction(session.StepEnumerator.Data, session);
                }
                else
                {
                    await currentStep.AsyncUndoAction(session.StepEnumerator.Data, session);
                }
#endif
                watch.Stop();

#if NET35 || NOASYNC
                context.Session.TransactionContext.SessionStorage.StepReceding(session);
#else
                await context.Session.TransactionContext.SessionStorage.StepReceding(session);
#endif

                if (session.ShouldLogStepExecution())
                {
                    session.TransactionContext
                    .Logger
                    .LogExecutionTime(
                        watch.Elapsed,
                        "Transaction '{0}': execution time for undo step action for step '{1}' with id '{2}'.",
                        session.TransactionContext.Info.Name,
                        session.StepEnumerator.CurrentStepIndex,
                        currentStep.Id);
                }
            }
            catch (Exception e)
            {
                watch.Stop();
                string info = string.Format(
                    "Transaction '{0}': an error occurred during processing undo step action for step '{1}' with id '{2}', execution time '{3}'.",
                    session.TransactionContext.Info.Name,
                    session.StepEnumerator.CurrentStepIndex,
                    currentStep.Id,
                    watch.Elapsed);
                session.TransactionContext.Logger.ErrorFormat(e, info);
#if NET35 || NOASYNC
                SessionEndPreparationOperation.PrepareEndSession(new SessionEndContext <TStepId, TData>()
#else
                await SessionEndPreparationOperation.PrepareEndSession(new SessionEndContext <TStepId, TData>()
#endif
                {
                    Session = context.Session,
                    RunPostActions = false,
                    Result = ResultType.Failed
                }
                                                                 .AddError(context.CaughtException)
                                                                 .AddError(e));
            }
        }
Example #19
0
        public static async Task RunUndo <TStepId, TData>(RunUndoContext <TStepId, TData> context)
#endif
        {
            while (context.ProcessStepPredicate(context.Session.StepEnumerator.CurrentStep))
            {
                ITransactionStep <TStepId, TData> step = context.Session.StepEnumerator.CurrentStep;

                if (step == null)
                {
                    if (context.NoSessionEnd)
                    {
#if NET35 || NOASYNC
                        context.UndoFinishAction();
#else
                        await context.UndoFinishAction();
#endif
                        return;
                    }

#if NET35 || NOASYNC
                    SessionEndPreparationOperation.PrepareEndSession(new SessionEndContext <TStepId, TData>()
#else
                    await SessionEndPreparationOperation.PrepareEndSession(new SessionEndContext <TStepId, TData>()
#endif
                    {
                        RunPostActions = false,
                        Session        = context.Session,
                        Result         = context.Result
                    }
                                                                     .AddError(context.CaughtException));

                    return;
                }

                ITransactionSession <TStepId, TData> session = context.Session;

                if (session.Recovered &&
                    step.Settings.NotRunOnRecovered())
                {
                    session.TransactionContext
                    .Logger
                    .DebugFormat(
                        "Transaction '{0}': ignoring the undo step action for step '{1}' with id '{2}' as the step cannot be executed on a recovered transaction.",
                        session.TransactionContext.Info.Name,
                        session.StepEnumerator.CurrentStepIndex,
                        session.StepEnumerator.CurrentStep.Id);
                    session.StepEnumerator.MovePrevious();
                    continue;
                }
#if NET35 || NOASYNC
                if (step.UndoAction == null)
#else
                if (step.UndoAction == null &&
                    step.AsyncUndoAction == null)
#endif
                {
                    session.TransactionContext
                    .Logger
                    .DebugFormat(
                        "Transaction '{0}': no undo step action for step '{1}' with id '{2}'.",
                        session.TransactionContext.Info.Name,
                        session.StepEnumerator.CurrentStepIndex,
                        session.StepEnumerator.CurrentStep.Id);
                    session.StepEnumerator.MovePrevious();
                    continue;
                }

                IExecutor executor = step.UndoActionExecutor != null
                                            ? step.UndoActionExecutor
                                            : step.Settings.SameExecutorForAllActions()
                                                ? step.StepActionExecutor
                                                : null;

                if (executor != null &&
                    executor.ShouldRun)
                {
#if NET35 || NOASYNC
                    executor.Run(() =>
                    {
                        ProcessUndoOperation.ProcessUndo(context);

                        if (!session.Ended)
                        {
                            session.StepEnumerator.MovePrevious();
                            RunUndoOperation.RunUndo(context);
                        }
                    });
#else
                    executor.Run(async() =>
                    {
                        await ProcessUndoOperation.ProcessUndo(context);

                        if (!session.Ended)
                        {
                            session.StepEnumerator.MovePrevious();
                            await RunUndoOperation.RunUndo(context);
                        }
                    });
#endif
                    return;
                }
                else
                {
#if NET35 || NOASYNC
                    ProcessUndoOperation.ProcessUndo(context);
#else
                    await ProcessUndoOperation.ProcessUndo(context);
#endif
                    session.StepEnumerator.MovePrevious();
                }
            }

#if NET35 || NOASYNC
            context.UndoFinishAction();
#else
            await context.UndoFinishAction();
#endif
        }
 public IOInputContinue <TInput, TOutput, TOutput> ContinueWith(ITransactionStep <TInput, TOutput> step)
 {
     Entities.Add(step);
     return(new IOInputContinueExecute <TInput, TOutput, TOutput>(this));
 }
 public OutputVoidContinue <TOriginalOutput> ContinueWith(ITransactionStep step)
 {
     Transaction.Entities.Add(step);
     return(this);
 }
        public static async Task RunPost <TStepId, TData>(SessionEndContext <TStepId, TData> context)
#endif
        {
            while (true)
            {
                ITransactionStep <TStepId, TData> step = context.Session.StepEnumerator.CurrentStep;

                if (step == null)
                {
#if NET35 || NOASYNC
                    SessionEndOperation.EndSession(context);
#else
                    await SessionEndOperation.EndSession(context);
#endif
                    return;
                }

                ITransactionSession <TStepId, TData> session = context.Session;

                if (session.Recovered &&
                    step.Settings.NotRunOnRecovered())
                {
                    session.TransactionContext
                    .Logger
                    .DebugFormat(
                        "Transaction '{0}': ignoring the post step action for step '{1}' with id '{2}' as the step cannot be executed on a recovered transaction.",
                        session.TransactionContext.Info.Name,
                        session.StepEnumerator.CurrentStepIndex,
                        session.StepEnumerator.CurrentStep.Id);
                    session.StepEnumerator.MoveNext();
                    continue;
                }
#if NET35 || NOASYNC
                if (step.PostAction == null)
#else
                if (step.PostAction == null &&
                    step.AsyncPostAction == null)
#endif
                {
                    session.TransactionContext
                    .Logger
                    .DebugFormat(
                        "Transaction '{0}': no post step action for step '{1}' with id '{2}'.",
                        session.TransactionContext.Info.Name,
                        session.StepEnumerator.CurrentStepIndex,
                        session.StepEnumerator.CurrentStep.Id);
                    session.StepEnumerator.MoveNext();
                    continue;
                }

                IExecutor executor = step.PostActionExecutor != null
                                            ? step.PostActionExecutor
                                            : step.Settings.SameExecutorForAllActions()
                                                ? step.StepActionExecutor
                                                : null;

                if (executor != null &&
                    executor.ShouldRun)
                {
#if NET35 || NOASYNC
                    executor.Run(() =>
                    {
                        ProcessPostOperation.ProcessPost(context);

                        if (!session.Ended)
                        {
                            session.StepEnumerator.MoveNext();
                            RunPostOperation.RunPost(context);
                        }
                    });
#else
                    executor.Run(async() =>
                    {
                        await ProcessPostOperation.ProcessPost(context);

                        if (!session.Ended)
                        {
                            session.StepEnumerator.MoveNext();
                            await RunPostOperation.RunPost(context);
                        }
                    });
#endif
                    return;
                }
                else
                {
#if NET35 || NOASYNC
                    ProcessPostOperation.ProcessPost(context);
#else
                    await ProcessPostOperation.ProcessPost(context);
#endif
                    session.StepEnumerator.MoveNext();
                }
            }
        }
Example #23
0
        public static async Task RunSession <TStepId, TData>(ITransactionSession <TStepId, TData> session)
#endif
        {
            while (true)
            {
                ITransactionStep <TStepId, TData> step = session.StepEnumerator.CurrentStep;

                if (step == null)
                {
#if NET35 || NOASYNC
                    SessionEndPreparationOperation.PrepareEndSession(new SessionEndContext <TStepId, TData>()
#else
                    await SessionEndPreparationOperation.PrepareEndSession(new SessionEndContext <TStepId, TData>()
#endif
                    {
                        Session        = session,
                        RunPostActions = true,
                        Result         = ResultType.Success
                    });

                    return;
                }

#if NET35 || NOASYNC
                session.PrepareStep();
#else
                await session.PrepareStep();
#endif

                if (session.Ended)
                {
                    return;
                }

                if (session.Recovered &&
                    step.Settings.NotRunOnRecovered())
                {
                    session.TransactionContext
                    .Logger
                    .DebugFormat(
                        "Transaction '{0}': ignoring step '{1}' with id '{2}' as the step cannot be executed on a recovered transaction.",
                        session.TransactionContext.Info.Name,
                        session.StepEnumerator.CurrentStepIndex,
                        session.StepEnumerator.CurrentStep.Id);
                    session.StepEnumerator.MoveNext();
                    continue;
                }

                session.TransactionContext
                .Logger
                .DebugFormat(
                    "Transaction '{0}: running step '{1}' with id '{2}'.",
                    session.TransactionContext.Info.Name,
                    session.StepEnumerator.CurrentStepIndex,
                    session.StepEnumerator.CurrentStep.Id);

                IExecutor executor = session.StepEnumerator.CurrentStep.StepActionExecutor;

                if (executor != null &&
                    executor.ShouldRun)
                {
#if NET35 || NOASYNC
                    executor.Run(() =>
                    {
                        session.ProcessStep();

                        if (!session.Ended)
                        {
                            RunSessionOperation.MoveToNextStep(session, true);
                        }
                    });
#else
                    executor.Run(async() =>
                    {
                        await session.ProcessStep();

                        if (!session.Ended)
                        {
                            await RunSessionOperation.MoveToNextStep(session, true);
                        }
                    });
#endif
                    return;
                }
                else
                {
#if NET35 || NOASYNC
                    session.ProcessStep();
#else
                    await session.ProcessStep();
#endif

                    if (session.Ended)
                    {
                        return;
                    }

#if NET35 || NOASYNC
                    RunSessionOperation.MoveToNextStep(session, false);
#else
                    await RunSessionOperation.MoveToNextStep(session, false);
#endif
                }
            }
        }
 ContinueWith <TOutput>(ITransactionStep <TRequiredInput, TOutput> step)
 {
     Transaction.Entities.Add(step);
     return(new IOInputContinue <TOriginalInput, TOutput>(Transaction));
 }
 public IOInputContinue <TStepOutput> ContinueWith <TStepOutput>(
     ITransactionStep <TRequiredInput, TStepOutput> step)
 {
     Transaction.Entities.Add(step);
     return(new IOInputContinue <TStepOutput>(Transaction));
 }
 public OutputVoidContinueExecute ContinueWith(ITransactionStep step)
 {
     Entities.Add(step);
     return(new OutputVoidContinueExecute(this));
 }
Example #27
0
        public ITransactionStep SetNext(ITransactionStep handler)
        {
            nextHandler = handler;

            return(handler);
        }
 ContinueWith <TStepOutput>(ITransactionStep <TInput, TStepOutput> step)
 {
     Entities.Add(step);
     return(new IOInputContinue <TInput, TOutput, TStepOutput>(this));
 }
Example #29
0
        public void WhenCreateAdapter_ShouldCreateProperly()
        {
            // Arrange
            byte   expectedData        = 200;
            string adapterExpectedData = expectedData.ToString(CultureInfo.InvariantCulture);
            bool   postActionExecuted  = false;
            bool   stepActionExecuted  = false;
            bool   undoActionExecuted  = false;
            Mock <ITransactionStep <int, byte> > step = new Mock <ITransactionStep <int, byte> >();

            step.SetupGet(x => x.Id)
            .Returns(123);
            step.SetupGet(x => x.Settings)
            .Returns((StepSettings)int.MaxValue);
            step.SetupGet(x => x.PostAction)
            .Returns((byte data, IPostTransactionSessionInfo <int> sessionInfo) =>
            {
                postActionExecuted = true;
                data.Should().Be(expectedData);
            });
            step.SetupGet(x => x.StepAction)
            .Returns((byte data, IStepTransactionSessionInfo <int> sessionInfo) =>
            {
                stepActionExecuted = true;
                data.Should().Be(expectedData);
                sessionInfo.CurrentStepId.Should().Be(step.Object.Id);
            });
            step.SetupGet(x => x.UndoAction)
            .Returns((byte data, IUndoTransactionSessionInfo <int> sessionInfo) =>
            {
                undoActionExecuted = true;
                data.Should().Be(expectedData);
                sessionInfo.CurrentStepId.Should().Be(step.Object.Id);
            });
            step.SetupGet(x => x.PostActionExecutor)
            .Returns(new Mock <IExecutor>().Object);
            step.SetupGet(x => x.StepActionExecutor)
            .Returns(new Mock <IExecutor>().Object);
            step.SetupGet(x => x.UndoActionExecutor)
            .Returns(new Mock <IExecutor>().Object);
            Mock <IStepTransactionSessionInfo <string> > stepInfo = new Mock <IStepTransactionSessionInfo <string> >();

            stepInfo.SetupGet(x => x.CurrentStepId)
            .Returns(step.Object.Id.ToString(CultureInfo.InvariantCulture));
            stepInfo.SetupGet(x => x.Cancelled)
            .Returns(true);
            stepInfo.SetupGet(x => x.Recovered)
            .Returns(true);
            stepInfo.SetupGet(x => x.SessionId)
            .Returns(Guid.NewGuid());
            stepInfo.SetupGet(x => x.StartTimestamp)
            .Returns(DateTime.Now);
            Mock <IUndoTransactionSessionInfo <string> > undoInfo = stepInfo.As <IUndoTransactionSessionInfo <string> >();
            Mock <IPostTransactionSessionInfo <string> > postInfo = undoInfo.As <IPostTransactionSessionInfo <string> >();
            ITransactionStep <string, string>            adapter  = step.Object.Adapter <string, string, int, byte>(id => id.ToString(), idString => int.Parse(idString), data => byte.Parse(data));

            // Act
            adapter.PostAction(adapterExpectedData, postInfo.Object);

            // Assert
            postActionExecuted.Should().BeTrue();

            // Act
            adapter.StepAction(adapterExpectedData, stepInfo.Object);

            // Assert
            stepActionExecuted.Should().BeTrue();

            // Act
            adapter.UndoAction(adapterExpectedData, undoInfo.Object);

            // Assert
            undoActionExecuted.Should().BeTrue();

            // Assert
            int.Parse(adapter.Id).Should().Be(step.Object.Id);
            adapter.Settings.Should().Be(step.Object.Settings);
            adapter.PostActionExecutor.Should().BeSameAs(step.Object.PostActionExecutor);
            adapter.StepActionExecutor.Should().BeSameAs(step.Object.StepActionExecutor);
            adapter.UndoActionExecutor.Should().BeSameAs(step.Object.UndoActionExecutor);
        }