started implementing the consul service provider

This commit is contained in:
TomPallister 2017-02-04 13:16:31 +00:00
parent 7900aa3f49
commit c46dcc05b8
41 changed files with 282 additions and 140 deletions

View File

@ -34,6 +34,8 @@ namespace Ocelot.Configuration.Builder
private string _downstreamHost;
private int _dsPort;
private string _loadBalancer;
private string _serviceProviderHost;
private int _serviceProviderPort;
public ReRouteBuilder()
{
@ -206,14 +208,25 @@ namespace Ocelot.Configuration.Builder
return this;
}
public ReRouteBuilder WithServiceProviderHost(string serviceProviderHost)
{
_serviceProviderHost = serviceProviderHost;
return this;
}
public ReRouteBuilder WithServiceProviderPort(int serviceProviderPort)
{
_serviceProviderPort = serviceProviderPort;
return this;
}
public ReRoute Build()
{
return new ReRoute(new DownstreamPathTemplate(_downstreamPathTemplate), _upstreamTemplate, _upstreamHttpMethod, _upstreamTemplatePattern,
_isAuthenticated, new AuthenticationOptions(_authenticationProvider, _authenticationProviderUrl, _scopeName,
_requireHttps, _additionalScopes, _scopeSecret), _configHeaderExtractorProperties, _claimToClaims, _routeClaimRequirement,
_isAuthorised, _claimToQueries, _requestIdHeaderKey, _isCached, _fileCacheOptions, _serviceName,
_useServiceDiscovery, _serviceDiscoveryAddress, _serviceDiscoveryProvider, _downstreamScheme, _loadBalancer,
_downstreamHost, _dsPort, _loadBalancerKey);
_isAuthorised, _claimToQueries, _requestIdHeaderKey, _isCached, _fileCacheOptions, _downstreamScheme, _loadBalancer,
_downstreamHost, _dsPort, _loadBalancerKey, new ServiceProviderConfiguraion(_serviceName, _downstreamHost, _dsPort, _useServiceDiscovery, _serviceDiscoveryProvider, _serviceProviderHost, _serviceProviderPort));
}
}
}

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Ocelot.Configuration.File;
@ -8,7 +9,6 @@ using Ocelot.Configuration.Parser;
using Ocelot.Configuration.Validator;
using Ocelot.LoadBalancer.LoadBalancers;
using Ocelot.Responses;
using Ocelot.ServiceDiscovery;
using Ocelot.Utilities;
using Ocelot.Values;
@ -46,9 +46,9 @@ namespace Ocelot.Configuration.Creator
_logger = logger;
}
public Response<IOcelotConfiguration> Create()
public async Task<Response<IOcelotConfiguration>> Create()
{
var config = SetUpConfiguration();
var config = await SetUpConfiguration();
return new OkResponse<IOcelotConfiguration>(config);
}
@ -57,7 +57,7 @@ namespace Ocelot.Configuration.Creator
/// This method is meant to be tempoary to convert a config to an ocelot config...probably wont keep this but we will see
/// will need a refactor at some point as its crap
/// </summary>
private IOcelotConfiguration SetUpConfiguration()
private async Task<IOcelotConfiguration> SetUpConfiguration()
{
var response = _configurationValidator.IsValid(_options.Value);
@ -77,14 +77,14 @@ namespace Ocelot.Configuration.Creator
foreach (var reRoute in _options.Value.ReRoutes)
{
var ocelotReRoute = SetUpReRoute(reRoute, _options.Value.GlobalConfiguration);
var ocelotReRoute = await SetUpReRoute(reRoute, _options.Value.GlobalConfiguration);
reRoutes.Add(ocelotReRoute);
}
return new OcelotConfiguration(reRoutes);
}
private ReRoute SetUpReRoute(FileReRoute fileReRoute, FileGlobalConfiguration globalConfiguration)
private async Task<ReRoute> SetUpReRoute(FileReRoute fileReRoute, FileGlobalConfiguration globalConfiguration)
{
var globalRequestIdConfiguration = !string.IsNullOrEmpty(globalConfiguration?.RequestIdKey);
@ -101,7 +101,6 @@ namespace Ocelot.Configuration.Creator
: fileReRoute.RequestIdKey;
var useServiceDiscovery = !string.IsNullOrEmpty(fileReRoute.ServiceName)
&& !string.IsNullOrEmpty(globalConfiguration?.ServiceDiscoveryProvider?.Address)
&& !string.IsNullOrEmpty(globalConfiguration?.ServiceDiscoveryProvider?.Provider);
//note - not sure if this is the correct key, but this is probably the only unique key i can think of given my poor brain
@ -109,6 +108,13 @@ namespace Ocelot.Configuration.Creator
ReRoute reRoute;
var serviceProviderPort = globalConfiguration?.ServiceDiscoveryProvider?.Port ?? 0;
var serviceProviderConfiguration = new ServiceProviderConfiguraion(fileReRoute.ServiceName,
fileReRoute.DownstreamHost, fileReRoute.DownstreamPort, useServiceDiscovery,
globalConfiguration?.ServiceDiscoveryProvider?.Provider, globalConfiguration?.ServiceDiscoveryProvider?.Host,
serviceProviderPort);
if (isAuthenticated)
{
var authOptionsForRoute = new AuthenticationOptions(fileReRoute.AuthenticationOptions.Provider,
@ -125,11 +131,10 @@ namespace Ocelot.Configuration.Creator
fileReRoute.UpstreamHttpMethod, upstreamTemplate, isAuthenticated,
authOptionsForRoute, claimsToHeaders, claimsToClaims,
fileReRoute.RouteClaimsRequirement, isAuthorised, claimsToQueries,
requestIdKey, isCached, new CacheOptions(fileReRoute.FileCacheOptions.TtlSeconds),
fileReRoute.ServiceName, useServiceDiscovery,
globalConfiguration?.ServiceDiscoveryProvider?.Provider,
globalConfiguration?.ServiceDiscoveryProvider?.Address, fileReRoute.DownstreamScheme,
fileReRoute.LoadBalancer, fileReRoute.DownstreamHost, fileReRoute.DownstreamPort, loadBalancerKey);
requestIdKey, isCached, new CacheOptions(fileReRoute.FileCacheOptions.TtlSeconds)
, fileReRoute.DownstreamScheme,
fileReRoute.LoadBalancer, fileReRoute.DownstreamHost, fileReRoute.DownstreamPort, loadBalancerKey,
serviceProviderConfiguration);
}
else
{
@ -139,13 +144,12 @@ namespace Ocelot.Configuration.Creator
null, new List<ClaimToThing>(), new List<ClaimToThing>(),
fileReRoute.RouteClaimsRequirement, isAuthorised, new List<ClaimToThing>(),
requestIdKey, isCached, new CacheOptions(fileReRoute.FileCacheOptions.TtlSeconds),
fileReRoute.ServiceName, useServiceDiscovery,
globalConfiguration?.ServiceDiscoveryProvider?.Provider,
globalConfiguration?.ServiceDiscoveryProvider?.Address, fileReRoute.DownstreamScheme,
fileReRoute.LoadBalancer, fileReRoute.DownstreamHost, fileReRoute.DownstreamPort, loadBalancerKey);
fileReRoute.DownstreamScheme,
fileReRoute.LoadBalancer, fileReRoute.DownstreamHost, fileReRoute.DownstreamPort, loadBalancerKey,
serviceProviderConfiguration);
}
var loadBalancer = _loadBalanceFactory.Get(reRoute);
var loadBalancer = await _loadBalanceFactory.Get(reRoute);
_loadBalancerHouse.Add(reRoute.LoadBalancerKey, loadBalancer);
return reRoute;
}

