public Tuple <ExecutionResult, StepRuntime> Execute(StepRuntime rt, IProcessRuntimeEnvironment env)
            {
                var result = _real.Execute(rt, env);

                _persistenceService.OnExecute(_real, result, env);
                return(result);
            }
예제 #2
0
        /// <summary>
        /// Try to get next step to continue execution
        /// </summary>
        /// <param name="step"></param>
        /// <param name="env"></param>
        /// <param name="nextStep"></param>
        /// <returns></returns>
        private bool TryGetNextStep(StepRuntime step, IProcessRuntimeEnvironment env, out StepRuntime nextStep)
        {
            nextStep = null;
            // check for specific transition name
            var linkRuntimes = _links.Where(l => l.SourceStepId == step.Id).ToList();

            if (linkRuntimes.Count == 1)
            {
                nextStep = _steps.FirstOrDefault(s => s.Id == linkRuntimes[0].TargetStepId);
                return(true);
            }
            if (!string.IsNullOrEmpty(env.Transition))
            {
                LinkRuntime linkRuntime = linkRuntimes.FirstOrDefault(l => l.Definition.Name == env.Transition);
                nextStep = linkRuntime == null ? null : _steps.FirstOrDefault(s => s.Id == linkRuntime.TargetStepId);
                return(nextStep != null);
            }
            foreach (LinkRuntime link in linkRuntimes)
            {
                if (link.Evaluate(env).Result)
                {
                    nextStep = _steps.FirstOrDefault(s => s.Id == link.TargetStepId);
                    break;
                }
            }
            return(nextStep != null);
        }
            public Tuple <ExecutionResult, StepRuntime> Continue(IProcessRuntimeEnvironment env)
            {
                var result = _real.Continue(env);

                _persistenceService.OnContinue(_real, result, env);
                return(result);
            }
예제 #4
0
 /// <summary>
 /// Override base method to return 1 if the script does not exist
 /// </summary>
 /// <param name="env"></param>
 /// <returns></returns>
 public override Task <int> Execute(IProcessRuntimeEnvironment env)
 {
     if (_sd.Lang == ScriptLanguage.None)
     {
         return(Task.FromResult(1));
     }
     return(base.Execute(env));
 }
예제 #5
0
 /// <summary>
 /// Continue the process execution from Suspended state
 /// </summary>
 /// <param name="env"></param>
 /// <returns></returns>
 public virtual Tuple <ExecutionResult, StepRuntime> Continue(IProcessRuntimeEnvironment env)
 {
     if (State != ProcessStateEnum.Suspended)
     {
         throw new InvalidProcessStateException($"To be able to continue, the Process Id={Id} must be in Suspended state. Current state is {State}.");
     }
     return(OnStepExecutionReady(SuspendedInStep, env));
 }
예제 #6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="rt"></param>
        /// <param name="env"></param>
        /// <param name="messages"></param>
        /// <returns></returns>
        protected virtual bool TryEnter(StepRuntime rt, IProcessRuntimeEnvironment env, out string[] messages)
        {
            messages = EmptyStrArr;
            AsyncValidationResult onEnterResult = rt.ValidateOnEnter(env).Result;

            if (!onEnterResult.Valid)
            {
                messages = onEnterResult.Messages;
            }
            return(onEnterResult.Valid);
        }
        /// <summary>
        /// Evaluate the link
        /// </summary>
        /// <param name="env"></param>
        /// <returns>evaluation result true if a link condition has been satisfied. </returns>
        public async Task <bool> Evaluate(IProcessRuntimeEnvironment env)
        {
            if (_script == null)
            {
                return(await Task.FromResult(true));
            }

            int val = await _script.Execute(env);

            return(val == 1);
        }
예제 #8
0
 public IReadOnlyList <string> GetValues(IProcessRuntimeEnvironment env)
 {
     if (!_compiled)
     {
         string[] errors;
         if (!_sc.TryCompile(out errors))
         {
             throw new ArgumentException(
                       string.Format("Compiletion error for Tag {0} : {1}", Name, string.Join(";", errors)));
         }
         _compiled = true;
     }
     return(_sc.Execute(env).Result);
 }
