Feature/move polly (#561)

* added delegate to select last handler

* #529 implemented a way we can inject the last delegating handler

* wip - moving code

* #529 removed loads of qos code and moved it into Ocelot.Provider.Polly
This commit is contained in:
Tom Pallister
2018-08-19 10:14:15 +01:00
committed by GitHub
parent e909cf9ce7
commit 98ba0271be
27 changed files with 213 additions and 669 deletions

View File

@ -16,23 +16,28 @@ using Xunit;
namespace Ocelot.UnitTests.Requester
{
using Responder;
public class DelegatingHandlerHandlerProviderFactoryTests
{
private DelegatingHandlerHandlerFactory _factory;
private readonly Mock<IOcelotLoggerFactory> _loggerFactory;
private DownstreamReRoute _request;
private Response<List<Func<DelegatingHandler>>> _result;
private readonly Mock<IQosProviderHouse> _qosProviderHouse;
private readonly Mock<IQoSFactory> _qosFactory;
private readonly Mock<ITracingHandlerFactory> _tracingFactory;
private IServiceProvider _serviceProvider;
private readonly IServiceCollection _services;
private readonly QosDelegatingHandlerDelegate _qosDelegate;
public DelegatingHandlerHandlerProviderFactoryTests()
{
_qosDelegate = (a, b) => new FakeQoSHandler();
_tracingFactory = new Mock<ITracingHandlerFactory>();
_qosProviderHouse = new Mock<IQosProviderHouse>();
_qosFactory = new Mock<IQoSFactory>();
_loggerFactory = new Mock<IOcelotLoggerFactory>();
_services = new ServiceCollection();
_services.AddSingleton(_qosDelegate);
}
[Fact]
@ -56,8 +61,8 @@ namespace Ocelot.UnitTests.Requester
.Build();
this.Given(x => GivenTheFollowingRequest(reRoute))
.And(x => GivenTheQosFactoryReturns(new FakeQoSHandler()))
.And(x => GivenTheTracingFactoryReturns())
.And(x => GivenTheQosProviderHouseReturns(new OkResponse<IQoSProvider>(It.IsAny<PollyQoSProvider>())))
.And(x => GivenTheServiceProviderReturnsGlobalDelegatingHandlers<FakeDelegatingHandlerThree, FakeDelegatingHandlerFour>())
.And(x => GivenTheServiceProviderReturnsSpecificDelegatingHandlers<FakeDelegatingHandler, FakeDelegatingHandlerTwo>())
.When(x => WhenIGet())
@ -67,7 +72,7 @@ namespace Ocelot.UnitTests.Requester
.And(x => ThenHandlerAtPositionIs<FakeDelegatingHandler>(2))
.And(x => ThenHandlerAtPositionIs<FakeDelegatingHandlerTwo>(3))
.And(x => ThenHandlerAtPositionIs<FakeTracingHandler>(4))
.And(x => ThenHandlerAtPositionIs<PollyCircuitBreakingDelegatingHandler>(5))
.And(x => ThenHandlerAtPositionIs<FakeQoSHandler>(5))
.BDDfy();
}
@ -93,8 +98,8 @@ namespace Ocelot.UnitTests.Requester
.Build();
this.Given(x => GivenTheFollowingRequest(reRoute))
.And(x => GivenTheQosFactoryReturns(new FakeQoSHandler()))
.And(x => GivenTheTracingFactoryReturns())
.And(x => GivenTheQosProviderHouseReturns(new OkResponse<IQoSProvider>(It.IsAny<PollyQoSProvider>())))
.And(x => GivenTheServiceProviderReturnsGlobalDelegatingHandlers<FakeDelegatingHandlerFour, FakeDelegatingHandlerThree>())
.And(x => GivenTheServiceProviderReturnsSpecificDelegatingHandlers<FakeDelegatingHandler, FakeDelegatingHandlerTwo>())
.When(x => WhenIGet())
@ -104,7 +109,7 @@ namespace Ocelot.UnitTests.Requester
.And(x => ThenHandlerAtPositionIs<FakeDelegatingHandler>(2)) //second from config
.And(x => ThenHandlerAtPositionIs<FakeDelegatingHandlerFour>(3)) //third from config (global)
.And(x => ThenHandlerAtPositionIs<FakeTracingHandler>(4))
.And(x => ThenHandlerAtPositionIs<PollyCircuitBreakingDelegatingHandler>(5))
.And(x => ThenHandlerAtPositionIs<FakeQoSHandler>(5))
.BDDfy();
}
@ -129,8 +134,8 @@ namespace Ocelot.UnitTests.Requester
.Build();
this.Given(x => GivenTheFollowingRequest(reRoute))
.And(x => GivenTheQosFactoryReturns(new FakeQoSHandler()))
.And(x => GivenTheTracingFactoryReturns())
.And(x => GivenTheQosProviderHouseReturns(new OkResponse<IQoSProvider>(It.IsAny<PollyQoSProvider>())))
.And(x => GivenTheServiceProviderReturnsGlobalDelegatingHandlers<FakeDelegatingHandlerThree, FakeDelegatingHandlerFour>())
.And(x => GivenTheServiceProviderReturnsSpecificDelegatingHandlers<FakeDelegatingHandler, FakeDelegatingHandlerTwo>())
.When(x => WhenIGet())
@ -140,7 +145,7 @@ namespace Ocelot.UnitTests.Requester
.And(x => ThenHandlerAtPositionIs<FakeDelegatingHandlerTwo>(2))
.And(x => ThenHandlerAtPositionIs<FakeDelegatingHandler>(3))
.And(x => ThenHandlerAtPositionIs<FakeTracingHandler>(4))
.And(x => ThenHandlerAtPositionIs<PollyCircuitBreakingDelegatingHandler>(5))
.And(x => ThenHandlerAtPositionIs<FakeQoSHandler>(5))
.BDDfy();
}
@ -164,8 +169,8 @@ namespace Ocelot.UnitTests.Requester
.Build();
this.Given(x => GivenTheFollowingRequest(reRoute))
.And(x => GivenTheQosFactoryReturns(new FakeQoSHandler()))
.And(x => GivenTheTracingFactoryReturns())
.And(x => GivenTheQosProviderHouseReturns(new OkResponse<IQoSProvider>(It.IsAny<PollyQoSProvider>())))
.And(x => GivenTheServiceProviderReturnsGlobalDelegatingHandlers<FakeDelegatingHandlerThree, FakeDelegatingHandlerFour>())
.And(x => GivenTheServiceProviderReturnsSpecificDelegatingHandlers<FakeDelegatingHandler, FakeDelegatingHandlerTwo>())
.When(x => WhenIGet())
@ -174,7 +179,7 @@ namespace Ocelot.UnitTests.Requester
.And(x => ThenHandlerAtPositionIs<FakeDelegatingHandlerFour>(1))
.And(x => ThenHandlerAtPositionIs<FakeDelegatingHandler>(2))
.And(x => ThenHandlerAtPositionIs<FakeTracingHandler>(3))
.And(x => ThenHandlerAtPositionIs<PollyCircuitBreakingDelegatingHandler>(4))
.And(x => ThenHandlerAtPositionIs<FakeQoSHandler>(4))
.BDDfy();
}
@ -194,8 +199,8 @@ namespace Ocelot.UnitTests.Requester
.Build();
this.Given(x => GivenTheFollowingRequest(reRoute))
.And(x => GivenTheQosFactoryReturns(new FakeQoSHandler()))
.And(x => GivenTheTracingFactoryReturns())
.And(x => GivenTheQosProviderHouseReturns(new OkResponse<IQoSProvider>(It.IsAny<PollyQoSProvider>())))
.And(x => GivenTheServiceProviderReturnsGlobalDelegatingHandlers<FakeDelegatingHandler, FakeDelegatingHandlerTwo>())
.And(x => GivenTheServiceProviderReturnsSpecificDelegatingHandlers<FakeDelegatingHandler, FakeDelegatingHandlerTwo>())
.When(x => WhenIGet())
@ -203,7 +208,7 @@ namespace Ocelot.UnitTests.Requester
.And(x => ThenHandlerAtPositionIs<FakeDelegatingHandler>(0))
.And(x => ThenHandlerAtPositionIs<FakeDelegatingHandlerTwo>(1))
.And(x => ThenHandlerAtPositionIs<FakeTracingHandler>(2))
.And(x => ThenHandlerAtPositionIs<PollyCircuitBreakingDelegatingHandler>(3))
.And(x => ThenHandlerAtPositionIs<FakeQoSHandler>(3))
.BDDfy();
}
@ -225,7 +230,6 @@ namespace Ocelot.UnitTests.Requester
.Build();
this.Given(x => GivenTheFollowingRequest(reRoute))
.And(x => GivenTheQosProviderHouseReturns(new OkResponse<IQoSProvider>(It.IsAny<PollyQoSProvider>())))
.And(x => GivenTheServiceProviderReturnsSpecificDelegatingHandlers<FakeDelegatingHandler, FakeDelegatingHandlerTwo>())
.When(x => WhenIGet())
.Then(x => ThenThereIsDelegatesInProvider(2))
@ -247,12 +251,12 @@ namespace Ocelot.UnitTests.Requester
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false, true)).WithLoadBalancerKey("").Build();
this.Given(x => GivenTheFollowingRequest(reRoute))
.And(x => GivenTheQosProviderHouseReturns(new OkResponse<IQoSProvider>(It.IsAny<PollyQoSProvider>())))
.And(x => GivenTheQosFactoryReturns(new FakeQoSHandler()))
.And(x => GivenTheServiceProviderReturnsGlobalDelegatingHandlers<FakeDelegatingHandler, FakeDelegatingHandlerTwo>())
.When(x => WhenIGet())
.Then(x => ThenThereIsDelegatesInProvider(3))
.And(x => ThenTheDelegatesAreAddedCorrectly())
.And(x => ThenItIsPolly(2))
.And(x => ThenItIsQosHandler(2))
.BDDfy();
}
@ -287,11 +291,11 @@ namespace Ocelot.UnitTests.Requester
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false, true)).WithLoadBalancerKey("").Build();
this.Given(x => GivenTheFollowingRequest(reRoute))
.And(x => GivenTheQosProviderHouseReturns(new OkResponse<IQoSProvider>(It.IsAny<PollyQoSProvider>())))
.And(x => GivenTheQosFactoryReturns(new FakeQoSHandler()))
.And(x => GivenTheServiceProviderReturnsNothing())
.When(x => WhenIGet())
.Then(x => ThenThereIsDelegatesInProvider(1))
.And(x => ThenItIsPolly(0))
.And(x => ThenItIsQosHandler(0))
.BDDfy();
}
@ -309,7 +313,7 @@ namespace Ocelot.UnitTests.Requester
.WithHttpHandlerOptions(new HttpHandlerOptions(true, true, false, true)).WithLoadBalancerKey("").Build();
this.Given(x => GivenTheFollowingRequest(reRoute))
.And(x => GivenTheQosProviderHouseReturns(new ErrorResponse<IQoSProvider>(It.IsAny<Error>())))
.And(x => GivenTheQosFactoryReturnsError())
.And(x => GivenTheServiceProviderReturnsNothing())
.When(x => WhenIGet())
.Then(x => ThenAnErrorIsReturned())
@ -378,18 +382,25 @@ namespace Ocelot.UnitTests.Requester
handlerTwo.Order.ShouldBe(2);
}
private void GivenTheQosProviderHouseReturns(Response<IQoSProvider> qosProvider)
private void GivenTheQosFactoryReturns(DelegatingHandler handler)
{
_qosProviderHouse
_qosFactory
.Setup(x => x.Get(It.IsAny<DownstreamReRoute>()))
.Returns(qosProvider);
.Returns(new OkResponse<DelegatingHandler>(handler));
}
private void ThenItIsPolly(int i)
private void GivenTheQosFactoryReturnsError()
{
_qosFactory
.Setup(x => x.Get(It.IsAny<DownstreamReRoute>()))
.Returns(new ErrorResponse<DelegatingHandler>(new AnyError()));
}
private void ThenItIsQosHandler(int i)
{
var delegates = _result.Data;
var del = delegates[i].Invoke();
del.ShouldBeOfType<PollyCircuitBreakingDelegatingHandler>();
del.ShouldBeOfType<FakeQoSHandler>();
}
private void ThenThereIsDelegatesInProvider(int count)
@ -406,7 +417,7 @@ namespace Ocelot.UnitTests.Requester
private void WhenIGet()
{
_serviceProvider = _services.BuildServiceProvider();
_factory = new DelegatingHandlerHandlerFactory(_loggerFactory.Object, _tracingFactory.Object, _qosProviderHouse.Object, _serviceProvider);
_factory = new DelegatingHandlerHandlerFactory(_tracingFactory.Object, _qosFactory.Object, _serviceProvider);
_result = _factory.Get(_request);
}
@ -420,4 +431,8 @@ namespace Ocelot.UnitTests.Requester
internal class FakeTracingHandler : DelegatingHandler, ITracingHandler
{
}
internal class FakeQoSHandler : DelegatingHandler
{
}
}

