/// <summary>
        /// Compiles all decision nodes code and loops code in the given experiment
        /// </summary>
        /// <param name="experiment">The experiment.</param>
        /// <param name="availableInputMappingsPerNode">The available input mappings per node.</param>
        /// <param name="workspaceTypesDirectories">The workspace types directories.</param>
        /// <param name="loggerNameRoot">The logger name root.</param>
        /// <returns>
        /// true if there were no errors, otherwise false
        /// </returns>
        public static bool CompileAllDecisionNodes(IExperiment experiment, InputMappings availableInputMappingsPerNode, 
                                                   List<string> workspaceTypesDirectories, LoggerNameRoot loggerNameRoot)
        {
            bool noErrors = true;

            foreach (ExperimentNode node in experiment.Vertices)
            {
                IDecision decisionMetadata = node.Data.Metadata as IDecision;
                if (decisionMetadata != null)
                {
                    try
                    {
                        //build successor nodes label id lookup
                        Dictionary<string, string> successorNodeLabelIdLookup = PrepareSuccessorNodesLabelIdLookup(node, experiment);
                        Dictionary<string, string> predeccessorsOutputsNameTypeLookup = PreparePredeccessorsOutputsNameTypeLookup(node, availableInputMappingsPerNode);

                        node.ClearError();

                        BuildSourceAndCompileDecisionModule(decisionMetadata, successorNodeLabelIdLookup,
                            predeccessorsOutputsNameTypeLookup, workspaceTypesDirectories, loggerNameRoot);
                    }
                    catch (ArgumentException ex)
                    {
                        noErrors = false;
                        node.SetError(ex.Message);
                    }
                }
            }

            return noErrors;
        }
        /// <summary>
        /// Creates the Runnable node with a specific id based on the given metadata.
        /// Uses Composite Component Metadata config values to override Components config values in subgraph.
        /// </summary>
        /// <param name="id">The id of the node.</param>
        /// <param name="metadata">The component metadata.</param>
        /// <param name="loggerNameRoot">The logger name root - needed so that the logs are specific per experiment and experiment window.</param>
        /// <param name="library">The library of components.</param>
        /// <param name="componentsAppDomain">The components app domain is the app domain which components assemblies are going to be loaded into.</param>
        /// <param name="terminateExperimentExecutionResetEvent">The event that allows signalling termination of the experiment;
        /// Needed for the composite components sublevel experiments, so that they hold the referance to the same termination event as top level experiment</param>
        /// <returns>
        /// Created node
        /// </returns>
        public override RunnableNode CreateNode(String id, Metadata metadata, LoggerNameRoot loggerNameRoot, ComponentsLibrary library,
                                                AppDomain componentsAppDomain, System.Threading.ManualResetEvent terminateExperimentExecutionResetEvent)
        {
            RunnableNode retNode;

            ComponentMetadata originalComponentMetadata = metadata as ComponentMetadata;
            CompositeComponentMetadata compositeComponentMetadata = metadata as CompositeComponentMetadata;

            if (originalComponentMetadata != null)
            {
                ComponentMetadata overrideComponentMetadata = (ComponentMetadata)originalComponentMetadata.Clone();
                OverrideConfigValues(id, overrideComponentMetadata);
                retNode = base.CreateNode(id, overrideComponentMetadata, loggerNameRoot, library, componentsAppDomain, terminateExperimentExecutionResetEvent);
            }
            else if (compositeComponentMetadata != null)
            {
                OverrideConfigValues(id, compositeComponentMetadata);
                retNode = base.CreateCompositeComponentNode(id, compositeComponentMetadata, loggerNameRoot, library, componentsAppDomain, terminateExperimentExecutionResetEvent);
            }
            else
            {
                retNode = base.CreateNode(id, metadata, loggerNameRoot, library, componentsAppDomain, terminateExperimentExecutionResetEvent);
            }

            return retNode;
        }
        /// <summary>
        /// Validates the entire experiment.
        /// It validates the structure of the experimental graph,
        /// validates all inputs and outputs,
        /// checks if all components are in the component library.
        /// </summary>
        /// <param name="experiment">The experiment.</param>
        /// <param name="vertices">The vertices, that has been parsed from the start node. Nodes that are not connected to the start are being skipped.</param>
        /// <param name="edges">The edges, that has been parsed from the start node.</param>
        /// <returns>
        /// true if there is no errors, false, if errors has been detected
        /// </returns>
        public static bool ValidateExperiment(IExperiment experiment, out List<ExperimentNode> vertices, out List<ExperimentNodeConnection> edges,
                                              List<string> workspaceTypesDirectories, bool validateInputMapping, LoggerNameRoot loggerNameRoot)
        {
            bool noErrors = GraphValidator.Validate(experiment, out vertices, out edges);

            if (noErrors)
            {
                var availableInputMappingsPerNode = new TraceLab.Core.Utilities.InputMappings(experiment);
                if (validateInputMapping)
                {
                    noErrors = InputMappingValidator.Validate(experiment, availableInputMappingsPerNode);
                }
                
                if (noErrors)
                {
                    //recompile all decisions
                    noErrors = TraceLab.Core.Decisions.DecisionCompilationRunner.CompileAllDecisionNodes(experiment, availableInputMappingsPerNode, 
                                                                                                            workspaceTypesDirectories, loggerNameRoot);
                }
            }

            if (noErrors)
            {
                noErrors = ValidComponents(vertices);
            }
            
            return noErrors;
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Creates the logger for the given metadata and node id
        /// </summary>
        /// <param name="loggerNameRoot">The logger name root.</param>
        /// <param name="nodeId">The node id.</param>
        /// <param name="loggableMetadata">The metadata.</param>
        /// <returns></returns>
        internal static ComponentLogger CreateLogger(LoggerNameRoot loggerNameRoot, string nodeId, ILoggable loggableMetadata)
        {
            string loggerName = GetLoggerSourceInfo(nodeId, loggableMetadata, loggerNameRoot);
            CreateLoggingRules(loggerName, loggableMetadata.LogLevels);

            if (string.IsNullOrEmpty(loggerName))
                loggerName = Guid.NewGuid().ToString();
            
            return new ComponentLoggerImplementation(loggerName);
        }
        /// <summary>
        /// Creates the Runnable node with a specific id based on the given metadata.
        /// </summary>
        /// <param name="nodeId">The node id.</param>
        /// <param name="metadata">The component metadata.</param>
        /// <param name="loggerNameRoot">The logger name root - needed so that the logs are specific per experiment and experiment window.</param>
        /// <param name="library">The library of components.</param>
        /// <param name="componentsAppDomain">The components app domain is the app domain which components assemblies are going to be loaded into.</param>
        /// <param name="terminateExperimentExecutionResetEvent">The event that allows signalling termination of the experiment; 
        /// Needed for the composite components sublevel experiments, so that they hold the referance to the same termination event as top level experiment.</param>
        /// <returns>
        /// Created node
        /// </returns>
        public virtual RunnableNode CreateNode(String nodeId, Metadata metadata, LoggerNameRoot loggerNameRoot, 
                                               ComponentsLibrary library, AppDomain componentsAppDomain, System.Threading.ManualResetEvent terminateExperimentExecutionResetEvent)
        {
            RunnableNode retNode;

            ComponentMetadata componentMetadata = metadata as ComponentMetadata;
            DecisionMetadata decisionMetadata = metadata as DecisionMetadata;
            StartNodeMetadata startNodeMetadata = metadata as StartNodeMetadata;
            EndNodeMetadata endNodeMetadata = metadata as EndNodeMetadata;
            ScopeBaseMetadata scopeMetadata = metadata as ScopeBaseMetadata;
            LoopScopeMetadata loopMetadata = metadata as LoopScopeMetadata;
            CompositeComponentMetadata compositeComponentMetadata = metadata as CompositeComponentMetadata;
            ExitDecisionMetadata exitDecisionMetadata = metadata as ExitDecisionMetadata;
            if (componentMetadata != null)
            {
                TraceLabSDK.ComponentLogger logger = TraceLab.Core.Components.LoggerFactory.CreateLogger(loggerNameRoot, nodeId, componentMetadata);
                IComponent component = library.LoadComponent(componentMetadata, Workspace, logger, componentsAppDomain);
                retNode = new RunnableComponentNode(nodeId, componentMetadata.Label, component, logger, library, componentMetadata.WaitsForAllPredecessors);
            }
            else if (decisionMetadata != null)
            {
                IDecisionModule decisionModule = DecisionModuleFactory.LoadDecisionModule(decisionMetadata, Workspace, componentsAppDomain);
                retNode = new RunnableDecisionNode(nodeId, decisionMetadata.Label, decisionModule, library, decisionMetadata.WaitsForAllPredecessors);
            }
            else if (startNodeMetadata != null)
            {
                retNode = new RunnableStartNode(nodeId);
            }
            else if (endNodeMetadata != null)
            {
                retNode = new RunnableEndNode(nodeId, endNodeMetadata.WaitsForAllPredecessors);
            }
            else if (loopMetadata != null)
            {
                retNode = CreateLoopNode(nodeId, loopMetadata, loggerNameRoot, library, componentsAppDomain, terminateExperimentExecutionResetEvent);
            }
            else if (scopeMetadata != null)
            {
                retNode = CreateScopeCompositeComponentNode(nodeId, scopeMetadata, loggerNameRoot, library, componentsAppDomain, terminateExperimentExecutionResetEvent);
            }
            else if (compositeComponentMetadata != null)
            {
                retNode = CreateCompositeComponentNode(nodeId, compositeComponentMetadata, loggerNameRoot, library, componentsAppDomain, terminateExperimentExecutionResetEvent);
            }
            else if (exitDecisionMetadata != null)
            {
                retNode = new RunnablePrimitiveNode(nodeId, exitDecisionMetadata.WaitsForAllPredecessors);
            }
            else
            {
                throw new Exceptions.InconsistentTemplateException("Could not identify node type.");
            }

            return retNode;
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Adapts the specified experiment into runnable experiment.
        /// Adapt method validates given experiment and builds runnable experiment which is going to be executed by the experiment runner.
        /// During adapation the experiment is validated.
        /// In case of detected error in the experiment, this method returns empty RunnableExperimentBase with no nodes and no edges.
        /// There are several errors that can be detected.
        /// There are nodes connected to start, but not to graph end.
        /// Loops without decisions nodes.
        /// Input mappings are incorrect.
        /// Failed component load or instantiation, especially in case of incorrect configuration values.
        /// </summary>
        /// <param name="experiment">The experiment which is going to be adapted into RunnableExperiment..</param>
        /// <param name="nodesFactory">The nodes factory, by which all nodes in runnable experiment are created..</param>
        /// <param name="library">The library of components.</param>
        /// <param name="workspaceTypeDirectories">The workspace type directories.</param>
        /// <returns>
        /// Runnable experiment that experiment is going to execute, pruned from nodes that are not connected to main flow beginning at Start node. 
        /// In case of detected error in the experiment, this method returns empty RunnableExperimentBase with no nodes and no edges.
        /// </returns>
        public static RunnableExperimentBase Adapt(IExperiment experiment, IRunnableNodeFactory nodesFactory, Components.ComponentsLibrary library, List<string> workspaceTypeDirectories)
        {
            LoggerNameRoot loggerNameRoot = new LoggerNameRoot(experiment.ExperimentInfo.Id);

            // Create the new domain for the runnable experiment with whatever current security evidence we're running with.
            // The components app domain is the app domain which components assemblies are going to be loaded into.

            var helper = new TraceLab.Core.Components.LibraryHelper(workspaceTypeDirectories);
            AppDomain componentsAppDomain = helper.CreateDomain(experiment.ExperimentInfo.Id);

            return Adapt(experiment, loggerNameRoot, nodesFactory, library, workspaceTypeDirectories, componentsAppDomain, new System.Threading.ManualResetEvent(false), true);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Creates the logger for the given metadata and node id
        /// </summary>
        /// <param name="loggerNameRoot">The logger name root.</param>
        /// <param name="nodeId">The node id.</param>
        /// <param name="loggableMetadata">The metadata.</param>
        /// <returns></returns>
        internal static ComponentLogger CreateLogger(LoggerNameRoot loggerNameRoot, string nodeId, ILoggable loggableMetadata)
        {
            string loggerName = GetLoggerSourceInfo(nodeId, loggableMetadata, loggerNameRoot);

            CreateLoggingRules(loggerName, loggableMetadata.LogLevels);

            if (string.IsNullOrEmpty(loggerName))
            {
                loggerName = Guid.NewGuid().ToString();
            }

            return(new ComponentLoggerImplementation(loggerName));
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Adapts the specified experiment into runnable experiment.
        /// Adapt method validates given experiment and builds runnable experiment which is going to be executed by the experiment runner.
        /// During adapation the experiment is validated.
        /// In case of detected error in the experiment, this method returns empty RunnableExperimentBase with no nodes and no edges.
        /// There are several errors that can be detected.
        /// There are nodes connected to start, but not to graph end.
        /// Loops without decisions nodes.
        /// Input mappings are incorrect.
        /// Failed component load or instantiation, especially in case of incorrect configuration values.
        /// </summary>
        /// <param name="experiment">The experiment which is going to be adapted into RunnableExperiment..</param>
        /// <param name="loggerNameRoot">The logger name root - needed so that the logs are specific per experiment and experiment window.</param>
        /// <param name="nodesFactory">The nodes factory, by which all nodes in runnable experiment are created..</param>
        /// <param name="library">The library of components.</param>
        /// <param name="workspaceTypeDirectories">The workspace type directories.</param>
        /// <param name="componentsAppDomain">The components app domain is the app domain which components assemblies are going to be loaded into.</param>
        /// <param name="terminateExperimentExecutionResetEvent">The event that allows signalling termination of the experiment</param>
        /// <returns>
        /// Runnable experiment that experiment is going to execute, pruned from nodes that are not connected to main flow beginning at Start node.
        /// In case of detected error in the experiment, this method returns empty RunnableExperimentBase with no nodes and no edges.
        /// </returns>
        public static RunnableExperimentBase Adapt(IExperiment experiment, LoggerNameRoot loggerNameRoot, IRunnableNodeFactory nodesFactory, 
                                                    Components.ComponentsLibrary library, List<string> workspaceTypeDirectories,
                                                    AppDomain componentsAppDomain, System.Threading.ManualResetEvent terminateExperimentExecutionResetEvent, bool validateInputMapping)
        {
            RunnableExperimentBase runnableExperiment = new RunnableExperiment(nodesFactory, library, componentsAppDomain, terminateExperimentExecutionResetEvent);

            List<ExperimentNode> vertices;
            List<ExperimentNodeConnection> edges;
            bool noErrors = ExperimentValidator.ValidateExperiment(experiment, out vertices, out edges, workspaceTypeDirectories, validateInputMapping, loggerNameRoot);

            if (noErrors)
            {
                foreach (ExperimentNode node in vertices)
                {
                    try
                    {
                        runnableExperiment.AddNode(node.ID, node.Data.Metadata, loggerNameRoot);
                    }
                    catch (TraceLab.Core.Exceptions.IncorrectSubTemplateException ex)
                    {
                        runnableExperiment.Clear();
                        noErrors = false;
                        NLog.LogManager.GetCurrentClassLogger().Error(ex.Message);
                        node.SetError(ex.Message);
                        break;
                    }
                    catch (Exception ex)
                    {
                        runnableExperiment.Clear();
                        noErrors = false;
                        string msg = "Unable to initialize component: " + ex.Message;
                        NLog.LogManager.GetCurrentClassLogger().Error(msg, ex);
                        node.SetError(msg);
                        break;
                    }
                }
            }

            if (noErrors)
            {
                foreach (ExperimentNodeConnection edge in edges)
                {
                    runnableExperiment.AddDirectedEdge(edge.Source.ID, edge.Target.ID);
                }

            } 
            
            return runnableExperiment;
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Gets the name of the logger constructed from several parts.
        /// </summary>
        /// <param name="nodeId">The node id.</param>
        /// <param name="loggerNameRoot">The logger name root.</param>
        /// <param name="componentName">Name of the component.</param>
        /// <param name="sourceAssembly">The source assembly.</param>
        /// <param name="componentLabel">The component label.</param>
        /// <returns></returns>
        private static string GetLoggerSourceInfo(string nodeId, LoggerNameRoot loggerNameRoot, string componentName, string sourceAssembly, string componentLabel)
        {
            string loggerName;

            if (String.IsNullOrEmpty(loggerNameRoot.UserFriendlyRoot))
            {
                //skip the user friendly root
                loggerName = String.Format("{0}:{1}::Classname:{2}::SourceAssembly:{3}::Label:{4}", loggerNameRoot.ExperimentPathRoot, nodeId, componentName, sourceAssembly, componentLabel);
            }
            else
            {
                //otherwise show user friendly root
                loggerName = String.Format("{0}:{1}::Classname:{2}::SourceAssembly:{3}::Label:{4} : {5}", loggerNameRoot.ExperimentPathRoot, nodeId, componentName, sourceAssembly, loggerNameRoot.UserFriendlyRoot, componentLabel);
            }

            return(loggerName);
        }
 /// <summary>
 /// Compiles the code of the single decision node or loop scope node. It handles DecisionNode and LoopScopeNode slightly differently.
 /// Method.
 /// </summary>
 /// <param name="node">The node.</param>
 /// <param name="experiment">The experiment.</param>
 /// <param name="workspaceTypesDirectories">The workspace types directories.</param>
 /// <param name="loggerNameRoot">The logger name root.</param>
 public static void CompileDecision(ExperimentNode node, IExperiment experiment, List<string> workspaceTypesDirectories, LoggerNameRoot loggerNameRoot)
 {
     ExperimentDecisionNode decisionNode = node as ExperimentDecisionNode;
     if (decisionNode != null)
     {
         Dictionary<string, string> successorNodeLabelIdLookup = PrepareSuccessorNodesLabelIdLookup(node, experiment);
         CompileDecisionInternal(decisionNode, experiment, workspaceTypesDirectories, loggerNameRoot, successorNodeLabelIdLookup);
     }
     else
     {
         LoopScopeNode loopScopeNode = node as LoopScopeNode;
         if (loopScopeNode != null)
         {
             //loop scope does not need successor nodes lookups, so pass in empty dictionary
             Dictionary<string, string> successorNodeLabelIdLookup = new Dictionary<string, string>();
             CompileDecisionInternal(loopScopeNode, experiment, workspaceTypesDirectories, loggerNameRoot, successorNodeLabelIdLookup);
         }
     }
 }
Ejemplo n.º 11
0
        /// <summary>
        /// Gets the name of the logger constructed from several parts.
        /// </summary>
        /// <param name="nodeId">The node id.</param>
        /// <param name="loggerNameRoot">The logger name root.</param>
        /// <param name="componentName">Name of the component.</param>
        /// <param name="sourceAssembly">The source assembly.</param>
        /// <param name="componentLabel">The component label.</param>
        /// <returns></returns>
        private static string GetLoggerSourceInfo(string nodeId, LoggerNameRoot loggerNameRoot, string componentName, string sourceAssembly, string componentLabel)
        {
            string loggerName;
            if (String.IsNullOrEmpty(loggerNameRoot.UserFriendlyRoot))
            {
                //skip the user friendly root
                loggerName = String.Format("{0}:{1}::Classname:{2}::SourceAssembly:{3}::Label:{4}", loggerNameRoot.ExperimentPathRoot, nodeId, componentName, sourceAssembly, componentLabel);
            }
            else
            {
                //otherwise show user friendly root
                loggerName = String.Format("{0}:{1}::Classname:{2}::SourceAssembly:{3}::Label:{4} : {5}", loggerNameRoot.ExperimentPathRoot, nodeId, componentName, sourceAssembly, loggerNameRoot.UserFriendlyRoot, componentLabel);
            }

            return loggerName;
        }
Ejemplo n.º 12
0
 /// <summary>
 /// Gets the logger source info.
 /// </summary>
 /// <param name="nodeId">The node id.</param>
 /// <param name="loggableMetadata">The loggable metadata.</param>
 /// <param name="loggerNameRoot">The logger name root.</param>
 /// <returns></returns>
 private static string GetLoggerSourceInfo(string nodeId, ILoggable loggableMetadata, LoggerNameRoot loggerNameRoot)
 {
     return GetLoggerSourceInfo(nodeId,
                          loggerNameRoot,
                          loggableMetadata.Classname,
                          loggableMetadata.SourceAssembly,
                          loggableMetadata.Label);
 }
        /// <summary>
        /// Handles the event of Check Code Button Click.
        /// It compiles decision code.
        /// </summary>
        /// <param name="sender">Sender.</param>
        /// <param name="e">E.</param>
        protected void CheckCode (object sender, EventArgs e)
        {
            List<string> workspaceTypeDirectories = m_applicationContext.Application.WorkspaceViewModel.WorkspaceTypeDirectories;
            Experiment experiment = m_applicationContext.Application.Experiment;
            LoggerNameRoot loggerNameRoot = new LoggerNameRoot(experiment.ExperimentInfo.Id);

            //compile decision - the result is set in metadata Compilation Status, and eventual message in Error
            TraceLab.Core.Decisions.DecisionCompilationRunner.CompileDecision(m_decisionControl.ExperimentNode, 
                                                                              experiment, 
                                                                              workspaceTypeDirectories, 
                                                                              loggerNameRoot);

            //retrieve compilation status from metadata
            if(m_metadata.CompilationStatus == CompilationStatus.Successful) 
            {
                this.errorTextView.ShowInfoMessage("Compilation successful!");
            } 
            //otherwise error displays on ErrorChanged event - see HandleErrorChanged method
        }
 /// <summary>
 /// Adds the node.
 /// </summary>
 /// <param name="id">The id.</param>
 /// <param name="metadata">The metadata.</param>
 public override void AddNode(String id, Metadata metadata, LoggerNameRoot loggerNameRoot)
 {
     // adds a node to the graph
     RunnableNode node = m_nodesFactory.CreateNode(id, metadata, loggerNameRoot, Library, ComponentsAppDomain, TerminateExperimentExecutionResetEvent);
     if (node is RunnableStartNode)
     {
         //allow set only once
         if (m_startNode != null)
         {
             throw new TraceLab.Core.Exceptions.InconsistentTemplateException("Template cannot have two start nodes defined.");
         }
         m_startNode = node;
     }
     if (node is RunnableEndNode)
     {
         //allow set only once
         if (m_endNode != null)
         {
             throw new TraceLab.Core.Exceptions.InconsistentTemplateException("Template cannot have two end nodes defined.");
         }
         m_endNode = node;
     }
     m_nodes.Add(node);
 }
        /// <summary>
        /// Compiles the decision module func.
        /// </summary>
        /// <param name="param">The param.</param>
        private void CompileDecisionModuleFunc(object param)
        {
            var args = param as List<object>;
            if (args != null && args.Count == 2)
            {
                //validate args
                var node = args[0] as ExperimentNode;
                var appVM = args[1] as ApplicationViewModelWrapper;

                if (node != null && appVM != null)
                {
                    List<string> workspaceTypeDirectories = appVM.WorkspaceViewModel.WorkspaceTypeDirectories;
                    string topExperimentId = appVM.ExperimentViewModel.TopLevel.ExperimentInfo.Id;
                    LoggerNameRoot loggerNameRoot = new LoggerNameRoot(topExperimentId);

                    TraceLab.Core.Decisions.DecisionCompilationRunner.CompileDecision(node, m_experiment, workspaceTypeDirectories, loggerNameRoot);
                }
            }
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Creates the scope composite component node. It actually returns the composite component, but with different nested workspace wrapper.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <param name="loopScopeMetadata">The scope metadata.</param>
        /// <param name="loggerNameRoot">The logger name root.</param>
        /// <param name="library">The library.</param>
        /// <param name="componentsAppDomain">The components app domain.</param>
        /// <param name="terminateExperimentExecutionResetEvent">The terminate experiment execution reset event.</param>
        /// <returns></returns>
        protected RunnableNode CreateLoopNode(string id, LoopScopeMetadata loopScopeMetadata, LoggerNameRoot loggerNameRoot,
                                                                 ComponentsLibrary library, AppDomain componentsAppDomain,
                                                                 System.Threading.ManualResetEvent terminateExperimentExecutionResetEvent)
        {
            ScopeNestedWorkspaceWrapper workspaceWrapper = WorkspaceWrapperFactory.CreateCompositeComponentWorkspaceWrapper(loopScopeMetadata, Workspace, id, componentsAppDomain);

            //scope can standard runnable factory, unlike the composite component
            IRunnableNodeFactory nodesFactory = new RunnableNodeFactory(workspaceWrapper);

            RunnableExperimentBase subExperiment = ConstructSubExperiment(loopScopeMetadata, loggerNameRoot, library, componentsAppDomain, terminateExperimentExecutionResetEvent, nodesFactory);

            ILoopDecisionModule decisionModule = DecisionModuleFactory.LoadDecisionModule(loopScopeMetadata, Workspace, componentsAppDomain);
            return new RunnableLoopNode(id, decisionModule, loopScopeMetadata, subExperiment, workspaceWrapper, library, loopScopeMetadata.WaitsForAllPredecessors);
        }
Ejemplo n.º 17
0
 public RunnableNode CreateNode(string id, Metadata metadata, LoggerNameRoot loggerNameRoot, TraceLab.Core.Components.ComponentsLibrary library, AppDomain componentsAppDomain,
     System.Threading.ManualResetEvent terminateExperimentExecutionResetEvent)
 {
     return CreateNode(id, metadata, terminateExperimentExecutionResetEvent);
 }
Ejemplo n.º 18
0
 /// <summary>
 /// Gets the logger source info.
 /// </summary>
 /// <param name="nodeId">The node id.</param>
 /// <param name="loggableMetadata">The loggable metadata.</param>
 /// <param name="loggerNameRoot">The logger name root.</param>
 /// <returns></returns>
 private static string GetLoggerSourceInfo(string nodeId, ILoggable loggableMetadata, LoggerNameRoot loggerNameRoot)
 {
     return(GetLoggerSourceInfo(nodeId,
                                loggerNameRoot,
                                loggableMetadata.Classname,
                                loggableMetadata.SourceAssembly,
                                loggableMetadata.Label));
 }
 /// <summary>
 /// Adds the node.
 /// </summary>
 /// <param name="id">The id.</param>
 /// <param name="metadata">The metadata.</param>
 /// <param name="loggerNameRoot">The logger name root.</param>
 public abstract void AddNode(String id, Metadata metadata, LoggerNameRoot loggerNameRoot);
 /// <summary>
 /// Validates the entire experiment. 
 /// It validates the structure of the experimental graph, 
 /// validates all inputs and outputs, 
 /// checks if all components are in the component library.
 /// </summary>
 /// <param name="experiment">The experiment.</param>
 /// <returns>true if there is no errors, false, if errors has been detected</returns>
 public static bool ValidateExperiment(IExperiment experiment, List<string> workspaceTypesDirectories, LoggerNameRoot loggerNameRoot)
 {
     List<ExperimentNode> vertices;
     List<ExperimentNodeConnection> edges;
     return ValidateExperiment(experiment, out vertices, out edges, workspaceTypesDirectories, true, loggerNameRoot);
 }
Ejemplo n.º 21
0
 /// <summary>
 /// Creates the composite component node.
 /// </summary>
 /// <param name="id">The id.</param>
 /// <param name="compositeComponentMetadata">The composite component metadata.</param>
 /// <param name="loggerNameRoot">The logger name root - needed so that the logs are specific per experiment and experiment window.</param>
 /// <param name="library">The library of components.</param>
 /// <param name="componentsAppDomain">The components app domain is the app domain which components assemblies are going to be loaded into.</param>
 /// <param name="terminateExperimentExecutionResetEvent">The event that allows signalling termination of the experiment; The sublevel experiments hold the referance to the same termination event as top level experiment.</param>
 /// <returns>
 /// Created composite component node
 /// </returns>
 protected RunnableNode CreateCompositeComponentNode(string id, CompositeComponentMetadata compositeComponentMetadata, LoggerNameRoot loggerNameRoot,
                                                     ComponentsLibrary library, AppDomain componentsAppDomain, 
                                                     System.Threading.ManualResetEvent terminateExperimentExecutionResetEvent)
 {
     NestedWorkspaceWrapper workspaceWrapper = WorkspaceWrapperFactory.CreateCompositeComponentWorkspaceWrapper(compositeComponentMetadata, Workspace, id, componentsAppDomain);
     NodesFactoryOfSubGraph nodesFactoryOfSubGraph = new NodesFactoryOfSubGraph(compositeComponentMetadata, workspaceWrapper);
     
     RunnableExperimentBase subExperiment = ConstructSubExperiment(compositeComponentMetadata, loggerNameRoot, library, 
                                                     componentsAppDomain, terminateExperimentExecutionResetEvent, nodesFactoryOfSubGraph);
     
     return new RunnableCompositeComponentNode(id, compositeComponentMetadata, subExperiment, workspaceWrapper, library, compositeComponentMetadata.WaitsForAllPredecessors);
 }
        /// <summary>
        /// Compiles the decision.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="experiment">The experiment.</param>
        /// <param name="workspaceTypesDirectories">The workspace types directories.</param>
        /// <param name="loggerNameRoot">The logger name root.</param>
        private static void CompileDecisionInternal(ExperimentNode node, IExperiment experiment, List<string> workspaceTypesDirectories, 
                                                    LoggerNameRoot loggerNameRoot, Dictionary<string, string> successorNodeLabelIdLookup)
        {
            InputMappings availableInputMappingsPerNode = new InputMappings(experiment);

            Dictionary<string, string> predeccessorsOutputsNameTypeLookup = PreparePredeccessorsOutputsNameTypeLookup(node, availableInputMappingsPerNode);

            IDecision decisionMetadata = (IDecision)node.Data.Metadata;
            try
            {
                if (decisionMetadata != null)
                {
                    node.ClearError();

                    BuildSourceAndCompileDecisionModule(decisionMetadata, successorNodeLabelIdLookup, predeccessorsOutputsNameTypeLookup, workspaceTypesDirectories, loggerNameRoot);

                    decisionMetadata.CompilationStatus = TraceLab.Core.Components.CompilationStatus.Successful;
                }
            }
            catch (ArgumentException ex)
            {
                decisionMetadata.CompilationStatus = TraceLab.Core.Components.CompilationStatus.Failed;
                node.SetError(ex.Message);
            }
        }
Ejemplo n.º 23
0
        /// <summary>
        /// Constructs the sub experiment.
        /// </summary>
        /// <param name="compositeComponentMetadata">The composite component metadata.</param>
        /// <param name="loggerNameRoot">The logger name root.</param>
        /// <param name="library">The library.</param>
        /// <param name="componentsAppDomain">The components app domain.</param>
        /// <param name="terminateExperimentExecutionResetEvent">The terminate experiment execution reset event - must be the same as top level experiment termination event.</param>
        /// <param name="nodesFactoryOfSubGraph">The nodes factory of sub graph.</param>
        /// <returns></returns>
        private RunnableExperimentBase ConstructSubExperiment(CompositeComponentBaseMetadata compositeComponentMetadata, LoggerNameRoot loggerNameRoot, 
                                                ComponentsLibrary library, AppDomain componentsAppDomain, 
                                                System.Threading.ManualResetEvent terminateExperimentExecutionResetEvent, IRunnableNodeFactory nodesFactoryOfSubGraph)
        {
            //add to experiment id the owner node id to make it unique
            LoggerNameRoot compositeComponentNodeLoggerNameRoot = loggerNameRoot.CreateLoggerNameRootForCompositeNode(compositeComponentMetadata);

            RunnableExperimentBase subExperiment = GraphAdapter.Adapt(compositeComponentMetadata.ComponentGraph, compositeComponentNodeLoggerNameRoot,
                                                                        nodesFactoryOfSubGraph, library, Workspace.TypeDirectories,
                                                                        componentsAppDomain, terminateExperimentExecutionResetEvent, false);

            if (subExperiment.IsEmpty)
            {
                throw new TraceLab.Core.Exceptions.IncorrectSubTemplateException("Unable to execute subexperiment due to errors.");
            }
            return subExperiment;
        }
        /// <summary>
        /// Builds the source of decision module and compile decision module into the assembly
        /// </summary>
        /// <param name="metadata">The metadata.</param>
        /// <param name="successorNodeLabelIdLookup">The successor node label id lookup.</param>
        /// <param name="predeccessorsOutputsNameTypeLookup">The predeccessors outputs name type lookup.</param>
        /// <param name="workspaceTypesDirectories">The workspace types directories.</param>
        /// <param name="loggerNameRoot">The logger name root.</param>
        private static void BuildSourceAndCompileDecisionModule(IDecision metadata, Dictionary<string, string> successorNodeLabelIdLookup,
                                            Dictionary<string, string> predeccessorsOutputsNameTypeLookup, 
                                            List<string> workspaceTypesDirectories, LoggerNameRoot loggerNameRoot)
        {
            metadata.FireRequestLatestCode();

            //create local componentlogger (ComponentLoggerImplementation implements MarshalByRefObject, thanks to which it can pass logs between appdomains
            TraceLabSDK.ComponentLogger logger = LoggerFactory.CreateLogger(loggerNameRoot, metadata.UniqueDecisionID, metadata);

            //construct the final code, and collect types assemblies locations to be referenced by the compilator
            HashSet<string> assembliesReferenceLocations;
            string finalDecisionModuleSourceCode = DecisionCodeBuilder.BuildCodeSource(metadata, workspaceTypesDirectories, 
                                successorNodeLabelIdLookup, predeccessorsOutputsNameTypeLookup, logger, out assembliesReferenceLocations);

            // Create the new domain with whatever current security evidence we're running with using the library helper
            LibraryHelper helper = new LibraryHelper(workspaceTypesDirectories);

            AppDomain newDomain = helper.CreateDomain("DecisionModuleCompilation");
            newDomain.Load(Assembly.GetExecutingAssembly().GetName());
            helper.PreloadWorkspaceTypes(newDomain);

            //// Load our output assembly into the other domain.
            DecisionModuleCompilator compiler =
                (DecisionModuleCompilator)newDomain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, typeof(DecisionModuleCompilator).FullName,
                                                                            false,
                                                                            BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.CreateInstance | BindingFlags.Instance, null,
                                                                            new object[] { },
                                                                            System.Globalization.CultureInfo.CurrentCulture, new object[] { });
            
            compiler.CompileDecisionModule(finalDecisionModuleSourceCode, metadata.SourceAssembly, assembliesReferenceLocations);

#if !MONO_DEV
            //when developing on mono in MonoDevelop application crashes when unloading appdomain.
            //it only happens from within of MonoDevelop with attached debugger. Running normally, works fine.
            AppDomain.Unload(newDomain);
#endif
        }