Feature/#574 look at httpclient cache key (#589)

* #574 consolidate some code, man the config stuff is a mess!

* #574 just use the downstream re route and the key for caching http clients

* #574 added benchmark, i was suprised to learn using a complex type was faster than a string in benchmark .net dictionary tests, hey ho probably dont have enough data in the type...
This commit is contained in:
Tom Pallister
2018-09-01 13:10:45 +01:00
committed by GitHub
parent 55277cac45
commit 66b68fc685
40 changed files with 672 additions and 289 deletions

View File

@ -54,6 +54,7 @@ namespace Ocelot.UnitTests.Requester
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true))
.WithLoadBalancerKey("")
.WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithOriginalValue("").Build())
.WithQosOptions(new QoSOptionsBuilder().Build())
.Build();
@ -74,6 +75,7 @@ namespace Ocelot.UnitTests.Requester
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true))
.WithLoadBalancerKey("")
.WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithOriginalValue("").Build())
.WithQosOptions(new QoSOptionsBuilder().Build())
.Build();
@ -89,6 +91,68 @@ namespace Ocelot.UnitTests.Requester
.BDDfy();
}
[Fact]
public void should_get_from_cache_with_different_query_string()
{
var qosOptions = new QoSOptionsBuilder()
.Build();
var reRoute = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true))
.WithLoadBalancerKey("")
.WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithOriginalValue("").Build())
.WithQosOptions(new QoSOptionsBuilder().Build())
.Build();
this.Given(x => GivenARealCache())
.And(x => GivenTheFactoryReturns())
.And(x => GivenARequest(reRoute, "http://wwww.someawesomewebsite.com/woot?badman=1"))
.And(x => WhenIBuildTheFirstTime())
.And(x => WhenISave())
.And(x => WhenIBuildAgain())
.And(x => GivenARequest(reRoute, "http://wwww.someawesomewebsite.com/woot?badman=2"))
.And(x => WhenISave())
.When(x => WhenIBuildAgain())
.Then(x => ThenTheHttpClientIsFromTheCache())
.BDDfy();
}
[Fact]
public void should_not_get_from_cache_with_different_query_string()
{
var qosOptions = new QoSOptionsBuilder()
.Build();
var reRouteA = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true))
.WithLoadBalancerKey("")
.WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithContainsQueryString(true).WithOriginalValue("").Build())
.WithQosOptions(new QoSOptionsBuilder().Build())
.Build();
var reRouteB = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true))
.WithLoadBalancerKey("")
.WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithContainsQueryString(true).WithOriginalValue("").Build())
.WithQosOptions(new QoSOptionsBuilder().Build())
.Build();
this.Given(x => GivenARealCache())
.And(x => GivenTheFactoryReturns())
.And(x => GivenARequest(reRouteA, "http://wwww.someawesomewebsite.com/woot?badman=1"))
.And(x => WhenIBuildTheFirstTime())
.And(x => WhenISave())
.And(x => WhenIBuildAgain())
.And(x => GivenARequest(reRouteB, "http://wwww.someawesomewebsite.com/woot?badman=2"))
.And(x => WhenISave())
.When(x => WhenIBuildAgain())
.Then(x => ThenTheHttpClientIsNotFromTheCache())
.BDDfy();
}
[Fact]
public void should_log_if_ignoring_ssl_errors()
{
@ -99,6 +163,7 @@ namespace Ocelot.UnitTests.Requester
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true))
.WithLoadBalancerKey("")
.WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithOriginalValue("").Build())
.WithQosOptions(new QoSOptionsBuilder().Build())
.WithDangerousAcceptAnyServerCertificateValidator(true)
.Build();
@ -121,6 +186,7 @@ namespace Ocelot.UnitTests.Requester
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true))
.WithLoadBalancerKey("")
.WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithOriginalValue("").Build())
.WithQosOptions(new QoSOptionsBuilder().Build())
.Build();
@ -152,6 +218,7 @@ namespace Ocelot.UnitTests.Requester
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, true, false, true))
.WithLoadBalancerKey("")
.WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithOriginalValue("").Build())
.WithQosOptions(new QoSOptionsBuilder().Build())
.Build();
@ -176,9 +243,9 @@ namespace Ocelot.UnitTests.Requester
[InlineData("PATCH")]
public void should_add_verb_to_cache_key(string verb)
{
var client = "http://localhost:5012";
var downstreamUrl = "http://localhost:5012/";
HttpMethod method = new HttpMethod(verb);
var method = new HttpMethod(verb);
var qosOptions = new QoSOptionsBuilder()
.Build();
@ -187,14 +254,15 @@ namespace Ocelot.UnitTests.Requester
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true))
.WithLoadBalancerKey("")
.WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithOriginalValue("").Build())
.WithQosOptions(new QoSOptionsBuilder().Build())
.Build();
this.Given(_ => GivenADownstreamService())
.And(_ => GivenARequestWithAUrlAndMethod(reRoute, client, method))
.And(_ => GivenARequestWithAUrlAndMethod(reRoute, downstreamUrl, method))
.And(_ => GivenTheFactoryReturnsNothing())
.And(_ => WhenIBuild())
.And(_ => GivenCacheIsCalledWithExpectedKey($"{method.ToString()}:{client}"))
.And(_ => GivenCacheIsCalledWithExpectedKey($"{method.ToString()}:{downstreamUrl}"))
.BDDfy();
}
@ -209,6 +277,11 @@ namespace Ocelot.UnitTests.Requester
_againHttpClient.ShouldBe(_firstHttpClient);
}
private void ThenTheHttpClientIsNotFromTheCache()
{
_againHttpClient.ShouldNotBe(_firstHttpClient);
}
private void WhenISave()
{
_builder.Save();
@ -216,17 +289,17 @@ namespace Ocelot.UnitTests.Requester
private void GivenCacheIsCalledWithExpectedKey(string expectedKey)
{
_cacheHandlers.Verify(x => x.Get(It.Is<string>(p => p.Equals(expectedKey, StringComparison.OrdinalIgnoreCase))), Times.Once);
_cacheHandlers.Verify(x => x.Get(It.IsAny<DownstreamReRoute>()), Times.Once);
}
private void ThenTheDangerousAcceptAnyServerCertificateValidatorWarningIsLogged()
{
_logger.Verify(x => x.LogWarning($"You have ignored all SSL warnings by using DangerousAcceptAnyServerCertificateValidator for this DownstreamReRoute, UpstreamPathTemplate: {_context.DownstreamReRoute.UpstreamPathTemplate}, DownstreamPathTemplate: {_context.DownstreamReRoute.DownstreamPathTemplate}"), Times.Once);
_logger.Verify(x => x.LogWarning($"You have ignored all SSL warnings by using DangerousAcceptAnyServerCertificateValidator for this DownstreamReRoute, UpstreamPathTemplate: {_context.DownstreamReRoute.UpstreamPathTemplate}, DownstreamDownstreamPathTemplate: {_context.DownstreamReRoute.DownstreamDownstreamPathTemplate}"), Times.Once);
}
private void GivenTheClientIsCached()
{
_cacheHandlers.Setup(x => x.Get(It.IsAny<string>())).Returns(_httpClient);
_cacheHandlers.Setup(x => x.Get(It.IsAny<DownstreamReRoute>())).Returns(_httpClient);
}
private void ThenTheCookieIsSet()
@ -287,7 +360,12 @@ namespace Ocelot.UnitTests.Requester
private void GivenARequest(DownstreamReRoute downstream)
{
GivenARequestWithAUrlAndMethod(downstream, "http://localhost:5003", HttpMethod.Get);
GivenARequest(downstream, "http://localhost:5003");
}
private void GivenARequest(DownstreamReRoute downstream, string downstreamUrl)
{
GivenARequestWithAUrlAndMethod(downstream, downstreamUrl, HttpMethod.Get);
}
private void GivenARequestWithAUrlAndMethod(DownstreamReRoute downstream, string url, HttpMethod method)