View File

@ -144,7 +144,7 @@ namespace Ocelot.UnitTests.Requester
private void ThenTheErrorIsTimeout()
{
_response.Errors[0].ShouldBeOfType<RequestTimedOutError>();
_response.Errors[0].ShouldBeOfType<UnableToCompleteRequestError>();
}
private void GivenTheHouseReturnsOkHandler()

View File

@ -1,15 +1,17 @@
using Moq;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.Logging;
using Ocelot.Requester.QoS;
using Shouldly;
using System.Collections.Generic;
using TestStack.BDDfy;
using Xunit;
/*
namespace Ocelot.UnitTests.Requester
{
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.Logging;
using Ocelot.Requester.QoS;
using Shouldly;
using System.Collections.Generic;
using TestStack.BDDfy;
using Xunit;
public class QoSProviderFactoryTests
{
private readonly IQoSProviderFactory _factory;
@ -22,10 +24,9 @@ namespace Ocelot.UnitTests.Requester
{
_logger = new Mock<IOcelotLogger>();
_loggerFactory = new Mock<IOcelotLoggerFactory>();
_loggerFactory
.Setup(x => x.CreateLogger<PollyQoSProvider>())
.Returns(_logger.Object);
_factory = new QoSProviderFactory(_loggerFactory.Object);
var services = new ServiceCollection();
var provider = services.BuildServiceProvider();
_factory = new QoSProviderFactory(_loggerFactory.Object, provider);
}
[Fact]
@ -46,7 +47,7 @@ namespace Ocelot.UnitTests.Requester
}
[Fact]
public void should_return_polly_qos_provider()
public void should_return_delegate_provider()
{
var qosOptions = new QoSOptionsBuilder()
.WithTimeoutValue(100)
@ -55,13 +56,13 @@ namespace Ocelot.UnitTests.Requester
.Build();
var reRoute = new DownstreamReRouteBuilder()
.WithUpstreamHttpMethod(new List<string> { "get" })
.WithQosOptions(qosOptions)
.Build();
.WithUpstreamHttpMethod(new List<string> { "get" })
.WithQosOptions(qosOptions)
.Build();
this.Given(x => x.GivenAReRoute(reRoute))
.When(x => x.WhenIGetTheQoSProvider())
.Then(x => x.ThenTheQoSProviderIsReturned<PollyQoSProvider>())
.Then(x => x.ThenTheQoSProviderIsReturned<FakeProvider>())
.BDDfy();
}
@ -80,4 +81,13 @@ namespace Ocelot.UnitTests.Requester
_result.ShouldBeOfType<T>();
}
}
internal class FakeProvider : IQoSProvider
{
public T CircuitBreaker<T>()
{
throw new System.NotImplementedException();
}
}
}
*/

