コード例 #1
0
 internal SequentialWorkflowActivity(IWorkflow workflow, MethodBase method, IWorkflowActivity previous)
 {
     Workflow         = workflow;
     Method           = method;
     PreviousActivity = previous;
     Key = Guid.NewGuid().ToString("N");
 }
コード例 #2
0
        public IWorkflowActivity Activate()
        {
            IWorkflowActivity activity = null;

            try
            {
                _logger.Information("Activate Activity {0}", _process.Process);
                activity = LoadActivity();

                //get the list of the required attributes from Activity
                List <string> required = new List <string>(activity.RequiredAttributes);
                //check if we have what we need
                WorkflowActivityArgs activity_args = new WorkflowActivityArgs();
                if (!ProcessAttributeRequest(activity_args, required))
                {
                    throw new Exception("Not all requested Attributes are available");
                }

                activity_args.Logger = _logger;
                activity.Configure(activity_args);
            }
            catch (Exception ex)
            {
                //result = WfResult.Create(WfStatus.Failed, ex.Message, -5);
                throw ex;
            }
            return(activity);
        }
コード例 #3
0
 private static IWorkflowActivity FindActivity(string activityKey, IWorkflowActivity activity)
 {
     if (activity != null && activity.Key != activityKey)
     {
         if (activity is IWorkflowConditionalActivity)
         {
             var condition = activity as IWorkflowConditionalActivity;
             activity = FindActivity(activityKey, condition.IfTrueActivity)
                        ?? FindActivity(activityKey, condition.ElseActivity)
                        ?? FindActivity(activityKey, condition.NextActivity);
         }
         else
         {
             activity = FindActivity(activityKey, activity.NextActivity);
         }
     }
     return(activity);
 }
コード例 #4
0
        private Func <ActionResult> OnSuccess(IWorkflowActivity currentActivity, object @return)
        {
            return(() =>
            {
                var nextActivity = currentActivity.NextActivity;
                if (nextActivity != null)
                {
                    if (nextActivity is IWorkflowConditionalActivity)
                    {
                        var condition = nextActivity as IWorkflowConditionalActivity;
                        nextActivity = condition.Condition(@return)
                            ? condition.IfTrueActivity
                            : condition.ElseActivity;
                    }

                    var values = new RouteValueDictionary(new
                    {
                        workflowKey = nextActivity.Workflow.Key,
                        activityKey = nextActivity.Key,
                        modelType = nextActivity.Method.DeclaringType.PartialName(),
                        methodName = nextActivity.Method.Name,
                        index = 0
                    });

                    WorkflowBindingParameterValueProvider.BindingParameters.Clear();
                    if (nextActivity.Binding != null)
                    {
                        var binding = nextActivity.Binding(@return);
                        if (binding != null)
                        {
                            foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(binding))
                            {
                                WorkflowBindingParameterValueProvider.BindingParameters.Add(prop.Name, prop.GetValue(binding));
                            }
                        }
                    }

                    return RedirectToAction(RunningObjectsAction.Execute.ToString(), values);
                }
                return GetRedirectOnFinish();
            });
        }
コード例 #5
0
 private Func <object, ActionResult> OnSuccessWithReturn(IWorkflowActivity nextActivity)
 {
     return(@return => OnSuccess(nextActivity, @return)());
 }
