示例#1
0
        public IYodiiEngineResult SetDiscoveredInfo(IDiscoveredInfo info)
        {
            if (info == null)
            {
                throw new ArgumentNullException("info");
            }
            if (info == _discoveredInfo)
            {
                return(_successResult);
            }

            if (IsRunning)
            {
                var r = ConfigurationSolver.CreateAndApplyStaticResolution(this, _manager.FinalConfiguration, info, false, false, false);
                if (r.Item1 != null)
                {
                    Debug.Assert(!r.Item1.Success, "Not null means necessarily an error.");
                    Debug.Assert(r.Item1.Engine == this);
                    return(r.Item1);
                }
                return(DoDynamicResolution(r.Item2, null, null, () => DiscoveredInfo = info));
            }
            else
            {
                DiscoveredInfo = info;
            }
            return(_successResult);
        }
示例#2
0
 public YodiiEngine(IYodiiEngineHost host)
 {
     if (host == null)
     {
         throw new ArgumentNullException("host");
     }
     _successResult  = new SuccessYodiiEngineResult(this);
     _host           = host;
     _discoveredInfo = EmptyDiscoveredInfo.Empty;
     _manager        = new ConfigurationManager(this);
     _yodiiCommands  = new YodiiCommandList();
     _liveInfo       = new LiveInfo(this);
 }
示例#3
0
        /// <summary>
        /// Checks that this IDiscoveredInfo obeys to integrity constraints (see remarks).
        /// </summary>
        /// <param name="this">This discovered information.</param>
        /// <returns>True if data is valid, false otherwise.</returns>
        /// <remarks>
        /// IDiscoveredInfo constraints checked here :
        /// - IServiceInfo and IPluginInfo names are unique, in both collections (A service cannot have a plugin name, and vice-versa).
        /// - IServiceInfo generalizations do not specialize this IServiceInfo (Generalization loop).
        /// - IPluginInfo contains valid service references (cannot reference a service of its own family, outside its own tree).
        /// </remarks>
        public static bool IsValid(this IDiscoveredInfo @this)
        {
            // Check plugin and service identifiers
            HashSet <string> pluginOrServiceIds = new HashSet <string>();

            foreach (var service in @this.ServiceInfos)
            {
                if (!pluginOrServiceIds.Add(service.ServiceFullName))
                {
                    return(false); // Service name appears twice.
                }

                // Check if service is contained in its generalization tree (generalization loop)
                List <IServiceInfo> visitedServices = new List <IServiceInfo>();

                IServiceInfo g = service.Generalization;
                visitedServices.Add(service);
                while (g != null)
                {
                    if (visitedServices.Contains(g))
                    {
                        return(false); // This service is contained in its generalization tree.
                    }
                    visitedServices.Add(g);
                    g = g.Generalization;
                }
            }

            foreach (var plugin in @this.PluginInfos)
            {
                if (!pluginOrServiceIds.Add(plugin.PluginFullName))
                {
                    return(false); // Plugin name is already used.
                }

                foreach (var serviceRef in plugin.ServiceReferences)
                {
                    if (!plugin.CanReference(serviceRef.Reference))
                    {
                        return(false); // Service reference points to a service that cannot be run (same family, different branch).
                    }
                }
            }

            return(true);
        }
