mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-11-04 15:10:50 +08:00 
			
		
		
		
	merge newest code for develop
This commit is contained in:
		@@ -1,23 +1,19 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using Ocelot.Values;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration.Builder
 | 
			
		||||
{
 | 
			
		||||
    public class ReRouteBuilder
 | 
			
		||||
    {
 | 
			
		||||
        private AuthenticationOptions _authenticationOptions;
 | 
			
		||||
        private string _loadBalancerKey;
 | 
			
		||||
        private string _downstreamPathTemplate;
 | 
			
		||||
        private string _upstreamTemplate;
 | 
			
		||||
        private string _upstreamTemplatePattern;
 | 
			
		||||
        private string _upstreamHttpMethod;
 | 
			
		||||
        private bool _isAuthenticated;
 | 
			
		||||
        private string _authenticationProvider;
 | 
			
		||||
        private string _authenticationProviderUrl;
 | 
			
		||||
        private string _scopeName;
 | 
			
		||||
        private List<string> _additionalScopes;
 | 
			
		||||
        private bool _requireHttps;
 | 
			
		||||
        private string _scopeSecret;
 | 
			
		||||
        private List<ClaimToThing> _configHeaderExtractorProperties;
 | 
			
		||||
        private List<ClaimToThing> _claimToClaims;
 | 
			
		||||
        private Dictionary<string, string> _routeClaimRequirement;
 | 
			
		||||
@@ -26,29 +22,19 @@ namespace Ocelot.Configuration.Builder
 | 
			
		||||
        private string _requestIdHeaderKey;
 | 
			
		||||
        private bool _isCached;
 | 
			
		||||
        private CacheOptions _fileCacheOptions;
 | 
			
		||||
        private bool _useServiceDiscovery;
 | 
			
		||||
        private string _serviceName;
 | 
			
		||||
        private string _serviceDiscoveryProvider;
 | 
			
		||||
        private string _serviceDiscoveryAddress;
 | 
			
		||||
        private string _downstreamScheme;
 | 
			
		||||
        private string _downstreamHost;
 | 
			
		||||
        private int _dsPort;
 | 
			
		||||
        private int _downstreamPort;
 | 
			
		||||
        private string _loadBalancer;
 | 
			
		||||
        private string _serviceProviderHost;
 | 
			
		||||
        private int _serviceProviderPort;
 | 
			
		||||
        private ServiceProviderConfiguraion _serviceProviderConfiguraion;
 | 
			
		||||
        private bool _useQos;
 | 
			
		||||
        private QoSOptions _qosOptions;
 | 
			
		||||
        public bool _enableRateLimiting;
 | 
			
		||||
        public RateLimitOptions _rateLimitOptions;
 | 
			
		||||
 | 
			
		||||
        public ReRouteBuilder()
 | 
			
		||||
        {
 | 
			
		||||
            _additionalScopes = new List<string>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ReRouteBuilder WithLoadBalancer(string loadBalancer)
 | 
			
		||||
        {
 | 
			
		||||
            _loadBalancer = loadBalancer;
 | 
			
		||||
          _loadBalancer = loadBalancer;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -64,37 +50,13 @@ namespace Ocelot.Configuration.Builder
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ReRouteBuilder WithServiceDiscoveryAddress(string serviceDiscoveryAddress)
 | 
			
		||||
        {
 | 
			
		||||
            _serviceDiscoveryAddress = serviceDiscoveryAddress;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ReRouteBuilder WithServiceDiscoveryProvider(string serviceDiscoveryProvider)
 | 
			
		||||
        {
 | 
			
		||||
            _serviceDiscoveryProvider = serviceDiscoveryProvider;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ReRouteBuilder WithServiceName(string serviceName)
 | 
			
		||||
        {
 | 
			
		||||
            _serviceName = serviceName;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ReRouteBuilder WithUseServiceDiscovery(bool useServiceDiscovery)
 | 
			
		||||
        {
 | 
			
		||||
            _useServiceDiscovery = useServiceDiscovery;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ReRouteBuilder WithDownstreamPathTemplate(string input)
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamPathTemplate = input;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ReRouteBuilder WithUpstreamTemplate(string input)
 | 
			
		||||
        public ReRouteBuilder WithUpstreamPathTemplate(string input)
 | 
			
		||||
        {
 | 
			
		||||
            _upstreamTemplate = input;
 | 
			
		||||
            return this;
 | 
			
		||||
@@ -122,42 +84,6 @@ namespace Ocelot.Configuration.Builder
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ReRouteBuilder WithAuthenticationProvider(string input)
 | 
			
		||||
        {
 | 
			
		||||
            _authenticationProvider = input;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ReRouteBuilder WithAuthenticationProviderUrl(string input)
 | 
			
		||||
        {
 | 
			
		||||
            _authenticationProviderUrl = input;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ReRouteBuilder WithAuthenticationProviderScopeName(string input)
 | 
			
		||||
        {
 | 
			
		||||
            _scopeName = input;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ReRouteBuilder WithAuthenticationProviderAdditionalScopes(List<string> input)
 | 
			
		||||
        {
 | 
			
		||||
            _additionalScopes = input;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ReRouteBuilder WithRequireHttps(bool input)
 | 
			
		||||
        {
 | 
			
		||||
            _requireHttps = input;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ReRouteBuilder WithScopeSecret(string input)
 | 
			
		||||
        {
 | 
			
		||||
            _scopeSecret = input;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ReRouteBuilder WithRequestIdKey(string input)
 | 
			
		||||
        {
 | 
			
		||||
            _requestIdHeaderKey = input;
 | 
			
		||||
@@ -202,7 +128,7 @@ namespace Ocelot.Configuration.Builder
 | 
			
		||||
 | 
			
		||||
        public ReRouteBuilder WithDownstreamPort(int port)
 | 
			
		||||
        {
 | 
			
		||||
            _dsPort = port;
 | 
			
		||||
            _downstreamPort = port;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -225,15 +151,15 @@ namespace Ocelot.Configuration.Builder
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ReRouteBuilder WithServiceProviderHost(string serviceProviderHost)
 | 
			
		||||
        public ReRouteBuilder WithServiceProviderConfiguraion(ServiceProviderConfiguraion serviceProviderConfiguraion)
 | 
			
		||||
        {
 | 
			
		||||
            _serviceProviderHost = serviceProviderHost;
 | 
			
		||||
            _serviceProviderConfiguraion = serviceProviderConfiguraion;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ReRouteBuilder WithServiceProviderPort(int serviceProviderPort)
 | 
			
		||||
        public ReRouteBuilder WithAuthenticationOptions(AuthenticationOptions authenticationOptions)
 | 
			
		||||
        {
 | 
			
		||||
            _serviceProviderPort = serviceProviderPort;
 | 
			
		||||
            _authenticationOptions = authenticationOptions;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -252,14 +178,31 @@ namespace Ocelot.Configuration.Builder
 | 
			
		||||
 | 
			
		||||
        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, _downstreamScheme, _loadBalancer,
 | 
			
		||||
                _downstreamHost, _dsPort, _loadBalancerKey, new ServiceProviderConfiguraion(_serviceName, _downstreamHost, _dsPort, _useServiceDiscovery,
 | 
			
		||||
                _serviceDiscoveryProvider, _serviceProviderHost, _serviceProviderPort),
 | 
			
		||||
                _useQos,_qosOptions,_enableRateLimiting,_rateLimitOptions);
 | 
			
		||||
 | 
			
		||||
            return new ReRoute(
 | 
			
		||||
                new PathTemplate(_downstreamPathTemplate), 
 | 
			
		||||
                new PathTemplate(_upstreamTemplate), 
 | 
			
		||||
                new HttpMethod(_upstreamHttpMethod), 
 | 
			
		||||
                _upstreamTemplatePattern, 
 | 
			
		||||
                _isAuthenticated, 
 | 
			
		||||
                _authenticationOptions,
 | 
			
		||||
                _configHeaderExtractorProperties, 
 | 
			
		||||
                _claimToClaims, 
 | 
			
		||||
                _routeClaimRequirement, 
 | 
			
		||||
                _isAuthorised, 
 | 
			
		||||
                _claimToQueries, 
 | 
			
		||||
                _requestIdHeaderKey, 
 | 
			
		||||
                _isCached, 
 | 
			
		||||
                _fileCacheOptions, 
 | 
			
		||||
                _downstreamScheme, 
 | 
			
		||||
                _loadBalancer,
 | 
			
		||||
                _downstreamHost, 
 | 
			
		||||
                _downstreamPort, 
 | 
			
		||||
                _loadBalancerKey, 
 | 
			
		||||
                _serviceProviderConfiguraion, 
 | 
			
		||||
                _useQos, 
 | 
			
		||||
                _qosOptions,
 | 
			
		||||
                _enableRateLimiting,
 | 
			
		||||
                _rateLimitOptions);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,13 +4,14 @@ using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Microsoft.Extensions.Logging;
 | 
			
		||||
using Microsoft.Extensions.Options;
 | 
			
		||||
using Ocelot.Configuration.Builder;
 | 
			
		||||
using Ocelot.Configuration.File;
 | 
			
		||||
using Ocelot.Configuration.Parser;
 | 
			
		||||
using Ocelot.Configuration.Validator;
 | 
			
		||||
using Ocelot.LoadBalancer.LoadBalancers;
 | 
			
		||||
using Ocelot.Requester.QoS;
 | 
			
		||||
using Ocelot.Responses;
 | 
			
		||||
using Ocelot.Utilities;
 | 
			
		||||
using Ocelot.Values;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration.Creator
 | 
			
		||||
{
 | 
			
		||||
@@ -24,11 +25,14 @@ namespace Ocelot.Configuration.Creator
 | 
			
		||||
        private const string RegExMatchEverything = ".*";
 | 
			
		||||
        private const string RegExMatchEndString = "$";
 | 
			
		||||
        private const string RegExIgnoreCase = "(?i)";
 | 
			
		||||
        private const string RegExForwardSlashOnly = "^/$";
 | 
			
		||||
 | 
			
		||||
        private readonly IClaimToThingConfigurationParser _claimToThingConfigurationParser;
 | 
			
		||||
        private readonly ILogger<FileOcelotConfigurationCreator> _logger;
 | 
			
		||||
        private readonly ILoadBalancerFactory _loadBalanceFactory;
 | 
			
		||||
        private readonly ILoadBalancerHouse _loadBalancerHouse;
 | 
			
		||||
        private readonly IQoSProviderFactory _qoSProviderFactory;
 | 
			
		||||
        private readonly IQosProviderHouse _qosProviderHouse;
 | 
			
		||||
 | 
			
		||||
        public FileOcelotConfigurationCreator(
 | 
			
		||||
            IOptions<FileConfiguration> options, 
 | 
			
		||||
@@ -36,10 +40,14 @@ namespace Ocelot.Configuration.Creator
 | 
			
		||||
            IClaimToThingConfigurationParser claimToThingConfigurationParser, 
 | 
			
		||||
            ILogger<FileOcelotConfigurationCreator> logger,
 | 
			
		||||
            ILoadBalancerFactory loadBalancerFactory,
 | 
			
		||||
            ILoadBalancerHouse loadBalancerHouse)
 | 
			
		||||
            ILoadBalancerHouse loadBalancerHouse, 
 | 
			
		||||
            IQoSProviderFactory qoSProviderFactory, 
 | 
			
		||||
            IQosProviderHouse qosProviderHouse)
 | 
			
		||||
        {
 | 
			
		||||
            _loadBalanceFactory = loadBalancerFactory;
 | 
			
		||||
            _loadBalancerHouse = loadBalancerHouse;
 | 
			
		||||
            _qoSProviderFactory = qoSProviderFactory;
 | 
			
		||||
            _qosProviderHouse = qosProviderHouse;
 | 
			
		||||
            _options = options;
 | 
			
		||||
            _configurationValidator = configurationValidator;
 | 
			
		||||
            _claimToThingConfigurationParser = claimToThingConfigurationParser;
 | 
			
		||||
@@ -53,10 +61,6 @@ namespace Ocelot.Configuration.Creator
 | 
			
		||||
            return new OkResponse<IOcelotConfiguration>(config);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 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 async Task<IOcelotConfiguration> SetUpConfiguration()
 | 
			
		||||
        {
 | 
			
		||||
            var response = _configurationValidator.IsValid(_options.Value);
 | 
			
		||||
@@ -86,93 +90,179 @@ namespace Ocelot.Configuration.Creator
 | 
			
		||||
 | 
			
		||||
        private async Task<ReRoute> SetUpReRoute(FileReRoute fileReRoute, FileGlobalConfiguration globalConfiguration)
 | 
			
		||||
        {
 | 
			
		||||
            var globalRequestIdConfiguration = !string.IsNullOrEmpty(globalConfiguration?.RequestIdKey);
 | 
			
		||||
            var isAuthenticated = IsAuthenticated(fileReRoute);
 | 
			
		||||
 | 
			
		||||
            var upstreamTemplate = BuildUpstreamTemplate(fileReRoute);
 | 
			
		||||
            var isAuthorised = IsAuthorised(fileReRoute);
 | 
			
		||||
 | 
			
		||||
            var isAuthenticated = !string.IsNullOrEmpty(fileReRoute.AuthenticationOptions?.Provider);
 | 
			
		||||
            var isCached = IsCached(fileReRoute);
 | 
			
		||||
 | 
			
		||||
            var isAuthorised = fileReRoute.RouteClaimsRequirement?.Count > 0;
 | 
			
		||||
            var requestIdKey = BuildRequestId(fileReRoute, globalConfiguration);
 | 
			
		||||
 | 
			
		||||
            var isCached = fileReRoute.FileCacheOptions.TtlSeconds > 0;
 | 
			
		||||
            var reRouteKey = BuildReRouteKey(fileReRoute);
 | 
			
		||||
 | 
			
		||||
            var isQos = fileReRoute.QoSOptions.ExceptionsAllowedBeforeBreaking > 0 && fileReRoute.QoSOptions.TimeoutValue >0;
 | 
			
		||||
            var upstreamTemplatePattern = BuildUpstreamTemplatePattern(fileReRoute);
 | 
			
		||||
 | 
			
		||||
            var requestIdKey = globalRequestIdConfiguration
 | 
			
		||||
                ? globalConfiguration.RequestIdKey
 | 
			
		||||
                : fileReRoute.RequestIdKey;
 | 
			
		||||
            var isQos = IsQoS(fileReRoute);
 | 
			
		||||
 | 
			
		||||
            var useServiceDiscovery = !string.IsNullOrEmpty(fileReRoute.ServiceName)
 | 
			
		||||
                && !string.IsNullOrEmpty(globalConfiguration?.ServiceDiscoveryProvider?.Provider);
 | 
			
		||||
            var serviceProviderConfiguration = BuildServiceProviderConfiguration(fileReRoute, globalConfiguration);
 | 
			
		||||
 | 
			
		||||
             //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
 | 
			
		||||
            var loadBalancerKey = $"{fileReRoute.UpstreamTemplate}{fileReRoute.UpstreamHttpMethod}";
 | 
			
		||||
            var authOptionsForRoute = BuildAuthenticationOptions(fileReRoute);
 | 
			
		||||
 | 
			
		||||
            ReRoute reRoute;
 | 
			
		||||
            var claimsToHeaders = BuildAddThingsToRequest(fileReRoute.AddHeadersToRequest);
 | 
			
		||||
 | 
			
		||||
            var enableRateLimiting = (fileReRoute.RateLimitOptions!= null && fileReRoute.RateLimitOptions.EnableRateLimiting)? true: false;
 | 
			
		||||
            RateLimitOptions rateLimitOption = null;
 | 
			
		||||
            if (enableRateLimiting)
 | 
			
		||||
            {
 | 
			
		||||
                rateLimitOption = new RateLimitOptions(enableRateLimiting, globalConfiguration.RateLimitOptions.ClientIdHeader, 
 | 
			
		||||
                   fileReRoute.RateLimitOptions.ClientWhitelist, globalConfiguration.RateLimitOptions.DisableRateLimitHeaders,
 | 
			
		||||
                   globalConfiguration.RateLimitOptions.QuotaExceededMessage, globalConfiguration.RateLimitOptions.RateLimitCounterPrefix,
 | 
			
		||||
                   new RateLimitRule(fileReRoute.RateLimitOptions.Period, TimeSpan.FromSeconds(fileReRoute.RateLimitOptions.PeriodTimespan), fileReRoute.RateLimitOptions.Limit)
 | 
			
		||||
                   , globalConfiguration.RateLimitOptions.HttpStatusCode);                
 | 
			
		||||
            }
 | 
			
		||||
            var serviceProviderPort = globalConfiguration?.ServiceDiscoveryProvider?.Port ?? 0;
 | 
			
		||||
            var claimsToClaims = BuildAddThingsToRequest(fileReRoute.AddClaimsToRequest);
 | 
			
		||||
 | 
			
		||||
            var serviceProviderConfiguration = new ServiceProviderConfiguraion(fileReRoute.ServiceName,
 | 
			
		||||
                fileReRoute.DownstreamHost, fileReRoute.DownstreamPort, useServiceDiscovery,
 | 
			
		||||
                globalConfiguration?.ServiceDiscoveryProvider?.Provider, globalConfiguration?.ServiceDiscoveryProvider?.Host,
 | 
			
		||||
                serviceProviderPort);
 | 
			
		||||
            var claimsToQueries = BuildAddThingsToRequest(fileReRoute.AddQueriesToRequest);
 | 
			
		||||
 | 
			
		||||
            if (isAuthenticated)
 | 
			
		||||
            {
 | 
			
		||||
                var authOptionsForRoute = new AuthenticationOptions(fileReRoute.AuthenticationOptions.Provider,
 | 
			
		||||
                    fileReRoute.AuthenticationOptions.ProviderRootUrl, fileReRoute.AuthenticationOptions.ScopeName,
 | 
			
		||||
                    fileReRoute.AuthenticationOptions.RequireHttps, fileReRoute.AuthenticationOptions.AdditionalScopes,
 | 
			
		||||
                    fileReRoute.AuthenticationOptions.ScopeSecret);
 | 
			
		||||
            var qosOptions = BuildQoSOptions(fileReRoute);
 | 
			
		||||
 | 
			
		||||
                var claimsToHeaders = GetAddThingsToRequest(fileReRoute.AddHeadersToRequest);
 | 
			
		||||
                var claimsToClaims = GetAddThingsToRequest(fileReRoute.AddClaimsToRequest);
 | 
			
		||||
                var claimsToQueries = GetAddThingsToRequest(fileReRoute.AddQueriesToRequest);
 | 
			
		||||
            var enableRateLimiting = IsEnableRateLimiting(fileReRoute);
 | 
			
		||||
 | 
			
		||||
                reRoute = new ReRoute(new DownstreamPathTemplate(fileReRoute.DownstreamPathTemplate),
 | 
			
		||||
                   fileReRoute.UpstreamTemplate,
 | 
			
		||||
                   fileReRoute.UpstreamHttpMethod, upstreamTemplate, isAuthenticated,
 | 
			
		||||
                   authOptionsForRoute, claimsToHeaders, claimsToClaims,
 | 
			
		||||
                   fileReRoute.RouteClaimsRequirement, isAuthorised, claimsToQueries,
 | 
			
		||||
                   requestIdKey, isCached, new CacheOptions(fileReRoute.FileCacheOptions.TtlSeconds)
 | 
			
		||||
                   , fileReRoute.DownstreamScheme,
 | 
			
		||||
                   fileReRoute.LoadBalancer, fileReRoute.DownstreamHost, fileReRoute.DownstreamPort, loadBalancerKey,
 | 
			
		||||
                   serviceProviderConfiguration, isQos, 
 | 
			
		||||
                   new QoSOptions(fileReRoute.QoSOptions.ExceptionsAllowedBeforeBreaking, fileReRoute.QoSOptions.DurationOfBreak, fileReRoute.QoSOptions.TimeoutValue),
 | 
			
		||||
                   enableRateLimiting, rateLimitOption);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                reRoute = new ReRoute(new DownstreamPathTemplate(fileReRoute.DownstreamPathTemplate),
 | 
			
		||||
                    fileReRoute.UpstreamTemplate,
 | 
			
		||||
                    fileReRoute.UpstreamHttpMethod, upstreamTemplate, isAuthenticated,
 | 
			
		||||
                    null, new List<ClaimToThing>(), new List<ClaimToThing>(),
 | 
			
		||||
                    fileReRoute.RouteClaimsRequirement, isAuthorised, new List<ClaimToThing>(),
 | 
			
		||||
                    requestIdKey, isCached, new CacheOptions(fileReRoute.FileCacheOptions.TtlSeconds),
 | 
			
		||||
                    fileReRoute.DownstreamScheme,
 | 
			
		||||
                    fileReRoute.LoadBalancer, fileReRoute.DownstreamHost, fileReRoute.DownstreamPort, loadBalancerKey,
 | 
			
		||||
                    serviceProviderConfiguration, isQos,
 | 
			
		||||
                    new QoSOptions(fileReRoute.QoSOptions.ExceptionsAllowedBeforeBreaking, fileReRoute.QoSOptions.DurationOfBreak, fileReRoute.QoSOptions.TimeoutValue),
 | 
			
		||||
                    enableRateLimiting, rateLimitOption);
 | 
			
		||||
            }
 | 
			
		||||
      
 | 
			
		||||
            var loadBalancer = await _loadBalanceFactory.Get(reRoute);
 | 
			
		||||
            _loadBalancerHouse.Add(reRoute.LoadBalancerKey, loadBalancer);
 | 
			
		||||
            var rateLimitOption = BuildRateLimitOptions(fileReRoute, globalConfiguration, enableRateLimiting);
 | 
			
		||||
 | 
			
		||||
            var reRoute = new ReRouteBuilder()
 | 
			
		||||
                .WithDownstreamPathTemplate(fileReRoute.DownstreamPathTemplate)
 | 
			
		||||
                .WithUpstreamPathTemplate(fileReRoute.UpstreamPathTemplate)
 | 
			
		||||
                .WithUpstreamHttpMethod(fileReRoute.UpstreamHttpMethod)
 | 
			
		||||
                .WithUpstreamTemplatePattern(upstreamTemplatePattern)
 | 
			
		||||
                .WithIsAuthenticated(isAuthenticated)
 | 
			
		||||
                .WithAuthenticationOptions(authOptionsForRoute)
 | 
			
		||||
                .WithClaimsToHeaders(claimsToHeaders)
 | 
			
		||||
                .WithClaimsToClaims(claimsToClaims)
 | 
			
		||||
                .WithRouteClaimsRequirement(fileReRoute.RouteClaimsRequirement)
 | 
			
		||||
                .WithIsAuthorised(isAuthorised)
 | 
			
		||||
                .WithClaimsToQueries(claimsToQueries)
 | 
			
		||||
                .WithRequestIdKey(requestIdKey)
 | 
			
		||||
                .WithIsCached(isCached)
 | 
			
		||||
                .WithCacheOptions(new CacheOptions(fileReRoute.FileCacheOptions.TtlSeconds))
 | 
			
		||||
                .WithDownstreamScheme(fileReRoute.DownstreamScheme)
 | 
			
		||||
                .WithLoadBalancer(fileReRoute.LoadBalancer)
 | 
			
		||||
                .WithDownstreamHost(fileReRoute.DownstreamHost)
 | 
			
		||||
                .WithDownstreamPort(fileReRoute.DownstreamPort)
 | 
			
		||||
                .WithLoadBalancerKey(reRouteKey)
 | 
			
		||||
                .WithServiceProviderConfiguraion(serviceProviderConfiguration)
 | 
			
		||||
                .WithIsQos(isQos)
 | 
			
		||||
                .WithQosOptions(qosOptions)
 | 
			
		||||
                .WithEnableRateLimiting(enableRateLimiting)
 | 
			
		||||
                .WithRateLimitOptions(rateLimitOption)
 | 
			
		||||
                .Build();
 | 
			
		||||
            await SetupLoadBalancer(reRoute);
 | 
			
		||||
            SetupQosProvider(reRoute);
 | 
			
		||||
            return reRoute;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private string BuildUpstreamTemplate(FileReRoute reRoute)
 | 
			
		||||
        private static RateLimitOptions BuildRateLimitOptions(FileReRoute fileReRoute, FileGlobalConfiguration globalConfiguration, bool enableRateLimiting)
 | 
			
		||||
        {
 | 
			
		||||
            var upstreamTemplate = reRoute.UpstreamTemplate;
 | 
			
		||||
            RateLimitOptions rateLimitOption = null;
 | 
			
		||||
            if (enableRateLimiting)
 | 
			
		||||
            {
 | 
			
		||||
                rateLimitOption = new RateLimitOptions(enableRateLimiting, globalConfiguration.RateLimitOptions.ClientIdHeader,
 | 
			
		||||
                   fileReRoute.RateLimitOptions.ClientWhitelist, globalConfiguration.RateLimitOptions.DisableRateLimitHeaders,
 | 
			
		||||
                   globalConfiguration.RateLimitOptions.QuotaExceededMessage, globalConfiguration.RateLimitOptions.RateLimitCounterPrefix,
 | 
			
		||||
                   new RateLimitRule(fileReRoute.RateLimitOptions.Period, TimeSpan.FromSeconds(fileReRoute.RateLimitOptions.PeriodTimespan), fileReRoute.RateLimitOptions.Limit)
 | 
			
		||||
                   , globalConfiguration.RateLimitOptions.HttpStatusCode);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return rateLimitOption;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static bool IsEnableRateLimiting(FileReRoute fileReRoute)
 | 
			
		||||
        {
 | 
			
		||||
            return (fileReRoute.RateLimitOptions != null && fileReRoute.RateLimitOptions.EnableRateLimiting) ? true : false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private QoSOptions BuildQoSOptions(FileReRoute fileReRoute)
 | 
			
		||||
        {
 | 
			
		||||
            return new QoSOptionsBuilder()
 | 
			
		||||
                .WithExceptionsAllowedBeforeBreaking(fileReRoute.QoSOptions.ExceptionsAllowedBeforeBreaking)
 | 
			
		||||
                .WithDurationOfBreak(fileReRoute.QoSOptions.DurationOfBreak)
 | 
			
		||||
                .WithTimeoutValue(fileReRoute.QoSOptions.TimeoutValue)
 | 
			
		||||
                .Build();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private bool IsQoS(FileReRoute fileReRoute)
 | 
			
		||||
        {
 | 
			
		||||
            return fileReRoute.QoSOptions?.ExceptionsAllowedBeforeBreaking > 0 && fileReRoute.QoSOptions?.TimeoutValue > 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private bool IsAuthenticated(FileReRoute fileReRoute)
 | 
			
		||||
        {
 | 
			
		||||
            return !string.IsNullOrEmpty(fileReRoute.AuthenticationOptions?.Provider);
 | 
			
		||||
        }
 | 
			
		||||
      
 | 
			
		||||
        private bool IsAuthorised(FileReRoute fileReRoute)
 | 
			
		||||
        {
 | 
			
		||||
            return fileReRoute.RouteClaimsRequirement?.Count > 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private bool IsCached(FileReRoute fileReRoute)
 | 
			
		||||
        {
 | 
			
		||||
            return fileReRoute.FileCacheOptions.TtlSeconds > 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private string BuildRequestId(FileReRoute fileReRoute, FileGlobalConfiguration globalConfiguration)
 | 
			
		||||
        {
 | 
			
		||||
            var globalRequestIdConfiguration = !string.IsNullOrEmpty(globalConfiguration?.RequestIdKey);
 | 
			
		||||
 | 
			
		||||
             var requestIdKey = globalRequestIdConfiguration
 | 
			
		||||
                ? globalConfiguration.RequestIdKey
 | 
			
		||||
                : fileReRoute.RequestIdKey;
 | 
			
		||||
 | 
			
		||||
                return requestIdKey;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private string BuildReRouteKey(FileReRoute fileReRoute)
 | 
			
		||||
        {
 | 
			
		||||
            //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
 | 
			
		||||
            var loadBalancerKey = $"{fileReRoute.UpstreamPathTemplate}{fileReRoute.UpstreamHttpMethod}";
 | 
			
		||||
            return loadBalancerKey;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private AuthenticationOptions BuildAuthenticationOptions(FileReRoute fileReRoute)
 | 
			
		||||
        {
 | 
			
		||||
            return new AuthenticationOptionsBuilder()
 | 
			
		||||
                                        .WithProvider(fileReRoute.AuthenticationOptions?.Provider)
 | 
			
		||||
                                        .WithProviderRootUrl(fileReRoute.AuthenticationOptions?.ProviderRootUrl)
 | 
			
		||||
                                        .WithScopeName(fileReRoute.AuthenticationOptions?.ScopeName)
 | 
			
		||||
                                        .WithRequireHttps(fileReRoute.AuthenticationOptions.RequireHttps)
 | 
			
		||||
                                        .WithAdditionalScopes(fileReRoute.AuthenticationOptions?.AdditionalScopes)
 | 
			
		||||
                                        .WithScopeSecret(fileReRoute.AuthenticationOptions?.ScopeSecret)
 | 
			
		||||
                                        .Build();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async Task SetupLoadBalancer(ReRoute reRoute)
 | 
			
		||||
        {
 | 
			
		||||
            var loadBalancer = await _loadBalanceFactory.Get(reRoute);
 | 
			
		||||
            _loadBalancerHouse.Add(reRoute.ReRouteKey, loadBalancer);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void SetupQosProvider(ReRoute reRoute)
 | 
			
		||||
        {
 | 
			
		||||
            var loadBalancer = _qoSProviderFactory.Get(reRoute);
 | 
			
		||||
            _qosProviderHouse.Add(reRoute.ReRouteKey, loadBalancer);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private ServiceProviderConfiguraion BuildServiceProviderConfiguration(FileReRoute fileReRoute, FileGlobalConfiguration globalConfiguration)
 | 
			
		||||
        {
 | 
			
		||||
            var useServiceDiscovery = !string.IsNullOrEmpty(fileReRoute.ServiceName)
 | 
			
		||||
                && !string.IsNullOrEmpty(globalConfiguration?.ServiceDiscoveryProvider?.Provider);
 | 
			
		||||
 | 
			
		||||
            var serviceProviderPort = globalConfiguration?.ServiceDiscoveryProvider?.Port ?? 0;
 | 
			
		||||
 | 
			
		||||
            return new ServiceProviderConfiguraionBuilder()
 | 
			
		||||
                    .WithServiceName(fileReRoute.ServiceName)
 | 
			
		||||
                    .WithDownstreamHost(fileReRoute.DownstreamHost)
 | 
			
		||||
                    .WithDownstreamPort(fileReRoute.DownstreamPort)
 | 
			
		||||
                    .WithUseServiceDiscovery(useServiceDiscovery)
 | 
			
		||||
                    .WithServiceDiscoveryProvider(globalConfiguration?.ServiceDiscoveryProvider?.Provider)
 | 
			
		||||
                    .WithServiceDiscoveryProviderHost(globalConfiguration?.ServiceDiscoveryProvider?.Host)
 | 
			
		||||
                    .WithServiceDiscoveryProviderPort(serviceProviderPort)
 | 
			
		||||
                    .Build();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private string BuildUpstreamTemplatePattern(FileReRoute reRoute)
 | 
			
		||||
        {
 | 
			
		||||
            var upstreamTemplate = reRoute.UpstreamPathTemplate;
 | 
			
		||||
 | 
			
		||||
            upstreamTemplate = upstreamTemplate.SetLastCharacterAs('/');
 | 
			
		||||
 | 
			
		||||
@@ -194,6 +284,11 @@ namespace Ocelot.Configuration.Creator
 | 
			
		||||
                upstreamTemplate = upstreamTemplate.Replace(placeholder, RegExMatchEverything);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (upstreamTemplate == "/")
 | 
			
		||||
            {
 | 
			
		||||
                return RegExForwardSlashOnly;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var route = reRoute.ReRouteIsCaseSensitive 
 | 
			
		||||
                ? $"{upstreamTemplate}{RegExMatchEndString}" 
 | 
			
		||||
                : $"{RegExIgnoreCase}{upstreamTemplate}{RegExMatchEndString}";
 | 
			
		||||
@@ -201,7 +296,7 @@ namespace Ocelot.Configuration.Creator
 | 
			
		||||
            return route;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private List<ClaimToThing> GetAddThingsToRequest(Dictionary<string,string> thingBeingAdded)
 | 
			
		||||
        private List<ClaimToThing> BuildAddThingsToRequest(Dictionary<string,string> thingBeingAdded)
 | 
			
		||||
        {
 | 
			
		||||
            var claimsToTHings = new List<ClaimToThing>();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,15 @@
 | 
			
		||||
using Polly.Timeout;
 | 
			
		||||
using System;
 | 
			
		||||
using System;
 | 
			
		||||
using Polly.Timeout;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration
 | 
			
		||||
{
 | 
			
		||||
    public class QoSOptions
 | 
			
		||||
    {
 | 
			
		||||
        public QoSOptions(int exceptionsAllowedBeforeBreaking, int durationofBreak, int timeoutValue, TimeoutStrategy timeoutStrategy = TimeoutStrategy.Pessimistic)
 | 
			
		||||
        public QoSOptions(
 | 
			
		||||
            int exceptionsAllowedBeforeBreaking, 
 | 
			
		||||
            int durationofBreak, 
 | 
			
		||||
            int timeoutValue, 
 | 
			
		||||
            TimeoutStrategy timeoutStrategy = TimeoutStrategy.Pessimistic)
 | 
			
		||||
        {
 | 
			
		||||
            ExceptionsAllowedBeforeBreaking = exceptionsAllowedBeforeBreaking;
 | 
			
		||||
            DurationOfBreak = TimeSpan.FromMilliseconds(durationofBreak);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,31 +1,44 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using Ocelot.Values;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration
 | 
			
		||||
{
 | 
			
		||||
    public class ReRoute
 | 
			
		||||
    {
 | 
			
		||||
        public ReRoute(DownstreamPathTemplate downstreamPathTemplate, 
 | 
			
		||||
            string upstreamTemplate, string upstreamHttpMethod, 
 | 
			
		||||
        public ReRoute(PathTemplate downstreamPathTemplate, 
 | 
			
		||||
            PathTemplate upstreamTemplate, 
 | 
			
		||||
            HttpMethod upstreamHttpMethod, 
 | 
			
		||||
            string upstreamTemplatePattern, 
 | 
			
		||||
            bool isAuthenticated, AuthenticationOptions authenticationOptions, 
 | 
			
		||||
            bool isAuthenticated, 
 | 
			
		||||
            AuthenticationOptions authenticationOptions, 
 | 
			
		||||
            List<ClaimToThing> configurationHeaderExtractorProperties, 
 | 
			
		||||
            List<ClaimToThing> claimsToClaims, 
 | 
			
		||||
            Dictionary<string, string> routeClaimsRequirement, bool isAuthorised, 
 | 
			
		||||
            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,
 | 
			
		||||
            bool isQos,QoSOptions qos, bool enableRateLimit, RateLimitOptions ratelimitOptions)
 | 
			
		||||
            string requestIdKey, 
 | 
			
		||||
            bool isCached, 
 | 
			
		||||
            CacheOptions fileCacheOptions, 
 | 
			
		||||
            string downstreamScheme, 
 | 
			
		||||
            string loadBalancer, 
 | 
			
		||||
            string downstreamHost, 
 | 
			
		||||
            int downstreamPort, 
 | 
			
		||||
            string reRouteKey, 
 | 
			
		||||
            ServiceProviderConfiguraion serviceProviderConfiguraion,
 | 
			
		||||
            bool isQos,
 | 
			
		||||
            QoSOptions qos,
 | 
			
		||||
            bool enableRateLimit,
 | 
			
		||||
            RateLimitOptions ratelimitOptions)
 | 
			
		||||
        {
 | 
			
		||||
            LoadBalancerKey = loadBalancerKey;
 | 
			
		||||
            ReRouteKey = reRouteKey;
 | 
			
		||||
            ServiceProviderConfiguraion = serviceProviderConfiguraion;
 | 
			
		||||
            LoadBalancer = loadBalancer;
 | 
			
		||||
            DownstreamHost = downstreamHost;
 | 
			
		||||
            DownstreamPort = downstreamPort;
 | 
			
		||||
            DownstreamPathTemplate = downstreamPathTemplate;
 | 
			
		||||
            UpstreamTemplate = upstreamTemplate;
 | 
			
		||||
            UpstreamPathTemplate = upstreamTemplate;
 | 
			
		||||
            UpstreamHttpMethod = upstreamHttpMethod;
 | 
			
		||||
            UpstreamTemplatePattern = upstreamTemplatePattern;
 | 
			
		||||
            IsAuthenticated = isAuthenticated;
 | 
			
		||||
@@ -48,11 +61,11 @@ namespace Ocelot.Configuration
 | 
			
		||||
            RateLimitOptions = ratelimitOptions;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string LoadBalancerKey {get;private set;}
 | 
			
		||||
        public DownstreamPathTemplate DownstreamPathTemplate { get; private set; }
 | 
			
		||||
        public string UpstreamTemplate { get; private set; }
 | 
			
		||||
        public string ReRouteKey {get;private set;}
 | 
			
		||||
        public PathTemplate DownstreamPathTemplate { get; private set; }
 | 
			
		||||
        public PathTemplate UpstreamPathTemplate { get; private set; }
 | 
			
		||||
        public string UpstreamTemplatePattern { get; private set; }
 | 
			
		||||
        public string UpstreamHttpMethod { get; private set; }
 | 
			
		||||
        public HttpMethod UpstreamHttpMethod { get; private set; }
 | 
			
		||||
        public bool IsAuthenticated { get; private set; }
 | 
			
		||||
        public bool IsAuthorised { get; private set; }
 | 
			
		||||
        public AuthenticationOptions AuthenticationOptions { get; private set; }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user