mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-06-19 12:18:16 +08:00
Feature/more dynamic routes (#508)
* Made the file config poller use IHostedService, bit more generic, not just need to provide the correct implementations of the repo services and it will poll anything..this means we can open up redis for #458 * removed comments * #458 allow users to set rate limits per service for dynamic re routes * #458 added docs for rate limting on dynamic reroutes
This commit is contained in:
@ -17,6 +17,7 @@
|
||||
using Ocelot.Errors;
|
||||
using Ocelot.UnitTests.TestData;
|
||||
using Ocelot.Values;
|
||||
using System;
|
||||
|
||||
public class FileInternalConfigurationCreatorTests
|
||||
{
|
||||
@ -821,6 +822,54 @@
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_set_up_dynamic_re_routes()
|
||||
{
|
||||
var reRouteOptions = new ReRouteOptionsBuilder()
|
||||
.Build();
|
||||
|
||||
var downstreamReRoute = new DownstreamReRouteBuilder()
|
||||
.WithEnableRateLimiting(true)
|
||||
.WithRateLimitOptions(new RateLimitOptionsBuilder().Build())
|
||||
.Build();
|
||||
|
||||
var rateLimitOptions = new RateLimitOptionsBuilder()
|
||||
.WithRateLimitRule(new RateLimitRule("1s", 1, 1))
|
||||
.Build();
|
||||
|
||||
this.Given(x => x.GivenTheConfigIs(new FileConfiguration
|
||||
{
|
||||
DynamicReRoutes = new List<FileDynamicReRoute>
|
||||
{
|
||||
new FileDynamicReRoute
|
||||
{
|
||||
ServiceName = "test",
|
||||
RateLimitRule = new FileRateLimitRule
|
||||
{
|
||||
Period = "1s",
|
||||
PeriodTimespan = 1,
|
||||
Limit = 1
|
||||
}
|
||||
}
|
||||
},
|
||||
}))
|
||||
.And(x => x.GivenTheConfigIsValid())
|
||||
.And(x => GivenTheRateLimitCreatorReturns(rateLimitOptions))
|
||||
.And(x => GivenTheDownstreamAddresses())
|
||||
.And(x => GivenTheHeaderFindAndReplaceCreatorReturns())
|
||||
.And(x => x.GivenTheFollowingOptionsAreReturned(reRouteOptions))
|
||||
.When(x => x.WhenICreateTheConfig())
|
||||
.Then(x => x.ThenTheDynamicReRouteIsSetUp("test", rateLimitOptions.RateLimitRule))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheRateLimitCreatorReturns(RateLimitOptions rateLimitOptions)
|
||||
{
|
||||
_rateLimitOptions
|
||||
.Setup(x => x.Create(It.IsAny<FileRateLimitRule>(), It.IsAny<FileGlobalConfiguration>()))
|
||||
.Returns(rateLimitOptions);
|
||||
}
|
||||
|
||||
private void GivenTheConfigIsInvalid(List<Error> errors)
|
||||
{
|
||||
_validator
|
||||
@ -844,7 +893,7 @@
|
||||
private void ThenTheRateLimitOptionsCreatorIsCalledCorrectly()
|
||||
{
|
||||
_rateLimitOptions
|
||||
.Verify(x => x.Create(It.IsAny<FileReRoute>(), It.IsAny<FileGlobalConfiguration>(), It.IsAny<bool>()), Times.Once);
|
||||
.Verify(x => x.Create(It.IsAny<FileRateLimitRule>(), It.IsAny<FileGlobalConfiguration>()), Times.Once);
|
||||
}
|
||||
|
||||
private void GivenTheConfigIsValid()
|
||||
@ -864,6 +913,16 @@
|
||||
_config = _internalConfigurationCreator.Create(_fileConfiguration).Result;
|
||||
}
|
||||
|
||||
private void ThenTheDynamicReRouteIsSetUp(string serviceName, RateLimitRule rateLimitOptions)
|
||||
{
|
||||
var dynamic = _config.Data.ReRoutes[0].DownstreamReRoute[0];
|
||||
dynamic.ServiceName.ShouldBe(serviceName);
|
||||
dynamic.EnableEndpointEndpointRateLimiting.ShouldBeTrue();
|
||||
dynamic.RateLimitOptions.RateLimitRule.Period.ShouldBe(rateLimitOptions.Period);
|
||||
dynamic.RateLimitOptions.RateLimitRule.Limit.ShouldBe(rateLimitOptions.Limit);
|
||||
dynamic.RateLimitOptions.RateLimitRule.PeriodTimespan.ShouldBe(rateLimitOptions.PeriodTimespan);
|
||||
}
|
||||
|
||||
private void ThenTheReRoutesAre(List<ReRoute> expectedReRoutes)
|
||||
{
|
||||
for (int i = 0; i < _config.Data.ReRoutes.Count; i++)
|
||||
|
@ -1,108 +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,
|
||||
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);
|
||||
TimeSpan.FromSeconds(_result.RateLimitRule.PeriodTimespan).Ticks.ShouldBe(TimeSpan.FromSeconds(expected.RateLimitRule.PeriodTimespan).Ticks);
|
||||
}
|
||||
}
|
||||
}
|
||||
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,
|
||||
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.RateLimitOptions, _fileGlobalConfig);
|
||||
}
|
||||
|
||||
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);
|
||||
TimeSpan.FromSeconds(_result.RateLimitRule.PeriodTimespan).Ticks.ShouldBe(TimeSpan.FromSeconds(expected.RateLimitRule.PeriodTimespan).Ticks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user