mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-11-04 09:15:27 +08:00 
			
		
		
		
	refactoring to consolidate configuration code
This commit is contained in:
		@@ -1,230 +1,230 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Microsoft.Extensions.Options;
 | 
			
		||||
using Ocelot.Cache;
 | 
			
		||||
using Ocelot.Configuration.Builder;
 | 
			
		||||
using Ocelot.Configuration.File;
 | 
			
		||||
using Ocelot.Configuration.Validator;
 | 
			
		||||
using Ocelot.DependencyInjection;
 | 
			
		||||
using Ocelot.Logging;
 | 
			
		||||
using Ocelot.Responses;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration.Creator
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Register as singleton
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class FileOcelotConfigurationCreator : IOcelotConfigurationCreator
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IOptions<FileConfiguration> _options;
 | 
			
		||||
        private readonly IConfigurationValidator _configurationValidator;
 | 
			
		||||
        private readonly IOcelotLogger _logger;
 | 
			
		||||
        private readonly IClaimsToThingCreator _claimsToThingCreator;
 | 
			
		||||
        private readonly IAuthenticationOptionsCreator _authOptionsCreator;
 | 
			
		||||
        private readonly IUpstreamTemplatePatternCreator _upstreamTemplatePatternCreator;
 | 
			
		||||
        private readonly IRequestIdKeyCreator _requestIdKeyCreator;
 | 
			
		||||
        private readonly IServiceProviderConfigurationCreator _serviceProviderConfigCreator;
 | 
			
		||||
        private readonly IQoSOptionsCreator _qosOptionsCreator;
 | 
			
		||||
        private readonly IReRouteOptionsCreator _fileReRouteOptionsCreator;
 | 
			
		||||
        private readonly IRateLimitOptionsCreator _rateLimitOptionsCreator;
 | 
			
		||||
        private readonly IRegionCreator _regionCreator;
 | 
			
		||||
        private readonly IHttpHandlerOptionsCreator _httpHandlerOptionsCreator;
 | 
			
		||||
        private readonly IAdministrationPath _adminPath;
 | 
			
		||||
        private readonly IHeaderFindAndReplaceCreator _headerFAndRCreator;
 | 
			
		||||
        private readonly IDownstreamAddressesCreator _downstreamAddressesCreator;
 | 
			
		||||
 | 
			
		||||
        public FileOcelotConfigurationCreator(
 | 
			
		||||
            IOptions<FileConfiguration> options, 
 | 
			
		||||
            IConfigurationValidator configurationValidator,
 | 
			
		||||
            IOcelotLoggerFactory loggerFactory,
 | 
			
		||||
            IClaimsToThingCreator claimsToThingCreator,
 | 
			
		||||
            IAuthenticationOptionsCreator authOptionsCreator,
 | 
			
		||||
            IUpstreamTemplatePatternCreator upstreamTemplatePatternCreator,
 | 
			
		||||
            IRequestIdKeyCreator requestIdKeyCreator,
 | 
			
		||||
            IServiceProviderConfigurationCreator serviceProviderConfigCreator,
 | 
			
		||||
            IQoSOptionsCreator qosOptionsCreator,
 | 
			
		||||
            IReRouteOptionsCreator fileReRouteOptionsCreator,
 | 
			
		||||
            IRateLimitOptionsCreator rateLimitOptionsCreator,
 | 
			
		||||
            IRegionCreator regionCreator,
 | 
			
		||||
            IHttpHandlerOptionsCreator httpHandlerOptionsCreator,
 | 
			
		||||
            IAdministrationPath adminPath,
 | 
			
		||||
            IHeaderFindAndReplaceCreator headerFAndRCreator,
 | 
			
		||||
            IDownstreamAddressesCreator downstreamAddressesCreator
 | 
			
		||||
            )
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamAddressesCreator = downstreamAddressesCreator;
 | 
			
		||||
            _headerFAndRCreator = headerFAndRCreator;
 | 
			
		||||
            _adminPath = adminPath;
 | 
			
		||||
            _regionCreator = regionCreator;
 | 
			
		||||
            _rateLimitOptionsCreator = rateLimitOptionsCreator;
 | 
			
		||||
            _requestIdKeyCreator = requestIdKeyCreator;
 | 
			
		||||
            _upstreamTemplatePatternCreator = upstreamTemplatePatternCreator;
 | 
			
		||||
            _authOptionsCreator = authOptionsCreator;
 | 
			
		||||
            _options = options;
 | 
			
		||||
            _configurationValidator = configurationValidator;
 | 
			
		||||
            _logger = loggerFactory.CreateLogger<FileOcelotConfigurationCreator>();
 | 
			
		||||
            _claimsToThingCreator = claimsToThingCreator;
 | 
			
		||||
            _serviceProviderConfigCreator = serviceProviderConfigCreator;
 | 
			
		||||
            _qosOptionsCreator = qosOptionsCreator;
 | 
			
		||||
            _fileReRouteOptionsCreator = fileReRouteOptionsCreator;
 | 
			
		||||
            _httpHandlerOptionsCreator = httpHandlerOptionsCreator;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        public async Task<Response<IOcelotConfiguration>> Create(FileConfiguration fileConfiguration)
 | 
			
		||||
        {     
 | 
			
		||||
            var config = await SetUpConfiguration(fileConfiguration);
 | 
			
		||||
            return config;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async Task<Response<IOcelotConfiguration>> SetUpConfiguration(FileConfiguration fileConfiguration)
 | 
			
		||||
        {
 | 
			
		||||
            var response = await _configurationValidator.IsValid(fileConfiguration);
 | 
			
		||||
 | 
			
		||||
            if (response.Data.IsError)
 | 
			
		||||
            {
 | 
			
		||||
                return new ErrorResponse<IOcelotConfiguration>(response.Data.Errors);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var reRoutes = new List<ReRoute>();
 | 
			
		||||
 | 
			
		||||
            foreach (var reRoute in fileConfiguration.ReRoutes)
 | 
			
		||||
            {
 | 
			
		||||
                var downstreamReRoute = SetUpDownstreamReRoute(reRoute, fileConfiguration.GlobalConfiguration);
 | 
			
		||||
 | 
			
		||||
                var ocelotReRoute = SetUpReRoute(reRoute, downstreamReRoute);
 | 
			
		||||
                
 | 
			
		||||
                reRoutes.Add(ocelotReRoute);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            foreach (var aggregate in fileConfiguration.Aggregates)
 | 
			
		||||
            {
 | 
			
		||||
                var ocelotReRoute = SetUpAggregateReRoute(reRoutes, aggregate, fileConfiguration.GlobalConfiguration);
 | 
			
		||||
                reRoutes.Add(ocelotReRoute);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var serviceProviderConfiguration = _serviceProviderConfigCreator.Create(fileConfiguration.GlobalConfiguration);
 | 
			
		||||
            
 | 
			
		||||
            var config = new OcelotConfiguration(reRoutes, _adminPath.Path, serviceProviderConfiguration, fileConfiguration.GlobalConfiguration.RequestIdKey);
 | 
			
		||||
 | 
			
		||||
            return new OkResponse<IOcelotConfiguration>(config);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ReRoute SetUpAggregateReRoute(List<ReRoute> reRoutes, FileAggregateReRoute aggregateReRoute, FileGlobalConfiguration globalConfiguration)
 | 
			
		||||
        {
 | 
			
		||||
            var applicableReRoutes = reRoutes
 | 
			
		||||
                .SelectMany(x => x.DownstreamReRoute)
 | 
			
		||||
                .Where(r => aggregateReRoute.ReRouteKeys.Contains(r.Key))
 | 
			
		||||
                .ToList();
 | 
			
		||||
 | 
			
		||||
            if(applicableReRoutes.Count != aggregateReRoute.ReRouteKeys.Count)
 | 
			
		||||
            {
 | 
			
		||||
                //todo - log or throw or return error whatever?
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            //make another re route out of these
 | 
			
		||||
            var upstreamTemplatePattern = _upstreamTemplatePatternCreator.Create(aggregateReRoute);
 | 
			
		||||
 | 
			
		||||
            var reRoute = new ReRouteBuilder()
 | 
			
		||||
                .WithUpstreamPathTemplate(aggregateReRoute.UpstreamPathTemplate)
 | 
			
		||||
                .WithUpstreamHttpMethod(aggregateReRoute.UpstreamHttpMethod)
 | 
			
		||||
                .WithUpstreamTemplatePattern(upstreamTemplatePattern)
 | 
			
		||||
                .WithDownstreamReRoutes(applicableReRoutes)
 | 
			
		||||
                .WithUpstreamHost(aggregateReRoute.UpstreamHost)
 | 
			
		||||
                .WithAggregator(aggregateReRoute.Aggregator)
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            return reRoute;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private ReRoute SetUpReRoute(FileReRoute fileReRoute, DownstreamReRoute downstreamReRoutes)
 | 
			
		||||
        {
 | 
			
		||||
            var upstreamTemplatePattern = _upstreamTemplatePatternCreator.Create(fileReRoute);
 | 
			
		||||
 | 
			
		||||
            var reRoute = new ReRouteBuilder()
 | 
			
		||||
                .WithUpstreamPathTemplate(fileReRoute.UpstreamPathTemplate)
 | 
			
		||||
                .WithUpstreamHttpMethod(fileReRoute.UpstreamHttpMethod)
 | 
			
		||||
                .WithUpstreamTemplatePattern(upstreamTemplatePattern)
 | 
			
		||||
                .WithDownstreamReRoute(downstreamReRoutes)
 | 
			
		||||
                .WithUpstreamHost(fileReRoute.UpstreamHost)
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            return reRoute;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
         private DownstreamReRoute SetUpDownstreamReRoute(FileReRoute fileReRoute, FileGlobalConfiguration globalConfiguration)
 | 
			
		||||
        {
 | 
			
		||||
            var fileReRouteOptions = _fileReRouteOptionsCreator.Create(fileReRoute);
 | 
			
		||||
 | 
			
		||||
            var requestIdKey = _requestIdKeyCreator.Create(fileReRoute, globalConfiguration);
 | 
			
		||||
 | 
			
		||||
            var reRouteKey = CreateReRouteKey(fileReRoute);
 | 
			
		||||
 | 
			
		||||
            var upstreamTemplatePattern = _upstreamTemplatePatternCreator.Create(fileReRoute);
 | 
			
		||||
 | 
			
		||||
            var authOptionsForRoute = _authOptionsCreator.Create(fileReRoute);
 | 
			
		||||
 | 
			
		||||
            var claimsToHeaders = _claimsToThingCreator.Create(fileReRoute.AddHeadersToRequest);
 | 
			
		||||
 | 
			
		||||
            var claimsToClaims = _claimsToThingCreator.Create(fileReRoute.AddClaimsToRequest);
 | 
			
		||||
 | 
			
		||||
            var claimsToQueries = _claimsToThingCreator.Create(fileReRoute.AddQueriesToRequest);
 | 
			
		||||
 | 
			
		||||
            var qosOptions = _qosOptionsCreator.Create(fileReRoute);
 | 
			
		||||
 | 
			
		||||
            var rateLimitOption = _rateLimitOptionsCreator.Create(fileReRoute, globalConfiguration, fileReRouteOptions.EnableRateLimiting);
 | 
			
		||||
 | 
			
		||||
            var region = _regionCreator.Create(fileReRoute);
 | 
			
		||||
 | 
			
		||||
            var httpHandlerOptions = _httpHandlerOptionsCreator.Create(fileReRoute);
 | 
			
		||||
 | 
			
		||||
            var hAndRs = _headerFAndRCreator.Create(fileReRoute);
 | 
			
		||||
 | 
			
		||||
            var downstreamAddresses = _downstreamAddressesCreator.Create(fileReRoute);
 | 
			
		||||
 | 
			
		||||
            var reRoute = new DownstreamReRouteBuilder()
 | 
			
		||||
                .WithKey(fileReRoute.Key)
 | 
			
		||||
                .WithDownstreamPathTemplate(fileReRoute.DownstreamPathTemplate)
 | 
			
		||||
                .WithUpstreamPathTemplate(fileReRoute.UpstreamPathTemplate)
 | 
			
		||||
                .WithUpstreamHttpMethod(fileReRoute.UpstreamHttpMethod)
 | 
			
		||||
                .WithUpstreamTemplatePattern(upstreamTemplatePattern)
 | 
			
		||||
                .WithIsAuthenticated(fileReRouteOptions.IsAuthenticated)
 | 
			
		||||
                .WithAuthenticationOptions(authOptionsForRoute)
 | 
			
		||||
                .WithClaimsToHeaders(claimsToHeaders)
 | 
			
		||||
                .WithClaimsToClaims(claimsToClaims)
 | 
			
		||||
                .WithRouteClaimsRequirement(fileReRoute.RouteClaimsRequirement)
 | 
			
		||||
                .WithIsAuthorised(fileReRouteOptions.IsAuthorised)
 | 
			
		||||
                .WithClaimsToQueries(claimsToQueries)
 | 
			
		||||
                .WithRequestIdKey(requestIdKey)
 | 
			
		||||
                .WithIsCached(fileReRouteOptions.IsCached)
 | 
			
		||||
                .WithCacheOptions(new CacheOptions(fileReRoute.FileCacheOptions.TtlSeconds, region))
 | 
			
		||||
                .WithDownstreamScheme(fileReRoute.DownstreamScheme)
 | 
			
		||||
                .WithLoadBalancer(fileReRoute.LoadBalancer)
 | 
			
		||||
                .WithDownstreamAddresses(downstreamAddresses)
 | 
			
		||||
                .WithReRouteKey(reRouteKey)
 | 
			
		||||
                .WithIsQos(fileReRouteOptions.IsQos)
 | 
			
		||||
                .WithQosOptions(qosOptions)
 | 
			
		||||
                .WithEnableRateLimiting(fileReRouteOptions.EnableRateLimiting)
 | 
			
		||||
                .WithRateLimitOptions(rateLimitOption)
 | 
			
		||||
                .WithHttpHandlerOptions(httpHandlerOptions)
 | 
			
		||||
                .WithServiceName(fileReRoute.ServiceName)
 | 
			
		||||
                .WithUseServiceDiscovery(fileReRoute.UseServiceDiscovery)
 | 
			
		||||
                .WithUpstreamHeaderFindAndReplace(hAndRs.Upstream)
 | 
			
		||||
                .WithDownstreamHeaderFindAndReplace(hAndRs.Downstream)
 | 
			
		||||
                .WithUpstreamHost(fileReRoute.UpstreamHost)
 | 
			
		||||
                .WithDelegatingHandlers(fileReRoute.DelegatingHandlers)
 | 
			
		||||
                .WithAddHeadersToDownstream(hAndRs.AddHeadersToDownstream)
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            return reRoute;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private string CreateReRouteKey(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}|{string.Join(",", fileReRoute.UpstreamHttpMethod)}";
 | 
			
		||||
            return loadBalancerKey;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Microsoft.Extensions.Options;
 | 
			
		||||
using Ocelot.Cache;
 | 
			
		||||
using Ocelot.Configuration.Builder;
 | 
			
		||||
using Ocelot.Configuration.File;
 | 
			
		||||
using Ocelot.Configuration.Validator;
 | 
			
		||||
using Ocelot.DependencyInjection;
 | 
			
		||||
using Ocelot.Logging;
 | 
			
		||||
using Ocelot.Responses;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration.Creator
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Register as singleton
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class FileInternalConfigurationCreator : IInternalConfigurationCreator
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IOptions<FileConfiguration> _options;
 | 
			
		||||
        private readonly IConfigurationValidator _configurationValidator;
 | 
			
		||||
        private readonly IOcelotLogger _logger;
 | 
			
		||||
        private readonly IClaimsToThingCreator _claimsToThingCreator;
 | 
			
		||||
        private readonly IAuthenticationOptionsCreator _authOptionsCreator;
 | 
			
		||||
        private readonly IUpstreamTemplatePatternCreator _upstreamTemplatePatternCreator;
 | 
			
		||||
        private readonly IRequestIdKeyCreator _requestIdKeyCreator;
 | 
			
		||||
        private readonly IServiceProviderConfigurationCreator _serviceProviderConfigCreator;
 | 
			
		||||
        private readonly IQoSOptionsCreator _qosOptionsCreator;
 | 
			
		||||
        private readonly IReRouteOptionsCreator _fileReRouteOptionsCreator;
 | 
			
		||||
        private readonly IRateLimitOptionsCreator _rateLimitOptionsCreator;
 | 
			
		||||
        private readonly IRegionCreator _regionCreator;
 | 
			
		||||
        private readonly IHttpHandlerOptionsCreator _httpHandlerOptionsCreator;
 | 
			
		||||
        private readonly IAdministrationPath _adminPath;
 | 
			
		||||
        private readonly IHeaderFindAndReplaceCreator _headerFAndRCreator;
 | 
			
		||||
        private readonly IDownstreamAddressesCreator _downstreamAddressesCreator;
 | 
			
		||||
 | 
			
		||||
        public FileInternalConfigurationCreator(
 | 
			
		||||
            IOptions<FileConfiguration> options, 
 | 
			
		||||
            IConfigurationValidator configurationValidator,
 | 
			
		||||
            IOcelotLoggerFactory loggerFactory,
 | 
			
		||||
            IClaimsToThingCreator claimsToThingCreator,
 | 
			
		||||
            IAuthenticationOptionsCreator authOptionsCreator,
 | 
			
		||||
            IUpstreamTemplatePatternCreator upstreamTemplatePatternCreator,
 | 
			
		||||
            IRequestIdKeyCreator requestIdKeyCreator,
 | 
			
		||||
            IServiceProviderConfigurationCreator serviceProviderConfigCreator,
 | 
			
		||||
            IQoSOptionsCreator qosOptionsCreator,
 | 
			
		||||
            IReRouteOptionsCreator fileReRouteOptionsCreator,
 | 
			
		||||
            IRateLimitOptionsCreator rateLimitOptionsCreator,
 | 
			
		||||
            IRegionCreator regionCreator,
 | 
			
		||||
            IHttpHandlerOptionsCreator httpHandlerOptionsCreator,
 | 
			
		||||
            IAdministrationPath adminPath,
 | 
			
		||||
            IHeaderFindAndReplaceCreator headerFAndRCreator,
 | 
			
		||||
            IDownstreamAddressesCreator downstreamAddressesCreator
 | 
			
		||||
            )
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamAddressesCreator = downstreamAddressesCreator;
 | 
			
		||||
            _headerFAndRCreator = headerFAndRCreator;
 | 
			
		||||
            _adminPath = adminPath;
 | 
			
		||||
            _regionCreator = regionCreator;
 | 
			
		||||
            _rateLimitOptionsCreator = rateLimitOptionsCreator;
 | 
			
		||||
            _requestIdKeyCreator = requestIdKeyCreator;
 | 
			
		||||
            _upstreamTemplatePatternCreator = upstreamTemplatePatternCreator;
 | 
			
		||||
            _authOptionsCreator = authOptionsCreator;
 | 
			
		||||
            _options = options;
 | 
			
		||||
            _configurationValidator = configurationValidator;
 | 
			
		||||
            _logger = loggerFactory.CreateLogger<FileInternalConfigurationCreator>();
 | 
			
		||||
            _claimsToThingCreator = claimsToThingCreator;
 | 
			
		||||
            _serviceProviderConfigCreator = serviceProviderConfigCreator;
 | 
			
		||||
            _qosOptionsCreator = qosOptionsCreator;
 | 
			
		||||
            _fileReRouteOptionsCreator = fileReRouteOptionsCreator;
 | 
			
		||||
            _httpHandlerOptionsCreator = httpHandlerOptionsCreator;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        public async Task<Response<IInternalConfiguration>> Create(FileConfiguration fileConfiguration)
 | 
			
		||||
        {     
 | 
			
		||||
            var config = await SetUpConfiguration(fileConfiguration);
 | 
			
		||||
            return config;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async Task<Response<IInternalConfiguration>> SetUpConfiguration(FileConfiguration fileConfiguration)
 | 
			
		||||
        {
 | 
			
		||||
            var response = await _configurationValidator.IsValid(fileConfiguration);
 | 
			
		||||
 | 
			
		||||
            if (response.Data.IsError)
 | 
			
		||||
            {
 | 
			
		||||
                return new ErrorResponse<IInternalConfiguration>(response.Data.Errors);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var reRoutes = new List<ReRoute>();
 | 
			
		||||
 | 
			
		||||
            foreach (var reRoute in fileConfiguration.ReRoutes)
 | 
			
		||||
            {
 | 
			
		||||
                var downstreamReRoute = SetUpDownstreamReRoute(reRoute, fileConfiguration.GlobalConfiguration);
 | 
			
		||||
 | 
			
		||||
                var ocelotReRoute = SetUpReRoute(reRoute, downstreamReRoute);
 | 
			
		||||
                
 | 
			
		||||
                reRoutes.Add(ocelotReRoute);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            foreach (var aggregate in fileConfiguration.Aggregates)
 | 
			
		||||
            {
 | 
			
		||||
                var ocelotReRoute = SetUpAggregateReRoute(reRoutes, aggregate, fileConfiguration.GlobalConfiguration);
 | 
			
		||||
                reRoutes.Add(ocelotReRoute);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var serviceProviderConfiguration = _serviceProviderConfigCreator.Create(fileConfiguration.GlobalConfiguration);
 | 
			
		||||
            
 | 
			
		||||
            var config = new InternalConfiguration(reRoutes, _adminPath.Path, serviceProviderConfiguration, fileConfiguration.GlobalConfiguration.RequestIdKey);
 | 
			
		||||
 | 
			
		||||
            return new OkResponse<IInternalConfiguration>(config);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ReRoute SetUpAggregateReRoute(List<ReRoute> reRoutes, FileAggregateReRoute aggregateReRoute, FileGlobalConfiguration globalConfiguration)
 | 
			
		||||
        {
 | 
			
		||||
            var applicableReRoutes = reRoutes
 | 
			
		||||
                .SelectMany(x => x.DownstreamReRoute)
 | 
			
		||||
                .Where(r => aggregateReRoute.ReRouteKeys.Contains(r.Key))
 | 
			
		||||
                .ToList();
 | 
			
		||||
 | 
			
		||||
            if(applicableReRoutes.Count != aggregateReRoute.ReRouteKeys.Count)
 | 
			
		||||
            {
 | 
			
		||||
                //todo - log or throw or return error whatever?
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            //make another re route out of these
 | 
			
		||||
            var upstreamTemplatePattern = _upstreamTemplatePatternCreator.Create(aggregateReRoute);
 | 
			
		||||
 | 
			
		||||
            var reRoute = new ReRouteBuilder()
 | 
			
		||||
                .WithUpstreamPathTemplate(aggregateReRoute.UpstreamPathTemplate)
 | 
			
		||||
                .WithUpstreamHttpMethod(aggregateReRoute.UpstreamHttpMethod)
 | 
			
		||||
                .WithUpstreamTemplatePattern(upstreamTemplatePattern)
 | 
			
		||||
                .WithDownstreamReRoutes(applicableReRoutes)
 | 
			
		||||
                .WithUpstreamHost(aggregateReRoute.UpstreamHost)
 | 
			
		||||
                .WithAggregator(aggregateReRoute.Aggregator)
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            return reRoute;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private ReRoute SetUpReRoute(FileReRoute fileReRoute, DownstreamReRoute downstreamReRoutes)
 | 
			
		||||
        {
 | 
			
		||||
            var upstreamTemplatePattern = _upstreamTemplatePatternCreator.Create(fileReRoute);
 | 
			
		||||
 | 
			
		||||
            var reRoute = new ReRouteBuilder()
 | 
			
		||||
                .WithUpstreamPathTemplate(fileReRoute.UpstreamPathTemplate)
 | 
			
		||||
                .WithUpstreamHttpMethod(fileReRoute.UpstreamHttpMethod)
 | 
			
		||||
                .WithUpstreamTemplatePattern(upstreamTemplatePattern)
 | 
			
		||||
                .WithDownstreamReRoute(downstreamReRoutes)
 | 
			
		||||
                .WithUpstreamHost(fileReRoute.UpstreamHost)
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            return reRoute;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
         private DownstreamReRoute SetUpDownstreamReRoute(FileReRoute fileReRoute, FileGlobalConfiguration globalConfiguration)
 | 
			
		||||
        {
 | 
			
		||||
            var fileReRouteOptions = _fileReRouteOptionsCreator.Create(fileReRoute);
 | 
			
		||||
 | 
			
		||||
            var requestIdKey = _requestIdKeyCreator.Create(fileReRoute, globalConfiguration);
 | 
			
		||||
 | 
			
		||||
            var reRouteKey = CreateReRouteKey(fileReRoute);
 | 
			
		||||
 | 
			
		||||
            var upstreamTemplatePattern = _upstreamTemplatePatternCreator.Create(fileReRoute);
 | 
			
		||||
 | 
			
		||||
            var authOptionsForRoute = _authOptionsCreator.Create(fileReRoute);
 | 
			
		||||
 | 
			
		||||
            var claimsToHeaders = _claimsToThingCreator.Create(fileReRoute.AddHeadersToRequest);
 | 
			
		||||
 | 
			
		||||
            var claimsToClaims = _claimsToThingCreator.Create(fileReRoute.AddClaimsToRequest);
 | 
			
		||||
 | 
			
		||||
            var claimsToQueries = _claimsToThingCreator.Create(fileReRoute.AddQueriesToRequest);
 | 
			
		||||
 | 
			
		||||
            var qosOptions = _qosOptionsCreator.Create(fileReRoute);
 | 
			
		||||
 | 
			
		||||
            var rateLimitOption = _rateLimitOptionsCreator.Create(fileReRoute, globalConfiguration, fileReRouteOptions.EnableRateLimiting);
 | 
			
		||||
 | 
			
		||||
            var region = _regionCreator.Create(fileReRoute);
 | 
			
		||||
 | 
			
		||||
            var httpHandlerOptions = _httpHandlerOptionsCreator.Create(fileReRoute);
 | 
			
		||||
 | 
			
		||||
            var hAndRs = _headerFAndRCreator.Create(fileReRoute);
 | 
			
		||||
 | 
			
		||||
            var downstreamAddresses = _downstreamAddressesCreator.Create(fileReRoute);
 | 
			
		||||
 | 
			
		||||
            var reRoute = new DownstreamReRouteBuilder()
 | 
			
		||||
                .WithKey(fileReRoute.Key)
 | 
			
		||||
                .WithDownstreamPathTemplate(fileReRoute.DownstreamPathTemplate)
 | 
			
		||||
                .WithUpstreamPathTemplate(fileReRoute.UpstreamPathTemplate)
 | 
			
		||||
                .WithUpstreamHttpMethod(fileReRoute.UpstreamHttpMethod)
 | 
			
		||||
                .WithUpstreamTemplatePattern(upstreamTemplatePattern)
 | 
			
		||||
                .WithIsAuthenticated(fileReRouteOptions.IsAuthenticated)
 | 
			
		||||
                .WithAuthenticationOptions(authOptionsForRoute)
 | 
			
		||||
                .WithClaimsToHeaders(claimsToHeaders)
 | 
			
		||||
                .WithClaimsToClaims(claimsToClaims)
 | 
			
		||||
                .WithRouteClaimsRequirement(fileReRoute.RouteClaimsRequirement)
 | 
			
		||||
                .WithIsAuthorised(fileReRouteOptions.IsAuthorised)
 | 
			
		||||
                .WithClaimsToQueries(claimsToQueries)
 | 
			
		||||
                .WithRequestIdKey(requestIdKey)
 | 
			
		||||
                .WithIsCached(fileReRouteOptions.IsCached)
 | 
			
		||||
                .WithCacheOptions(new CacheOptions(fileReRoute.FileCacheOptions.TtlSeconds, region))
 | 
			
		||||
                .WithDownstreamScheme(fileReRoute.DownstreamScheme)
 | 
			
		||||
                .WithLoadBalancer(fileReRoute.LoadBalancer)
 | 
			
		||||
                .WithDownstreamAddresses(downstreamAddresses)
 | 
			
		||||
                .WithReRouteKey(reRouteKey)
 | 
			
		||||
                .WithIsQos(fileReRouteOptions.IsQos)
 | 
			
		||||
                .WithQosOptions(qosOptions)
 | 
			
		||||
                .WithEnableRateLimiting(fileReRouteOptions.EnableRateLimiting)
 | 
			
		||||
                .WithRateLimitOptions(rateLimitOption)
 | 
			
		||||
                .WithHttpHandlerOptions(httpHandlerOptions)
 | 
			
		||||
                .WithServiceName(fileReRoute.ServiceName)
 | 
			
		||||
                .WithUseServiceDiscovery(fileReRoute.UseServiceDiscovery)
 | 
			
		||||
                .WithUpstreamHeaderFindAndReplace(hAndRs.Upstream)
 | 
			
		||||
                .WithDownstreamHeaderFindAndReplace(hAndRs.Downstream)
 | 
			
		||||
                .WithUpstreamHost(fileReRoute.UpstreamHost)
 | 
			
		||||
                .WithDelegatingHandlers(fileReRoute.DelegatingHandlers)
 | 
			
		||||
                .WithAddHeadersToDownstream(hAndRs.AddHeadersToDownstream)
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            return reRoute;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private string CreateReRouteKey(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}|{string.Join(",", fileReRoute.UpstreamHttpMethod)}";
 | 
			
		||||
            return loadBalancerKey;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,11 @@
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Ocelot.Configuration.File;
 | 
			
		||||
using Ocelot.Responses;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration.Creator
 | 
			
		||||
{
 | 
			
		||||
    public interface IInternalConfigurationCreator
 | 
			
		||||
    {
 | 
			
		||||
        Task<Response<IInternalConfiguration>> Create(FileConfiguration fileConfiguration);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,11 +0,0 @@
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Ocelot.Configuration.File;
 | 
			
		||||
using Ocelot.Responses;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration.Creator
 | 
			
		||||
{
 | 
			
		||||
    public interface IOcelotConfigurationCreator
 | 
			
		||||
    {
 | 
			
		||||
        Task<Response<IOcelotConfiguration>> Create(FileConfiguration fileConfiguration);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,16 +1,14 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using IdentityServer4.AccessTokenValidation;
 | 
			
		||||
using IdentityServer4.Models;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration.Provider
 | 
			
		||||
{
 | 
			
		||||
    public interface IIdentityServerConfiguration
 | 
			
		||||
    {
 | 
			
		||||
        string ApiName { get;  }
 | 
			
		||||
        string ApiSecret { get;  }
 | 
			
		||||
        bool RequireHttps { get;  }
 | 
			
		||||
        List<string> AllowedScopes { get;  }
 | 
			
		||||
        string CredentialsSigningCertificateLocation { get; }
 | 
			
		||||
        string CredentialsSigningCertificatePassword { get; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
namespace Ocelot.Configuration
 | 
			
		||||
{
 | 
			
		||||
    using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
    public interface IIdentityServerConfiguration
 | 
			
		||||
    {
 | 
			
		||||
        string ApiName { get;  }
 | 
			
		||||
        string ApiSecret { get;  }
 | 
			
		||||
        bool RequireHttps { get;  }
 | 
			
		||||
        List<string> AllowedScopes { get;  }
 | 
			
		||||
        string CredentialsSigningCertificateLocation { get; }
 | 
			
		||||
        string CredentialsSigningCertificatePassword { get; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,12 +1,12 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration
 | 
			
		||||
{
 | 
			
		||||
    public interface IOcelotConfiguration
 | 
			
		||||
    {
 | 
			
		||||
        List<ReRoute> ReRoutes { get; }
 | 
			
		||||
        string AdministrationPath {get;}
 | 
			
		||||
        ServiceProviderConfiguration ServiceProviderConfiguration {get;}
 | 
			
		||||
        string RequestId {get;}
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration
 | 
			
		||||
{
 | 
			
		||||
    public interface IInternalConfiguration
 | 
			
		||||
    {
 | 
			
		||||
        List<ReRoute> ReRoutes { get; }
 | 
			
		||||
        string AdministrationPath {get;}
 | 
			
		||||
        ServiceProviderConfiguration ServiceProviderConfiguration {get;}
 | 
			
		||||
        string RequestId {get;}
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,32 +1,30 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using IdentityServer4.AccessTokenValidation;
 | 
			
		||||
using IdentityServer4.Models;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration.Provider
 | 
			
		||||
{
 | 
			
		||||
    public class IdentityServerConfiguration : IIdentityServerConfiguration
 | 
			
		||||
    {
 | 
			
		||||
        public IdentityServerConfiguration(
 | 
			
		||||
            string apiName, 
 | 
			
		||||
            bool requireHttps, 
 | 
			
		||||
            string apiSecret,
 | 
			
		||||
            List<string> allowedScopes,
 | 
			
		||||
            string credentialsSigningCertificateLocation, 
 | 
			
		||||
            string credentialsSigningCertificatePassword)
 | 
			
		||||
        {
 | 
			
		||||
            ApiName = apiName;
 | 
			
		||||
            RequireHttps = requireHttps;
 | 
			
		||||
            ApiSecret = apiSecret;
 | 
			
		||||
            AllowedScopes = allowedScopes;
 | 
			
		||||
            CredentialsSigningCertificateLocation = credentialsSigningCertificateLocation;
 | 
			
		||||
            CredentialsSigningCertificatePassword = credentialsSigningCertificatePassword;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string ApiName { get; private set; }
 | 
			
		||||
        public bool RequireHttps { get; private set; }
 | 
			
		||||
        public List<string> AllowedScopes { get; private set; }
 | 
			
		||||
        public string ApiSecret { get; private set; }
 | 
			
		||||
        public string CredentialsSigningCertificateLocation { get; private set; }
 | 
			
		||||
        public string CredentialsSigningCertificatePassword { get; private set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
namespace Ocelot.Configuration
 | 
			
		||||
{
 | 
			
		||||
    using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
    public class IdentityServerConfiguration : IIdentityServerConfiguration
 | 
			
		||||
    {
 | 
			
		||||
        public IdentityServerConfiguration(
 | 
			
		||||
            string apiName, 
 | 
			
		||||
            bool requireHttps, 
 | 
			
		||||
            string apiSecret,
 | 
			
		||||
            List<string> allowedScopes,
 | 
			
		||||
            string credentialsSigningCertificateLocation, 
 | 
			
		||||
            string credentialsSigningCertificatePassword)
 | 
			
		||||
        {
 | 
			
		||||
            ApiName = apiName;
 | 
			
		||||
            RequireHttps = requireHttps;
 | 
			
		||||
            ApiSecret = apiSecret;
 | 
			
		||||
            AllowedScopes = allowedScopes;
 | 
			
		||||
            CredentialsSigningCertificateLocation = credentialsSigningCertificateLocation;
 | 
			
		||||
            CredentialsSigningCertificatePassword = credentialsSigningCertificatePassword;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string ApiName { get; }
 | 
			
		||||
        public bool RequireHttps { get; }
 | 
			
		||||
        public List<string> AllowedScopes { get; }
 | 
			
		||||
        public string ApiSecret { get; }
 | 
			
		||||
        public string CredentialsSigningCertificateLocation { get; }
 | 
			
		||||
        public string CredentialsSigningCertificatePassword { get; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,20 +1,20 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration
 | 
			
		||||
{
 | 
			
		||||
    public class OcelotConfiguration : IOcelotConfiguration
 | 
			
		||||
    {
 | 
			
		||||
        public OcelotConfiguration(List<ReRoute> reRoutes, string administrationPath, ServiceProviderConfiguration serviceProviderConfiguration, string requestId)
 | 
			
		||||
        {
 | 
			
		||||
            ReRoutes = reRoutes;
 | 
			
		||||
            AdministrationPath = administrationPath;
 | 
			
		||||
            ServiceProviderConfiguration = serviceProviderConfiguration;
 | 
			
		||||
            RequestId = requestId;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public List<ReRoute> ReRoutes { get; }
 | 
			
		||||
        public string AdministrationPath {get;}
 | 
			
		||||
        public ServiceProviderConfiguration ServiceProviderConfiguration {get;}
 | 
			
		||||
        public string RequestId {get;}
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration
 | 
			
		||||
{
 | 
			
		||||
    public class InternalConfiguration : IInternalConfiguration
 | 
			
		||||
    {
 | 
			
		||||
        public InternalConfiguration(List<ReRoute> reRoutes, string administrationPath, ServiceProviderConfiguration serviceProviderConfiguration, string requestId)
 | 
			
		||||
        {
 | 
			
		||||
            ReRoutes = reRoutes;
 | 
			
		||||
            AdministrationPath = administrationPath;
 | 
			
		||||
            ServiceProviderConfiguration = serviceProviderConfiguration;
 | 
			
		||||
            RequestId = requestId;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public List<ReRoute> ReRoutes { get; }
 | 
			
		||||
        public string AdministrationPath {get;}
 | 
			
		||||
        public ServiceProviderConfiguration ServiceProviderConfiguration {get;}
 | 
			
		||||
        public string RequestId {get;}
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,9 +0,0 @@
 | 
			
		||||
using Ocelot.Responses;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration.Provider
 | 
			
		||||
{
 | 
			
		||||
    public interface IOcelotConfigurationProvider
 | 
			
		||||
    {
 | 
			
		||||
        Response<IOcelotConfiguration> Get();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,30 +0,0 @@
 | 
			
		||||
using Ocelot.Configuration.Repository;
 | 
			
		||||
using Ocelot.Responses;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration.Provider
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Register as singleton
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class OcelotConfigurationProvider : IOcelotConfigurationProvider
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IOcelotConfigurationRepository _config;
 | 
			
		||||
 | 
			
		||||
        public OcelotConfigurationProvider(IOcelotConfigurationRepository repo)
 | 
			
		||||
        {
 | 
			
		||||
            _config = repo;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Response<IOcelotConfiguration> Get()
 | 
			
		||||
        {
 | 
			
		||||
            var repoConfig = _config.Get();
 | 
			
		||||
 | 
			
		||||
            if (repoConfig.IsError)
 | 
			
		||||
            {
 | 
			
		||||
                return new ErrorResponse<IOcelotConfiguration>(repoConfig.Errors);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return new OkResponse<IOcelotConfiguration>(repoConfig.Data);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,35 +1,45 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Consul;
 | 
			
		||||
using Newtonsoft.Json;
 | 
			
		||||
using Ocelot.Configuration.File;
 | 
			
		||||
using Ocelot.Infrastructure.Consul;
 | 
			
		||||
using Ocelot.Logging;
 | 
			
		||||
using Ocelot.Responses;
 | 
			
		||||
using Ocelot.ServiceDiscovery.Configuration;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration.Repository
 | 
			
		||||
{
 | 
			
		||||
    using System;
 | 
			
		||||
    using System.Text;
 | 
			
		||||
    using System.Threading.Tasks;
 | 
			
		||||
    using Consul;
 | 
			
		||||
    using Newtonsoft.Json;
 | 
			
		||||
    using Ocelot.Configuration.File;
 | 
			
		||||
    using Ocelot.Infrastructure.Consul;
 | 
			
		||||
    using Ocelot.Logging;
 | 
			
		||||
    using Ocelot.Responses;
 | 
			
		||||
    using Ocelot.ServiceDiscovery.Configuration;
 | 
			
		||||
 | 
			
		||||
    public class ConsulFileConfigurationRepository : IFileConfigurationRepository
 | 
			
		||||
    {
 | 
			
		||||
        private readonly ConsulClient _consul;
 | 
			
		||||
        private const string OcelotConfiguration = "OcelotConfiguration";
 | 
			
		||||
        private const string OcelotConfiguration = "InternalConfiguration";
 | 
			
		||||
        private readonly Cache.IOcelotCache<FileConfiguration> _cache;
 | 
			
		||||
        private readonly IOcelotLogger _logger;
 | 
			
		||||
 | 
			
		||||
        public ConsulFileConfigurationRepository(
 | 
			
		||||
            Cache.IOcelotCache<FileConfiguration> cache,
 | 
			
		||||
            ServiceProviderConfiguration serviceProviderConfiguration, 
 | 
			
		||||
            IInternalConfigurationRepository repo, 
 | 
			
		||||
            IConsulClientFactory factory,
 | 
			
		||||
            IOcelotLoggerFactory loggerFactory)
 | 
			
		||||
        {
 | 
			
		||||
            _logger = loggerFactory.CreateLogger<ConsulFileConfigurationRepository>();
 | 
			
		||||
            _cache = cache;
 | 
			
		||||
 | 
			
		||||
            var consulHost = string.IsNullOrEmpty(serviceProviderConfiguration?.Host) ? "localhost" : serviceProviderConfiguration?.Host;
 | 
			
		||||
            var consulPort = serviceProviderConfiguration?.Port ?? 8500;
 | 
			
		||||
            var token = serviceProviderConfiguration?.Token;
 | 
			
		||||
            var internalConfig = repo.Get();
 | 
			
		||||
 | 
			
		||||
            var consulHost = "localhost";
 | 
			
		||||
            var consulPort = 8500;
 | 
			
		||||
            string token = null;
 | 
			
		||||
 | 
			
		||||
            if (!internalConfig.IsError)
 | 
			
		||||
            {
 | 
			
		||||
                consulHost = string.IsNullOrEmpty(internalConfig.Data.ServiceProviderConfiguration?.Host) ? consulHost : internalConfig.Data.ServiceProviderConfiguration?.Host;
 | 
			
		||||
                consulPort = internalConfig.Data.ServiceProviderConfiguration?.Port ?? consulPort;
 | 
			
		||||
                token = internalConfig.Data.ServiceProviderConfiguration?.Token;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var config = new ConsulRegistryConfiguration(consulHost, consulPort, OcelotConfiguration, token);
 | 
			
		||||
 | 
			
		||||
            _consul = factory.Get(config);
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,10 @@
 | 
			
		||||
using Ocelot.Responses;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration.Repository
 | 
			
		||||
{
 | 
			
		||||
    public interface IInternalConfigurationRepository
 | 
			
		||||
    {
 | 
			
		||||
        Response<IInternalConfiguration> Get();
 | 
			
		||||
        Response AddOrReplace(IInternalConfiguration internalConfiguration);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,10 +0,0 @@
 | 
			
		||||
using Ocelot.Responses;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration.Repository
 | 
			
		||||
{
 | 
			
		||||
    public interface IOcelotConfigurationRepository
 | 
			
		||||
    {
 | 
			
		||||
        Response<IOcelotConfiguration> Get();
 | 
			
		||||
        Response AddOrReplace(IOcelotConfiguration ocelotConfiguration);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,30 @@
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Ocelot.Responses;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration.Repository
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Register as singleton
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class InMemoryInternalConfigurationRepository : IInternalConfigurationRepository
 | 
			
		||||
    {
 | 
			
		||||
        private static readonly object LockObject = new object();
 | 
			
		||||
 | 
			
		||||
        private IInternalConfiguration _internalConfiguration;
 | 
			
		||||
 | 
			
		||||
        public Response<IInternalConfiguration> Get()
 | 
			
		||||
        {
 | 
			
		||||
            return new OkResponse<IInternalConfiguration>(_internalConfiguration);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Response AddOrReplace(IInternalConfiguration internalConfiguration)
 | 
			
		||||
        {
 | 
			
		||||
            lock (LockObject)
 | 
			
		||||
            {
 | 
			
		||||
                _internalConfiguration = internalConfiguration;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return new OkResponse();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,30 +0,0 @@
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Ocelot.Responses;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Configuration.Repository
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Register as singleton
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class InMemoryOcelotConfigurationRepository : IOcelotConfigurationRepository
 | 
			
		||||
    {
 | 
			
		||||
        private static readonly object LockObject = new object();
 | 
			
		||||
 | 
			
		||||
        private IOcelotConfiguration _ocelotConfiguration;
 | 
			
		||||
 | 
			
		||||
        public Response<IOcelotConfiguration> Get()
 | 
			
		||||
        {
 | 
			
		||||
            return new OkResponse<IOcelotConfiguration>(_ocelotConfiguration);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Response AddOrReplace(IOcelotConfiguration ocelotConfiguration)
 | 
			
		||||
        {
 | 
			
		||||
            lock (LockObject)
 | 
			
		||||
            {
 | 
			
		||||
                _ocelotConfiguration = ocelotConfiguration;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return new OkResponse();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -8,13 +8,13 @@ namespace Ocelot.Configuration.Setter
 | 
			
		||||
{
 | 
			
		||||
    public class FileConfigurationSetter : IFileConfigurationSetter
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IOcelotConfigurationRepository _configRepo;
 | 
			
		||||
        private readonly IOcelotConfigurationCreator _configCreator;
 | 
			
		||||
        private readonly IInternalConfigurationRepository _configRepo;
 | 
			
		||||
        private readonly IInternalConfigurationCreator _configCreator;
 | 
			
		||||
        private readonly IFileConfigurationRepository _repo;
 | 
			
		||||
 | 
			
		||||
        public FileConfigurationSetter(
 | 
			
		||||
            IOcelotConfigurationRepository configRepo, 
 | 
			
		||||
            IOcelotConfigurationCreator configCreator, 
 | 
			
		||||
            IInternalConfigurationRepository configRepo, 
 | 
			
		||||
            IInternalConfigurationCreator configCreator, 
 | 
			
		||||
            IFileConfigurationRepository repo)
 | 
			
		||||
        {
 | 
			
		||||
            _configRepo = configRepo;
 | 
			
		||||
 
 | 
			
		||||
@@ -73,8 +73,8 @@ namespace Ocelot.DependencyInjection
 | 
			
		||||
            _services.TryAddSingleton<IHttpResponseHeaderReplacer, HttpResponseHeaderReplacer>();
 | 
			
		||||
            _services.TryAddSingleton<IHttpContextRequestHeaderReplacer, HttpContextRequestHeaderReplacer>();
 | 
			
		||||
            _services.TryAddSingleton<IHeaderFindAndReplaceCreator, HeaderFindAndReplaceCreator>();
 | 
			
		||||
            _services.TryAddSingleton<IOcelotConfigurationCreator, FileOcelotConfigurationCreator>();
 | 
			
		||||
            _services.TryAddSingleton<IOcelotConfigurationRepository, InMemoryOcelotConfigurationRepository>();
 | 
			
		||||
            _services.TryAddSingleton<IInternalConfigurationCreator, FileInternalConfigurationCreator>();
 | 
			
		||||
            _services.TryAddSingleton<IInternalConfigurationRepository, InMemoryInternalConfigurationRepository>();
 | 
			
		||||
            _services.TryAddSingleton<IConfigurationValidator, FileConfigurationFluentValidator>();
 | 
			
		||||
            _services.TryAddSingleton<IClaimsToThingCreator, ClaimsToThingCreator>();
 | 
			
		||||
            _services.TryAddSingleton<IAuthenticationOptionsCreator, AuthenticationOptionsCreator>();
 | 
			
		||||
@@ -96,7 +96,6 @@ namespace Ocelot.DependencyInjection
 | 
			
		||||
            _services.TryAddSingleton<ILoadBalancerHouse, LoadBalancerHouse>();
 | 
			
		||||
            _services.TryAddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
 | 
			
		||||
            _services.TryAddSingleton<IRemoveOutputHeaders, RemoveOutputHeaders>();
 | 
			
		||||
            _services.TryAddSingleton<IOcelotConfigurationProvider, OcelotConfigurationProvider>();
 | 
			
		||||
            _services.TryAddSingleton<IClaimToThingConfigurationParser, ClaimToThingConfigurationParser>();
 | 
			
		||||
            _services.TryAddSingleton<IClaimsAuthoriser, ClaimsAuthoriser>();
 | 
			
		||||
            _services.TryAddSingleton<IScopesAuthoriser, ScopesAuthoriser>();
 | 
			
		||||
@@ -247,17 +246,6 @@ namespace Ocelot.DependencyInjection
 | 
			
		||||
 | 
			
		||||
        public IOcelotBuilder AddStoreOcelotConfigurationInConsul()
 | 
			
		||||
        {
 | 
			
		||||
            var serviceDiscoveryPort = _configurationRoot.GetValue("GlobalConfiguration:ServiceDiscoveryProvider:Port", 0);
 | 
			
		||||
            var serviceDiscoveryHost = _configurationRoot.GetValue("GlobalConfiguration:ServiceDiscoveryProvider:Host", string.Empty);
 | 
			
		||||
            var serviceDiscoveryToken = _configurationRoot.GetValue("GlobalConfiguration:ServiceDiscoveryProvider:Token", string.Empty);
 | 
			
		||||
 | 
			
		||||
            var config = new ServiceProviderConfigurationBuilder()
 | 
			
		||||
                .WithPort(serviceDiscoveryPort)
 | 
			
		||||
                .WithHost(serviceDiscoveryHost)
 | 
			
		||||
                .WithToken(serviceDiscoveryToken)
 | 
			
		||||
                .Build();
 | 
			
		||||
 | 
			
		||||
            _services.AddSingleton<ServiceProviderConfiguration>(config);
 | 
			
		||||
            _services.AddSingleton<ConsulFileConfigurationPoller>();
 | 
			
		||||
            _services.AddSingleton<IFileConfigurationRepository, ConsulFileConfigurationRepository>();
 | 
			
		||||
            return this;
 | 
			
		||||
@@ -273,12 +261,12 @@ namespace Ocelot.DependencyInjection
 | 
			
		||||
            _services.AddSingleton<ICacheManager<CachedResponse>>(cacheManagerOutputCache);
 | 
			
		||||
            _services.AddSingleton<IOcelotCache<CachedResponse>>(ocelotOutputCacheManager);
 | 
			
		||||
 | 
			
		||||
            var ocelotConfigCacheManagerOutputCache = CacheFactory.Build<IOcelotConfiguration>("OcelotConfigurationCache", settings);
 | 
			
		||||
            var ocelotConfigCacheManager = new OcelotCacheManagerCache<IOcelotConfiguration>(ocelotConfigCacheManagerOutputCache);
 | 
			
		||||
            _services.RemoveAll(typeof(ICacheManager<IOcelotConfiguration>));
 | 
			
		||||
            _services.RemoveAll(typeof(IOcelotCache<IOcelotConfiguration>));
 | 
			
		||||
            _services.AddSingleton<ICacheManager<IOcelotConfiguration>>(ocelotConfigCacheManagerOutputCache);
 | 
			
		||||
            _services.AddSingleton<IOcelotCache<IOcelotConfiguration>>(ocelotConfigCacheManager);
 | 
			
		||||
            var ocelotConfigCacheManagerOutputCache = CacheFactory.Build<IInternalConfiguration>("OcelotConfigurationCache", settings);
 | 
			
		||||
            var ocelotConfigCacheManager = new OcelotCacheManagerCache<IInternalConfiguration>(ocelotConfigCacheManagerOutputCache);
 | 
			
		||||
            _services.RemoveAll(typeof(ICacheManager<IInternalConfiguration>));
 | 
			
		||||
            _services.RemoveAll(typeof(IOcelotCache<IInternalConfiguration>));
 | 
			
		||||
            _services.AddSingleton<ICacheManager<IInternalConfiguration>>(ocelotConfigCacheManagerOutputCache);
 | 
			
		||||
            _services.AddSingleton<IOcelotCache<IInternalConfiguration>>(ocelotConfigCacheManager);
 | 
			
		||||
 | 
			
		||||
            var fileConfigCacheManagerOutputCache = CacheFactory.Build<FileConfiguration>("FileConfigurationCache", settings);
 | 
			
		||||
            var fileConfigCacheManager = new OcelotCacheManagerCache<FileConfiguration>(fileConfigCacheManagerOutputCache);
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,7 @@ namespace Ocelot.DownstreamRouteFinder.Finder
 | 
			
		||||
            _placeholderNameAndValueFinder = urlPathPlaceholderNameAndValueFinder;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Response<DownstreamRoute> FindDownstreamRoute(string path, string httpMethod, IOcelotConfiguration configuration, string upstreamHost)
 | 
			
		||||
        public Response<DownstreamRoute> FindDownstreamRoute(string path, string httpMethod, IInternalConfiguration configuration, string upstreamHost)
 | 
			
		||||
        {
 | 
			
		||||
            var downstreamRoutes = new List<DownstreamRoute>();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,6 @@ namespace Ocelot.DownstreamRouteFinder.Finder
 | 
			
		||||
{
 | 
			
		||||
    public interface IDownstreamRouteFinder
 | 
			
		||||
    {
 | 
			
		||||
        Response<DownstreamRoute> FindDownstreamRoute(string upstreamUrlPath, string upstreamHttpMethod, IOcelotConfiguration configuration, string upstreamHost);
 | 
			
		||||
        Response<DownstreamRoute> FindDownstreamRoute(string upstreamUrlPath, string upstreamHttpMethod, IInternalConfiguration configuration, string upstreamHost);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@ using System.Threading.Tasks;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using Ocelot.Configuration;
 | 
			
		||||
using Ocelot.Configuration.Provider;
 | 
			
		||||
using Ocelot.Configuration.Repository;
 | 
			
		||||
using Ocelot.DownstreamRouteFinder.Finder;
 | 
			
		||||
using Ocelot.Infrastructure.Extensions;
 | 
			
		||||
using Ocelot.Logging;
 | 
			
		||||
@@ -14,17 +15,17 @@ namespace Ocelot.DownstreamRouteFinder.Middleware
 | 
			
		||||
    {
 | 
			
		||||
        private readonly OcelotRequestDelegate _next;
 | 
			
		||||
        private readonly IDownstreamRouteFinder _downstreamRouteFinder;
 | 
			
		||||
        private readonly IOcelotConfigurationProvider _configProvider;
 | 
			
		||||
        private readonly IInternalConfigurationRepository _repo;
 | 
			
		||||
        private readonly IMultiplexer _multiplexer;
 | 
			
		||||
 | 
			
		||||
        public DownstreamRouteFinderMiddleware(OcelotRequestDelegate next,
 | 
			
		||||
            IOcelotLoggerFactory loggerFactory,
 | 
			
		||||
            IDownstreamRouteFinder downstreamRouteFinder,
 | 
			
		||||
            IOcelotConfigurationProvider configProvider,
 | 
			
		||||
            IInternalConfigurationRepository repo,
 | 
			
		||||
            IMultiplexer multiplexer)
 | 
			
		||||
                :base(loggerFactory.CreateLogger<DownstreamRouteFinderMiddleware>())
 | 
			
		||||
        {
 | 
			
		||||
            _configProvider = configProvider;
 | 
			
		||||
            _repo = repo;
 | 
			
		||||
            _multiplexer = multiplexer;
 | 
			
		||||
            _next = next;
 | 
			
		||||
            _downstreamRouteFinder = downstreamRouteFinder;
 | 
			
		||||
@@ -36,7 +37,7 @@ namespace Ocelot.DownstreamRouteFinder.Middleware
 | 
			
		||||
 | 
			
		||||
            var upstreamHost = context.HttpContext.Request.Headers["Host"];
 | 
			
		||||
 | 
			
		||||
            var configuration = _configProvider.Get();
 | 
			
		||||
            var configuration = _repo.Get();
 | 
			
		||||
 | 
			
		||||
            if (configuration.IsError)
 | 
			
		||||
            {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Ocelot.Configuration.Provider;
 | 
			
		||||
using Ocelot.Configuration.Repository;
 | 
			
		||||
using Ocelot.Infrastructure.Extensions;
 | 
			
		||||
using Ocelot.Infrastructure.RequestData;
 | 
			
		||||
using Ocelot.Logging;
 | 
			
		||||
@@ -15,16 +15,16 @@ namespace Ocelot.Errors.Middleware
 | 
			
		||||
    public class ExceptionHandlerMiddleware : OcelotMiddleware
 | 
			
		||||
    {
 | 
			
		||||
        private readonly OcelotRequestDelegate _next;
 | 
			
		||||
        private readonly IOcelotConfigurationProvider _provider;
 | 
			
		||||
        private readonly IInternalConfigurationRepository _configRepo;
 | 
			
		||||
        private readonly IRequestScopedDataRepository _repo;
 | 
			
		||||
 | 
			
		||||
        public ExceptionHandlerMiddleware(OcelotRequestDelegate next,
 | 
			
		||||
            IOcelotLoggerFactory loggerFactory, 
 | 
			
		||||
            IOcelotConfigurationProvider provider, 
 | 
			
		||||
            IOcelotLoggerFactory loggerFactory,
 | 
			
		||||
            IInternalConfigurationRepository configRepo, 
 | 
			
		||||
            IRequestScopedDataRepository repo)
 | 
			
		||||
                : base(loggerFactory.CreateLogger<ExceptionHandlerMiddleware>())
 | 
			
		||||
        {
 | 
			
		||||
            _provider = provider;
 | 
			
		||||
            _configRepo = configRepo;
 | 
			
		||||
            _repo = repo;
 | 
			
		||||
            _next = next;
 | 
			
		||||
        }
 | 
			
		||||
@@ -58,7 +58,7 @@ namespace Ocelot.Errors.Middleware
 | 
			
		||||
            //try and get the global request id and set it for logs...
 | 
			
		||||
            //should this basically be immutable per request...i guess it should!
 | 
			
		||||
            //first thing is get config
 | 
			
		||||
            var configuration = _provider.Get(); 
 | 
			
		||||
            var configuration = _configRepo.Get(); 
 | 
			
		||||
            
 | 
			
		||||
            if(configuration.IsError)
 | 
			
		||||
            {
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,6 @@
 | 
			
		||||
    using Ocelot.Configuration;
 | 
			
		||||
    using Ocelot.Configuration.Creator;
 | 
			
		||||
    using Ocelot.Configuration.File;
 | 
			
		||||
    using Ocelot.Configuration.Provider;
 | 
			
		||||
    using Ocelot.Configuration.Repository;
 | 
			
		||||
    using Ocelot.Configuration.Setter;
 | 
			
		||||
    using Ocelot.Responses;
 | 
			
		||||
@@ -84,63 +83,108 @@
 | 
			
		||||
            node.Start(nodeId.Id);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static async Task<IOcelotConfiguration> CreateConfiguration(IApplicationBuilder builder)
 | 
			
		||||
        private static async Task<IInternalConfiguration> CreateConfiguration(IApplicationBuilder builder)
 | 
			
		||||
        {
 | 
			
		||||
            var deps = GetDependencies(builder);
 | 
			
		||||
            // make configuration from file system?
 | 
			
		||||
            // earlier user needed to add ocelot files in startup configuration stuff, asp.net will map it to this
 | 
			
		||||
            var fileConfig = (IOptions<FileConfiguration>)builder.ApplicationServices.GetService(typeof(IOptions<FileConfiguration>));
 | 
			
		||||
            
 | 
			
		||||
            // now create the config
 | 
			
		||||
            var internalConfigCreator = (IInternalConfigurationCreator)builder.ApplicationServices.GetService(typeof(IInternalConfigurationCreator));
 | 
			
		||||
            var internalConfig = await internalConfigCreator.Create(fileConfig.Value);
 | 
			
		||||
 | 
			
		||||
            var ocelotConfiguration = deps.provider.Get();
 | 
			
		||||
            // now save it in memory
 | 
			
		||||
            var internalConfigRepo = (IInternalConfigurationRepository)builder.ApplicationServices.GetService(typeof(IInternalConfigurationRepository));
 | 
			
		||||
            internalConfigRepo.AddOrReplace(internalConfig.Data);
 | 
			
		||||
 | 
			
		||||
            if (ConfigurationNotSetUp(ocelotConfiguration))
 | 
			
		||||
            var fileConfigSetter = (IFileConfigurationSetter)builder.ApplicationServices.GetService(typeof(IFileConfigurationSetter));
 | 
			
		||||
 | 
			
		||||
            var fileConfigRepo = (IFileConfigurationRepository)builder.ApplicationServices.GetService(typeof(IFileConfigurationRepository));
 | 
			
		||||
 | 
			
		||||
            if (UsingConsul(fileConfigRepo))
 | 
			
		||||
            {
 | 
			
		||||
                var response = await SetConfig(builder, deps.fileConfiguration, deps.setter, deps.provider, deps.repo);
 | 
			
		||||
                
 | 
			
		||||
                if (UnableToSetConfig(response))
 | 
			
		||||
                await SetFileConfigInConsul(builder, fileConfigRepo, fileConfig, internalConfigCreator, internalConfigRepo);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                await SetFileConfig(fileConfigSetter, fileConfig);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return GetOcelotConfigAndReturn(internalConfigRepo);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static async Task SetFileConfigInConsul(IApplicationBuilder builder,
 | 
			
		||||
            IFileConfigurationRepository fileConfigRepo, IOptions<FileConfiguration> fileConfig,
 | 
			
		||||
            IInternalConfigurationCreator internalConfigCreator, IInternalConfigurationRepository internalConfigRepo)
 | 
			
		||||
        {
 | 
			
		||||
            // get the config from consul.
 | 
			
		||||
            var fileConfigFromConsul = await fileConfigRepo.Get();
 | 
			
		||||
 | 
			
		||||
            if (IsError(fileConfigFromConsul))
 | 
			
		||||
            {
 | 
			
		||||
                ThrowToStopOcelotStarting(fileConfigFromConsul);
 | 
			
		||||
            }
 | 
			
		||||
            else if (ConfigNotStoredInConsul(fileConfigFromConsul))
 | 
			
		||||
            {
 | 
			
		||||
                //there was no config in consul set the file in config in consul
 | 
			
		||||
                await fileConfigRepo.Set(fileConfig.Value);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                // create the internal config from consul data
 | 
			
		||||
                var internalConfig = await internalConfigCreator.Create(fileConfigFromConsul.Data);
 | 
			
		||||
 | 
			
		||||
                if (IsError(internalConfig))
 | 
			
		||||
                {
 | 
			
		||||
                    ThrowToStopOcelotStarting(response);
 | 
			
		||||
                    ThrowToStopOcelotStarting(internalConfig);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    // add the internal config to the internal repo
 | 
			
		||||
                    var response = internalConfigRepo.AddOrReplace(internalConfig.Data);
 | 
			
		||||
 | 
			
		||||
                    if (IsError(response))
 | 
			
		||||
                    {
 | 
			
		||||
                        ThrowToStopOcelotStarting(response);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (IsError(internalConfig))
 | 
			
		||||
                {
 | 
			
		||||
                    ThrowToStopOcelotStarting(internalConfig);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return GetOcelotConfigAndReturn(deps.provider);
 | 
			
		||||
            //todo - this starts the poller if it has been registered...please this is so bad.
 | 
			
		||||
            var hack = builder.ApplicationServices.GetService(typeof(ConsulFileConfigurationPoller));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static async Task<Response> SetConfig(IApplicationBuilder builder, IOptions<FileConfiguration> fileConfiguration, IFileConfigurationSetter setter, IOcelotConfigurationProvider provider, IFileConfigurationRepository repo)
 | 
			
		||||
        private static async Task SetFileConfig(IFileConfigurationSetter fileConfigSetter, IOptions<FileConfiguration> fileConfig)
 | 
			
		||||
        {
 | 
			
		||||
            if (UsingConsul(repo))
 | 
			
		||||
            Response response;
 | 
			
		||||
            response = await fileConfigSetter.Set(fileConfig.Value);
 | 
			
		||||
 | 
			
		||||
            if (IsError(response))
 | 
			
		||||
            {
 | 
			
		||||
                return await SetUpConfigFromConsul(builder, repo, setter, fileConfiguration);
 | 
			
		||||
                ThrowToStopOcelotStarting(response);
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            return await setter.Set(fileConfiguration.Value);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static bool UnableToSetConfig(Response response)
 | 
			
		||||
        private static bool ConfigNotStoredInConsul(Responses.Response<FileConfiguration> fileConfigFromConsul)
 | 
			
		||||
        {
 | 
			
		||||
            return fileConfigFromConsul.Data == null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static bool IsError(Response response)
 | 
			
		||||
        {
 | 
			
		||||
            return response == null || response.IsError;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static bool ConfigurationNotSetUp(Ocelot.Responses.Response<IOcelotConfiguration> ocelotConfiguration)
 | 
			
		||||
        {
 | 
			
		||||
            return ocelotConfiguration == null || ocelotConfiguration.Data == null || ocelotConfiguration.IsError;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static (IOptions<FileConfiguration> fileConfiguration, IFileConfigurationSetter setter, IOcelotConfigurationProvider provider, IFileConfigurationRepository repo) GetDependencies(IApplicationBuilder builder)
 | 
			
		||||
        {
 | 
			
		||||
            var fileConfiguration = (IOptions<FileConfiguration>)builder.ApplicationServices.GetService(typeof(IOptions<FileConfiguration>));
 | 
			
		||||
            
 | 
			
		||||
            var setter = (IFileConfigurationSetter)builder.ApplicationServices.GetService(typeof(IFileConfigurationSetter));
 | 
			
		||||
            
 | 
			
		||||
            var provider = (IOcelotConfigurationProvider)builder.ApplicationServices.GetService(typeof(IOcelotConfigurationProvider));
 | 
			
		||||
 | 
			
		||||
            var repo = (IFileConfigurationRepository)builder.ApplicationServices.GetService(typeof(IFileConfigurationRepository));
 | 
			
		||||
 | 
			
		||||
            return (fileConfiguration, setter, provider, repo);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static IOcelotConfiguration GetOcelotConfigAndReturn(IOcelotConfigurationProvider provider)
 | 
			
		||||
        private static IInternalConfiguration GetOcelotConfigAndReturn(IInternalConfigurationRepository provider)
 | 
			
		||||
        {
 | 
			
		||||
            var ocelotConfiguration = provider.Get();
 | 
			
		||||
 | 
			
		||||
            if(ocelotConfiguration == null || ocelotConfiguration.Data == null || ocelotConfiguration.IsError)
 | 
			
		||||
            if(ocelotConfiguration?.Data == null || ocelotConfiguration.IsError)
 | 
			
		||||
            {
 | 
			
		||||
                ThrowToStopOcelotStarting(ocelotConfiguration);
 | 
			
		||||
            }
 | 
			
		||||
@@ -158,49 +202,7 @@
 | 
			
		||||
            return fileConfigRepo.GetType() == typeof(ConsulFileConfigurationRepository);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static async Task<Response> SetUpConfigFromConsul(IApplicationBuilder builder, IFileConfigurationRepository consulFileConfigRepo, IFileConfigurationSetter setter, IOptions<FileConfiguration> fileConfig)
 | 
			
		||||
        {
 | 
			
		||||
            Response config = null;
 | 
			
		||||
 | 
			
		||||
            var ocelotConfigurationRepository =
 | 
			
		||||
                (IOcelotConfigurationRepository) builder.ApplicationServices.GetService(
 | 
			
		||||
                    typeof(IOcelotConfigurationRepository));
 | 
			
		||||
 | 
			
		||||
            var ocelotConfigurationCreator =
 | 
			
		||||
                (IOcelotConfigurationCreator) builder.ApplicationServices.GetService(
 | 
			
		||||
                    typeof(IOcelotConfigurationCreator));
 | 
			
		||||
 | 
			
		||||
            var fileConfigFromConsul = await consulFileConfigRepo.Get();
 | 
			
		||||
 | 
			
		||||
            if (fileConfigFromConsul.Data == null)
 | 
			
		||||
            {
 | 
			
		||||
                config = await setter.Set(fileConfig.Value);
 | 
			
		||||
                var hack = builder.ApplicationServices.GetService(typeof(ConsulFileConfigurationPoller));
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                var ocelotConfig = await ocelotConfigurationCreator.Create(fileConfigFromConsul.Data);
 | 
			
		||||
 | 
			
		||||
                if(ocelotConfig.IsError)
 | 
			
		||||
                {
 | 
			
		||||
                    return new ErrorResponse(ocelotConfig.Errors);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                config = ocelotConfigurationRepository.AddOrReplace(ocelotConfig.Data);
 | 
			
		||||
 | 
			
		||||
                if (config.IsError)
 | 
			
		||||
                {
 | 
			
		||||
                    return new ErrorResponse(config.Errors);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                //todo - this starts the poller if it has been registered...please this is so bad.
 | 
			
		||||
                var hack = builder.ApplicationServices.GetService(typeof(ConsulFileConfigurationPoller));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return new OkResponse();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static void CreateAdministrationArea(IApplicationBuilder builder, IOcelotConfiguration configuration)
 | 
			
		||||
        private static void CreateAdministrationArea(IApplicationBuilder builder, IInternalConfiguration configuration)
 | 
			
		||||
        {
 | 
			
		||||
            if(!string.IsNullOrEmpty(configuration.AdministrationPath))
 | 
			
		||||
            {
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Hosting;
 | 
			
		||||
using Microsoft.Extensions.Options;
 | 
			
		||||
using Ocelot.Configuration;
 | 
			
		||||
using Ocelot.Configuration.Provider;
 | 
			
		||||
using Ocelot.Configuration.Repository;
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
using Rafty.Concensus;
 | 
			
		||||
using Rafty.Infrastructure;
 | 
			
		||||
@@ -15,20 +16,20 @@ namespace Ocelot.Raft
 | 
			
		||||
    public class FilePeersProvider : IPeersProvider
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IOptions<FilePeers> _options;
 | 
			
		||||
        private List<IPeer> _peers;
 | 
			
		||||
        private readonly List<IPeer> _peers;
 | 
			
		||||
        private IBaseUrlFinder _finder;
 | 
			
		||||
        private IOcelotConfigurationProvider _provider;
 | 
			
		||||
        private IInternalConfigurationRepository _repo;
 | 
			
		||||
        private IIdentityServerConfiguration _identityServerConfig;
 | 
			
		||||
 | 
			
		||||
        public FilePeersProvider(IOptions<FilePeers> options, IBaseUrlFinder finder, IOcelotConfigurationProvider provider, IIdentityServerConfiguration identityServerConfig)
 | 
			
		||||
        public FilePeersProvider(IOptions<FilePeers> options, IBaseUrlFinder finder, IInternalConfigurationRepository repo, IIdentityServerConfiguration identityServerConfig)
 | 
			
		||||
        {
 | 
			
		||||
            _identityServerConfig = identityServerConfig;
 | 
			
		||||
            _provider = provider;
 | 
			
		||||
            _repo = repo;
 | 
			
		||||
            _finder = finder;
 | 
			
		||||
            _options = options;
 | 
			
		||||
            _peers = new List<IPeer>();
 | 
			
		||||
            
 | 
			
		||||
            var config = _provider.Get();
 | 
			
		||||
            var config = _repo.Get();
 | 
			
		||||
            foreach (var item in _options.Value.Peers)
 | 
			
		||||
            {
 | 
			
		||||
                var httpClient = new HttpClient();
 | 
			
		||||
 
 | 
			
		||||
@@ -21,10 +21,10 @@ namespace Ocelot.Raft
 | 
			
		||||
        private JsonSerializerSettings _jsonSerializerSettings;
 | 
			
		||||
        private string _baseSchemeUrlAndPort;
 | 
			
		||||
        private BearerToken _token;
 | 
			
		||||
        private IOcelotConfiguration _config;
 | 
			
		||||
        private IInternalConfiguration _config;
 | 
			
		||||
        private IIdentityServerConfiguration _identityServerConfiguration;
 | 
			
		||||
 | 
			
		||||
        public HttpPeer(string hostAndPort, HttpClient httpClient, IBaseUrlFinder finder, IOcelotConfiguration config, IIdentityServerConfiguration identityServerConfiguration)
 | 
			
		||||
        public HttpPeer(string hostAndPort, HttpClient httpClient, IBaseUrlFinder finder, IInternalConfiguration config, IIdentityServerConfiguration identityServerConfiguration)
 | 
			
		||||
        {
 | 
			
		||||
            _identityServerConfiguration = identityServerConfiguration;
 | 
			
		||||
            _config = config;
 | 
			
		||||
 
 | 
			
		||||
@@ -303,7 +303,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                            {
 | 
			
		||||
                                app.Run(async context =>
 | 
			
		||||
                                {
 | 
			
		||||
                                    if (context.Request.Method.ToLower() == "get" && context.Request.Path.Value == "/v1/kv/OcelotConfiguration")
 | 
			
		||||
                                    if (context.Request.Method.ToLower() == "get" && context.Request.Path.Value == "/v1/kv/InternalConfiguration")
 | 
			
		||||
                                    {
 | 
			
		||||
                                        var json = JsonConvert.SerializeObject(_config);
 | 
			
		||||
 | 
			
		||||
@@ -315,7 +315,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
 | 
			
		||||
                                        await context.Response.WriteJsonAsync(new FakeConsulGetResponse[] { kvp });
 | 
			
		||||
                                    }                               
 | 
			
		||||
                                    else if (context.Request.Method.ToLower() == "put" && context.Request.Path.Value == "/v1/kv/OcelotConfiguration")
 | 
			
		||||
                                    else if (context.Request.Method.ToLower() == "put" && context.Request.Path.Value == "/v1/kv/InternalConfiguration")
 | 
			
		||||
                                    {
 | 
			
		||||
                                        try
 | 
			
		||||
                                        {
 | 
			
		||||
@@ -352,7 +352,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
            public int CreateIndex => 100;
 | 
			
		||||
            public int ModifyIndex => 200;
 | 
			
		||||
            public int LockIndex => 200;
 | 
			
		||||
            public string Key => "OcelotConfiguration";
 | 
			
		||||
            public string Key => "InternalConfiguration";
 | 
			
		||||
            public int Flags => 0;
 | 
			
		||||
            public string Value { get; private set; }
 | 
			
		||||
            public string Session => "adf4238a-882b-9ddc-4a9d-5b6758e4159e";
 | 
			
		||||
 
 | 
			
		||||
@@ -26,10 +26,10 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
    {
 | 
			
		||||
        private readonly Mock<IOptions<FileConfiguration>> _fileConfig;
 | 
			
		||||
        private readonly Mock<IConfigurationValidator> _validator;
 | 
			
		||||
        private Response<IOcelotConfiguration> _config;
 | 
			
		||||
        private Response<IInternalConfiguration> _config;
 | 
			
		||||
        private FileConfiguration _fileConfiguration;
 | 
			
		||||
        private readonly Mock<IOcelotLoggerFactory> _logger;
 | 
			
		||||
        private readonly FileOcelotConfigurationCreator _ocelotConfigurationCreator;
 | 
			
		||||
        private readonly FileInternalConfigurationCreator _internalConfigurationCreator;
 | 
			
		||||
        private Mock<IClaimsToThingCreator> _claimsToThingCreator;
 | 
			
		||||
        private Mock<IAuthenticationOptionsCreator> _authOptionsCreator;
 | 
			
		||||
        private Mock<IUpstreamTemplatePatternCreator> _upstreamTemplatePatternCreator;
 | 
			
		||||
@@ -63,7 +63,7 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
            _headerFindAndReplaceCreator = new Mock<IHeaderFindAndReplaceCreator>();
 | 
			
		||||
            _downstreamAddressesCreator = new Mock<IDownstreamAddressesCreator>();
 | 
			
		||||
 | 
			
		||||
            _ocelotConfigurationCreator = new FileOcelotConfigurationCreator( 
 | 
			
		||||
            _internalConfigurationCreator = new FileInternalConfigurationCreator( 
 | 
			
		||||
                _fileConfig.Object,
 | 
			
		||||
                _validator.Object, 
 | 
			
		||||
                _logger.Object,
 | 
			
		||||
@@ -807,7 +807,7 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
 | 
			
		||||
        private void WhenICreateTheConfig()
 | 
			
		||||
        {
 | 
			
		||||
            _config = _ocelotConfigurationCreator.Create(_fileConfiguration).Result;
 | 
			
		||||
            _config = _internalConfigurationCreator.Create(_fileConfiguration).Result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheReRoutesAre(List<ReRoute> expectedReRoutes)
 | 
			
		||||
 
 | 
			
		||||
@@ -19,17 +19,17 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
    {
 | 
			
		||||
        private FileConfiguration _fileConfiguration;
 | 
			
		||||
        private FileConfigurationSetter _configSetter;
 | 
			
		||||
        private Mock<IOcelotConfigurationRepository> _configRepo;
 | 
			
		||||
        private Mock<IOcelotConfigurationCreator> _configCreator;
 | 
			
		||||
        private Response<IOcelotConfiguration> _configuration;
 | 
			
		||||
        private Mock<IInternalConfigurationRepository> _configRepo;
 | 
			
		||||
        private Mock<IInternalConfigurationCreator> _configCreator;
 | 
			
		||||
        private Response<IInternalConfiguration> _configuration;
 | 
			
		||||
        private object _result; 
 | 
			
		||||
        private Mock<IFileConfigurationRepository> _repo;
 | 
			
		||||
 | 
			
		||||
        public FileConfigurationSetterTests()
 | 
			
		||||
        {
 | 
			
		||||
            _repo = new Mock<IFileConfigurationRepository>();
 | 
			
		||||
            _configRepo = new Mock<IOcelotConfigurationRepository>();
 | 
			
		||||
            _configCreator = new Mock<IOcelotConfigurationCreator>();
 | 
			
		||||
            _configRepo = new Mock<IInternalConfigurationRepository>();
 | 
			
		||||
            _configCreator = new Mock<IInternalConfigurationCreator>();
 | 
			
		||||
            _configSetter = new FileConfigurationSetter(_configRepo.Object, _configCreator.Object, _repo.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -38,11 +38,11 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
        {
 | 
			
		||||
            var fileConfig = new FileConfiguration();
 | 
			
		||||
            var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
 | 
			
		||||
            var config = new OcelotConfiguration(new List<ReRoute>(), string.Empty, serviceProviderConfig, "asdf");
 | 
			
		||||
            var config = new InternalConfiguration(new List<ReRoute>(), string.Empty, serviceProviderConfig, "asdf");
 | 
			
		||||
 | 
			
		||||
            this.Given(x => GivenTheFollowingConfiguration(fileConfig))
 | 
			
		||||
                .And(x => GivenTheRepoReturns(new OkResponse()))
 | 
			
		||||
                .And(x => GivenTheCreatorReturns(new OkResponse<IOcelotConfiguration>(config)))
 | 
			
		||||
                .And(x => GivenTheCreatorReturns(new OkResponse<IInternalConfiguration>(config)))
 | 
			
		||||
                .When(x => WhenISetTheConfiguration())
 | 
			
		||||
                .Then(x => ThenTheConfigurationRepositoryIsCalledCorrectly())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
@@ -67,7 +67,7 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
 | 
			
		||||
            this.Given(x => GivenTheFollowingConfiguration(fileConfig))
 | 
			
		||||
                .And(x => GivenTheRepoReturns(new OkResponse()))
 | 
			
		||||
                .And(x => GivenTheCreatorReturns(new ErrorResponse<IOcelotConfiguration>(It.IsAny<Error>())))
 | 
			
		||||
                .And(x => GivenTheCreatorReturns(new ErrorResponse<IInternalConfiguration>(It.IsAny<Error>())))
 | 
			
		||||
                .When(x => WhenISetTheConfiguration())
 | 
			
		||||
                .And(x => ThenAnErrorResponseIsReturned())
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
@@ -85,7 +85,7 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
            _result.ShouldBeOfType<ErrorResponse>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheCreatorReturns(Response<IOcelotConfiguration> configuration)
 | 
			
		||||
        private void GivenTheCreatorReturns(Response<IInternalConfiguration> configuration)
 | 
			
		||||
        {
 | 
			
		||||
            _configuration = configuration;
 | 
			
		||||
            _configCreator
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,5 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Ocelot.Configuration;
 | 
			
		||||
using Ocelot.Configuration.Builder;
 | 
			
		||||
using Ocelot.Configuration.Repository;
 | 
			
		||||
@@ -14,14 +12,14 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
{
 | 
			
		||||
    public class InMemoryConfigurationRepositoryTests
 | 
			
		||||
    {
 | 
			
		||||
        private readonly InMemoryOcelotConfigurationRepository _repo;
 | 
			
		||||
        private IOcelotConfiguration _config;
 | 
			
		||||
        private readonly InMemoryInternalConfigurationRepository _repo;
 | 
			
		||||
        private IInternalConfiguration _config;
 | 
			
		||||
        private Response _result;
 | 
			
		||||
        private Response<IOcelotConfiguration> _getResult;
 | 
			
		||||
        private Response<IInternalConfiguration> _getResult;
 | 
			
		||||
 | 
			
		||||
        public InMemoryConfigurationRepositoryTests()
 | 
			
		||||
        {
 | 
			
		||||
            _repo = new InMemoryOcelotConfigurationRepository();
 | 
			
		||||
            _repo = new InMemoryInternalConfigurationRepository();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
@@ -58,7 +56,7 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
            WhenIAddOrReplaceTheConfig();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheConfigurationIs(IOcelotConfiguration config)
 | 
			
		||||
        private void GivenTheConfigurationIs(IInternalConfiguration config)
 | 
			
		||||
        {
 | 
			
		||||
            _config = config;
 | 
			
		||||
        }
 | 
			
		||||
@@ -73,7 +71,7 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
            _result.IsError.ShouldBeFalse();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        class FakeConfig : IOcelotConfiguration
 | 
			
		||||
        class FakeConfig : IInternalConfiguration
 | 
			
		||||
        {
 | 
			
		||||
            private readonly string _downstreamTemplatePath;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,80 +0,0 @@
 | 
			
		||||
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;
 | 
			
		||||
using Ocelot.Errors;
 | 
			
		||||
using Ocelot.Responses;
 | 
			
		||||
using Shouldly;
 | 
			
		||||
using TestStack.BDDfy;
 | 
			
		||||
using Xunit;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
{
 | 
			
		||||
    public class OcelotConfigurationProviderTests
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IOcelotConfigurationProvider _ocelotConfigurationProvider;
 | 
			
		||||
        private readonly Mock<IOcelotConfigurationRepository> _configurationRepository;
 | 
			
		||||
        private Response<IOcelotConfiguration> _result;
 | 
			
		||||
 | 
			
		||||
        public OcelotConfigurationProviderTests()
 | 
			
		||||
        {
 | 
			
		||||
            _configurationRepository = new Mock<IOcelotConfigurationRepository>();
 | 
			
		||||
            _ocelotConfigurationProvider = new OcelotConfigurationProvider(_configurationRepository.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_get_config()
 | 
			
		||||
        {
 | 
			
		||||
            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, serviceProviderConfig, ""))))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_error()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(x => x.GivenTheRepoReturns(new ErrorResponse<IOcelotConfiguration>(new List<Error>
 | 
			
		||||
                    {
 | 
			
		||||
                        new AnyError()
 | 
			
		||||
                    })))
 | 
			
		||||
              .When(x => x.WhenIGetTheConfig())
 | 
			
		||||
              .Then(x => x.TheFollowingIsReturned(
 | 
			
		||||
                    new ErrorResponse<IOcelotConfiguration>(new List<Error>
 | 
			
		||||
                    {
 | 
			
		||||
                        new AnyError()
 | 
			
		||||
                    })))
 | 
			
		||||
              .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheRepoReturns(Response<IOcelotConfiguration> config)
 | 
			
		||||
        {
 | 
			
		||||
            _configurationRepository
 | 
			
		||||
                .Setup(x => x.Get())
 | 
			
		||||
                .Returns(config);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenIGetTheConfig()
 | 
			
		||||
        {
 | 
			
		||||
            _result = _ocelotConfigurationProvider.Get();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void TheFollowingIsReturned(Response<IOcelotConfiguration> expected)
 | 
			
		||||
        {
 | 
			
		||||
            _result.IsError.ShouldBe(expected.IsError);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        class AnyError : Error
 | 
			
		||||
        {
 | 
			
		||||
            public AnyError() 
 | 
			
		||||
                : base("blamo", OcelotErrorCode.UnknownError)
 | 
			
		||||
            {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -325,8 +325,8 @@ namespace Ocelot.UnitTests.DependencyInjection
 | 
			
		||||
            var outputCache = _services.Single(x => x.ServiceType == typeof(IOcelotCache<CachedResponse>));
 | 
			
		||||
            var outputCacheManager = _services.Single(x => x.ServiceType == typeof(ICacheManager<CachedResponse>));
 | 
			
		||||
            var instance = (ICacheManager<CachedResponse>)outputCacheManager.ImplementationInstance;
 | 
			
		||||
            var ocelotConfigCache = _services.Single(x => x.ServiceType == typeof(IOcelotCache<IOcelotConfiguration>));
 | 
			
		||||
            var ocelotConfigCacheManager = _services.Single(x => x.ServiceType == typeof(ICacheManager<IOcelotConfiguration>));
 | 
			
		||||
            var ocelotConfigCache = _services.Single(x => x.ServiceType == typeof(IOcelotCache<IInternalConfiguration>));
 | 
			
		||||
            var ocelotConfigCacheManager = _services.Single(x => x.ServiceType == typeof(ICacheManager<IInternalConfiguration>));
 | 
			
		||||
            var fileConfigCache = _services.Single(x => x.ServiceType == typeof(IOcelotCache<FileConfiguration>));
 | 
			
		||||
            var fileConfigCacheManager = _services.Single(x => x.ServiceType == typeof(ICacheManager<FileConfiguration>));
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,4 @@
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
using Ocelot.Middleware.Multiplexer;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
{
 | 
			
		||||
    using System.Collections.Generic;
 | 
			
		||||
    using System.Threading.Tasks;
 | 
			
		||||
@@ -9,7 +6,6 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
    using Moq;
 | 
			
		||||
    using Ocelot.Configuration;
 | 
			
		||||
    using Ocelot.Configuration.Builder;
 | 
			
		||||
    using Ocelot.Configuration.Provider;
 | 
			
		||||
    using Ocelot.DownstreamRouteFinder;
 | 
			
		||||
    using Ocelot.DownstreamRouteFinder.Finder;
 | 
			
		||||
    using Ocelot.DownstreamRouteFinder.Middleware;
 | 
			
		||||
@@ -19,23 +15,26 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
    using Shouldly;
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
    using Xunit;
 | 
			
		||||
    using Ocelot.Configuration.Repository;
 | 
			
		||||
    using Ocelot.Middleware;
 | 
			
		||||
    using Ocelot.Middleware.Multiplexer;
 | 
			
		||||
 | 
			
		||||
    public class DownstreamRouteFinderMiddlewareTests
 | 
			
		||||
    {
 | 
			
		||||
        private readonly Mock<IDownstreamRouteFinder> _finder;
 | 
			
		||||
        private readonly Mock<IOcelotConfigurationProvider> _provider;
 | 
			
		||||
        private readonly Mock<IInternalConfigurationRepository> _repo;
 | 
			
		||||
        private Response<DownstreamRoute> _downstreamRoute;
 | 
			
		||||
        private IOcelotConfiguration _config;
 | 
			
		||||
        private IInternalConfiguration _config;
 | 
			
		||||
        private Mock<IOcelotLoggerFactory> _loggerFactory;
 | 
			
		||||
        private Mock<IOcelotLogger> _logger;
 | 
			
		||||
        private DownstreamRouteFinderMiddleware _middleware;
 | 
			
		||||
        private DownstreamContext _downstreamContext;
 | 
			
		||||
        private readonly DownstreamRouteFinderMiddleware _middleware;
 | 
			
		||||
        private readonly DownstreamContext _downstreamContext;
 | 
			
		||||
        private OcelotRequestDelegate _next;
 | 
			
		||||
        private readonly Mock<IMultiplexer> _multiplexer;
 | 
			
		||||
 | 
			
		||||
        public DownstreamRouteFinderMiddlewareTests()
 | 
			
		||||
        {
 | 
			
		||||
            _provider = new Mock<IOcelotConfigurationProvider>();
 | 
			
		||||
            _repo = new Mock<IInternalConfigurationRepository>();
 | 
			
		||||
            _finder = new Mock<IDownstreamRouteFinder>();
 | 
			
		||||
            _downstreamContext = new DownstreamContext(new DefaultHttpContext());
 | 
			
		||||
            _loggerFactory = new Mock<IOcelotLoggerFactory>();
 | 
			
		||||
@@ -43,13 +42,13 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
            _loggerFactory.Setup(x => x.CreateLogger<DownstreamRouteFinderMiddleware>()).Returns(_logger.Object);
 | 
			
		||||
            _next = context => Task.CompletedTask;
 | 
			
		||||
            _multiplexer = new Mock<IMultiplexer>();
 | 
			
		||||
            _middleware = new DownstreamRouteFinderMiddleware(_next, _loggerFactory.Object, _finder.Object, _provider.Object, _multiplexer.Object);
 | 
			
		||||
            _middleware = new DownstreamRouteFinderMiddleware(_next, _loggerFactory.Object, _finder.Object, _repo.Object, _multiplexer.Object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_call_scoped_data_repository_correctly()
 | 
			
		||||
        {
 | 
			
		||||
            var config = new OcelotConfiguration(null, null, new ServiceProviderConfigurationBuilder().Build(), "");
 | 
			
		||||
            var config = new InternalConfiguration(null, null, new ServiceProviderConfigurationBuilder().Build(), "");
 | 
			
		||||
 | 
			
		||||
            var downstreamReRoute = new DownstreamReRouteBuilder()
 | 
			
		||||
                .WithDownstreamPathTemplate("any old string")
 | 
			
		||||
@@ -74,19 +73,19 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
            _middleware.Invoke(_downstreamContext).GetAwaiter().GetType();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheFollowingConfig(IOcelotConfiguration config)
 | 
			
		||||
        private void GivenTheFollowingConfig(IInternalConfiguration config)
 | 
			
		||||
        {
 | 
			
		||||
            _config = config;
 | 
			
		||||
            _provider
 | 
			
		||||
            _repo
 | 
			
		||||
                .Setup(x => x.Get())
 | 
			
		||||
                .Returns(new OkResponse<IOcelotConfiguration>(_config));
 | 
			
		||||
                .Returns(new OkResponse<IInternalConfiguration>(_config));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheDownStreamRouteFinderReturns(DownstreamRoute downstreamRoute)
 | 
			
		||||
        {
 | 
			
		||||
            _downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
 | 
			
		||||
            _finder
 | 
			
		||||
                .Setup(x => x.FindDownstreamRoute(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<IOcelotConfiguration>(), It.IsAny<string>()))
 | 
			
		||||
                .Setup(x => x.FindDownstreamRoute(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<IInternalConfiguration>(), It.IsAny<string>()))
 | 
			
		||||
                .Returns(_downstreamRoute);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
        private string _upstreamUrlPath;
 | 
			
		||||
        private Response<DownstreamRoute> _result;
 | 
			
		||||
        private List<ReRoute> _reRoutesConfig;
 | 
			
		||||
        private OcelotConfiguration _config;
 | 
			
		||||
        private InternalConfiguration _config;
 | 
			
		||||
        private Response<UrlMatch> _match;
 | 
			
		||||
        private string _upstreamHttpMethod;
 | 
			
		||||
        private string _upstreamHost;
 | 
			
		||||
@@ -711,7 +711,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
 | 
			
		||||
        private void GivenTheConfigurationIs(List<ReRoute> reRoutesConfig, string adminPath, ServiceProviderConfiguration serviceProviderConfig)
 | 
			
		||||
        {
 | 
			
		||||
            _reRoutesConfig = reRoutesConfig;
 | 
			
		||||
            _config = new OcelotConfiguration(_reRoutesConfig, adminPath, serviceProviderConfig, "");
 | 
			
		||||
            _config = new InternalConfiguration(_reRoutesConfig, adminPath, serviceProviderConfig, "");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenThereIsAnUpstreamUrlPath(string upstreamUrlPath)
 | 
			
		||||
 
 | 
			
		||||
@@ -9,17 +9,17 @@ namespace Ocelot.UnitTests.Errors
 | 
			
		||||
    using TestStack.BDDfy;
 | 
			
		||||
    using Xunit;
 | 
			
		||||
    using Microsoft.AspNetCore.Http;
 | 
			
		||||
    using Ocelot.Configuration.Provider;
 | 
			
		||||
    using Moq;
 | 
			
		||||
    using Ocelot.Configuration;
 | 
			
		||||
    using Ocelot.Errors;
 | 
			
		||||
    using Ocelot.Infrastructure.RequestData;
 | 
			
		||||
    using Ocelot.Middleware;
 | 
			
		||||
    using Ocelot.Configuration.Repository;
 | 
			
		||||
 | 
			
		||||
    public class ExceptionHandlerMiddlewareTests
 | 
			
		||||
    {
 | 
			
		||||
        bool _shouldThrowAnException;
 | 
			
		||||
        private readonly Mock<IOcelotConfigurationProvider> _provider;
 | 
			
		||||
        private readonly Mock<IInternalConfigurationRepository> _configRepo;
 | 
			
		||||
        private readonly Mock<IRequestScopedDataRepository> _repo;
 | 
			
		||||
        private Mock<IOcelotLoggerFactory> _loggerFactory;
 | 
			
		||||
        private Mock<IOcelotLogger> _logger;
 | 
			
		||||
@@ -29,7 +29,7 @@ namespace Ocelot.UnitTests.Errors
 | 
			
		||||
 | 
			
		||||
        public ExceptionHandlerMiddlewareTests()
 | 
			
		||||
        {
 | 
			
		||||
            _provider = new Mock<IOcelotConfigurationProvider>();
 | 
			
		||||
            _configRepo = new Mock<IInternalConfigurationRepository>();
 | 
			
		||||
            _repo = new Mock<IRequestScopedDataRepository>();
 | 
			
		||||
            _downstreamContext = new DownstreamContext(new DefaultHttpContext());
 | 
			
		||||
            _loggerFactory = new Mock<IOcelotLoggerFactory>();
 | 
			
		||||
@@ -45,13 +45,13 @@ namespace Ocelot.UnitTests.Errors
 | 
			
		||||
 | 
			
		||||
                context.HttpContext.Response.StatusCode = (int)HttpStatusCode.OK;
 | 
			
		||||
            };
 | 
			
		||||
            _middleware = new ExceptionHandlerMiddleware(_next, _loggerFactory.Object, _provider.Object, _repo.Object);
 | 
			
		||||
            _middleware = new ExceptionHandlerMiddleware(_next, _loggerFactory.Object, _configRepo.Object, _repo.Object);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void NoDownstreamException()
 | 
			
		||||
        {
 | 
			
		||||
            var config = new OcelotConfiguration(null, null, null, null);
 | 
			
		||||
            var config = new InternalConfiguration(null, null, null, null);
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenAnExceptionWillNotBeThrownDownstream())
 | 
			
		||||
                .And(_ => GivenTheConfigurationIs(config))
 | 
			
		||||
@@ -64,7 +64,7 @@ namespace Ocelot.UnitTests.Errors
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void DownstreamException()
 | 
			
		||||
        {
 | 
			
		||||
            var config = new OcelotConfiguration(null, null, null, null);
 | 
			
		||||
            var config = new InternalConfiguration(null, null, null, null);
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenAnExceptionWillBeThrownDownstream())
 | 
			
		||||
                .And(_ => GivenTheConfigurationIs(config))
 | 
			
		||||
@@ -76,7 +76,7 @@ namespace Ocelot.UnitTests.Errors
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void ShouldSetRequestId()
 | 
			
		||||
        {
 | 
			
		||||
            var config = new OcelotConfiguration(null, null, null, "requestidkey");
 | 
			
		||||
            var config = new InternalConfiguration(null, null, null, "requestidkey");
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenAnExceptionWillNotBeThrownDownstream())
 | 
			
		||||
                .And(_ => GivenTheConfigurationIs(config))
 | 
			
		||||
@@ -89,7 +89,7 @@ namespace Ocelot.UnitTests.Errors
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void ShouldSetAspDotNetRequestId()
 | 
			
		||||
        {
 | 
			
		||||
            var config = new OcelotConfiguration(null, null, null, null);
 | 
			
		||||
            var config = new InternalConfiguration(null, null, null, null);
 | 
			
		||||
 | 
			
		||||
            this.Given(_ => GivenAnExceptionWillNotBeThrownDownstream())
 | 
			
		||||
                .And(_ => GivenTheConfigurationIs(config))
 | 
			
		||||
@@ -133,7 +133,7 @@ namespace Ocelot.UnitTests.Errors
 | 
			
		||||
        private void GivenTheConfigThrows()
 | 
			
		||||
        {
 | 
			
		||||
            var ex = new Exception("outer", new Exception("inner"));
 | 
			
		||||
             _provider
 | 
			
		||||
             _configRepo
 | 
			
		||||
                .Setup(x => x.Get()).Throws(ex);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -144,8 +144,8 @@ namespace Ocelot.UnitTests.Errors
 | 
			
		||||
 | 
			
		||||
        private void GivenTheConfigReturnsError()
 | 
			
		||||
        {
 | 
			
		||||
            var response = new Responses.ErrorResponse<IOcelotConfiguration>(new FakeError());
 | 
			
		||||
            _provider
 | 
			
		||||
            var response = new Responses.ErrorResponse<IInternalConfiguration>(new FakeError());
 | 
			
		||||
            _configRepo
 | 
			
		||||
                .Setup(x => x.Get()).Returns(response);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -154,10 +154,10 @@ namespace Ocelot.UnitTests.Errors
 | 
			
		||||
            _repo.Verify(x => x.Add(key, value), Times.Once);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenTheConfigurationIs(IOcelotConfiguration config)
 | 
			
		||||
        private void GivenTheConfigurationIs(IInternalConfiguration config)
 | 
			
		||||
        {
 | 
			
		||||
            var response = new Responses.OkResponse<IOcelotConfiguration>(config);
 | 
			
		||||
            _provider
 | 
			
		||||
            var response = new Responses.OkResponse<IInternalConfiguration>(config);
 | 
			
		||||
            _configRepo
 | 
			
		||||
                .Setup(x => x.Get()).Returns(response);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user