示例#4
0
        /// <summary>
        /// Asserts that both DiscoveredInfo are equivalent.
        /// </summary>
        /// <param name="a">A</param>
        /// <param name="b">B</param>
        public static void AssertDiscoveredInfoEquivalence(IDiscoveredInfo a, IDiscoveredInfo b)
        {
            Assert.That(a.PluginInfos.Count == b.PluginInfos.Count);
            Assert.That(a.ServiceInfos.Count == b.ServiceInfos.Count);

            foreach (var sA in a.ServiceInfos)
            {
                var sB = b.ServiceInfos.First(s => sA.ServiceFullName == s.ServiceFullName);

                AssertServiceEquivalence(sA, sB, true);
            }

            foreach (var pA in a.PluginInfos)
            {
                var pB = b.PluginInfos.First(p => pA.PluginFullName == p.PluginFullName);

                AssertPluginEquivalence(pA, pB, true);
            }

            Assert.That(a.IsValid() == b.IsValid());
        }
        /// <summary>
        /// Asserts that both DiscoveredInfo are equivalent.
        /// </summary>
        /// <param name="a">A</param>
        /// <param name="b">B</param>
        public static void AssertDiscoveredInfoEquivalence( IDiscoveredInfo a, IDiscoveredInfo b )
        {
            Assert.That( a.PluginInfos.Count == b.PluginInfos.Count );
            Assert.That( a.ServiceInfos.Count == b.ServiceInfos.Count );

            foreach( var sA in a.ServiceInfos )
            {
                var sB = b.ServiceInfos.First( s => sA.ServiceFullName == s.ServiceFullName );

                AssertServiceEquivalence( sA, sB, true );
            }

            foreach( var pA in a.PluginInfos )
            {
                var pB = b.PluginInfos.First( p => pA.PluginFullName == p.PluginFullName );

                AssertPluginEquivalence( pA, pB, true );
            }

            Assert.That( a.IsValid() == b.IsValid() );
        }
        IYodiiEngineStaticOnlyResult StaticResolution( FinalConfiguration finalConfig, IDiscoveredInfo info, bool createStaticSolvedConfigOnSuccess )
        {
            // Registering all Services.
            Step = Engine.ConfigurationSolverStep.RegisterServices;
            {
                // In order to be deterministic, works on an ordered list of IServiceInfo to build the graph.
                List<IServiceInfo> orderedServicesInfo = info.ServiceInfos.Where( s => s != null && !String.IsNullOrWhiteSpace( s.ServiceFullName ) ).OrderBy( s => s.ServiceFullName ).ToList();
                if( _revertServicesOrder ) orderedServicesInfo.Reverse();
                foreach( IServiceInfo sI in orderedServicesInfo )
                {
                    // This creates services and applies solved configuration to them: directly disabled services
                    // and specializations disabled by their generalizations' configuration are handled.
                    RegisterService( finalConfig, sI );
                }
                _orderedServices = orderedServicesInfo.Select( s => _services[s.ServiceFullName] ).ToArray();
            }

            // Service trees have been built.
            // We can now instantiate plugin data.
            Step = Engine.ConfigurationSolverStep.RegisterPlugins;
            {
                // In order to be deterministic, works on an ordered list of IPluginInfo to build the graph.
                List<IPluginInfo> orderedPluginsInfo = info.PluginInfos.Where( p => p != null ).OrderBy( p => p.PluginFullName ).ToList();
                if( _revertPluginsOrder ) orderedPluginsInfo.Reverse();
                foreach( IPluginInfo p in orderedPluginsInfo )
                {
                    RegisterPlugin( finalConfig, p );
                }
                _orderedPlugins = orderedPluginsInfo.Select( p => _plugins[p.PluginFullName] ).ToArray();
            }
            // All possible plugins are registered. Services without any available plugins are de facto disabled.
            // Propagation for each service is deferred.
            Step = Engine.ConfigurationSolverStep.OnAllPluginsAdded;
            {
                foreach( var f in _serviceFamilies )
                {
                    f.OnAllPluginsAdded();
                }
                ProcessDeferredPropagations();
            }

            // Now, we apply ServiceReference Running constraints from every plugins to their referenced services.
            Step = ConfigurationSolverStep.PropagatePluginStatus;
            {
                foreach( PluginData p in _orderedPlugins )
                {
                    if( p.FinalConfigSolvedStatus == SolvedConfigurationStatus.Running )
                    {
                        p.PropagateRunningStatus();
                    }
                }
                ProcessDeferredPropagations();
            }

            // Finalizes static resolution by computing final Runnable statuses per impact for Optional and Runnable plugins or services.
            Step = ConfigurationSolverStep.InitializeFinalStartableStatus;
            {
                foreach( ServiceData s in _orderedServices ) s.InitializeFinalStartableStatus();
                foreach( PluginData p in _orderedPlugins ) p.InitializeFinalStartableStatus();
            }

            List<PluginData> blockingPlugins = null;
            List<ServiceData> blockingServices = null;
            Step = ConfigurationSolverStep.BlockingDetection;
            {
                // Time to conclude about configuration and to initialize dynamic resolution.
                // Any Plugin that has a ConfigOriginalStatus greater or equal to Runnable and is Disabled leads to an impossible configuration.
                foreach( PluginData p in _orderedPlugins )
                {
                    if( p.Disabled )
                    {
                        if( p.ConfigOriginalStatus >= ConfigurationStatus.Runnable )
                        {
                            if( blockingPlugins == null ) blockingPlugins = new List<PluginData>();
                            blockingPlugins.Add( p );
                        }
                    }
                }

                // Any Service that has a ConfigOriginalStatus greater or equal to Runnable and is Disabled leads to an impossible configuration.
                foreach( ServiceData s in _orderedServices )
                {
                    if( s.Disabled )
                    {
                        if( s.ConfigOriginalStatus >= ConfigurationStatus.Runnable )
                        {
                            if( blockingServices == null ) blockingServices = new List<ServiceData>();
                            blockingServices.Add( s );
                        }
                    }
                }
            }
            if( blockingPlugins != null || blockingServices != null )
            {
                Step = ConfigurationSolverStep.StaticError;
                return new YodiiEngineResult( this, blockingPlugins, blockingServices, _engine );
            }
            Step = ConfigurationSolverStep.WaitingForDynamicResolution;
            if( createStaticSolvedConfigOnSuccess )
            {
                return new YodiiEngineResult( this, _engine );
            }
            return null;
        }
 internal static Tuple<IYodiiEngineStaticOnlyResult, ConfigurationSolver> CreateAndApplyStaticResolution( YodiiEngine engine, FinalConfiguration finalConfiguration, IDiscoveredInfo discoveredInfo, bool revertServices, bool revertPlugins, bool createStaticSolvedConfigOnSuccess )
 {
     ConfigurationSolver temporarySolver = new ConfigurationSolver(  engine,revertServices, revertPlugins );
     IYodiiEngineStaticOnlyResult result =  temporarySolver.StaticResolution( finalConfiguration, discoveredInfo, createStaticSolvedConfigOnSuccess );
     // StaticResolution returns null on success.
     // If there is a result, it is either an error or createStaticSolvedConfigOnSuccess is true and this is a StaticResolutionOnly: in both
     // case we do not need to keep the temporary solver.
     if( result != null ) temporarySolver = null;
     return Tuple.Create( result, temporarySolver );
 }
