mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-04-22 06:22:50 +08:00
finished refactoring config cretor
This commit is contained in:
parent
8bbd781820
commit
558a0dfdab
71
src/Ocelot/Configuration/Builder/RateLimitOptionsBuilder.cs
Normal file
71
src/Ocelot/Configuration/Builder/RateLimitOptionsBuilder.cs
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Ocelot.Configuration.Builder
|
||||||
|
{
|
||||||
|
public class RateLimitOptionsBuilder
|
||||||
|
{
|
||||||
|
private bool _enableRateLimiting;
|
||||||
|
private string _clientIdHeader;
|
||||||
|
private List<string> _clientWhitelist;
|
||||||
|
private bool _disableRateLimitHeaders;
|
||||||
|
private string _quotaExceededMessage;
|
||||||
|
private string _rateLimitCounterPrefix;
|
||||||
|
private RateLimitRule _rateLimitRule;
|
||||||
|
private int _httpStatusCode;
|
||||||
|
|
||||||
|
public RateLimitOptionsBuilder WithEnableRateLimiting(bool enableRateLimiting)
|
||||||
|
{
|
||||||
|
_enableRateLimiting = enableRateLimiting;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RateLimitOptionsBuilder WithClientIdHeader(string clientIdheader)
|
||||||
|
{
|
||||||
|
_clientIdHeader = clientIdheader;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RateLimitOptionsBuilder WithClientWhiteList(List<string> clientWhitelist)
|
||||||
|
{
|
||||||
|
_clientWhitelist = clientWhitelist;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RateLimitOptionsBuilder WithDisableRateLimitHeaders(bool disableRateLimitHeaders)
|
||||||
|
{
|
||||||
|
_disableRateLimitHeaders = disableRateLimitHeaders;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RateLimitOptionsBuilder WithQuotaExceededMessage(string quotaExceededMessage)
|
||||||
|
{
|
||||||
|
_quotaExceededMessage = quotaExceededMessage;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RateLimitOptionsBuilder WithRateLimitCounterPrefix(string rateLimitCounterPrefix)
|
||||||
|
{
|
||||||
|
_rateLimitCounterPrefix = rateLimitCounterPrefix;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RateLimitOptionsBuilder WithRateLimitRule(RateLimitRule rateLimitRule)
|
||||||
|
{
|
||||||
|
_rateLimitRule = rateLimitRule;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RateLimitOptionsBuilder WithHttpStatusCode(int httpStatusCode)
|
||||||
|
{
|
||||||
|
_httpStatusCode = httpStatusCode;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RateLimitOptions Build()
|
||||||
|
{
|
||||||
|
return new RateLimitOptions(_enableRateLimiting, _clientIdHeader, _clientWhitelist,
|
||||||
|
_disableRateLimitHeaders, _quotaExceededMessage, _rateLimitCounterPrefix,
|
||||||
|
_rateLimitRule, _httpStatusCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -34,6 +34,7 @@ namespace Ocelot.Configuration.Creator
|
|||||||
private IServiceProviderConfigurationCreator _serviceProviderConfigCreator;
|
private IServiceProviderConfigurationCreator _serviceProviderConfigCreator;
|
||||||
private IQoSOptionsCreator _qosOptionsCreator;
|
private IQoSOptionsCreator _qosOptionsCreator;
|
||||||
private IReRouteOptionsCreator _fileReRouteOptionsCreator;
|
private IReRouteOptionsCreator _fileReRouteOptionsCreator;
|
||||||
|
private IRateLimitOptionsCreator _rateLimitOptionsCreator;
|
||||||
|
|
||||||
public FileOcelotConfigurationCreator(
|
public FileOcelotConfigurationCreator(
|
||||||
IOptions<FileConfiguration> options,
|
IOptions<FileConfiguration> options,
|
||||||
@ -49,9 +50,11 @@ namespace Ocelot.Configuration.Creator
|
|||||||
IRequestIdKeyCreator requestIdKeyCreator,
|
IRequestIdKeyCreator requestIdKeyCreator,
|
||||||
IServiceProviderConfigurationCreator serviceProviderConfigCreator,
|
IServiceProviderConfigurationCreator serviceProviderConfigCreator,
|
||||||
IQoSOptionsCreator qosOptionsCreator,
|
IQoSOptionsCreator qosOptionsCreator,
|
||||||
IReRouteOptionsCreator fileReRouteOptionsCreator
|
IReRouteOptionsCreator fileReRouteOptionsCreator,
|
||||||
|
IRateLimitOptionsCreator rateLimitOptionsCreator
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
_rateLimitOptionsCreator = rateLimitOptionsCreator;
|
||||||
_requestIdKeyCreator = requestIdKeyCreator;
|
_requestIdKeyCreator = requestIdKeyCreator;
|
||||||
_upstreamTemplatePatternCreator = upstreamTemplatePatternCreator;
|
_upstreamTemplatePatternCreator = upstreamTemplatePatternCreator;
|
||||||
_authOptionsCreator = authOptionsCreator;
|
_authOptionsCreator = authOptionsCreator;
|
||||||
@ -131,7 +134,7 @@ namespace Ocelot.Configuration.Creator
|
|||||||
|
|
||||||
var qosOptions = _qosOptionsCreator.Create(fileReRoute);
|
var qosOptions = _qosOptionsCreator.Create(fileReRoute);
|
||||||
|
|
||||||
var rateLimitOption = BuildRateLimitOptions(fileReRoute, globalConfiguration, fileReRouteOptions.EnableRateLimiting);
|
var rateLimitOption = _rateLimitOptionsCreator.Create(fileReRoute, globalConfiguration, fileReRouteOptions.EnableRateLimiting);
|
||||||
|
|
||||||
var reRoute = new ReRouteBuilder()
|
var reRoute = new ReRouteBuilder()
|
||||||
.WithDownstreamPathTemplate(fileReRoute.DownstreamPathTemplate)
|
.WithDownstreamPathTemplate(fileReRoute.DownstreamPathTemplate)
|
||||||
@ -165,21 +168,6 @@ namespace Ocelot.Configuration.Creator
|
|||||||
return reRoute;
|
return reRoute;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static RateLimitOptions BuildRateLimitOptions(FileReRoute fileReRoute, FileGlobalConfiguration globalConfiguration, bool enableRateLimiting)
|
|
||||||
{
|
|
||||||
RateLimitOptions rateLimitOption = null;
|
|
||||||
if (enableRateLimiting)
|
|
||||||
{
|
|
||||||
rateLimitOption = new RateLimitOptions(enableRateLimiting, globalConfiguration.RateLimitOptions.ClientIdHeader,
|
|
||||||
fileReRoute.RateLimitOptions.ClientWhitelist, globalConfiguration.RateLimitOptions.DisableRateLimitHeaders,
|
|
||||||
globalConfiguration.RateLimitOptions.QuotaExceededMessage, globalConfiguration.RateLimitOptions.RateLimitCounterPrefix,
|
|
||||||
new RateLimitRule(fileReRoute.RateLimitOptions.Period, TimeSpan.FromSeconds(fileReRoute.RateLimitOptions.PeriodTimespan), fileReRoute.RateLimitOptions.Limit)
|
|
||||||
, globalConfiguration.RateLimitOptions.HttpStatusCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rateLimitOption;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string CreateReRouteKey(FileReRoute fileReRoute)
|
private string CreateReRouteKey(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
|
//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
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
using Ocelot.Configuration.File;
|
||||||
|
|
||||||
|
namespace Ocelot.Configuration.Creator
|
||||||
|
{
|
||||||
|
public interface IRateLimitOptionsCreator
|
||||||
|
{
|
||||||
|
RateLimitOptions Create(FileReRoute fileReRoute, FileGlobalConfiguration globalConfiguration, bool enableRateLimiting);
|
||||||
|
}
|
||||||
|
}
|
32
src/Ocelot/Configuration/Creator/RateLimitOptionsCreator.cs
Normal file
32
src/Ocelot/Configuration/Creator/RateLimitOptionsCreator.cs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
using System;
|
||||||
|
using Ocelot.Configuration.Builder;
|
||||||
|
using Ocelot.Configuration.File;
|
||||||
|
|
||||||
|
namespace Ocelot.Configuration.Creator
|
||||||
|
{
|
||||||
|
public class RateLimitOptionsCreator : IRateLimitOptionsCreator
|
||||||
|
{
|
||||||
|
public RateLimitOptions Create(FileReRoute fileReRoute, FileGlobalConfiguration globalConfiguration, bool enableRateLimiting)
|
||||||
|
{
|
||||||
|
RateLimitOptions rateLimitOption = null;
|
||||||
|
|
||||||
|
if (enableRateLimiting)
|
||||||
|
{
|
||||||
|
rateLimitOption = new RateLimitOptionsBuilder()
|
||||||
|
.WithClientIdHeader(globalConfiguration.RateLimitOptions.ClientIdHeader)
|
||||||
|
.WithClientWhiteList(fileReRoute.RateLimitOptions.ClientWhitelist)
|
||||||
|
.WithDisableRateLimitHeaders(globalConfiguration.RateLimitOptions.DisableRateLimitHeaders)
|
||||||
|
.WithEnableRateLimiting(fileReRoute.RateLimitOptions.EnableRateLimiting)
|
||||||
|
.WithHttpStatusCode(globalConfiguration.RateLimitOptions.HttpStatusCode)
|
||||||
|
.WithQuotaExceededMessage(globalConfiguration.RateLimitOptions.QuotaExceededMessage)
|
||||||
|
.WithRateLimitCounterPrefix(globalConfiguration.RateLimitOptions.RateLimitCounterPrefix)
|
||||||
|
.WithRateLimitRule(new RateLimitRule(fileReRoute.RateLimitOptions.Period,
|
||||||
|
TimeSpan.FromSeconds(fileReRoute.RateLimitOptions.PeriodTimespan),
|
||||||
|
fileReRoute.RateLimitOptions.Limit))
|
||||||
|
.Build();
|
||||||
|
}
|
||||||
|
|
||||||
|
return rateLimitOption;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -67,6 +67,7 @@ namespace Ocelot.DependencyInjection
|
|||||||
services.AddSingleton<IServiceProviderConfigurationCreator,ServiceProviderConfigurationCreator>();
|
services.AddSingleton<IServiceProviderConfigurationCreator,ServiceProviderConfigurationCreator>();
|
||||||
services.AddSingleton<IQoSOptionsCreator, QoSOptionsCreator>();
|
services.AddSingleton<IQoSOptionsCreator, QoSOptionsCreator>();
|
||||||
services.AddSingleton<IReRouteOptionsCreator, ReRouteOptionsCreator>();
|
services.AddSingleton<IReRouteOptionsCreator, ReRouteOptionsCreator>();
|
||||||
|
services.AddSingleton<IRateLimitOptionsCreator, RateLimitOptionsCreator>();
|
||||||
|
|
||||||
var identityServerConfiguration = IdentityServerConfigurationCreator.GetIdentityServerConfiguration();
|
var identityServerConfiguration = IdentityServerConfigurationCreator.GetIdentityServerConfiguration();
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
private Mock<IServiceProviderConfigurationCreator> _serviceProviderConfigCreator;
|
private Mock<IServiceProviderConfigurationCreator> _serviceProviderConfigCreator;
|
||||||
private Mock<IQoSOptionsCreator> _qosOptionsCreator;
|
private Mock<IQoSOptionsCreator> _qosOptionsCreator;
|
||||||
private Mock<IReRouteOptionsCreator> _fileReRouteOptionsCreator;
|
private Mock<IReRouteOptionsCreator> _fileReRouteOptionsCreator;
|
||||||
|
private Mock<IRateLimitOptionsCreator> _rateLimitOptions;
|
||||||
|
|
||||||
public FileConfigurationCreatorTests()
|
public FileConfigurationCreatorTests()
|
||||||
{
|
{
|
||||||
@ -56,13 +57,41 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
_serviceProviderConfigCreator = new Mock<IServiceProviderConfigurationCreator>();
|
_serviceProviderConfigCreator = new Mock<IServiceProviderConfigurationCreator>();
|
||||||
_qosOptionsCreator = new Mock<IQoSOptionsCreator>();
|
_qosOptionsCreator = new Mock<IQoSOptionsCreator>();
|
||||||
_fileReRouteOptionsCreator = new Mock<IReRouteOptionsCreator>();
|
_fileReRouteOptionsCreator = new Mock<IReRouteOptionsCreator>();
|
||||||
|
_rateLimitOptions = new Mock<IRateLimitOptionsCreator>();
|
||||||
|
|
||||||
_ocelotConfigurationCreator = new FileOcelotConfigurationCreator(
|
_ocelotConfigurationCreator = new FileOcelotConfigurationCreator(
|
||||||
_fileConfig.Object, _validator.Object, _logger.Object,
|
_fileConfig.Object, _validator.Object, _logger.Object,
|
||||||
_loadBalancerFactory.Object, _loadBalancerHouse.Object,
|
_loadBalancerFactory.Object, _loadBalancerHouse.Object,
|
||||||
_qosProviderFactory.Object, _qosProviderHouse.Object, _claimsToThingCreator.Object,
|
_qosProviderFactory.Object, _qosProviderHouse.Object, _claimsToThingCreator.Object,
|
||||||
_authOptionsCreator.Object, _upstreamTemplatePatternCreator.Object, _requestIdKeyCreator.Object,
|
_authOptionsCreator.Object, _upstreamTemplatePatternCreator.Object, _requestIdKeyCreator.Object,
|
||||||
_serviceProviderConfigCreator.Object, _qosOptionsCreator.Object, _fileReRouteOptionsCreator.Object);
|
_serviceProviderConfigCreator.Object, _qosOptionsCreator.Object, _fileReRouteOptionsCreator.Object,
|
||||||
|
_rateLimitOptions.Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_call_rate_limit_options_creator()
|
||||||
|
{
|
||||||
|
var reRouteOptions = new ReRouteOptionsBuilder()
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
|
||||||
|
{
|
||||||
|
ReRoutes = new List<FileReRoute>
|
||||||
|
{
|
||||||
|
new FileReRoute
|
||||||
|
{
|
||||||
|
DownstreamHost = "127.0.0.1",
|
||||||
|
UpstreamPathTemplate = "/api/products/{productId}",
|
||||||
|
DownstreamPathTemplate = "/products/{productId}",
|
||||||
|
UpstreamHttpMethod = "Get",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
.And(x => x.GivenTheConfigIsValid())
|
||||||
|
.And(x => x.GivenTheFollowingOptionsAreReturned(reRouteOptions))
|
||||||
|
.When(x => x.WhenICreateTheConfig())
|
||||||
|
.Then(x => x.ThenTheRateLimitOptionsCreatorIsCalledCorrectly())
|
||||||
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -431,8 +460,6 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_create_with_authentication_properties()
|
public void should_create_with_authentication_properties()
|
||||||
{
|
{
|
||||||
@ -499,6 +526,11 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
.Returns(fileReRouteOptions);
|
.Returns(fileReRouteOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ThenTheRateLimitOptionsCreatorIsCalledCorrectly()
|
||||||
|
{
|
||||||
|
_rateLimitOptions
|
||||||
|
.Verify(x => x.Create(It.IsAny<FileReRoute>(), It.IsAny<FileGlobalConfiguration>(), It.IsAny<bool>()), Times.Once);
|
||||||
|
}
|
||||||
|
|
||||||
private void GivenTheConfigIsValid()
|
private void GivenTheConfigIsValid()
|
||||||
{
|
{
|
||||||
|
@ -0,0 +1,108 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Ocelot.Configuration;
|
||||||
|
using Ocelot.Configuration.Builder;
|
||||||
|
using Ocelot.Configuration.Creator;
|
||||||
|
using Ocelot.Configuration.File;
|
||||||
|
using Shouldly;
|
||||||
|
using TestStack.BDDfy;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Ocelot.UnitTests.Configuration
|
||||||
|
{
|
||||||
|
public class RateLimitOptionsCreatorTests
|
||||||
|
{
|
||||||
|
private FileReRoute _fileReRoute;
|
||||||
|
private FileGlobalConfiguration _fileGlobalConfig;
|
||||||
|
private bool _enabled;
|
||||||
|
private RateLimitOptionsCreator _creator;
|
||||||
|
private RateLimitOptions _result;
|
||||||
|
|
||||||
|
public RateLimitOptionsCreatorTests()
|
||||||
|
{
|
||||||
|
_creator = new RateLimitOptionsCreator();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_create_rate_limit_options()
|
||||||
|
{
|
||||||
|
var fileReRoute = new FileReRoute
|
||||||
|
{
|
||||||
|
RateLimitOptions = new FileRateLimitRule
|
||||||
|
{
|
||||||
|
ClientWhitelist = new List<string>(),
|
||||||
|
Period = "Period",
|
||||||
|
Limit = 1,
|
||||||
|
PeriodTimespan = 1,
|
||||||
|
EnableRateLimiting = true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var fileGlobalConfig = new FileGlobalConfiguration
|
||||||
|
{
|
||||||
|
RateLimitOptions = new FileRateLimitOptions
|
||||||
|
{
|
||||||
|
ClientIdHeader = "ClientIdHeader",
|
||||||
|
DisableRateLimitHeaders = true,
|
||||||
|
QuotaExceededMessage = "QuotaExceededMessage",
|
||||||
|
RateLimitCounterPrefix = "RateLimitCounterPrefix",
|
||||||
|
HttpStatusCode = 200
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var expected = new RateLimitOptionsBuilder()
|
||||||
|
.WithClientIdHeader("ClientIdHeader")
|
||||||
|
.WithClientWhiteList(fileReRoute.RateLimitOptions.ClientWhitelist)
|
||||||
|
.WithDisableRateLimitHeaders(true)
|
||||||
|
.WithEnableRateLimiting(true)
|
||||||
|
.WithHttpStatusCode(200)
|
||||||
|
.WithQuotaExceededMessage("QuotaExceededMessage")
|
||||||
|
.WithRateLimitCounterPrefix("RateLimitCounterPrefix")
|
||||||
|
.WithRateLimitRule(new RateLimitRule(fileReRoute.RateLimitOptions.Period,
|
||||||
|
TimeSpan.FromSeconds(fileReRoute.RateLimitOptions.PeriodTimespan),
|
||||||
|
fileReRoute.RateLimitOptions.Limit))
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
|
||||||
|
.And(x => x.GivenTheFollowingFileGlobalConfig(fileGlobalConfig))
|
||||||
|
.And(x => x.GivenRateLimitingIsEnabled())
|
||||||
|
.When(x => x.WhenICreate())
|
||||||
|
.Then(x => x.ThenTheFollowingIsReturned(expected))
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenTheFollowingFileReRoute(FileReRoute fileReRoute)
|
||||||
|
{
|
||||||
|
_fileReRoute = fileReRoute;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenTheFollowingFileGlobalConfig(FileGlobalConfiguration fileGlobalConfig)
|
||||||
|
{
|
||||||
|
_fileGlobalConfig = fileGlobalConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenRateLimitingIsEnabled()
|
||||||
|
{
|
||||||
|
_enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WhenICreate()
|
||||||
|
{
|
||||||
|
_result = _creator.Create(_fileReRoute, _fileGlobalConfig, _enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThenTheFollowingIsReturned(RateLimitOptions expected)
|
||||||
|
{
|
||||||
|
_result.ClientIdHeader.ShouldBe(expected.ClientIdHeader);
|
||||||
|
_result.ClientWhitelist.ShouldBe(expected.ClientWhitelist);
|
||||||
|
_result.DisableRateLimitHeaders.ShouldBe(expected.DisableRateLimitHeaders);
|
||||||
|
_result.EnableRateLimiting.ShouldBe(expected.EnableRateLimiting);
|
||||||
|
_result.HttpStatusCode.ShouldBe(expected.HttpStatusCode);
|
||||||
|
_result.QuotaExceededMessage.ShouldBe(expected.QuotaExceededMessage);
|
||||||
|
_result.RateLimitCounterPrefix.ShouldBe(expected.RateLimitCounterPrefix);
|
||||||
|
_result.RateLimitRule.Limit.ShouldBe(expected.RateLimitRule.Limit);
|
||||||
|
_result.RateLimitRule.Period.ShouldBe(expected.RateLimitRule.Period);
|
||||||
|
_result.RateLimitRule.PeriodTimespan.Ticks.ShouldBe(expected.RateLimitRule.PeriodTimespan.Ticks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user