コード例 #6
0
        private IWorkflowActivity LoadActivity()
        {
            string activity_path = String.Empty;

            if (_attributes.Keys.Contains(ACTIVITY_LOCATION))
            {
                activity_path = _attributes[ACTIVITY_LOCATION];
            }

            string[] activity_name      = _process.Process.Split('.');
            string   activity_dll       = activity_name[0] + ".dll";
            string   activity_namespace = String.Empty;

            for (int i = 1; i < activity_name.Length - 1; i++)
            {
                activity_namespace += ((i == 1) ? "" : ".") + activity_name[i];
            }
            string activity_classname = activity_name[activity_name.Length - 1];

            string            dll_path = System.IO.Path.Combine(activity_path, activity_dll);
            string            path     = System.IO.Path.GetFullPath(dll_path);
            IWorkflowActivity activity = null;

            try
            {
                // Load dll
                Assembly assembly = Assembly.LoadFile(path);

                // Look for the interface
                foreach (Type item in assembly.GetTypes())
                {
                    if (!item.IsClass)
                    {
                        continue;
                    }

                    if (!(item.Namespace == activity_namespace && item.Name == activity_classname))
                    {
                        continue;
                    }

                    if (item.GetInterfaces().Contains(typeof(IWorkflowActivity)))
                    {
                        activity = (IWorkflowActivity)Activator.CreateInstance(item);
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                string message = ex.Message;
                ReflectionTypeLoadException tex = ex as ReflectionTypeLoadException;
                if (tex != null && tex.LoaderExceptions != null)
                {
                    foreach (Exception lex in tex.LoaderExceptions)
                    {
                        message += " " + lex.Message;
                    }
                }
                throw new Exception(string.Format("Error loading activity DLL {0}: {1}!", path, message));
            }

            // no IWorkflowActivity interface
            if (activity == null)
            {
                throw new Exception(string.Format("IWorkflowActivity interface is missing {0}!", path));
            }

            return(activity);
        }
コード例 #7
0
 public SequentialWorkflowConditionalActivity(IWorkflow workflow, Func<object, bool> condition, IWorkflowActivity previousActivity)
     : base(workflow, null, previousActivity)
 {
     Condition = condition;
 }
コード例 #8
0
        public WfResult Run(CancellationToken extToken)
        {
            _logger.Information("Start Processing Workflow Constraint {ItemKey}", _item.Key);

            WfResult result = WfResult.Unknown;
            WorkflowAttributeCollection attributes = _db.WorkflowAttributeCollectionGet(_item.WorkflowId, _item.StepId, _item.ConstId, _item.RunId);

            attributes.Merge(_wfp.Attributes);

            WorkflowActivity activity = new WorkflowActivity(_item.Process, attributes, _logger);

            TimeSpan timeout = TimeSpan.FromSeconds((_item.WaitPeriod <= 0) ? 7200 : _item.WaitPeriod);
            TimeSpan sleep   = TimeSpan.FromSeconds((_item.Ping <= 0) ? 30 : _item.Ping);

            try
            {
                using (CancellationTokenSource timeoutCts = new CancellationTokenSource(timeout))
                    using (CancellationTokenSource linkedCts = CancellationTokenSource.CreateLinkedTokenSource(extToken, timeoutCts.Token))
                    {
                        Task <WfResult> task = Task.Factory.StartNew(() =>
                        {
                            WfResult const_result    = WfResult.Unknown;
                            IWorkflowActivity runner = activity.Activate();
                            while (true)
                            {
                                //Run constraint activity
                                using (linkedCts.Token.Register(Thread.CurrentThread.Abort))
                                {
                                    try
                                    {
                                        //do thread hard abort if it is stuck on Run
                                        //constraint logic should never allow this to happen thou
                                        const_result = runner.Run(linkedCts.Token);
                                        _logger.Debug("Constraint {ItemKey} current status = {WfStatus}", _item.Key, const_result.StatusCode.ToString());

                                        if (const_result.StatusCode != WfStatus.Waiting)
                                        {
                                            break;
                                        }
                                    }
                                    catch (ThreadAbortException ex)
                                    {
                                        throw ex;
                                    }
                                }

                                //cts.Token.ThrowIfCancellationRequested();
                                Task.Delay(sleep, linkedCts.Token).Wait();
                                if (linkedCts.IsCancellationRequested)
                                {
                                    const_result = WfResult.Canceled;
                                    break;
                                }
                            }
                            return(const_result);
                        }, linkedCts.Token);

                        result = task.Result;
                    }
            }
            catch (AggregateException ex)
            {
                //result = WfResult.Create(WfStatus.Failed,"timeout",-3);
                throw ex;
            }
            finally
            {
                _logger.Information("Finish Processing Workflow Constraint {ItemKey} with result - {WfStatus}", _item.Key, result.StatusCode.ToString());
            }

            return(result);
        }
コード例 #9
0
 private IWorkflowActivity StartAt(MethodBase method)
 {
     return(StartActivity = new SequentialWorkflowActivity(this, method, null));
 }
コード例 #10
0
 public SequentialWorkflowConditionalActivity(IWorkflow workflow, Func <object, bool> condition, IWorkflowActivity previousActivity)
     : base(workflow, null, previousActivity)
 {
     Condition = condition;
 }
コード例 #11
0
 private static IWorkflowActivity FindActivity(string activityKey, IWorkflowActivity activity)
 {
     if (activity != null && activity.Key != activityKey)
     {
         if (activity is IWorkflowConditionalActivity)
         {
             var condition = activity as IWorkflowConditionalActivity;
             activity = FindActivity(activityKey, condition.IfTrueActivity)
                        ?? FindActivity(activityKey, condition.ElseActivity)
                        ?? FindActivity(activityKey, condition.NextActivity);
         }
         else
             activity = FindActivity(activityKey, activity.NextActivity);
     }
     return activity;
 }
コード例 #12
0
 private Func<object, ActionResult> OnSuccessWithReturn(IWorkflowActivity nextActivity)
 {
     return @return => OnSuccess(nextActivity, @return)();
 }
コード例 #13
0
        private Func<ActionResult> OnSuccess(IWorkflowActivity currentActivity, object @return)
        {
            return () =>
            {
                var nextActivity = currentActivity.NextActivity;
                if (nextActivity != null)
                {
                    if (nextActivity is IWorkflowConditionalActivity)
                    {
                        var condition = nextActivity as IWorkflowConditionalActivity;
                        nextActivity = condition.Condition(@return)
                            ? condition.IfTrueActivity
                            : condition.ElseActivity;
                    }

                    var values = new RouteValueDictionary(new
                    {
                        workflowKey = nextActivity.Workflow.Key,
                        activityKey = nextActivity.Key,
                        modelType = nextActivity.Method.DeclaringType.PartialName(),
                        methodName = nextActivity.Method.Name,
                        index = 0
                    });

                    WorkflowBindingParameterValueProvider.BindingParameters.Clear();
                    if (nextActivity.Binding != null)
                    {
                        var binding = nextActivity.Binding(@return);
                        if (binding != null)
                        {
                            foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(binding))
                                WorkflowBindingParameterValueProvider.BindingParameters.Add(prop.Name, prop.GetValue(binding));
                        }
                    }

                    return RedirectToAction(RunningObjectsAction.Execute.ToString(), values);
                }
                return GetRedirectOnFinish();
            };
        }
コード例 #14
0
        public WfResult Run(CancellationToken extToken)
        {
            _logger.Information("Start Processing Workflow step {ItemKey}:{ItemName}", _step.Key, _step.StepName);
            WfResult result = WfResult.Succeeded;

            try
            {
                //Step Constraints
                if (_step.StepConstraints != null)
                {
                    foreach (WorkflowConstraint wfc in _step.StepConstraints)
                    {
                        if (wfc.IsDisabled || wfc.Process.ProcessId == 0)
                        {
                            _logger.Debug("Constraint process is not defined or disabled {ItemKey}:{ItemName}", _step.Key, _step.StepName);
                            continue;
                        }

                        if ((wfc.Process.ScopeId & 12) == 0)
                        {
                            throw new ArgumentException(String.Format("Constraint Process is not of correct scope 0011 = {0}", wfc.Process.ScopeId));
                        }


                        wfc.WorkflowId = _step.WorkflowId;
                        wfc.StepId     = _step.StepId;
                        wfc.RunId      = _step.RunId;
                        WorkflowConstraintProcessor wcp = new WorkflowConstraintProcessor(wfc, _wfp);
                        result = wcp.Run(extToken);
                        if (result.StatusCode == WfStatus.Failed)
                        {
                            _logger.Error("Workflow step {ItemKey}:{ItemName} failed with: {ErrorCode}", _step.Key, _step.StepName, result.Message, result.ErrorCode);
                            return(result);
                        }
                    }
                }

                WorkflowAttributeCollection attributes = null;
                if (_step.StepProcess != null)
                {
                    //always evaluate step attributes
                    attributes = _db.WorkflowAttributeCollectionGet(_step.WorkflowId, _step.StepId, 0, _step.RunId);
                    attributes.Merge(_wfp.Attributes);

                    if (_step.StepProcess.ProcessId != 0)
                    {
                        if ((_step.StepProcess.ScopeId & 3) == 0)
                        {
                            throw new ArgumentException(String.Format("Step Process is not of correct scope 1100 = {0}", _step.StepProcess.ScopeId));
                        }

                        //Run Step Activity here
                        WorkflowActivity  step_activity = new WorkflowActivity(_step.StepProcess, attributes, _logger);
                        IWorkflowActivity step_runner   = step_activity.Activate();
                        result = (ProcessRunAsync(step_runner, extToken, _step.StepRetry, _step.StepDelayOnRetry, _step.StepTimeout, _logger)).Result;
                    }
                    else
                    {
                        _logger.Debug("Step process is not defined. Skipped {ItemKey}", _step.Key);
                    }
                }



                if (result.StatusCode == WfStatus.Succeeded &&
                    _step.StepOnSuccessProcess != null)
                {
                    _logger.Information("On step success");
                    _logger.Debug("On success process - {ProcessName}", _step.StepOnSuccessProcess.Process);

                    if ((_step.StepOnSuccessProcess.ScopeId & 3) == 0)
                    {
                        throw new ArgumentException(String.Format("OnSuccess Process is not of correct scope 1100 = {0}", _step.StepOnSuccessProcess.ScopeId));
                    }

                    //Run OnSuccess Activity here
                    //re-evaluate attribites
                    //if (attributes == null)
                    attributes = _db.WorkflowAttributeCollectionGet(_step.WorkflowId, _step.StepId, 0, _step.RunId);
                    WorkflowActivity  success_activity = new WorkflowActivity(_step.StepOnSuccessProcess, attributes, _logger);
                    IWorkflowActivity success_runner   = success_activity.Activate();

                    WfResult task_result = (ProcessRunAsync(success_runner, extToken, 0, 0, _step.StepTimeout, _logger)).Result;
                    if (task_result.StatusCode == WfStatus.Failed)
                    {
                        result = task_result;
                    }
                }
                else if (result.StatusCode == WfStatus.Failed &&
                         _step.StepOnFailureProcess != null)
                {
                    _logger.Information("On step failure");
                    _logger.Debug("On failure process - {ProcessName}", _step.StepOnFailureProcess.Process);

                    if ((_step.StepOnFailureProcess.ScopeId & 3) == 0)
                    {
                        throw new ArgumentException(String.Format("OnFailure Process is not of correct scope 1100 = {0}", _step.StepOnFailureProcess.ScopeId));
                    }

                    //Run OnFailure Activity here
                    //re-evaluate attribites
                    //if (attributes == null)
                    attributes = _db.WorkflowAttributeCollectionGet(_step.WorkflowId, _step.StepId, 0, _step.RunId);
                    WorkflowActivity  failure_activity = new WorkflowActivity(_step.StepOnFailureProcess, attributes, _logger);
                    IWorkflowActivity failure_runner   = failure_activity.Activate();

                    WfResult task_result = (ProcessRunAsync(failure_runner, extToken, 0, 0, _step.StepTimeout, _logger)).Result;
                    if (task_result.StatusCode == WfStatus.Failed)
                    {
                        result = task_result;
                    }
                }
            }
            catch (AggregateException aex)
            {
                _logger.Error(aex, "AggregateException: {Message}", aex.Message);
                foreach (var ex in aex.InnerExceptions)
                {
                    _logger.Error(ex, "InnerException: {Message}", ex.Message);
                }
                result = WfResult.Create(WfStatus.Failed, aex.Message, -10);
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "Exception: {0}", ex.Message);
                result = WfResult.Create(WfStatus.Failed, ex.Message, -10);
            }

            _logger.Information("Workflow step {ItemKey}:{ItemName} finished with result {WfStatus}", _step.Key, _step.StepName, result.StatusCode.ToString());
            return(result);
        }
