/// <summary> /// Adds a step to the workflow. /// </summary> /// <param name="step">The step to add. Must contain a method called "run" which returns a type derived from WorkflowStepResult.</param> /// <param name="stepNumber">The step number</param> protected void Add(IWorkflowStep step, int stepNumber) { var type = step.GetType(); // get the method called 'run' var runMethod = type.GetMethod("Run"); // get the return type of the method var returnType = runMethod.ReturnType; // insure that the type it returns derives from workflowsStepResult if (returnType.BaseType != typeof(WorkflowStepResult)) { throw new WorkflowStepAdditionException("Attempted to add a workflow step that did not return a type derived from WorkflowStepBase"); } var args = runMethod.GetParameters(); // if there are args (there might not be any) // see if there are any available types that have the same name (ignoring case) and same type. There should only ever be exactly 1 if (args.Any() && args.Any(arg => availableParams.Count(at => String.Compare(arg.Name, at.Item1, StringComparison.OrdinalIgnoreCase) == 0 && arg.ParameterType == at.Item2 && at.Item3 <= stepNumber) != 1)) { throw new WorkflowStepAdditionException("Attempted to add a workflow step that would be unable to execute."); } // setup the available args // get the returnType properties, in order to filter them out. var unusableTypeList = this.GetWorkflowStepResultPropertyBlacklist(); var returnTypeProps = returnType.GetProperties().ToList().Where(p => !unusableTypeList.Contains(p.Name)).ToList(); foreach (var returnTypeProp in returnTypeProps) { // must add one to the available step, because otherwise, it would be passing something to itself, which wouldn't be correct; // the value will be null to start with. availableParams.Add(Tuple.Create(returnTypeProp.Name, returnTypeProp.PropertyType, stepNumber)); } this.steps.Add(new WorkflowStepWrapper { ExecutionMethod = runMethod, ExecutionParameters = args, StepNumber = stepNumber, WorkflowStep = step}); }
public void ShouldParseWorkflowRunStepWithTimeout() { //Arrange var stepsResolver = A.Fake <IWorkflowStepResolver>(); var options = new WorkflowRunStepOptions { Timeout = 2400 }; var steps = new IWorkflowStep[] { new WorkflowRunStep { Name = "step-1", Command = "command-1", Options = options } }; var expectedWorkflow = new Workflow(); expectedWorkflow.Stages = new Dictionary <string, WorkflowStage> { { "Build", new WorkflowStage { Steps = steps } } }; A.CallTo(() => stepsResolver.Resolve(A <IReadOnlyCollection <string> > .Ignored)).Returns(typeof(WorkflowRunStep)); var parser = new WorkflowParser(stepsResolver); //Act var workflow = parser.Parse(@" stages: Build: steps: - name: step-1 run: command-1 with: timeout: 2400 "); //Assert workflow.Should().BeEquivalentTo(expectedWorkflow); }
private void AddWorkflowStateInfoByCondition(string workflowName, IWorkflowStep workflowStep) { var workflowStateEntity = GetWorkflowStateInfoByCondition(workflowName, workflowStep.StepId); if (workflowStateEntity == null) { workflowStateEntity = new WorkflowStateInfoModel { CreateDateTime = DateTime.Now, LastUpdateDateTime = DateTime.Now, StateNodeName = workflowStep.StepId, StateNodeDisplayName = workflowStep.StepId, WorkflowName = workflowName, WorkflowDisplayName = workflowName }; DataOperationBLL.Current.Insert(workflowStateEntity); } else { workflowStateEntity.WorkflowDisplayName = workflowName; workflowStateEntity.StateNodeDisplayName = workflowStep.StepId; //Todo: modify workflowStateInfo DataOperationBLL.Current.Modify(workflowStateEntity); } }
public ParallelStepBuilder(IWorkflowBuilder <TData> workflowBuilder, IStepBuilder <TData, TStepBody> stepBuilder, IStepBuilder <TData, Sequence> referenceBuilder) { WorkflowBuilder = workflowBuilder; Step = stepBuilder.Step; _stepBuilder = stepBuilder; _referenceBuilder = referenceBuilder; }
public void ShouldParseWorkflowRunStepWithExpression() { //Arrange var stepsResolver = A.Fake <IWorkflowStepResolver>(); var expectedSteps = new IWorkflowStep[] { new WorkflowRunStep { Name = "step-1", Command = "./output/${{ jeeves.inputs.exeName }}" } }; var expectedWorkflow = new Workflow(); expectedWorkflow.Stages = new Dictionary <string, WorkflowStage> { { "Build", new WorkflowStage { Steps = expectedSteps } } }; A.CallTo(() => stepsResolver.Resolve(A <IReadOnlyCollection <string> > .Ignored)).Returns(typeof(WorkflowRunStep)); var parser = new WorkflowParser(stepsResolver); //Act var workflow = parser.Parse(@" stages: Build: steps: - name: step-1 run: ./output/${{ jeeves.inputs.exeName }} "); //Assert workflow.Should().BeEquivalentTo(expectedWorkflow); }
public void ShouldParseWorkflowRunStep() { //Arrange var stepsResolver = A.Fake <IWorkflowStepResolver>(); var expectedSteps = new IWorkflowStep[] { new WorkflowAssertStep { Name = "step-1", Assert = "assert-1" } }; var expectedWorkflow = new Workflow(); expectedWorkflow.Stages = new Dictionary <string, WorkflowStage> { { "Build", new WorkflowStage { Steps = expectedSteps } } }; A.CallTo(() => stepsResolver.Resolve(A <IReadOnlyCollection <string> > .Ignored)).Returns(typeof(WorkflowAssertStep)); var parser = new WorkflowParser(stepsResolver); //Act var workflow = parser.Parse(@" stages: Build: steps: - name: step-1 assert: assert-1 "); //Assert workflow.Should().BeEquivalentTo(expectedWorkflow); }
public async Task <WorkflowStepState> Execute(IWorkflowStep step, WorkflowContext context, IList <StepParam> sParams) { context.CurrentStepsIds = new[] { step.Id }; contextInjector.InjectInstanceContextInStep(CreateWorkflowInstanceContext(context), step, sParams); contextInjector.InjectInputParametersInStep(context, step, sParams); if (context.RequiredParameters.Any()) { return(WorkflowStepState.InputRequired); } var state = await step.Execute(); CheckStepState(step, context, state, sParams); return(state); }
private void CheckStepState(IWorkflowStep step, WorkflowContext context, WorkflowStepState state, IList <StepParam> sParams) { if (state == WorkflowStepState.InputRequired) { // Set the local context if (!context.LocalContexts.ContainsKey(step.Id)) { context.LocalContexts.Add(step.Id, new JObject()); } contextInjector.SetLocalContext(step, context, sParams); } else { context.CurrentStepsIds = null; } contextInjector.SetOutputParameters(step, context, sParams); }
public void ShouldParseWorkflowStageSteps() { //Arrange var stepsResolver = A.Fake <IWorkflowStepResolver>(); var expectedSteps = new IWorkflowStep[] { new WorkflowRunStep { Name = "step-1", Command = "command-1" }, new WorkflowAssertStep { Name = "step-2", Assert = "assert-2" } }; var expectedWorkflow = new Workflow { Stages = new Dictionary <string, WorkflowStage> { { "Build", new WorkflowStage { Steps = expectedSteps } } } }; A.CallTo(() => stepsResolver.Resolve(A <IReadOnlyCollection <string> > .Ignored)).ReturnsLazily(args => { var properties = args.GetArgument <IReadOnlyCollection <string> >(0); return(properties !.Contains("run", StringComparer.OrdinalIgnoreCase) ? typeof(WorkflowRunStep) : typeof(WorkflowAssertStep)); }); var parser = new WorkflowParser(stepsResolver); //Act var workflow = parser.Parse(@" stages: Build: steps: - name: step-1 run: command-1 - name: step-2 assert: assert-2 "); //Assert workflow.Should().BeEquivalentTo(expectedWorkflow); }
/// <summary> /// Adds a step to the workflow. /// </summary> /// <param name="step">The step to add. Must contain a method called "run" which returns a type derived from WorkflowStepResult.</param> /// <param name="stepNumber">The step number</param> protected void Add(IWorkflowStep step, int stepNumber) { var type = step.GetType(); // get the method called 'run' var runMethod = type.GetMethod("Run"); // get the return type of the method var returnType = runMethod.ReturnType; // insure that the type it returns derives from workflowsStepResult if (returnType.BaseType != typeof(WorkflowStepResult)) { throw new WorkflowStepAdditionException("Attempted to add a workflow step that did not return a type derived from WorkflowStepBase"); } var args = runMethod.GetParameters(); // if there are args (there might not be any) // see if there are any available types that have the same name (ignoring case) and same type. There should only ever be exactly 1 if (args.Any() && args.Any(arg => availableParams.Count(at => String.Compare(arg.Name, at.Item1, StringComparison.OrdinalIgnoreCase) == 0 && arg.ParameterType == at.Item2 && at.Item3 <= stepNumber) != 1)) { throw new WorkflowStepAdditionException("Attempted to add a workflow step that would be unable to execute."); } // setup the available args // get the returnType properties, in order to filter them out. var unusableTypeList = this.GetWorkflowStepResultPropertyBlacklist(); var returnTypeProps = returnType.GetProperties().ToList().Where(p => !unusableTypeList.Contains(p.Name)).ToList(); foreach (var returnTypeProp in returnTypeProps) { // must add one to the available step, because otherwise, it would be passing something to itself, which wouldn't be correct; // the value will be null to start with. availableParams.Add(Tuple.Create(returnTypeProp.Name, returnTypeProp.PropertyType, stepNumber)); } this.steps.Add(new WorkflowStepWrapper { ExecutionMethod = runMethod, ExecutionParameters = args, StepNumber = stepNumber, WorkflowStep = step }); }
private void AddWorkflowStateInfoByCondition(string workflowName, IWorkflowStep workflowStep) { var workflowStateEntity = GetWorkflowStateInfoByCondition(workflowName, workflowStep.StepId); if (workflowStateEntity == null) { workflowStateEntity = new WorkflowStateInfoModel { CreateDateTime = DateTime.Now, LastUpdateDateTime = DateTime.Now, StateNodeName = workflowStep.StepId, StateNodeDisplayName = workflowStep.StepId, WorkflowName = workflowName, WorkflowDisplayName = workflowName }; DataOperationBLL.Current.Insert(workflowStateEntity); } else { workflowStateEntity.WorkflowDisplayName = workflowName; workflowStateEntity.StateNodeDisplayName = workflowStep.StepId; //Todo: modify workflowStateInfo DataOperationBLL.Current.Modify(workflowStateEntity); } }
public StepBuilder(IWorkflowBuilder <TData> workflowBuilder, IWorkflowStep <TStepBody> step) { WorkflowBuilder = workflowBuilder; Step = step; }
public StepResponse(IWorkflowStep next) : this(true, "", next) { }
private StepResponse(bool success, string message, IWorkflowStep nextStep) { this.Success = success; this.Message = message; NextStep = nextStep; }
public void Add(IWorkflowStep step) { _workflowSteps.Add(step); }
public void Remove(IWorkflowStep step) { _workflowSteps.Remove(step); }
public StepResponse(IWorkflowStep next, string message) : this(true, message, next) { }