mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-11-04 09:15:27 +08:00 
			
		
		
		
	plugged load balancer middleware into Ocelot pipeline, load balanced downstream host and port now used by url creator middleware
This commit is contained in:
		@@ -6,6 +6,7 @@ namespace Ocelot.Configuration.Builder
 | 
			
		||||
{
 | 
			
		||||
    public class ReRouteBuilder
 | 
			
		||||
    {
 | 
			
		||||
        private string _loadBalancerKey;
 | 
			
		||||
        private string _downstreamPathTemplate;
 | 
			
		||||
        private string _upstreamTemplate;
 | 
			
		||||
        private string _upstreamTemplatePattern;
 | 
			
		||||
@@ -199,6 +200,12 @@ namespace Ocelot.Configuration.Builder
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ReRouteBuilder WithLoadBalancerKey(string loadBalancerKey)
 | 
			
		||||
        {
 | 
			
		||||
            _loadBalancerKey = loadBalancerKey;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ReRoute Build()
 | 
			
		||||
        {
 | 
			
		||||
            return new ReRoute(new DownstreamPathTemplate(_downstreamPathTemplate), _upstreamTemplate, _upstreamHttpMethod, _upstreamTemplatePattern, 
 | 
			
		||||
@@ -206,7 +213,7 @@ namespace Ocelot.Configuration.Builder
 | 
			
		||||
                _requireHttps, _additionalScopes, _scopeSecret), _configHeaderExtractorProperties, _claimToClaims, _routeClaimRequirement, 
 | 
			
		||||
                _isAuthorised, _claimToQueries, _requestIdHeaderKey, _isCached, _fileCacheOptions, _serviceName, 
 | 
			
		||||
                _useServiceDiscovery, _serviceDiscoveryAddress, _serviceDiscoveryProvider, _downstreamScheme, _loadBalancer,
 | 
			
		||||
                _downstreamHost, _dsPort);
 | 
			
		||||
                _downstreamHost, _dsPort, _loadBalancerKey);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -104,6 +104,9 @@ namespace Ocelot.Configuration.Creator
 | 
			
		||||
                && !string.IsNullOrEmpty(globalConfiguration?.ServiceDiscoveryProvider?.Address)
 | 
			
		||||
                && !string.IsNullOrEmpty(globalConfiguration?.ServiceDiscoveryProvider?.Provider);
 | 
			
		||||
 | 
			
		||||
            //note - not sure if this is the correct key, but this is probably the only unique key i can think of given my poor brain
 | 
			
		||||
            var loadBalancerKey = $"{fileReRoute.UpstreamTemplate}{fileReRoute.UpstreamHttpMethod}";
 | 
			
		||||
 | 
			
		||||
            ReRoute reRoute;
 | 
			
		||||
            
 | 
			
		||||
            if (isAuthenticated)
 | 
			
		||||
@@ -124,7 +127,7 @@ namespace Ocelot.Configuration.Creator
 | 
			
		||||
                    requestIdKey, isCached, new CacheOptions(fileReRoute.FileCacheOptions.TtlSeconds),
 | 
			
		||||
                    fileReRoute.ServiceName, useServiceDiscovery, globalConfiguration?.ServiceDiscoveryProvider?.Provider,
 | 
			
		||||
                    globalConfiguration?.ServiceDiscoveryProvider?.Address, fileReRoute.DownstreamScheme, 
 | 
			
		||||
                    fileReRoute.LoadBalancer, fileReRoute.DownstreamHost, fileReRoute.DownstreamPort);
 | 
			
		||||
                    fileReRoute.LoadBalancer, fileReRoute.DownstreamHost, fileReRoute.DownstreamPort,loadBalancerKey);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            reRoute = new ReRoute(new DownstreamPathTemplate(fileReRoute.DownstreamPathTemplate), fileReRoute.UpstreamTemplate, 
 | 
			
		||||
@@ -134,11 +137,10 @@ namespace Ocelot.Configuration.Creator
 | 
			
		||||
                    requestIdKey, isCached, new CacheOptions(fileReRoute.FileCacheOptions.TtlSeconds),
 | 
			
		||||
                    fileReRoute.ServiceName, useServiceDiscovery, globalConfiguration?.ServiceDiscoveryProvider?.Provider,
 | 
			
		||||
                    globalConfiguration?.ServiceDiscoveryProvider?.Address, fileReRoute.DownstreamScheme,
 | 
			
		||||
                    fileReRoute.LoadBalancer, fileReRoute.DownstreamHost, fileReRoute.DownstreamPort);
 | 
			
		||||
                    fileReRoute.LoadBalancer, fileReRoute.DownstreamHost, fileReRoute.DownstreamPort,loadBalancerKey);
 | 
			
		||||
 | 
			
		||||
            var loadBalancer = _loadBalanceFactory.Get(reRoute);
 | 
			
		||||
            //todo - not sure if this is the correct key, but this is probably the only unique key i can think of
 | 
			
		||||
            _loadBalancerHouse.Add($"{fileReRoute.UpstreamTemplate}{fileReRoute.UpstreamHttpMethod}", loadBalancer);
 | 
			
		||||
            _loadBalancerHouse.Add(reRoute.LoadBalancerKey, loadBalancer);
 | 
			
		||||
            return reRoute;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -11,8 +11,9 @@ namespace Ocelot.Configuration
 | 
			
		||||
            List<ClaimToThing> claimsToClaims, Dictionary<string, string> routeClaimsRequirement, bool isAuthorised, List<ClaimToThing> claimsToQueries, 
 | 
			
		||||
            string requestIdKey, bool isCached, CacheOptions fileCacheOptions, string serviceName, bool useServiceDiscovery,
 | 
			
		||||
            string serviceDiscoveryProvider, string serviceDiscoveryAddress,
 | 
			
		||||
            string downstreamScheme, string loadBalancer, string downstreamHost, int downstreamPort)
 | 
			
		||||
            string downstreamScheme, string loadBalancer, string downstreamHost, int downstreamPort, string loadBalancerKey)
 | 
			
		||||
        {
 | 
			
		||||
            LoadBalancerKey = loadBalancerKey;
 | 
			
		||||
            LoadBalancer = loadBalancer;
 | 
			
		||||
            DownstreamHost = downstreamHost;
 | 
			
		||||
            DownstreamPort = downstreamPort;
 | 
			
		||||
@@ -39,6 +40,7 @@ namespace Ocelot.Configuration
 | 
			
		||||
                ServiceDiscoveryAddress = serviceDiscoveryAddress;
 | 
			
		||||
                DownstreamScheme = downstreamScheme;
 | 
			
		||||
        }
 | 
			
		||||
        public string LoadBalancerKey {get;private set;}
 | 
			
		||||
        public DownstreamPathTemplate DownstreamPathTemplate { get; private set; }
 | 
			
		||||
        public string UpstreamTemplate { get; private set; }
 | 
			
		||||
        public string UpstreamTemplatePattern { get; private set; }
 | 
			
		||||
 
 | 
			
		||||
