refactoring service discovery and load balancing approach into load balancing middleware

This commit is contained in:
TomPallister
2017-02-01 22:00:01 +00:00
54 changed files with 1160 additions and 547 deletions

View File

@ -0,0 +1,53 @@
using System.Collections.Generic;
using Ocelot.ServiceDiscovery;
using Ocelot.Values;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.ServiceDiscovery
{
public class ConfigurationServiceProviderTests
{
private ConfigurationServiceProvider _serviceProvider;
private HostAndPort _hostAndPort;
private List<Service> _result;
private List<Service> _expected;
[Fact]
public void should_return_services()
{
var hostAndPort = new HostAndPort("127.0.0.1", 80);
var services = new List<Service>
{
new Service("product", hostAndPort)
};
this.Given(x => x.GivenServices(services))
.When(x => x.WhenIGetTheService())
.Then(x => x.ThenTheFollowingIsReturned(services))
.BDDfy();
}
private void GivenServices(List<Service> services)
{
_expected = services;
}
private void WhenIGetTheService()
{
_serviceProvider = new ConfigurationServiceProvider(_expected);
_result = _serviceProvider.Get();
}
private void ThenTheFollowingIsReturned(List<Service> services)
{
_result[0].HostAndPort.DownstreamHost.ShouldBe(services[0].HostAndPort.DownstreamHost);
_result[0].HostAndPort.DownstreamPort.ShouldBe(services[0].HostAndPort.DownstreamPort);
_result[0].Name.ShouldBe(services[0].Name);
}
}
}

View File

@ -0,0 +1,45 @@
using Ocelot.ServiceDiscovery;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.ServiceDiscovery
{
public class ServiceProviderFactoryTests
{
private ServiceConfiguraion _serviceConfig;
private IServiceProvider _result;
private readonly ServiceProviderFactory _factory;
public ServiceProviderFactoryTests()
{
_factory = new ServiceProviderFactory();
}
[Fact]
public void should_return_no_service_provider()
{
var serviceConfig = new ServiceConfiguraion("product", "127.0.0.1", 80, false);
this.Given(x => x.GivenTheReRoute(serviceConfig))
.When(x => x.WhenIGetTheServiceProvider())
.Then(x => x.ThenTheServiceProviderIs<ConfigurationServiceProvider>())
.BDDfy();
}
private void GivenTheReRoute(ServiceConfiguraion serviceConfig)
{
_serviceConfig = serviceConfig;
}
private void WhenIGetTheServiceProvider()
{
_result = _factory.Get(_serviceConfig);
}
private void ThenTheServiceProviderIs<T>()
{
_result.ShouldBeOfType<T>();
}
}
}

View File

@ -0,0 +1,136 @@
using System.Collections.Generic;
using Ocelot.Values;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.ServiceDiscovery
{
public class ServiceRegistryTests
{
private Service _service;
private List<Service> _services;
private ServiceRegistry _serviceRegistry;
private ServiceRepository _serviceRepository;
public ServiceRegistryTests()
{
_serviceRepository = new ServiceRepository();
_serviceRegistry = new ServiceRegistry(_serviceRepository);
}
[Fact]
public void should_register_service()
{
this.Given(x => x.GivenAServiceToRegister("product", "localhost:5000", 80))
.When(x => x.WhenIRegisterTheService())
.Then(x => x.ThenTheServiceIsRegistered())
.BDDfy();
}
public void should_lookup_service()
{
this.Given(x => x.GivenAServiceIsRegistered("product", "localhost:600", 80))
.When(x => x.WhenILookupTheService("product"))
.Then(x => x.ThenTheServiceDetailsAreReturned())
.BDDfy();
}
private void ThenTheServiceDetailsAreReturned()
{
_services[0].HostAndPort.DownstreamHost.ShouldBe(_service.HostAndPort.DownstreamHost);
_services[0].HostAndPort.DownstreamPort.ShouldBe(_service.HostAndPort.DownstreamPort);
_services[0].Name.ShouldBe(_service.Name);
}
private void WhenILookupTheService(string name)
{
_services = _serviceRegistry.Lookup(name);
}
private void GivenAServiceIsRegistered(string name, string address, int port)
{
_service = new Service(name, new HostAndPort(address, port));
_serviceRepository.Set(_service);
}
private void GivenAServiceToRegister(string name, string address, int port)
{
_service = new Service(name, new HostAndPort(address, port));
}
private void WhenIRegisterTheService()
{
_serviceRegistry.Register(_service);
}
private void ThenTheServiceIsRegistered()
{
var serviceNameAndAddress = _serviceRepository.Get(_service.Name);
serviceNameAndAddress[0].HostAndPort.DownstreamHost.ShouldBe(_service.HostAndPort.DownstreamHost);
serviceNameAndAddress[0].HostAndPort.DownstreamPort.ShouldBe(_service.HostAndPort.DownstreamPort);
serviceNameAndAddress[0].Name.ShouldBe(_service.Name);
}
}
public interface IServiceRegistry
{
void Register(Service serviceNameAndAddress);
List<Service> Lookup(string name);
}
public class ServiceRegistry : IServiceRegistry
{
private readonly IServiceRepository _repository;
public ServiceRegistry(IServiceRepository repository)
{
_repository = repository;
}
public void Register(Service serviceNameAndAddress)
{
_repository.Set(serviceNameAndAddress);
}
public List<Service> Lookup(string name)
{
return _repository.Get(name);
}
}
public interface IServiceRepository
{
List<Service> Get(string serviceName);
void Set(Service serviceNameAndAddress);
}
public class ServiceRepository : IServiceRepository
{
private Dictionary<string, List<Service>> _registeredServices;
public ServiceRepository()
{
_registeredServices = new Dictionary<string, List<Service>>();
}
public List<Service> Get(string serviceName)
{
return _registeredServices[serviceName];
}
public void Set(Service serviceNameAndAddress)
{
List<Service> services;
if(_registeredServices.TryGetValue(serviceNameAndAddress.Name, out services))
{
services.Add(serviceNameAndAddress);
_registeredServices[serviceNameAndAddress.Name] = services;
}
else
{
_registeredServices[serviceNameAndAddress.Name] = new List<Service>(){ serviceNameAndAddress };
}
}
}
}