예제 #1
0
        void ProcessRecursive(IActionContainer parentContext, SecurityContext parentSecurityContext,
                              ActionItem actionGroup, List <ActionItem> actions, ExecuteResult parentResult,
                              Dictionary <string, string> dynamicData, bool dryRun,
                              Func <SecurityContext, ActionItem, Dictionary <string, string>, object, bool, ExecuteResult> executeHandlerMethod)
        {
            if (WantsStopOrPause())
            {
                return;
            }


            parentContext.EnsureInitialized();

            //queryStatus provides the inbound value to ExecuteCase evaluation; it's the ExecuteCase comparison value.
            //queryStatus is carried downward through successive subtree executions.
            StatusType queryStatus = parentResult.Status;

            #region actionGroup
            if (actionGroup != null &&
                (((actionGroup.ExecuteCase & parentResult.Status) == actionGroup.ExecuteCase) || (actionGroup.ExecuteCase == StatusType.Any)))
            {
                actionGroup.EnsureInitialized();

                #region actionGroup-forEach
                if ((actionGroup.HasParameters && actionGroup.Parameters.HasForEach) ||
                    (actionGroup.Handler.HasConfig && actionGroup.Handler.Config.HasForEach))
                {
                    List <ActionItem> resolvedParmsActionGroup = new List <ActionItem>();
                    ResolveConfigAndParameters(actionGroup, dynamicData, ref resolvedParmsActionGroup, parentResult.ExitData);

                    foreach (ActionItem ai in resolvedParmsActionGroup)
                    {
                        ai.Parameters.ForEach = null;
                    }

                    actionGroup.InstanceId = ActionInstanceIdCounter++;
                    ActionItem agclone = actionGroup.Clone();
                    agclone.Result            = new ExecuteResult();
                    parentContext.ActionGroup = agclone;

                    Parallel.ForEach(resolvedParmsActionGroup, a =>    // foreach( ActionItem a in resolvedParmsActionGroup )
                    {
#if sqlite
                        a.CreateInstance(parentContext, InstanceId);
#endif
                        a.InstanceId     = ActionInstanceIdCounter++;
                        ActionItem clone = a.Clone();
                        agclone.Actions.Add(clone);

                        ExecuteResult r = executeHandlerMethod(parentSecurityContext, a, dynamicData, parentResult.ExitData, dryRun);
                        parentContext.ActionGroup.Result.SetBranchStatusChecked(r);
                        parentContext.Result.SetBranchStatusChecked(r);
                        clone.Handler.Type      = actionGroup.Handler.Type;
                        clone.Handler.StartInfo = actionGroup.Handler.StartInfo;
                        clone.Result            = r;

                        if (r.Status > queryStatus)
                        {
                            queryStatus = r.Status;
                        }

                        if (a.HasActions)
                        {
                            ProcessRecursive(clone, a.RunAs, a.ActionGroup, a.Actions, r, dynamicData, dryRun, executeHandlerMethod);
                            parentContext.ActionGroup.Result.SetBranchStatusChecked(clone.Result);
                            parentContext.Result.SetBranchStatusChecked(clone.Result);

                            if (clone.Result.Status > queryStatus)
                            {
                                queryStatus = clone.Result.Status;
                            }
                        }
                    });
                }
                #endregion
                #region actionGroup-single
                else
                {
#if sqlite
                    actionGroup.CreateInstance(parentContext, InstanceId);
#endif
                    ResolveConfigAndParameters(actionGroup, dynamicData, parentResult.ExitData);

                    actionGroup.InstanceId = ActionInstanceIdCounter++;
                    ActionItem clone = actionGroup.Clone();
                    parentContext.ActionGroup = clone;

                    ExecuteResult r = executeHandlerMethod(parentSecurityContext, actionGroup, dynamicData, parentResult.ExitData, dryRun);
                    parentContext.Result.SetBranchStatusChecked(r);
                    clone.Handler.Type      = actionGroup.Handler.Type;
                    clone.Handler.StartInfo = actionGroup.Handler.StartInfo;
                    clone.Result            = r;

                    if (r.Status > queryStatus)
                    {
                        queryStatus = r.Status;
                    }

                    if (actionGroup.HasActions)
                    {
                        ProcessRecursive(clone, actionGroup.RunAs, null, actionGroup.Actions, r, dynamicData, dryRun, executeHandlerMethod);
                        parentContext.Result.SetBranchStatusChecked(clone.Result);

                        if (clone.Result.Status > queryStatus)
                        {
                            queryStatus = clone.Result.Status;
                        }
                    }
                }
                #endregion
            }
            #endregion


            #region actions
            IEnumerable <ActionItem> actionList =
                actions.Where(a => (((a.ExecuteCase & queryStatus) == a.ExecuteCase) || (a.ExecuteCase == StatusType.Any)));

            List <ActionItem> resolvedParmsActions = new List <ActionItem>();
            Parallel.ForEach(actionList, a =>    // foreach( ActionItem a in actionList )
                             ResolveConfigAndParameters(a, dynamicData, ref resolvedParmsActions, parentResult.ExitData)
                             );

            Parallel.ForEach(resolvedParmsActions, a =>    // foreach( ActionItem a in resolvedParmsActions )
            {
#if sqlite
                a.CreateInstance(parentContext, InstanceId);
#endif
                a.InstanceId     = ActionInstanceIdCounter++;
                ActionItem clone = a.Clone();
                parentContext.Actions.Add(clone);

                ExecuteResult r = a.Result;
                if (r?.Status != StatusType.Failed)
                {
                    r = executeHandlerMethod(parentSecurityContext, a, dynamicData, parentResult.ExitData, dryRun);
                }

                parentContext.Result.SetBranchStatusChecked(r);
                clone.Handler.Type      = a.Handler.Type;
                clone.Handler.StartInfo = a.Handler.StartInfo;
                clone.Result            = r;

                if (a.HasActions)
                {
                    ProcessRecursive(clone, a.RunAs, a.ActionGroup, a.Actions, r, dynamicData, dryRun, executeHandlerMethod);
                    parentContext.Result.SetBranchStatusChecked(clone.Result);
                }
            });
            #endregion
        }