Exemple #1
0
 /// <summary>
 /// creates a new <see cref="AssignStateNode"/>
 /// </summary>
 /// <param name="node">node of which to assign result</param>
 /// <param name="variableName">name of variable to assign result to</param>
 /// <param name="variableoperation">operation to use when assigning variable</param>
 /// <param name="compiler">compiler to use to compile variable operation</param>
 public AssignStateNode(IInstanceNode node, string variableName, VariableOperation variableoperation, IScriptCompiler compiler)
 {
     this.node    = node;
     VariableName = variableName;
     if (variableoperation != VariableOperation.Assign)
     {
         operation = compiler.CompileCode($"$lhs{variableoperation.ToOperatorString()}$rhs", ScriptLanguage.NCScript);
     }
 }
 /// <summary>
 /// creates a new <see cref="SuspendState"/>
 /// </summary>
 /// <param name="workflow">suspended workflow</param>
 /// <param name="node">suspended node</param>
 /// <param name="variables">variables of executing workflow</param>
 /// <param name="language">default language of workflow</param>
 /// <param name="profiling">determines whether profiling is enabled</param>
 /// <param name="subflow">suspended sub workflow (optional)</param>
 public SuspendState(WorkflowIdentifier workflow, IInstanceNode node, StateVariableProvider variables, ScriptLanguage?language, bool profiling, SuspendState subflow = null)
 {
     Variables = variables;
     Node      = node;
     Subflow   = subflow;
     Language  = language;
     Profiling = profiling;
     Workflow  = workflow;
 }
Exemple #3
0
        /// <inheritdoc />
        public async Task <WorkflowInstance> BuildWorkflow(WorkflowDetails workflow)
        {
            WorkflowInstance instance = cacheservice.GetObject <WorkflowInstance, long>(workflow.Id, workflow.Revision);

            if (instance != null)
            {
                return(instance);
            }

            logger.LogInformation("Rebuilding workflow '{name}'", workflow.Name);
            int startcount = workflow.Nodes.Count(n => n.Type == NodeType.Start);

            if (startcount == 0)
            {
                throw new ArgumentException("Workflow has no start node");
            }
            if (startcount > 1)
            {
                throw new ArgumentException("Workflow has more than one start node");
            }

            StartNode startnode = null;

            Dictionary <Guid, IInstanceNode> nodes = new Dictionary <Guid, IInstanceNode>();

            foreach (NodeDetails node in workflow.Nodes)
            {
                IInstanceNode nodeinstance = await BuildNode(workflow.Language, node, node.Id);

                nodes[node.Id] = nodeinstance;

                if (nodeinstance is StartNode startinstance)
                {
                    startnode = startinstance;
                }
            }

            foreach (TransitionData transition in workflow.Transitions)
            {
                await BuildTransition(workflow, transition.OriginId, transition.TargetId, transition, id => nodes[id]);
            }

            instance = new WorkflowInstance {
                Id        = workflow.Id,
                Revision  = workflow.Revision,
                Name      = workflow.Name,
                Language  = workflow.Language,
                StartNode = startnode
            };
            cacheservice.StoreObject(workflow.Id, workflow.Revision, instance);
            return(instance);
        }
Exemple #4
0
 private void Initialize(AddressSpaceCompiler addressSpaceCompiler, IInstanceNode node, XmlQualifiedName nodeID, bool isInstanceDeclaration, int?parentAddressSpaceIndex)
 {
     Debug.Assert(node != null, "Parameter error at AddressSpaceNode creator: node cannot be null");
     Debug.Assert(nodeID != null, "NodeID cannot be null");
     ErrorList                 = new List <Diagnostics>();
     m_References              = new InstanceReferencesCollection(this);
     m_Compiler                = addressSpaceCompiler;
     m_IsInstanceDeclaration   = isInstanceDeclaration;
     m_ParentAddressSpaceIndex = parentAddressSpaceIndex;
     m_Node            = node;
     m_NodeID          = nodeID;
     AddressSpaceIndex = m_Compiler.AddNode2AddressSpace(this, m_NodeID.ToString());
     InstanceWrapper   = m_Node.DerivePropertyValuesFrom(null);
 }
        /// <summary>
        /// Adds the <see cref="IInstanceNode" /> to the collection of a type children with goal to build inheritance chain and override the attributes of the base type by the derived type.
        /// </summary>
        /// <param name="childItem">The child item of the <paramref name="modelParentNode" />.</param>
        /// <param name="modelParentNode">The model parent node - the node, which type is processed and <paramref name="childItem" /> added.</param>
        /// <param name="typeParentID">The parent identifier of the type provisioning instance declarations - prefix to the relative reference path.</param>
        void IInstanceNodesCollection.Add(IInstanceNode childItem, IInstanceNodeContext modelParentNode, XmlQualifiedName typeParentID)
        {
            XmlQualifiedName _itemNodeID       = InstanceIdentifier.AddSuffix(modelParentNode.NodeID, childItem.SymbolicName.Name);
            string           _stringItemNodeID = InstanceIdentifier.NodeId(_itemNodeID);

            if (this.m_dictionary.ContainsKey(_stringItemNodeID))
            {
                this.m_dictionary[_stringItemNodeID].AddInstanceDeclarationOf(childItem, typeParentID);
            }
            else
            {
                this.Add(_stringItemNodeID, childItem, _itemNodeID, modelParentNode.AddressSpaceIndex, true);
            }
        }
        void IInstanceNodesCollection.Add(IInstanceNode childItem, XmlQualifiedName parentNodeID, int parentAddressSpaceIndex, bool isInstanceDeclaration)
        {
            XmlQualifiedName _itemNodeID       = InstanceIdentifier.AddSuffix(parentNodeID, childItem.SymbolicName.Name);
            string           _stringItemNodeId = InstanceIdentifier.NodeId(_itemNodeID);

            if (!this.m_dictionary.ContainsKey(_stringItemNodeId))
            {
                this.Add(_stringItemNodeId, childItem, _itemNodeID, parentAddressSpaceIndex, isInstanceDeclaration);
            }
            else
            {
                string _msg = String.Format("The node {0} is declared twice and has been removed from the model", childItem.SymbolicName.ToString());
                m_compiler.Assert(false, parentAddressSpaceIndex, _msg);
            }
        }