예제 #9
0
        /// <summary>
        /// Execute Single Step in the workflow
        /// </summary>
        /// <returns>
        /// This method returns a tuple of two elements:
        /// <see cref="ExecutionResult"/>
        /// <see cref="StepRuntime"/>
        /// Next Step in Execution flow
        /// If the execution result has value of Suspend
        ///  </returns>
        public virtual Tuple <ExecutionResult, StepRuntime> Execute(StepRuntime rt, IProcessRuntimeEnvironment env)
        {
            Func <StateActionParams, Tuple <ExecutionResult, StepRuntime> > f;

            if (!StatusActions.TryGetValue(State, out f))
            {
                throw new InvalidProcessStateException($"Process Id={Id} State={State} is not supported.");
            }
            return(f(new StateActionParams
            {
                Process = this,
                Step = rt,
                Env = env
            }));
        }
예제 #10
0
        /// <summary>
        /// Execute script Async
        /// </summary>
        /// <param name="env"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentException"></exception>
        public virtual async Task <T> Execute(IProcessRuntimeEnvironment env)
        {
            if (_sd.Lang == ScriptLanguage.None)
            {
                return(default(T));
            }
            if (_script == null)
            {
                throw new ArgumentException("Script is not initialized.");
            }
            ScriptState <T> result = await _script.RunAsync(env);

            if (result.Exception != null)
            {
                throw result.Exception;
            }
            return(result.ReturnValue);
        }
예제 #11
0
            public async Task <ExecutionResult> ExecuteAsync(IProcessRuntimeEnvironment env)
            {
                try
                {
                    int result = await _script.Execute(env);

                    return(new ExecutionResult(result == 1
                        ? StepExecutionStatusEnum.Ready
                        : StepExecutionStatusEnum.Failed));
                }
                catch (AggregateException ex)
                {
                    return(new ExecutionResult(StepExecutionStatusEnum.Failed, null, ex.Flatten().Message));
                }
                catch (Exception ex)
                {
                    return(new ExecutionResult(StepExecutionStatusEnum.Failed, null, ex.Message));
                }
            }
예제 #12
0
        /// <summary>
        /// Validates the on enter on exit criteria.
        /// </summary>
        /// <param name="env">The env.</param>
        /// <param name="rt">The rt.</param>
        /// <param name="f">The f.</param>
        /// <returns></returns>
        private async Task <AsyncValidationResult> ValidateOnEnterOnExit(IProcessRuntimeEnvironment env,
                                                                         CsScriptRuntime rt, Func <VariableMapDefinition, bool> f)
        {
            if (!IsCompiled)
            {
                return(new AsyncValidationResult($"The step Id {_stepDef.StepId} is not compiled."));
            }
            string[] errors;
            if (!TryValidateVariables(env, _stepDef.VariablesMap?.Where(f) ?? new VariableMapDefinition[] { }, out errors))
            {
                return(new AsyncValidationResult(errors));
            }
            if (rt == null)
            {
                return(new AsyncValidationResult());
            }
            int result = await rt.Execute(env);

            return(result == 1 ? new AsyncValidationResult() : new AsyncValidationResult("Script validation fails"));
        }
예제 #13
0
        /// <summary>
        /// Tries to validate required variables.
        /// </summary>
        /// <param name="env">The env.</param>
        /// <param name="vars">The vars.</param>
        /// <param name="errors">The errors.</param>
        /// <returns></returns>
        private bool TryValidateVariables(IProcessRuntimeEnvironment env, IEnumerable <VariableMapDefinition> vars, out string[] errors)
        {
            List <string> varErrors = new List <string>();

            foreach (var v in vars)
            {
                try
                {
                    object val = env.PropertySet.Get <object>(v.Name);
                    if (val == null)
                    {
                        varErrors.Add($"Variable {v.Name} has no value.");
                    }
                }
                catch (ArgumentException ex)
                {
                    varErrors.Add(ex.Message);
                }
            }
            errors = varErrors.ToArray();
            return(varErrors.Count == 0);
        }