示例#8
0
        internal static Tuple <IYodiiEngineStaticOnlyResult, ConfigurationSolver> CreateAndApplyStaticResolution(YodiiEngine engine, FinalConfiguration finalConfiguration, IDiscoveredInfo discoveredInfo, bool revertServices, bool revertPlugins, bool createStaticSolvedConfigOnSuccess)
        {
            ConfigurationSolver          temporarySolver = new ConfigurationSolver(engine, revertServices, revertPlugins);
            IYodiiEngineStaticOnlyResult result          = temporarySolver.StaticResolution(finalConfiguration, discoveredInfo, createStaticSolvedConfigOnSuccess);

            // StaticResolution returns null on success.
            // If there is a result, it is either an error or createStaticSolvedConfigOnSuccess is true and this is a StaticResolutionOnly: in both
            // case we do not need to keep the temporary solver.
            if (result != null)
            {
                temporarySolver = null;
            }
            return(Tuple.Create(result, temporarySolver));
        }
示例#9
0
        IYodiiEngineStaticOnlyResult StaticResolution(FinalConfiguration finalConfig, IDiscoveredInfo info, bool createStaticSolvedConfigOnSuccess)
        {
            // Registering all Services.
            Step = Engine.ConfigurationSolverStep.RegisterServices;
            {
                // In order to be deterministic, works on an ordered list of IServiceInfo to build the graph.
                List <IServiceInfo> orderedServicesInfo = info.ServiceInfos.Where(s => s != null && !String.IsNullOrWhiteSpace(s.ServiceFullName)).OrderBy(s => s.ServiceFullName).ToList();
                if (_revertServicesOrder)
                {
                    orderedServicesInfo.Reverse();
                }
                foreach (IServiceInfo sI in orderedServicesInfo)
                {
                    // This creates services and applies solved configuration to them: directly disabled services
                    // and specializations disabled by their generalizations' configuration are handled.
                    RegisterService(finalConfig, sI);
                }
                _orderedServices = orderedServicesInfo.Select(s => _services[s.ServiceFullName]).ToArray();
            }

            // Service trees have been built.
            // We can now instantiate plugin data.
            Step = Engine.ConfigurationSolverStep.RegisterPlugins;
            {
                // In order to be deterministic, works on an ordered list of IPluginInfo to build the graph.
                List <IPluginInfo> orderedPluginsInfo = info.PluginInfos.Where(p => p != null).OrderBy(p => p.PluginFullName).ToList();
                if (_revertPluginsOrder)
                {
                    orderedPluginsInfo.Reverse();
                }
                foreach (IPluginInfo p in orderedPluginsInfo)
                {
                    RegisterPlugin(finalConfig, p);
                }
                _orderedPlugins = orderedPluginsInfo.Select(p => _plugins[p.PluginFullName]).ToArray();
            }
            // All possible plugins are registered. Services without any available plugins are de facto disabled.
            // Propagation for each service is deferred.
            Step = Engine.ConfigurationSolverStep.OnAllPluginsAdded;
            {
                foreach (var f in _serviceFamilies)
                {
                    f.OnAllPluginsAdded();
                }
                ProcessDeferredPropagations();
            }

            // Now, we apply ServiceReference Running constraints from every plugins to their referenced services.
            Step = ConfigurationSolverStep.PropagatePluginStatus;
            {
                foreach (PluginData p in _orderedPlugins)
                {
                    if (p.FinalConfigSolvedStatus == SolvedConfigurationStatus.Running)
                    {
                        p.PropagateRunningStatus();
                    }
                }
                ProcessDeferredPropagations();
            }

            // Finalizes static resolution by computing final Runnable statuses per impact for Optional and Runnable plugins or services.
            Step = ConfigurationSolverStep.InitializeFinalStartableStatus;
            {
                foreach (ServiceData s in _orderedServices)
                {
                    s.InitializeFinalStartableStatus();
                }
                foreach (PluginData p in _orderedPlugins)
                {
                    p.InitializeFinalStartableStatus();
                }
            }

            List <PluginData>  blockingPlugins  = null;
            List <ServiceData> blockingServices = null;

            Step = ConfigurationSolverStep.BlockingDetection;
            {
                // Time to conclude about configuration and to initialize dynamic resolution.
                // Any Plugin that has a ConfigOriginalStatus greater or equal to Runnable and is Disabled leads to an impossible configuration.
                foreach (PluginData p in _orderedPlugins)
                {
                    if (p.Disabled)
                    {
                        if (p.ConfigOriginalStatus >= ConfigurationStatus.Runnable)
                        {
                            if (blockingPlugins == null)
                            {
                                blockingPlugins = new List <PluginData>();
                            }
                            blockingPlugins.Add(p);
                        }
                    }
                }

                // Any Service that has a ConfigOriginalStatus greater or equal to Runnable and is Disabled leads to an impossible configuration.
                foreach (ServiceData s in _orderedServices)
                {
                    if (s.Disabled)
                    {
                        if (s.ConfigOriginalStatus >= ConfigurationStatus.Runnable)
                        {
                            if (blockingServices == null)
                            {
                                blockingServices = new List <ServiceData>();
                            }
                            blockingServices.Add(s);
                        }
                    }
                }
            }
            if (blockingPlugins != null || blockingServices != null)
            {
                Step = ConfigurationSolverStep.StaticError;
                return(new YodiiEngineResult(this, blockingPlugins, blockingServices, _engine));
            }
            Step = ConfigurationSolverStep.WaitingForDynamicResolution;
            if (createStaticSolvedConfigOnSuccess)
            {
                return(new YodiiEngineResult(this, _engine));
            }
            return(null);
        }