Exemple #7
0
        /// <inheritdoc />
        public async Task <WorkflowInstance> BuildWorkflow(WorkflowStructure workflow)
        {
            logger.LogInformation("Building workflow '{name}'", workflow.Name);
            int startcount = workflow.Nodes.Count(n => n.Type == NodeType.Start);

            if (startcount == 0)
            {
                throw new ArgumentException("Workflow has no start node");
            }
            if (startcount > 1)
            {
                throw new ArgumentException("Workflow has more than one start node");
            }

            StartNode startnode = null;

            List <IInstanceNode> nodes = new List <IInstanceNode>();

            foreach (NodeData node in workflow.Nodes)
            {
                IInstanceNode nodeinstance = await BuildNode(workflow.Language, node);

                nodes.Add(nodeinstance);
                if (nodeinstance is StartNode startinstance)
                {
                    startnode = startinstance;
                }
            }

            foreach (IndexTransition transition in workflow.Transitions)
            {
                await BuildTransition(workflow, transition.OriginIndex, transition.TargetIndex, transition, i => nodes[i]);
            }

            return(new WorkflowInstance {
                Name = workflow.Name,
                StartNode = startnode,
                Language = workflow.Language
            });
        }
Exemple #8
0
        async Task <InstanceTransition> EvaluateTransitions(IInstanceNode current, WorkableLogger tasklogger, IVariableProvider variableprovider, List <InstanceTransition> transitions, CancellationToken token)
        {
            if (transitions == null)
            {
                return(null);
            }

            InstanceTransition transition = null;

            foreach (InstanceTransition conditionaltransition in transitions.Where(c => c.Condition != null))
            {
                if (await conditionaltransition.Condition.ExecuteAsync <bool>(variableprovider, token))
                {
                    transition = conditionaltransition;
                    break;
                }
            }

            if (transition == null)
            {
                InstanceTransition[] defaulttransitions = transitions.Where(t => t.Condition == null).ToArray();
                if (defaulttransitions.Length > 1)
                {
                    throw new InvalidOperationException($"More than one default transition defined for '{current.NodeName}'.");
                }
                transition = defaulttransitions.FirstOrDefault();
            }

            if (transition?.Log != null)
            {
                try {
                    tasklogger.Info(await transition.Log.ExecuteAsync <string>(variableprovider, token));
                }
                catch (Exception e) {
                    tasklogger.Error($"Error executing transition log of '{current.NodeName}'->'{transition.Target?.NodeName}'", e);
                    throw;
                }
            }
            return(transition);
        }
Exemple #9
0
 /// <summary>
 /// Adds an information model instance node <paramref name="node" /> to address space.
 /// It is used to register an existing node.
 /// </summary>
 /// <param name="node">The node to be added to the address space.</param>
 void IAddressSpaceCreator.AddNode2AddressSpace(IInstanceNode node)
 {
     new InstanceNodeContext(this, node);
 }
Exemple #10
0
 /// <summary>
 /// Adds the instance declaration of.
 /// </summary>
 /// <param name="node">The node to be duplicated by deriving from the instance declaration.</param>
 /// <param name="typeParentID">The parent identifier of the type provisioning instance declarations - prefix to the relative reference path.</param>
 void IInstanceNodeContext.AddInstanceDeclarationOf(IInstanceNode node, XmlQualifiedName typeParentID)
 {
     InstanceWrapper = InstanceWrapper.DerivePropertyValuesFrom((IInstanceDesign)node.Wrapper4PropertyGrid);
     node.AddAllReferences4InstanceDeclaration(m_References, typeParentID);
 }
