diff --git a/src/Ocelot/Configuration/Creator/FileOcelotConfigurationCreator.cs b/src/Ocelot/Configuration/Creator/FileOcelotConfigurationCreator.cs
index a2ebb709..c44edd08 100644
--- a/src/Ocelot/Configuration/Creator/FileOcelotConfigurationCreator.cs
+++ b/src/Ocelot/Configuration/Creator/FileOcelotConfigurationCreator.cs
@@ -1,191 +1,191 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading.Tasks;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Options;
-using Ocelot.Configuration.Builder;
-using Ocelot.Configuration.File;
-using Ocelot.Configuration.Parser;
-using Ocelot.Configuration.Validator;
-using Ocelot.LoadBalancer.LoadBalancers;
-using Ocelot.Logging;
-using Ocelot.Requester.QoS;
-using Ocelot.Responses;
-using Ocelot.Utilities;
-
-namespace Ocelot.Configuration.Creator
-{
- ///
- /// Register as singleton
- ///
- public class FileOcelotConfigurationCreator : IOcelotConfigurationCreator
- {
- private readonly IOptions _options;
- private readonly IConfigurationValidator _configurationValidator;
- private readonly IOcelotLogger _logger;
- private readonly ILoadBalancerFactory _loadBalanceFactory;
- private readonly ILoadBalancerHouse _loadBalancerHouse;
- private readonly IQoSProviderFactory _qoSProviderFactory;
- private readonly IQosProviderHouse _qosProviderHouse;
- private readonly IClaimsToThingCreator _claimsToThingCreator;
- private readonly IAuthenticationOptionsCreator _authOptionsCreator;
- private IUpstreamTemplatePatternCreator _upstreamTemplatePatternCreator;
- private IRequestIdKeyCreator _requestIdKeyCreator;
- private IServiceProviderConfigurationCreator _serviceProviderConfigCreator;
- private IQoSOptionsCreator _qosOptionsCreator;
- private IReRouteOptionsCreator _fileReRouteOptionsCreator;
- private IRateLimitOptionsCreator _rateLimitOptionsCreator;
-
- public FileOcelotConfigurationCreator(
- IOptions options,
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using Ocelot.Configuration.Builder;
+using Ocelot.Configuration.File;
+using Ocelot.Configuration.Parser;
+using Ocelot.Configuration.Validator;
+using Ocelot.LoadBalancer.LoadBalancers;
+using Ocelot.Logging;
+using Ocelot.Requester.QoS;
+using Ocelot.Responses;
+using Ocelot.Utilities;
+
+namespace Ocelot.Configuration.Creator
+{
+ ///
+ /// Register as singleton
+ ///
+ public class FileOcelotConfigurationCreator : IOcelotConfigurationCreator
+ {
+ private readonly IOptions _options;
+ private readonly IConfigurationValidator _configurationValidator;
+ private readonly IOcelotLogger _logger;
+ private readonly ILoadBalancerFactory _loadBalanceFactory;
+ private readonly ILoadBalancerHouse _loadBalancerHouse;
+ private readonly IQoSProviderFactory _qoSProviderFactory;
+ private readonly IQosProviderHouse _qosProviderHouse;
+ private readonly IClaimsToThingCreator _claimsToThingCreator;
+ private readonly IAuthenticationOptionsCreator _authOptionsCreator;
+ private IUpstreamTemplatePatternCreator _upstreamTemplatePatternCreator;
+ private IRequestIdKeyCreator _requestIdKeyCreator;
+ private IServiceProviderConfigurationCreator _serviceProviderConfigCreator;
+ private IQoSOptionsCreator _qosOptionsCreator;
+ private IReRouteOptionsCreator _fileReRouteOptionsCreator;
+ private IRateLimitOptionsCreator _rateLimitOptionsCreator;
+
+ public FileOcelotConfigurationCreator(
+ IOptions options,
IConfigurationValidator configurationValidator,
- IOcelotLoggerFactory loggerFactory,
- ILoadBalancerFactory loadBalancerFactory,
- ILoadBalancerHouse loadBalancerHouse,
- IQoSProviderFactory qoSProviderFactory,
- IQosProviderHouse qosProviderHouse,
- IClaimsToThingCreator claimsToThingCreator,
- IAuthenticationOptionsCreator authOptionsCreator,
- IUpstreamTemplatePatternCreator upstreamTemplatePatternCreator,
- IRequestIdKeyCreator requestIdKeyCreator,
- IServiceProviderConfigurationCreator serviceProviderConfigCreator,
- IQoSOptionsCreator qosOptionsCreator,
- IReRouteOptionsCreator fileReRouteOptionsCreator,
- IRateLimitOptionsCreator rateLimitOptionsCreator
- )
- {
- _rateLimitOptionsCreator = rateLimitOptionsCreator;
- _requestIdKeyCreator = requestIdKeyCreator;
- _upstreamTemplatePatternCreator = upstreamTemplatePatternCreator;
- _authOptionsCreator = authOptionsCreator;
- _loadBalanceFactory = loadBalancerFactory;
- _loadBalancerHouse = loadBalancerHouse;
- _qoSProviderFactory = qoSProviderFactory;
- _qosProviderHouse = qosProviderHouse;
- _options = options;
- _configurationValidator = configurationValidator;
- _logger = loggerFactory.CreateLogger();
- _claimsToThingCreator = claimsToThingCreator;
- _serviceProviderConfigCreator = serviceProviderConfigCreator;
- _qosOptionsCreator = qosOptionsCreator;
- _fileReRouteOptionsCreator = fileReRouteOptionsCreator;
- }
-
- public async Task> Create()
- {
- var config = await SetUpConfiguration(_options.Value);
-
- return new OkResponse(config);
- }
-
- public async Task> Create(FileConfiguration fileConfiguration)
- {
- var config = await SetUpConfiguration(fileConfiguration);
-
- return new OkResponse(config);
- }
-
- private async Task SetUpConfiguration(FileConfiguration fileConfiguration)
- {
- var response = _configurationValidator.IsValid(fileConfiguration);
-
- if (response.Data.IsError)
- {
- var errorBuilder = new StringBuilder();
-
- foreach (var error in response.Errors)
- {
- errorBuilder.AppendLine(error.Message);
- }
-
- throw new Exception($"Unable to start Ocelot..configuration, errors were {errorBuilder}");
- }
-
- var reRoutes = new List();
-
- foreach (var reRoute in fileConfiguration.ReRoutes)
- {
- var ocelotReRoute = await SetUpReRoute(reRoute, fileConfiguration.GlobalConfiguration);
- reRoutes.Add(ocelotReRoute);
- }
-
- return new OcelotConfiguration(reRoutes, fileConfiguration.GlobalConfiguration.AdministrationPath);
- }
-
- private async Task SetUpReRoute(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 serviceProviderConfiguration = _serviceProviderConfigCreator.Create(fileReRoute, globalConfiguration);
-
- 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 reRoute = new ReRouteBuilder()
- .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))
- .WithDownstreamScheme(fileReRoute.DownstreamScheme)
- .WithLoadBalancer(fileReRoute.LoadBalancer)
- .WithDownstreamHost(fileReRoute.DownstreamHost)
- .WithDownstreamPort(fileReRoute.DownstreamPort)
- .WithLoadBalancerKey(reRouteKey)
- .WithServiceProviderConfiguraion(serviceProviderConfiguration)
- .WithIsQos(fileReRouteOptions.IsQos)
- .WithQosOptions(qosOptions)
- .WithEnableRateLimiting(fileReRouteOptions.EnableRateLimiting)
- .WithRateLimitOptions(rateLimitOption)
- .Build();
-
- await SetupLoadBalancer(reRoute);
- SetupQosProvider(reRoute);
- 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}{fileReRoute.UpstreamHttpMethod}";
- return loadBalancerKey;
- }
-
- private async Task SetupLoadBalancer(ReRoute reRoute)
- {
- var loadBalancer = await _loadBalanceFactory.Get(reRoute);
- _loadBalancerHouse.Add(reRoute.ReRouteKey, loadBalancer);
- }
-
- private void SetupQosProvider(ReRoute reRoute)
- {
- var loadBalancer = _qoSProviderFactory.Get(reRoute);
- _qosProviderHouse.Add(reRoute.ReRouteKey, loadBalancer);
- }
- }
+ IOcelotLoggerFactory loggerFactory,
+ ILoadBalancerFactory loadBalancerFactory,
+ ILoadBalancerHouse loadBalancerHouse,
+ IQoSProviderFactory qoSProviderFactory,
+ IQosProviderHouse qosProviderHouse,
+ IClaimsToThingCreator claimsToThingCreator,
+ IAuthenticationOptionsCreator authOptionsCreator,
+ IUpstreamTemplatePatternCreator upstreamTemplatePatternCreator,
+ IRequestIdKeyCreator requestIdKeyCreator,
+ IServiceProviderConfigurationCreator serviceProviderConfigCreator,
+ IQoSOptionsCreator qosOptionsCreator,
+ IReRouteOptionsCreator fileReRouteOptionsCreator,
+ IRateLimitOptionsCreator rateLimitOptionsCreator
+ )
+ {
+ _rateLimitOptionsCreator = rateLimitOptionsCreator;
+ _requestIdKeyCreator = requestIdKeyCreator;
+ _upstreamTemplatePatternCreator = upstreamTemplatePatternCreator;
+ _authOptionsCreator = authOptionsCreator;
+ _loadBalanceFactory = loadBalancerFactory;
+ _loadBalancerHouse = loadBalancerHouse;
+ _qoSProviderFactory = qoSProviderFactory;
+ _qosProviderHouse = qosProviderHouse;
+ _options = options;
+ _configurationValidator = configurationValidator;
+ _logger = loggerFactory.CreateLogger();
+ _claimsToThingCreator = claimsToThingCreator;
+ _serviceProviderConfigCreator = serviceProviderConfigCreator;
+ _qosOptionsCreator = qosOptionsCreator;
+ _fileReRouteOptionsCreator = fileReRouteOptionsCreator;
+ }
+
+ public async Task> Create()
+ {
+ var config = await SetUpConfiguration(_options.Value);
+
+ return new OkResponse(config);
+ }
+
+ public async Task> Create(FileConfiguration fileConfiguration)
+ {
+ var config = await SetUpConfiguration(fileConfiguration);
+
+ return new OkResponse(config);
+ }
+
+ private async Task SetUpConfiguration(FileConfiguration fileConfiguration)
+ {
+ var response = _configurationValidator.IsValid(fileConfiguration);
+
+ if (response.Data.IsError)
+ {
+ var errorBuilder = new StringBuilder();
+
+ foreach (var error in response.Errors)
+ {
+ errorBuilder.AppendLine(error.Message);
+ }
+
+ throw new Exception($"Unable to start Ocelot..configuration, errors were {errorBuilder}");
+ }
+
+ var reRoutes = new List();
+
+ foreach (var reRoute in fileConfiguration.ReRoutes)
+ {
+ var ocelotReRoute = await SetUpReRoute(reRoute, fileConfiguration.GlobalConfiguration);
+ reRoutes.Add(ocelotReRoute);
+ }
+
+ return new OcelotConfiguration(reRoutes, fileConfiguration.GlobalConfiguration.AdministrationPath);
+ }
+
+ private async Task SetUpReRoute(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 serviceProviderConfiguration = _serviceProviderConfigCreator.Create(fileReRoute, globalConfiguration);
+
+ 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 reRoute = new ReRouteBuilder()
+ .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))
+ .WithDownstreamScheme(fileReRoute.DownstreamScheme)
+ .WithLoadBalancer(fileReRoute.LoadBalancer)
+ .WithDownstreamHost(fileReRoute.DownstreamHost)
+ .WithDownstreamPort(fileReRoute.DownstreamPort)
+ .WithLoadBalancerKey(reRouteKey)
+ .WithServiceProviderConfiguraion(serviceProviderConfiguration)
+ .WithIsQos(fileReRouteOptions.IsQos)
+ .WithQosOptions(qosOptions)
+ .WithEnableRateLimiting(fileReRouteOptions.EnableRateLimiting)
+ .WithRateLimitOptions(rateLimitOption)
+ .Build();
+
+ await SetupLoadBalancer(reRoute);
+ SetupQosProvider(reRoute);
+ 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}{fileReRoute.UpstreamHttpMethod}";
+ return loadBalancerKey;
+ }
+
+ private async Task SetupLoadBalancer(ReRoute reRoute)
+ {
+ var loadBalancer = await _loadBalanceFactory.Get(reRoute);
+ _loadBalancerHouse.Add(reRoute.ReRouteKey, loadBalancer);
+ }
+
+ private void SetupQosProvider(ReRoute reRoute)
+ {
+ var loadBalancer = _qoSProviderFactory.Get(reRoute);
+ _qosProviderHouse.Add(reRoute.ReRouteKey, loadBalancer);
+ }
+ }
}
\ No newline at end of file
diff --git a/src/Ocelot/Requester/HttpClientHttpRequester.cs b/src/Ocelot/Requester/HttpClientHttpRequester.cs
index a7f747d4..3f85af0c 100644
--- a/src/Ocelot/Requester/HttpClientHttpRequester.cs
+++ b/src/Ocelot/Requester/HttpClientHttpRequester.cs
@@ -22,9 +22,12 @@ namespace Ocelot.Requester
public async Task> GetResponse(Request.Request request)
{
- var cacheKey = GetCacheKey(request);
+ var builder = new HttpClientBuilder();
+
+ var cacheKey = GetCacheKey(request, builder);
+
+ var httpClient = GetHttpClient(cacheKey, builder);
- IHttpClient httpClient = GetHttpClient(cacheKey);
try
{
var response = await httpClient.SendAsync(request.HttpRequestMessage);
@@ -51,11 +54,10 @@ namespace Ocelot.Requester
}
- private IHttpClient GetHttpClient(string cacheKey)
+ private IHttpClient GetHttpClient(string cacheKey, IHttpClientBuilder builder)
{
- var builder = new HttpClientBuilder();
-
var httpClient = _cacheHandlers.Get(cacheKey);
+
if (httpClient == null)
{
httpClient = builder.Create();
@@ -63,9 +65,16 @@ namespace Ocelot.Requester
return httpClient;
}
- private string GetCacheKey(Request.Request request)
+ private string GetCacheKey(Request.Request request, IHttpClientBuilder builder)
{
string baseUrl = $"{request.HttpRequestMessage.RequestUri.Scheme}://{request.HttpRequestMessage.RequestUri.Authority}";
+
+ if (request.IsQos)
+ {
+ builder.WithQos(request.QosProvider, _logger);
+ baseUrl = $"{baseUrl}{request.QosProvider.CircuitBreaker.CircuitBreakerPolicy.PolicyKey}";
+ }
+
return baseUrl;
}
}
diff --git a/test/Ocelot.AcceptanceTests/QoSTests.cs b/test/Ocelot.AcceptanceTests/QoSTests.cs
index 98c0540e..8825b75b 100644
--- a/test/Ocelot.AcceptanceTests/QoSTests.cs
+++ b/test/Ocelot.AcceptanceTests/QoSTests.cs
@@ -45,7 +45,8 @@ namespace Ocelot.AcceptanceTests
ExceptionsAllowedBeforeBreaking = 1,
TimeoutValue = 500,
DurationOfBreak = 1000
- }
+ },
+
}
}
};