mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-11-01 06:15:27 +08:00 
			
		
		
		
	massive refactor to handle creating load balancer first time a re route is called
This commit is contained in:
		| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "projects": [ "src", "test" ], | ||||
|   "sdk": { | ||||
|     "version": "2.0.0" | ||||
|     "version": "2.0.2" | ||||
|   } | ||||
| } | ||||
| @@ -26,13 +26,14 @@ namespace Ocelot.Configuration.Builder | ||||
|         private string _downstreamHost; | ||||
|         private int _downstreamPort; | ||||
|         private string _loadBalancer; | ||||
|         private ServiceProviderConfiguration _serviceProviderConfiguraion; | ||||
|         private bool _useQos; | ||||
|         private QoSOptions _qosOptions; | ||||
|         private HttpHandlerOptions _httpHandlerOptions; | ||||
|         public bool _enableRateLimiting; | ||||
|         public RateLimitOptions _rateLimitOptions; | ||||
|         private string _authenticationProviderKey; | ||||
|         private bool _useServiceDiscovery; | ||||
|         private string _serviceName; | ||||
|  | ||||
|         public ReRouteBuilder WithLoadBalancer(string loadBalancer) | ||||
|         { | ||||
| @@ -154,12 +155,6 @@ namespace Ocelot.Configuration.Builder | ||||
|             return this; | ||||
|         } | ||||
|  | ||||
|         public ReRouteBuilder WithServiceProviderConfiguraion(ServiceProviderConfiguration serviceProviderConfiguraion) | ||||
|         { | ||||
|             _serviceProviderConfiguraion = serviceProviderConfiguraion; | ||||
|             return this; | ||||
|         } | ||||
|  | ||||
|         public ReRouteBuilder WithAuthenticationOptions(AuthenticationOptions authenticationOptions) | ||||
|         { | ||||
|             _authenticationOptions = authenticationOptions; | ||||
| @@ -190,6 +185,18 @@ namespace Ocelot.Configuration.Builder | ||||
|             return this; | ||||
|         } | ||||
|  | ||||
|         public ReRouteBuilder WithUseServiceDiscovery(bool useServiceDiscovery) | ||||
|         { | ||||
|             _useServiceDiscovery = useServiceDiscovery; | ||||
|             return this; | ||||
|         } | ||||
|  | ||||
|         public ReRouteBuilder WithServiceName(string serviceName) | ||||
|         { | ||||
|             _serviceName = serviceName; | ||||
|             return this; | ||||
|         } | ||||
|  | ||||
|         public ReRoute Build() | ||||
|         { | ||||
|             return new ReRoute( | ||||
| @@ -212,12 +219,13 @@ namespace Ocelot.Configuration.Builder | ||||
|                 _downstreamHost,  | ||||
|                 _downstreamPort,  | ||||
|                 _loadBalancerKey,  | ||||
|                 _serviceProviderConfiguraion,  | ||||
|                 _useQos,  | ||||
|                 _qosOptions, | ||||
|                 _enableRateLimiting, | ||||
|                 _rateLimitOptions, | ||||
|                 _httpHandlerOptions); | ||||
|                 _httpHandlerOptions, | ||||
|                 _useServiceDiscovery, | ||||
|                 _serviceName); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -2,38 +2,10 @@ namespace Ocelot.Configuration.Builder | ||||
| { | ||||
|     public class ServiceProviderConfigurationBuilder | ||||
|     { | ||||
|         private string _serviceName; | ||||
|         private string _downstreamHost; | ||||
|         private int _downstreamPort; | ||||
|         private bool _userServiceDiscovery; | ||||
|         private string _serviceDiscoveryProvider; | ||||
|         private string _serviceDiscoveryProviderHost; | ||||
|         private int _serviceDiscoveryProviderPort; | ||||
|  | ||||
|         public ServiceProviderConfigurationBuilder WithServiceName(string serviceName) | ||||
|         { | ||||
|             _serviceName = serviceName; | ||||
|             return this; | ||||
|         } | ||||
|  | ||||
|         public ServiceProviderConfigurationBuilder WithDownstreamHost(string downstreamHost) | ||||
|         { | ||||
|             _downstreamHost = downstreamHost; | ||||
|             return this; | ||||
|         } | ||||
|  | ||||
|         public ServiceProviderConfigurationBuilder WithDownstreamPort(int downstreamPort) | ||||
|         { | ||||
|             _downstreamPort = downstreamPort; | ||||
|             return this; | ||||
|         } | ||||
|  | ||||
|         public ServiceProviderConfigurationBuilder WithUseServiceDiscovery(bool userServiceDiscovery) | ||||
|         { | ||||
|             _userServiceDiscovery = userServiceDiscovery; | ||||
|             return this; | ||||
|         } | ||||
|  | ||||
|         public ServiceProviderConfigurationBuilder WithServiceDiscoveryProvider(string serviceDiscoveryProvider) | ||||
|         { | ||||
|             _serviceDiscoveryProvider = serviceDiscoveryProvider; | ||||
| @@ -52,11 +24,9 @@ namespace Ocelot.Configuration.Builder | ||||
|             return this; | ||||
|         } | ||||
|  | ||||
|          | ||||
|         public ServiceProviderConfiguration Build() | ||||
|         { | ||||
|             return new ServiceProviderConfiguration(_serviceName, _downstreamHost, _downstreamPort, _userServiceDiscovery, | ||||
|             _serviceDiscoveryProvider, _serviceDiscoveryProviderHost,_serviceDiscoveryProviderPort); | ||||
|             return new ServiceProviderConfiguration(_serviceDiscoveryProvider, _serviceDiscoveryProviderHost,_serviceDiscoveryProviderPort); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -26,7 +26,6 @@ namespace Ocelot.Configuration.Creator | ||||
|         private readonly IOptions<FileConfiguration> _options; | ||||
|         private readonly IConfigurationValidator _configurationValidator; | ||||
|         private readonly IOcelotLogger _logger; | ||||
|         private readonly ILoadBalancerCreator _lbCreator; | ||||
|         private readonly IQoSProviderFactory _qoSProviderFactory; | ||||
|         private readonly IQosProviderHouse _qosProviderHouse; | ||||
|         private readonly IClaimsToThingCreator _claimsToThingCreator; | ||||
| @@ -44,7 +43,6 @@ namespace Ocelot.Configuration.Creator | ||||
|             IOptions<FileConfiguration> options,  | ||||
|             IConfigurationValidator configurationValidator, | ||||
|             IOcelotLoggerFactory loggerFactory, | ||||
|             ILoadBalancerCreator lbCreator, | ||||
|             IQoSProviderFactory qoSProviderFactory,  | ||||
|             IQosProviderHouse qosProviderHouse, | ||||
|             IClaimsToThingCreator claimsToThingCreator, | ||||
| @@ -59,7 +57,6 @@ namespace Ocelot.Configuration.Creator | ||||
|             IHttpHandlerOptionsCreator httpHandlerOptionsCreator | ||||
|             ) | ||||
|         { | ||||
|             _lbCreator = lbCreator; | ||||
|             _regionCreator = regionCreator; | ||||
|             _rateLimitOptionsCreator = rateLimitOptionsCreator; | ||||
|             _requestIdKeyCreator = requestIdKeyCreator; | ||||
| @@ -114,8 +111,10 @@ namespace Ocelot.Configuration.Creator | ||||
|                 var ocelotReRoute = await SetUpReRoute(reRoute, fileConfiguration.GlobalConfiguration); | ||||
|                 reRoutes.Add(ocelotReRoute); | ||||
|             } | ||||
|  | ||||
|             var serviceProviderConfiguration = _serviceProviderConfigCreator.Create(fileConfiguration.GlobalConfiguration); | ||||
|              | ||||
|             return new OcelotConfiguration(reRoutes, fileConfiguration.GlobalConfiguration.AdministrationPath); | ||||
|             return new OcelotConfiguration(reRoutes, fileConfiguration.GlobalConfiguration.AdministrationPath, serviceProviderConfiguration); | ||||
|         } | ||||
|  | ||||
|         private async Task<ReRoute> SetUpReRoute(FileReRoute fileReRoute, FileGlobalConfiguration globalConfiguration) | ||||
| @@ -128,8 +127,6 @@ namespace Ocelot.Configuration.Creator | ||||
|  | ||||
|             var upstreamTemplatePattern = _upstreamTemplatePatternCreator.Create(fileReRoute); | ||||
|  | ||||
|             var serviceProviderConfiguration = _serviceProviderConfigCreator.Create(fileReRoute, globalConfiguration); | ||||
|  | ||||
|             var authOptionsForRoute = _authOptionsCreator.Create(fileReRoute); | ||||
|  | ||||
|             var claimsToHeaders = _claimsToThingCreator.Create(fileReRoute.AddHeadersToRequest); | ||||
| @@ -166,7 +163,6 @@ namespace Ocelot.Configuration.Creator | ||||
|                 .WithDownstreamHost(fileReRoute.DownstreamHost) | ||||
|                 .WithDownstreamPort(fileReRoute.DownstreamPort) | ||||
|                 .WithLoadBalancerKey(reRouteKey) | ||||
|                 .WithServiceProviderConfiguraion(serviceProviderConfiguration) | ||||
|                 .WithIsQos(fileReRouteOptions.IsQos) | ||||
|                 .WithQosOptions(qosOptions) | ||||
|                 .WithEnableRateLimiting(fileReRouteOptions.EnableRateLimiting) | ||||
| @@ -174,7 +170,6 @@ namespace Ocelot.Configuration.Creator | ||||
|                 .WithHttpHandlerOptions(httpHandlerOptions) | ||||
|                 .Build(); | ||||
|  | ||||
|             await _lbCreator.SetupLoadBalancer(reRoute); | ||||
|             SetupQosProvider(reRoute); | ||||
|             return reRoute; | ||||
|         } | ||||
|   | ||||
| @@ -4,6 +4,6 @@ namespace Ocelot.Configuration.Creator | ||||
| { | ||||
|     public interface IServiceProviderConfigurationCreator | ||||
|     { | ||||
|         ServiceProviderConfiguration Create(FileReRoute fileReRoute, FileGlobalConfiguration globalConfiguration); | ||||
|         ServiceProviderConfiguration Create(FileGlobalConfiguration globalConfiguration); | ||||
|     } | ||||
| } | ||||
| @@ -5,18 +5,11 @@ namespace Ocelot.Configuration.Creator | ||||
| { | ||||
|     public class ServiceProviderConfigurationCreator : IServiceProviderConfigurationCreator | ||||
|     { | ||||
|         public ServiceProviderConfiguration Create(FileReRoute fileReRoute, FileGlobalConfiguration globalConfiguration) | ||||
|         public ServiceProviderConfiguration Create(FileGlobalConfiguration globalConfiguration) | ||||
|         { | ||||
|             var useServiceDiscovery = !string.IsNullOrEmpty(fileReRoute.ServiceName) | ||||
|                 && !string.IsNullOrEmpty(globalConfiguration?.ServiceDiscoveryProvider?.Provider); | ||||
|  | ||||
|             var serviceProviderPort = globalConfiguration?.ServiceDiscoveryProvider?.Port ?? 0; | ||||
|  | ||||
|             return new ServiceProviderConfigurationBuilder() | ||||
|                     .WithServiceName(fileReRoute.ServiceName) | ||||
|                     .WithDownstreamHost(fileReRoute.DownstreamHost) | ||||
|                     .WithDownstreamPort(fileReRoute.DownstreamPort) | ||||
|                     .WithUseServiceDiscovery(useServiceDiscovery) | ||||
|                     .WithServiceDiscoveryProvider(globalConfiguration?.ServiceDiscoveryProvider?.Provider) | ||||
|                     .WithServiceDiscoveryProviderHost(globalConfiguration?.ServiceDiscoveryProvider?.Host) | ||||
|                     .WithServiceDiscoveryProviderPort(serviceProviderPort) | ||||
|   | ||||
| @@ -6,5 +6,6 @@ namespace Ocelot.Configuration | ||||
|     { | ||||
|         List<ReRoute> ReRoutes { get; } | ||||
|         string AdministrationPath {get;} | ||||
|         ServiceProviderConfiguration ServiceProviderConfiguration {get;} | ||||
|     } | ||||
| } | ||||
| @@ -4,13 +4,15 @@ namespace Ocelot.Configuration | ||||
| { | ||||
|     public class OcelotConfiguration : IOcelotConfiguration | ||||
|     { | ||||
|         public OcelotConfiguration(List<ReRoute> reRoutes, string administrationPath) | ||||
|         public OcelotConfiguration(List<ReRoute> reRoutes, string administrationPath, ServiceProviderConfiguration serviceProviderConfiguration) | ||||
|         { | ||||
|             ReRoutes = reRoutes; | ||||
|             AdministrationPath = administrationPath; | ||||
|             ServiceProviderConfiguration = serviceProviderConfiguration; | ||||
|         } | ||||
|  | ||||
|         public List<ReRoute> ReRoutes { get; } | ||||
|         public string AdministrationPath {get;} | ||||
|         public ServiceProviderConfiguration ServiceProviderConfiguration {get;} | ||||
|     } | ||||
| } | ||||
| @@ -25,15 +25,17 @@ namespace Ocelot.Configuration | ||||
|             string downstreamHost,  | ||||
|             int downstreamPort,  | ||||
|             string reRouteKey,  | ||||
|             ServiceProviderConfiguration serviceProviderConfiguraion, | ||||
|             bool isQos, | ||||
|             QoSOptions qosOptions, | ||||
|             bool enableEndpointRateLimiting, | ||||
|             RateLimitOptions ratelimitOptions, | ||||
|             HttpHandlerOptions httpHandlerOptions) | ||||
|             HttpHandlerOptions httpHandlerOptions, | ||||
|             bool useServiceDiscovery, | ||||
|             string serviceName) | ||||
|         { | ||||
|             ServiceName = serviceName; | ||||
|             UseServiceDiscovery = useServiceDiscovery; | ||||
|             ReRouteKey = reRouteKey; | ||||
|             ServiceProviderConfiguraion = serviceProviderConfiguraion; | ||||
|             LoadBalancer = loadBalancer; | ||||
|             DownstreamHost = downstreamHost; | ||||
|             DownstreamPort = downstreamPort; | ||||
| @@ -83,9 +85,10 @@ namespace Ocelot.Configuration | ||||
|         public string LoadBalancer {get;private set;} | ||||
|         public string DownstreamHost { get; private set; } | ||||
|         public int DownstreamPort { get; private set; } | ||||
|         public ServiceProviderConfiguration ServiceProviderConfiguraion { get; private set; } | ||||
|         public bool EnableEndpointEndpointRateLimiting { get; private set; } | ||||
|         public RateLimitOptions RateLimitOptions { get; private set; } | ||||
|         public HttpHandlerOptions HttpHandlerOptions { get; private set; } | ||||
|         public bool UseServiceDiscovery {get;private set;} | ||||
|         public string ServiceName {get;private set;} | ||||
|     } | ||||
| } | ||||
| @@ -2,22 +2,13 @@ | ||||
| { | ||||
|     public class ServiceProviderConfiguration | ||||
|     { | ||||
|         public ServiceProviderConfiguration(string serviceName, string downstreamHost, | ||||
|             int downstreamPort, bool useServiceDiscovery, string serviceDiscoveryProvider, string serviceProviderHost, int serviceProviderPort) | ||||
|         public ServiceProviderConfiguration(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 ServiceProviderHost { get; private set; } | ||||
|         public int ServiceProviderPort { get; private set; } | ||||
|   | ||||
| @@ -94,7 +94,6 @@ namespace Ocelot.DependencyInjection | ||||
|                 .AddJsonFormatters(); | ||||
|  | ||||
|             services.AddLogging(); | ||||
|             services.TryAddSingleton<ILoadBalancerCreator, LoadBalancerCreator>(); | ||||
|             services.TryAddSingleton<IRegionCreator, RegionCreator>(); | ||||
|             services.TryAddSingleton<IFileConfigurationRepository, FileConfigurationRepository>(); | ||||
|             services.TryAddSingleton<IFileConfigurationSetter, FileConfigurationSetter>(); | ||||
|   | ||||
| @@ -1,10 +0,0 @@ | ||||
| using System.Threading.Tasks; | ||||
| using Ocelot.Configuration; | ||||
|  | ||||
| namespace Ocelot.LoadBalancer | ||||
| { | ||||
|     public interface ILoadBalancerCreator | ||||
|     { | ||||
|         Task SetupLoadBalancer(ReRoute reRoute); | ||||
|     } | ||||
| } | ||||
| @@ -1,24 +0,0 @@ | ||||
| using System.Threading.Tasks; | ||||
| using Ocelot.Configuration; | ||||
| using Ocelot.LoadBalancer.LoadBalancers; | ||||
|  | ||||
| namespace Ocelot.LoadBalancer | ||||
| { | ||||
|     public class LoadBalancerCreator : ILoadBalancerCreator | ||||
|     { | ||||
|         private readonly ILoadBalancerHouse _loadBalancerHouse; | ||||
|         private readonly ILoadBalancerFactory _loadBalanceFactory; | ||||
|  | ||||
|         public LoadBalancerCreator(ILoadBalancerHouse loadBalancerHouse, ILoadBalancerFactory loadBalancerFactory) | ||||
|         { | ||||
|             _loadBalancerHouse = loadBalancerHouse; | ||||
|             _loadBalanceFactory = loadBalancerFactory; | ||||
|         } | ||||
|      | ||||
|         public async Task SetupLoadBalancer(ReRoute reRoute) | ||||
|         { | ||||
|             var loadBalancer = await _loadBalanceFactory.Get(reRoute); | ||||
|             _loadBalancerHouse.Add(reRoute.ReRouteKey, loadBalancer); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -5,6 +5,6 @@ namespace Ocelot.LoadBalancer.LoadBalancers | ||||
| { | ||||
|     public interface ILoadBalancerFactory | ||||
|     { | ||||
|         Task<ILoadBalancer> Get(ReRoute reRoute); | ||||
|         Task<ILoadBalancer> Get(ReRoute reRoute, ServiceProviderConfiguration config); | ||||
|     } | ||||
| } | ||||
| @@ -1,10 +1,11 @@ | ||||
| using Ocelot.Responses; | ||||
| using System.Threading.Tasks; | ||||
| using Ocelot.Configuration; | ||||
| using Ocelot.Responses; | ||||
|  | ||||
| namespace Ocelot.LoadBalancer.LoadBalancers | ||||
| { | ||||
|     public interface ILoadBalancerHouse | ||||
|     { | ||||
|         Response<ILoadBalancer> Get(string key); | ||||
|         Response Add(string key, ILoadBalancer loadBalancer); | ||||
|         Task<Response<ILoadBalancer>> Get(ReRoute reRoute, ServiceProviderConfiguration config); | ||||
|     } | ||||
| } | ||||
| @@ -12,16 +12,16 @@ namespace Ocelot.LoadBalancer.LoadBalancers | ||||
|             _serviceProviderFactory = serviceProviderFactory; | ||||
|         } | ||||
|  | ||||
|         public async Task<ILoadBalancer> Get(ReRoute reRoute) | ||||
|         public async Task<ILoadBalancer> Get(ReRoute reRoute, ServiceProviderConfiguration config) | ||||
|         {             | ||||
|             var serviceProvider = _serviceProviderFactory.Get(reRoute.ServiceProviderConfiguraion); | ||||
|             var serviceProvider = _serviceProviderFactory.Get(config, reRoute); | ||||
|  | ||||
|             switch (reRoute.LoadBalancer) | ||||
|             { | ||||
|                 case "RoundRobin": | ||||
|                     return new RoundRobinLoadBalancer(async () => await serviceProvider.Get()); | ||||
|                 case "LeastConnection": | ||||
|                     return new LeastConnectionLoadBalancer(async () => await serviceProvider.Get(), reRoute.ServiceProviderConfiguraion.ServiceName); | ||||
|                     return new LeastConnectionLoadBalancer(async () => await serviceProvider.Get(), reRoute.ServiceName); | ||||
|                 default: | ||||
|                     return new NoLoadBalancer(await serviceProvider.Get()); | ||||
|             } | ||||
|   | ||||
| @@ -1,33 +1,58 @@ | ||||
| using System.Collections.Generic; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Threading.Tasks; | ||||
| using Ocelot.Configuration; | ||||
| using Ocelot.Responses; | ||||
|  | ||||
| namespace Ocelot.LoadBalancer.LoadBalancers | ||||
| { | ||||
|     public class LoadBalancerHouse : ILoadBalancerHouse | ||||
|     { | ||||
|         private readonly ILoadBalancerFactory _factory; | ||||
|         private readonly Dictionary<string, ILoadBalancer> _loadBalancers; | ||||
|  | ||||
|         public LoadBalancerHouse() | ||||
|         public LoadBalancerHouse(ILoadBalancerFactory factory) | ||||
|         { | ||||
|             _factory = factory; | ||||
|             _loadBalancers = new Dictionary<string, ILoadBalancer>(); | ||||
|         } | ||||
|  | ||||
|         public Response<ILoadBalancer> Get(string key) | ||||
|         public async Task<Response<ILoadBalancer>> Get(ReRoute reRoute, ServiceProviderConfiguration config) | ||||
|         { | ||||
|             ILoadBalancer loadBalancer; | ||||
|  | ||||
|             if(_loadBalancers.TryGetValue(key, out loadBalancer)) | ||||
|             try | ||||
|             { | ||||
|                 return new OkResponse<ILoadBalancer>(_loadBalancers[key]); | ||||
|                 ILoadBalancer loadBalancer; | ||||
|  | ||||
|                 if(_loadBalancers.TryGetValue(reRoute.ReRouteKey, out loadBalancer)) | ||||
|                 { | ||||
|                     loadBalancer = _loadBalancers[reRoute.ReRouteKey]; | ||||
|  | ||||
|                     //todo - we have some duplicate namey type logic in the LoadBalancerFactory...maybe we can do something | ||||
|                     //about this.. | ||||
|                     if((reRoute.LoadBalancer == "RoundRobin" && loadBalancer.GetType() != typeof(RoundRobinLoadBalancer)) | ||||
|                         || (reRoute.LoadBalancer == "LeastConnection" && loadBalancer.GetType() != typeof(LeastConnectionLoadBalancer))) | ||||
|                     { | ||||
|                         loadBalancer = await _factory.Get(reRoute, config); | ||||
|                         AddLoadBalancer(reRoute.ReRouteKey, loadBalancer); | ||||
|                     } | ||||
|  | ||||
|                     return new OkResponse<ILoadBalancer>(loadBalancer); | ||||
|                 } | ||||
|  | ||||
|                 loadBalancer = await _factory.Get(reRoute, config); | ||||
|                 AddLoadBalancer(reRoute.ReRouteKey, loadBalancer); | ||||
|                 return new OkResponse<ILoadBalancer>(loadBalancer); | ||||
|             } | ||||
|  | ||||
|                 return new ErrorResponse<ILoadBalancer>(new List<Ocelot.Errors.Error>() | ||||
|             catch(Exception ex) | ||||
|             { | ||||
|                 new UnableToFindLoadBalancerError($"unabe to find load balancer for {key}") | ||||
|             }); | ||||
|                 return new ErrorResponse<ILoadBalancer>(new List<Ocelot.Errors.Error>() | ||||
|                 { | ||||
|                     new UnableToFindLoadBalancerError($"unabe to find load balancer for {reRoute.ReRouteKey} exception is {ex}") | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public Response Add(string key, ILoadBalancer loadBalancer) | ||||
|         private void AddLoadBalancer(string key, ILoadBalancer loadBalancer) | ||||
|         { | ||||
|             if (!_loadBalancers.ContainsKey(key)) | ||||
|             { | ||||
| @@ -36,7 +61,6 @@ namespace Ocelot.LoadBalancer.LoadBalancers | ||||
|  | ||||
|             _loadBalancers.Remove(key); | ||||
|             _loadBalancers.Add(key, loadBalancer); | ||||
|             return new OkResponse(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| using System; | ||||
| using System.Threading.Tasks; | ||||
| using Microsoft.AspNetCore.Http; | ||||
| using Ocelot.Configuration.Provider; | ||||
| using Ocelot.Infrastructure.RequestData; | ||||
| using Ocelot.LoadBalancer.LoadBalancers; | ||||
| using Ocelot.Logging; | ||||
| @@ -11,6 +12,7 @@ namespace Ocelot.LoadBalancer.Middleware | ||||
| { | ||||
|     public class LoadBalancingMiddleware : OcelotMiddleware | ||||
|     { | ||||
|         private readonly IOcelotConfigurationProvider _configProvider; | ||||
|         private readonly RequestDelegate _next; | ||||
|         private readonly IOcelotLogger _logger; | ||||
|         private readonly ILoadBalancerHouse _loadBalancerHouse; | ||||
| @@ -18,9 +20,11 @@ namespace Ocelot.LoadBalancer.Middleware | ||||
|         public LoadBalancingMiddleware(RequestDelegate next, | ||||
|             IOcelotLoggerFactory loggerFactory, | ||||
|             IRequestScopedDataRepository requestScopedDataRepository, | ||||
|             ILoadBalancerHouse loadBalancerHouse)  | ||||
|             ILoadBalancerHouse loadBalancerHouse, | ||||
|             IOcelotConfigurationProvider configProvider)  | ||||
|             : base(requestScopedDataRepository) | ||||
|         { | ||||
|             _configProvider = configProvider; | ||||
|             _next = next; | ||||
|             _logger = loggerFactory.CreateLogger<QueryStringBuilderMiddleware>(); | ||||
|             _loadBalancerHouse = loadBalancerHouse; | ||||
| @@ -28,7 +32,9 @@ namespace Ocelot.LoadBalancer.Middleware | ||||
|  | ||||
|         public async Task Invoke(HttpContext context) | ||||
|         { | ||||
|             var loadBalancer = _loadBalancerHouse.Get(DownstreamRoute.ReRoute.ReRouteKey); | ||||
|             var configuration = await _configProvider.Get();  | ||||
|  | ||||
|             var loadBalancer = await _loadBalancerHouse.Get(DownstreamRoute.ReRoute, configuration.Data.ServiceProviderConfiguration); | ||||
|             if(loadBalancer.IsError) | ||||
|             { | ||||
|                 _logger.LogDebug("there was an error retriving the loadbalancer, setting pipeline error"); | ||||
|   | ||||
| @@ -4,6 +4,6 @@ namespace Ocelot.ServiceDiscovery | ||||
| { | ||||
|     public interface IServiceDiscoveryProviderFactory | ||||
|     { | ||||
|         IServiceDiscoveryProvider Get(ServiceProviderConfiguration serviceConfig); | ||||
|         IServiceDiscoveryProvider Get(ServiceProviderConfiguration serviceConfig, ReRoute reRoute); | ||||
|     } | ||||
| } | ||||
| @@ -6,17 +6,17 @@ namespace Ocelot.ServiceDiscovery | ||||
| { | ||||
|     public class ServiceDiscoveryProviderFactory : IServiceDiscoveryProviderFactory | ||||
|     { | ||||
|         public  IServiceDiscoveryProvider Get(ServiceProviderConfiguration serviceConfig) | ||||
|         public  IServiceDiscoveryProvider Get(ServiceProviderConfiguration serviceConfig, ReRoute reRoute) | ||||
|         { | ||||
|             if (serviceConfig.UseServiceDiscovery) | ||||
|             if (reRoute.UseServiceDiscovery) | ||||
|             { | ||||
|                 return GetServiceDiscoveryProvider(serviceConfig.ServiceName, serviceConfig.ServiceDiscoveryProvider, serviceConfig.ServiceProviderHost, serviceConfig.ServiceProviderPort); | ||||
|                 return GetServiceDiscoveryProvider(reRoute.ServiceName, serviceConfig.ServiceDiscoveryProvider, serviceConfig.ServiceProviderHost, serviceConfig.ServiceProviderPort); | ||||
|             } | ||||
|  | ||||
|             var services = new List<Service>() | ||||
|             { | ||||
|                 new Service(serviceConfig.ServiceName,  | ||||
|                 new HostAndPort(serviceConfig.DownstreamHost, serviceConfig.DownstreamPort), | ||||
|                 new Service(reRoute.ServiceName,  | ||||
|                 new HostAndPort(reRoute.DownstreamHost, reRoute.DownstreamPort), | ||||
|                 string.Empty,  | ||||
|                 string.Empty,  | ||||
|                 new string[0]) | ||||
|   | ||||
| @@ -3,11 +3,13 @@ using System.Collections.Generic; | ||||
| using System.IO; | ||||
| using System.Net; | ||||
| using System.Text; | ||||
| using System.Threading; | ||||
| using Microsoft.AspNetCore.Builder; | ||||
| using Microsoft.AspNetCore.Hosting; | ||||
| using Microsoft.AspNetCore.Http; | ||||
| using Newtonsoft.Json; | ||||
| using Ocelot.Configuration; | ||||
| using Ocelot.Configuration.Builder; | ||||
| using Ocelot.Configuration.File; | ||||
| using Ocelot.ServiceDiscovery; | ||||
| using TestStack.BDDfy; | ||||
| @@ -60,7 +62,7 @@ namespace Ocelot.AcceptanceTests | ||||
|             var consulConfig = new ConsulRegistryConfiguration("localhost", 9500, "Ocelot"); | ||||
|  | ||||
|             this.Given(x => GivenThereIsAFakeConsulServiceDiscoveryProvider(fakeConsulServiceDiscoveryUrl)) | ||||
|                 .And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51779", 200, "Hello from Laura")) | ||||
|                 .And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51779", "", 200, "Hello from Laura")) | ||||
|                 .And(x => _steps.GivenThereIsAConfiguration(configuration)) | ||||
|                 .And(x => _steps.GivenOcelotIsRunningUsingConsulToStoreConfig(consulConfig)) | ||||
|                 .When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) | ||||
| @@ -69,6 +71,69 @@ namespace Ocelot.AcceptanceTests | ||||
|                 .BDDfy(); | ||||
|         } | ||||
|  | ||||
|         [Fact] | ||||
|         public void should_fix_issue_142() | ||||
|         {             | ||||
|             var configuration = new FileConfiguration | ||||
|             { | ||||
|                 ReRoutes = new List<FileReRoute> | ||||
|                     { | ||||
|                     }, | ||||
|                 GlobalConfiguration = new FileGlobalConfiguration() | ||||
|                 { | ||||
|                     ServiceDiscoveryProvider = new FileServiceDiscoveryProvider() | ||||
|                     { | ||||
|                         Provider = "Consul", | ||||
|                         Host = "localhost", | ||||
|                         Port = 9500 | ||||
|                     } | ||||
|                 } | ||||
|             }; | ||||
|  | ||||
|             var fakeConsulServiceDiscoveryUrl = "http://localhost:9500"; | ||||
|  | ||||
|             var consulConfig = new ConsulRegistryConfiguration("localhost", 9500, "Ocelot"); | ||||
|  | ||||
|             var serviceProviderConfig = new ServiceProviderConfigurationBuilder() | ||||
|                 .WithServiceDiscoveryProvider("Consul") | ||||
|                 .WithServiceDiscoveryProviderHost("localhost") | ||||
|                 .WithServiceDiscoveryProviderPort(8500) | ||||
|                 .Build(); | ||||
|  | ||||
|             var reRoute = new ReRouteBuilder() | ||||
|                 .WithDownstreamPathTemplate("/status") | ||||
|                 .WithUpstreamTemplatePattern("^(?i)/cs/status/$") | ||||
|                 .WithDownstreamScheme("http") | ||||
|                 .WithDownstreamHost("localhost") | ||||
|                 .WithDownstreamPort(51779) | ||||
|                 .WithUpstreamPathTemplate("/cs/status") | ||||
|                 .WithUpstreamHttpMethod(new List<string> {"Get"}) | ||||
|                 .WithLoadBalancer("LeastConnection") | ||||
|                 .WithLoadBalancerKey("/cs/status|Get") | ||||
|                 .WithServiceName("") | ||||
|                 .WithUseServiceDiscovery(true) | ||||
|                 .Build(); | ||||
|  | ||||
|             var reRoutes = new List<ReRoute> { reRoute }; | ||||
|              | ||||
|             var config = new OcelotConfiguration(reRoutes, null, serviceProviderConfig); | ||||
|  | ||||
|             this.Given(x => GivenTheConsulConfigurationIs(config)) | ||||
|                 .And(x => GivenThereIsAFakeConsulServiceDiscoveryProvider(fakeConsulServiceDiscoveryUrl)) | ||||
|                 .And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51779", "/status", 200, "Hello from Laura")) | ||||
|                 .And(x => _steps.GivenThereIsAConfiguration(configuration)) | ||||
|                 .And(x => _steps.GivenOcelotIsRunningUsingConsulToStoreConfig(consulConfig)) | ||||
|                 .When(x => _steps.WhenIGetUrlOnTheApiGateway("/cs/status")) | ||||
|                 .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK)) | ||||
|                 .And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura")) | ||||
|                 .BDDfy(); | ||||
|         } | ||||
|  | ||||
|         private void GivenTheConsulConfigurationIs(OcelotConfiguration config) | ||||
|         { | ||||
|             _config = config; | ||||
|         } | ||||
|  | ||||
|         private void GivenThereIsAFakeConsulServiceDiscoveryProvider(string url) | ||||
|         { | ||||
|             _fakeConsulBuilder = new WebHostBuilder() | ||||
| @@ -137,7 +202,7 @@ namespace Ocelot.AcceptanceTests | ||||
|             public string Session => "adf4238a-882b-9ddc-4a9d-5b6758e4159e"; | ||||
|         } | ||||
|  | ||||
|         private void GivenThereIsAServiceRunningOn(string url, int statusCode, string responseBody) | ||||
|         private void GivenThereIsAServiceRunningOn(string url, string basePath, int statusCode, string responseBody) | ||||
|         { | ||||
|             _builder = new WebHostBuilder() | ||||
|                 .UseUrls(url) | ||||
| @@ -147,6 +212,8 @@ namespace Ocelot.AcceptanceTests | ||||
|                 .UseUrls(url) | ||||
|                 .Configure(app => | ||||
|                 { | ||||
|                     app.UsePathBase(basePath); | ||||
|  | ||||
|                     app.Run(async context => | ||||
|                     { | ||||
|                         context.Response.StatusCode = statusCode; | ||||
|   | ||||
							
								
								
									
										0
									
								
								test/Ocelot.AcceptanceTests/RequestId:0HL9635DF6NNV
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								test/Ocelot.AcceptanceTests/RequestId:0HL9635DF6NNV
									
									
									
									
									
										Normal file
									
								
							| @@ -44,7 +44,6 @@ namespace Ocelot.UnitTests.Configuration | ||||
|         private Mock<IRateLimitOptionsCreator> _rateLimitOptions; | ||||
|         private Mock<IRegionCreator> _regionCreator; | ||||
|         private Mock<IHttpHandlerOptionsCreator> _httpHandlerOptionsCreator; | ||||
|         private Mock<ILoadBalancerCreator> _lbCreator; | ||||
|  | ||||
|         public FileConfigurationCreatorTests() | ||||
|         { | ||||
| @@ -65,11 +64,9 @@ namespace Ocelot.UnitTests.Configuration | ||||
|             _rateLimitOptions = new Mock<IRateLimitOptionsCreator>(); | ||||
|             _regionCreator = new Mock<IRegionCreator>(); | ||||
|             _httpHandlerOptionsCreator = new Mock<IHttpHandlerOptionsCreator>(); | ||||
|             _lbCreator = new Mock<ILoadBalancerCreator>(); | ||||
|  | ||||
|             _ocelotConfigurationCreator = new FileOcelotConfigurationCreator(  | ||||
|                 _fileConfig.Object, _validator.Object, _logger.Object, | ||||
|                 _lbCreator.Object,  | ||||
|                 _qosProviderFactory.Object, _qosProviderHouse.Object, _claimsToThingCreator.Object, | ||||
|                 _authOptionsCreator.Object, _upstreamTemplatePatternCreator.Object, _requestIdKeyCreator.Object, | ||||
|                 _serviceProviderConfigCreator.Object, _qosOptionsCreator.Object, _fileReRouteOptionsCreator.Object, | ||||
| @@ -189,32 +186,6 @@ namespace Ocelot.UnitTests.Configuration | ||||
|                 .BDDfy(); | ||||
|         } | ||||
|  | ||||
|         [Fact] | ||||
|         public void should_create_load_balancer() | ||||
|         { | ||||
|             var reRouteOptions = new ReRouteOptionsBuilder() | ||||
|                 .Build(); | ||||
|  | ||||
|             this.Given(x => x.GivenTheConfigIs(new FileConfiguration | ||||
|                             { | ||||
|                                 ReRoutes = new List<FileReRoute> | ||||
|                                 { | ||||
|                                     new FileReRoute | ||||
|                                     { | ||||
|                                         DownstreamHost = "127.0.0.1", | ||||
|                                         UpstreamPathTemplate = "/api/products/{productId}", | ||||
|                                         DownstreamPathTemplate = "/products/{productId}", | ||||
|                                         UpstreamHttpMethod = new List<string> { "Get" }, | ||||
|                                     } | ||||
|                                 }, | ||||
|                             })) | ||||
|                                 .And(x => x.GivenTheConfigIsValid()) | ||||
|                                 .And(x => x.GivenTheFollowingOptionsAreReturned(reRouteOptions)) | ||||
|                                 .When(x => x.WhenICreateTheConfig()) | ||||
|                                 .And(x => x.ThenTheLoadBalancerCreatorIsCalledCorrectly()) | ||||
|                     .BDDfy(); | ||||
|         } | ||||
|  | ||||
|         [Fact] | ||||
|         public void should_use_downstream_host() | ||||
|         { | ||||
| @@ -320,12 +291,8 @@ namespace Ocelot.UnitTests.Configuration | ||||
|                                     .WithDownstreamPathTemplate("/products/{productId}") | ||||
|                                     .WithUpstreamPathTemplate("/api/products/{productId}") | ||||
|                                     .WithUpstreamHttpMethod(new List<string> { "Get" }) | ||||
|                                     .WithServiceProviderConfiguraion(new ServiceProviderConfigurationBuilder() | ||||
|                                         .WithUseServiceDiscovery(true) | ||||
|                                         .WithServiceDiscoveryProvider("consul") | ||||
|                                         .WithServiceDiscoveryProviderHost("127.0.0.1") | ||||
|                                         .WithServiceName("ProductService") | ||||
|                                         .Build()) | ||||
|                                     .WithUseServiceDiscovery(true) | ||||
|                                     .WithServiceName("ProductService") | ||||
|                                     .Build() | ||||
|                             })) | ||||
|                             .BDDfy(); | ||||
| @@ -359,9 +326,7 @@ namespace Ocelot.UnitTests.Configuration | ||||
|                                     .WithDownstreamPathTemplate("/products/{productId}") | ||||
|                                     .WithUpstreamPathTemplate("/api/products/{productId}") | ||||
|                                     .WithUpstreamHttpMethod(new List<string> { "Get" }) | ||||
|                                     .WithServiceProviderConfiguraion(new ServiceProviderConfigurationBuilder() | ||||
|                                         .WithUseServiceDiscovery(false) | ||||
|                                         .Build()) | ||||
|                                     .WithUseServiceDiscovery(false) | ||||
|                                     .Build() | ||||
|                             })) | ||||
|                             .BDDfy(); | ||||
| @@ -604,20 +569,6 @@ namespace Ocelot.UnitTests.Configuration | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         private void ThenTheServiceConfigurationIs(ServiceProviderConfiguration expected) | ||||
|         { | ||||
|             for (int i = 0; i < _config.Data.ReRoutes.Count; i++) | ||||
|             { | ||||
|                 var result = _config.Data.ReRoutes[i]; | ||||
|                 result.ServiceProviderConfiguraion.DownstreamHost.ShouldBe(expected.DownstreamHost); | ||||
|                 result.ServiceProviderConfiguraion.DownstreamPort.ShouldBe(expected.DownstreamPort); | ||||
|                 result.ServiceProviderConfiguraion.ServiceDiscoveryProvider.ShouldBe(expected.ServiceDiscoveryProvider); | ||||
|                 result.ServiceProviderConfiguraion.ServiceName.ShouldBe(expected.ServiceName); | ||||
|                 result.ServiceProviderConfiguraion.ServiceProviderHost.ShouldBe(expected.ServiceProviderHost); | ||||
|                 result.ServiceProviderConfiguraion.ServiceProviderPort.ShouldBe(expected.ServiceProviderPort); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         private void ThenTheAuthenticationOptionsAre(List<ReRoute> expectedReRoutes) | ||||
|         { | ||||
|             for (int i = 0; i < _config.Data.ReRoutes.Count; i++) | ||||
| @@ -628,11 +579,6 @@ namespace Ocelot.UnitTests.Configuration | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         private void ThenTheLoadBalancerCreatorIsCalledCorrectly() | ||||
|         { | ||||
|             _lbCreator.Verify(x => x.SetupLoadBalancer(It.IsAny<ReRoute>()), Times.Once); | ||||
|         } | ||||
|  | ||||
|         private void GivenTheQosProviderFactoryReturns() | ||||
|         { | ||||
|             _qosProviderFactory | ||||
|   | ||||
| @@ -2,6 +2,7 @@ using System; | ||||
| using System.Collections.Generic; | ||||
| using Moq; | ||||
| using Ocelot.Configuration; | ||||
| using Ocelot.Configuration.Builder; | ||||
| using Ocelot.Configuration.Creator; | ||||
| using Ocelot.Configuration.File; | ||||
| using Ocelot.Configuration.Repository; | ||||
| @@ -36,7 +37,8 @@ namespace Ocelot.UnitTests.Configuration | ||||
|         public void should_set_configuration() | ||||
|         { | ||||
|             var fileConfig = new FileConfiguration(); | ||||
|             var config = new OcelotConfiguration(new List<ReRoute>(), string.Empty); | ||||
|             var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build(); | ||||
|             var config = new OcelotConfiguration(new List<ReRoute>(), string.Empty, serviceProviderConfig); | ||||
|  | ||||
|             this.Given(x => GivenTheFollowingConfiguration(fileConfig)) | ||||
|                 .And(x => GivenTheRepoReturns(new OkResponse())) | ||||
|   | ||||
| @@ -92,6 +92,8 @@ namespace Ocelot.UnitTests.Configuration | ||||
|             }; | ||||
|  | ||||
|             public string AdministrationPath {get;} | ||||
|  | ||||
|             public ServiceProviderConfiguration ServiceProviderConfiguration => throw new NotImplementedException(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| using System.Collections.Generic; | ||||
| using Moq; | ||||
| using Ocelot.Configuration; | ||||
| using Ocelot.Configuration.Builder; | ||||
| using Ocelot.Configuration.Creator; | ||||
| using Ocelot.Configuration.Provider; | ||||
| using Ocelot.Configuration.Repository; | ||||
| @@ -27,9 +28,11 @@ namespace Ocelot.UnitTests.Configuration | ||||
|         [Fact] | ||||
|         public void should_get_config() | ||||
|         { | ||||
|             this.Given(x => x.GivenTheRepoReturns(new OkResponse<IOcelotConfiguration>(new OcelotConfiguration(new List<ReRoute>(), string.Empty)))) | ||||
|             var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build(); | ||||
|  | ||||
|             this.Given(x => x.GivenTheRepoReturns(new OkResponse<IOcelotConfiguration>(new OcelotConfiguration(new List<ReRoute>(), string.Empty, serviceProviderConfig)))) | ||||
|                 .When(x => x.WhenIGetTheConfig()) | ||||
|                 .Then(x => x.TheFollowingIsReturned(new OkResponse<IOcelotConfiguration>(new OcelotConfiguration(new List<ReRoute>(), string.Empty)))) | ||||
|                 .Then(x => x.TheFollowingIsReturned(new OkResponse<IOcelotConfiguration>(new OcelotConfiguration(new List<ReRoute>(), string.Empty, serviceProviderConfig)))) | ||||
|                 .BDDfy(); | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -60,15 +60,12 @@ namespace Ocelot.UnitTests.Configuration | ||||
|  | ||||
|         private void WhenICreate() | ||||
|         { | ||||
|             _result = _creator.Create(_reRoute, _globalConfig); | ||||
|             _result = _creator.Create(_globalConfig); | ||||
|         } | ||||
|  | ||||
|         private void ThenTheConfigIs(ServiceProviderConfiguration expected) | ||||
|         { | ||||
|             _result.DownstreamHost.ShouldBe(expected.DownstreamHost); | ||||
|             _result.DownstreamPort.ShouldBe(expected.DownstreamPort); | ||||
|             _result.ServiceDiscoveryProvider.ShouldBe(expected.ServiceDiscoveryProvider); | ||||
|             _result.ServiceName.ShouldBe(expected.ServiceName); | ||||
|             _result.ServiceProviderHost.ShouldBe(expected.ServiceProviderHost); | ||||
|             _result.ServiceProviderPort.ShouldBe(expected.ServiceProviderPort); | ||||
|         } | ||||
|   | ||||
| @@ -36,6 +36,8 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder | ||||
|         [Fact] | ||||
|         public void should_return_route() | ||||
|         { | ||||
|             var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build(); | ||||
|  | ||||
|             this.Given(x => x.GivenThereIsAnUpstreamUrlPath("matchInUrlMatcher/")) | ||||
|                 .And(x =>x.GivenTheTemplateVariableAndNameFinderReturns( | ||||
|                         new OkResponse<List<UrlPathPlaceholderNameAndValue>>( | ||||
| @@ -48,7 +50,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder | ||||
|                         .WithUpstreamHttpMethod(new List<string> { "Get" }) | ||||
|                         .WithUpstreamTemplatePattern("someUpstreamPath") | ||||
|                         .Build() | ||||
|                 }, string.Empty | ||||
|                 }, string.Empty, serviceProviderConfig | ||||
|                 )) | ||||
|                 .And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(true)))) | ||||
|                 .And(x => x.GivenTheUpstreamHttpMethodIs("Get")) | ||||
| @@ -69,6 +71,8 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder | ||||
|         [Fact] | ||||
|         public void should_append_slash_to_upstream_url_path() | ||||
|         { | ||||
|             var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build(); | ||||
|  | ||||
|             this.Given(x => x.GivenThereIsAnUpstreamUrlPath("matchInUrlMatcher")) | ||||
|                 .And(x =>x.GivenTheTemplateVariableAndNameFinderReturns( | ||||
|                         new OkResponse<List<UrlPathPlaceholderNameAndValue>>( | ||||
| @@ -81,7 +85,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder | ||||
|                         .WithUpstreamHttpMethod(new List<string> { "Get" }) | ||||
|                         .WithUpstreamTemplatePattern("someUpstreamPath") | ||||
|                         .Build() | ||||
|                 }, string.Empty | ||||
|                 }, string.Empty, serviceProviderConfig | ||||
|                 )) | ||||
|                 .And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(true)))) | ||||
|                 .And(x => x.GivenTheUpstreamHttpMethodIs("Get")) | ||||
| @@ -101,6 +105,8 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder | ||||
|         [Fact] | ||||
|         public void should_return_route_if_upstream_path_and_upstream_template_are_the_same() | ||||
|         { | ||||
|             var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build(); | ||||
|  | ||||
|             this.Given(x => x.GivenThereIsAnUpstreamUrlPath("someUpstreamPath")) | ||||
|                 .And( | ||||
|                     x => | ||||
| @@ -114,7 +120,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder | ||||
|                         .WithUpstreamHttpMethod(new List<string> { "Get" }) | ||||
|                         .WithUpstreamTemplatePattern("someUpstreamPath") | ||||
|                         .Build() | ||||
|                 }, string.Empty | ||||
|                 }, string.Empty, serviceProviderConfig | ||||
|                     )) | ||||
|                 .And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(true)))) | ||||
|                 .And(x => x.GivenTheUpstreamHttpMethodIs("Get")) | ||||
| @@ -133,6 +139,8 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder | ||||
|         [Fact] | ||||
|         public void should_return_correct_route_for_http_verb() | ||||
|         { | ||||
|             var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build(); | ||||
|  | ||||
|             this.Given(x => x.GivenThereIsAnUpstreamUrlPath("someUpstreamPath")) | ||||
|                 .And( | ||||
|                     x => | ||||
| @@ -152,7 +160,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder | ||||
|                         .WithUpstreamHttpMethod(new List<string> { "Post" }) | ||||
|                         .WithUpstreamTemplatePattern("") | ||||
|                         .Build() | ||||
|                 }, string.Empty | ||||
|                 }, string.Empty, serviceProviderConfig | ||||
|                     )) | ||||
|                 .And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(true)))) | ||||
|                 .And(x => x.GivenTheUpstreamHttpMethodIs("Post")) | ||||
| @@ -169,7 +177,9 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder | ||||
|  | ||||
|         [Fact] | ||||
|         public void should_not_return_route() | ||||
|         { | ||||
|         {             | ||||
|             var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build(); | ||||
|  | ||||
|             this.Given(x => x.GivenThereIsAnUpstreamUrlPath("dontMatchPath/")) | ||||
|                  .And(x => x.GivenTheConfigurationIs(new List<ReRoute> | ||||
|                      { | ||||
| @@ -179,7 +189,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder | ||||
|                         .WithUpstreamHttpMethod(new List<string> { "Get" }) | ||||
|                         .WithUpstreamTemplatePattern("somePath") | ||||
|                         .Build(),    | ||||
|                      }, string.Empty | ||||
|                      }, string.Empty, serviceProviderConfig | ||||
|                  )) | ||||
|                  .And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(false)))) | ||||
|                  .And(x => x.GivenTheUpstreamHttpMethodIs("Get")) | ||||
| @@ -193,6 +203,8 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder | ||||
|         [Fact] | ||||
|         public void should_return_correct_route_for_http_verb_setting_multiple_upstream_http_method() | ||||
|         { | ||||
|             var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build(); | ||||
|  | ||||
|             this.Given(x => x.GivenThereIsAnUpstreamUrlPath("someUpstreamPath")) | ||||
|                 .And( | ||||
|                     x => | ||||
| @@ -206,7 +218,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder | ||||
|                         .WithUpstreamHttpMethod(new List<string> { "Get", "Post" }) | ||||
|                         .WithUpstreamTemplatePattern("") | ||||
|                         .Build() | ||||
|                 }, string.Empty | ||||
|                 }, string.Empty, serviceProviderConfig | ||||
|                     )) | ||||
|                 .And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(true)))) | ||||
|                 .And(x => x.GivenTheUpstreamHttpMethodIs("Post")) | ||||
| @@ -224,6 +236,8 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder | ||||
|         [Fact] | ||||
|         public void should_return_correct_route_for_http_verb_setting_all_upstream_http_method() | ||||
|         { | ||||
|             var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build(); | ||||
|  | ||||
|             this.Given(x => x.GivenThereIsAnUpstreamUrlPath("someUpstreamPath")) | ||||
|                 .And( | ||||
|                     x => | ||||
| @@ -237,7 +251,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder | ||||
|                         .WithUpstreamHttpMethod(new List<string>()) | ||||
|                         .WithUpstreamTemplatePattern("") | ||||
|                         .Build() | ||||
|                 }, string.Empty | ||||
|                 }, string.Empty, serviceProviderConfig | ||||
|                     )) | ||||
|                 .And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(true)))) | ||||
|                 .And(x => x.GivenTheUpstreamHttpMethodIs("Post")) | ||||
| @@ -255,6 +269,8 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder | ||||
|         [Fact] | ||||
|         public void should_not_return_route_for_http_verb_not_setting_in_upstream_http_method() | ||||
|         { | ||||
|             var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build(); | ||||
|  | ||||
|             this.Given(x => x.GivenThereIsAnUpstreamUrlPath("someUpstreamPath")) | ||||
|                 .And( | ||||
|                     x => | ||||
| @@ -268,7 +284,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder | ||||
|                         .WithUpstreamHttpMethod(new List<string> { "Get", "Patch", "Delete" }) | ||||
|                         .WithUpstreamTemplatePattern("") | ||||
|                         .Build() | ||||
|                 }, string.Empty | ||||
|                 }, string.Empty, serviceProviderConfig | ||||
|                     )) | ||||
|                 .And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(true)))) | ||||
|                 .And(x => x.GivenTheUpstreamHttpMethodIs("Post")) | ||||
| @@ -322,12 +338,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder | ||||
|                 .Returns(_match); | ||||
|         } | ||||
|  | ||||
|         private void GivenTheConfigurationIs(List<ReRoute> reRoutesConfig, string adminPath) | ||||
|         private void GivenTheConfigurationIs(List<ReRoute> reRoutesConfig, string adminPath, ServiceProviderConfiguration serviceProviderConfig) | ||||
|         { | ||||
|             _reRoutesConfig = reRoutesConfig; | ||||
|             _mockConfig | ||||
|                 .Setup(x => x.Get()) | ||||
|                 .ReturnsAsync(new OkResponse<IOcelotConfiguration>(new OcelotConfiguration(_reRoutesConfig, adminPath))); | ||||
|                 .ReturnsAsync(new OkResponse<IOcelotConfiguration>(new OcelotConfiguration(_reRoutesConfig, adminPath, serviceProviderConfig))); | ||||
|         } | ||||
|  | ||||
|         private void GivenThereIsAnUpstreamUrlPath(string upstreamUrlPath) | ||||
|   | ||||
| @@ -1,57 +0,0 @@ | ||||
| using Xunit; | ||||
| using Shouldly; | ||||
| using TestStack.BDDfy; | ||||
| using Ocelot.LoadBalancer; | ||||
| using Ocelot.LoadBalancer.LoadBalancers; | ||||
| using Moq; | ||||
| using Ocelot.Configuration; | ||||
| using System.Collections.Generic; | ||||
| using Ocelot.Values; | ||||
| using Ocelot.Configuration.Builder; | ||||
|  | ||||
| namespace Ocelot.UnitTests.LoadBalancer | ||||
| { | ||||
|     public class LoadBalancerCreatorTests | ||||
|     { | ||||
|         private LoadBalancerCreator _creator; | ||||
|         private ILoadBalancerHouse _house; | ||||
|         private Mock<ILoadBalancerFactory> _factory; | ||||
|         private ReRoute _reRoute; | ||||
|  | ||||
|         public LoadBalancerCreatorTests() | ||||
|         { | ||||
|             _house = new LoadBalancerHouse(); | ||||
|             _factory = new Mock<ILoadBalancerFactory>(); | ||||
|             _creator = new LoadBalancerCreator(_house, _factory.Object); | ||||
|         } | ||||
|  | ||||
|         [Fact] | ||||
|         public void should_create_load_balancer() | ||||
|         { | ||||
|             var reRoute = new ReRouteBuilder().WithLoadBalancerKey("Test").Build(); | ||||
|             this.Given(x => GivenTheFollowingReRoute(reRoute)) | ||||
|                 .When(x => WhenICallTheCreator()) | ||||
|                 .Then(x => x.ThenTheLoadBalancerIsCreated()) | ||||
|                 .BDDfy(); | ||||
|         } | ||||
|  | ||||
|         private void GivenTheFollowingReRoute(ReRoute reRoute) | ||||
|         { | ||||
|             _reRoute = reRoute; | ||||
|             _factory | ||||
|                 .Setup(x => x.Get(It.IsAny<ReRoute>())) | ||||
|                 .ReturnsAsync(new NoLoadBalancer(new List<Service>())); | ||||
|         } | ||||
|  | ||||
|         private void WhenICallTheCreator() | ||||
|         { | ||||
|             _creator.SetupLoadBalancer(_reRoute).Wait(); | ||||
|         } | ||||
|  | ||||
|         private void ThenTheLoadBalancerIsCreated() | ||||
|         { | ||||
|             var lb = _house.Get(_reRoute.ReRouteKey); | ||||
|             lb.ShouldNotBeNull(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -17,7 +17,8 @@ namespace Ocelot.UnitTests.LoadBalancer | ||||
|         private ILoadBalancer _result; | ||||
|         private Mock<IServiceDiscoveryProviderFactory> _serviceProviderFactory; | ||||
|         private Mock<IServiceDiscoveryProvider> _serviceProvider; | ||||
|          | ||||
|         private ServiceProviderConfiguration _serviceProviderConfig; | ||||
|  | ||||
|         public LoadBalancerFactoryTests() | ||||
|         { | ||||
|             _serviceProviderFactory = new Mock<IServiceDiscoveryProviderFactory>(); | ||||
| @@ -29,11 +30,11 @@ namespace Ocelot.UnitTests.LoadBalancer | ||||
|         public void should_return_no_load_balancer() | ||||
|         { | ||||
|             var reRoute = new ReRouteBuilder() | ||||
|                 .WithServiceProviderConfiguraion(new ServiceProviderConfigurationBuilder().Build()) | ||||
|                 .WithUpstreamHttpMethod(new List<string> { "Get" }) | ||||
|                 .Build(); | ||||
|  | ||||
|             this.Given(x => x.GivenAReRoute(reRoute)) | ||||
|                 .And(x => GivenAServiceProviderConfig(new ServiceProviderConfigurationBuilder().Build())) | ||||
|                 .And(x => x.GivenTheServiceProviderFactoryReturns()) | ||||
|                 .When(x => x.WhenIGetTheLoadBalancer()) | ||||
|                 .Then(x => x.ThenTheLoadBalancerIsReturned<NoLoadBalancer>()) | ||||
| @@ -46,10 +47,10 @@ namespace Ocelot.UnitTests.LoadBalancer | ||||
|              var reRoute = new ReRouteBuilder() | ||||
|                 .WithLoadBalancer("RoundRobin") | ||||
|                 .WithUpstreamHttpMethod(new List<string> { "Get" }) | ||||
|                 .WithServiceProviderConfiguraion(new ServiceProviderConfigurationBuilder().Build()) | ||||
|                 .Build(); | ||||
|  | ||||
|             this.Given(x => x.GivenAReRoute(reRoute)) | ||||
|                 .And(x => GivenAServiceProviderConfig(new ServiceProviderConfigurationBuilder().Build())) | ||||
|                 .And(x => x.GivenTheServiceProviderFactoryReturns()) | ||||
|                 .When(x => x.WhenIGetTheLoadBalancer()) | ||||
|                 .Then(x => x.ThenTheLoadBalancerIsReturned<RoundRobinLoadBalancer>()) | ||||
| @@ -62,10 +63,10 @@ namespace Ocelot.UnitTests.LoadBalancer | ||||
|              var reRoute = new ReRouteBuilder() | ||||
|                 .WithLoadBalancer("LeastConnection") | ||||
|                 .WithUpstreamHttpMethod(new List<string> { "Get" }) | ||||
|                 .WithServiceProviderConfiguraion(new ServiceProviderConfigurationBuilder().Build()) | ||||
|                 .Build(); | ||||
|  | ||||
|             this.Given(x => x.GivenAReRoute(reRoute)) | ||||
|                 .And(x => GivenAServiceProviderConfig(new ServiceProviderConfigurationBuilder().Build())) | ||||
|                 .And(x => x.GivenTheServiceProviderFactoryReturns()) | ||||
|                 .When(x => x.WhenIGetTheLoadBalancer()) | ||||
|                 .Then(x => x.ThenTheLoadBalancerIsReturned<LeastConnectionLoadBalancer>()) | ||||
| @@ -78,27 +79,32 @@ namespace Ocelot.UnitTests.LoadBalancer | ||||
|             var reRoute = new ReRouteBuilder() | ||||
|                 .WithLoadBalancer("RoundRobin") | ||||
|                 .WithUpstreamHttpMethod(new List<string> { "Get" }) | ||||
|                 .WithServiceProviderConfiguraion(new ServiceProviderConfigurationBuilder().Build()) | ||||
|                 .Build(); | ||||
|  | ||||
|             this.Given(x => x.GivenAReRoute(reRoute)) | ||||
|                 .And(x => GivenAServiceProviderConfig(new ServiceProviderConfigurationBuilder().Build())) | ||||
|                 .And(x => x.GivenTheServiceProviderFactoryReturns()) | ||||
|                 .When(x => x.WhenIGetTheLoadBalancer()) | ||||
|                 .Then(x => x.ThenTheServiceProviderIsCalledCorrectly()) | ||||
|                 .BDDfy(); | ||||
|         } | ||||
|  | ||||
|         private void GivenAServiceProviderConfig(ServiceProviderConfiguration serviceProviderConfig) | ||||
|         { | ||||
|             _serviceProviderConfig = serviceProviderConfig; | ||||
|         } | ||||
|  | ||||
|         private void GivenTheServiceProviderFactoryReturns() | ||||
|         { | ||||
|             _serviceProviderFactory | ||||
|                 .Setup(x => x.Get(It.IsAny<ServiceProviderConfiguration>())) | ||||
|                 .Setup(x => x.Get(It.IsAny<ServiceProviderConfiguration>(), It.IsAny<ReRoute>())) | ||||
|                 .Returns(_serviceProvider.Object); | ||||
|         } | ||||
|  | ||||
|         private void ThenTheServiceProviderIsCalledCorrectly() | ||||
|         { | ||||
|             _serviceProviderFactory | ||||
|                 .Verify(x => x.Get(It.IsAny<ServiceProviderConfiguration>()), Times.Once); | ||||
|                 .Verify(x => x.Get(It.IsAny<ServiceProviderConfiguration>(), It.IsAny<ReRoute>()), Times.Once); | ||||
|         } | ||||
|  | ||||
|         private void GivenAReRoute(ReRoute reRoute) | ||||
| @@ -108,7 +114,7 @@ namespace Ocelot.UnitTests.LoadBalancer | ||||
|  | ||||
|         private void WhenIGetTheLoadBalancer() | ||||
|         { | ||||
|             _result = _factory.Get(_reRoute).Result; | ||||
|             _result = _factory.Get(_reRoute, _serviceProviderConfig).Result; | ||||
|         } | ||||
|  | ||||
|         private void ThenTheLoadBalancerIsReturned<T>() | ||||
|   | ||||
| @@ -1,5 +1,8 @@ | ||||
| using System; | ||||
| using System.Threading.Tasks; | ||||
| using Moq; | ||||
| using Ocelot.Configuration; | ||||
| using Ocelot.Configuration.Builder; | ||||
| using Ocelot.LoadBalancer.LoadBalancers; | ||||
| using Ocelot.Responses; | ||||
| using Ocelot.Values; | ||||
| @@ -11,35 +14,38 @@ namespace Ocelot.UnitTests.LoadBalancer | ||||
| { | ||||
|     public class LoadBalancerHouseTests | ||||
|     { | ||||
|         private ReRoute _reRoute; | ||||
|         private ILoadBalancer _loadBalancer; | ||||
|         private readonly LoadBalancerHouse _loadBalancerHouse; | ||||
|         private Response _addResult; | ||||
|         private Response<ILoadBalancer> _getResult; | ||||
|         private string _key; | ||||
|         private Mock<ILoadBalancerFactory> _factory; | ||||
|         private ServiceProviderConfiguration _serviceProviderConfig; | ||||
|  | ||||
|         public LoadBalancerHouseTests() | ||||
|         { | ||||
|             _loadBalancerHouse = new LoadBalancerHouse(); | ||||
|             _factory = new Mock<ILoadBalancerFactory>(); | ||||
|             _loadBalancerHouse = new LoadBalancerHouse(_factory.Object); | ||||
|         } | ||||
|  | ||||
|         [Fact] | ||||
|         public void should_store_load_balancer() | ||||
|         public void should_store_load_balancer_on_first_request() | ||||
|         { | ||||
|             var key = "test"; | ||||
|             var reRoute = new ReRouteBuilder().WithLoadBalancerKey("test").Build(); | ||||
|  | ||||
|             this.Given(x => x.GivenThereIsALoadBalancer(key, new FakeLoadBalancer())) | ||||
|                 .When(x => x.WhenIAddTheLoadBalancer()) | ||||
|             this.Given(x => x.GivenThereIsALoadBalancer(reRoute, new FakeLoadBalancer())) | ||||
|                 .Then(x => x.ThenItIsAdded()) | ||||
|                 .BDDfy(); | ||||
|         } | ||||
|  | ||||
|         [Fact] | ||||
|         public void should_get_load_balancer() | ||||
|         public void should_not_store_load_balancer_on_second_request() | ||||
|         { | ||||
|             var key = "test"; | ||||
|             var reRoute = new ReRouteBuilder().WithLoadBalancerKey("test").Build(); | ||||
|  | ||||
|             this.Given(x => x.GivenThereIsALoadBalancer(key, new FakeLoadBalancer())) | ||||
|                 .When(x => x.WhenWeGetTheLoadBalancer(key)) | ||||
|             this.Given(x => x.GivenThereIsALoadBalancer(reRoute, new FakeLoadBalancer())) | ||||
|                 .When(x => x.WhenWeGetTheLoadBalancer(reRoute)) | ||||
|                 .Then(x => x.ThenItIsReturned()) | ||||
|                 .BDDfy(); | ||||
|         } | ||||
| @@ -47,26 +53,50 @@ namespace Ocelot.UnitTests.LoadBalancer | ||||
|         [Fact] | ||||
|         public void should_store_load_balancers_by_key() | ||||
|         { | ||||
|             var key = "test"; | ||||
|             var keyTwo = "testTwo"; | ||||
|             var reRoute = new ReRouteBuilder().WithLoadBalancerKey("test").Build(); | ||||
|             var reRouteTwo = new ReRouteBuilder().WithLoadBalancerKey("testtwo").Build(); | ||||
|  | ||||
|             this.Given(x => x.GivenThereIsALoadBalancer(key, new FakeLoadBalancer())) | ||||
|                 .And(x => x.GivenThereIsALoadBalancer(keyTwo, new FakeRoundRobinLoadBalancer())) | ||||
|                 .When(x => x.WhenWeGetTheLoadBalancer(key)) | ||||
|             this.Given(x => x.GivenThereIsALoadBalancer(reRoute, new FakeLoadBalancer())) | ||||
|                 .And(x => x.GivenThereIsALoadBalancer(reRouteTwo, new FakeRoundRobinLoadBalancer())) | ||||
|                 .When(x => x.WhenWeGetTheLoadBalancer(reRoute)) | ||||
|                 .Then(x => x.ThenTheLoadBalancerIs<FakeLoadBalancer>()) | ||||
|                 .When(x => x.WhenWeGetTheLoadBalancer(keyTwo)) | ||||
|                 .When(x => x.WhenWeGetTheLoadBalancer(reRouteTwo)) | ||||
|                 .Then(x => x.ThenTheLoadBalancerIs<FakeRoundRobinLoadBalancer>()) | ||||
|                 .BDDfy(); | ||||
|         } | ||||
|  | ||||
|         [Fact] | ||||
|         public void should_return_error_if_no_load_balancer_with_key() | ||||
|         public void should_return_error_if_exception() | ||||
|         { | ||||
|             this.When(x => x.WhenWeGetTheLoadBalancer("test")) | ||||
|             var reRoute = new ReRouteBuilder().Build(); | ||||
|  | ||||
|             this.When(x => x.WhenWeGetTheLoadBalancer(reRoute)) | ||||
|             .Then(x => x.ThenAnErrorIsReturned()) | ||||
|             .BDDfy(); | ||||
|         } | ||||
|  | ||||
|         [Fact] | ||||
|         public void should_get_new_load_balancer_if_reroute_load_balancer_has_changed() | ||||
|         { | ||||
|             var reRoute = new ReRouteBuilder().WithLoadBalancerKey("test").Build(); | ||||
|  | ||||
|             var reRouteTwo = new ReRouteBuilder().WithLoadBalancer("LeastConnection").WithLoadBalancerKey("test").Build(); | ||||
|  | ||||
|             this.Given(x => x.GivenThereIsALoadBalancer(reRoute, new FakeLoadBalancer())) | ||||
|                 .When(x => x.WhenWeGetTheLoadBalancer(reRoute)) | ||||
|                 .Then(x => x.ThenTheLoadBalancerIs<FakeLoadBalancer>()) | ||||
|                 .When(x => x.WhenIGetTheReRouteWithTheSameKeyButDifferentLoadBalancer(reRouteTwo)) | ||||
|                 .Then(x => x.ThenTheLoadBalancerIs<LeastConnectionLoadBalancer>()) | ||||
|                 .BDDfy(); | ||||
|         } | ||||
|  | ||||
|         private void WhenIGetTheReRouteWithTheSameKeyButDifferentLoadBalancer(ReRoute reRoute) | ||||
|         { | ||||
|             _reRoute = reRoute; | ||||
|             _factory.Setup(x => x.Get(_reRoute, _serviceProviderConfig)).ReturnsAsync(new LeastConnectionLoadBalancer(null, null)); | ||||
|             _getResult = _loadBalancerHouse.Get(_reRoute, _serviceProviderConfig).Result; | ||||
|         } | ||||
|  | ||||
|          private void ThenAnErrorIsReturned() | ||||
|         { | ||||
|             _getResult.IsError.ShouldBeTrue(); | ||||
| @@ -80,31 +110,30 @@ namespace Ocelot.UnitTests.LoadBalancer | ||||
|  | ||||
|         private void ThenItIsAdded() | ||||
|         { | ||||
|             _addResult.IsError.ShouldBe(false); | ||||
|             _addResult.ShouldBeOfType<OkResponse>(); | ||||
|         } | ||||
|  | ||||
|         private void WhenIAddTheLoadBalancer() | ||||
|         { | ||||
|             _addResult = _loadBalancerHouse.Add(_key, _loadBalancer); | ||||
|             _getResult.IsError.ShouldBe(false); | ||||
|             _getResult.ShouldBeOfType<OkResponse<ILoadBalancer>>(); | ||||
|             _getResult.Data.ShouldBe(_loadBalancer); | ||||
|             _factory.Verify(x => x.Get(_reRoute, _serviceProviderConfig), Times.Once); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         private void GivenThereIsALoadBalancer(string key, ILoadBalancer loadBalancer) | ||||
|         private void GivenThereIsALoadBalancer(ReRoute reRoute, ILoadBalancer loadBalancer) | ||||
|         { | ||||
|             _key = key; | ||||
|             _reRoute = reRoute; | ||||
|             _loadBalancer = loadBalancer; | ||||
|             WhenIAddTheLoadBalancer(); | ||||
|             _factory.Setup(x => x.Get(_reRoute, _serviceProviderConfig)).ReturnsAsync(loadBalancer); | ||||
|             _getResult = _loadBalancerHouse.Get(reRoute, _serviceProviderConfig).Result; | ||||
|         } | ||||
|  | ||||
|         private void WhenWeGetTheLoadBalancer(string key) | ||||
|         private void WhenWeGetTheLoadBalancer(ReRoute reRoute) | ||||
|         { | ||||
|             _getResult = _loadBalancerHouse.Get(key); | ||||
|             _getResult = _loadBalancerHouse.Get(reRoute, _serviceProviderConfig).Result; | ||||
|         } | ||||
|  | ||||
|         private void ThenItIsReturned() | ||||
|         { | ||||
|             _getResult.Data.ShouldBe(_loadBalancer); | ||||
|             _factory.Verify(x => x.Get(_reRoute, _serviceProviderConfig), Times.Once); | ||||
|         } | ||||
|  | ||||
|         class FakeLoadBalancer : ILoadBalancer | ||||
|   | ||||
| @@ -5,6 +5,7 @@ namespace Ocelot.UnitTests.LoadBalancer | ||||
|     using Microsoft.AspNetCore.Builder; | ||||
|     using Microsoft.Extensions.DependencyInjection; | ||||
|     using Moq; | ||||
|     using Ocelot.Configuration; | ||||
|     using Ocelot.Configuration.Builder; | ||||
|     using Ocelot.DownstreamRouteFinder; | ||||
|     using Ocelot.Errors; | ||||
| @@ -137,8 +138,8 @@ namespace Ocelot.UnitTests.LoadBalancer | ||||
|         private void GivenTheLoadBalancerHouseReturns() | ||||
|         { | ||||
|             _loadBalancerHouse | ||||
|                 .Setup(x => x.Get(It.IsAny<string>())) | ||||
|                 .Returns(new OkResponse<ILoadBalancer>(_loadBalancer.Object)); | ||||
|                 .Setup(x => x.Get(It.IsAny<ReRoute>(), It.IsAny<ServiceProviderConfiguration>())) | ||||
|                 .ReturnsAsync(new OkResponse<ILoadBalancer>(_loadBalancer.Object)); | ||||
|         } | ||||
|  | ||||
|         private void GivenTheLoadBalancerHouseReturnsAnError() | ||||
| @@ -149,8 +150,8 @@ namespace Ocelot.UnitTests.LoadBalancer | ||||
|             }); | ||||
|  | ||||
|             _loadBalancerHouse | ||||
|                 .Setup(x => x.Get(It.IsAny<string>())) | ||||
|                 .Returns(_getLoadBalancerHouseError); | ||||
|                 .Setup(x => x.Get(It.IsAny<ReRoute>(), It.IsAny<ServiceProviderConfiguration>())) | ||||
|                 .ReturnsAsync(_getLoadBalancerHouseError); | ||||
|         } | ||||
|  | ||||
|         private void ThenAnErrorStatingLoadBalancerCouldNotBeFoundIsSetOnPipeline() | ||||
|   | ||||
| @@ -12,6 +12,7 @@ namespace Ocelot.UnitTests.ServiceDiscovery | ||||
|         private ServiceProviderConfiguration _serviceConfig; | ||||
|         private IServiceDiscoveryProvider _result; | ||||
|         private readonly ServiceDiscoveryProviderFactory _factory; | ||||
|         private ReRoute _reRoute; | ||||
|  | ||||
|         public ServiceProviderFactoryTests() | ||||
|         { | ||||
| @@ -22,12 +23,11 @@ namespace Ocelot.UnitTests.ServiceDiscovery | ||||
|         public void should_return_no_service_provider() | ||||
|         { | ||||
|             var serviceConfig = new ServiceProviderConfigurationBuilder() | ||||
|                 .WithDownstreamHost("127.0.0.1") | ||||
|                 .WithDownstreamPort(80) | ||||
|                 .WithUseServiceDiscovery(false) | ||||
|                 .Build(); | ||||
|  | ||||
|             this.Given(x => x.GivenTheReRoute(serviceConfig)) | ||||
|             var reRoute = new ReRouteBuilder().Build(); | ||||
|  | ||||
|             this.Given(x => x.GivenTheReRoute(serviceConfig, reRoute)) | ||||
|                 .When(x => x.WhenIGetTheServiceProvider()) | ||||
|                 .Then(x => x.ThenTheServiceProviderIs<ConfigurationServiceProvider>()) | ||||
|                 .BDDfy(); | ||||
| @@ -36,26 +36,30 @@ namespace Ocelot.UnitTests.ServiceDiscovery | ||||
|         [Fact] | ||||
|         public void should_return_consul_service_provider() | ||||
|         { | ||||
|             var serviceConfig = new ServiceProviderConfigurationBuilder() | ||||
|             var reRoute = new ReRouteBuilder() | ||||
|                 .WithServiceName("product") | ||||
|                 .WithUseServiceDiscovery(true) | ||||
|                 .Build(); | ||||
|  | ||||
|             var serviceConfig = new ServiceProviderConfigurationBuilder() | ||||
|                 .WithServiceDiscoveryProvider("Consul") | ||||
|                 .Build(); | ||||
|  | ||||
|             this.Given(x => x.GivenTheReRoute(serviceConfig)) | ||||
|             this.Given(x => x.GivenTheReRoute(serviceConfig, reRoute)) | ||||
|                 .When(x => x.WhenIGetTheServiceProvider()) | ||||
|                 .Then(x => x.ThenTheServiceProviderIs<ConsulServiceDiscoveryProvider>()) | ||||
|                 .BDDfy(); | ||||
|         } | ||||
|  | ||||
|         private void GivenTheReRoute(ServiceProviderConfiguration serviceConfig) | ||||
|         private void GivenTheReRoute(ServiceProviderConfiguration serviceConfig, ReRoute reRoute) | ||||
|         { | ||||
|             _serviceConfig = serviceConfig; | ||||
|             _reRoute = reRoute; | ||||
|         } | ||||
|  | ||||
|         private void WhenIGetTheServiceProvider() | ||||
|         { | ||||
|             _result = _factory.Get(_serviceConfig); | ||||
|             _result = _factory.Get(_serviceConfig, _reRoute); | ||||
|         } | ||||
|  | ||||
|         private void ThenTheServiceProviderIs<T>() | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Tom Gardham-Pallister
					Tom Gardham-Pallister