mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-06-19 09:48:16 +08:00
started implementing the consul service provider
This commit is contained in:
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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)
|
||||
public ServiceProviderConfiguraion(string serviceName, string downstreamHost,
|
||||
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; }
|
||||
}
|
||||
}
|
@ -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));
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
24
src/Ocelot/Infrastructure/Extensions/StringExtensions.cs
Normal file
24
src/Ocelot/Infrastructure/Extensions/StringExtensions.cs
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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)
|
||||
{
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
16
src/Ocelot/ServiceDiscovery/ConsulRegistryConfiguration.cs
Normal file
16
src/Ocelot/ServiceDiscovery/ConsulRegistryConfiguration.cs
Normal 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; }
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using Ocelot.Configuration;
|
||||
|
||||
namespace Ocelot.ServiceDiscovery
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user