public void ReadConfiguration() { #if NET452 System.Configuration.ConfigurationManager.ConnectionStrings.SetWritable().Add(new System.Configuration.ConnectionStringSettings("RabbitMQConnectionString", "ConnString")); #endif int overrideCallsCount = 0; var settings = new NAMESettings() { ConnectionStringProviderOverride = (node) => { overrideCallsCount = overrideCallsCount + 1; return(null); } }; ParsedDependencies configuration = DependenciesReader.ReadDependencies(CONFIGURATION_FILE, new DummyFilePathMapper(), settings, new NAMEContext()); #if NET452 Assert.Equal(4, configuration.InfrastructureDependencies.Count()); Assert.Equal(2, configuration.ServiceDependencies.Count()); Assert.Equal(1, overrideCallsCount); #else Assert.Equal(3, configuration.InfrastructureDependencies.Count()); Assert.Equal(2, configuration.ServiceDependencies.Count()); Assert.Equal(0, overrideCallsCount); #endif var elasticsearchDependency = configuration.InfrastructureDependencies.OfType <VersionedDependency>().Single(d => d.Type == SupportedDependencies.Elasticsearch); var castedMaxVersion = Assert.IsAssignableFrom <WildcardDependencyVersion>(elasticsearchDependency.MaximumVersion); Assert.False(castedMaxVersion.IsMajorWildcard); Assert.True(castedMaxVersion.IsMinorWildcard); }
public bool Start(int port, NAMESettings settings) { try { this.webHost = new WebHostBuilder() .UseKestrel() .UseStartup <ServerStartup>() .UseUrls($"http://{this.nameConfiguration.AddressToListenOn}:{port}/{this.nameConfiguration.ManifestUriPrefix.TrimStart('/').TrimEnd('/')}/") .ConfigureServices((services) => { services.AddSingleton(settings); services.AddSingleton(this.nameConfiguration); services.AddSingleton(this.pathMapper); }) .Build(); this.webHost.Start(); this.Port = port; return(true); } catch (Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException) { this.webHost?.Dispose(); return(false); } }
public NAMEHandler(string apiName, string apiVersion, string dependenciesFile, IFilePathMapper pathMapper, NAMESettings settings) { this.apiName = apiName; this.apiVersion = apiVersion; this.dependenciesFile = dependenciesFile; this.pathMapper = pathMapper; this.settings = settings; }
public void ReadConfiguration_CallsMultipleTimes_ConnectionStringProviderOverride() { string fileContents = @"{ ""infrastructure_dependencies"": [ ], ""service_dependencies"": [ { ""name"": ""Some Service0"", ""min_version"": ""0.3"", ""max_version"": ""*"", ""connection_string"": { ""unrecognizedString"": 0 } }, { ""name"": ""Some Service1"", ""min_version"": ""0.3"", ""max_version"": ""*"", ""connection_string"": { ""unrecognizedString"": 1 } } ] }"; string fileName = Guid.NewGuid() + ".json"; File.WriteAllText(fileName, fileContents); try { int iterationsCount = 0; var settings = new NAMESettings() { ConnectionStringProviderOverride = (node) => { Assert.Equal(iterationsCount, node["unrecognizedString"].AsInt); iterationsCount++; return(new StaticConnectionStringProvider(iterationsCount.ToString())); } }; ParsedDependencies configuration = DependenciesReader.ReadDependencies(fileName, new DummyFilePathMapper(), settings, new NAMEContext()); Assert.Equal(0, configuration.InfrastructureDependencies.Count()); Assert.Equal(2, configuration.ServiceDependencies.Count()); Assert.Equal(2, iterationsCount); var firstDependency = (ConnectedDependency)configuration.ServiceDependencies.First(); var secondDependency = (ConnectedDependency)configuration.ServiceDependencies.Skip(1).First(); Assert.IsType <StaticConnectionStringProvider>(firstDependency.ConnectionStringProvider); Assert.IsType <StaticConnectionStringProvider>(secondDependency.ConnectionStringProvider); } finally { File.Delete(fileName); } }
private static ParsedDependencies ParseDependenciesFromString( string jsonContents, IFilePathMapper pathMapper, NAMESettings settings, NAMEContext context) { JsonNode rootNode = Json.Json.Parse(jsonContents); return(new ParsedDependencies( HandleDependencyArray(rootNode?["infrastructure_dependencies"]?.AsArray, pathMapper, settings, context), HandleDependencyArray(rootNode?["service_dependencies"]?.AsArray, pathMapper, settings, context))); }
public void ReadConfiguration_WithAllOverrides() { string fileContents = @"{ ""$schema"": ""./config-manifest.schema.json"", ""Overrides"": { ""RunningMode"": ""NAMEDisabled"", ""RegistryEndpoints"": [ ""http://name:80/api"", ""http://name2:80/api"" ], ""SelfHostPortRangeFirst"": 1, ""SelfHostPortRangeLast"": 10, ""ServiceDependencyMaxHops"": 2, ""ConnectedDependencyShowConnectionString"": false, ""DependencyConnectTimeout"": 429496721, ""DependencyReadWriteTimeout"": 429496722, ""RegistryBootstrapRetryFrequency"": ""00.02:00:00"", ""RegistryBootstrapTimeout"": ""00.00:00:31"" }, ""infrastructure_dependencies"": [ ], ""service_dependencies"": [ ] }"; string fileName = Guid.NewGuid() + ".json"; File.WriteAllText(fileName, fileContents); try { NAMESettings settings = DependenciesReader.ReadNAMESettingsOverrides(fileName, new DummyFilePathMapper()); ParsedDependencies configuration = DependenciesReader.ReadDependencies(fileName, new DummyFilePathMapper(), settings, new NAMEContext()); Assert.Equal(0, configuration.InfrastructureDependencies.Count()); Assert.Equal(0, configuration.ServiceDependencies.Count()); Assert.Equal(SupportedNAMEBehaviours.NAMEDisabled, settings.RunningMode); Assert.Equal(new[] { "http://name:80/api", "http://name2:80/api" }, settings.RegistryEndpoints); Assert.Equal(1, settings.SelfHostPortRangeFirst); Assert.Equal(10, settings.SelfHostPortRangeLast); Assert.Equal(2, settings.ServiceDependencyMaxHops); Assert.False(settings.ConnectedDependencyShowConnectionString); Assert.Equal(429496721, settings.DependencyConnectTimeout); Assert.Equal(429496722, settings.DependencyReadWriteTimeout); Assert.Equal(TimeSpan.FromHours(2), settings.RegistryBootstrapRetryFrequency); Assert.Equal(TimeSpan.FromSeconds(31), settings.RegistryBootstrapTimeout); } finally { File.Delete(fileName); } }
/// <summary> /// Reads the configuration. /// </summary> /// <param name="dependenciesFile">The configuration file.</param> /// <param name="pathMapper">The path mapper.</param> /// <param name="settings">The settings.</param> /// <param name="context">The context.</param> /// <returns> /// Returns the dependencies read from the file. /// </returns> /// <exception cref="NAMEException">An unhandled exception happened.</exception> /// <exception cref="System.IO.FileNotFoundException">The configuration file was not found.</exception> public static ParsedDependencies ReadDependencies( string dependenciesFile, IFilePathMapper pathMapper, NAMESettings settings, NAMEContext context) { Guard.NotNull(settings, nameof(settings)); if (context == null) { context = new NAMEContext(); } string jsonContents = ReadJsonContents(pathMapper.MapPath(dependenciesFile)); return(ParseDependenciesFromString(jsonContents, pathMapper, settings, context)); }
public void ReadConfiguration_UsesConnectionStringProviderReturnedFromOverride() { string fileContents = @"{ ""infrastructure_dependencies"": [ { ""type"": ""RabbitMq"", ""name"": ""rabbitmq"", ""min_version"": ""2.0"", ""max_version"": ""3.3"", ""connection_string"": { ""locator"": ""JSONPath"", ""key"": ""shouldn't matter"" } } ], ""service_dependencies"": [ ] }"; string fileName = Guid.NewGuid() + ".json"; File.WriteAllText(fileName, fileContents); try { int iterationsCount = 0; var settings = new NAMESettings() { ConnectionStringProviderOverride = (node) => { iterationsCount++; return(new StaticConnectionStringProvider(string.Empty)); } }; ParsedDependencies configuration = DependenciesReader.ReadDependencies(fileName, new DummyFilePathMapper(), settings, new NAMEContext()); Assert.Equal(1, configuration.InfrastructureDependencies.Count()); Assert.Equal(0, configuration.ServiceDependencies.Count()); Assert.Equal(1, iterationsCount); var firstDependency = (ConnectedDependency)configuration.InfrastructureDependencies.First(); Assert.IsType <StaticConnectionStringProvider>(firstDependency.ConnectionStringProvider); } finally { File.Delete(fileName); } }
/// <summary> /// Registers the instance in one or more registars. /// </summary> /// <param name="pathMapper">The path mapper.</param> /// <param name="apiName">Name of the API.</param> /// <param name="apiVersion">The API version.</param> /// <param name="dependenciesFileLocation">The dependencies file location.</param> /// <param name="settings">The context.</param> /// <param name="hostname">The hostname.</param> /// <param name="port">The port.</param> /// <param name="nameVersion">The name version.</param> /// <param name="nameEndpoint">The name endpoint.</param> /// <param name="supportedProtocols">The supported protocols.</param> /// <exception cref="System.ArgumentException">Too many dots. - nameVersion</exception> /// <exception cref="System.ArgumentNullException">nameConfig /// or /// hostname /// or /// vpath /// or /// nameVersion /// or /// nameEndpoint /// or /// supportedProtocols</exception> public void RegisterInstance( IFilePathMapper pathMapper, string apiName, string apiVersion, string dependenciesFileLocation, NAMESettings settings, string hostname, uint?port, string nameVersion, string nameEndpoint, params uint[] supportedProtocols) { this.pathMapper = Guard.NotNull(pathMapper, nameof(pathMapper)); // todo guard this.settings = Guard.NotNull(settings, nameof(settings)); this.Hostname = Guard.NotNull(hostname, nameof(hostname)); this.NameVersion = Guard.NotNull(nameVersion, nameof(nameVersion)); this.NameEndpoint = Guard.NotNull(nameEndpoint, nameof(nameEndpoint)); this.SupportedProtocols = Guard.NotNull(supportedProtocols, nameof(supportedProtocols)); this.dependenciesFileLocation = dependenciesFileLocation; this.ApiName = apiName; this.ApiVersion = apiVersion; this.Hostname = hostname; this.Port = port; int dotsCount = nameVersion.Length - nameVersion.Replace(".", string.Empty).Length; if (dotsCount > 3) { throw new ArgumentException("Too many dots.", nameof(nameVersion)); } this.NameVersion = nameVersion.Substring(0, nameVersion.LastIndexOf('.')); this.SupportedProtocols = supportedProtocols; if (this.settings.RegistryEndpoints.Length == 0) { LogInfo("No registry endpoints to register this api", true); return; } LogInfo("RegisterInstance started", true); this.RegisterTask = Task.Factory.StartNew(this.RegisterLoop, this.cancellationTokenSource.Token); }
public bool Start(int port, NAMESettings settings) { try { this.settings = settings; this.httpListener = new SocketHttpListener.Net.HttpListener(); this.httpListener.Prefixes.Add($"http://{this.nameConfiguration.AddressToListenOn}:{port}/{this.nameConfiguration.ManifestUriPrefix.TrimStart('/').TrimEnd('/')}/"); this.httpListener.OnContext = this.OnContext; this.httpListener.Start(); return(true); } catch (System.Net.HttpListenerException) { this.httpListener?.Stop(); return(false); } }
public async Task CheckDependencies_ConnectionStringFromOverride() { string contents = @"{ ""$schema"": ""./config-manifest.schema.json"", ""infrastructure_dependencies"": [ { ""type"": ""MongoDb"", ""min_version"": ""2.6"", ""max_version"": """ + Constants.SpecificMongoVersion + @""", ""connection_string"": { ""locator"": ""hard-coded"" } } ], ""service_dependencies"": [ ] }"; string fileName = Guid.NewGuid() + ".json"; File.WriteAllText(fileName, contents); try { var settings = new NAMESettings() { ConnectionStringProviderOverride = (node) => { if (node["locator"].Value == "hard-coded") { return(new StaticConnectionStringProvider("mongodb://" + Constants.SpecificMongoHostname + ":27017/nPVR_Dev_TST")); } return(null); } }; var parsedDependencies = DependenciesReader.ReadDependencies(fileName, new DummyFilePathMapper(), settings, new Core.NAMEContext()); await DependenciesExtensions.CheckDependencies(parsedDependencies); } finally { File.Delete(fileName); } }
public void ReadConfiguration_OperatingSystemDependency_SkipsOverride() { string fileContents = @"{ ""infrastructure_dependencies"": [ { ""os_name"": ""Ubuntu"", ""type"": ""OperatingSystem"", ""min_version"": ""16.04"", ""max_version"": ""14.04"" } ], ""service_dependencies"": [ ] }"; string fileName = Guid.NewGuid() + ".json"; File.WriteAllText(fileName, fileContents); try { int iterationsCount = 0; var settings = new NAMESettings() { ConnectionStringProviderOverride = (node) => { iterationsCount++; return(null); } }; ParsedDependencies configuration = DependenciesReader.ReadDependencies(fileName, new DummyFilePathMapper(), settings, new NAMEContext()); Assert.Equal(1, configuration.InfrastructureDependencies.Count()); Assert.Equal(0, configuration.ServiceDependencies.Count()); Assert.Equal(0, iterationsCount); } finally { File.Delete(fileName); } }
/// <summary> /// Reads the dependencies. /// </summary> /// <param name="configurationStream">The configuration stream.</param> /// <param name="pathMapper">The path mapper.</param> /// <param name="settings">The context information.</param> /// <param name="context">The context.</param> /// <returns> /// Returns the dependencies read from the stream. /// </returns> /// <exception cref="NAMEException">Configuration file stream is not in readable state</exception> public static ParsedDependencies ReadDependencies( Stream configurationStream, IFilePathMapper pathMapper, NAMESettings settings, NAMEContext context) { Guard.NotNull(settings, nameof(settings)); if (context == null) { context = new NAMEContext(); } if (configurationStream.CanRead == false) { throw new NAMEException("Configuration file stream is not in readable state"); } using (StreamReader reader = new StreamReader(configurationStream)) { var jsonContents = reader.ReadToEnd(); return(ParseDependenciesFromString(jsonContents, pathMapper, settings, context)); } }
/// <summary> /// Initializes a new instance of the <see cref="NAMEMiddleware" /> class. /// </summary> /// <param name="next">The next middleware in the pipeline.</param> /// <param name="nameConfiguration">The name configuration.</param> /// <param name="settings">The name settings.</param> /// <param name="pathMapper">The path mapper.</param> public NAMEMiddleware( RequestDelegate next, NAMEBaseConfiguration nameConfiguration, NAMESettings settings, IFilePathMapper pathMapper) { this.next = next; this.nameConfiguration = nameConfiguration; this.settings = settings; this.pathMapper = pathMapper; if (string.IsNullOrEmpty(nameConfiguration.ManifestUriPrefix)) { this.nameRequestMatcher = new TemplateMatcher(TemplateParser.Parse(Constants.MANIFEST_ENDPOINT.TrimStart('/')), new RouteValueDictionary()); this.nameUiRequestMatcher = new TemplateMatcher(TemplateParser.Parse(Constants.MANIFEST_UI_ENDPOINT.TrimStart('/')), new RouteValueDictionary()); } else { this.nameRequestMatcher = new TemplateMatcher(TemplateParser.Parse(nameConfiguration.ManifestUriPrefix.TrimEnd('/') + Constants.MANIFEST_ENDPOINT), new RouteValueDictionary()); this.nameUiRequestMatcher = new TemplateMatcher(TemplateParser.Parse(nameConfiguration.ManifestUriPrefix.TrimEnd('/') + Constants.MANIFEST_UI_ENDPOINT), new RouteValueDictionary()); } }
private static IList <Dependency> HandleDependencyArray( JsonArray dependencies, IFilePathMapper pathMapper, NAMESettings configuration, NAMEContext context, int depth = 0) { IList <Dependency> handledDependencies = new List <Dependency>(); if (dependencies == null) { return(handledDependencies); } foreach (JsonNode dependency in dependencies) { if (dependency.AsObject != null) { handledDependencies.Add(HandleDependency(dependency.AsObject, pathMapper, configuration, context, depth)); } } return(handledDependencies); }
public NAMEUiHandler(NAMESettings settings) { this.settings = settings; }
/// <summary> /// Reads the NAME settings overrides. /// </summary> /// <param name="settingsFile">The settings file.</param> /// <param name="pathMapper">The path mapper.</param> /// <returns> /// Returns the <see cref="NAMESettings" />. /// </returns> public static NAMESettings ReadNAMESettingsOverrides(string settingsFile, IFilePathMapper pathMapper) { Guard.NotNull(settingsFile, nameof(settingsFile)); var jsonContents = ReadJsonContents(pathMapper.MapPath(settingsFile)); JsonNode rootNode = Json.Json.Parse(jsonContents); var overrideNode = rootNode["Overrides"]; var settings = new NAMESettings(); if (overrideNode == null) { return(settings); } var registryEndpoints = overrideNode[nameof(settings.RegistryEndpoints)]?.AsArray; if (registryEndpoints != null) { settings.RegistryEndpoints = new string[registryEndpoints.Count]; for (int i = 0; i < registryEndpoints.Count; i++) { settings.RegistryEndpoints[i] = registryEndpoints[i].Value; } } var selfhostPortRangeFirst = overrideNode[nameof(settings.SelfHostPortRangeFirst)]?.AsInt; if (selfhostPortRangeFirst != null) { settings.SelfHostPortRangeFirst = selfhostPortRangeFirst.Value; } var selfhostPortRangeLast = overrideNode[nameof(settings.SelfHostPortRangeLast)]?.AsInt; if (selfhostPortRangeLast != null) { settings.SelfHostPortRangeLast = selfhostPortRangeLast.Value; } var serviceDependencyMaxHops = overrideNode[nameof(settings.ServiceDependencyMaxHops)]?.AsInt; if (serviceDependencyMaxHops != null) { settings.ServiceDependencyMaxHops = serviceDependencyMaxHops.Value; } var serviceDependencyShowConnectionString = overrideNode[nameof(settings.ConnectedDependencyShowConnectionString)]?.AsBool; if (serviceDependencyShowConnectionString != null) { settings.ConnectedDependencyShowConnectionString = serviceDependencyShowConnectionString.Value; } var dependencyConnectTimeout = overrideNode[nameof(settings.DependencyConnectTimeout)]?.AsInt; if (dependencyConnectTimeout != null) { settings.DependencyConnectTimeout = dependencyConnectTimeout.Value; } var dependencyReadWriteTimeout = overrideNode[nameof(settings.DependencyReadWriteTimeout)]?.AsInt; if (dependencyReadWriteTimeout != null) { settings.DependencyReadWriteTimeout = dependencyReadWriteTimeout.Value; } var registryReAnnounceFrequency = overrideNode[nameof(settings.RegistryReAnnounceFrequency)]; if (registryReAnnounceFrequency != null && TimeSpan.TryParse(registryReAnnounceFrequency, out TimeSpan parsedAnnounceFreq)) { settings.RegistryReAnnounceFrequency = parsedAnnounceFreq; } var registryPingFrequency = overrideNode[nameof(settings.RegistryPingFrequency)]; if (registryPingFrequency != null && TimeSpan.TryParse(registryPingFrequency, out TimeSpan parsedPingFreq)) { settings.RegistryPingFrequency = parsedPingFreq; } var runningMode = overrideNode[nameof(settings.RunningMode)]; if (runningMode != null && Enum.TryParse <SupportedNAMEBehaviours>(runningMode.Value.ToString(), false, out var behaviour)) { settings.RunningMode = behaviour; } var registryBootstrapRetryFrequency = overrideNode[nameof(settings.RegistryBootstrapRetryFrequency)]; if (registryBootstrapRetryFrequency != null && TimeSpan.TryParse(registryBootstrapRetryFrequency, out TimeSpan bootstrapRetryFreq)) { settings.RegistryBootstrapRetryFrequency = bootstrapRetryFreq; } var registryBootstrapConnectTimeout = overrideNode[nameof(settings.RegistryBootstrapTimeout)]; if (registryBootstrapConnectTimeout != null && TimeSpan.TryParse(registryBootstrapConnectTimeout, out TimeSpan bootstrapConnectTimeout)) { settings.RegistryBootstrapTimeout = bootstrapConnectTimeout; } return(settings); }
private static IVersionResolver GetConnectedDependencyVersionResolver(SupportedDependencies dependencyType, IConnectionStringProvider connectionStringProvider, NAMESettings configuration, NAMEContext context) { switch (dependencyType) { case SupportedDependencies.MongoDb: return(new MongoDb.MongoDbVersionResolver(connectionStringProvider, configuration.DependencyConnectTimeout, configuration.DependencyReadWriteTimeout)); case SupportedDependencies.RabbitMq: return(new RabbitMq.RabbitMqVersionResolver(connectionStringProvider, configuration.DependencyConnectTimeout, configuration.DependencyReadWriteTimeout)); case SupportedDependencies.SqlServer: return(new SqlServer.SqlServerVersionResolver(connectionStringProvider, configuration.DependencyConnectTimeout, configuration.DependencyReadWriteTimeout)); case SupportedDependencies.Service: return(new Service.ServiceVersionResolver(connectionStringProvider, context.ServiceDependencyCurrentNumberOfHops, configuration.ServiceDependencyMaxHops, configuration.DependencyConnectTimeout, configuration.DependencyReadWriteTimeout)); default: throw new NAMEException($"The dependency of type {dependencyType} is not supported as a connected dependency."); } }
private static Dependency HandleDependency(JsonClass dependency, IFilePathMapper pathMapper, NAMESettings configuration, NAMEContext context, int depth = 0) { if (depth == MAX_DEPENDENCY_DEPTH) { throw new NAMEException($"Reached the maximum dependency recursion of {MAX_DEPENDENCY_DEPTH}."); } if (dependency == null) { return(null); } var conditionObject = dependency["oneOf"]; if (conditionObject != null) { depth++; return(new OneOfDependency(HandleDependencyArray(conditionObject.AsArray, pathMapper, configuration, context, depth))); } var minVersion = dependency["min_version"].Value; var maxVersion = dependency["max_version"].Value; var name = dependency["name"]?.Value; var type = dependency["type"]?.Value; var osName = dependency["os_name"]?.Value; type = string.IsNullOrEmpty(type) ? SupportedDependencies.Service.ToString() : type; SupportedDependencies typedType; if (!Enum.TryParse(type, out typedType)) { throw new NAMEException($"The dependency type {type} is not supported."); } VersionedDependency result; if (typedType == SupportedDependencies.OperatingSystem) { result = new OperatingSystemDependency() { OperatingSystemName = osName, MinimumVersion = ParseVersion(minVersion, osName), MaximumVersion = ParseVersion(maxVersion, osName) }; } else { var connectionStringProvider = ParseConnectionStringProvider(dependency["connection_string"], pathMapper); result = new ConnectedDependency(GetConnectedDependencyVersionResolver(typedType, connectionStringProvider, configuration, context)) { ConnectionStringProvider = connectionStringProvider, MinimumVersion = ParseVersion(minVersion, type), MaximumVersion = ParseVersion(maxVersion, type), ShowConnectionStringInJson = configuration.ConnectedDependencyShowConnectionString }; } result.Name = name; result.Type = typedType; return(result); }
/// <summary> /// Reads the and log dependencies. /// </summary> /// <param name="configuration">The configuration.</param> /// <param name="logToConsole">if set to <c>true</c> [log to console].</param> /// <param name="pathMapper">The path mapper.</param> /// <param name="settings">The context information.</param> /// <returns> /// The <see cref="ParsedDependencies" /> object populated from the dependencies file /// </returns> /// <exception cref="NAMEException">Error parsing the dependencies file.</exception> /// <exception cref="DependenciesCheckException">Wrapper for all possible exceptions in the NAME process</exception> public static ParsedDependencies ReadAndLogDependencies(NAMEBaseConfiguration configuration, bool logToConsole, IFilePathMapper pathMapper, out NAMESettings settings) { var dependencies = new ParsedDependencies(null, null); settings = DependenciesReader.ReadNAMESettingsOverrides(configuration.DependenciesFilePath, pathMapper); try { dependencies = DependenciesReader.ReadDependencies(configuration.DependenciesFilePath, pathMapper, settings, new NAMEContext()); } catch (NAMEException ex) { LogWarning($"Could not parse the dependencies file: {ex.Message}.", logToConsole); if (configuration.ThrowOnDependenciesFail) { if (ex is NAMEException) { throw; } else { throw new NAMEException("Error parsing the dependencies file.", ex, NAMEStatusLevel.Error); } } return(dependencies); } if (settings.RunningMode == SupportedNAMEBehaviours.NAMEDisabled) { LogInfo("NAME was disabled in the dependencies file.", logToConsole); return(dependencies); } LogInfo("Starting the dependencies state logs.", logToConsole); Func <IEnumerable <DependencyCheckStatus> > logStatusesAction = () => { var allStatuses = LogDependenciesStatuses(dependencies.InfrastructureDependencies, logToConsole); allStatuses.AddRange(LogDependenciesStatuses(dependencies.ServiceDependencies, logToConsole)); return(allStatuses); }; if (configuration.ThrowOnDependenciesFail) { var allStatuses = logStatusesAction(); if (allStatuses.Any(s => s.CheckStatus != NAMEStatusLevel.Ok)) { throw new DependenciesCheckException(allStatuses); } } else { Task.Factory .StartNew(logStatusesAction) .ContinueWith( task => { LogWarning("Exception logging dependencies status:", logToConsole); var flattened = task.Exception.Flatten(); flattened.Handle(ex => { LogWarning(ex.Message, logToConsole); return(true); }); }, TaskContinuationOptions.OnlyOnFaulted); } return(dependencies); }
/// <summary> /// Determines if the manifest endpoint should be enabled considering the current <see cref="NAMESettings"/> state. /// </summary> /// <param name="nameSettings">The NAME settings.</param> /// <returns>Returns true if the endpoint should be enabled.</returns> public static bool IsManifestEndpointEnabled(this NAMESettings nameSettings) { return(nameSettings.RunningMode != SupportedNAMEBehaviours.NAMEDisabled); }
/// <summary> /// Reads the and log dependencies. /// </summary> /// <param name="configuration">The configuration.</param> /// <param name="logToConsole">if set to <c>true</c> [log to console].</param> /// <param name="pathMapper">The path mapper.</param> /// <param name="settings">The context information.</param> /// <returns> /// The <see cref="ParsedDependencies" /> object populated from the dependencies file /// </returns> /// <exception cref="NAMEException">Error parsing the dependencies file.</exception> /// <exception cref="DependenciesCheckException">Wrapper for all possible exceptions in the NAME process</exception> public static ParsedDependencies ReadAndLogDependencies(NAMEBaseConfiguration configuration, bool logToConsole, IFilePathMapper pathMapper, out NAMESettings settings) { var dependencies = new ParsedDependencies(null, null); settings = DependenciesReader.ReadNAMESettingsOverrides(configuration.DependenciesFilePath, pathMapper); try { dependencies = DependenciesReader.ReadDependencies(configuration.DependenciesFilePath, pathMapper, settings, new NAMEContext()); } catch (NAMEException ex) { LogWarning($"Could not parse the dependencies file: {ex.Message}.", logToConsole); if (configuration.ThrowOnDependenciesFail) { if (ex is NAMEException) { throw; } else { throw new NAMEException("Error parsing the dependencies file.", ex); } } return(dependencies); } if (settings.RunningMode == SupportedNAMEBehaviours.NAMEDisabled) { LogInfo("NAME was disabled in the dependencies file.", logToConsole); return(dependencies); } LogInfo("Starting the dependencies state logs.", logToConsole); var allStatuses = LogDependenciesStatuses(dependencies.InfrastructureDependencies, logToConsole); allStatuses.AddRange(LogDependenciesStatuses(dependencies.ServiceDependencies, logToConsole)); if (configuration.ThrowOnDependenciesFail && allStatuses.Any(s => !s.CheckPassed)) { throw new DependenciesCheckException(allStatuses); } return(dependencies); }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IFilePathMapper pathMapper, NAMEKestrelConfiguration configuration, NAMESettings settings) { app.UseMiddleware <NAMEMiddleware>(configuration, settings, pathMapper); }