mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-11-04 15:10:50 +08:00 
			
		
		
		
	Addressing issue #559 (Infinite configuration file growth when ASPNETCORE_ENVIRONMENT is defined)
Made IHostingEnvironment optional for AddOcelot() to avoid breaking change.
This commit is contained in:
		@@ -9,6 +9,7 @@ namespace Ocelot.DependencyInjection
 | 
			
		||||
    using System.Text.RegularExpressions;
 | 
			
		||||
    using Configuration.File;
 | 
			
		||||
    using Newtonsoft.Json;
 | 
			
		||||
    using Microsoft.AspNetCore.Hosting;
 | 
			
		||||
 | 
			
		||||
    public static class ConfigurationBuilderExtensions
 | 
			
		||||
    {
 | 
			
		||||
@@ -28,32 +29,37 @@ namespace Ocelot.DependencyInjection
 | 
			
		||||
            return builder;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static IConfigurationBuilder AddOcelot(this IConfigurationBuilder builder)
 | 
			
		||||
        public static IConfigurationBuilder AddOcelot(this IConfigurationBuilder builder, IHostingEnvironment env = null)
 | 
			
		||||
        {
 | 
			
		||||
            const string pattern = "(?i)ocelot\\.([a-zA-Z0-9]*)(\\.json)$";
 | 
			
		||||
            const string primaryConfigFile = "ocelot.json";
 | 
			
		||||
 | 
			
		||||
            var reg = new Regex(pattern);
 | 
			
		||||
            const string globalConfigFile = "ocelot.global.json";
 | 
			
		||||
 | 
			
		||||
            var files = Directory.GetFiles(".")
 | 
			
		||||
                .Where(path => reg.IsMatch(path))
 | 
			
		||||
            const string subConfigPattern = @"^ocelot\.[a-zA-Z0-9]+\.json$";
 | 
			
		||||
 | 
			
		||||
            string excludeConfigName = env?.EnvironmentName != null ? $"ocelot.{env.EnvironmentName}.json" : string.Empty;
 | 
			
		||||
 | 
			
		||||
            var reg = new Regex(subConfigPattern, RegexOptions.IgnoreCase | RegexOptions.Singleline);
 | 
			
		||||
 | 
			
		||||
            var files = new DirectoryInfo(".")
 | 
			
		||||
                .EnumerateFiles()
 | 
			
		||||
                .Where(fi => reg.IsMatch(fi.Name) && (fi.Name != excludeConfigName))
 | 
			
		||||
                .ToList();
 | 
			
		||||
 | 
			
		||||
            var fileConfiguration = new FileConfiguration();
 | 
			
		||||
 | 
			
		||||
            foreach (var file in files)
 | 
			
		||||
            {
 | 
			
		||||
                // windows and unix sigh...
 | 
			
		||||
                if(files.Count > 1 && (file == "./ocelot.json" || file == ".\\ocelot.json"))
 | 
			
		||||
                if(files.Count > 1 && file.Name.Equals(primaryConfigFile, StringComparison.OrdinalIgnoreCase))
 | 
			
		||||
                {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                var lines = File.ReadAllText(file);
 | 
			
		||||
                var lines = File.ReadAllText(file.FullName);
 | 
			
		||||
                
 | 
			
		||||
                var config = JsonConvert.DeserializeObject<FileConfiguration>(lines);
 | 
			
		||||
 | 
			
		||||
                // windows and unix sigh...
 | 
			
		||||
                if (file == "./ocelot.global.json" || file == ".\\ocelot.global.json")
 | 
			
		||||
                if (file.Name.Equals(globalConfigFile, StringComparison.OrdinalIgnoreCase))
 | 
			
		||||
                {
 | 
			
		||||
                    fileConfiguration.GlobalConfiguration = config.GlobalConfiguration;
 | 
			
		||||
                }
 | 
			
		||||
@@ -64,9 +70,9 @@ namespace Ocelot.DependencyInjection
 | 
			
		||||
 | 
			
		||||
            var json = JsonConvert.SerializeObject(fileConfiguration);
 | 
			
		||||
 | 
			
		||||
            File.WriteAllText("ocelot.json", json);
 | 
			
		||||
            File.WriteAllText(primaryConfigFile, json);
 | 
			
		||||
 | 
			
		||||
            builder.AddJsonFile("ocelot.json");
 | 
			
		||||
            builder.AddJsonFile(primaryConfigFile);
 | 
			
		||||
 | 
			
		||||
            return builder;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,8 @@
 | 
			
		||||
    using Shouldly;
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
    using Xunit;
 | 
			
		||||
    using Moq;
 | 
			
		||||
    using Microsoft.AspNetCore.Hosting;
 | 
			
		||||
 | 
			
		||||
    public class ConfigurationBuilderExtensionsTests
 | 
			
		||||
    {
 | 
			
		||||
@@ -19,6 +21,18 @@
 | 
			
		||||
        private FileConfiguration _reRouteA;
 | 
			
		||||
        private FileConfiguration _reRouteB;
 | 
			
		||||
        private FileConfiguration _aggregate;
 | 
			
		||||
        private FileConfiguration _envSpecific;
 | 
			
		||||
 | 
			
		||||
        public ConfigurationBuilderExtensionsTests()
 | 
			
		||||
        {
 | 
			
		||||
            // Clean up config files before each test
 | 
			
		||||
            var subConfigFiles = new DirectoryInfo(".").GetFiles("ocelot.*.json");
 | 
			
		||||
 | 
			
		||||
            foreach(var config in subConfigFiles)
 | 
			
		||||
            {
 | 
			
		||||
                config.Delete();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_add_base_url_to_config()
 | 
			
		||||
@@ -32,13 +46,23 @@
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_merge_files()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(_ => GivenMultipleConfigurationFiles())
 | 
			
		||||
                .When(_ => WhenIAddOcelotConfiguration())
 | 
			
		||||
            this.Given(_ => GivenMultipleConfigurationFiles(false))
 | 
			
		||||
                .When(_ => WhenIAddOcelotConfiguration(false))
 | 
			
		||||
                .Then(_ => ThenTheConfigsAreMerged())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenMultipleConfigurationFiles()
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_merge_files_except_env()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(_ => GivenMultipleConfigurationFiles(true))
 | 
			
		||||
                .When(_ => WhenIAddOcelotConfiguration(true))
 | 
			
		||||
                .Then(_ => ThenTheConfigsAreMerged())
 | 
			
		||||
                .And(_ => NotContainsEnvSpecificConfig())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenMultipleConfigurationFiles(bool addEnvSpecificConfig)
 | 
			
		||||
        {
 | 
			
		||||
            _globalConfig = new FileConfiguration
 | 
			
		||||
            {
 | 
			
		||||
@@ -159,16 +183,52 @@
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            _envSpecific = new FileConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                ReRoutes = new List<FileReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new FileReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            DownstreamScheme = "DownstreamSchemeSpec",
 | 
			
		||||
                            DownstreamPathTemplate = "DownstreamPathTemplateSpec",
 | 
			
		||||
                            Key = "KeySpec",
 | 
			
		||||
                            UpstreamHost = "UpstreamHostSpec",
 | 
			
		||||
                            UpstreamHttpMethod = new List<string>
 | 
			
		||||
                            {
 | 
			
		||||
                                "UpstreamHttpMethodSpec"
 | 
			
		||||
                            },
 | 
			
		||||
                            DownstreamHostAndPorts = new List<FileHostAndPort>
 | 
			
		||||
                            {
 | 
			
		||||
                                new FileHostAndPort
 | 
			
		||||
                                {
 | 
			
		||||
                                    Host = "HostSpec",
 | 
			
		||||
                                    Port = 80
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            File.WriteAllText("ocelot.global.json", JsonConvert.SerializeObject(_globalConfig));
 | 
			
		||||
            File.WriteAllText("ocelot.reRoutesA.json", JsonConvert.SerializeObject(_reRouteA));
 | 
			
		||||
            File.WriteAllText("ocelot.reRoutesB.json", JsonConvert.SerializeObject(_reRouteB));
 | 
			
		||||
            File.WriteAllText("ocelot.aggregates.json", JsonConvert.SerializeObject(_aggregate));
 | 
			
		||||
 | 
			
		||||
            if (addEnvSpecificConfig)
 | 
			
		||||
            {
 | 
			
		||||
                File.WriteAllText("ocelot.Env.json", JsonConvert.SerializeObject(_envSpecific));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenIAddOcelotConfiguration()
 | 
			
		||||
        private void WhenIAddOcelotConfiguration(bool addEnv)
 | 
			
		||||
        {
 | 
			
		||||
            IConfigurationBuilder builder = new ConfigurationBuilder();
 | 
			
		||||
            builder.AddOcelot();
 | 
			
		||||
 | 
			
		||||
            var hostingEnvironment = new Mock<IHostingEnvironment>();
 | 
			
		||||
            hostingEnvironment.SetupGet(x => x.EnvironmentName).Returns(addEnv ? "Env" : null);
 | 
			
		||||
 | 
			
		||||
            builder.AddOcelot(hostingEnvironment.Object);
 | 
			
		||||
 | 
			
		||||
            _configRoot = builder.Build();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -208,6 +268,14 @@
 | 
			
		||||
            fc.Aggregates.Count.ShouldBe(_aggregate.Aggregates.Count);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void NotContainsEnvSpecificConfig()
 | 
			
		||||
        {
 | 
			
		||||
            var fc = (FileConfiguration)_configRoot.Get(typeof(FileConfiguration));
 | 
			
		||||
            fc.ReRoutes.ShouldNotContain(x => x.DownstreamScheme == _envSpecific.ReRoutes[0].DownstreamScheme);
 | 
			
		||||
            fc.ReRoutes.ShouldNotContain(x => x.DownstreamPathTemplate == _envSpecific.ReRoutes[0].DownstreamPathTemplate);
 | 
			
		||||
            fc.ReRoutes.ShouldNotContain(x => x.Key == _envSpecific.ReRoutes[0].Key);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheBaseUrl(string baseUrl)
 | 
			
		||||
        {
 | 
			
		||||
            #pragma warning disable CS0618
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user