Skip to content

Commit

Permalink
Jobject + acceptance test
Browse files Browse the repository at this point in the history
  • Loading branch information
jlukawska authored and raman-m committed Nov 1, 2023
1 parent 0835298 commit 9b8d442
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 20 deletions.
36 changes: 16 additions & 20 deletions src/Ocelot/DependencyInjection/ConfigurationBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ public static IConfigurationBuilder AddOcelot(this IConfigurationBuilder builder
.Where(fi => reg.IsMatch(fi.Name) && fi.Name != excludeConfigName)
.ToArray();

dynamic fileConfiguration = new ExpandoObject();
fileConfiguration.GlobalConfiguration = new ExpandoObject();
fileConfiguration.Aggregates = new List<object>();
fileConfiguration.ReRoutes = new List<object>();
dynamic fileConfiguration = new JObject();
fileConfiguration.GlobalConfiguration = new JObject();
fileConfiguration.Aggregates = new JArray();
fileConfiguration.ReRoutes = new JArray();

foreach (var file in files)
{
Expand All @@ -75,8 +75,7 @@ public static IConfigurationBuilder AddOcelot(this IConfigurationBuilder builder
}

var lines = File.ReadAllText(file.FullName);

dynamic config = JsonConvert.DeserializeObject<ExpandoObject>(lines);
dynamic config = JToken.Parse(lines);

if (file.Name.Equals(GlobalConfigFile, StringComparison.OrdinalIgnoreCase))
{
Expand Down Expand Up @@ -106,25 +105,22 @@ public static IConfigurationBuilder AddOcelot(this IConfigurationBuilder builder
return builder.AddJsonFile(PrimaryConfigFile, false, false);
}

private static void TryAddSection(ExpandoObject mergedConfig, ExpandoObject config, string sectionName)
private static void TryAddSection(JToken mergedConfig, JToken config, string sectionName)
{
var configAsDict = config as IDictionary<string, object>;
var mergedConfigAsDict = mergedConfig as IDictionary<string, object>;
if (configAsDict.ContainsKey(sectionName) && mergedConfigAsDict.ContainsKey(sectionName))
var mergedConfigSection = mergedConfig[sectionName];
var configSection = config[sectionName];

if (configSection != null)
{
var mergedSectionAsExpando = mergedConfigAsDict[sectionName] as ExpandoObject;
if (mergedSectionAsExpando != null)
if (configSection is JObject)
{
mergedConfigAsDict[sectionName] = configAsDict[sectionName];
mergedConfig[sectionName] = configSection;
}
else
else if (configSection is JArray)
{
var mergedSectionAsList = mergedConfigAsDict[sectionName] as List<object>;
var sectionAsList = configAsDict[sectionName] as List<object>;

mergedSectionAsList.AddRange(sectionAsList);
(mergedConfigSection as JArray).Merge(configSection);
}
}
}
}
}
}
}
94 changes: 94 additions & 0 deletions test/Ocelot.AcceptanceTests/ConfigurationMergeTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
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())
.BDDfy();
}

private void GivenOcelotIsRunningWithMultipleConfigs()
{
_webHostBuilder = new WebHostBuilder();

_webHostBuilder
.UseContentRoot(Directory.GetCurrentDirectory())
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
var env = hostingContext.HostingEnvironment;
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
config.AddOcelot("MergeConfiguration", hostingContext.HostingEnvironment);
config.AddEnvironmentVariables();
})
.ConfigureServices(s =>
{
s.AddOcelot();
})
.Configure(app =>
{
app.UseOcelot().Wait();
});

_ocelotServer = new TestServer(_webHostBuilder);

_ocelotClient = _ocelotServer.CreateClient();
}

private void ThenConfigContentShouldBeMerged()
{
var mergedConfigFileName = "ocelot.json";
File.Exists(mergedConfigFileName).ShouldBeTrue();
var lines = File.ReadAllText(mergedConfigFileName);
var config = JObject.Parse(lines);

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 routeWithCustomProperty2 = config[nameof(FileConfiguration.ReRoutes)].Children().SingleOrDefault(c => c["somethingmore"] != null);
routeWithCustomProperty2.ShouldNotBeNull();
routeWithCustomProperty2["somethingmore"].ShouldBe("something");
}
}
}
20 changes: 20 additions & 0 deletions test/Ocelot.AcceptanceTests/MergeConfiguration/ocelot.global.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"ReRoutes": [
{
"DownstreamPathTemplate": "/{global}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 54001
}
],
"UpstreamPathTemplate": "/{global}",
"UpstreamHttpMethod": [ "Get" ],
"somethingmore": "something"
}
],
"GlobalConfiguration": {
"BaseUrl": "http://api.test.com"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"ReRoutes": [
{
"DownstreamPathTemplate": "/xservice.svc/serviceMethodA/byNumber/{number}",
"UpstreamPathTemplate": "/gw/serviceMethodA/byNumber/{number}",
"UpstreamHttpMethod": [
"Get",
"Post"
],
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "host",
"Port": 80
}
],
"CustomStrategyProperty": {
"GET": [
"SomeCustomStrategyMethodA"
],
"POST": [
"SomeCustomStrategyMethodB"
]
}
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"ReRoutes": [
{
"DownstreamPathTemplate": "/b/{action}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 54001
}
],
"UpstreamPathTemplate": "/b/{action}",
"UpstreamHttpMethod": [ "Get" ],
"MyCustomProperty": "bbb"
}
]
}
16 changes: 16 additions & 0 deletions test/Ocelot.AcceptanceTests/Ocelot.AcceptanceTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,22 @@
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<NoWarn>1591</NoWarn>
</PropertyGroup>
<ItemGroup>
<None Remove="MergeConfiguration\ocelot.global.json" />
<None Remove="MergeConfiguration\ocelot.xservices.json" />
<None Remove="MergeConfiguration\ocelot.yservices.json" />
</ItemGroup>
<ItemGroup>
<Content Include="MergeConfiguration\ocelot.global.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="MergeConfiguration\ocelot.xservices.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="MergeConfiguration\ocelot.yservices.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>

<ItemGroup>
<None Update="appsettings.product.json">
Expand Down

0 comments on commit 9b8d442

Please sign in to comment.