public WorkflowActivity(WorkflowProcess process, WorkflowAttributeCollection attributes, ILogger logger)
        {
            _process = process;
            _logger  = logger;

            _attributes.Merge(attributes);
        }
        private bool ProcessAttributeRequest(WorkflowActivityArgs args, List <string> required)
        {
            bool ret = true;
            WorkflowAttributeCollection found = new WorkflowAttributeCollection();
            List <string> attr_list           = new List <string>();

            if (required != null && required.Count > 0)
            {
                List <WorkflowParameter> list = _process.Parameters;
                foreach (string name in required)
                {
                    ret = false;
                    WorkflowParameter curr_param = list.FirstOrDefault(p => p.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase));
                    //find if override exist
                    if (curr_param != null && curr_param.Override != null)
                    {
                        foreach (string attr_name in curr_param.Override)
                        {
                            if (_attributes.Keys.Contains(attr_name))
                            {
                                found.Add(name, _attributes[attr_name]);
                                ret = true;
                                break;
                            }
                        }
                    }
                    else
                    {
                        if (_attributes.Keys.Contains(name))
                        {
                            found.Add(name, _attributes[name]);
                            ret = true;
                        }
                    }

                    if (!ret)
                    {
                        if (curr_param == null || curr_param.Default == null)
                        {
                            _logger.Error("Error {ErrorCode}: Attribute {Name} is not found", -11, name);
                            break;
                        }
                        else
                        {
                            found.Add(name, curr_param.Default);
                            ret = true;
                        }
                    }
                }
            }

            args.RequiredAttributes = found;
            return(ret);
        }
        /// <summary>
        /// Returns resolved Attribute Collection set based on the request scope.
        /// </summary>
        /// <param name="WfId"></param>
        /// <param name="StepId"></param>
        /// <param name="ConstId"></param>
        /// <param name="RunId"></param>
        /// <returns></returns>
        public WorkflowAttributeCollection WorkflowAttributeCollectionGet(int WfId, int StepId, int ConstId, int RunId)
        {
            WorkflowAttributeCollection attributes = new WorkflowAttributeCollection();
            string xml_string;

            using (SqlConnection cn = new SqlConnection())
            {
                cn.ConnectionString = _connection_string;
                try
                {
                    cn.Open();

                    string cmd_text = String.Format(WORKFLOW_ATTRIBUTE_QUERY
                                                    , WfId
                                                    , (StepId == 0) ? "null" : StepId.ToString()
                                                    , (ConstId == 0) ? "null" : ConstId.ToString()
                                                    , RunId,
                                                    ((_debug) ? 1 : 0));
                    using (SqlCommand cmd = new SqlCommand(cmd_text, cn))
                    {
                        cmd.CommandTimeout = COMMAND_TIMEOUT;
                        cmd.CommandType    = CommandType.Text;
                        var xml = cmd.ExecuteScalar();
                        xml_string = xml.ToString();
                    }

                    attributes = new WorkflowAttributeCollection(MetadataAttributeCollection.DeSerializefromXml(xml_string));
                }
                catch (Exception ex)
                {
                    throw (ex);
                }
                finally
                {
                    if (cn.State != ConnectionState.Closed)
                    {
                        cn.Close();
                    }
                }
            }

            return(attributes);
        }
        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);
        }
 public WorkflowProcessor(WorkflowAttributeCollection attributes)
 {
     _logger     = Log.Logger;
     _attributes = attributes;
     Initialize();
 }
예제 #6
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);
        }