mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-06-17 22:23:21 +08:00
Feature/inject error mapper (#562)
* 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 * #529 can now inject http client expcetions to ocelot errors mappers and updated docs
This commit is contained in:
parent
98ba0271be
commit
6d8b18c01d
@ -5,7 +5,22 @@ Ocelot supports one QoS capability at the current time. You can set on a per ReR
|
|||||||
want to use a circuit breaker when making requests to a downstream service. This uses the an awesome
|
want to use a circuit breaker when making requests to a downstream service. This uses the an awesome
|
||||||
.NET library called Polly check them out `here <https://github.com/App-vNext/Polly>`_.
|
.NET library called Polly check them out `here <https://github.com/App-vNext/Polly>`_.
|
||||||
|
|
||||||
Add the following section to a ReRoute configuration.
|
The first thing you need to do if you want to use the administration API is bring in the relavent NuGet package..
|
||||||
|
|
||||||
|
``Install-Package Ocelot.Provider.Polly``
|
||||||
|
|
||||||
|
Then in your ConfigureServices method
|
||||||
|
|
||||||
|
.. code-block:: csharp
|
||||||
|
|
||||||
|
public virtual void ConfigureServices(IServiceCollection services)
|
||||||
|
{
|
||||||
|
services
|
||||||
|
.AddOcelot()
|
||||||
|
.AddPolly();
|
||||||
|
}
|
||||||
|
|
||||||
|
Then add the following section to a ReRoute configuration.
|
||||||
|
|
||||||
.. code-block:: json
|
.. code-block:: json
|
||||||
|
|
||||||
|
@ -7,8 +7,6 @@
|
|||||||
int durationofBreak,
|
int durationofBreak,
|
||||||
int timeoutValue,
|
int timeoutValue,
|
||||||
string key,
|
string key,
|
||||||
//todo - this is never set in Ocelot so always Pessimistic...I guess it doesn't
|
|
||||||
//matter to much.
|
|
||||||
string timeoutStrategy = "Pessimistic")
|
string timeoutStrategy = "Pessimistic")
|
||||||
{
|
{
|
||||||
ExceptionsAllowedBeforeBreaking = exceptionsAllowedBeforeBreaking;
|
ExceptionsAllowedBeforeBreaking = exceptionsAllowedBeforeBreaking;
|
||||||
|
@ -130,6 +130,7 @@ namespace Ocelot.DependencyInjection
|
|||||||
Services.TryAddSingleton<IDownstreamRequestCreator, DownstreamRequestCreator>();
|
Services.TryAddSingleton<IDownstreamRequestCreator, DownstreamRequestCreator>();
|
||||||
Services.TryAddSingleton<IFrameworkDescription, FrameworkDescription>();
|
Services.TryAddSingleton<IFrameworkDescription, FrameworkDescription>();
|
||||||
Services.TryAddSingleton<IQoSFactory, QoSFactory>();
|
Services.TryAddSingleton<IQoSFactory, QoSFactory>();
|
||||||
|
Services.TryAddSingleton<IExceptionToErrorMapper, HttpExeptionToErrorMapper>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IOcelotBuilder AddSingletonDefinedAggregator<T>()
|
public IOcelotBuilder AddSingletonDefinedAggregator<T>()
|
||||||
|
@ -12,14 +12,17 @@ namespace Ocelot.Requester
|
|||||||
private readonly IHttpClientCache _cacheHandlers;
|
private readonly IHttpClientCache _cacheHandlers;
|
||||||
private readonly IOcelotLogger _logger;
|
private readonly IOcelotLogger _logger;
|
||||||
private readonly IDelegatingHandlerHandlerFactory _factory;
|
private readonly IDelegatingHandlerHandlerFactory _factory;
|
||||||
|
private readonly IExceptionToErrorMapper _mapper;
|
||||||
|
|
||||||
public HttpClientHttpRequester(IOcelotLoggerFactory loggerFactory,
|
public HttpClientHttpRequester(IOcelotLoggerFactory loggerFactory,
|
||||||
IHttpClientCache cacheHandlers,
|
IHttpClientCache cacheHandlers,
|
||||||
IDelegatingHandlerHandlerFactory house)
|
IDelegatingHandlerHandlerFactory factory,
|
||||||
|
IExceptionToErrorMapper mapper)
|
||||||
{
|
{
|
||||||
_logger = loggerFactory.CreateLogger<HttpClientHttpRequester>();
|
_logger = loggerFactory.CreateLogger<HttpClientHttpRequester>();
|
||||||
_cacheHandlers = cacheHandlers;
|
_cacheHandlers = cacheHandlers;
|
||||||
_factory = house;
|
_factory = factory;
|
||||||
|
_mapper = mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Response<HttpResponseMessage>> GetResponse(DownstreamContext context)
|
public async Task<Response<HttpResponseMessage>> GetResponse(DownstreamContext context)
|
||||||
@ -35,7 +38,8 @@ namespace Ocelot.Requester
|
|||||||
}
|
}
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
return new ErrorResponse<HttpResponseMessage>(new UnableToCompleteRequestError(exception));
|
var error = _mapper.Map(exception);
|
||||||
|
return new ErrorResponse<HttpResponseMessage>(error);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
29
src/Ocelot/Requester/HttpExeptionToErrorMapper.cs
Normal file
29
src/Ocelot/Requester/HttpExeptionToErrorMapper.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
namespace Ocelot.Requester
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Errors;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
public class HttpExeptionToErrorMapper : IExceptionToErrorMapper
|
||||||
|
{
|
||||||
|
private readonly Dictionary<Type, Func<Exception, Error>> _mappers;
|
||||||
|
|
||||||
|
public HttpExeptionToErrorMapper(IServiceProvider serviceProvider)
|
||||||
|
{
|
||||||
|
_mappers = serviceProvider.GetService<Dictionary<Type, Func<Exception, Error>>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Error Map(Exception exception)
|
||||||
|
{
|
||||||
|
var type = exception.GetType();
|
||||||
|
|
||||||
|
if (_mappers != null && _mappers.ContainsKey(type))
|
||||||
|
{
|
||||||
|
return _mappers[type](exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new UnableToCompleteRequestError(exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
10
src/Ocelot/Requester/IExceptionToErrorMapper.cs
Normal file
10
src/Ocelot/Requester/IExceptionToErrorMapper.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
using System;
|
||||||
|
using Ocelot.Errors;
|
||||||
|
|
||||||
|
namespace Ocelot.Requester
|
||||||
|
{
|
||||||
|
public interface IExceptionToErrorMapper
|
||||||
|
{
|
||||||
|
Error Map(Exception exception);
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +0,0 @@
|
|||||||
using System.Net.Http;
|
|
||||||
|
|
||||||
namespace Ocelot.Requester
|
|
||||||
{
|
|
||||||
public class ReRouteDelegatingHandler<T>
|
|
||||||
where T : DelegatingHandler
|
|
||||||
{
|
|
||||||
public T DelegatingHandler { get; private set; }
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
using Ocelot.Errors;
|
|
||||||
|
|
||||||
namespace Ocelot.Requester
|
|
||||||
{
|
|
||||||
public class UnableToFindDelegatingHandlerProviderError : Error
|
|
||||||
{
|
|
||||||
public UnableToFindDelegatingHandlerProviderError(string message)
|
|
||||||
: base(message, OcelotErrorCode.UnableToFindDelegatingHandlerProviderError)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -27,6 +27,7 @@ namespace Ocelot.UnitTests.Requester
|
|||||||
private DownstreamContext _request;
|
private DownstreamContext _request;
|
||||||
private Mock<IOcelotLoggerFactory> _loggerFactory;
|
private Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||||
private Mock<IOcelotLogger> _logger;
|
private Mock<IOcelotLogger> _logger;
|
||||||
|
private Mock<IExceptionToErrorMapper> _mapper;
|
||||||
|
|
||||||
public HttpClientHttpRequesterTest()
|
public HttpClientHttpRequesterTest()
|
||||||
{
|
{
|
||||||
@ -38,10 +39,12 @@ namespace Ocelot.UnitTests.Requester
|
|||||||
.Setup(x => x.CreateLogger<HttpClientHttpRequester>())
|
.Setup(x => x.CreateLogger<HttpClientHttpRequester>())
|
||||||
.Returns(_logger.Object);
|
.Returns(_logger.Object);
|
||||||
_cacheHandlers = new Mock<IHttpClientCache>();
|
_cacheHandlers = new Mock<IHttpClientCache>();
|
||||||
|
_mapper = new Mock<IExceptionToErrorMapper>();
|
||||||
_httpClientRequester = new HttpClientHttpRequester(
|
_httpClientRequester = new HttpClientHttpRequester(
|
||||||
_loggerFactory.Object,
|
_loggerFactory.Object,
|
||||||
_cacheHandlers.Object,
|
_cacheHandlers.Object,
|
||||||
_factory.Object);
|
_factory.Object,
|
||||||
|
_mapper.Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -144,6 +147,7 @@ namespace Ocelot.UnitTests.Requester
|
|||||||
|
|
||||||
private void ThenTheErrorIsTimeout()
|
private void ThenTheErrorIsTimeout()
|
||||||
{
|
{
|
||||||
|
_mapper.Verify(x => x.Map(It.IsAny<Exception>()), Times.Once);
|
||||||
_response.Errors[0].ShouldBeOfType<UnableToCompleteRequestError>();
|
_response.Errors[0].ShouldBeOfType<UnableToCompleteRequestError>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,6 +169,8 @@ namespace Ocelot.UnitTests.Requester
|
|||||||
};
|
};
|
||||||
|
|
||||||
_factory.Setup(x => x.Get(It.IsAny<DownstreamReRoute>())).Returns(new OkResponse<List<Func<DelegatingHandler>>>(handlers));
|
_factory.Setup(x => x.Get(It.IsAny<DownstreamReRoute>())).Returns(new OkResponse<List<Func<DelegatingHandler>>>(handlers));
|
||||||
|
|
||||||
|
_mapper.Setup(x => x.Map(It.IsAny<Exception>())).Returns(new UnableToCompleteRequestError(new Exception()));
|
||||||
}
|
}
|
||||||
|
|
||||||
class OkDelegatingHandler : DelegatingHandler
|
class OkDelegatingHandler : DelegatingHandler
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
namespace Ocelot.UnitTests.Requester
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Ocelot.Errors;
|
||||||
|
using Ocelot.Requester;
|
||||||
|
using Responder;
|
||||||
|
using Shouldly;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
public class HttpExeptionToErrorMapperTests
|
||||||
|
{
|
||||||
|
private HttpExeptionToErrorMapper _mapper;
|
||||||
|
private readonly ServiceCollection _services;
|
||||||
|
|
||||||
|
public HttpExeptionToErrorMapperTests()
|
||||||
|
{
|
||||||
|
_services = new ServiceCollection();
|
||||||
|
var provider = _services.BuildServiceProvider();
|
||||||
|
_mapper = new HttpExeptionToErrorMapper(provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_return_default_error_because_mappers_are_null()
|
||||||
|
{
|
||||||
|
var error = _mapper.Map(new Exception());
|
||||||
|
|
||||||
|
error.ShouldBeOfType<UnableToCompleteRequestError>();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_return_error_from_mapper()
|
||||||
|
{
|
||||||
|
var errorMapping = new Dictionary<Type, Func<Exception, Error>>
|
||||||
|
{
|
||||||
|
{typeof(TaskCanceledException), e => new AnyError()},
|
||||||
|
};
|
||||||
|
|
||||||
|
_services.AddSingleton(errorMapping);
|
||||||
|
|
||||||
|
var provider = _services.BuildServiceProvider();
|
||||||
|
|
||||||
|
_mapper = new HttpExeptionToErrorMapper(provider);
|
||||||
|
|
||||||
|
var error = _mapper.Map(new TaskCanceledException());
|
||||||
|
|
||||||
|
error.ShouldBeOfType<AnyError>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
55
test/Ocelot.UnitTests/Requester/QoSFactoryTests.cs
Normal file
55
test/Ocelot.UnitTests/Requester/QoSFactoryTests.cs
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
namespace Ocelot.UnitTests.Requester
|
||||||
|
{
|
||||||
|
using System.Net.Http;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Moq;
|
||||||
|
using Ocelot.Configuration;
|
||||||
|
using Ocelot.Configuration.Builder;
|
||||||
|
using Ocelot.Logging;
|
||||||
|
using Ocelot.Requester;
|
||||||
|
using Ocelot.Requester.QoS;
|
||||||
|
using Shouldly;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
public class QoSFactoryTests
|
||||||
|
{
|
||||||
|
private QoSFactory _factory;
|
||||||
|
private ServiceCollection _services;
|
||||||
|
private readonly Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||||
|
|
||||||
|
public QoSFactoryTests()
|
||||||
|
{
|
||||||
|
_services = new ServiceCollection();
|
||||||
|
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||||
|
var provider = _services.BuildServiceProvider();
|
||||||
|
_factory = new QoSFactory(provider, _loggerFactory.Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_return_error()
|
||||||
|
{
|
||||||
|
var downstreamReRoute = new DownstreamReRouteBuilder().Build();
|
||||||
|
var handler = _factory.Get(downstreamReRoute);
|
||||||
|
handler.IsError.ShouldBeTrue();
|
||||||
|
handler.Errors[0].ShouldBeOfType<UnableToFindQoSProviderError>();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_return_handler()
|
||||||
|
{
|
||||||
|
_services = new ServiceCollection();
|
||||||
|
DelegatingHandler QosDelegatingHandlerDelegate(DownstreamReRoute a, IOcelotLoggerFactory b) => new FakeDelegatingHandler();
|
||||||
|
_services.AddSingleton<QosDelegatingHandlerDelegate>(QosDelegatingHandlerDelegate);
|
||||||
|
var provider = _services.BuildServiceProvider();
|
||||||
|
_factory = new QoSFactory(provider, _loggerFactory.Object);
|
||||||
|
var downstreamReRoute = new DownstreamReRouteBuilder().Build();
|
||||||
|
var handler = _factory.Get(downstreamReRoute);
|
||||||
|
handler.IsError.ShouldBeFalse();
|
||||||
|
handler.Data.ShouldBeOfType<FakeDelegatingHandler>();
|
||||||
|
}
|
||||||
|
|
||||||
|
class FakeDelegatingHandler : DelegatingHandler
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,93 +0,0 @@
|
|||||||
/*
|
|
||||||
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;
|
|
||||||
private DownstreamReRoute _reRoute;
|
|
||||||
private IQoSProvider _result;
|
|
||||||
private Mock<IOcelotLoggerFactory> _loggerFactory;
|
|
||||||
private Mock<IOcelotLogger> _logger;
|
|
||||||
|
|
||||||
public QoSProviderFactoryTests()
|
|
||||||
{
|
|
||||||
_logger = new Mock<IOcelotLogger>();
|
|
||||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
|
||||||
var services = new ServiceCollection();
|
|
||||||
var provider = services.BuildServiceProvider();
|
|
||||||
_factory = new QoSProviderFactory(_loggerFactory.Object, provider);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void should_return_no_qos_provider()
|
|
||||||
{
|
|
||||||
var qosOptions = new QoSOptionsBuilder()
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var reRoute = new DownstreamReRouteBuilder()
|
|
||||||
.WithQosOptions(qosOptions)
|
|
||||||
.WithUpstreamHttpMethod(new List<string> { "get" })
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
this.Given(x => x.GivenAReRoute(reRoute))
|
|
||||||
.When(x => x.WhenIGetTheQoSProvider())
|
|
||||||
.Then(x => x.ThenTheQoSProviderIsReturned<NoQoSProvider>())
|
|
||||||
.BDDfy();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void should_return_delegate_provider()
|
|
||||||
{
|
|
||||||
var qosOptions = new QoSOptionsBuilder()
|
|
||||||
.WithTimeoutValue(100)
|
|
||||||
.WithDurationOfBreak(100)
|
|
||||||
.WithExceptionsAllowedBeforeBreaking(100)
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var reRoute = new DownstreamReRouteBuilder()
|
|
||||||
.WithUpstreamHttpMethod(new List<string> { "get" })
|
|
||||||
.WithQosOptions(qosOptions)
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
this.Given(x => x.GivenAReRoute(reRoute))
|
|
||||||
.When(x => x.WhenIGetTheQoSProvider())
|
|
||||||
.Then(x => x.ThenTheQoSProviderIsReturned<FakeProvider>())
|
|
||||||
.BDDfy();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GivenAReRoute(DownstreamReRoute reRoute)
|
|
||||||
{
|
|
||||||
_reRoute = reRoute;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WhenIGetTheQoSProvider()
|
|
||||||
{
|
|
||||||
_result = _factory.Get(_reRoute);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ThenTheQoSProviderIsReturned<T>()
|
|
||||||
{
|
|
||||||
_result.ShouldBeOfType<T>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class FakeProvider : IQoSProvider
|
|
||||||
{
|
|
||||||
public T CircuitBreaker<T>()
|
|
||||||
{
|
|
||||||
throw new System.NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
@ -1,195 +0,0 @@
|
|||||||
/*
|
|
||||||
using Moq;
|
|
||||||
using Ocelot.Configuration;
|
|
||||||
using Ocelot.Configuration.Builder;
|
|
||||||
using Ocelot.Requester.QoS;
|
|
||||||
using Ocelot.Responses;
|
|
||||||
using Shouldly;
|
|
||||||
using TestStack.BDDfy;
|
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
namespace Ocelot.UnitTests.Requester
|
|
||||||
{
|
|
||||||
public class QosProviderHouseTests
|
|
||||||
{
|
|
||||||
private IQoSProvider _qoSProvider;
|
|
||||||
private readonly QosProviderHouse _qosProviderHouse;
|
|
||||||
private Response<IQoSProvider> _getResult;
|
|
||||||
private DownstreamReRoute _reRoute;
|
|
||||||
private readonly Mock<IQoSProviderFactory> _factory;
|
|
||||||
|
|
||||||
public QosProviderHouseTests()
|
|
||||||
{
|
|
||||||
_factory = new Mock<IQoSProviderFactory>();
|
|
||||||
_qosProviderHouse = new QosProviderHouse(_factory.Object);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void should_store_qos_provider_on_first_request()
|
|
||||||
{
|
|
||||||
var qosOptions = new QoSOptionsBuilder()
|
|
||||||
.WithKey("test")
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var reRoute = new DownstreamReRouteBuilder()
|
|
||||||
.WithQosOptions(qosOptions)
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAQoSProvider(reRoute, new FakeQoSProvider()))
|
|
||||||
.Then(x => x.ThenItIsAdded())
|
|
||||||
.BDDfy();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void should_not_store_qos_provider_on_first_request()
|
|
||||||
{
|
|
||||||
var qosOptions = new QoSOptionsBuilder()
|
|
||||||
.WithKey("test")
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var reRoute = new DownstreamReRouteBuilder()
|
|
||||||
.WithQosOptions(qosOptions)
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAQoSProvider(reRoute, new FakeQoSProvider()))
|
|
||||||
.When(x => x.WhenWeGetTheQoSProvider(reRoute))
|
|
||||||
.Then(x => x.ThenItIsReturned())
|
|
||||||
.BDDfy();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void should_store_qos_providers_by_key()
|
|
||||||
{
|
|
||||||
var qosOptions = new QoSOptionsBuilder()
|
|
||||||
.WithKey("test")
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var qosOptionsTwo = new QoSOptionsBuilder()
|
|
||||||
.WithKey("testTwo")
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var reRoute = new DownstreamReRouteBuilder()
|
|
||||||
.WithQosOptions(qosOptions)
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var reRouteTwo = new DownstreamReRouteBuilder()
|
|
||||||
.WithQosOptions(qosOptionsTwo)
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAQoSProvider(reRoute, new FakeQoSProvider()))
|
|
||||||
.And(x => x.GivenThereIsAQoSProvider(reRouteTwo, new FakePollyQoSProvider()))
|
|
||||||
.When(x => x.WhenWeGetTheQoSProvider(reRoute))
|
|
||||||
.Then(x => x.ThenTheQoSProviderIs<FakeQoSProvider>())
|
|
||||||
.When(x => x.WhenWeGetTheQoSProvider(reRouteTwo))
|
|
||||||
.Then(x => x.ThenTheQoSProviderIs<FakePollyQoSProvider>())
|
|
||||||
.BDDfy();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void should_return_error_if_no_qos_provider_with_key()
|
|
||||||
{
|
|
||||||
var qosOptions = new QoSOptionsBuilder()
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var reRoute = new DownstreamReRouteBuilder()
|
|
||||||
.WithQosOptions(qosOptions)
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
this.When(x => x.WhenWeGetTheQoSProvider(reRoute))
|
|
||||||
.Then(x => x.ThenAnErrorIsReturned())
|
|
||||||
.BDDfy();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void should_get_new_qos_provider_if_reroute_qos_provider_has_changed()
|
|
||||||
{
|
|
||||||
var useQoSOptions = new QoSOptionsBuilder()
|
|
||||||
.WithTimeoutValue(1)
|
|
||||||
.WithKey("test")
|
|
||||||
.WithDurationOfBreak(1)
|
|
||||||
.WithExceptionsAllowedBeforeBreaking(1)
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var dontUseQoSOptions = new QoSOptionsBuilder()
|
|
||||||
.WithKey("test")
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var reRoute = new DownstreamReRouteBuilder()
|
|
||||||
.WithQosOptions(dontUseQoSOptions)
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
var reRouteTwo = new DownstreamReRouteBuilder()
|
|
||||||
.WithQosOptions(useQoSOptions)
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAQoSProvider(reRoute, new FakeQoSProvider()))
|
|
||||||
.When(x => x.WhenWeGetTheQoSProvider(reRoute))
|
|
||||||
.Then(x => x.ThenTheQoSProviderIs<FakeQoSProvider>())
|
|
||||||
.When(x => x.WhenIGetTheReRouteWithTheSameKeyButDifferentQosProvider(reRouteTwo))
|
|
||||||
.Then(x => x.ThenTheQoSProviderIs<FakePollyQoSProvider>())
|
|
||||||
.BDDfy();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WhenIGetTheReRouteWithTheSameKeyButDifferentQosProvider(DownstreamReRoute reRoute)
|
|
||||||
{
|
|
||||||
_reRoute = reRoute;
|
|
||||||
_factory.Setup(x => x.Get(_reRoute)).Returns(new FakePollyQoSProvider());
|
|
||||||
_getResult = _qosProviderHouse.Get(_reRoute);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ThenAnErrorIsReturned()
|
|
||||||
{
|
|
||||||
_getResult.IsError.ShouldBeTrue();
|
|
||||||
_getResult.Errors[0].ShouldBeOfType<UnableToFindQoSProviderError>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ThenTheQoSProviderIs<T>()
|
|
||||||
{
|
|
||||||
_getResult.Data.ShouldBeOfType<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ThenItIsAdded()
|
|
||||||
{
|
|
||||||
_getResult.IsError.ShouldBe(false);
|
|
||||||
_getResult.ShouldBeOfType<OkResponse<IQoSProvider>>();
|
|
||||||
_factory.Verify(x => x.Get(_reRoute), Times.Once);
|
|
||||||
_getResult.Data.ShouldBe(_qoSProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GivenThereIsAQoSProvider(DownstreamReRoute reRoute, IQoSProvider qoSProvider)
|
|
||||||
{
|
|
||||||
_reRoute = reRoute;
|
|
||||||
_qoSProvider = qoSProvider;
|
|
||||||
_factory.Setup(x => x.Get(_reRoute)).Returns(_qoSProvider);
|
|
||||||
_getResult = _qosProviderHouse.Get(reRoute);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WhenWeGetTheQoSProvider(DownstreamReRoute reRoute)
|
|
||||||
{
|
|
||||||
_getResult = _qosProviderHouse.Get(reRoute);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ThenItIsReturned()
|
|
||||||
{
|
|
||||||
_getResult.Data.ShouldBe(_qoSProvider);
|
|
||||||
_factory.Verify(x => x.Get(_reRoute), Times.Once);
|
|
||||||
}
|
|
||||||
|
|
||||||
class FakeQoSProvider : IQoSProvider
|
|
||||||
{
|
|
||||||
T IQoSProvider.CircuitBreaker<T>()
|
|
||||||
{
|
|
||||||
throw new System.NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class FakePollyQoSProvider : IQoSProvider
|
|
||||||
{
|
|
||||||
T IQoSProvider.CircuitBreaker<T>()
|
|
||||||
{
|
|
||||||
throw new System.NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
Loading…
x
Reference in New Issue
Block a user