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))); }
/// <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)); }
protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { if (!this.settings.IsManifestEndpointEnabled()) { return(new HttpResponseMessage(HttpStatusCode.NotFound)); } int currentHopCount; if (request.Headers.TryGetValues(Constants.HOP_COUNT_HEADER_NAME, out IEnumerable <string> headerValues)) { if (!int.TryParse(headerValues.First(), out currentHopCount)) { currentHopCount = 0; LogWarning($"The received hop count header it not a valid int value ({headerValues.First()}), defaulting to 0.", false); } } else { currentHopCount = 0; } currentHopCount++; if (currentHopCount == this.settings.ServiceDependencyMaxHops) { return new HttpResponseMessage { StatusCode = (HttpStatusCode)Constants.SERVICE_HOPS_ERROR_STATUS_CODE } } ; var context = new NAMEContext() { ServiceDependencyCurrentNumberOfHops = currentHopCount }; ParsedDependencies innerDependencies = DependenciesReader.ReadDependencies(this.dependenciesFile, this.pathMapper, this.settings, context); var manifest = await ManifestGenerator.GenerateJson(this.apiName, this.apiVersion, innerDependencies).ConfigureAwait(false); var content = new StringContent(manifest); content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); return(new HttpResponseMessage { Content = content }); } }
private async Task GetManifest(HttpContext context) { context.Response.ContentType = "application/json"; int currentHopCount; if (context.Request.Headers.TryGetValue(Constants.HOP_COUNT_HEADER_NAME, out StringValues headerValues)) { if (!int.TryParse(headerValues.First(), out currentHopCount)) { currentHopCount = 0; Trace.TraceWarning($"The received hop count header it not a valid int value ({headerValues.First()}), defaulting to 0."); } } else { currentHopCount = 0; } currentHopCount++; var nameContext = new NAMEContext() { ServiceDependencyCurrentNumberOfHops = currentHopCount }; var dependencies = DependenciesReader.ReadDependencies(this.nameConfiguration.DependenciesFilePath, this.pathMapper, this.settings, nameContext); if (currentHopCount == this.settings.ServiceDependencyMaxHops) { context.Response.StatusCode = Constants.SERVICE_HOPS_ERROR_STATUS_CODE; return; } string manifest = await ManifestGenerator.GenerateJson(this.nameConfiguration.APIName, this.nameConfiguration.APIVersion, dependencies); context.Response.ContentType = "application/json"; await context.Response.WriteAsync(manifest); }
private async Task GetManifest(HttpListenerContext context, NAMEHttpListenerConfiguration configuration) { context.Response.ContentType = "application/json"; int currentHopCount = 0; var hopCountHeaders = context.Request.Headers.GetValues(Constants.HOP_COUNT_HEADER_NAME); if (hopCountHeaders?.Length > 0) { if (!int.TryParse(hopCountHeaders.First(), out currentHopCount)) { currentHopCount = 0; LogWarning($"The received hop count header it not a valid int value ({hopCountHeaders.First()}), defaulting to 0.", this.nameConfiguration.LogHealthCheckToConsole); } } currentHopCount++; var nameContext = new NAMEContext() { ServiceDependencyCurrentNumberOfHops = currentHopCount }; var dependencies = DependenciesReader.ReadDependencies(configuration.DependenciesFilePath, this.pathMapper, this.settings, nameContext); if (currentHopCount == this.settings.ServiceDependencyMaxHops) { context.Response.StatusCode = Constants.SERVICE_HOPS_ERROR_STATUS_CODE; return; } string manifest = await ManifestGenerator.GenerateJson(configuration.APIName, configuration.APIVersion, dependencies).ConfigureAwait(false); context.Response.ContentType = "application/json"; var manifestBytes = Encoding.UTF8.GetBytes(manifest); context.Response.OutputStream.Write(manifestBytes, 0, manifestBytes.Length); }
/// <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)); } }
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); }
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); }
private async Task <string> GetManifest(NAMEContext context) { ParsedDependencies innerDependencies = DependenciesReader.ReadDependencies(this.dependenciesFileLocation, this.pathMapper, this.settings, context); return(await ManifestGenerator.GenerateJson(this.ApiName, this.ApiVersion, innerDependencies).ConfigureAwait(false)); }