View File

@ -1,9 +1,10 @@
using System.Threading.Tasks;
using Ocelot.Responses;
namespace Ocelot.Configuration.Creator
{
public interface IOcelotConfigurationCreator
{
Response<IOcelotConfiguration> Create();
Task<Response<IOcelotConfiguration>> Create();
}
}

View File

@ -3,6 +3,7 @@ namespace Ocelot.Configuration.File
public class FileServiceDiscoveryProvider
{
public string Provider {get;set;}
public string Address {get;set;}
public string Host {get;set;}
public int Port { get; set; }
}
}

View File

@ -1,9 +1,10 @@
using Ocelot.Responses;
using System.Threading.Tasks;
using Ocelot.Responses;
namespace Ocelot.Configuration.Provider
{
public interface IOcelotConfigurationProvider
{
Response<IOcelotConfiguration> Get();
Task<Response<IOcelotConfiguration>> Get();
}
}

View File

@ -1,4 +1,5 @@
using Ocelot.Configuration.Creator;
using System.Threading.Tasks;
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.Repository;
using Ocelot.Responses;
@ -19,7 +20,7 @@ namespace Ocelot.Configuration.Provider
_creator = creator;
}
public Response<IOcelotConfiguration> Get()
public async Task<Response<IOcelotConfiguration>> Get()
{
var repoConfig = _repo.Get();
@ -30,7 +31,7 @@ namespace Ocelot.Configuration.Provider
if (repoConfig.Data == null)
{
var creatorConfig = _creator.Create();
var creatorConfig = await _creator.Create();
if (creatorConfig.IsError)
{

View File

@ -6,15 +6,20 @@ namespace Ocelot.Configuration
{
public class ReRoute
{
public ReRoute(DownstreamPathTemplate downstreamPathTemplate, string upstreamTemplate, string upstreamHttpMethod, string upstreamTemplatePattern,
bool isAuthenticated, AuthenticationOptions authenticationOptions, List<ClaimToThing> configurationHeaderExtractorProperties,
List<ClaimToThing> claimsToClaims, Dictionary<string, string> routeClaimsRequirement, bool isAuthorised, List<ClaimToThing> claimsToQueries,
string requestIdKey, bool isCached, CacheOptions fileCacheOptions, string serviceName, bool useServiceDiscovery,
string serviceDiscoveryProvider, string serviceDiscoveryAddress,
string downstreamScheme, string loadBalancer, string downstreamHost, int downstreamPort,
string loadBalancerKey)
public ReRoute(DownstreamPathTemplate downstreamPathTemplate,
string upstreamTemplate, string upstreamHttpMethod,
string upstreamTemplatePattern,
bool isAuthenticated, AuthenticationOptions authenticationOptions,
List<ClaimToThing> configurationHeaderExtractorProperties,
List<ClaimToThing> claimsToClaims,
Dictionary<string, string> routeClaimsRequirement, bool isAuthorised,
List<ClaimToThing> claimsToQueries,
string requestIdKey, bool isCached, CacheOptions fileCacheOptions,
string downstreamScheme, string loadBalancer, string downstreamHost,
int downstreamPort, string loadBalancerKey, ServiceProviderConfiguraion serviceProviderConfiguraion)
{
LoadBalancerKey = loadBalancerKey;
ServiceProviderConfiguraion = serviceProviderConfiguraion;
LoadBalancer = loadBalancer;
DownstreamHost = downstreamHost;
DownstreamPort = downstreamPort;
@ -35,12 +40,9 @@ namespace Ocelot.Configuration
?? new List<ClaimToThing>();
ClaimsToHeaders = configurationHeaderExtractorProperties
?? new List<ClaimToThing>();
ServiceName = serviceName;
UseServiceDiscovery = useServiceDiscovery;
ServiceDiscoveryProvider = serviceDiscoveryProvider;
ServiceDiscoveryAddress = serviceDiscoveryAddress;
DownstreamScheme = downstreamScheme;
}
public string LoadBalancerKey {get;private set;}
public DownstreamPathTemplate DownstreamPathTemplate { get; private set; }
public string UpstreamTemplate { get; private set; }
@ -56,13 +58,10 @@ namespace Ocelot.Configuration
public string RequestIdKey { get; private set; }
public bool IsCached { get; private set; }
public CacheOptions FileCacheOptions { get; private set; }
public string ServiceName { get; private set;}
public bool UseServiceDiscovery { get; private set;}
public string ServiceDiscoveryProvider { get; private set;}
public string ServiceDiscoveryAddress { get; private set;}
public string DownstreamScheme {get;private set;}
public string LoadBalancer {get;private set;}
public string DownstreamHost { get; private set; }
public int DownstreamPort { get; private set; }
public ServiceProviderConfiguraion ServiceProviderConfiguraion { get; private set; }
}
}

View File

@ -1,21 +1,25 @@
namespace Ocelot.ServiceDiscovery
namespace Ocelot.Configuration
{
public class ServiceProviderConfiguraion
{
public ServiceProviderConfiguraion(string serviceName, string downstreamHost,
int downstreamPort, bool useServiceDiscovery, string serviceDiscoveryProvider)
int downstreamPort, bool useServiceDiscovery, string serviceDiscoveryProvider, string serviceProviderHost, int serviceProviderPort)
{
ServiceName = serviceName;
DownstreamHost = downstreamHost;
DownstreamPort = downstreamPort;
UseServiceDiscovery = useServiceDiscovery;
ServiceDiscoveryProvider = serviceDiscoveryProvider;
ServiceProviderHost = serviceProviderHost;
ServiceProviderPort = serviceProviderPort;
}
public string ServiceName { get; }
public string DownstreamHost { get; }
public int DownstreamPort { get; }
public bool UseServiceDiscovery { get; }
public string ServiceDiscoveryProvider {get;}
public string ServiceDiscoveryProvider { get; }
public string ServiceProviderHost { get; private set; }
public int ServiceProviderPort { get; private set; }
}
}

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Ocelot.Configuration.Provider;
using Ocelot.DownstreamRouteFinder.UrlMatcher;
using Ocelot.Errors;
@ -21,9 +22,9 @@ namespace Ocelot.DownstreamRouteFinder.Finder
_urlPathPlaceholderNameAndValueFinder = urlPathPlaceholderNameAndValueFinder;
}
public Response<DownstreamRoute> FindDownstreamRoute(string upstreamUrlPath, string upstreamHttpMethod)
public async Task<Response<DownstreamRoute>> FindDownstreamRoute(string upstreamUrlPath, string upstreamHttpMethod)
{
var configuration = _configProvider.Get();
var configuration = await _configProvider.Get();
var applicableReRoutes = configuration.Data.ReRoutes.Where(r => string.Equals(r.UpstreamHttpMethod, upstreamHttpMethod, StringComparison.CurrentCultureIgnoreCase));

View File

@ -1,9 +1,10 @@
using Ocelot.Responses;
using System.Threading.Tasks;
using Ocelot.Responses;
namespace Ocelot.DownstreamRouteFinder.Finder
{
public interface IDownstreamRouteFinder
{
Response<DownstreamRoute> FindDownstreamRoute(string upstreamUrlPath, string upstreamHttpMethod);
Task<Response<DownstreamRoute>> FindDownstreamRoute(string upstreamUrlPath, string upstreamHttpMethod);
}
}

View File

@ -34,7 +34,7 @@ namespace Ocelot.DownstreamRouteFinder.Middleware
_logger.LogDebug("upstream url path is {upstreamUrlPath}", upstreamUrlPath);
var downstreamRoute = _downstreamRouteFinder.FindDownstreamRoute(upstreamUrlPath, context.Request.Method);
var downstreamRoute = await _downstreamRouteFinder.FindDownstreamRoute(upstreamUrlPath, context.Request.Method);
if (downstreamRoute.IsError)
{

View File

@ -0,0 +1,24 @@
using System;
namespace Ocelot.Infrastructure.Extensions
{
public static class StringExtensions
{
public static string TrimStart(this string source, string trim, StringComparison stringComparison = StringComparison.Ordinal)
{
if (source == null)
{
return null;
}
string s = source;
while (s.StartsWith(trim, stringComparison))
{
s = s.Substring(trim.Length);
}
return s;
}
}
}

View File

@ -1,4 +1,5 @@
using System;
using System.Threading.Tasks;
using Ocelot.Responses;
using Ocelot.Values;
@ -6,7 +7,7 @@ namespace Ocelot.LoadBalancer.LoadBalancers
{
public interface ILoadBalancer
{
Response<HostAndPort> Lease();
Task<Response<HostAndPort>> Lease();
Response Release(HostAndPort hostAndPort);
}
}

View File

@ -1,9 +1,10 @@
using Ocelot.Configuration;
using System.Threading.Tasks;
using Ocelot.Configuration;
namespace Ocelot.LoadBalancer.LoadBalancers
{
public interface ILoadBalancerFactory
{
ILoadBalancer Get(ReRoute reRoute);
Task<ILoadBalancer> Get(ReRoute reRoute);
}
}

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Ocelot.Errors;
using Ocelot.Responses;
using Ocelot.Values;
@ -9,20 +10,20 @@ namespace Ocelot.LoadBalancer.LoadBalancers
{
public class LeastConnectionLoadBalancer : ILoadBalancer
{
private Func<List<Service>> _services;
private List<Lease> _leases;
private string _serviceName;
private readonly Func<Task<List<Service>>> _services;
private readonly List<Lease> _leases;
private readonly string _serviceName;
public LeastConnectionLoadBalancer(Func<List<Service>> services, string serviceName)
public LeastConnectionLoadBalancer(Func<Task<List<Service>>> services, string serviceName)
{
_services = services;
_serviceName = serviceName;
_leases = new List<Lease>();
}
public Response<HostAndPort> Lease()
public async Task<Response<HostAndPort>> Lease()
{
var services = _services();
var services = await _services.Invoke();
if (services == null)
{

View File

@ -1,4 +1,5 @@
using Ocelot.Configuration;
using System.Threading.Tasks;
using Ocelot.Configuration;
using Ocelot.ServiceDiscovery;
namespace Ocelot.LoadBalancer.LoadBalancers
@ -11,25 +12,27 @@ namespace Ocelot.LoadBalancer.LoadBalancers
_serviceProviderFactory = serviceProviderFactory;
}
public ILoadBalancer Get(ReRoute reRoute)
public async Task<ILoadBalancer> Get(ReRoute reRoute)
{
var serviceConfig = new ServiceProviderConfiguraion(
reRoute.ServiceName,
reRoute.DownstreamHost,
reRoute.DownstreamPort,
reRoute.UseServiceDiscovery,
reRoute.ServiceDiscoveryProvider);
reRoute.ServiceProviderConfiguraion.ServiceName,
reRoute.ServiceProviderConfiguraion.DownstreamHost,
reRoute.ServiceProviderConfiguraion.DownstreamPort,
reRoute.ServiceProviderConfiguraion.UseServiceDiscovery,
reRoute.ServiceProviderConfiguraion.ServiceDiscoveryProvider,
reRoute.ServiceProviderConfiguraion.ServiceProviderHost,
reRoute.ServiceProviderConfiguraion.ServiceProviderPort);
var serviceProvider = _serviceProviderFactory.Get(serviceConfig);
switch (reRoute.LoadBalancer)
{
case "RoundRobin":
return new RoundRobinLoadBalancer(serviceProvider.Get());
return new RoundRobinLoadBalancer(await serviceProvider.Get());
case "LeastConnection":
return new LeastConnectionLoadBalancer(() => serviceProvider.Get(), reRoute.ServiceName);
return new LeastConnectionLoadBalancer(async () => await serviceProvider.Get(), reRoute.ServiceProviderConfiguraion.ServiceName);
default:
return new NoLoadBalancer(serviceProvider.Get());
return new NoLoadBalancer(await serviceProvider.Get());
}
}
}

View File

@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Ocelot.Responses;
using Ocelot.Values;
@ -14,7 +15,7 @@ namespace Ocelot.LoadBalancer.LoadBalancers
_services = services;
}
public Response<HostAndPort> Lease()
public async Task<Response<HostAndPort>> Lease()
{
var service = _services.FirstOrDefault();
return new OkResponse<HostAndPort>(service.HostAndPort);

View File

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Ocelot.Responses;
using Ocelot.Values;
@ -14,7 +15,7 @@ namespace Ocelot.LoadBalancer.LoadBalancers
_services = services;
}
public Response<HostAndPort> Lease()
public async Task<Response<HostAndPort>> Lease()
{
if (_last >= _services.Count)
{

View File

@ -37,7 +37,7 @@ namespace Ocelot.LoadBalancer.Middleware
//set errors and return
}
var hostAndPort = loadBalancer.Data.Lease();
var hostAndPort = await loadBalancer.Data.Lease();
if(hostAndPort.IsError)
{
//set errors and return

View File

@ -1,18 +1,19 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Ocelot.Values;
namespace Ocelot.ServiceDiscovery
{
public class ConfigurationServiceProvider : IServiceDiscoveryProvider
{
private List<Service> _services;
private readonly List<Service> _services;
public ConfigurationServiceProvider(List<Service> services)
{
_services = services;
}
public List<Service> Get()
public async Task<List<Service>> Get()
{
return _services;
}

View File

@ -0,0 +1,16 @@
namespace Ocelot.ServiceDiscovery
{
public class ConsulRegistryConfiguration
{
public ConsulRegistryConfiguration(string hostName, int port, string serviceName)
{
HostName = hostName;
Port = port;
ServiceName = serviceName;
}
public string ServiceName { get; private set; }
public string HostName { get; private set; }
public int Port { get; private set; }
}
}

View File

@ -2,15 +2,54 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Consul;
using Ocelot.Infrastructure.Extensions;
using Ocelot.Values;
namespace Ocelot.ServiceDiscovery
{
public class ConsulServiceDiscoveryProvider : IServiceDiscoveryProvider
{
public List<Service> Get()
private readonly ConsulRegistryConfiguration _configuration;
private readonly ConsulClient _consul;
private const string VersionPrefix = "version-";
public ConsulServiceDiscoveryProvider(ConsulRegistryConfiguration consulRegistryConfiguration)
{
throw new NotImplementedException();
var consulHost = string.IsNullOrEmpty(consulRegistryConfiguration?.HostName) ? "localhost" : consulRegistryConfiguration.HostName;
var consulPort = consulRegistryConfiguration?.Port ?? 8500;
_configuration = new ConsulRegistryConfiguration(consulHost, consulPort, consulRegistryConfiguration?.ServiceName);
_consul = new ConsulClient(config =>
{
config.Address = new Uri($"http://{_configuration.HostName}:{_configuration.Port}");
});
}
public async Task<List<Service>> Get()
{
var queryResult = await _consul.Health.Service(_configuration.ServiceName, string.Empty, true);
var services = queryResult.Response.Select(BuildService);
return services.ToList();
}
private Service BuildService(ServiceEntry serviceEntry)
{
return new Service(
serviceEntry.Service.Service,
new HostAndPort(serviceEntry.Service.Address, serviceEntry.Service.Port),
serviceEntry.Service.ID,
GetVersionFromStrings(serviceEntry.Service.Tags),
serviceEntry.Service.Tags ?? Enumerable.Empty<string>());
}
private string GetVersionFromStrings(IEnumerable<string> strings)
{
return strings
?.FirstOrDefault(x => x.StartsWith(VersionPrefix, StringComparison.Ordinal))
.TrimStart(VersionPrefix);
}
}
}

View File

@ -1,10 +1,11 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Ocelot.Values;
namespace Ocelot.ServiceDiscovery
{
public interface IServiceDiscoveryProvider
{
List<Service> Get();
Task<List<Service>> Get();
}
}

View File

@ -1,4 +1,5 @@
using System;
using Ocelot.Configuration;
namespace Ocelot.ServiceDiscovery
{

View File

@ -1,4 +1,5 @@
using System.Collections.Generic;
using Ocelot.Configuration;
using Ocelot.Values;
namespace Ocelot.ServiceDiscovery
@ -9,20 +10,25 @@ namespace Ocelot.ServiceDiscovery
{
if (serviceConfig.UseServiceDiscovery)
{
return GetServiceDiscoveryProvider(serviceConfig.ServiceName, serviceConfig.ServiceDiscoveryProvider);
return GetServiceDiscoveryProvider(serviceConfig.ServiceName, serviceConfig.ServiceDiscoveryProvider, serviceConfig.ServiceProviderHost, serviceConfig.ServiceProviderPort);
}
var services = new List<Service>()
{
new Service(serviceConfig.ServiceName, new HostAndPort(serviceConfig.DownstreamHost, serviceConfig.DownstreamPort))
new Service(serviceConfig.ServiceName,
new HostAndPort(serviceConfig.DownstreamHost, serviceConfig.DownstreamPort),
string.Empty,
string.Empty,
new string[0])
};
return new ConfigurationServiceProvider(services);
}
private IServiceDiscoveryProvider GetServiceDiscoveryProvider(string serviceName, string serviceProviderName)
private IServiceDiscoveryProvider GetServiceDiscoveryProvider(string serviceName, string serviceProviderName, string providerHostName, int providerPort)
{
return new ConsulServiceDiscoveryProvider();
var consulRegistryConfiguration = new ConsulRegistryConfiguration(providerHostName, providerPort, serviceName);
return new ConsulServiceDiscoveryProvider(consulRegistryConfiguration);
}
}
}

View File

@ -1,13 +1,29 @@
using System.Collections.Generic;
namespace Ocelot.Values
{
public class Service
{
public Service(string name, HostAndPort hostAndPort)
public Service(string name,
HostAndPort hostAndPort,
string id,
string version,
IEnumerable<string> tags)
{
Name = name;
HostAndPort = hostAndPort;
Id = id;
Version = version;
Tags = tags;
}
public string Name {get; private set;}
public HostAndPort HostAndPort {get; private set;}
public string Id { get; private set; }
public string Name { get; private set; }
public string Version { get; private set; }
public IEnumerable<string> Tags { get; private set; }
public HostAndPort HostAndPort { get; private set; }
}
}

View File

@ -29,7 +29,7 @@ namespace Ocelot.AcceptanceTests
var serviceName = "product";
var downstreamServiceOneUrl = "http://localhost:50879";
var downstreamServiceTwoUrl = "http://localhost:50880";
var fakeConsulServiceDiscoveryUrl = "http://localhost:9500";
var fakeConsulServiceDiscoveryUrl = "http://localhost:8500";
var downstreamServiceOneCounter = 0;
var downstreamServiceTwoCounter = 0;
@ -51,7 +51,8 @@ namespace Ocelot.AcceptanceTests
{
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider()
{
Provider = "Consul"
Provider = "Consul",
Host = "localhost"
}
}
};

View File

@ -1 +1 @@
{"ReRoutes":[{"DownstreamPathTemplate":"41879/","UpstreamTemplate":"/","UpstreamHttpMethod":"Get","AuthenticationOptions":{"Provider":null,"ProviderRootUrl":null,"ScopeName":null,"RequireHttps":false,"AdditionalScopes":[],"ScopeSecret":null},"AddHeadersToRequest":{},"AddClaimsToRequest":{},"RouteClaimsRequirement":{},"AddQueriesToRequest":{},"RequestIdKey":null,"FileCacheOptions":{"TtlSeconds":0},"ReRouteIsCaseSensitive":false,"ServiceName":null,"DownstreamScheme":"http","DownstreamHost":"localhost","DownstreamPort":41879,"LoadBalancer":null}],"GlobalConfiguration":{"RequestIdKey":null,"ServiceDiscoveryProvider":{"Provider":null,"Address":null}}}
{"ReRoutes":[{"DownstreamPathTemplate":"41879/","UpstreamTemplate":"/","UpstreamHttpMethod":"Get","AuthenticationOptions":{"Provider":null,"ProviderRootUrl":null,"ScopeName":null,"RequireHttps":false,"AdditionalScopes":[],"ScopeSecret":null},"AddHeadersToRequest":{},"AddClaimsToRequest":{},"RouteClaimsRequirement":{},"AddQueriesToRequest":{},"RequestIdKey":null,"FileCacheOptions":{"TtlSeconds":0},"ReRouteIsCaseSensitive":false,"ServiceName":null,"DownstreamScheme":"http","DownstreamHost":"localhost","DownstreamPort":41879,"LoadBalancer":null}],"GlobalConfiguration":{"RequestIdKey":null,"ServiceDiscoveryProvider":{"Provider":null,"Host":null,"Port":0}}}

View File

@ -151,7 +151,7 @@ namespace Ocelot.UnitTests.Configuration
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider
{
Provider = "consul",
Address = "127.0.0.1"
Host = "127.0.0.1"
}
}
}))
@ -579,7 +579,7 @@ namespace Ocelot.UnitTests.Configuration
private void WhenICreateTheConfig()
{
_config = _ocelotConfigurationCreator.Create();
_config = _ocelotConfigurationCreator.Create().Result;
}
private void ThenTheReRoutesAre(List<ReRoute> expectedReRoutes)
@ -617,7 +617,7 @@ namespace Ocelot.UnitTests.Configuration
{
_loadBalancerFactory
.Setup(x => x.Get(It.IsAny<ReRoute>()))
.Returns(_loadBalancer.Object);
.ReturnsAsync(_loadBalancer.Object);
}
private void TheLoadBalancerFactoryIsCalledCorrectly()

View File

@ -81,7 +81,7 @@ namespace Ocelot.UnitTests.Configuration
{
_creator
.Setup(x => x.Create())
.Returns(config);
.ReturnsAsync(config);
}
private void GivenTheRepoReturns(Response<IOcelotConfiguration> config)
@ -93,7 +93,7 @@ namespace Ocelot.UnitTests.Configuration
private void WhenIGetTheConfig()
{
_result = _ocelotConfigurationProvider.Get();
_result = _ocelotConfigurationProvider.Get().Result;
}
private void TheFollowingIsReturned(Response<IOcelotConfiguration> expected)

View File

@ -84,7 +84,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
_downstreamRouteFinder
.Setup(x => x.FindDownstreamRoute(It.IsAny<string>(), It.IsAny<string>()))
.Returns(_downstreamRoute);
.ReturnsAsync(_downstreamRoute);
}
public void Dispose()

