diff --git a/src/Ocelot/Errors/OcelotErrorCode.cs b/src/Ocelot/Errors/OcelotErrorCode.cs index 85c3e097..f2c479df 100644 --- a/src/Ocelot/Errors/OcelotErrorCode.cs +++ b/src/Ocelot/Errors/OcelotErrorCode.cs @@ -23,6 +23,8 @@ DownstreamSchemeNullOrEmptyError, DownstreamHostNullOrEmptyError, ServicesAreNullError, - ServicesAreEmptyError + ServicesAreEmptyError, + UnableToFindServiceProviderError, + UnableToFindLoadBalancerError } } diff --git a/src/Ocelot/LoadBalancer/LoadBalancers/LoadBalancerHouse.cs b/src/Ocelot/LoadBalancer/LoadBalancers/LoadBalancerHouse.cs index 2bb8b966..12c040c0 100644 --- a/src/Ocelot/LoadBalancer/LoadBalancers/LoadBalancerHouse.cs +++ b/src/Ocelot/LoadBalancer/LoadBalancers/LoadBalancerHouse.cs @@ -6,7 +6,7 @@ using Ocelot.Responses; namespace Ocelot.LoadBalancer.LoadBalancers { - public class LoadBalancerHouse + public class LoadBalancerHouse : ILoadBalancerHouse { private readonly Dictionary _loadBalancers; @@ -17,7 +17,17 @@ namespace Ocelot.LoadBalancer.LoadBalancers public Response Get(string key) { - return new OkResponse(_loadBalancers[key]); + ILoadBalancer loadBalancer; + + if(_loadBalancers.TryGetValue(key, out loadBalancer)) + { + return new OkResponse(_loadBalancers[key]); + } + + return new ErrorResponse(new List() + { + new UnableToFindLoadBalancerError($"unabe to find load balancer for {key}") + }); } public Response Add(string key, ILoadBalancer loadBalancer) diff --git a/src/Ocelot/LoadBalancer/LoadBalancers/UnableToFindLoadBalancerError.cs b/src/Ocelot/LoadBalancer/LoadBalancers/UnableToFindLoadBalancerError.cs new file mode 100644 index 00000000..3dd3ede4 --- /dev/null +++ b/src/Ocelot/LoadBalancer/LoadBalancers/UnableToFindLoadBalancerError.cs @@ -0,0 +1,12 @@ +using Ocelot.Errors; + +namespace Ocelot.LoadBalancer.LoadBalancers +{ + public class UnableToFindLoadBalancerError : Errors.Error + { + public UnableToFindLoadBalancerError(string message) + : base(message, OcelotErrorCode.UnableToFindLoadBalancerError) + { + } + } +} \ No newline at end of file diff --git a/src/Ocelot/ServiceDiscovery/IServiceProviderHouse.cs b/src/Ocelot/ServiceDiscovery/IServiceProviderHouse.cs new file mode 100644 index 00000000..0f85f528 --- /dev/null +++ b/src/Ocelot/ServiceDiscovery/IServiceProviderHouse.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using Ocelot.Responses; + +namespace Ocelot.ServiceDiscovery +{ + public interface IServiceProviderHouse + { + Response Get(string key); + Response Add(string key, IServiceProvider serviceProvider); + } +} \ No newline at end of file diff --git a/src/Ocelot/ServiceDiscovery/ServiceProviderHouse.cs b/src/Ocelot/ServiceDiscovery/ServiceProviderHouse.cs new file mode 100644 index 00000000..63d14dce --- /dev/null +++ b/src/Ocelot/ServiceDiscovery/ServiceProviderHouse.cs @@ -0,0 +1,34 @@ +using System.Collections.Generic; +using Ocelot.Responses; + +namespace Ocelot.ServiceDiscovery +{ + public class ServiceProviderHouse : IServiceProviderHouse + { + private Dictionary _serviceProviders; + + public ServiceProviderHouse() + { + _serviceProviders = new Dictionary(); + } + + public Response Get(string key) + { + IServiceProvider serviceProvider; + if(_serviceProviders.TryGetValue(key, out serviceProvider)) + { + return new OkResponse(serviceProvider); + } + + return new ErrorResponse(new List() + { + new UnableToFindServiceProviderError($"unabe to find service provider for {key}") + }); + } + public Response Add(string key, IServiceProvider serviceProvider) + { + _serviceProviders[key] = serviceProvider; + return new OkResponse(); + } + } +} \ No newline at end of file diff --git a/src/Ocelot/ServiceDiscovery/UnableToFindServiceProviderError.cs b/src/Ocelot/ServiceDiscovery/UnableToFindServiceProviderError.cs new file mode 100644 index 00000000..b8ed1a47 --- /dev/null +++ b/src/Ocelot/ServiceDiscovery/UnableToFindServiceProviderError.cs @@ -0,0 +1,12 @@ +using Ocelot.Errors; + +namespace Ocelot.ServiceDiscovery +{ + public class UnableToFindServiceProviderError : Error + { + public UnableToFindServiceProviderError(string message) + : base(message, OcelotErrorCode.UnableToFindServiceProviderError) + { + } + } +} \ No newline at end of file diff --git a/test/Ocelot.UnitTests/LoadBalancer/LoadBalancerHouseTests.cs b/test/Ocelot.UnitTests/LoadBalancer/LoadBalancerHouseTests.cs index 2fd15ee7..31a7bd37 100644 --- a/test/Ocelot.UnitTests/LoadBalancer/LoadBalancerHouseTests.cs +++ b/test/Ocelot.UnitTests/LoadBalancer/LoadBalancerHouseTests.cs @@ -38,7 +38,7 @@ namespace Ocelot.UnitTests.LoadBalancer var key = "test"; this.Given(x => x.GivenThereIsALoadBalancer(key, new FakeLoadBalancer())) - .When(x => x.WhenWeGetThatLoadBalancer(key)) + .When(x => x.WhenWeGetTheLoadBalancer(key)) .Then(x => x.ThenItIsReturned()) .BDDfy(); } @@ -51,13 +51,27 @@ namespace Ocelot.UnitTests.LoadBalancer this.Given(x => x.GivenThereIsALoadBalancer(key, new FakeLoadBalancer())) .And(x => x.GivenThereIsALoadBalancer(keyTwo, new FakeRoundRobinLoadBalancer())) - .When(x => x.WhenWeGetThatLoadBalancer(key)) + .When(x => x.WhenWeGetTheLoadBalancer(key)) .Then(x => x.ThenTheLoadBalancerIs()) - .When(x => x.WhenWeGetThatLoadBalancer(keyTwo)) + .When(x => x.WhenWeGetTheLoadBalancer(keyTwo)) .Then(x => x.ThenTheLoadBalancerIs()) .BDDfy(); } + [Fact] + public void should_return_error_if_no_load_balancer_with_key() + { + this.When(x => x.WhenWeGetTheLoadBalancer("test")) + .Then(x => x.ThenAnErrorIsReturned()) + .BDDfy(); + } + + private void ThenAnErrorIsReturned() + { + _getResult.IsError.ShouldBeTrue(); + _getResult.Errors[0].ShouldBeOfType(); + } + private void ThenTheLoadBalancerIs() { _getResult.Data.ShouldBeOfType(); @@ -82,7 +96,7 @@ namespace Ocelot.UnitTests.LoadBalancer WhenIAddTheLoadBalancer(); } - private void WhenWeGetThatLoadBalancer(string key) + private void WhenWeGetTheLoadBalancer(string key) { _getResult = _loadBalancerHouse.Get(key); } diff --git a/test/Ocelot.UnitTests/ServiceDiscovery/ServiceProviderHouseTests.cs b/test/Ocelot.UnitTests/ServiceDiscovery/ServiceProviderHouseTests.cs new file mode 100644 index 00000000..9443c113 --- /dev/null +++ b/test/Ocelot.UnitTests/ServiceDiscovery/ServiceProviderHouseTests.cs @@ -0,0 +1,126 @@ +using System; +using System.Collections.Generic; +using Ocelot.LoadBalancer.LoadBalancers; +using Ocelot.Responses; +using Ocelot.ServiceDiscovery; +using Ocelot.Values; +using Shouldly; +using TestStack.BDDfy; +using Xunit; + +namespace Ocelot.UnitTests.LoadBalancer +{ + public class ServiceProviderHouseTests + { + private Ocelot.ServiceDiscovery.IServiceProvider _serviceProvider; + private readonly ServiceProviderHouse _serviceProviderHouse; + private Response _addResult; + private Response _getResult; + private string _key; + + public ServiceProviderHouseTests() + { + _serviceProviderHouse = new ServiceProviderHouse(); + } + + [Fact] + public void should_store_service_provider() + { + var key = "test"; + + this.Given(x => x.GivenThereIsAServiceProvider(key, new FakeServiceProvider())) + .When(x => x.WhenIAddTheServiceProvider()) + .Then(x => x.ThenItIsAdded()) + .BDDfy(); + } + + [Fact] + public void should_get_service_provider() + { + var key = "test"; + + this.Given(x => x.GivenThereIsAServiceProvider(key, new FakeServiceProvider())) + .When(x => x.WhenWeGetTheServiceProvider(key)) + .Then(x => x.ThenItIsReturned()) + .BDDfy(); + } + + [Fact] + public void should_store_service_providers_by_key() + { + var key = "test"; + var keyTwo = "testTwo"; + + this.Given(x => x.GivenThereIsAServiceProvider(key, new FakeServiceProvider())) + .And(x => x.GivenThereIsAServiceProvider(keyTwo, new FakeConsulServiceProvider())) + .When(x => x.WhenWeGetTheServiceProvider(key)) + .Then(x => x.ThenTheServiceProviderIs()) + .When(x => x.WhenWeGetTheServiceProvider(keyTwo)) + .Then(x => x.ThenTheServiceProviderIs()) + .BDDfy(); + } + + [Fact] + public void should_return_error_if_no_service_provider_house_with_key() + { + this.When(x => x.WhenWeGetTheServiceProvider("test")) + .Then(x => x.ThenAnErrorIsReturned()) + .BDDfy(); + } + + private void ThenAnErrorIsReturned() + { + _getResult.IsError.ShouldBeTrue(); + _getResult.Errors[0].ShouldBeOfType(); + } + + private void ThenTheServiceProviderIs() + { + _getResult.Data.ShouldBeOfType(); + } + + private void ThenItIsAdded() + { + _addResult.IsError.ShouldBe(false); + _addResult.ShouldBeOfType(); + } + + private void WhenIAddTheServiceProvider() + { + _addResult = _serviceProviderHouse.Add(_key, _serviceProvider); + } + + private void GivenThereIsAServiceProvider(string key, Ocelot.ServiceDiscovery.IServiceProvider serviceProvider) + { + _key = key; + _serviceProvider = serviceProvider; + WhenIAddTheServiceProvider(); + } + + private void WhenWeGetTheServiceProvider(string key) + { + _getResult = _serviceProviderHouse.Get(key); + } + + private void ThenItIsReturned() + { + _getResult.Data.ShouldBe(_serviceProvider); + } + + class FakeServiceProvider : Ocelot.ServiceDiscovery.IServiceProvider + { + public List Get() + { + throw new NotImplementedException(); + } + } + + class FakeConsulServiceProvider : Ocelot.ServiceDiscovery.IServiceProvider + { + public List Get() + { + throw new NotImplementedException(); + } + } + } +}