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));
        }
Beispiel #3
0
        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
            });
        }
    }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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));
            }
        }
Beispiel #7
0
        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);
        }
Beispiel #10
0
        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));
        }