/// <summary> /// The RunAction method is called when Forge encounters an ActionName while walking the tree. /// </summary> /// <param name="actionContext">The action context holding relevant information for this Action.</param> public override async Task <ActionResponse> RunAction(ActionContext actionContext) { SubroutineInput input = (SubroutineInput)actionContext.ActionInput; // Rehydrate the subroutine's SessionId if previously persisted. SubroutineIntermediates intermediates = await actionContext.GetIntermediates <SubroutineIntermediates>(); if (intermediates == null) { intermediates = new SubroutineIntermediates() { SessionId = Guid.NewGuid() }; await actionContext.CommitIntermediates <SubroutineIntermediates>(intermediates); } // Initialize TreeWalkerSession for this subroutine. TreeWalkerSession subroutineSession = this.parameters.InitializeSubroutineTree(input, intermediates.SessionId, this.parameters); // Update KeyPrefix of ForgeState for state persistence separation. subroutineSession.Parameters.ForgeState.UpdateKeyPrefix(subroutineSession.Parameters.RootSessionId, subroutineSession.Parameters.SessionId); // Walk tree starting at CurrentTreeNode if persisted, otherwise RootTreeNodeKey if given, otherwise "Root" as default. string currentTreeNode = await subroutineSession.GetCurrentTreeNode() ?? subroutineSession.Schema.RootTreeNodeKey; // WalkTree may throw exceptions. We let this happen to allow for possible retry handling. await subroutineSession.WalkTree(currentTreeNode); // Return the subroutine's last action response if available, otherwise return tree walker Status. return(await subroutineSession.GetLastActionResponseAsync() ?? new ActionResponse() { Status = subroutineSession.Status }); }
public void TestInitialize(string jsonSchema) { // Initialize contexts, callbacks, and actions. this.sessionId = Guid.NewGuid(); this.forgeState = new ForgeDictionary(new Dictionary <string, object>(), this.sessionId); this.callbacks = new TreeWalkerCallbacks(); this.token = new CancellationTokenSource().Token; this.UserContext.Name = "MyName"; this.UserContext.ResourceType = "Container"; this.UserContext.GetCount = (Func <Int32>)(() => { return(1); }); this.UserContext.GetCountAsync = (Func <Task <Int32> >)(() => { return(Task.FromResult(2)); }); this.parameters = new TreeWalkerParameters( this.sessionId, jsonSchema, this.forgeState, this.callbacks, this.token) { UserContext = this.UserContext, ForgeActionsAssembly = typeof(CollectDiagnosticsAction).Assembly }; this.session = new TreeWalkerSession(this.parameters); }
public void Test_ExternalExecutors() { this.TestInitialize(jsonSchema: ForgeSchemaHelper.ExternalExecutors); Dictionary <string, Func <string, CancellationToken, Task <object> > > externalExecutors = new Dictionary <string, Func <string, CancellationToken, Task <object> > >(); externalExecutors.Add("External|", External); this.parameters.ExternalExecutors = externalExecutors; this.session = new TreeWalkerSession(this.parameters); // Test - WalkTree to execute an Action with an ActionInput that uses an external executor. Confirm expected results. string actualStatus = this.session.WalkTree("Root").GetAwaiter().GetResult(); Assert.AreEqual("RanToCompletion", actualStatus); ActionResponse leafActionResponse = this.session.GetLastActionResponse(); Assert.AreEqual( "StatusResult_Executed", leafActionResponse.Status, "Expected to successfully retrieve the Func output value from the action."); }