예제 #14
0
 protected virtual void OnExecute(IProcessRuntime runtime, Tuple <ExecutionResult, StepRuntime> result, IProcessRuntimeEnvironment env)
 {
     using (var ctx = new ProcessDbContext())
     {
         ProcessRuntimePersistence persistence = ctx.Process.Find(runtime.Id);
         if (persistence == null)
         {
             throw new ArgumentException("Invalid Workflow Id:" + runtime.Id);
         }
         _propertySepPersistenceService.SaveCollection(ctx, runtime.Id, env.PropertySet);
         persistence.Status          = (int)runtime.State;
         persistence.LastUpdated     = DateTime.UtcNow;
         persistence.SuspendedStepId = runtime.SuspendedInStep?.StepId;
         persistence.NextStepId      = runtime.State == ProcessStateEnum.Completed? null: result.Item2?.StepId;
         ctx.SaveChanges();
     }
 }
예제 #15
0
 protected virtual void OnContinue(IProcessRuntime real, Tuple <ExecutionResult, StepRuntime> result, IProcessRuntimeEnvironment env)
 {
     throw new NotImplementedException();
 }
예제 #16
0
 public async Task <ExecutionResult> ExecuteAsync(IProcessRuntimeEnvironment env)
 {
     return(new ExecutionResult(StepExecutionStatusEnum.Ready));
 }
예제 #17
0
 /// <summary>
 /// Executes the step asynchrnously.
 /// </summary>
 /// <param name="env">The env.</param>
 /// <returns></returns>
 public async Task <ExecutionResult> ExecuteAsync(IProcessRuntimeEnvironment env)
 {
     return(await _handler.ExecuteAsync(env));
 }
예제 #18
0
 public async Task <ExecutionResult> ExecuteAsync(IProcessRuntimeEnvironment env)
 {
     env.CurrentStep = _step;
     return(await env.IocServiceAsync(_step._stepDef.StepHandler.IocName));
 }
        /// <summary>
        /// Continue the execution after freeze
        /// </summary>
        /// <param name="real"></param>
        /// <param name="result"></param>
        /// <param name="env"></param>
        /// <exception cref="NotImplementedException"></exception>
        private void OnContinue(IProcessRuntime real, Tuple <ExecutionResult, StepRuntime> result, IProcessRuntimeEnvironment env)
        {
            var persistedCollection = CreatePersistentPropertyCollection(real, env.PropertySet);
            var filter = Builders <MongoProcessRuntimePersistence> .Filter.Eq(r => r.Id, real.Id);

            var updater = Builders <MongoProcessRuntimePersistence> .Update
                          .Set(r => r.Status, (int)real.State)
                          .Set(r => r.PropertyCollection, persistedCollection)
                          .CurrentDate(r => r.LastUpdated);

            if (result.Item1.Status == StepExecutionStatusEnum.Ready)
            {
                updater = updater.Set(r => r.NextStepId, result.Item2.StepId);
            }
            if (result.Item1.Status == StepExecutionStatusEnum.Suspend)
            {
                updater = updater.Set(r => r.NextStepId, null).Set(r => r.SuspendedStepId, result.Item2.StepId);
            }
            UpdateResult updateResult = _collection.UpdateOne(filter, updater);

            if (updateResult.ModifiedCount != 1)
            {
                throw new ArgumentException($"Cannot modify the process Id={real.Id}");
            }
        }
예제 #20
0
 public async Task <ExecutionResult> ExecuteAsync(IProcessRuntimeEnvironment env)
 {
     env.CurrentStep = _step;
     return(await env.TaskServiceAsync());
 }
예제 #21
0
 public IReadOnlyList <string> GetValues(IProcessRuntimeEnvironment env)
 {
     return(_values);
 }
예제 #22
0
 public IReadOnlyList <string> GetValues(IProcessRuntimeEnvironment env)
 {
     return(_service.GetValues(env));
 }
