зеркало из https://github.com/microsoft/Forge.git
Merging Forge.DataContracts into Forge.TreeWalker for simplicity.
This commit is contained in:
Родитель
5075d129a6
Коммит
df0736e8fb
|
@ -64,10 +64,6 @@
|
|||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Forge.DataContracts\Forge.DataContracts.csproj">
|
||||
<Project>{c49a8494-13e5-4214-8434-708ba280c5b1}</Project>
|
||||
<Name>Forge.DataContracts</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Forge.TreeWalker\Forge.TreeWalker.csproj">
|
||||
<Project>{00fc1c22-6ae9-4f60-8a3e-05885ba34c9c}</Project>
|
||||
<Name>Forge.TreeWalker</Name>
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
<Reference Include="System.Threading.Tasks" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Runtime" />
|
||||
<Reference Include="System.Runtime.Serialization" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
|
@ -66,6 +67,7 @@
|
|||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="contracts\ForgeTree.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="src\ActionContext.cs" />
|
||||
<Compile Include="src\ActionDefinition.cs" />
|
||||
|
@ -83,14 +85,9 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
<None Include="contracts\ForgeSchemaValidationRules.json" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Forge.DataContracts\Forge.DataContracts.csproj">
|
||||
<Project>{c49a8494-13e5-4214-8434-708ba280c5b1}</Project>
|
||||
<Name>Forge.DataContracts</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
|
|
|
@ -2,16 +2,14 @@
|
|||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[assembly: InternalsVisibleTo("Forge.TreeWalker.UnitTests")]
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Forge")]
|
||||
[assembly: AssemblyTitle("Forge.TreeWalker")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Microsoft")]
|
||||
[assembly: AssemblyProduct("Forge")]
|
||||
[assembly: AssemblyProduct("Forge.TreeWalker")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2019")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
|
|
@ -0,0 +1,193 @@
|
|||
{
|
||||
"type": "object",
|
||||
"definitions": {
|
||||
"TreeDefinition": {
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
".*?": {
|
||||
"$ref": "#/definitions/TreeNodeDefinition"
|
||||
}
|
||||
}
|
||||
},
|
||||
"TreeNodeDefinition": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/definitions/SelectionTypeNodeDefinition"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/ActionTypeNodeDefinition"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/LeafTypeNodeDefinition"
|
||||
}
|
||||
]
|
||||
},
|
||||
"SelectionTypeNodeDefinition": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Type": {
|
||||
"type": "string",
|
||||
"enum": [ "Selection" ]
|
||||
},
|
||||
"ChildSelector": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/ChildSelectorDefinition"
|
||||
},
|
||||
"minItems": 1
|
||||
},
|
||||
"Properties": {
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [ "Type" ]
|
||||
},
|
||||
"ActionTypeNodeDefinition": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Type": {
|
||||
"type": "string",
|
||||
"enum": [ "Action" ]
|
||||
},
|
||||
"Timeout": {
|
||||
"type": [ "number", "string" ]
|
||||
},
|
||||
"Actions": {
|
||||
"patternProperties": {
|
||||
".*?": {
|
||||
"$ref": "#/definitions/ActionDefinition"
|
||||
}
|
||||
},
|
||||
"minProperties": 1
|
||||
},
|
||||
"ChildSelector": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/ChildSelectorDefinition"
|
||||
},
|
||||
"minItems": 1
|
||||
},
|
||||
"Properties": {
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [ "Type", "Actions" ]
|
||||
},
|
||||
"LeafTypeNodeDefinition": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Type": {
|
||||
"type": "string",
|
||||
"enum": [ "Leaf" ]
|
||||
},
|
||||
"Actions": {
|
||||
"patternProperties": {
|
||||
".*?": {
|
||||
"$ref": "#/definitions/LeafNodeSummaryActionDefinition"
|
||||
}
|
||||
},
|
||||
"minProperties": 1,
|
||||
"maxProperties": 1
|
||||
},
|
||||
"Properties": {
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [ "Type" ]
|
||||
},
|
||||
"ChildSelectorDefinition": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Label": {
|
||||
"type": "string"
|
||||
},
|
||||
"ShouldSelect": {
|
||||
"type": "string"
|
||||
},
|
||||
"Child": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [ "Label", "Child" ]
|
||||
},
|
||||
"RetryPolicy": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Type": {
|
||||
"type": "string",
|
||||
"enum": [ "None", "FixedInterval", "ExponentialBackoff" ]
|
||||
},
|
||||
"MinBackoffMs": {
|
||||
"type": "number"
|
||||
},
|
||||
"MaxBackoffMs": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"required": [ "Type" ]
|
||||
},
|
||||
"ActionDefinition": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Action": {
|
||||
"type": "string"
|
||||
},
|
||||
"Input": {
|
||||
"type": "object"
|
||||
},
|
||||
"Properties": {
|
||||
"type": "object"
|
||||
},
|
||||
"Timeout": {
|
||||
"type": [ "number", "string" ]
|
||||
},
|
||||
"ContinuationOnTimeout": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"RetryPolicy": {
|
||||
"$ref": "#/definitions/RetryPolicy"
|
||||
},
|
||||
"ContinuationOnRetryExhaustion": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [ "Action" ]
|
||||
},
|
||||
"LeafNodeSummaryActionDefinition": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Action": {
|
||||
"enum": [ "LeafNodeSummaryAction" ]
|
||||
},
|
||||
"Input": {
|
||||
"type": [ "object", "string" ],
|
||||
"properties": {
|
||||
"Status": {
|
||||
"type": "string"
|
||||
},
|
||||
"StatusCode": {
|
||||
"type": [ "number", "string" ]
|
||||
},
|
||||
"Output": {
|
||||
"type": [ "object", "string" ]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [ "Action", "Input" ]
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"Tree": {
|
||||
"$ref": "#/definitions/TreeDefinition"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
|
@ -0,0 +1,252 @@
|
|||
//-----------------------------------------------------------------------
|
||||
// <copyright file="ForgeTree.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// The Forge schema data contracts.
|
||||
// </summary>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace Forge.DataContracts
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
/// <summary>
|
||||
/// The Forge tree.
|
||||
/// This outermost data structure holds the Forge schema.
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
public class ForgeTree
|
||||
{
|
||||
/// <summary>
|
||||
/// Dictionary mapping unique TreeNodeKeys to TreeNodes.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public Dictionary<string, TreeNode> Tree { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The tree node.
|
||||
/// Holds information to navigate the tree and perform actions.
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
public class TreeNode
|
||||
{
|
||||
/// <summary>
|
||||
/// The tree node type.
|
||||
/// </summary>
|
||||
[DataMember(IsRequired = true)]
|
||||
public TreeNodeType Type { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Additional properties passed to wrapper class.
|
||||
/// String properties starting with <see cref="TreeWalkerSession.RoslynLeadingText"/> represent a code-snippet that will be evaluated.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public dynamic Properties { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The child selectors.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public ChildSelector[] ChildSelector { get; private set; }
|
||||
|
||||
#region Properties used only by TreeNodeType.Action nodes
|
||||
|
||||
/// <summary>
|
||||
/// The actions to execute when the TreeNodeType is Action.
|
||||
/// Dictionary mapping unique TreeActionKeys to TreeActions.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public Dictionary<string, TreeAction> Actions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Timeout in milliseconds for executing the TreeActions. Default to -1 (infinite) if not specified.
|
||||
/// String properties starting with <see cref="TreeWalkerSession.RoslynLeadingText"/> represent a code-snippet that will be evaluated.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public dynamic Timeout { get; set; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The child selector for the TreeNode.
|
||||
/// Used to navigate the tree by referencing child TreeNodes.
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
public class ChildSelector
|
||||
{
|
||||
/// <summary>
|
||||
/// String code-snippet that can be parsed and evaluated to a boolean value.
|
||||
/// If the expression is true, visit the attached child TreeNode.
|
||||
/// If the expression is empty, evaluate to true by default.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public string ShouldSelect { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Reader-friendly label that describes the intention of the ShouldSelect expression.
|
||||
/// Used in ForgeEditor for display purposes.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public string Label { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// String key pointer to a child TreeNode.
|
||||
/// Visit this child if the attached ShouldSelect expression evaluates to true.
|
||||
/// </summary>
|
||||
[DataMember(IsRequired = true)]
|
||||
public string Child { get; private set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The tree action for the TreeNode.
|
||||
/// Holds instructions and policies for executing an action.
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
public class TreeAction
|
||||
{
|
||||
/// <summary>
|
||||
/// String name of the action that maps to an action-task.
|
||||
/// These actions may be predefined Forge actions or action-tasks passed by a Wrapper class.
|
||||
/// </summary>
|
||||
[DataMember(IsRequired = true)]
|
||||
public string Action { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Dynamic input parameters passed to the action-task.
|
||||
/// Wrapper class is responsible for making sure the action-task input matches the input defined in the schema.
|
||||
/// String properties starting with <see cref="TreeWalkerSession.RoslynLeadingText"/> represent a code-snippet that will be evaluated.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public dynamic Input { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Additional properties passed to wrapper class.
|
||||
/// String properties starting with <see cref="TreeWalkerSession.RoslynLeadingText"/> represent a code-snippet that will be evaluated.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public dynamic Properties { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Timeout in milliseconds for executing the action. Default to -1 (infinite) if not specified.
|
||||
/// String properties starting with <see cref="TreeWalkerSession.RoslynLeadingText"/> represent a code-snippet that will be evaluated.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public dynamic Timeout { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A flag that represents how to handle the exit of the action due to timeout. If false (default), then the session will end on the
|
||||
/// timeout. If true and a timeout is hit, the action will continue on as if it were successful after committing a "TimeoutOnAction" response.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public bool ContinuationOnTimeout { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Retry policy of the action.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public RetryPolicy RetryPolicy { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A flag that represents how to handle the exit of the action due to retry exhaustion. If false (default), then the session will end once
|
||||
/// retries are exhausted or no retries are specified. If true and retries are exhausted, the action will continue on as if it were successful
|
||||
/// after committing a "RetryExhaustedOnAction" response.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public bool ContinuationOnRetryExhaustion { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The retry policy for the TreeAction.
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
public class RetryPolicy
|
||||
{
|
||||
/// <summary>
|
||||
/// The retry policy type.
|
||||
/// </summary>
|
||||
[DataMember(IsRequired = true)]
|
||||
public RetryPolicyType Type { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Minimum backoff time in milliseconds.
|
||||
/// When retrying an action, wait at least this long before your next attempt.
|
||||
/// This is useful to ensure actions are not retried too quickly.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public long MinBackoffMs { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Maximum backoff time in milliseconds.
|
||||
/// When retrying an action, wait at most this long before your next attempt.
|
||||
/// This is useful to ensure exponential backoff doesn't wait too long.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public long MaxBackoffMs { get; private set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The retry policy types.
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
public enum RetryPolicyType
|
||||
{
|
||||
/// <summary>
|
||||
/// Do not retry.
|
||||
/// </summary>
|
||||
[EnumMember]
|
||||
None = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Retry at a fixed interval every MinBackoffMs.
|
||||
/// </summary>
|
||||
[EnumMember]
|
||||
FixedInterval = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Retry with an exponential backoff.
|
||||
/// Start with MinBackoffMs, then wait Math.Min(MinBackoffMs * 2^(retryCount), MaxBackoffMs).
|
||||
/// </summary>
|
||||
[EnumMember]
|
||||
ExponentialBackoff = 2
|
||||
|
||||
// TODO: Add a FixedCount type that will give the full timeout duration for the set number of retries.
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The tree node types.
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
public enum TreeNodeType
|
||||
{
|
||||
/// <summary>
|
||||
/// Undefined.
|
||||
/// </summary>
|
||||
[EnumMember]
|
||||
Unknown = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Selection type node.
|
||||
/// </summary>
|
||||
[EnumMember]
|
||||
Selection = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Action type node.
|
||||
/// This node includes TreeAction(s).
|
||||
/// </summary>
|
||||
[EnumMember]
|
||||
Action = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Leaf type node.
|
||||
/// This represents an end state in tree.
|
||||
/// </summary>
|
||||
[EnumMember]
|
||||
Leaf = 3
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
<package id="Microsoft.CodeAnalysis.CSharp.Scripting" version="1.3.2" targetFramework="net462" />
|
||||
<package id="Microsoft.CodeAnalysis.Scripting" version="1.3.2" targetFramework="net462" />
|
||||
<package id="Microsoft.CodeAnalysis.Scripting.Common" version="1.3.2" targetFramework="net462" />
|
||||
<package id="Microsoft.CSharp" version="4.5.0" targetFramework="net462" />
|
||||
<package id="Newtonsoft.Json" version="12.0.2" targetFramework="net462" />
|
||||
<package id="System.Collections.Immutable" version="1.1.37" targetFramework="net462" />
|
||||
<package id="System.Reflection.Metadata" version="1.2.0" targetFramework="net462" />
|
||||
|
|
|
@ -371,7 +371,7 @@ namespace Forge.TreeWalker
|
|||
/// <exception cref="OperationCanceledException">If the cancellation token was triggered.</exception>
|
||||
/// <exception cref="Exception">If an unexpected exception was thrown.</exception>
|
||||
/// <returns>The key of the next child to visit, or <c>null</c> if no match was found.</returns>
|
||||
internal async Task<string> VisitNode(string treeNodeKey)
|
||||
public async Task<string> VisitNode(string treeNodeKey)
|
||||
{
|
||||
TreeNode treeNode = this.Schema.Tree[treeNodeKey];
|
||||
|
||||
|
|
|
@ -5,8 +5,6 @@ VisualStudioVersion = 16.0.29215.179
|
|||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Forge.TreeWalker", "Forge.TreeWalker\Forge.TreeWalker.csproj", "{00FC1C22-6AE9-4F60-8A3E-05885BA34C9C}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Forge.DataContracts", "Forge.DataContracts\Forge.DataContracts.csproj", "{C49A8494-13E5-4214-8434-708BA280C5B1}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Forge.TreeWalker.UnitTests", "Forge.TreeWalker.UnitTests\Forge.TreeWalker.UnitTests.csproj", "{A33AF1FF-1291-4CB1-A733-3243E1FE967E}"
|
||||
EndProject
|
||||
Global
|
||||
|
@ -19,10 +17,6 @@ Global
|
|||
{00FC1C22-6AE9-4F60-8A3E-05885BA34C9C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{00FC1C22-6AE9-4F60-8A3E-05885BA34C9C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{00FC1C22-6AE9-4F60-8A3E-05885BA34C9C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C49A8494-13E5-4214-8434-708BA280C5B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C49A8494-13E5-4214-8434-708BA280C5B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C49A8494-13E5-4214-8434-708BA280C5B1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C49A8494-13E5-4214-8434-708BA280C5B1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A33AF1FF-1291-4CB1-A733-3243E1FE967E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A33AF1FF-1291-4CB1-A733-3243E1FE967E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A33AF1FF-1291-4CB1-A733-3243E1FE967E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
|
|
Загрузка…
Ссылка в новой задаче