View File

@ -159,7 +159,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
_reRoutesConfig = reRoutesConfig;
_mockConfig
.Setup(x => x.Get())
.Returns(new OkResponse<IOcelotConfiguration>(new OcelotConfiguration(_reRoutesConfig)));
.ReturnsAsync(new OkResponse<IOcelotConfiguration>(new OcelotConfiguration(_reRoutesConfig)));
}
private void GivenThereIsAnUpstreamUrlPath(string upstreamUrlPath)
@ -169,7 +169,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
private void WhenICallTheFinder()
{
_result = _downstreamRouteFinder.FindDownstreamRoute(_upstreamUrlPath, _upstreamHttpMethod);
_result = _downstreamRouteFinder.FindDownstreamRoute(_upstreamUrlPath, _upstreamHttpMethod).Result;
}
private void ThenTheFollowingIsReturned(DownstreamRoute expected)

View File

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Ocelot.LoadBalancer.LoadBalancers;
using Ocelot.Responses;
using Ocelot.Values;
@ -24,7 +25,7 @@ namespace Ocelot.UnitTests.LoadBalancer
var availableServices = new List<Service>
{
new Service(serviceName, hostAndPort)
new Service(serviceName, hostAndPort, string.Empty, string.Empty, new string[0])
};
this.Given(x => x.GivenAHostAndPort(hostAndPort))
@ -41,23 +42,23 @@ namespace Ocelot.UnitTests.LoadBalancer
var availableServices = new List<Service>
{
new Service(serviceName, new HostAndPort("127.0.0.1", 80)),
new Service(serviceName, new HostAndPort("127.0.0.2", 80)),
new Service(serviceName, new HostAndPort("127.0.0.3", 80))
new Service(serviceName, new HostAndPort("127.0.0.1", 80), string.Empty, string.Empty, new string[0]),
new Service(serviceName, new HostAndPort("127.0.0.2", 80), string.Empty, string.Empty, new string[0]),
new Service(serviceName, new HostAndPort("127.0.0.3", 80), string.Empty, string.Empty, new string[0])
};
_services = availableServices;
_leastConnection = new LeastConnectionLoadBalancer(() => _services, serviceName);
_leastConnection = new LeastConnectionLoadBalancer(() => Task.FromResult(_services), serviceName);
var response = _leastConnection.Lease();
var response = _leastConnection.Lease().Result;
response.Data.DownstreamHost.ShouldBe(availableServices[0].HostAndPort.DownstreamHost);
response = _leastConnection.Lease();
response = _leastConnection.Lease().Result;
response.Data.DownstreamHost.ShouldBe(availableServices[1].HostAndPort.DownstreamHost);
response = _leastConnection.Lease();
response = _leastConnection.Lease().Result;
response.Data.DownstreamHost.ShouldBe(availableServices[2].HostAndPort.DownstreamHost);
}
@ -69,26 +70,26 @@ namespace Ocelot.UnitTests.LoadBalancer
var availableServices = new List<Service>
{
new Service(serviceName, new HostAndPort("127.0.0.1", 80)),
new Service(serviceName, new HostAndPort("127.0.0.2", 80)),
new Service(serviceName, new HostAndPort("127.0.0.1", 80), string.Empty, string.Empty, new string[0]),
new Service(serviceName, new HostAndPort("127.0.0.2", 80), string.Empty, string.Empty, new string[0]),
};
_services = availableServices;
_leastConnection = new LeastConnectionLoadBalancer(() => _services, serviceName);
_leastConnection = new LeastConnectionLoadBalancer(() => Task.FromResult(_services), serviceName);
var response = _leastConnection.Lease();
var response = _leastConnection.Lease().Result;
response.Data.DownstreamHost.ShouldBe(availableServices[0].HostAndPort.DownstreamHost);
response = _leastConnection.Lease();
response = _leastConnection.Lease().Result;
response.Data.DownstreamHost.ShouldBe(availableServices[1].HostAndPort.DownstreamHost);
response = _leastConnection.Lease();
response = _leastConnection.Lease().Result;
response.Data.DownstreamHost.ShouldBe(availableServices[0].HostAndPort.DownstreamHost);
response = _leastConnection.Lease();
response = _leastConnection.Lease().Result;
response.Data.DownstreamHost.ShouldBe(availableServices[1].HostAndPort.DownstreamHost);
}
@ -100,33 +101,33 @@ namespace Ocelot.UnitTests.LoadBalancer
var availableServices = new List<Service>
{
new Service(serviceName, new HostAndPort("127.0.0.1", 80)),
new Service(serviceName, new HostAndPort("127.0.0.2", 80)),
new Service(serviceName, new HostAndPort("127.0.0.1", 80), string.Empty, string.Empty, new string[0]),
new Service(serviceName, new HostAndPort("127.0.0.2", 80), string.Empty, string.Empty, new string[0]),
};
_services = availableServices;
_leastConnection = new LeastConnectionLoadBalancer(() => _services, serviceName);
_leastConnection = new LeastConnectionLoadBalancer(() => Task.FromResult(_services), serviceName);
var response = _leastConnection.Lease();
var response = _leastConnection.Lease().Result;
response.Data.DownstreamHost.ShouldBe(availableServices[0].HostAndPort.DownstreamHost);
response = _leastConnection.Lease();
response = _leastConnection.Lease().Result;
response.Data.DownstreamHost.ShouldBe(availableServices[1].HostAndPort.DownstreamHost);
response = _leastConnection.Lease();
response = _leastConnection.Lease().Result;
response.Data.DownstreamHost.ShouldBe(availableServices[0].HostAndPort.DownstreamHost);
response = _leastConnection.Lease();
response = _leastConnection.Lease().Result;
response.Data.DownstreamHost.ShouldBe(availableServices[1].HostAndPort.DownstreamHost);
//release this so 2 should have 1 connection and we should get 2 back as our next host and port
_leastConnection.Release(availableServices[1].HostAndPort);
response = _leastConnection.Lease();
response = _leastConnection.Lease().Result;
response.Data.DownstreamHost.ShouldBe(availableServices[1].HostAndPort.DownstreamHost);
}
@ -172,7 +173,7 @@ namespace Ocelot.UnitTests.LoadBalancer
private void GivenTheLoadBalancerStarts(List<Service> services, string serviceName)
{
_services = services;
_leastConnection = new LeastConnectionLoadBalancer(() => _services, serviceName);
_leastConnection = new LeastConnectionLoadBalancer(() => Task.FromResult(_services), serviceName);
}
private void WhenTheLoadBalancerStarts(List<Service> services, string serviceName)
@ -187,7 +188,7 @@ namespace Ocelot.UnitTests.LoadBalancer
private void WhenIGetTheNextHostAndPort()
{
_result = _leastConnection.Lease();
_result = _leastConnection.Lease().Result;
}
private void ThenTheNextHostAndPortIsReturned()

