diff --git a/src/Ocelot/Configuration/Creator/FileOcelotConfigurationCreator.cs b/src/Ocelot/Configuration/Creator/FileOcelotConfigurationCreator.cs index 0d853f94..c9161dee 100644 --- a/src/Ocelot/Configuration/Creator/FileOcelotConfigurationCreator.cs +++ b/src/Ocelot/Configuration/Creator/FileOcelotConfigurationCreator.cs @@ -31,6 +31,7 @@ namespace Ocelot.Configuration.Creator private readonly IClaimsToThingCreator _claimsToThingCreator; private readonly IAuthenticationOptionsCreator _authOptionsCreator; private IUpstreamTemplatePatternCreator _upstreamTemplatePatternCreator; + private IRequestIdKeyCreator _requestIdKeyCreator; public FileOcelotConfigurationCreator( IOptions options, @@ -42,8 +43,10 @@ namespace Ocelot.Configuration.Creator IQosProviderHouse qosProviderHouse, IClaimsToThingCreator claimsToThingCreator, IAuthenticationOptionsCreator authOptionsCreator, - IUpstreamTemplatePatternCreator upstreamTemplatePatternCreator) + IUpstreamTemplatePatternCreator upstreamTemplatePatternCreator, + IRequestIdKeyCreator requestIdKeyCreator) { + _requestIdKeyCreator = requestIdKeyCreator; _upstreamTemplatePatternCreator = upstreamTemplatePatternCreator; _authOptionsCreator = authOptionsCreator; _loadBalanceFactory = loadBalancerFactory; @@ -105,7 +108,7 @@ namespace Ocelot.Configuration.Creator var isCached = IsCached(fileReRoute); - var requestIdKey = BuildRequestId(fileReRoute, globalConfiguration); + var requestIdKey = _requestIdKeyCreator.Create(fileReRoute, globalConfiguration); var reRouteKey = BuildReRouteKey(fileReRoute); @@ -210,17 +213,6 @@ namespace Ocelot.Configuration.Creator return fileReRoute.FileCacheOptions.TtlSeconds > 0; } - private string BuildRequestId(FileReRoute fileReRoute, FileGlobalConfiguration globalConfiguration) - { - var globalRequestIdConfiguration = !string.IsNullOrEmpty(globalConfiguration?.RequestIdKey); - - var requestIdKey = globalRequestIdConfiguration - ? globalConfiguration.RequestIdKey - : fileReRoute.RequestIdKey; - - return requestIdKey; - } - private string BuildReRouteKey(FileReRoute fileReRoute) { //note - not sure if this is the correct key, but this is probably the only unique key i can think of given my poor brain diff --git a/src/Ocelot/Configuration/Creator/IRequestIdKeyCreator.cs b/src/Ocelot/Configuration/Creator/IRequestIdKeyCreator.cs new file mode 100644 index 00000000..2800f8a5 --- /dev/null +++ b/src/Ocelot/Configuration/Creator/IRequestIdKeyCreator.cs @@ -0,0 +1,9 @@ +using Ocelot.Configuration.File; + +namespace Ocelot.Configuration.Creator +{ + public interface IRequestIdKeyCreator + { + string Create(FileReRoute fileReRoute, FileGlobalConfiguration globalConfiguration); + } +} \ No newline at end of file diff --git a/src/Ocelot/Configuration/Creator/RequestIdKeyCreator.cs b/src/Ocelot/Configuration/Creator/RequestIdKeyCreator.cs new file mode 100644 index 00000000..caf00402 --- /dev/null +++ b/src/Ocelot/Configuration/Creator/RequestIdKeyCreator.cs @@ -0,0 +1,18 @@ +using Ocelot.Configuration.File; + +namespace Ocelot.Configuration.Creator +{ + public class RequestIdKeyCreator : IRequestIdKeyCreator + { + public string Create(FileReRoute fileReRoute, FileGlobalConfiguration globalConfiguration) + { + var globalRequestIdConfiguration = !string.IsNullOrEmpty(globalConfiguration?.RequestIdKey); + + var requestIdKey = globalRequestIdConfiguration + ? globalConfiguration.RequestIdKey + : fileReRoute.RequestIdKey; + + return requestIdKey; + } + } +} \ No newline at end of file diff --git a/src/Ocelot/DependencyInjection/ServiceCollectionExtensions.cs b/src/Ocelot/DependencyInjection/ServiceCollectionExtensions.cs index 54fef846..9b777248 100644 --- a/src/Ocelot/DependencyInjection/ServiceCollectionExtensions.cs +++ b/src/Ocelot/DependencyInjection/ServiceCollectionExtensions.cs @@ -63,6 +63,7 @@ namespace Ocelot.DependencyInjection services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(); var identityServerConfiguration = IdentityServerConfigurationCreator.GetIdentityServerConfiguration(); diff --git a/test/Ocelot.UnitTests/Configuration/FileConfigurationCreatorTests.cs b/test/Ocelot.UnitTests/Configuration/FileConfigurationCreatorTests.cs index bafea3cd..b0a4fa06 100644 --- a/test/Ocelot.UnitTests/Configuration/FileConfigurationCreatorTests.cs +++ b/test/Ocelot.UnitTests/Configuration/FileConfigurationCreatorTests.cs @@ -34,6 +34,7 @@ namespace Ocelot.UnitTests.Configuration private Mock _claimsToThingCreator; private Mock _authOptionsCreator; private Mock _upstreamTemplatePatternCreator; + private Mock _requestIdKeyCreator; public FileConfigurationCreatorTests() { @@ -49,12 +50,13 @@ namespace Ocelot.UnitTests.Configuration _claimsToThingCreator = new Mock(); _authOptionsCreator = new Mock(); _upstreamTemplatePatternCreator = new Mock(); + _requestIdKeyCreator = new Mock(); _ocelotConfigurationCreator = new FileOcelotConfigurationCreator( _fileConfig.Object, _validator.Object, _logger.Object, _loadBalancerFactory.Object, _loadBalancerHouse.Object, _qosProviderFactory.Object, _qosProviderHouse.Object, _claimsToThingCreator.Object, - _authOptionsCreator.Object, _upstreamTemplatePatternCreator.Object); + _authOptionsCreator.Object, _upstreamTemplatePatternCreator.Object, _requestIdKeyCreator.Object); } [Fact] @@ -279,7 +281,7 @@ namespace Ocelot.UnitTests.Configuration } [Fact] - public void should_set_global_request_id_key() + public void should_call_request_id_creator() { this.Given(x => x.GivenTheConfigIs(new FileConfiguration { @@ -298,7 +300,8 @@ namespace Ocelot.UnitTests.Configuration RequestIdKey = "blahhhh" } })) - .And(x => x.GivenTheConfigIsValid()) + .And(x => x.GivenTheConfigIsValid()) + .And(x => x.GivenTheRequestIdCreatorReturns("blahhhh")) .When(x => x.WhenICreateTheConfig()) .Then(x => x.ThenTheReRoutesAre(new List { @@ -309,6 +312,7 @@ namespace Ocelot.UnitTests.Configuration .WithRequestIdKey("blahhhh") .Build() })) + .And(x => x.ThenTheRequestIdKeyCreatorIsCalledCorrectly()) .BDDfy(); } @@ -465,6 +469,7 @@ namespace Ocelot.UnitTests.Configuration result.ClaimsToClaims.Count.ShouldBe(expected.ClaimsToClaims.Count); result.ClaimsToHeaders.Count.ShouldBe(expected.ClaimsToHeaders.Count); result.ClaimsToQueries.Count.ShouldBe(expected.ClaimsToQueries.Count); + result.RequestIdKey.ShouldBe(expected.RequestIdKey); } } @@ -549,5 +554,19 @@ namespace Ocelot.UnitTests.Configuration .Setup(x => x.Create(It.IsAny())) .Returns(pattern); } + + private void ThenTheRequestIdKeyCreatorIsCalledCorrectly() + { + _requestIdKeyCreator + .Verify(x => x.Create(_fileConfiguration.ReRoutes[0], _fileConfiguration.GlobalConfiguration), Times.Once); + } + + private void GivenTheRequestIdCreatorReturns(string requestId) + { + _requestIdKeyCreator + .Setup(x => x.Create(It.IsAny(), It.IsAny())) + .Returns(requestId); + } + } } diff --git a/test/Ocelot.UnitTests/Configuration/RequestIdKeyCreatorTests.cs b/test/Ocelot.UnitTests/Configuration/RequestIdKeyCreatorTests.cs new file mode 100644 index 00000000..f52cb808 --- /dev/null +++ b/test/Ocelot.UnitTests/Configuration/RequestIdKeyCreatorTests.cs @@ -0,0 +1,91 @@ +using Ocelot.Configuration.Creator; +using Ocelot.Configuration.File; +using Shouldly; +using TestStack.BDDfy; +using Xunit; + +namespace Ocelot.UnitTests.Configuration +{ + public class RequestIdKeyCreatorTests + { + private FileReRoute _fileReRoute; + private FileGlobalConfiguration _fileGlobalConfig; + private string _result; + private RequestIdKeyCreator _creator; + + public RequestIdKeyCreatorTests() + { + _creator = new RequestIdKeyCreator(); + } + + [Fact] + public void should_use_global_configuration() + { + var reRoute = new FileReRoute(); + var globalConfig = new FileGlobalConfiguration + { + RequestIdKey = "cheese" + }; + + this.Given(x => x.GivenTheFollowingReRoute(reRoute)) + .And(x => x.GivenTheFollowingGlobalConfig(globalConfig)) + .When(x => x.WhenICreate()) + .Then(x => x.ThenTheFollowingIsReturned("cheese")) + .BDDfy(); + } + + [Fact] + public void should_use_re_route_specific() + { + var reRoute = new FileReRoute + { + RequestIdKey = "cheese" + }; + var globalConfig = new FileGlobalConfiguration(); + + this.Given(x => x.GivenTheFollowingReRoute(reRoute)) + .And(x => x.GivenTheFollowingGlobalConfig(globalConfig)) + .When(x => x.WhenICreate()) + .Then(x => x.ThenTheFollowingIsReturned("cheese")) + .BDDfy(); + } + + [Fact] + public void should_use_global_cofiguration_over_re_route_specific() + { + var reRoute = new FileReRoute + { + RequestIdKey = "cheese" + }; var globalConfig = new FileGlobalConfiguration + { + RequestIdKey = "cheese" + }; + + this.Given(x => x.GivenTheFollowingReRoute(reRoute)) + .And(x => x.GivenTheFollowingGlobalConfig(globalConfig)) + .When(x => x.WhenICreate()) + .Then(x => x.ThenTheFollowingIsReturned("cheese")) + .BDDfy(); + } + + private void GivenTheFollowingReRoute(FileReRoute fileReRoute) + { + _fileReRoute = fileReRoute; + } + + private void GivenTheFollowingGlobalConfig(FileGlobalConfiguration globalConfig) + { + _fileGlobalConfig = globalConfig; + } + + private void WhenICreate() + { + _result = _creator.Create(_fileReRoute, _fileGlobalConfig); + } + + private void ThenTheFollowingIsReturned(string expected) + { + _result.ShouldBe(expected); + } + } +} \ No newline at end of file