mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-11-04 20:30:50 +08:00 
			
		
		
		
	more work towards getting service discovery working with load balancing
This commit is contained in:
		@@ -27,13 +27,19 @@ namespace Ocelot.Configuration.Creator
 | 
			
		||||
 | 
			
		||||
        private readonly IClaimToThingConfigurationParser _claimToThingConfigurationParser;
 | 
			
		||||
        private readonly ILogger<FileOcelotConfigurationCreator> _logger;
 | 
			
		||||
        private readonly ILoadBalancerFactory _loadBalanceFactory;
 | 
			
		||||
        private readonly ILoadBalancerHouse _loadBalancerHouse;
 | 
			
		||||
 | 
			
		||||
        public FileOcelotConfigurationCreator(
 | 
			
		||||
            IOptions<FileConfiguration> options, 
 | 
			
		||||
            IConfigurationValidator configurationValidator, 
 | 
			
		||||
            IClaimToThingConfigurationParser claimToThingConfigurationParser, 
 | 
			
		||||
            ILogger<FileOcelotConfigurationCreator> logger)
 | 
			
		||||
            ILogger<FileOcelotConfigurationCreator> logger,
 | 
			
		||||
            ILoadBalancerFactory loadBalancerFactory,
 | 
			
		||||
            ILoadBalancerHouse loadBalancerHouse)
 | 
			
		||||
        {
 | 
			
		||||
            _loadBalanceFactory = loadBalancerFactory;
 | 
			
		||||
            _loadBalancerHouse = loadBalancerHouse;
 | 
			
		||||
            _options = options;
 | 
			
		||||
            _configurationValidator = configurationValidator;
 | 
			
		||||
            _claimToThingConfigurationParser = claimToThingConfigurationParser;
 | 
			
		||||
@@ -78,55 +84,62 @@ namespace Ocelot.Configuration.Creator
 | 
			
		||||
            return new OcelotConfiguration(reRoutes);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private ReRoute SetUpReRoute(FileReRoute reRoute, FileGlobalConfiguration globalConfiguration)
 | 
			
		||||
        private ReRoute SetUpReRoute(FileReRoute fileReRoute, FileGlobalConfiguration globalConfiguration)
 | 
			
		||||
        {
 | 
			
		||||
            var globalRequestIdConfiguration = !string.IsNullOrEmpty(globalConfiguration?.RequestIdKey);
 | 
			
		||||
 | 
			
		||||
            var upstreamTemplate = BuildUpstreamTemplate(reRoute);
 | 
			
		||||
            var upstreamTemplate = BuildUpstreamTemplate(fileReRoute);
 | 
			
		||||
 | 
			
		||||
            var isAuthenticated = !string.IsNullOrEmpty(reRoute.AuthenticationOptions?.Provider);
 | 
			
		||||
            var isAuthenticated = !string.IsNullOrEmpty(fileReRoute.AuthenticationOptions?.Provider);
 | 
			
		||||
 | 
			
		||||
            var isAuthorised = reRoute.RouteClaimsRequirement?.Count > 0;
 | 
			
		||||
            var isAuthorised = fileReRoute.RouteClaimsRequirement?.Count > 0;
 | 
			
		||||
 | 
			
		||||
            var isCached = reRoute.FileCacheOptions.TtlSeconds > 0;
 | 
			
		||||
            var isCached = fileReRoute.FileCacheOptions.TtlSeconds > 0;
 | 
			
		||||
 | 
			
		||||
            var requestIdKey = globalRequestIdConfiguration
 | 
			
		||||
                ? globalConfiguration.RequestIdKey
 | 
			
		||||
                : reRoute.RequestIdKey;
 | 
			
		||||
                : fileReRoute.RequestIdKey;
 | 
			
		||||
 | 
			
		||||
            var useServiceDiscovery = !string.IsNullOrEmpty(reRoute.ServiceName)
 | 
			
		||||
            var useServiceDiscovery = !string.IsNullOrEmpty(fileReRoute.ServiceName)
 | 
			
		||||
                && !string.IsNullOrEmpty(globalConfiguration?.ServiceDiscoveryProvider?.Address)
 | 
			
		||||
                && !string.IsNullOrEmpty(globalConfiguration?.ServiceDiscoveryProvider?.Provider);
 | 
			
		||||
 | 
			
		||||
            ReRoute reRoute;
 | 
			
		||||
            
 | 
			
		||||
            if (isAuthenticated)
 | 
			
		||||
            {
 | 
			
		||||
                var authOptionsForRoute = new AuthenticationOptions(reRoute.AuthenticationOptions.Provider,
 | 
			
		||||
                    reRoute.AuthenticationOptions.ProviderRootUrl, reRoute.AuthenticationOptions.ScopeName,
 | 
			
		||||
                    reRoute.AuthenticationOptions.RequireHttps, reRoute.AuthenticationOptions.AdditionalScopes,
 | 
			
		||||
                    reRoute.AuthenticationOptions.ScopeSecret);
 | 
			
		||||
                var authOptionsForRoute = new AuthenticationOptions(fileReRoute.AuthenticationOptions.Provider,
 | 
			
		||||
                    fileReRoute.AuthenticationOptions.ProviderRootUrl, fileReRoute.AuthenticationOptions.ScopeName,
 | 
			
		||||
                    fileReRoute.AuthenticationOptions.RequireHttps, fileReRoute.AuthenticationOptions.AdditionalScopes,
 | 
			
		||||
                    fileReRoute.AuthenticationOptions.ScopeSecret);
 | 
			
		||||
 | 
			
		||||
                var claimsToHeaders = GetAddThingsToRequest(reRoute.AddHeadersToRequest);
 | 
			
		||||
                var claimsToClaims = GetAddThingsToRequest(reRoute.AddClaimsToRequest);
 | 
			
		||||
                var claimsToQueries = GetAddThingsToRequest(reRoute.AddQueriesToRequest);
 | 
			
		||||
                var claimsToHeaders = GetAddThingsToRequest(fileReRoute.AddHeadersToRequest);
 | 
			
		||||
                var claimsToClaims = GetAddThingsToRequest(fileReRoute.AddClaimsToRequest);
 | 
			
		||||
                var claimsToQueries = GetAddThingsToRequest(fileReRoute.AddQueriesToRequest);
 | 
			
		||||
 | 
			
		||||
                return new ReRoute(new DownstreamPathTemplate(reRoute.DownstreamPathTemplate), reRoute.UpstreamTemplate,
 | 
			
		||||
                    reRoute.UpstreamHttpMethod, upstreamTemplate, isAuthenticated,
 | 
			
		||||
                reRoute = new ReRoute(new DownstreamPathTemplate(fileReRoute.DownstreamPathTemplate), fileReRoute.UpstreamTemplate,
 | 
			
		||||
                    fileReRoute.UpstreamHttpMethod, upstreamTemplate, isAuthenticated,
 | 
			
		||||
                    authOptionsForRoute, claimsToHeaders, claimsToClaims,
 | 
			
		||||
                    reRoute.RouteClaimsRequirement, isAuthorised, claimsToQueries,
 | 
			
		||||
                    requestIdKey, isCached, new CacheOptions(reRoute.FileCacheOptions.TtlSeconds),
 | 
			
		||||
                    reRoute.ServiceName, useServiceDiscovery, globalConfiguration?.ServiceDiscoveryProvider?.Provider,
 | 
			
		||||
                    globalConfiguration?.ServiceDiscoveryProvider?.Address, reRoute.DownstreamScheme, 
 | 
			
		||||
                    reRoute.LoadBalancer, reRoute.DownstreamHost, reRoute.DownstreamPort);
 | 
			
		||||
                    fileReRoute.RouteClaimsRequirement, isAuthorised, claimsToQueries,
 | 
			
		||||
                    requestIdKey, isCached, new CacheOptions(fileReRoute.FileCacheOptions.TtlSeconds),
 | 
			
		||||
                    fileReRoute.ServiceName, useServiceDiscovery, globalConfiguration?.ServiceDiscoveryProvider?.Provider,
 | 
			
		||||
                    globalConfiguration?.ServiceDiscoveryProvider?.Address, fileReRoute.DownstreamScheme, 
 | 
			
		||||
                    fileReRoute.LoadBalancer, fileReRoute.DownstreamHost, fileReRoute.DownstreamPort);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return new ReRoute(new DownstreamPathTemplate(reRoute.DownstreamPathTemplate), reRoute.UpstreamTemplate, 
 | 
			
		||||
                reRoute.UpstreamHttpMethod, upstreamTemplate, isAuthenticated, 
 | 
			
		||||
            reRoute = new ReRoute(new DownstreamPathTemplate(fileReRoute.DownstreamPathTemplate), fileReRoute.UpstreamTemplate, 
 | 
			
		||||
                fileReRoute.UpstreamHttpMethod, upstreamTemplate, isAuthenticated, 
 | 
			
		||||
                null, new List<ClaimToThing>(), new List<ClaimToThing>(), 
 | 
			
		||||
                reRoute.RouteClaimsRequirement, isAuthorised, new List<ClaimToThing>(),
 | 
			
		||||
                    requestIdKey, isCached, new CacheOptions(reRoute.FileCacheOptions.TtlSeconds),
 | 
			
		||||
                    reRoute.ServiceName, useServiceDiscovery, globalConfiguration?.ServiceDiscoveryProvider?.Provider,
 | 
			
		||||
                    globalConfiguration?.ServiceDiscoveryProvider?.Address, reRoute.DownstreamScheme,
 | 
			
		||||
                    reRoute.LoadBalancer, reRoute.DownstreamHost, reRoute.DownstreamPort);
 | 
			
		||||
                fileReRoute.RouteClaimsRequirement, isAuthorised, new List<ClaimToThing>(),
 | 
			
		||||
                    requestIdKey, isCached, new CacheOptions(fileReRoute.FileCacheOptions.TtlSeconds),
 | 
			
		||||
                    fileReRoute.ServiceName, useServiceDiscovery, globalConfiguration?.ServiceDiscoveryProvider?.Provider,
 | 
			
		||||
                    globalConfiguration?.ServiceDiscoveryProvider?.Address, fileReRoute.DownstreamScheme,
 | 
			
		||||
                    fileReRoute.LoadBalancer, fileReRoute.DownstreamHost, fileReRoute.DownstreamPort);
 | 
			
		||||
 | 
			
		||||
            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);
 | 
			
		||||
            return reRoute;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private string BuildUpstreamTemplate(FileReRoute reRoute)
 | 
			
		||||
 
 | 
			
		||||
@@ -23,11 +23,13 @@ using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer;
 | 
			
		||||
using Ocelot.Headers;
 | 
			
		||||
using Ocelot.Infrastructure.Claims.Parser;
 | 
			
		||||
using Ocelot.Infrastructure.RequestData;
 | 
			
		||||
using Ocelot.LoadBalancer.LoadBalancers;
 | 
			
		||||
using Ocelot.Logging;
 | 
			
		||||
using Ocelot.QueryStrings;
 | 
			
		||||
using Ocelot.Request.Builder;
 | 
			
		||||
using Ocelot.Requester;
 | 
			
		||||
using Ocelot.Responder;
 | 
			
		||||
using Ocelot.ServiceDiscovery;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.DependencyInjection
 | 
			
		||||
{
 | 
			
		||||
@@ -59,6 +61,10 @@ namespace Ocelot.DependencyInjection
 | 
			
		||||
        {
 | 
			
		||||
            services.AddMvcCore().AddJsonFormatters();
 | 
			
		||||
            services.AddLogging();
 | 
			
		||||
            services.AddSingleton<Ocelot.ServiceDiscovery.IServiceProviderFactory, Ocelot.ServiceDiscovery.IServiceProviderFactory>();
 | 
			
		||||
            services.AddSingleton<ILoadBalancerFactory, ILoadBalancerFactory>();
 | 
			
		||||
            services.AddSingleton<ILoadBalancerHouse, LoadBalancerHouse>();
 | 
			
		||||
            services.AddSingleton<IServiceProviderHouse, ServiceProviderHouse>();
 | 
			
		||||
            services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
 | 
			
		||||
            services.AddSingleton<IUrlBuilder, UrlBuilder>();
 | 
			
		||||
            services.AddSingleton<IRemoveOutputHeaders, RemoveOutputHeaders>();
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,9 @@
 | 
			
		||||
namespace Ocelot.LoadBalancer.LoadBalancers
 | 
			
		||||
using Ocelot.Configuration;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.LoadBalancer.LoadBalancers
 | 
			
		||||
{
 | 
			
		||||
    public interface ILoadBalancerFactory
 | 
			
		||||
    {
 | 
			
		||||
        ILoadBalancer Get(string serviceName, string loadBalancer);
 | 
			
		||||
        ILoadBalancer Get(ReRoute reRoute);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,26 +1,34 @@
 | 
			
		||||
using Ocelot.ServiceDiscovery;
 | 
			
		||||
using Ocelot.Configuration;
 | 
			
		||||
using Ocelot.ServiceDiscovery;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.LoadBalancer.LoadBalancers
 | 
			
		||||
{
 | 
			
		||||
    public class LoadBalancerFactory : ILoadBalancerFactory
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IServiceProvider _serviceProvider;
 | 
			
		||||
 | 
			
		||||
        public LoadBalancerFactory(IServiceProvider serviceProvider)
 | 
			
		||||
        private readonly IServiceProviderFactory _serviceProviderFactory;
 | 
			
		||||
        public LoadBalancerFactory(IServiceProviderFactory serviceProviderFactory)
 | 
			
		||||
        {
 | 
			
		||||
            _serviceProvider = serviceProvider;
 | 
			
		||||
            _serviceProviderFactory = serviceProviderFactory;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ILoadBalancer Get(string serviceName, string loadBalancer)
 | 
			
		||||
        public ILoadBalancer Get(ReRoute reRoute)
 | 
			
		||||
        {
 | 
			
		||||
            switch (loadBalancer)
 | 
			
		||||
            var serviceConfig = new ServiceConfiguraion(
 | 
			
		||||
                reRoute.ServiceName,
 | 
			
		||||
                reRoute.DownstreamHost,
 | 
			
		||||
                reRoute.DownstreamPort,
 | 
			
		||||
                reRoute.UseServiceDiscovery);
 | 
			
		||||
            
 | 
			
		||||
            var serviceProvider = _serviceProviderFactory.Get(serviceConfig);
 | 
			
		||||
 | 
			
		||||
            switch (reRoute.LoadBalancer)
 | 
			
		||||
            {
 | 
			
		||||
                case "RoundRobin":
 | 
			
		||||
                    return new RoundRobinLoadBalancer(_serviceProvider.Get());
 | 
			
		||||
                    return new RoundRobinLoadBalancer(serviceProvider.Get());
 | 
			
		||||
                case "LeastConnection":
 | 
			
		||||
                    return new LeastConnectionLoadBalancer(() => _serviceProvider.Get(), serviceName);
 | 
			
		||||
                    return new LeastConnectionLoadBalancer(() => serviceProvider.Get(), reRoute.ServiceName);
 | 
			
		||||
                default:
 | 
			
		||||
                    return new NoLoadBalancer(_serviceProvider.Get());
 | 
			
		||||
                    return new NoLoadBalancer(serviceProvider.Get());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -14,37 +14,30 @@ namespace Ocelot.LoadBalancer.Middleware
 | 
			
		||||
    {
 | 
			
		||||
        private readonly RequestDelegate _next;
 | 
			
		||||
        private readonly IOcelotLogger _logger;
 | 
			
		||||
        private readonly ILoadBalancerHouse _loadBalancerHouse;
 | 
			
		||||
 | 
			
		||||
        public LoadBalancingMiddleware(RequestDelegate next,
 | 
			
		||||
            IOcelotLoggerFactory loggerFactory,
 | 
			
		||||
            IRequestScopedDataRepository requestScopedDataRepository) 
 | 
			
		||||
            IRequestScopedDataRepository requestScopedDataRepository,
 | 
			
		||||
            ILoadBalancerHouse loadBalancerHouse) 
 | 
			
		||||
            : base(requestScopedDataRepository)
 | 
			
		||||
        {
 | 
			
		||||
            _next = next;
 | 
			
		||||
            _logger = loggerFactory.CreateLogger<QueryStringBuilderMiddleware>();
 | 
			
		||||
            _loadBalancerHouse = loadBalancerHouse;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task Invoke(HttpContext context)
 | 
			
		||||
        {
 | 
			
		||||
            _logger.LogDebug("started calling query string builder middleware");
 | 
			
		||||
 | 
			
		||||
            //todo - get out of di? or do this when we bootstrap?
 | 
			
		||||
            var serviceProviderFactory = new ServiceProviderFactory();
 | 
			
		||||
            var serviceConfig = new ServiceConfiguraion(
 | 
			
		||||
                DownstreamRoute.ReRoute.ServiceName,
 | 
			
		||||
                DownstreamRoute.ReRoute.DownstreamHost,
 | 
			
		||||
                DownstreamRoute.ReRoute.DownstreamPort,
 | 
			
		||||
                DownstreamRoute.ReRoute.UseServiceDiscovery);
 | 
			
		||||
            //todo - get this out of some kind of service provider house?
 | 
			
		||||
            var serviceProvider = serviceProviderFactory.Get(serviceConfig);
 | 
			
		||||
 | 
			
		||||
            //todo - get out of di? or do this when we bootstrap?
 | 
			
		||||
            var loadBalancerFactory = new LoadBalancerFactory(serviceProvider);
 | 
			
		||||
            //todo - currently instanciates a load balancer per request which is wrong, 
 | 
			
		||||
            //need some kind of load balance house! :)
 | 
			
		||||
            var loadBalancer = loadBalancerFactory.Get(DownstreamRoute.ReRoute.ServiceName, DownstreamRoute.ReRoute.LoadBalancer);
 | 
			
		||||
            var response = loadBalancer.Lease();
 | 
			
		||||
 | 
			
		||||
            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);
 | 
			
		||||
            _logger.LogDebug("calling next middleware");
 | 
			
		||||
 | 
			
		||||
            //todo - try next middleware if we get an exception make sure we release 
 | 
			
		||||
@@ -53,11 +46,11 @@ namespace Ocelot.LoadBalancer.Middleware
 | 
			
		||||
            {
 | 
			
		||||
                await _next.Invoke(context);
 | 
			
		||||
 | 
			
		||||
                loadBalancer.Release(response.Data);
 | 
			
		||||
                loadBalancer.Data.Release(response.Data);
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception exception)
 | 
			
		||||
            catch (Exception)
 | 
			
		||||
            {
 | 
			
		||||
                loadBalancer.Release(response.Data);
 | 
			
		||||
                loadBalancer.Data.Release(response.Data);
 | 
			
		||||
                throw;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,12 @@
 | 
			
		||||
using Microsoft.AspNetCore.Builder;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.LoadBalancer.Middleware
 | 
			
		||||
{
 | 
			
		||||
 public static class LoadBalancingMiddlewareExtensions
 | 
			
		||||
    {
 | 
			
		||||
        public static IApplicationBuilder UseLoadBalancingMiddlewareExtensions(this IApplicationBuilder builder)
 | 
			
		||||
        {
 | 
			
		||||
            return builder.UseMiddleware<LoadBalancingMiddleware>();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -3,6 +3,7 @@ using System.Net.Http;
 | 
			
		||||
using Ocelot.DownstreamRouteFinder;
 | 
			
		||||
using Ocelot.Errors;
 | 
			
		||||
using Ocelot.Infrastructure.RequestData;
 | 
			
		||||
using Ocelot.Values;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Middleware
 | 
			
		||||
{
 | 
			
		||||
@@ -69,6 +70,20 @@ namespace Ocelot.Middleware
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public HostAndPort HostAndPort 
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                var hostAndPort = _requestScopedDataRepository.Get<HostAndPort>("HostAndPort");
 | 
			
		||||
                return hostAndPort.Data;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void SetHostAndPortForThisRequest(HostAndPort hostAndPort)
 | 
			
		||||
        {
 | 
			
		||||
            _requestScopedDataRepository.Add("HostAndPort", hostAndPort);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void SetDownstreamRouteForThisRequest(DownstreamRoute downstreamRoute)
 | 
			
		||||
        {
 | 
			
		||||
            _requestScopedDataRepository.Add("DownstreamRoute", downstreamRoute);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,5 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.ServiceDiscovery
 | 
			
		||||
{
 | 
			
		||||
    public interface IServiceProviderFactory
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using Ocelot.Responses;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.ServiceDiscovery
 | 
			
		||||
{
 | 
			
		||||
    public interface IServiceProviderHouse
 | 
			
		||||
    {
 | 
			
		||||
        Response<IServiceProvider> Get(string key);
 | 
			
		||||
        Response Add(string key, IServiceProvider serviceProvider);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,34 +0,0 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using Ocelot.Responses;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.ServiceDiscovery
 | 
			
		||||
{
 | 
			
		||||
     public class ServiceProviderHouse : IServiceProviderHouse
 | 
			
		||||
    {
 | 
			
		||||
        private Dictionary<string, Ocelot.ServiceDiscovery.IServiceProvider> _serviceProviders;
 | 
			
		||||
 | 
			
		||||
        public ServiceProviderHouse()
 | 
			
		||||
        {
 | 
			
		||||
            _serviceProviders = new Dictionary<string, Ocelot.ServiceDiscovery.IServiceProvider>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Response<IServiceProvider> Get(string key)
 | 
			
		||||
        {
 | 
			
		||||
            IServiceProvider serviceProvider;
 | 
			
		||||
            if(_serviceProviders.TryGetValue(key, out serviceProvider))
 | 
			
		||||
            {
 | 
			
		||||
                return new OkResponse<Ocelot.ServiceDiscovery.IServiceProvider>(serviceProvider);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return new ErrorResponse<IServiceProvider>(new List<Ocelot.Errors.Error>()
 | 
			
		||||
            {
 | 
			
		||||
                new UnableToFindServiceProviderError($"unabe to find service provider for {key}")
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        public Response Add(string key, IServiceProvider serviceProvider)
 | 
			
		||||
        {
 | 
			
		||||
            _serviceProviders[key] = serviceProvider;
 | 
			
		||||
            return new OkResponse();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user