View File

@ -99,7 +99,7 @@ namespace Ocelot.UnitTests.LoadBalancer
private void WhenIGetTheLoadBalancer()
{
_result = _factory.Get(_reRoute);
_result = _factory.Get(_reRoute).Result;
}
private void ThenTheLoadBalancerIsReturned<T>()

View File

@ -1,4 +1,5 @@
using System;
using System.Threading.Tasks;
using Ocelot.LoadBalancer.LoadBalancers;
using Ocelot.Responses;
using Ocelot.Values;
@ -108,7 +109,7 @@ namespace Ocelot.UnitTests.LoadBalancer
class FakeLoadBalancer : ILoadBalancer
{
public Response<HostAndPort> Lease()
public Task<Response<HostAndPort>> Lease()
{
throw new NotImplementedException();
}
@ -121,7 +122,7 @@ namespace Ocelot.UnitTests.LoadBalancer
class FakeRoundRobinLoadBalancer : ILoadBalancer
{
public Response<HostAndPort> Lease()
public Task<Response<HostAndPort>> Lease()
{
throw new NotImplementedException();
}

View File

@ -82,7 +82,7 @@ namespace Ocelot.UnitTests.LoadBalancer
_hostAndPort = new HostAndPort("127.0.0.1", 80);
_loadBalancer
.Setup(x => x.Lease())
.Returns(new OkResponse<HostAndPort>(_hostAndPort));
.ReturnsAsync(new OkResponse<HostAndPort>(_hostAndPort));
}
private void GivenTheDownStreamRouteIs(DownstreamRoute downstreamRoute)

View File

@ -21,7 +21,7 @@ namespace Ocelot.UnitTests.LoadBalancer
var services = new List<Service>
{
new Service("product", hostAndPort)
new Service("product", hostAndPort, string.Empty, string.Empty, new string[0])
};
this.Given(x => x.GivenServices(services))
.When(x => x.WhenIGetTheNextHostAndPort())
@ -37,7 +37,7 @@ namespace Ocelot.UnitTests.LoadBalancer
private void WhenIGetTheNextHostAndPort()
{
_loadBalancer = new NoLoadBalancer(_services);
_result = _loadBalancer.Lease();
_result = _loadBalancer.Lease().Result;
}
private void ThenTheHostAndPortIs(HostAndPort expected)

View File

@ -19,9 +19,9 @@ namespace Ocelot.UnitTests.LoadBalancer
{
_services = new List<Service>
{
new Service("product", new HostAndPort("127.0.0.1", 5000)),
new Service("product", new HostAndPort("127.0.0.1", 5001)),
new Service("product", new HostAndPort("127.0.0.1", 5001))
new Service("product", new HostAndPort("127.0.0.1", 5000), string.Empty, string.Empty, new string[0]),
new Service("product", new HostAndPort("127.0.0.1", 5001), string.Empty, string.Empty, new string[0]),
new Service("product", new HostAndPort("127.0.0.1", 5001), string.Empty, string.Empty, new string[0])
};
_roundRobin = new RoundRobinLoadBalancer(_services);
@ -46,18 +46,18 @@ namespace Ocelot.UnitTests.LoadBalancer
while (stopWatch.ElapsedMilliseconds < 1000)
{
var address = _roundRobin.Lease();
var address = _roundRobin.Lease().Result;
address.Data.ShouldBe(_services[0].HostAndPort);
address = _roundRobin.Lease();
address = _roundRobin.Lease().Result;
address.Data.ShouldBe(_services[1].HostAndPort);
address = _roundRobin.Lease();
address = _roundRobin.Lease().Result;
address.Data.ShouldBe(_services[2].HostAndPort);
}
}
private void GivenIGetTheNextAddress()
{
_hostAndPort = _roundRobin.Lease();
_hostAndPort = _roundRobin.Lease().Result;
}
private void ThenTheNextAddressIndexIs(int index)

View File

@ -21,7 +21,7 @@ namespace Ocelot.UnitTests.ServiceDiscovery
var services = new List<Service>
{
new Service("product", hostAndPort)
new Service("product", hostAndPort, string.Empty, string.Empty, new string[0])
};
this.Given(x => x.GivenServices(services))
@ -38,7 +38,7 @@ namespace Ocelot.UnitTests.ServiceDiscovery
private void WhenIGetTheService()
{
_serviceProvider = new ConfigurationServiceProvider(_expected);
_result = _serviceProvider.Get();
_result = _serviceProvider.Get().Result;
}
private void ThenTheFollowingIsReturned(List<Service> services)

View File

@ -1,3 +1,4 @@
using Ocelot.Configuration;
using Ocelot.ServiceDiscovery;
using Shouldly;
using TestStack.BDDfy;
@ -19,7 +20,7 @@ namespace Ocelot.UnitTests.ServiceDiscovery
[Fact]
public void should_return_no_service_provider()
{
var serviceConfig = new ServiceProviderConfiguraion("product", "127.0.0.1", 80, false, "Does not matter");
var serviceConfig = new ServiceProviderConfiguraion("product", "127.0.0.1", 80, false, "Does not matter", string.Empty, 0);
this.Given(x => x.GivenTheReRoute(serviceConfig))
.When(x => x.WhenIGetTheServiceProvider())
@ -30,7 +31,7 @@ namespace Ocelot.UnitTests.ServiceDiscovery
[Fact]
public void should_return_consul_service_provider()
{
var serviceConfig = new ServiceProviderConfiguraion("product", string.Empty, 0, true, "Consul");
var serviceConfig = new ServiceProviderConfiguraion("product", string.Empty, 0, true, "Consul", string.Empty, 0);
this.Given(x => x.GivenTheReRoute(serviceConfig))
.When(x => x.WhenIGetTheServiceProvider())

View File

@ -50,13 +50,13 @@ namespace Ocelot.UnitTests.ServiceDiscovery
private void GivenAServiceIsRegistered(string name, string address, int port)
{
_service = new Service(name, new HostAndPort(address, port));
_service = new Service(name, new HostAndPort(address, port), string.Empty, string.Empty, new string[0]);
_serviceRepository.Set(_service);
}
private void GivenAServiceToRegister(string name, string address, int port)
{
_service = new Service(name, new HostAndPort(address, port));
_service = new Service(name, new HostAndPort(address, port), string.Empty, string.Empty, new string[0]);
}
private void WhenIRegisterTheService()