diff --git a/src/Ocelot/LoadBalancer/Middleware/LoadBalancingMiddleware.cs b/src/Ocelot/LoadBalancer/Middleware/LoadBalancingMiddleware.cs index d2e9ee8a..7d09ea3a 100644 --- a/src/Ocelot/LoadBalancer/Middleware/LoadBalancingMiddleware.cs +++ b/src/Ocelot/LoadBalancer/Middleware/LoadBalancingMiddleware.cs @@ -31,16 +31,18 @@ namespace Ocelot.LoadBalancer.Middleware { _logger.LogDebug("started calling load balancing middleware"); - var loadBalancer = _loadBalancerHouse.Get(DownstreamRoute.ReRoute.LoadBalancerKey); - if(loadBalancer.IsError) + var getLoadBalancer = _loadBalancerHouse.Get(DownstreamRoute.ReRoute.LoadBalancerKey); + if(getLoadBalancer.IsError) { - //set errors and return + SetPipelineError(getLoadBalancer.Errors); + return; } - var hostAndPort = await loadBalancer.Data.Lease(); + var hostAndPort = await getLoadBalancer.Data.Lease(); if(hostAndPort.IsError) - { - //set errors and return + { + SetPipelineError(hostAndPort.Errors); + return; } SetHostAndPortForThisRequest(hostAndPort.Data); @@ -51,11 +53,11 @@ namespace Ocelot.LoadBalancer.Middleware { await _next.Invoke(context); - loadBalancer.Data.Release(hostAndPort.Data); + getLoadBalancer.Data.Release(hostAndPort.Data); } catch (Exception) { - loadBalancer.Data.Release(hostAndPort.Data); + getLoadBalancer.Data.Release(hostAndPort.Data); _logger.LogDebug("error calling next middleware, exception will be thrown to global handler"); throw; } diff --git a/test/Ocelot.UnitTests/LoadBalancer/LoadBalancerMiddlewareTests.cs b/test/Ocelot.UnitTests/LoadBalancer/LoadBalancerMiddlewareTests.cs index ab6a59a8..5d750f83 100644 --- a/test/Ocelot.UnitTests/LoadBalancer/LoadBalancerMiddlewareTests.cs +++ b/test/Ocelot.UnitTests/LoadBalancer/LoadBalancerMiddlewareTests.cs @@ -7,6 +7,7 @@ using Microsoft.Extensions.DependencyInjection; using Moq; using Ocelot.Configuration.Builder; using Ocelot.DownstreamRouteFinder; +using Ocelot.Errors; using Ocelot.Infrastructure.RequestData; using Ocelot.LoadBalancer.LoadBalancers; using Ocelot.LoadBalancer.Middleware; @@ -31,6 +32,8 @@ namespace Ocelot.UnitTests.LoadBalancer private OkResponse _request; private OkResponse _downstreamUrl; private OkResponse _downstreamRoute; + private ErrorResponse _getLoadBalancerHouseError; + private ErrorResponse _getHostAndPortError; public LoadBalancerMiddlewareTests() { @@ -77,6 +80,45 @@ namespace Ocelot.UnitTests.LoadBalancer .BDDfy(); } + [Fact] + public void should_set_pipeline_error_if_cannot_get_load_balancer() + { + var downstreamRoute = new DownstreamRoute(new List(), + new ReRouteBuilder() + .Build()); + + this.Given(x => x.GivenTheDownStreamUrlIs("any old string")) + .And(x => x.GivenTheDownStreamRouteIs(downstreamRoute)) + .And(x => x.GivenTheLoadBalancerHouseReturnsAnError()) + .When(x => x.WhenICallTheMiddleware()) + .Then(x => x.ThenAnErrorStatingLoadBalancerCouldNotBeFoundIsSetOnPipeline()) + .BDDfy(); + } + + [Fact] + public void should_set_pipeline_error_if_cannot_get_least() + { + var downstreamRoute = new DownstreamRoute(new List(), + new ReRouteBuilder() + .Build()); + + this.Given(x => x.GivenTheDownStreamUrlIs("any old string")) + .And(x => x.GivenTheDownStreamRouteIs(downstreamRoute)) + .And(x => x.GivenTheLoadBalancerHouseReturns()) + .And(x => x.GivenTheLoadBalancerReturnsAnError()) + .When(x => x.WhenICallTheMiddleware()) + .Then(x => x.ThenAnErrorStatingHostAndPortCouldNotBeFoundIsSetOnPipeline()) + .BDDfy(); + } + + private void GivenTheLoadBalancerReturnsAnError() + { + _getHostAndPortError = new ErrorResponse(new List() { new ServicesAreNullError($"services were null for bah") }); + _loadBalancer + .Setup(x => x.Lease()) + .ReturnsAsync(_getHostAndPortError); + } + private void GivenTheLoadBalancerReturns() { _hostAndPort = new HostAndPort("127.0.0.1", 80); @@ -100,12 +142,43 @@ namespace Ocelot.UnitTests.LoadBalancer .Returns(new OkResponse(_loadBalancer.Object)); } + + private void GivenTheLoadBalancerHouseReturnsAnError() + { + _getLoadBalancerHouseError = new ErrorResponse(new List() + { + new UnableToFindLoadBalancerError($"unabe to find load balancer for bah") + }); + + _loadBalancerHouse + .Setup(x => x.Get(It.IsAny())) + .Returns(_getLoadBalancerHouseError); + } + private void ThenTheScopedDataRepositoryIsCalledCorrectly() { _scopedRepository .Verify(x => x.Add("HostAndPort", _hostAndPort), Times.Once()); } + private void ThenAnErrorStatingLoadBalancerCouldNotBeFoundIsSetOnPipeline() + { + _scopedRepository + .Verify(x => x.Add("OcelotMiddlewareError", true), Times.Once); + + _scopedRepository + .Verify(x => x.Add("OcelotMiddlewareErrors", _getLoadBalancerHouseError.Errors), Times.Once); + } + + private void ThenAnErrorStatingHostAndPortCouldNotBeFoundIsSetOnPipeline() + { + _scopedRepository + .Verify(x => x.Add("OcelotMiddlewareError", true), Times.Once); + + _scopedRepository + .Verify(x => x.Add("OcelotMiddlewareErrors", _getHostAndPortError.Errors), Times.Once); + } + private void WhenICallTheMiddleware() { _result = _client.GetAsync(_url).Result;