mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-04-22 18:22:49 +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:
parent
8f4ae03290
commit
af3c39da6a
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user