@@ -47,15 +47,12 @@ namespace Ocelot.DownstreamUrlCreator.Middleware
 | 
			
		||||
 | 
			
		||||
            var dsScheme = DownstreamRoute.ReRoute.DownstreamScheme;
 | 
			
		||||
            
 | 
			
		||||
            //todo - get this out of scoped data repo?
 | 
			
		||||
            var dsHostAndPort = new HostAndPort(DownstreamRoute.ReRoute.DownstreamHost,
 | 
			
		||||
                DownstreamRoute.ReRoute.DownstreamPort);
 | 
			
		||||
            var dsHostAndPort = HostAndPort;
 | 
			
		||||
 | 
			
		||||
            var dsUrl = _urlBuilder.Build(dsPath.Data.Value, dsScheme, dsHostAndPort);
 | 
			
		||||
 | 
			
		||||
            if (dsUrl.IsError)
 | 
			
		||||
            {
 | 
			
		||||
                //todo - release the lb connection?
 | 
			
		||||
                _logger.LogDebug("IUrlBuilder returned an error, setting pipeline error");
 | 
			
		||||
 | 
			
		||||
                SetPipelineError(dsUrl.Errors);
 | 
			
		||||
@@ -70,8 +67,6 @@ namespace Ocelot.DownstreamUrlCreator.Middleware
 | 
			
		||||
 | 
			
		||||
            await _next.Invoke(context);
 | 
			
		||||
 | 
			
		||||
            //todo - release the lb connection?
 | 
			
		||||
 | 
			
		||||
            _logger.LogDebug("succesfully called next middleware");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -31,26 +31,32 @@ namespace Ocelot.LoadBalancer.Middleware
 | 
			
		||||
        {
 | 
			
		||||
            _logger.LogDebug("started calling load balancing middleware");
 | 
			
		||||
 | 
			
		||||
            var loadBalancer = _loadBalancerHouse.Get($"{DownstreamRoute.ReRoute.UpstreamTemplate}{DownstreamRoute.ReRoute.UpstreamHttpMethod}");
 | 
			
		||||
            //todo check reponse and return error
 | 
			
		||||
            
 | 
			
		||||
            var response = loadBalancer.Data.Lease();
 | 
			
		||||
            //todo check reponse and return error
 | 
			
		||||
            
 | 
			
		||||
            SetHostAndPortForThisRequest(response.Data);
 | 
			
		||||
            var loadBalancer = _loadBalancerHouse.Get(DownstreamRoute.ReRoute.LoadBalancerKey);
 | 
			
		||||
            if(loadBalancer.IsError)
 | 
			
		||||
            {
 | 
			
		||||
                //set errors and return
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var hostAndPort = loadBalancer.Data.Lease();
 | 
			
		||||
            if(hostAndPort.IsError)
 | 
			
		||||
            {
 | 
			
		||||
                //set errors and return
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            SetHostAndPortForThisRequest(hostAndPort.Data);
 | 
			
		||||
 | 
			
		||||
            _logger.LogDebug("calling next middleware");
 | 
			
		||||
 | 
			
		||||
            //todo - try next middleware if we get an exception make sure we release 
 | 
			
		||||
            //the host and port? Not sure if this is the way to go but we shall see!
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                await _next.Invoke(context);
 | 
			
		||||
 | 
			
		||||
                loadBalancer.Data.Release(response.Data);
 | 
			
		||||
                loadBalancer.Data.Release(hostAndPort.Data);
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception)
 | 
			
		||||
            {
 | 
			
		||||
                loadBalancer.Data.Release(response.Data);
 | 
			
		||||
                loadBalancer.Data.Release(hostAndPort.Data);
 | 
			
		||||
                 _logger.LogDebug("error calling next middleware, exception will be thrown to global handler");
 | 
			
		||||
                throw;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ namespace Ocelot.LoadBalancer.Middleware
 | 
			
		||||
{
 | 
			
		||||
 public static class LoadBalancingMiddlewareExtensions
 | 
			
		||||
    {
 | 
			
		||||
        public static IApplicationBuilder UseLoadBalancingMiddlewareExtensions(this IApplicationBuilder builder)
 | 
			
		||||
        public static IApplicationBuilder UseLoadBalancingMiddleware(this IApplicationBuilder builder)
 | 
			
		||||
        {
 | 
			
		||||
            return builder.UseMiddleware<LoadBalancingMiddleware>();
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,7 @@ namespace Ocelot.Middleware
 | 
			
		||||
    using System.Threading.Tasks;
 | 
			
		||||
    using Authorisation.Middleware;
 | 
			
		||||
    using Microsoft.AspNetCore.Http;
 | 
			
		||||
    using Ocelot.LoadBalancer.Middleware;
 | 
			
		||||
 | 
			
		||||
    public static class OcelotMiddlewareExtensions
 | 
			
		||||
    {
 | 
			
		||||
@@ -98,6 +99,9 @@ namespace Ocelot.Middleware
 | 
			
		||||
            // Now we can run any query string transformation logic
 | 
			
		||||
            builder.UseQueryStringBuilderMiddleware();
 | 
			
		||||
 | 
			
		||||
            // Get the load balancer for this request
 | 
			
		||||
            builder.UseLoadBalancingMiddleware();
 | 
			
		||||
 | 
			
		||||
            // This takes the downstream route we retrieved earlier and replaces any placeholders with the variables that should be used
 | 
			
		||||
            builder.UseDownstreamUrlCreatorMiddleware();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user