예제 #23
0
 public async Task <ExecutionResult> ExecuteAsync(IProcessRuntimeEnvironment env)
 {
     env.CurrentStep = _step;
     return(await env.LoadExecuteAssemplyAsync(_step._stepDef.StepHandler.ClassFullName));
 }
        /// <summary>
        ///
        /// </summary>
        /// <param name="runtime"></param>
        /// <param name="result"></param>
        /// <param name="env"></param>
        /// <exception cref="NotImplementedException"></exception>
        private void OnExecute(IProcessRuntime runtime, Tuple <ExecutionResult, StepRuntime> result, IProcessRuntimeEnvironment env)
        {
            var persistedCollection = CreatePersistentPropertyCollection(runtime, env.PropertySet);
            var filter = Builders <MongoProcessRuntimePersistence> .Filter.Eq(r => r.Id, runtime.Id);

            var updater = Builders <MongoProcessRuntimePersistence> .Update
                          .Set(r => r.Status, (int)runtime.State)
                          .Set(r => r.SuspendedStepId, runtime.SuspendedInStep?.StepId)
                          .Set(r => r.PropertyCollection, persistedCollection)
                          .Set(r => r.NextStepId, runtime.State == ProcessStateEnum.Completed? null: result.Item2?.StepId)
                          .CurrentDate(r => r.LastUpdated);

            UpdateResult updateResult = _collection.UpdateOne(filter, updater);

            if (updateResult.ModifiedCount != 1)
            {
                throw new ArgumentException($"Cannot modify the process Id={runtime.Id}");
            }
        }
예제 #25
0
        /// <summary>
        /// On Execute step
        /// </summary>
        /// <param name="rt"></param>
        /// <param name="env"></param>
        /// <returns></returns>
        protected virtual Tuple <ExecutionResult, StepRuntime> OnExecute(StepRuntime rt, IProcessRuntimeEnvironment env)
        {
            BeforeExecute();
            string[] errors;
            if (!TryEnter(rt, env, out errors))
            {
                State = ProcessStateEnum.Failed;
                OnEntryValidationError(errors);
                return(new Tuple <ExecutionResult,
                                  StepRuntime>(new ExecutionResult(StepExecutionStatusEnum.Failed), null));
            }
            State             = ProcessStateEnum.Ready;
            _lastExecutedStep = rt;
            var stepExecutionResult = rt.ExecuteAsync(env).Result;
            Func <StateActionParams, Tuple <ExecutionResult, StepRuntime> > f;

            if (!PostStatusActions.TryGetValue(stepExecutionResult.Status, out f))
            {
                throw new InvalidProcessStateException(
                          $"Step Execution status {stepExecutionResult.Status} is not supported for Process Id={Id}");
            }
            try
            {
                return(f(new StateActionParams
                {
                    Step = rt,
                    Process = this,
                    Env = env,
                    Result = stepExecutionResult
                }));
            }
            finally
            {
                AfterExecute();
            }
        }
예제 #26
0
        /// <summary>
        /// Step Execution Read moves the workflow to its next step.
        /// </summary>
        /// <param name="rt"></param>
        /// <param name="env"></param>
        /// <returns></returns>
        protected virtual Tuple <ExecutionResult, StepRuntime> OnStepExecutionReady(StepRuntime rt, IProcessRuntimeEnvironment env)
        {
            _lastExecutedStep = rt;
            var onExitResult = rt.ValidateOnExit(env).Result;

            if (onExitResult.Valid)
            {
                StepRuntime next;
                if (TryGetNextStep(rt, env, out next))
                {
                    SuspendedInStep = null;
                    State           = ProcessStateEnum.Ready;
                    return(new Tuple <ExecutionResult, StepRuntime>(
                               new ExecutionResult(StepExecutionStatusEnum.Ready), next));
                }
                if (rt.IsEnd)
                {
                    SuspendedInStep = null;
                    State           = ProcessStateEnum.Completed;
                    return(new Tuple <ExecutionResult, StepRuntime>(new ExecutionResult(StepExecutionStatusEnum.Completed), rt));
                }
                else
                {
                    return(new Tuple <ExecutionResult, StepRuntime>(new ExecutionResult(StepExecutionStatusEnum.Ready), next));
                }
            }
            OnExitValidationError(onExitResult.Messages);
            State = ProcessStateEnum.Failed;
            return(new Tuple <ExecutionResult, StepRuntime>(
                       new ExecutionResult(StepExecutionStatusEnum.Failed, null, onExitResult.Messages), rt));
        }
예제 #27
0
 /// <summary>
 /// Validate Step conditions on exit
 /// </summary>
 /// <param name="env"></param>
 /// <returns></returns>
 public async Task <AsyncValidationResult> ValidateOnExit(IProcessRuntimeEnvironment env)
 {
     return(await ValidateOnEnterOnExit(env, _onExit,
                                        v => (v.Required & VarRequiredEnum.OnExit) == VarRequiredEnum.OnExit));
 }