diff --git a/src/Ocelot/LoadBalancer/LoadBalancers/LoadBalancerFactory.cs b/src/Ocelot/LoadBalancer/LoadBalancers/LoadBalancerFactory.cs index 58f6ff4e..c9a9cbe8 100644 --- a/src/Ocelot/LoadBalancer/LoadBalancers/LoadBalancerFactory.cs +++ b/src/Ocelot/LoadBalancer/LoadBalancers/LoadBalancerFactory.cs @@ -29,7 +29,7 @@ namespace Ocelot.LoadBalancer.LoadBalancers var bus = new InMemoryBus(); return new CookieStickySessions(loadBalancer, reRoute.LoadBalancerOptions.Key, reRoute.LoadBalancerOptions.ExpiryInMs, bus); default: - return new NoLoadBalancer(await serviceProvider.Get()); + return new NoLoadBalancer(async () => await serviceProvider.Get()); } } } diff --git a/src/Ocelot/LoadBalancer/LoadBalancers/NoLoadBalancer.cs b/src/Ocelot/LoadBalancer/LoadBalancers/NoLoadBalancer.cs index 5cb28023..3f69aded 100644 --- a/src/Ocelot/LoadBalancer/LoadBalancers/NoLoadBalancer.cs +++ b/src/Ocelot/LoadBalancer/LoadBalancers/NoLoadBalancer.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Ocelot.Middleware; @@ -9,22 +10,23 @@ namespace Ocelot.LoadBalancer.LoadBalancers { public class NoLoadBalancer : ILoadBalancer { - private readonly List _services; + private readonly Func>> _services; - public NoLoadBalancer(List services) + public NoLoadBalancer(Func>> services) { _services = services; } public async Task> Lease(DownstreamContext downstreamContext) { + var services = await _services(); //todo first or default could be null.. - if (_services == null || _services.Count == 0) + if (services == null || services.Count == 0) { return new ErrorResponse(new ServicesAreEmptyError("There were no services in NoLoadBalancer")); } - var service = await Task.FromResult(_services.FirstOrDefault()); + var service = await Task.FromResult(services.FirstOrDefault()); return new OkResponse(service.HostAndPort); } diff --git a/src/Ocelot/LoadBalancer/LoadBalancers/RoundRobin.cs b/src/Ocelot/LoadBalancer/LoadBalancers/RoundRobin.cs index 15fcf6eb..c9a63b24 100644 --- a/src/Ocelot/LoadBalancer/LoadBalancers/RoundRobin.cs +++ b/src/Ocelot/LoadBalancer/LoadBalancers/RoundRobin.cs @@ -20,13 +20,13 @@ namespace Ocelot.LoadBalancer.LoadBalancers public async Task> Lease(DownstreamContext downstreamContext) { - var services = await _services.Invoke(); + var services = await _services(); if (_last >= services.Count) { _last = 0; } - var next = await Task.FromResult(services[_last]); + var next = services[_last]; _last++; return new OkResponse(next.HostAndPort); } diff --git a/test/Ocelot.UnitTests/LoadBalancer/NoLoadBalancerTests.cs b/test/Ocelot.UnitTests/LoadBalancer/NoLoadBalancerTests.cs index 7b531d1e..6cb3a197 100644 --- a/test/Ocelot.UnitTests/LoadBalancer/NoLoadBalancerTests.cs +++ b/test/Ocelot.UnitTests/LoadBalancer/NoLoadBalancerTests.cs @@ -1,4 +1,6 @@ +using System; using System.Collections.Generic; +using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Ocelot.LoadBalancer.LoadBalancers; using Ocelot.Middleware; @@ -16,6 +18,12 @@ namespace Ocelot.UnitTests.LoadBalancer private NoLoadBalancer _loadBalancer; private Response _result; + public NoLoadBalancerTests() + { + _services = new List(); + _loadBalancer = new NoLoadBalancer(() => Task.FromResult(_services)); + } + [Fact] public void should_return_host_and_port() { @@ -25,6 +33,7 @@ namespace Ocelot.UnitTests.LoadBalancer { new Service("product", hostAndPort, string.Empty, string.Empty, new string[0]) }; + this.Given(x => x.GivenServices(services)) .When(x => x.WhenIGetTheNextHostAndPort()) .Then(x => x.ThenTheHostAndPortIs(hostAndPort)) @@ -34,25 +43,43 @@ namespace Ocelot.UnitTests.LoadBalancer [Fact] public void should_return_error_if_no_services() { - var services = new List(); - - this.Given(x => x.GivenServices(services)) - .When(x => x.WhenIGetTheNextHostAndPort()) + this.When(x => x.WhenIGetTheNextHostAndPort()) .Then(x => x.ThenThereIsAnError()) .BDDfy(); } + [Fact] + public void should_return_error_if_no_services_then_when_services_available_return_host_and_port() + { + var hostAndPort = new ServiceHostAndPort("127.0.0.1", 80); + + var services = new List + { + new Service("product", hostAndPort, string.Empty, string.Empty, new string[0]) + }; + + this.Given(_ => WhenIGetTheNextHostAndPort()) + .And(_ => ThenThereIsAnError()) + .And(_ => GivenServices(services)) + .When(_ => WhenIGetTheNextHostAndPort()) + .Then(_ => ThenTheHostAndPortIs(hostAndPort)) + .BDDfy(); + } + [Fact] public void should_return_error_if_null_services() { - List services = null; - - this.Given(x => x.GivenServices(services)) + this.Given(x => x.GivenServicesAreNull()) .When(x => x.WhenIGetTheNextHostAndPort()) .Then(x => x.ThenThereIsAnError()) .BDDfy(); } + private void GivenServicesAreNull() + { + _loadBalancer = new NoLoadBalancer(() => Task.FromResult((List)null)); + } + private void ThenThereIsAnError() { _result.IsError.ShouldBeTrue(); @@ -60,12 +87,11 @@ namespace Ocelot.UnitTests.LoadBalancer private void GivenServices(List services) { - _services = services; + _services.AddRange(services); } private void WhenIGetTheNextHostAndPort() { - _loadBalancer = new NoLoadBalancer(_services); _result = _loadBalancer.Lease(new DownstreamContext(new DefaultHttpContext())).Result; }