Exemple #11
0
 /// <summary>
 /// Initializes a new instance of the <see cref="InstanceNodeContext"/> class that represents an instance  that is on top of inheritance chain.
 /// </summary>
 /// <param name="addressSpaceCompiler">The address space compiler.</param>
 /// <param name="node">The node.</param>
 internal InstanceNodeContext(AddressSpaceCompiler addressSpaceCompiler, IInstanceNode node)
 {
     Initialize(addressSpaceCompiler, node, node.SymbolicName, false, new Nullable <int>());
     this.RegisterInstanceNodeInAddressSpace();
 }
Exemple #12
0
 /// <summary>
 /// Initializes a new instance of the <see cref="InstanceDeclaration"/> class it represents existing child or an instance of instance declarations.
 /// </summary>
 /// <param name="space">The address space.</param>
 /// <param name="node">The node to be represented by the instance of this class.</param>
 /// <param name="nodeID">The node unique identifier - key in the directory created as the browse path.</param>
 /// <param name="parentAddressSpaceIndex">Index of the parent in the address space if exist.</param>
 /// <param name="isInstanceDeclaration">If set to <c>true</c> object of this type represents an instance declaration.</param>
 /// <param name="modelParent">The model parent.</param>
 internal InstanceNodeContext(AddressSpaceCompiler addressSpaceCompiler, IInstanceNode node, XmlQualifiedName nodeID, int?parentAddressSpaceIndex, bool isInstanceDeclaration)
 {
     Initialize(addressSpaceCompiler, node, nodeID, isInstanceDeclaration, parentAddressSpaceIndex);
 }
Exemple #13
0
        async Task <object> Execute(WorkflowInstanceState state, CancellationToken token, IInstanceNode current, object lastresult = null)
        {
            while (current != null)
            {
                try {
                    if (state.Profiling)
                    {
                        Stopwatch stopwatch = Stopwatch.StartNew();
                        lastresult = await current.Execute(state, token);

                        state.Logger.Performance(state.Workflow, current.NodeId, current.NodeName, stopwatch.Elapsed);
                    }
                    else
                    {
                        lastresult = await current.Execute(state, token);
                    }

                    if (token.IsCancellationRequested)
                    {
                        throw new TaskCanceledException();
                    }

                    // used for workflow suspension
                    if (lastresult is SuspendState)
                    {
                        return(lastresult);
                    }
                }
                catch (Exception e) {
                    state.Logger.Warning($"Error while executing node '{current.NodeName}'", e.Message);

                    InstanceTransition next = await EvaluateTransitions(current, state.Logger, new VariableProvider(state.Variables, new Variable("error", e)), current.ErrorTransitions, token);

                    if (next == null)
                    {
                        throw;
                    }

                    current = next.Target;
                    continue;
                }

                try {
                    InstanceTransition transition;
                    if (lastresult is LoopCommand)
                    {
                        if (current.LoopTransitions.Count == 0)
                        {
                            throw new InvalidOperationException("Iterator node without any loop transitions detected.");
                        }

                        transition = await EvaluateTransitions(current, state.Logger, state.Variables, current.LoopTransitions, token);

                        current = transition?.Target ?? current;
                    }
                    else
                    {
                        transition = await EvaluateTransitions(current, state.Logger, state.Variables, current.Transitions, token);

                        current = transition?.Target;
                    }
                }
                catch (Exception e) {
                    state.Logger.Warning($"Error while evaluating transitions of node '{current?.NodeName}'", e.Message);

                    InstanceTransition next = await EvaluateTransitions(current, state.Logger, new VariableProvider(state.Variables, new Variable("error", e)), current?.ErrorTransitions, token);

                    if (next == null)
                    {
                        throw;
                    }

                    current = next.Target;
                }
            }

            return(lastresult);
        }
 private void Add(string nodeId, IInstanceNode node, XmlQualifiedName nodeID, int parentAddressSpaceIndex, bool isInstanceDeclaration)
 {
     this.m_dictionary.Add(nodeId, new InstanceNodeContext(m_compiler, node, nodeID, parentAddressSpaceIndex, isInstanceDeclaration));
 }
Exemple #15
0
 public static Task <object> Execute(IInstanceNode node, IDictionary <string, object> variables = null)
 {
     variables ??= new Dictionary <string, object>();
     return(node.Execute(new WorkflowInstanceState(new WorkflowIdentifier(), new WorkableLogger(new NullLogger <NodeTest>(), new WorkableTask()), new StateVariableProvider(variables), s => null, null, null, false), CancellationToken.None));
 }