コード例 #15
0
        private async Task <WfResult> ProcessRunAsync(IWorkflowActivity runner, CancellationToken token, int retry, int delay, int timeout, ILogger logger)
        {
            return(await Task.Factory.StartNew(() =>
            {
                WfResult result = WfResult.Failed;
                //do thread hard abort if it is stuck on Run
                //using (token.Register(Thread.CurrentThread.Abort))
                //{
                for (int i = 0; i <= retry; i++)
                {
                    using (CancellationTokenSource timeoutCts = new CancellationTokenSource())
                        using (CancellationTokenSource linkedCts = CancellationTokenSource.CreateLinkedTokenSource(token, timeoutCts.Token))
                        {
                            if (timeout > 0)
                            {
                                timeoutCts.CancelAfter(TimeSpan.FromSeconds(timeout));
                            }

                            try
                            {
                                token.ThrowIfCancellationRequested();
                                if (i > 0)
                                {
                                    logger.Information("Retry attempt {Count} on: {Message}", i, result.Message);

                                    if (delay > 0)
                                    {
                                        Task.Delay(TimeSpan.FromSeconds(delay), token).Wait();
                                    }
                                }

                                result = runner.Run(linkedCts.Token);
                            }
                            catch (ThreadAbortException ex)
                            {
                                logger.Error(ex, "ThreadAbortException: {0}", ex.Message);
                                result = WfResult.Create(WfStatus.Failed, ex.Message, -10);
                            }
                            catch (AggregateException aex)
                            {
                                logger.Error(aex, "AggregateException: {Message}", aex.Message);
                                foreach (var ex in aex.InnerExceptions)
                                {
                                    logger.Error(ex, "InnerException: {Message}", ex.Message);
                                }

                                result = WfResult.Failed;
                                if (timeoutCts.IsCancellationRequested)
                                {
                                    result = WfResult.Create(WfStatus.Failed, "Step was cancelled on timeout", -10);
                                    logger.Error(aex, result.Message);
                                }

                                if (token.IsCancellationRequested)
                                {
                                    logger.Error(aex, "Step was cancelled");
                                    result = WfResult.Canceled;
                                }
                            }
                            catch (Exception ex)
                            {
                                logger.Error(ex, "Exception: {Message}", ex.Message);
                                result = WfResult.Create(WfStatus.Failed, ex.Message, -10);
                            }

                            if (result.StatusCode == WfStatus.Succeeded ||
                                token.IsCancellationRequested)
                            {
                                break;
                            }
                        }
                }

                return result;

                //}
            }));//, token);
        }