mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-11-04 12: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 System.Text.RegularExpressions;
 | 
				
			||||||
    using Configuration.File;
 | 
					    using Configuration.File;
 | 
				
			||||||
    using Newtonsoft.Json;
 | 
					    using Newtonsoft.Json;
 | 
				
			||||||
 | 
					    using Microsoft.AspNetCore.Hosting;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static class ConfigurationBuilderExtensions
 | 
					    public static class ConfigurationBuilderExtensions
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -28,32 +29,37 @@ namespace Ocelot.DependencyInjection
 | 
				
			|||||||
            return builder;
 | 
					            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(".")
 | 
					            const string subConfigPattern = @"^ocelot\.[a-zA-Z0-9]+\.json$";
 | 
				
			||||||
                .Where(path => reg.IsMatch(path))
 | 
					
 | 
				
			||||||
 | 
					            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();
 | 
					                .ToList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var fileConfiguration = new FileConfiguration();
 | 
					            var fileConfiguration = new FileConfiguration();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            foreach (var file in files)
 | 
					            foreach (var file in files)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                // windows and unix sigh...
 | 
					                if(files.Count > 1 && file.Name.Equals(primaryConfigFile, StringComparison.OrdinalIgnoreCase))
 | 
				
			||||||
                if(files.Count > 1 && (file == "./ocelot.json" || file == ".\\ocelot.json"))
 | 
					 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    continue;
 | 
					                    continue;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var lines = File.ReadAllText(file);
 | 
					                var lines = File.ReadAllText(file.FullName);
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                var config = JsonConvert.DeserializeObject<FileConfiguration>(lines);
 | 
					                var config = JsonConvert.DeserializeObject<FileConfiguration>(lines);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // windows and unix sigh...
 | 
					                if (file.Name.Equals(globalConfigFile, StringComparison.OrdinalIgnoreCase))
 | 
				
			||||||
                if (file == "./ocelot.global.json" || file == ".\\ocelot.global.json")
 | 
					 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    fileConfiguration.GlobalConfiguration = config.GlobalConfiguration;
 | 
					                    fileConfiguration.GlobalConfiguration = config.GlobalConfiguration;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@@ -64,9 +70,9 @@ namespace Ocelot.DependencyInjection
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            var json = JsonConvert.SerializeObject(fileConfiguration);
 | 
					            var json = JsonConvert.SerializeObject(fileConfiguration);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            File.WriteAllText("ocelot.json", json);
 | 
					            File.WriteAllText(primaryConfigFile, json);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            builder.AddJsonFile("ocelot.json");
 | 
					            builder.AddJsonFile(primaryConfigFile);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return builder;
 | 
					            return builder;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,6 +9,8 @@
 | 
				
			|||||||
    using Shouldly;
 | 
					    using Shouldly;
 | 
				
			||||||
    using TestStack.BDDfy;
 | 
					    using TestStack.BDDfy;
 | 
				
			||||||
    using Xunit;
 | 
					    using Xunit;
 | 
				
			||||||
 | 
					    using Moq;
 | 
				
			||||||
 | 
					    using Microsoft.AspNetCore.Hosting;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public class ConfigurationBuilderExtensionsTests
 | 
					    public class ConfigurationBuilderExtensionsTests
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -19,6 +21,18 @@
 | 
				
			|||||||
        private FileConfiguration _reRouteA;
 | 
					        private FileConfiguration _reRouteA;
 | 
				
			||||||
        private FileConfiguration _reRouteB;
 | 
					        private FileConfiguration _reRouteB;
 | 
				
			||||||
        private FileConfiguration _aggregate;
 | 
					        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]
 | 
					        [Fact]
 | 
				
			||||||
        public void should_add_base_url_to_config()
 | 
					        public void should_add_base_url_to_config()
 | 
				
			||||||
@@ -32,13 +46,23 @@
 | 
				
			|||||||
        [Fact]
 | 
					        [Fact]
 | 
				
			||||||
        public void should_merge_files()
 | 
					        public void should_merge_files()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            this.Given(_ => GivenMultipleConfigurationFiles())
 | 
					            this.Given(_ => GivenMultipleConfigurationFiles(false))
 | 
				
			||||||
                .When(_ => WhenIAddOcelotConfiguration())
 | 
					                .When(_ => WhenIAddOcelotConfiguration(false))
 | 
				
			||||||
                .Then(_ => ThenTheConfigsAreMerged())
 | 
					                .Then(_ => ThenTheConfigsAreMerged())
 | 
				
			||||||
                .BDDfy();
 | 
					                .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
 | 
					            _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.global.json", JsonConvert.SerializeObject(_globalConfig));
 | 
				
			||||||
            File.WriteAllText("ocelot.reRoutesA.json", JsonConvert.SerializeObject(_reRouteA));
 | 
					            File.WriteAllText("ocelot.reRoutesA.json", JsonConvert.SerializeObject(_reRouteA));
 | 
				
			||||||
            File.WriteAllText("ocelot.reRoutesB.json", JsonConvert.SerializeObject(_reRouteB));
 | 
					            File.WriteAllText("ocelot.reRoutesB.json", JsonConvert.SerializeObject(_reRouteB));
 | 
				
			||||||
            File.WriteAllText("ocelot.aggregates.json", JsonConvert.SerializeObject(_aggregate));
 | 
					            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();
 | 
					            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();
 | 
					            _configRoot = builder.Build();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -208,6 +268,14 @@
 | 
				
			|||||||
            fc.Aggregates.Count.ShouldBe(_aggregate.Aggregates.Count);
 | 
					            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)
 | 
					        private void GivenTheBaseUrl(string baseUrl)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            #pragma warning disable CS0618
 | 
					            #pragma warning disable CS0618
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user