View File

@ -1,4 +1,5 @@
using Moq;
/*
using Moq;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.Requester.QoS;
@ -25,13 +26,13 @@ namespace Ocelot.UnitTests.Requester
[Fact]
public void should_store_qos_provider_on_first_request()
{
var qosOptions = new QoSOptionsBuilder()
.WithKey("test")
.Build();
{
var qosOptions = new QoSOptionsBuilder()
.WithKey("test")
.Build();
var reRoute = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
var reRoute = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
.Build();
this.Given(x => x.GivenThereIsAQoSProvider(reRoute, new FakeQoSProvider()))
@ -47,7 +48,7 @@ namespace Ocelot.UnitTests.Requester
.Build();
var reRoute = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
.WithQosOptions(qosOptions)
.Build();
this.Given(x => x.GivenThereIsAQoSProvider(reRoute, new FakeQoSProvider()))
@ -68,8 +69,8 @@ namespace Ocelot.UnitTests.Requester
.Build();
var reRoute = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
.Build();
.WithQosOptions(qosOptions)
.Build();
var reRouteTwo = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptionsTwo)
@ -88,10 +89,10 @@ namespace Ocelot.UnitTests.Requester
public void should_return_error_if_no_qos_provider_with_key()
{
var qosOptions = new QoSOptionsBuilder()
.Build();
.Build();
var reRoute = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
var reRoute = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
.Build();
this.When(x => x.WhenWeGetTheQoSProvider(reRoute))
@ -109,16 +110,16 @@ namespace Ocelot.UnitTests.Requester
.WithExceptionsAllowedBeforeBreaking(1)
.Build();
var dontUseQoSOptions = new QoSOptionsBuilder()
var dontUseQoSOptions = new QoSOptionsBuilder()
.WithKey("test")
.Build();
.Build();
var reRoute = new DownstreamReRouteBuilder()
.WithQosOptions(dontUseQoSOptions)
.Build();
var reRouteTwo = new DownstreamReRouteBuilder()
.WithQosOptions(useQoSOptions)
var reRouteTwo = new DownstreamReRouteBuilder()
.WithQosOptions(useQoSOptions)
.Build();
this.Given(x => x.GivenThereIsAQoSProvider(reRoute, new FakeQoSProvider()))
@ -176,12 +177,19 @@ namespace Ocelot.UnitTests.Requester
class FakeQoSProvider : IQoSProvider
{
public CircuitBreaker CircuitBreaker { get; }
T IQoSProvider.CircuitBreaker<T>()
{
throw new System.NotImplementedException();
}
}
class FakePollyQoSProvider : IQoSProvider
{
public CircuitBreaker CircuitBreaker { get; }
T IQoSProvider.CircuitBreaker<T>()
{
throw new System.NotImplementedException();
}
}
}
}
*/