Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to work with multiple configuration files per microservice? #1858

Closed
sachinvaid1604 opened this issue Dec 19, 2023 · 1 comment
Closed
Labels
question Initially seen a question could become a new feature or bug or closed ;)

Comments

@sachinvaid1604
Copy link

          > Ok guys, so I have found out what was causing the strange behaviour.

It was the folder structure that we are using in Kubernetes for our configuration files.

Generally placing configuration files in the folder structure described below will cause described issue.

This could be written in the documentation as a note.

Folder structure: etc/config/

Hi, Can you please provide a working code that can read multiple route configurations for each microservice and can run both. In my case, I can only access the last added route configuration.

Here is my program.cs file

using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Ocelot.DependencyInjection;
using Ocelot.Middleware;
using System.IO;

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args)
            .Build()
            .Run();
    }

    static IWebHostEnvironment _hostingContextEnvironment = null;

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseContentRoot(Directory.GetCurrentDirectory())
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                _hostingContextEnvironment = hostingContext.HostingEnvironment;

                config
                    .SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
                    .AddJsonFile("appsettings.json", true, true)
                    .AddJsonFile("ocelot.json", false, true)
                    .AddJsonFile("student.ocelot.Development.json", false, true)
                    .AddJsonFile("teacher.ocelot.Development.json", false, true)
                    .AddEnvironmentVariables();
            })
            .ConfigureServices(s =>
            {
                s.AddOcelot();
            })
            .Configure(app =>
            {
                app.UseOcelot().Wait();
            });
}

image

Originally posted by @sachinvaid1604 in #1186 (comment)

@raman-m
Copy link
Member

raman-m commented Dec 19, 2023

Sachin, fork Ocelot repo first to look into the Ocelot code!

After forking Ocelot you will figure out that AddJsonFile method is a part of JsonConfigurationExtensions class from Microsoft.Extensions.Configuration namespace!
If you press F12 key multiple times, you will get to this Microsoft ASP.NET implementation:

        /// <summary>
        /// Adds a JSON configuration source to <paramref name="builder"/>.
        /// </summary>
        /// <param name="builder">The <see cref="IConfigurationBuilder"/> to add to.</param>
        /// <param name="provider">The <see cref="IFileProvider"/> to use to access the file.</param>
        /// <param name="path">Path relative to the base path stored in
        /// <see cref="IConfigurationBuilder.Properties"/> of <paramref name="builder"/>.</param>
        /// <param name="optional">Whether the file is optional.</param>
        /// <param name="reloadOnChange">Whether the configuration should be reloaded if the file changes.</param>
        /// <returns>The <see cref="IConfigurationBuilder"/>.</returns>
        public static IConfigurationBuilder AddJsonFile(this IConfigurationBuilder builder, IFileProvider? provider, string path, bool optional, bool reloadOnChange)
        {
            ThrowHelper.ThrowIfNull(builder);

            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentException(SR.Error_InvalidFilePath, nameof(path));
            }

            return builder.AddJsonFile(s =>
            {
                s.FileProvider = provider;
                s.Path = path;
                s.Optional = optional;
                s.ReloadOnChange = reloadOnChange;
                s.ResolveFileProvider();
            });
        }

I have no idea how inner MS implementation merges config JSON.

If you call

                    .AddJsonFile("student.ocelot.Development.json", false, true)
                    .AddJsonFile("teacher.ocelot.Development.json", false, true)

and they describe the same routes, seems the second file will overwrite the routes from the first one.
Microsoft classes don't merge!

@raman-m raman-m changed the title Working with multiple configuration files per microservice is having unwanted outcome How to work with multiple configuration files per microservice? Dec 19, 2023
@raman-m raman-m added the question Initially seen a question could become a new feature or bug or closed ;) label Dec 19, 2023
@ThreeMammals ThreeMammals locked and limited conversation to collaborators Dec 19, 2023
@raman-m raman-m converted this issue into discussion #1859 Dec 19, 2023

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
question Initially seen a question could become a new feature or bug or closed ;)
Projects
None yet
Development

No branches or pull requests

2 participants