diff --git a/src/Ocelot/DependencyInjection/ConfigurationBuilderExtensions.cs b/src/Ocelot/DependencyInjection/ConfigurationBuilderExtensions.cs index 6497cad7d..40d783733 100644 --- a/src/Ocelot/DependencyInjection/ConfigurationBuilderExtensions.cs +++ b/src/Ocelot/DependencyInjection/ConfigurationBuilderExtensions.cs @@ -76,14 +76,9 @@ public static IConfigurationBuilder AddOcelot(this IConfigurationBuilder builder var lines = File.ReadAllText(file.FullName); dynamic config = JToken.Parse(lines); + var isGlobal = file.Name.Equals(globalConfigFile, StringComparison.OrdinalIgnoreCase); - if (file.Name.Equals(GlobalConfigFile, StringComparison.OrdinalIgnoreCase)) - { - TryAddSection(fileConfiguration, config, nameof(FileConfiguration.GlobalConfiguration)); - } - - TryAddSection(fileConfiguration, config, nameof(FileConfiguration.Aggregates)); - TryAddSection(fileConfiguration, config, nameof(FileConfiguration.ReRoutes)); + MergeConfig(fileConfiguration, config, isGlobal); } return builder.AddOcelot(fileConfiguration); @@ -105,20 +100,31 @@ public static IConfigurationBuilder AddOcelot(this IConfigurationBuilder builder return builder.AddJsonFile(PrimaryConfigFile, false, false); } - private static void TryAddSection(JToken mergedConfig, JToken config, string sectionName) + private static void MergeConfig(JToken destConfig, JToken srcConfig, bool isGlobal) + { + if (isGlobal) + { + MergeConfigSection(destConfig, srcConfig, nameof(FileConfiguration.GlobalConfiguration)); + } + + MergeConfigSection(destConfig, srcConfig, nameof(FileConfiguration.Aggregates)); + MergeConfigSection(destConfig, srcConfig, nameof(FileConfiguration.ReRoutes)); + } + + private static void MergeConfigSection(JToken destConfig, JToken srcConfig, string sectionName) { - var mergedConfigSection = mergedConfig[sectionName]; - var configSection = config[sectionName]; + var destConfigSection = destConfig[sectionName]; + var srcConfigSection = srcConfig[sectionName]; - if (configSection != null) + if (srcConfigSection != null) { - if (configSection is JObject) + if (srcConfigSection is JObject) { - mergedConfig[sectionName] = configSection; + destConfig[sectionName] = srcConfigSection; } - else if (configSection is JArray) + else if (srcConfigSection is JArray) { - (mergedConfigSection as JArray).Merge(configSection); + (destConfigSection as JArray).Merge(srcConfigSection); } } } diff --git a/test/Ocelot.AcceptanceTests/ConfigurationMergeTests.cs b/test/Ocelot.AcceptanceTests/ConfigurationMergeTests.cs index 2a24cb6f7..67502cedc 100644 --- a/test/Ocelot.AcceptanceTests/ConfigurationMergeTests.cs +++ b/test/Ocelot.AcceptanceTests/ConfigurationMergeTests.cs @@ -1,39 +1,28 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.TestHost; using Microsoft.Extensions.Configuration; -using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Ocelot.Configuration.File; using Ocelot.DependencyInjection; using Ocelot.Middleware; using Shouldly; -using System; -using System.Collections.Generic; using System.IO; using System.Linq; -using System.Net.Http; using TestStack.BDDfy; using Xunit; namespace Ocelot.AcceptanceTests { public class ConfigurationMergeTests - { - private Steps _steps; + { private IWebHostBuilder _webHostBuilder; private TestServer _ocelotServer; - private HttpClient _ocelotClient; - - public ConfigurationMergeTests() - { - _steps = new Steps(); - } [Fact] public void should_merge_reroutes_custom_properties() { this.Given(x => GivenOcelotIsRunningWithMultipleConfigs()) - .And(x => ThenConfigContentShouldBeMerged()) + .And(x => ThenConfigContentShouldBeMergedWithReRoutesCustomProperties()) .BDDfy(); } @@ -63,10 +52,10 @@ private void GivenOcelotIsRunningWithMultipleConfigs() _ocelotServer = new TestServer(_webHostBuilder); - _ocelotClient = _ocelotServer.CreateClient(); + var ocelotClient = _ocelotServer.CreateClient(); } - private void ThenConfigContentShouldBeMerged() + private void ThenConfigContentShouldBeMergedWithReRoutesCustomProperties() { var mergedConfigFileName = "ocelot.json"; File.Exists(mergedConfigFileName).ShouldBeTrue(); @@ -76,19 +65,28 @@ private void ThenConfigContentShouldBeMerged() config[nameof(FileConfiguration.ReRoutes)].ShouldNotBeNull(); config[nameof(FileConfiguration.ReRoutes)].Children().Count().ShouldBe(3); - var routeWithCustomProperty = config[nameof(FileConfiguration.ReRoutes)].Children().SingleOrDefault(c => c["CustomStrategyProperty"] != null); - routeWithCustomProperty.ShouldNotBeNull(); - var customProperty = routeWithCustomProperty["CustomStrategyProperty"]; - customProperty["GET"].ShouldNotBeNull(); - customProperty["GET"].Children().Count().ShouldBe(1); - customProperty["GET"].Children().FirstOrDefault().ShouldBe("SomeCustomStrategyMethodA"); - customProperty["POST"].ShouldNotBeNull(); - customProperty["POST"].Children().Count().ShouldBe(1); - customProperty["POST"].Children().FirstOrDefault().ShouldBe("SomeCustomStrategyMethodB"); + var routeWithCustomPropertyX = config[nameof(FileConfiguration.ReRoutes)].Children() + .SingleOrDefault(c => c["CustomStrategyProperty"] != null); + routeWithCustomPropertyX.ShouldNotBeNull(); + var customPropertyX = routeWithCustomPropertyX["CustomStrategyProperty"]; + customPropertyX["GET"].ShouldNotBeNull(); + customPropertyX["GET"].Children().Count().ShouldBe(1); + customPropertyX["GET"].Children().FirstOrDefault().ShouldBe("SomeCustomStrategyMethodA"); + customPropertyX["POST"].ShouldNotBeNull(); + customPropertyX["POST"].Children().Count().ShouldBe(1); + customPropertyX["POST"].Children().FirstOrDefault().ShouldBe("SomeCustomStrategyMethodB"); + + var routeWithCustomPropertyGlobal = config[nameof(FileConfiguration.ReRoutes)].Children() + .SingleOrDefault(c => c["somethingmore"] != null); + routeWithCustomPropertyGlobal.ShouldNotBeNull(); + routeWithCustomPropertyGlobal["somethingmore"].ShouldBe("something"); - var routeWithCustomProperty2 = config[nameof(FileConfiguration.ReRoutes)].Children().SingleOrDefault(c => c["somethingmore"] != null); - routeWithCustomProperty2.ShouldNotBeNull(); - routeWithCustomProperty2["somethingmore"].ShouldBe("something"); + var routeWithCustomPropertyY = config[nameof(FileConfiguration.ReRoutes)].Children() + .SingleOrDefault(c => c["MyCustomProperty"] != null); + routeWithCustomPropertyY.ShouldNotBeNull(); + routeWithCustomPropertyY["MyCustomProperty"].ShouldBeAssignableTo(typeof(JArray)); + routeWithCustomPropertyY["MyCustomProperty"].Count().ShouldBe(1); + routeWithCustomPropertyY["MyCustomProperty"].First().ShouldBe("myValue"); } } } diff --git a/test/Ocelot.AcceptanceTests/MergeConfiguration/ocelot.global.json b/test/Ocelot.AcceptanceTests/MergeConfiguration/ocelot.global.json index cf4c03f2b..bdaeaf3c3 100644 --- a/test/Ocelot.AcceptanceTests/MergeConfiguration/ocelot.global.json +++ b/test/Ocelot.AcceptanceTests/MergeConfiguration/ocelot.global.json @@ -6,7 +6,7 @@ "DownstreamHostAndPorts": [ { "Host": "localhost", - "Port": 54001 + "Port": 24012 } ], "UpstreamPathTemplate": "/{global}", diff --git a/test/Ocelot.AcceptanceTests/MergeConfiguration/ocelot.yservices.json b/test/Ocelot.AcceptanceTests/MergeConfiguration/ocelot.yservices.json index 86ed135af..b2c122cd2 100644 --- a/test/Ocelot.AcceptanceTests/MergeConfiguration/ocelot.yservices.json +++ b/test/Ocelot.AcceptanceTests/MergeConfiguration/ocelot.yservices.json @@ -6,12 +6,12 @@ "DownstreamHostAndPorts": [ { "Host": "localhost", - "Port": 54001 + "Port": 34234 } ], "UpstreamPathTemplate": "/b/{action}", "UpstreamHttpMethod": [ "Get" ], - "MyCustomProperty": "bbb" + "MyCustomProperty": [ "myValue" ] } ] }