From e80364a1f8af50bf7976fafbc20c6829a092b88a Mon Sep 17 00:00:00 2001 From: geffzhang Date: Thu, 2 Feb 2017 23:35:02 +0800 Subject: [PATCH 1/7] HttpClientHttpRequester implements the Circuit Breaker Pattern MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HttpClientHttpRequester implements the Circuit Breaker Pattern,I using Polly from thepollyproject.org --- .../Requester/HttpClientHttpRequester.cs | 40 ++++++++++++++++++- src/Ocelot/project.json | 3 +- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/Ocelot/Requester/HttpClientHttpRequester.cs b/src/Ocelot/Requester/HttpClientHttpRequester.cs index 0167ef6a..8056adeb 100644 --- a/src/Ocelot/Requester/HttpClientHttpRequester.cs +++ b/src/Ocelot/Requester/HttpClientHttpRequester.cs @@ -4,22 +4,58 @@ using System.Net.Http; using System.Threading.Tasks; using Ocelot.Errors; using Ocelot.Responses; +using Polly; +using Polly.Timeout; +using Polly.CircuitBreaker; +using Ocelot.Logging; namespace Ocelot.Requester { public class HttpClientHttpRequester : IHttpRequester { + private readonly IOcelotLogger _logger; + + public HttpClientHttpRequester(IOcelotLoggerFactory loggerFactory) + { + _logger = loggerFactory.CreateLogger(); + } + public async Task> GetResponse(Request.Request request) { + double timeoutvalue = 5000; + TimeoutStrategy timeoutStrategy = TimeoutStrategy.Pessimistic; + + var timeoutPolicy = Policy + .TimeoutAsync(TimeSpan.FromMilliseconds(timeoutvalue), timeoutStrategy); + + var circuitBreakerPolicy = Policy + .Handle() + .Or() + .Or() + .CircuitBreakerAsync( + exceptionsAllowedBeforeBreaking: 4, + durationOfBreak: TimeSpan.FromSeconds(8), + onBreak: (ex, breakDelay) => + { + _logger.LogError(".Breaker logging: Breaking the circuit for " + breakDelay.TotalMilliseconds + "ms!", ex); + }, + onReset: () => _logger.LogDebug(".Breaker logging: Call ok! Closed the circuit again."), + onHalfOpen: () => _logger.LogDebug(".Breaker logging: Half-open; next call is a trial.") + ); + using (var handler = new HttpClientHandler { CookieContainer = request.CookieContainer }) using (var httpClient = new HttpClient(handler)) { try { - var response = await httpClient.SendAsync(request.HttpRequestMessage); + // Retry the following call according to the policy - 3 times. + HttpResponseMessage response = await Policy.WrapAsync(circuitBreakerPolicy, timeoutPolicy).ExecuteAsync(() => + { + return httpClient.SendAsync(request.HttpRequestMessage); + }); return new OkResponse(response); } - catch (Exception exception) + catch (BrokenCircuitException exception) { return new ErrorResponse(new List diff --git a/src/Ocelot/project.json b/src/Ocelot/project.json index 85008568..6711d984 100644 --- a/src/Ocelot/project.json +++ b/src/Ocelot/project.json @@ -27,7 +27,8 @@ "Microsoft.NETCore.App": "1.1.0", "CacheManager.Core": "0.9.2", "CacheManager.Microsoft.Extensions.Configuration": "0.9.2", - "CacheManager.Microsoft.Extensions.Logging": "0.9.2" + "CacheManager.Microsoft.Extensions.Logging": "0.9.2", + "Polly": "5.0.3" }, "runtimes": { "win10-x64": {}, From 883be802b303c4049fcf40267ad55ccab3a39bb3 Mon Sep 17 00:00:00 2001 From: geffzhang Date: Fri, 3 Feb 2017 14:49:46 +0800 Subject: [PATCH 2/7] Refactor CircuitBreaker Pattern Add Qos Config in ReRoute And Refactor CircuitBreakingDelegatingHandler --- .../Configuration/Builder/ReRouteBuilder.cs | 24 +- .../Creator/FileOcelotConfigurationCreator.cs | 7 +- src/Ocelot/Configuration/File/FileReRoute.cs | 3 + src/Ocelot/Configuration/ReRoute.cs | 9 +- .../Request/Builder/HttpRequestCreator.cs | 4 +- src/Ocelot/Request/Builder/IRequestCreator.cs | 3 +- src/Ocelot/Request/Builder/RequestBuilder.cs | 9 +- .../HttpRequestBuilderMiddleware.cs | 3 +- src/Ocelot/Request/Request.cs | 7 +- .../CircuitBreakingDelegatingHandler.cs | 74 +++ src/Ocelot/Requester/HttpClientBuilder.cs | 41 ++ .../Requester/HttpClientHttpRequester.cs | 55 +-- src/Ocelot/Requester/IHttpRequester.cs | 2 + src/Ocelot/Values/QoS.cs | 27 ++ .../AuthenticationTests.cs | 9 + .../AuthorisationTests.cs | 3 + test/Ocelot.AcceptanceTests/CachingTests.cs | 6 + .../CaseSensitiveRoutingTests.cs | 30 +- .../ClaimsToHeadersForwardingTests.cs | 3 + .../ClaimsToQueryStringForwardingTests.cs | 3 + .../CustomMiddlewareTests.cs | 18 + test/Ocelot.AcceptanceTests/RequestIdTests.cs | 13 +- test/Ocelot.AcceptanceTests/RoutingTests.cs | 31 +- .../Ocelot.AcceptanceTests/configuration.json | 2 +- test/Ocelot.ManualTest/configuration.json | 437 ++++++++++-------- .../HttpRequestBuilderMiddlewareTests.cs | 4 +- .../Request/RequestBuilderTests.cs | 30 +- .../Requester/HttpRequesterMiddlewareTests.cs | 2 +- 28 files changed, 600 insertions(+), 259 deletions(-) create mode 100644 src/Ocelot/Requester/CircuitBreakingDelegatingHandler.cs create mode 100644 src/Ocelot/Requester/HttpClientBuilder.cs create mode 100644 src/Ocelot/Values/QoS.cs diff --git a/src/Ocelot/Configuration/Builder/ReRouteBuilder.cs b/src/Ocelot/Configuration/Builder/ReRouteBuilder.cs index 1e06a440..effb9cb8 100644 --- a/src/Ocelot/Configuration/Builder/ReRouteBuilder.cs +++ b/src/Ocelot/Configuration/Builder/ReRouteBuilder.cs @@ -32,6 +32,9 @@ namespace Ocelot.Configuration.Builder private string _downstreamScheme; private string _downstreamHost; private int _dsPort; + private int _exceptionsAllowedBeforeBreaking; + private int _durationOfBreak; + private int _timeoutValue; public ReRouteBuilder() { @@ -192,6 +195,24 @@ namespace Ocelot.Configuration.Builder return this; } + public ReRouteBuilder WithExceptionsAllowedBeforeBreaking(int exceptionsAllowedBeforeBreaking) + { + _exceptionsAllowedBeforeBreaking = exceptionsAllowedBeforeBreaking; + return this; + } + + public ReRouteBuilder WithDurationOfBreak(int durationOfBreak) + { + _durationOfBreak = durationOfBreak; + return this; + } + + public ReRouteBuilder WithTimeoutValue(int timeoutValue) + { + _timeoutValue = timeoutValue; + return this; + } + public ReRoute Build() { Func downstreamHostFunc = () => new HostAndPort(_downstreamHost, _dsPort); @@ -200,7 +221,8 @@ namespace Ocelot.Configuration.Builder _isAuthenticated, new AuthenticationOptions(_authenticationProvider, _authenticationProviderUrl, _scopeName, _requireHttps, _additionalScopes, _scopeSecret), _configHeaderExtractorProperties, _claimToClaims, _routeClaimRequirement, _isAuthorised, _claimToQueries, _requestIdHeaderKey, _isCached, _fileCacheOptions, _serviceName, - _useServiceDiscovery, _serviceDiscoveryAddress, _serviceDiscoveryProvider, downstreamHostFunc, _downstreamScheme); + _useServiceDiscovery, _serviceDiscoveryAddress, _serviceDiscoveryProvider, downstreamHostFunc, _downstreamScheme, + _exceptionsAllowedBeforeBreaking,_durationOfBreak, _timeoutValue); } } } diff --git a/src/Ocelot/Configuration/Creator/FileOcelotConfigurationCreator.cs b/src/Ocelot/Configuration/Creator/FileOcelotConfigurationCreator.cs index 8884f0d9..e22ecd0b 100644 --- a/src/Ocelot/Configuration/Creator/FileOcelotConfigurationCreator.cs +++ b/src/Ocelot/Configuration/Creator/FileOcelotConfigurationCreator.cs @@ -96,7 +96,6 @@ namespace Ocelot.Configuration.Creator && !string.IsNullOrEmpty(globalConfiguration?.ServiceDiscoveryProvider?.Address) && !string.IsNullOrEmpty(globalConfiguration?.ServiceDiscoveryProvider?.Provider); - Func downstreamHostAndPortFunc = () => new HostAndPort(reRoute.DownstreamHost.Trim('/'), reRoute.DownstreamPort); if (isAuthenticated) @@ -116,7 +115,8 @@ namespace Ocelot.Configuration.Creator reRoute.RouteClaimsRequirement, isAuthorised, claimsToQueries, requestIdKey, isCached, new CacheOptions(reRoute.FileCacheOptions.TtlSeconds), reRoute.ServiceName, useServiceDiscovery, globalConfiguration?.ServiceDiscoveryProvider?.Provider, - globalConfiguration?.ServiceDiscoveryProvider?.Address, downstreamHostAndPortFunc, reRoute.DownstreamScheme); + globalConfiguration?.ServiceDiscoveryProvider?.Address, downstreamHostAndPortFunc, reRoute.DownstreamScheme, + reRoute.ExceptionsAllowedBeforeBreaking, reRoute.DurationOfBreak, reRoute.TimeoutValue); } return new ReRoute(new DownstreamPathTemplate(reRoute.DownstreamPathTemplate), reRoute.UpstreamTemplate, @@ -125,7 +125,8 @@ namespace Ocelot.Configuration.Creator reRoute.RouteClaimsRequirement, isAuthorised, new List(), requestIdKey, isCached, new CacheOptions(reRoute.FileCacheOptions.TtlSeconds), reRoute.ServiceName, useServiceDiscovery, globalConfiguration?.ServiceDiscoveryProvider?.Provider, - globalConfiguration?.ServiceDiscoveryProvider?.Address, downstreamHostAndPortFunc, reRoute.DownstreamScheme); + globalConfiguration?.ServiceDiscoveryProvider?.Address, downstreamHostAndPortFunc, reRoute.DownstreamScheme, + reRoute.ExceptionsAllowedBeforeBreaking, reRoute.DurationOfBreak, reRoute.TimeoutValue); } private string BuildUpstreamTemplate(FileReRoute reRoute) diff --git a/src/Ocelot/Configuration/File/FileReRoute.cs b/src/Ocelot/Configuration/File/FileReRoute.cs index a653224a..314f13bf 100644 --- a/src/Ocelot/Configuration/File/FileReRoute.cs +++ b/src/Ocelot/Configuration/File/FileReRoute.cs @@ -29,5 +29,8 @@ namespace Ocelot.Configuration.File public string DownstreamScheme {get;set;} public string DownstreamHost {get;set;} public int DownstreamPort { get; set; } + public int ExceptionsAllowedBeforeBreaking { get; set; } + public int DurationOfBreak { get; set; } + public int TimeoutValue { get; set; } } } \ No newline at end of file diff --git a/src/Ocelot/Configuration/ReRoute.cs b/src/Ocelot/Configuration/ReRoute.cs index 960374cc..f6e188b7 100644 --- a/src/Ocelot/Configuration/ReRoute.cs +++ b/src/Ocelot/Configuration/ReRoute.cs @@ -10,7 +10,8 @@ namespace Ocelot.Configuration bool isAuthenticated, AuthenticationOptions authenticationOptions, List configurationHeaderExtractorProperties, List claimsToClaims, Dictionary routeClaimsRequirement, bool isAuthorised, List claimsToQueries, string requestIdKey, bool isCached, CacheOptions fileCacheOptions, string serviceName, bool useServiceDiscovery, - string serviceDiscoveryProvider, string serviceDiscoveryAddress, Func downstreamHostAndPort, string downstreamScheme) + string serviceDiscoveryProvider, string serviceDiscoveryAddress, Func downstreamHostAndPort, string downstreamScheme, + int exceptionsAllowedBeforeBreaking =3, int durationofBreak =8, int timeoutValue = 5000) { DownstreamPathTemplate = downstreamPathTemplate; UpstreamTemplate = upstreamTemplate; @@ -35,6 +36,9 @@ namespace Ocelot.Configuration ServiceDiscoveryAddress = serviceDiscoveryAddress; DownstreamHostAndPort = downstreamHostAndPort; DownstreamScheme = downstreamScheme; + ExceptionsAllowedBeforeBreaking = exceptionsAllowedBeforeBreaking; + DurationOfBreak = durationofBreak; + TimeoutValue = timeoutValue; } public DownstreamPathTemplate DownstreamPathTemplate { get; private set; } @@ -57,5 +61,8 @@ namespace Ocelot.Configuration public string ServiceDiscoveryAddress { get; private set;} public Func DownstreamHostAndPort {get;private set;} public string DownstreamScheme {get;private set;} + public int ExceptionsAllowedBeforeBreaking { get; private set; } + public int DurationOfBreak { get; private set; } + public int TimeoutValue { get; private set; } } } \ No newline at end of file diff --git a/src/Ocelot/Request/Builder/HttpRequestCreator.cs b/src/Ocelot/Request/Builder/HttpRequestCreator.cs index 91234331..27ba4c07 100644 --- a/src/Ocelot/Request/Builder/HttpRequestCreator.cs +++ b/src/Ocelot/Request/Builder/HttpRequestCreator.cs @@ -15,7 +15,8 @@ namespace Ocelot.Request.Builder IRequestCookieCollection cookies, QueryString queryString, string contentType, - RequestId.RequestId requestId) + RequestId.RequestId requestId, + Values.QoS qos) { var request = await new RequestBuilder() .WithHttpMethod(httpMethod) @@ -26,6 +27,7 @@ namespace Ocelot.Request.Builder .WithHeaders(headers) .WithRequestId(requestId) .WithCookies(cookies) + .WithQos(qos) .Build(); return new OkResponse(request); diff --git a/src/Ocelot/Request/Builder/IRequestCreator.cs b/src/Ocelot/Request/Builder/IRequestCreator.cs index 7641d848..858636b5 100644 --- a/src/Ocelot/Request/Builder/IRequestCreator.cs +++ b/src/Ocelot/Request/Builder/IRequestCreator.cs @@ -14,6 +14,7 @@ namespace Ocelot.Request.Builder IRequestCookieCollection cookies, QueryString queryString, string contentType, - RequestId.RequestId requestId); + RequestId.RequestId requestId, + Values.QoS qos); } } diff --git a/src/Ocelot/Request/Builder/RequestBuilder.cs b/src/Ocelot/Request/Builder/RequestBuilder.cs index c9463993..d7f35ef7 100644 --- a/src/Ocelot/Request/Builder/RequestBuilder.cs +++ b/src/Ocelot/Request/Builder/RequestBuilder.cs @@ -22,6 +22,7 @@ namespace Ocelot.Request.Builder private RequestId.RequestId _requestId; private IRequestCookieCollection _cookies; private readonly string[] _unsupportedHeaders = {"host"}; + private Values.QoS _qos; public RequestBuilder WithHttpMethod(string httpMethod) { @@ -71,6 +72,12 @@ namespace Ocelot.Request.Builder return this; } + public RequestBuilder WithQos(Values.QoS qos) + { + _qos = qos; + return this; + } + public async Task Build() { var uri = CreateUri(); @@ -90,7 +97,7 @@ namespace Ocelot.Request.Builder var cookieContainer = CreateCookieContainer(uri); - return new Request(httpRequestMessage, cookieContainer); + return new Request(httpRequestMessage, cookieContainer, _qos); } private Uri CreateUri() diff --git a/src/Ocelot/Request/Middleware/HttpRequestBuilderMiddleware.cs b/src/Ocelot/Request/Middleware/HttpRequestBuilderMiddleware.cs index a2c5194b..a875ea8c 100644 --- a/src/Ocelot/Request/Middleware/HttpRequestBuilderMiddleware.cs +++ b/src/Ocelot/Request/Middleware/HttpRequestBuilderMiddleware.cs @@ -32,7 +32,8 @@ namespace Ocelot.Request.Middleware var buildResult = await _requestCreator .Build(context.Request.Method, DownstreamUrl, context.Request.Body, context.Request.Headers, context.Request.Cookies, context.Request.QueryString, - context.Request.ContentType, new RequestId.RequestId(DownstreamRoute?.ReRoute?.RequestIdKey, context.TraceIdentifier)); + context.Request.ContentType, new RequestId.RequestId(DownstreamRoute?.ReRoute?.RequestIdKey, context.TraceIdentifier), + new Values.QoS(DownstreamRoute.ReRoute.ExceptionsAllowedBeforeBreaking, DownstreamRoute.ReRoute.DurationOfBreak, DownstreamRoute.ReRoute.TimeoutValue)); if (buildResult.IsError) { diff --git a/src/Ocelot/Request/Request.cs b/src/Ocelot/Request/Request.cs index d43071e1..60e23b1e 100644 --- a/src/Ocelot/Request/Request.cs +++ b/src/Ocelot/Request/Request.cs @@ -1,17 +1,20 @@ -using System.Net; +using Ocelot.Values; +using System.Net; using System.Net.Http; namespace Ocelot.Request { public class Request { - public Request(HttpRequestMessage httpRequestMessage, CookieContainer cookieContainer) + public Request(HttpRequestMessage httpRequestMessage, CookieContainer cookieContainer, QoS qos) { HttpRequestMessage = httpRequestMessage; CookieContainer = cookieContainer; + Qos = qos; } public HttpRequestMessage HttpRequestMessage { get; private set; } public CookieContainer CookieContainer { get; private set; } + public QoS Qos { get; private set; } } } diff --git a/src/Ocelot/Requester/CircuitBreakingDelegatingHandler.cs b/src/Ocelot/Requester/CircuitBreakingDelegatingHandler.cs new file mode 100644 index 00000000..4adc0eeb --- /dev/null +++ b/src/Ocelot/Requester/CircuitBreakingDelegatingHandler.cs @@ -0,0 +1,74 @@ +using Ocelot.Logging; +using Polly; +using Polly.CircuitBreaker; +using Polly.Timeout; +using System; +using System.Net; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +namespace Ocelot.Requester +{ + public class CircuitBreakingDelegatingHandler : DelegatingHandler + { + private readonly IOcelotLogger _logger; + private readonly int _exceptionsAllowedBeforeBreaking; + private readonly TimeSpan _durationOfBreak; + private readonly Policy _circuitBreakerPolicy; + private readonly TimeoutPolicy _timeoutPolicy; + + public CircuitBreakingDelegatingHandler(int exceptionsAllowedBeforeBreaking, TimeSpan durationOfBreak,TimeSpan timeoutValue + ,TimeoutStrategy timeoutStrategy, IOcelotLogger logger, HttpMessageHandler innerHandler) + : base(innerHandler) + { + this._exceptionsAllowedBeforeBreaking = exceptionsAllowedBeforeBreaking; + this._durationOfBreak = durationOfBreak; + + _circuitBreakerPolicy = Policy + .Handle() + .Or() + .Or() + .CircuitBreakerAsync( + exceptionsAllowedBeforeBreaking: exceptionsAllowedBeforeBreaking, + durationOfBreak: durationOfBreak, + onBreak: (ex, breakDelay) => + { + _logger.LogError(".Breaker logging: Breaking the circuit for " + breakDelay.TotalMilliseconds + "ms!", ex); + }, + onReset: () => _logger.LogDebug(".Breaker logging: Call ok! Closed the circuit again."), + onHalfOpen: () => _logger.LogDebug(".Breaker logging: Half-open; next call is a trial.") + ); + _timeoutPolicy = Policy.TimeoutAsync(timeoutValue, timeoutStrategy); + _logger = logger; + } + + protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + Task responseTask = null; + + try + { + responseTask = Policy.WrapAsync(_circuitBreakerPolicy, _timeoutPolicy).ExecuteAsync(() => + { + return base.SendAsync(request,cancellationToken); + }); + return responseTask; + } + catch (BrokenCircuitException ex) + { + _logger.LogError($"Reached to allowed number of exceptions. Circuit is open. AllowedExceptionCount: {_exceptionsAllowedBeforeBreaking}, DurationOfBreak: {_durationOfBreak}",ex); + throw; + } + catch (HttpRequestException) + { + return responseTask; + } + } + + private static bool IsTransientFailure(HttpResponseMessage result) + { + return result.StatusCode >= HttpStatusCode.InternalServerError; + } + } +} diff --git a/src/Ocelot/Requester/HttpClientBuilder.cs b/src/Ocelot/Requester/HttpClientBuilder.cs new file mode 100644 index 00000000..ebf19d24 --- /dev/null +++ b/src/Ocelot/Requester/HttpClientBuilder.cs @@ -0,0 +1,41 @@ +using Ocelot.Logging; +using Ocelot.Values; +using Polly.Timeout; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Ocelot.Requester +{ + internal class HttpClientBuilder + { + private readonly Dictionary> handlers = new Dictionary>(); + + public HttpClientBuilder WithCircuitBreaker(QoS qos, IOcelotLogger logger, HttpMessageHandler innerHandler) + { + handlers.Add(5000, () => new CircuitBreakingDelegatingHandler(qos.ExceptionsAllowedBeforeBreaking, qos.DurationOfBreak, qos.TimeoutValue, qos.TimeoutStrategy, logger, innerHandler)); + return this; + } + + internal HttpClient Build() + { + return handlers.Any() ? new HttpClient(CreateHttpMessageHandler()) : new HttpClient(); + } + + private HttpMessageHandler CreateHttpMessageHandler() + { + HttpMessageHandler httpMessageHandler = new HttpClientHandler(); + + handlers.OrderByDescending(handler => handler.Key).Select(handler => handler.Value).Reverse().ToList().ForEach(handler => + { + var delegatingHandler = handler(); + delegatingHandler.InnerHandler = httpMessageHandler; + httpMessageHandler = delegatingHandler; + }); + + return httpMessageHandler; + } + } +} diff --git a/src/Ocelot/Requester/HttpClientHttpRequester.cs b/src/Ocelot/Requester/HttpClientHttpRequester.cs index 8056adeb..35c405d1 100644 --- a/src/Ocelot/Requester/HttpClientHttpRequester.cs +++ b/src/Ocelot/Requester/HttpClientHttpRequester.cs @@ -4,9 +4,6 @@ using System.Net.Http; using System.Threading.Tasks; using Ocelot.Errors; using Ocelot.Responses; -using Polly; -using Polly.Timeout; -using Polly.CircuitBreaker; using Ocelot.Logging; namespace Ocelot.Requester @@ -14,7 +11,7 @@ namespace Ocelot.Requester public class HttpClientHttpRequester : IHttpRequester { private readonly IOcelotLogger _logger; - + public HttpClientHttpRequester(IOcelotLoggerFactory loggerFactory) { _logger = loggerFactory.CreateLogger(); @@ -22,46 +19,26 @@ namespace Ocelot.Requester public async Task> GetResponse(Request.Request request) { - double timeoutvalue = 5000; - TimeoutStrategy timeoutStrategy = TimeoutStrategy.Pessimistic; - - var timeoutPolicy = Policy - .TimeoutAsync(TimeSpan.FromMilliseconds(timeoutvalue), timeoutStrategy); - - var circuitBreakerPolicy = Policy - .Handle() - .Or() - .Or() - .CircuitBreakerAsync( - exceptionsAllowedBeforeBreaking: 4, - durationOfBreak: TimeSpan.FromSeconds(8), - onBreak: (ex, breakDelay) => - { - _logger.LogError(".Breaker logging: Breaking the circuit for " + breakDelay.TotalMilliseconds + "ms!", ex); - }, - onReset: () => _logger.LogDebug(".Breaker logging: Call ok! Closed the circuit again."), - onHalfOpen: () => _logger.LogDebug(".Breaker logging: Half-open; next call is a trial.") - ); + HttpClientBuilder builder = new HttpClientBuilder(); using (var handler = new HttpClientHandler { CookieContainer = request.CookieContainer }) - using (var httpClient = new HttpClient(handler)) { - try + builder.WithCircuitBreaker(request.Qos, _logger, handler); + using (var httpClient = builder.Build()) { - // Retry the following call according to the policy - 3 times. - HttpResponseMessage response = await Policy.WrapAsync(circuitBreakerPolicy, timeoutPolicy).ExecuteAsync(() => + try { - return httpClient.SendAsync(request.HttpRequestMessage); - }); - return new OkResponse(response); - } - catch (BrokenCircuitException exception) - { - return - new ErrorResponse(new List - { - new UnableToCompleteRequestError(exception) - }); + var response = await httpClient.SendAsync(request.HttpRequestMessage); + return new OkResponse(response); + } + catch (Exception exception) + { + return + new ErrorResponse(new List + { + new UnableToCompleteRequestError(exception) + }); + } } } } diff --git a/src/Ocelot/Requester/IHttpRequester.cs b/src/Ocelot/Requester/IHttpRequester.cs index 201c3add..e3972957 100644 --- a/src/Ocelot/Requester/IHttpRequester.cs +++ b/src/Ocelot/Requester/IHttpRequester.cs @@ -7,5 +7,7 @@ namespace Ocelot.Requester public interface IHttpRequester { Task> GetResponse(Request.Request request); + + } } diff --git a/src/Ocelot/Values/QoS.cs b/src/Ocelot/Values/QoS.cs new file mode 100644 index 00000000..b3e8df6a --- /dev/null +++ b/src/Ocelot/Values/QoS.cs @@ -0,0 +1,27 @@ +using Polly.Timeout; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Ocelot.Values +{ + public class QoS + { + public QoS(int exceptionsAllowedBeforeBreaking, int durationofBreak, int timeoutValue, TimeoutStrategy timeoutStrategy = TimeoutStrategy.Pessimistic) + { + ExceptionsAllowedBeforeBreaking = exceptionsAllowedBeforeBreaking; + DurationOfBreak = TimeSpan.FromMilliseconds(durationofBreak); + TimeoutValue = TimeSpan.FromMilliseconds(timeoutValue); + TimeoutStrategy = timeoutStrategy; + } + + public int ExceptionsAllowedBeforeBreaking { get; private set; } + + public TimeSpan DurationOfBreak { get; private set; } + + public TimeSpan TimeoutValue { get; private set; } + + public TimeoutStrategy TimeoutStrategy { get; private set; } + } +} diff --git a/test/Ocelot.AcceptanceTests/AuthenticationTests.cs b/test/Ocelot.AcceptanceTests/AuthenticationTests.cs index 8b14f4f1..4a23282c 100644 --- a/test/Ocelot.AcceptanceTests/AuthenticationTests.cs +++ b/test/Ocelot.AcceptanceTests/AuthenticationTests.cs @@ -125,6 +125,9 @@ namespace Ocelot.AcceptanceTests DownstreamScheme = _downstreamServiceScheme, UpstreamTemplate = "/", UpstreamHttpMethod = "Get", + ExceptionsAllowedBeforeBreaking = 3, + DurationOfBreak =5, + TimeoutValue = 5000, AuthenticationOptions = new FileAuthenticationOptions { AdditionalScopes = new List(), @@ -165,6 +168,9 @@ namespace Ocelot.AcceptanceTests DownstreamScheme = _downstreamServiceScheme, UpstreamTemplate = "/", UpstreamHttpMethod = "Post", + ExceptionsAllowedBeforeBreaking = 3, + DurationOfBreak =5, + TimeoutValue = 5000, AuthenticationOptions = new FileAuthenticationOptions { AdditionalScopes = new List(), @@ -205,6 +211,9 @@ namespace Ocelot.AcceptanceTests DownstreamScheme = _downstreamServiceScheme, UpstreamTemplate = "/", UpstreamHttpMethod = "Post", + ExceptionsAllowedBeforeBreaking = 3, + DurationOfBreak =5, + TimeoutValue = 5000, AuthenticationOptions = new FileAuthenticationOptions { AdditionalScopes = new List(), diff --git a/test/Ocelot.AcceptanceTests/AuthorisationTests.cs b/test/Ocelot.AcceptanceTests/AuthorisationTests.cs index 1f86c6ff..17f99528 100644 --- a/test/Ocelot.AcceptanceTests/AuthorisationTests.cs +++ b/test/Ocelot.AcceptanceTests/AuthorisationTests.cs @@ -43,6 +43,9 @@ namespace Ocelot.AcceptanceTests DownstreamHost = "localhost", UpstreamTemplate = "/", UpstreamHttpMethod = "Get", + ExceptionsAllowedBeforeBreaking = 3, + DurationOfBreak =5, + TimeoutValue = 5000, AuthenticationOptions = new FileAuthenticationOptions { AdditionalScopes = new List(), diff --git a/test/Ocelot.AcceptanceTests/CachingTests.cs b/test/Ocelot.AcceptanceTests/CachingTests.cs index e4e628af..46f5dc3c 100644 --- a/test/Ocelot.AcceptanceTests/CachingTests.cs +++ b/test/Ocelot.AcceptanceTests/CachingTests.cs @@ -37,6 +37,9 @@ namespace Ocelot.AcceptanceTests DownstreamHost = "localhost", UpstreamTemplate = "/", UpstreamHttpMethod = "Get", + ExceptionsAllowedBeforeBreaking = 3, + DurationOfBreak =5, + TimeoutValue = 5000, FileCacheOptions = new FileCacheOptions { TtlSeconds = 100 @@ -73,6 +76,9 @@ namespace Ocelot.AcceptanceTests DownstreamHost = "localhost", UpstreamTemplate = "/", UpstreamHttpMethod = "Get", + ExceptionsAllowedBeforeBreaking = 3, + DurationOfBreak =5, + TimeoutValue = 5000, FileCacheOptions = new FileCacheOptions { TtlSeconds = 1 diff --git a/test/Ocelot.AcceptanceTests/CaseSensitiveRoutingTests.cs b/test/Ocelot.AcceptanceTests/CaseSensitiveRoutingTests.cs index 81824602..9cb8e72c 100644 --- a/test/Ocelot.AcceptanceTests/CaseSensitiveRoutingTests.cs +++ b/test/Ocelot.AcceptanceTests/CaseSensitiveRoutingTests.cs @@ -35,7 +35,10 @@ namespace Ocelot.AcceptanceTests DownstreamScheme = "http", DownstreamHost = "localhost", UpstreamTemplate = "/products/{productId}", - UpstreamHttpMethod = "Get" + UpstreamHttpMethod = "Get", + ExceptionsAllowedBeforeBreaking = 3, + DurationOfBreak =5, + TimeoutValue = 5000 } } }; @@ -63,7 +66,10 @@ namespace Ocelot.AcceptanceTests DownstreamHost = "localhost", UpstreamTemplate = "/products/{productId}", UpstreamHttpMethod = "Get", - ReRouteIsCaseSensitive = false + ReRouteIsCaseSensitive = false, + ExceptionsAllowedBeforeBreaking = 3, + DurationOfBreak =5, + TimeoutValue = 5000, } } }; @@ -91,7 +97,10 @@ namespace Ocelot.AcceptanceTests DownstreamHost = "localhost", UpstreamTemplate = "/products/{productId}", UpstreamHttpMethod = "Get", - ReRouteIsCaseSensitive = true + ReRouteIsCaseSensitive = true, + ExceptionsAllowedBeforeBreaking = 3, + DurationOfBreak =5, + TimeoutValue = 5000 } } }; @@ -119,7 +128,10 @@ namespace Ocelot.AcceptanceTests DownstreamHost = "localhost", UpstreamTemplate = "/PRODUCTS/{productId}", UpstreamHttpMethod = "Get", - ReRouteIsCaseSensitive = true + ReRouteIsCaseSensitive = true, + ExceptionsAllowedBeforeBreaking = 3, + DurationOfBreak =5, + TimeoutValue = 5000, } } }; @@ -147,7 +159,10 @@ namespace Ocelot.AcceptanceTests DownstreamHost = "localhost", UpstreamTemplate = "/products/{productId}", UpstreamHttpMethod = "Get", - ReRouteIsCaseSensitive = true + ReRouteIsCaseSensitive = true, + ExceptionsAllowedBeforeBreaking = 3, + DurationOfBreak =5, + TimeoutValue = 5000, } } }; @@ -175,7 +190,10 @@ namespace Ocelot.AcceptanceTests DownstreamHost = "localhost", UpstreamTemplate = "/PRODUCTS/{productId}", UpstreamHttpMethod = "Get", - ReRouteIsCaseSensitive = true + ReRouteIsCaseSensitive = true, + ExceptionsAllowedBeforeBreaking = 3, + DurationOfBreak =5, + TimeoutValue = 5000 } } }; diff --git a/test/Ocelot.AcceptanceTests/ClaimsToHeadersForwardingTests.cs b/test/Ocelot.AcceptanceTests/ClaimsToHeadersForwardingTests.cs index 08bbd968..4c036eac 100644 --- a/test/Ocelot.AcceptanceTests/ClaimsToHeadersForwardingTests.cs +++ b/test/Ocelot.AcceptanceTests/ClaimsToHeadersForwardingTests.cs @@ -57,6 +57,9 @@ namespace Ocelot.AcceptanceTests DownstreamHost = "localhost", UpstreamTemplate = "/", UpstreamHttpMethod = "Get", + ExceptionsAllowedBeforeBreaking = 3, + DurationOfBreak =5, + TimeoutValue = 5000, AuthenticationOptions = new FileAuthenticationOptions { AdditionalScopes = new List diff --git a/test/Ocelot.AcceptanceTests/ClaimsToQueryStringForwardingTests.cs b/test/Ocelot.AcceptanceTests/ClaimsToQueryStringForwardingTests.cs index 04dc25db..fe8ff799 100644 --- a/test/Ocelot.AcceptanceTests/ClaimsToQueryStringForwardingTests.cs +++ b/test/Ocelot.AcceptanceTests/ClaimsToQueryStringForwardingTests.cs @@ -57,6 +57,9 @@ namespace Ocelot.AcceptanceTests DownstreamHost = "localhost", UpstreamTemplate = "/", UpstreamHttpMethod = "Get", + ExceptionsAllowedBeforeBreaking = 3, + DurationOfBreak =5, + TimeoutValue = 5000, AuthenticationOptions = new FileAuthenticationOptions { AdditionalScopes = new List diff --git a/test/Ocelot.AcceptanceTests/CustomMiddlewareTests.cs b/test/Ocelot.AcceptanceTests/CustomMiddlewareTests.cs index f6f6de20..1ad929de 100644 --- a/test/Ocelot.AcceptanceTests/CustomMiddlewareTests.cs +++ b/test/Ocelot.AcceptanceTests/CustomMiddlewareTests.cs @@ -51,6 +51,9 @@ namespace Ocelot.AcceptanceTests DownstreamHost = "localhost", UpstreamTemplate = "/", UpstreamHttpMethod = "Get", + ExceptionsAllowedBeforeBreaking = 3, + DurationOfBreak =5, + TimeoutValue = 5000, } } }; @@ -88,6 +91,9 @@ namespace Ocelot.AcceptanceTests DownstreamHost = "localhost", UpstreamTemplate = "/", UpstreamHttpMethod = "Get", + ExceptionsAllowedBeforeBreaking = 3, + DurationOfBreak =5, + TimeoutValue = 5000, } } }; @@ -125,6 +131,9 @@ namespace Ocelot.AcceptanceTests DownstreamHost = "localhost", UpstreamTemplate = "/", UpstreamHttpMethod = "Get", + ExceptionsAllowedBeforeBreaking = 3, + DurationOfBreak =5, + TimeoutValue = 5000, } } }; @@ -162,6 +171,9 @@ namespace Ocelot.AcceptanceTests DownstreamHost = "localhost", UpstreamTemplate = "/", UpstreamHttpMethod = "Get", + ExceptionsAllowedBeforeBreaking = 3, + DurationOfBreak =5, + TimeoutValue = 5000, } } }; @@ -199,6 +211,9 @@ namespace Ocelot.AcceptanceTests DownstreamHost = "localhost", UpstreamTemplate = "/", UpstreamHttpMethod = "Get", + ExceptionsAllowedBeforeBreaking = 3, + DurationOfBreak =5, + TimeoutValue = 5000, } } }; @@ -236,6 +251,9 @@ namespace Ocelot.AcceptanceTests DownstreamHost = "localhost", UpstreamTemplate = "/", UpstreamHttpMethod = "Get", + ExceptionsAllowedBeforeBreaking = 3, + DurationOfBreak =5, + TimeoutValue = 5000, } } }; diff --git a/test/Ocelot.AcceptanceTests/RequestIdTests.cs b/test/Ocelot.AcceptanceTests/RequestIdTests.cs index 9334786b..2273eb2c 100644 --- a/test/Ocelot.AcceptanceTests/RequestIdTests.cs +++ b/test/Ocelot.AcceptanceTests/RequestIdTests.cs @@ -39,7 +39,10 @@ namespace Ocelot.AcceptanceTests DownstreamHost = "localhost", UpstreamTemplate = "/", UpstreamHttpMethod = "Get", - RequestIdKey = _steps.RequestIdKey + RequestIdKey = _steps.RequestIdKey, + ExceptionsAllowedBeforeBreaking = 3, + DurationOfBreak =5, + TimeoutValue = 5000, } } }; @@ -67,7 +70,10 @@ namespace Ocelot.AcceptanceTests DownstreamHost = "localhost", UpstreamTemplate = "/", UpstreamHttpMethod = "Get", - RequestIdKey = _steps.RequestIdKey + RequestIdKey = _steps.RequestIdKey, + ExceptionsAllowedBeforeBreaking = 3, + DurationOfBreak =5, + TimeoutValue = 5000, } } }; @@ -97,6 +103,9 @@ namespace Ocelot.AcceptanceTests DownstreamHost = "localhost", UpstreamTemplate = "/", UpstreamHttpMethod = "Get", + ExceptionsAllowedBeforeBreaking = 3, + DurationOfBreak =5, + TimeoutValue = 5000, } }, GlobalConfiguration = new FileGlobalConfiguration diff --git a/test/Ocelot.AcceptanceTests/RoutingTests.cs b/test/Ocelot.AcceptanceTests/RoutingTests.cs index 4f97114f..acfec46c 100644 --- a/test/Ocelot.AcceptanceTests/RoutingTests.cs +++ b/test/Ocelot.AcceptanceTests/RoutingTests.cs @@ -46,6 +46,9 @@ namespace Ocelot.AcceptanceTests DownstreamPort = 51879, UpstreamTemplate = "/", UpstreamHttpMethod = "Get", + ExceptionsAllowedBeforeBreaking = 3, + DurationOfBreak =5, + TimeoutValue = 5000, } } }; @@ -74,6 +77,9 @@ namespace Ocelot.AcceptanceTests DownstreamPort = 51879, UpstreamTemplate = "/", UpstreamHttpMethod = "Get", + ExceptionsAllowedBeforeBreaking = 3, + DurationOfBreak =5, + TimeoutValue = 5000, } } }; @@ -102,6 +108,9 @@ namespace Ocelot.AcceptanceTests DownstreamPort = 51879, UpstreamTemplate = "/", UpstreamHttpMethod = "Get", + ExceptionsAllowedBeforeBreaking = 3, + DurationOfBreak =5, + TimeoutValue = 5000, } } }; @@ -130,6 +139,9 @@ namespace Ocelot.AcceptanceTests DownstreamPort = 51879, UpstreamTemplate = "/products/", UpstreamHttpMethod = "Get", + ExceptionsAllowedBeforeBreaking = 3, + DurationOfBreak =5, + TimeoutValue = 5000, } } }; @@ -158,6 +170,9 @@ namespace Ocelot.AcceptanceTests DownstreamPort = 51879, UpstreamTemplate = "/products", UpstreamHttpMethod = "Get", + ExceptionsAllowedBeforeBreaking = 3, + DurationOfBreak =5, + TimeoutValue = 5000, } } }; @@ -186,6 +201,9 @@ namespace Ocelot.AcceptanceTests DownstreamPort = 51879, UpstreamTemplate = "/products/{productId}", UpstreamHttpMethod = "Get", + ExceptionsAllowedBeforeBreaking = 3, + DurationOfBreak =5, + TimeoutValue = 5000, } } }; @@ -212,7 +230,10 @@ namespace Ocelot.AcceptanceTests DownstreamHost = "localhost", DownstreamPort = 51879, UpstreamTemplate = "/products/{productId}", - UpstreamHttpMethod = "Get" + UpstreamHttpMethod = "Get", + ExceptionsAllowedBeforeBreaking = 3, + DurationOfBreak =5, + TimeoutValue = 5000, } } }; @@ -240,7 +261,10 @@ namespace Ocelot.AcceptanceTests DownstreamPort = 51879, DownstreamScheme = "http", UpstreamTemplate = "/", - UpstreamHttpMethod = "Post" + UpstreamHttpMethod = "Post", + ExceptionsAllowedBeforeBreaking = 3, + DurationOfBreak =5, + TimeoutValue = 5000, } } }; @@ -269,6 +293,9 @@ namespace Ocelot.AcceptanceTests DownstreamHost = "localhost", DownstreamPort = 51879, UpstreamHttpMethod = "Get", + ExceptionsAllowedBeforeBreaking = 3, + DurationOfBreak =5, + TimeoutValue = 5000, } } }; diff --git a/test/Ocelot.AcceptanceTests/configuration.json b/test/Ocelot.AcceptanceTests/configuration.json index f28abefe..0c347f55 100755 --- a/test/Ocelot.AcceptanceTests/configuration.json +++ b/test/Ocelot.AcceptanceTests/configuration.json @@ -1 +1 @@ -{"ReRoutes":[{"DownstreamPathTemplate":"/","UpstreamTemplate":"/","UpstreamHttpMethod":"Get","AuthenticationOptions":{"Provider":null,"ProviderRootUrl":null,"ScopeName":null,"RequireHttps":false,"AdditionalScopes":[],"ScopeSecret":null},"AddHeadersToRequest":{},"AddClaimsToRequest":{},"RouteClaimsRequirement":{},"AddQueriesToRequest":{},"RequestIdKey":null,"FileCacheOptions":{"TtlSeconds":0},"ReRouteIsCaseSensitive":false,"ServiceName":null,"DownstreamScheme":"http","DownstreamHost":"localhost","DownstreamPort":41879}],"GlobalConfiguration":{"RequestIdKey":null,"ServiceDiscoveryProvider":{"Provider":null,"Address":null}}} \ No newline at end of file +{"ReRoutes":[{"DownstreamPathTemplate":"/","UpstreamTemplate":"/","UpstreamHttpMethod":"Get","AuthenticationOptions":{"Provider":null,"ProviderRootUrl":null,"ScopeName":null,"RequireHttps":false,"AdditionalScopes":[],"ScopeSecret":null},"AddHeadersToRequest":{},"AddClaimsToRequest":{},"RouteClaimsRequirement":{},"AddQueriesToRequest":{},"RequestIdKey":null,"FileCacheOptions":{"TtlSeconds":0},"ReRouteIsCaseSensitive":false,"ServiceName":null,"DownstreamScheme":"http","DownstreamHost":"localhost","DownstreamPort":41879,"ExceptionsAllowedBeforeBreaking":3,"DurationOfBreak":5,"TimeoutValue":5000}],"GlobalConfiguration":{"RequestIdKey":null,"ServiceDiscoveryProvider":{"Provider":null,"Address":null}}} \ No newline at end of file diff --git a/test/Ocelot.ManualTest/configuration.json b/test/Ocelot.ManualTest/configuration.json index f7e2bb75..a887f3fb 100644 --- a/test/Ocelot.ManualTest/configuration.json +++ b/test/Ocelot.ManualTest/configuration.json @@ -1,119 +1,149 @@ { "ReRoutes": [ - { - "DownstreamPathTemplate": "/", - "DownstreamScheme": "http", - "DownstreamHost": "localhost", - "DownstreamPort": 52876, - "UpstreamTemplate": "/identityserverexample", - "UpstreamHttpMethod": "Get", - "AuthenticationOptions": { - "Provider": "IdentityServer", - "ProviderRootUrl": "http://localhost:52888", - "ScopeName": "api", - "AdditionalScopes": [ - "openid", - "offline_access" - ], - "ScopeSecret": "secret" - }, - "AddHeadersToRequest": { - "CustomerId": "Claims[CustomerId] > value", - "LocationId": "Claims[LocationId] > value", - "UserType": "Claims[sub] > value[0] > |", - "UserId": "Claims[sub] > value[1] > |" - }, - "AddClaimsToRequest": { - "CustomerId": "Claims[CustomerId] > value", - "LocationId": "Claims[LocationId] > value", - "UserType": "Claims[sub] > value[0] > |", - "UserId": "Claims[sub] > value[1] > |" - }, - "AddQueriesToRequest": { - "CustomerId": "Claims[CustomerId] > value", - "LocationId": "Claims[LocationId] > value", - "UserType": "Claims[sub] > value[0] > |", - "UserId": "Claims[sub] > value[1] > |" - }, - "RouteClaimsRequirement": { - "UserType": "registered" - }, - "RequestIdKey": "OcRequestId" + { + "DownstreamPathTemplate": "/", + "DownstreamScheme": "http", + "DownstreamHost": "localhost", + "DownstreamPort": 52876, + "UpstreamTemplate": "/identityserverexample", + "UpstreamHttpMethod": "Get", + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000, + "AuthenticationOptions": { + "Provider": "IdentityServer", + "ProviderRootUrl": "http://localhost:52888", + "ScopeName": "api", + "AdditionalScopes": [ + "openid", + "offline_access" + ], + "ScopeSecret": "secret" }, - { - "DownstreamPathTemplate": "/posts", - "DownstreamScheme": "http", - "DownstreamHost": "jsonplaceholder.typicode.com", - "DownstreamPort": 80, - "UpstreamTemplate": "/posts", - "UpstreamHttpMethod": "Get", - "FileCacheOptions": { "TtlSeconds": 15 } + "AddHeadersToRequest": { + "CustomerId": "Claims[CustomerId] > value", + "LocationId": "Claims[LocationId] > value", + "UserType": "Claims[sub] > value[0] > |", + "UserId": "Claims[sub] > value[1] > |" }, - { - "DownstreamPathTemplate": "/posts/{postId}", - "DownstreamScheme": "http", - "DownstreamHost": "jsonplaceholder.typicode.com", - "DownstreamPort": 80, - "UpstreamTemplate": "/posts/{postId}", - "UpstreamHttpMethod": "Get" + "AddClaimsToRequest": { + "CustomerId": "Claims[CustomerId] > value", + "LocationId": "Claims[LocationId] > value", + "UserType": "Claims[sub] > value[0] > |", + "UserId": "Claims[sub] > value[1] > |" }, - { - "DownstreamPathTemplate": "/posts/{postId}/comments", - "DownstreamScheme": "http", - "DownstreamHost": "jsonplaceholder.typicode.com", - "DownstreamPort": 80, - "UpstreamTemplate": "/posts/{postId}/comments", - "UpstreamHttpMethod": "Get" + "AddQueriesToRequest": { + "CustomerId": "Claims[CustomerId] > value", + "LocationId": "Claims[LocationId] > value", + "UserType": "Claims[sub] > value[0] > |", + "UserId": "Claims[sub] > value[1] > |" }, - { - "DownstreamPathTemplate": "/comments", - "DownstreamScheme": "http", - "DownstreamHost": "jsonplaceholder.typicode.com", - "DownstreamPort": 80, - "UpstreamTemplate": "/comments", - "UpstreamHttpMethod": "Get" - }, - { - "DownstreamPathTemplate": "/posts", - "DownstreamScheme": "http", - "DownstreamHost": "jsonplaceholder.typicode.com", - "DownstreamPort": 80, - "UpstreamTemplate": "/posts", - "UpstreamHttpMethod": "Post" - }, - { - "DownstreamPathTemplate": "/posts/{postId}", - "DownstreamScheme": "http", - "DownstreamHost": "jsonplaceholder.typicode.com", - "DownstreamPort": 80, - "UpstreamTemplate": "/posts/{postId}", - "UpstreamHttpMethod": "Put" - }, - { - "DownstreamPathTemplate": "/posts/{postId}", - "DownstreamScheme": "http", - "DownstreamHost": "jsonplaceholder.typicode.com", - "DownstreamPort": 80, - "UpstreamTemplate": "/posts/{postId}", - "UpstreamHttpMethod": "Patch" - }, - { - "DownstreamPathTemplate": "/posts/{postId}", - "DownstreamScheme": "http", - "DownstreamHost": "jsonplaceholder.typicode.com", - "DownstreamPort": 80, - "UpstreamTemplate": "/posts/{postId}", - "UpstreamHttpMethod": "Delete" - }, - { - "DownstreamPathTemplate": "/api/products", - "DownstreamScheme": "http", - "DownstreamHost": "jsonplaceholder.typicode.com", - "DownstreamPort": 80, - "UpstreamTemplate": "/products", - "UpstreamHttpMethod": "Get", - "FileCacheOptions": { "TtlSeconds": 15 } + "RouteClaimsRequirement": { + "UserType": "registered" }, + "RequestIdKey": "OcRequestId" + }, + { + "DownstreamPathTemplate": "/posts", + "DownstreamScheme": "http", + "DownstreamHost": "jsonplaceholder.typicode.com", + "DownstreamPort": 80, + "UpstreamTemplate": "/posts", + "UpstreamHttpMethod": "Get", + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000, + "FileCacheOptions": { "TtlSeconds": 15 } + }, + { + "DownstreamPathTemplate": "/posts/{postId}", + "DownstreamScheme": "http", + "DownstreamHost": "jsonplaceholder.typicode.com", + "DownstreamPort": 80, + "UpstreamTemplate": "/posts/{postId}", + "UpstreamHttpMethod": "Get", + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000 + }, + { + "DownstreamPathTemplate": "/posts/{postId}/comments", + "DownstreamScheme": "http", + "DownstreamHost": "jsonplaceholder.typicode.com", + "DownstreamPort": 80, + "UpstreamTemplate": "/posts/{postId}/comments", + "UpstreamHttpMethod": "Get", + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000 + }, + { + "DownstreamPathTemplate": "/comments", + "DownstreamScheme": "http", + "DownstreamHost": "jsonplaceholder.typicode.com", + "DownstreamPort": 80, + "UpstreamTemplate": "/comments", + "UpstreamHttpMethod": "Get", + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000 + }, + { + "DownstreamPathTemplate": "/posts", + "DownstreamScheme": "http", + "DownstreamHost": "jsonplaceholder.typicode.com", + "DownstreamPort": 80, + "UpstreamTemplate": "/posts", + "UpstreamHttpMethod": "Post", + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000 + }, + { + "DownstreamPathTemplate": "/posts/{postId}", + "DownstreamScheme": "http", + "DownstreamHost": "jsonplaceholder.typicode.com", + "DownstreamPort": 80, + "UpstreamTemplate": "/posts/{postId}", + "UpstreamHttpMethod": "Put", + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000 + }, + { + "DownstreamPathTemplate": "/posts/{postId}", + "DownstreamScheme": "http", + "DownstreamHost": "jsonplaceholder.typicode.com", + "DownstreamPort": 80, + "UpstreamTemplate": "/posts/{postId}", + "UpstreamHttpMethod": "Patch", + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000 + }, + { + "DownstreamPathTemplate": "/posts/{postId}", + "DownstreamScheme": "http", + "DownstreamHost": "jsonplaceholder.typicode.com", + "DownstreamPort": 80, + "UpstreamTemplate": "/posts/{postId}", + "UpstreamHttpMethod": "Delete", + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000 + }, + { + "DownstreamPathTemplate": "/api/products", + "DownstreamScheme": "http", + "DownstreamHost": "jsonplaceholder.typicode.com", + "DownstreamPort": 80, + "UpstreamTemplate": "/products", + "UpstreamHttpMethod": "Get", + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000, + "FileCacheOptions": { "TtlSeconds": 15 } + }, { "DownstreamPathTemplate": "/api/products/{productId}", "DownstreamScheme": "http", @@ -123,87 +153,114 @@ "UpstreamHttpMethod": "Get", "FileCacheOptions": { "TtlSeconds": 15 } }, - { - "DownstreamPathTemplate": "/api/products", - "DownstreamScheme": "http", - "DownstreamHost": "products20161126090340.azurewebsites.net", - "DownstreamPort": 80, - "UpstreamTemplate": "/products", - "UpstreamHttpMethod": "Post", - "FileCacheOptions": { "TtlSeconds": 15 } - }, - { - "DownstreamPathTemplate": "/api/products/{productId}", - "DownstreamScheme": "http", - "DownstreamHost": "products20161126090340.azurewebsites.net", - "DownstreamPort": 80, - "UpstreamTemplate": "/products/{productId}", - "UpstreamHttpMethod": "Put", - "FileCacheOptions": { "TtlSeconds": 15 } - }, - { - "DownstreamPathTemplate": "/api/products/{productId}", - "DownstreamScheme": "http", - "DownstreamHost": "products20161126090340.azurewebsites.net", - "DownstreamPort": 80, - "UpstreamTemplate": "/products/{productId}", - "UpstreamHttpMethod": "Delete", - "FileCacheOptions": { "TtlSeconds": 15 } - }, - { - "DownstreamPathTemplate": "/api/customers", - "DownstreamScheme": "http", - "DownstreamHost": "customers20161126090811.azurewebsites.net", - "DownstreamPort": 80, - "UpstreamTemplate": "/customers", - "UpstreamHttpMethod": "Get", - "FileCacheOptions": { "TtlSeconds": 15 } - }, - { - "DownstreamPathTemplate": "/api/customers/{customerId}", - "DownstreamScheme": "http", - "DownstreamHost": "customers20161126090811.azurewebsites.net", - "DownstreamPort": 80, - "UpstreamTemplate": "/customers/{customerId}", - "UpstreamHttpMethod": "Get", - "FileCacheOptions": { "TtlSeconds": 15 } - }, - { - "DownstreamPathTemplate": "/api/customers", - "DownstreamScheme": "http", - "DownstreamHost": "customers20161126090811.azurewebsites.net", - "DownstreamPort": 80, - "UpstreamTemplate": "/customers", - "UpstreamHttpMethod": "Post", - "FileCacheOptions": { "TtlSeconds": 15 } - }, - { - "DownstreamPathTemplate": "/api/customers/{customerId}", - "DownstreamScheme": "http", - "DownstreamHost": "customers20161126090811.azurewebsites.net", - "DownstreamPort": 80, - "UpstreamTemplate": "/customers/{customerId}", - "UpstreamHttpMethod": "Put", - "FileCacheOptions": { "TtlSeconds": 15 } - }, - { - "DownstreamPathTemplate": "/api/customers/{customerId}", - "DownstreamScheme": "http", - "DownstreamHost": "customers20161126090811.azurewebsites.net", - "DownstreamPort": 80, - "UpstreamTemplate": "/customers/{customerId}", - "UpstreamHttpMethod": "Delete", - "FileCacheOptions": { "TtlSeconds": 15 } - }, - { - "DownstreamPathTemplate": "/posts", - "DownstreamScheme": "http", - "DownstreamHost": "jsonplaceholder.typicode.com", - "DownstreamPort": 80, - "UpstreamTemplate": "/posts/", - "UpstreamHttpMethod": "Get", - "FileCacheOptions": { "TtlSeconds": 15 } - } + { + "DownstreamPathTemplate": "/api/products", + "DownstreamScheme": "http", + "DownstreamHost": "products20161126090340.azurewebsites.net", + "DownstreamPort": 80, + "UpstreamTemplate": "/products", + "UpstreamHttpMethod": "Post", + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000, + "FileCacheOptions": { "TtlSeconds": 15 } + }, + { + "DownstreamPathTemplate": "/api/products/{productId}", + "DownstreamScheme": "http", + "DownstreamHost": "products20161126090340.azurewebsites.net", + "DownstreamPort": 80, + "UpstreamTemplate": "/products/{productId}", + "UpstreamHttpMethod": "Put", + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000, + "FileCacheOptions": { "TtlSeconds": 15 } + }, + { + "DownstreamPathTemplate": "/api/products/{productId}", + "DownstreamScheme": "http", + "DownstreamHost": "products20161126090340.azurewebsites.net", + "DownstreamPort": 80, + "UpstreamTemplate": "/products/{productId}", + "UpstreamHttpMethod": "Delete", + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000, + "FileCacheOptions": { "TtlSeconds": 15 } + }, + { + "DownstreamPathTemplate": "/api/customers", + "DownstreamScheme": "http", + "DownstreamHost": "customers20161126090811.azurewebsites.net", + "DownstreamPort": 80, + "UpstreamTemplate": "/customers", + "UpstreamHttpMethod": "Get", + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000, + "FileCacheOptions": { "TtlSeconds": 15 } + }, + { + "DownstreamPathTemplate": "/api/customers/{customerId}", + "DownstreamScheme": "http", + "DownstreamHost": "customers20161126090811.azurewebsites.net", + "DownstreamPort": 80, + "UpstreamTemplate": "/customers/{customerId}", + "UpstreamHttpMethod": "Get", + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000, + "FileCacheOptions": { "TtlSeconds": 15 } + }, + { + "DownstreamPathTemplate": "/api/customers", + "DownstreamScheme": "http", + "DownstreamHost": "customers20161126090811.azurewebsites.net", + "DownstreamPort": 80, + "UpstreamTemplate": "/customers", + "UpstreamHttpMethod": "Post", + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000, + "FileCacheOptions": { "TtlSeconds": 15 } + }, + { + "DownstreamPathTemplate": "/api/customers/{customerId}", + "DownstreamScheme": "http", + "DownstreamHost": "customers20161126090811.azurewebsites.net", + "DownstreamPort": 80, + "UpstreamTemplate": "/customers/{customerId}", + "UpstreamHttpMethod": "Put", + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000, + "FileCacheOptions": { "TtlSeconds": 15 } + }, + { + "DownstreamPathTemplate": "/api/customers/{customerId}", + "DownstreamScheme": "http", + "DownstreamHost": "customers20161126090811.azurewebsites.net", + "DownstreamPort": 80, + "UpstreamTemplate": "/customers/{customerId}", + "UpstreamHttpMethod": "Delete", + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000, + "FileCacheOptions": { "TtlSeconds": 15 } + }, + { + "DownstreamPathTemplate": "/posts", + "DownstreamScheme": "http", + "DownstreamHost": "jsonplaceholder.typicode.com", + "DownstreamPort": 80, + "UpstreamTemplate": "/posts/", + "UpstreamHttpMethod": "Get", + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000, + "FileCacheOptions": { "TtlSeconds": 15 } + } ], "GlobalConfiguration": { "RequestIdKey": "OcRequestId" diff --git a/test/Ocelot.UnitTests/Request/HttpRequestBuilderMiddlewareTests.cs b/test/Ocelot.UnitTests/Request/HttpRequestBuilderMiddlewareTests.cs index e2f81abe..406e7cb6 100644 --- a/test/Ocelot.UnitTests/Request/HttpRequestBuilderMiddlewareTests.cs +++ b/test/Ocelot.UnitTests/Request/HttpRequestBuilderMiddlewareTests.cs @@ -72,7 +72,7 @@ namespace Ocelot.UnitTests.Request this.Given(x => x.GivenTheDownStreamUrlIs("any old string")) .And(x => x.GivenTheDownStreamRouteIs(downstreamRoute)) - .And(x => x.GivenTheRequestBuilderReturns(new Ocelot.Request.Request(new HttpRequestMessage(), new CookieContainer()))) + .And(x => x.GivenTheRequestBuilderReturns(new Ocelot.Request.Request(new HttpRequestMessage(), new CookieContainer(),new Values.QoS(3, 8 ,5000, Polly.Timeout.TimeoutStrategy.Pessimistic)))) .When(x => x.WhenICallTheMiddleware()) .Then(x => x.ThenTheScopedDataRepositoryIsCalledCorrectly()) .BDDfy(); @@ -91,7 +91,7 @@ namespace Ocelot.UnitTests.Request _request = new OkResponse(request); _requestBuilder .Setup(x => x.Build(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), - It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(),It.IsAny())) .ReturnsAsync(_request); } diff --git a/test/Ocelot.UnitTests/Request/RequestBuilderTests.cs b/test/Ocelot.UnitTests/Request/RequestBuilderTests.cs index 3a07532e..55d18c38 100644 --- a/test/Ocelot.UnitTests/Request/RequestBuilderTests.cs +++ b/test/Ocelot.UnitTests/Request/RequestBuilderTests.cs @@ -25,6 +25,7 @@ namespace Ocelot.UnitTests.Request private readonly IRequestCreator _requestCreator; private Response _result; private Ocelot.RequestId.RequestId _requestId; + private Ocelot.Values.QoS _qos; public RequestBuilderTests() { @@ -37,6 +38,7 @@ namespace Ocelot.UnitTests.Request { this.Given(x => x.GivenIHaveHttpMethod("GET")) .And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk")) + .And(x=> x.GivenTheQos(new Values.QoS(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic))) .When(x => x.WhenICreateARequest()) .And(x => x.ThenTheCorrectDownstreamUrlIsUsed("http://www.bbc.co.uk/")) .BDDfy(); @@ -47,6 +49,8 @@ namespace Ocelot.UnitTests.Request { this.Given(x => x.GivenIHaveHttpMethod("POST")) .And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk")) + .And(x => x.GivenTheQos(new Values.QoS(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic))) + .When(x => x.WhenICreateARequest()) .And(x => x.ThenTheCorrectHttpMethodIsUsed(HttpMethod.Post)) .BDDfy(); @@ -59,7 +63,9 @@ namespace Ocelot.UnitTests.Request .And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk")) .And(x => x.GivenIHaveTheHttpContent(new StringContent("Hi from Tom"))) .And(x => x.GivenTheContentTypeIs("application/json")) - .When(x => x.WhenICreateARequest()) + .And(x => x.GivenTheQos(new Values.QoS(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic))) + + .When(x => x.WhenICreateARequest()) .And(x => x.ThenTheCorrectContentIsUsed(new StringContent("Hi from Tom"))) .BDDfy(); } @@ -71,6 +77,8 @@ namespace Ocelot.UnitTests.Request .And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk")) .And(x => x.GivenIHaveTheHttpContent(new StringContent("Hi from Tom"))) .And(x => x.GivenTheContentTypeIs("application/json")) + .And(x => x.GivenTheQos(new Values.QoS(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic))) + .When(x => x.WhenICreateARequest()) .And(x => x.ThenTheCorrectContentHeadersAreUsed(new HeaderDictionary { @@ -88,6 +96,8 @@ namespace Ocelot.UnitTests.Request .And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk")) .And(x => x.GivenIHaveTheHttpContent(new StringContent("Hi from Tom"))) .And(x => x.GivenTheContentTypeIs("application/json; charset=utf-8")) + .And(x => x.GivenTheQos(new Values.QoS(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic))) + .When(x => x.WhenICreateARequest()) .And(x => x.ThenTheCorrectContentHeadersAreUsed(new HeaderDictionary { @@ -107,6 +117,8 @@ namespace Ocelot.UnitTests.Request { {"ChopSticks", "Bubbles" } })) + .And(x => x.GivenTheQos(new Values.QoS(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic))) + .When(x => x.WhenICreateARequest()) .And(x => x.ThenTheCorrectHeadersAreUsed(new HeaderDictionary { @@ -124,7 +136,8 @@ namespace Ocelot.UnitTests.Request .And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk")) .And(x => x.GivenTheHttpHeadersAre(new HeaderDictionary())) .And(x => x.GivenTheRequestIdIs(new Ocelot.RequestId.RequestId("RequestId", requestId))) - .When(x => x.WhenICreateARequest()) + .And(x => x.GivenTheQos(new Values.QoS(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic))) + .When(x => x.WhenICreateARequest()) .And(x => x.ThenTheCorrectHeadersAreUsed(new HeaderDictionary { {"RequestId", requestId } @@ -142,7 +155,8 @@ namespace Ocelot.UnitTests.Request {"RequestId", "534534gv54gv45g" } })) .And(x => x.GivenTheRequestIdIs(new Ocelot.RequestId.RequestId("RequestId", Guid.NewGuid().ToString()))) - .When(x => x.WhenICreateARequest()) + .And(x => x.GivenTheQos(new Values.QoS(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic))) + .When(x => x.WhenICreateARequest()) .And(x => x.ThenTheCorrectHeadersAreUsed(new HeaderDictionary { {"RequestId", "534534gv54gv45g" } @@ -161,7 +175,8 @@ namespace Ocelot.UnitTests.Request .And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk")) .And(x => x.GivenTheHttpHeadersAre(new HeaderDictionary())) .And(x => x.GivenTheRequestIdIs(new Ocelot.RequestId.RequestId(requestIdKey, requestIdValue))) - .When(x => x.WhenICreateARequest()) + .And(x => x.GivenTheQos(new Values.QoS(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic))) + .When(x => x.WhenICreateARequest()) .And(x => x.ThenTheRequestIdIsNotInTheHeaders()) .BDDfy(); } @@ -171,6 +186,11 @@ namespace Ocelot.UnitTests.Request _requestId = requestId; } + private void GivenTheQos(Ocelot.Values.QoS qos) + { + _qos = qos; + } + [Fact] public void should_use_cookies() { @@ -281,7 +301,7 @@ namespace Ocelot.UnitTests.Request private void WhenICreateARequest() { _result = _requestCreator.Build(_httpMethod, _downstreamUrl, _content?.ReadAsStreamAsync().Result, _headers, - _cookies, _query, _contentType, _requestId).Result; + _cookies, _query, _contentType, _requestId, _qos).Result; } diff --git a/test/Ocelot.UnitTests/Requester/HttpRequesterMiddlewareTests.cs b/test/Ocelot.UnitTests/Requester/HttpRequesterMiddlewareTests.cs index d99a99eb..66c7491e 100644 --- a/test/Ocelot.UnitTests/Requester/HttpRequesterMiddlewareTests.cs +++ b/test/Ocelot.UnitTests/Requester/HttpRequesterMiddlewareTests.cs @@ -61,7 +61,7 @@ namespace Ocelot.UnitTests.Requester [Fact] public void should_call_scoped_data_repository_correctly() { - this.Given(x => x.GivenTheRequestIs(new Ocelot.Request.Request(new HttpRequestMessage(),new CookieContainer()))) + this.Given(x => x.GivenTheRequestIs(new Ocelot.Request.Request(new HttpRequestMessage(),new CookieContainer(), new Values.QoS(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic)))) .And(x => x.GivenTheRequesterReturns(new HttpResponseMessage())) .And(x => x.GivenTheScopedRepoReturns()) .When(x => x.WhenICallTheMiddleware()) From b10c95219e06e1a2cc12db33e0742c84263a1cf2 Mon Sep 17 00:00:00 2001 From: geffzhang Date: Tue, 7 Feb 2017 19:47:11 +0800 Subject: [PATCH 3/7] merge circuitbreakerpattern code --- global.json | 2 +- .../Configuration/Builder/ReRouteBuilder.cs | 3 +- .../Creator/FileOcelotConfigurationCreator.cs | 29 ++++----- src/Ocelot/Configuration/ReRoute.cs | 2 +- src/Ocelot/project.json | 62 +++++++++---------- .../Ocelot.AcceptanceTests/configuration.json | 2 +- 6 files changed, 49 insertions(+), 51 deletions(-) diff --git a/global.json b/global.json index ff8d898e..616b2c4e 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@  { "projects": [ "src", "test" ], "sdk": { - "version": "1.0.0-preview2-003133" + "version": "1.0.0-preview2-003131" } } diff --git a/src/Ocelot/Configuration/Builder/ReRouteBuilder.cs b/src/Ocelot/Configuration/Builder/ReRouteBuilder.cs index 7fed4047..9420c3f8 100644 --- a/src/Ocelot/Configuration/Builder/ReRouteBuilder.cs +++ b/src/Ocelot/Configuration/Builder/ReRouteBuilder.cs @@ -248,7 +248,8 @@ namespace Ocelot.Configuration.Builder _isAuthenticated, new AuthenticationOptions(_authenticationProvider, _authenticationProviderUrl, _scopeName, _requireHttps, _additionalScopes, _scopeSecret), _configHeaderExtractorProperties, _claimToClaims, _routeClaimRequirement, _isAuthorised, _claimToQueries, _requestIdHeaderKey, _isCached, _fileCacheOptions, _downstreamScheme, _loadBalancer, - _downstreamHost, _dsPort, _loadBalancerKey, new ServiceProviderConfiguraion(_serviceName, _downstreamHost, _dsPort, _useServiceDiscovery, _serviceDiscoveryProvider, _serviceProviderHost, _serviceProviderPort), + _downstreamHost, _dsPort, _loadBalancerKey, new ServiceProviderConfiguraion(_serviceName, _downstreamHost, _dsPort, _useServiceDiscovery, + _serviceDiscoveryProvider, _serviceProviderHost, _serviceProviderPort), _exceptionsAllowedBeforeBreaking,_durationOfBreak, _timeoutValue); } diff --git a/src/Ocelot/Configuration/Creator/FileOcelotConfigurationCreator.cs b/src/Ocelot/Configuration/Creator/FileOcelotConfigurationCreator.cs index f5e5090f..3ff3966c 100644 --- a/src/Ocelot/Configuration/Creator/FileOcelotConfigurationCreator.cs +++ b/src/Ocelot/Configuration/Creator/FileOcelotConfigurationCreator.cs @@ -103,9 +103,6 @@ namespace Ocelot.Configuration.Creator var useServiceDiscovery = !string.IsNullOrEmpty(fileReRoute.ServiceName) && !string.IsNullOrEmpty(globalConfiguration?.ServiceDiscoveryProvider?.Provider); - - Func downstreamHostAndPortFunc = () => new HostAndPort(reRoute.DownstreamHost.Trim('/'), reRoute.DownstreamPort); - //note - not sure if this is the correct key, but this is probably the only unique key i can think of given my poor brain var loadBalancerKey = $"{fileReRoute.UpstreamTemplate}{fileReRoute.UpstreamHttpMethod}"; @@ -130,16 +127,16 @@ namespace Ocelot.Configuration.Creator var claimsToClaims = GetAddThingsToRequest(fileReRoute.AddClaimsToRequest); var claimsToQueries = GetAddThingsToRequest(fileReRoute.AddQueriesToRequest); - reRoute = new ReRoute(new DownstreamPathTemplate(fileReRoute.DownstreamPathTemplate), - fileReRoute.UpstreamTemplate, - fileReRoute.UpstreamHttpMethod, upstreamTemplate, isAuthenticated, - authOptionsForRoute, claimsToHeaders, claimsToClaims, - fileReRoute.RouteClaimsRequirement, isAuthorised, claimsToQueries, - requestIdKey, isCached, new CacheOptions(fileReRoute.FileCacheOptions.TtlSeconds) - , fileReRoute.DownstreamScheme, - fileReRoute.LoadBalancer, fileReRoute.DownstreamHost, fileReRoute.DownstreamPort, loadBalancerKey, - serviceProviderConfiguration, serviceProviderConfiguration ,reRoute.ExceptionsAllowedBeforeBreaking, - reRoute.DurationOfBreak, reRoute.TimeoutValue); + reRoute = new ReRoute(new DownstreamPathTemplate(fileReRoute.DownstreamPathTemplate), + fileReRoute.UpstreamTemplate, + fileReRoute.UpstreamHttpMethod, upstreamTemplate, isAuthenticated, + authOptionsForRoute, claimsToHeaders, claimsToClaims, + fileReRoute.RouteClaimsRequirement, isAuthorised, claimsToQueries, + requestIdKey, isCached, new CacheOptions(fileReRoute.FileCacheOptions.TtlSeconds) + , fileReRoute.DownstreamScheme, + fileReRoute.LoadBalancer, fileReRoute.DownstreamHost, fileReRoute.DownstreamPort, loadBalancerKey, + serviceProviderConfiguration, fileReRoute.ExceptionsAllowedBeforeBreaking, + fileReRoute.DurationOfBreak, fileReRoute.TimeoutValue); } else { @@ -151,10 +148,10 @@ namespace Ocelot.Configuration.Creator requestIdKey, isCached, new CacheOptions(fileReRoute.FileCacheOptions.TtlSeconds), fileReRoute.DownstreamScheme, fileReRoute.LoadBalancer, fileReRoute.DownstreamHost, fileReRoute.DownstreamPort, loadBalancerKey, - serviceProviderConfiguration, serviceProviderConfiguration ,reRoute.ExceptionsAllowedBeforeBreaking, - reRoute.DurationOfBreak, reRoute.TimeoutValue); + serviceProviderConfiguration, fileReRoute.ExceptionsAllowedBeforeBreaking, + fileReRoute.DurationOfBreak, fileReRoute.TimeoutValue); } - + var loadBalancer = await _loadBalanceFactory.Get(reRoute); _loadBalancerHouse.Add(reRoute.LoadBalancerKey, loadBalancer); return reRoute; diff --git a/src/Ocelot/Configuration/ReRoute.cs b/src/Ocelot/Configuration/ReRoute.cs index 26a2d06e..7065361b 100644 --- a/src/Ocelot/Configuration/ReRoute.cs +++ b/src/Ocelot/Configuration/ReRoute.cs @@ -16,7 +16,7 @@ namespace Ocelot.Configuration List claimsToQueries, string requestIdKey, bool isCached, CacheOptions fileCacheOptions, string downstreamScheme, string loadBalancer, string downstreamHost, - int downstreamPort, string loadBalancerKey, ServiceProviderConfiguraion serviceProviderConfiguraion, + int downstreamPort, string loadBalancerKey, ServiceProviderConfiguraion serviceProviderConfiguraion, int exceptionsAllowedBeforeBreaking =3, int durationofBreak =8, int timeoutValue = 5000) { LoadBalancerKey = loadBalancerKey; diff --git a/src/Ocelot/project.json b/src/Ocelot/project.json index 6ba9441d..4e098803 100644 --- a/src/Ocelot/project.json +++ b/src/Ocelot/project.json @@ -1,38 +1,38 @@ { "version": "0.0.0-dev", - "dependencies": { - "Microsoft.AspNetCore.Server.IISIntegration": "1.1.0", - "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.1.0", - "Microsoft.Extensions.Configuration.FileExtensions": "1.1.0", - "Microsoft.Extensions.Configuration.Json": "1.1.0", - "Microsoft.Extensions.Logging": "1.1.0", - "Microsoft.Extensions.Logging.Console": "1.1.0", - "Microsoft.Extensions.Logging.Debug": "1.1.0", - "Microsoft.Extensions.Options.ConfigurationExtensions": "1.1.0", - "Microsoft.AspNetCore.Http": "1.1.0", - "System.Text.RegularExpressions": "4.3.0", - "Microsoft.AspNetCore.Authentication.OAuth": "1.1.0", - "Microsoft.AspNetCore.Authentication.JwtBearer": "1.1.0", - "Microsoft.AspNetCore.Authentication.OpenIdConnect": "1.1.0", - "Microsoft.AspNetCore.Authentication.Cookies": "1.1.0", - "Microsoft.AspNetCore.Authentication.Google": "1.1.0", - "Microsoft.AspNetCore.Authentication.Facebook": "1.1.0", - "Microsoft.AspNetCore.Authentication.Twitter": "1.1.0", - "Microsoft.AspNetCore.Authentication.MicrosoftAccount": "1.1.0", - "Microsoft.AspNetCore.Authentication": "1.1.0", - "IdentityServer4.AccessTokenValidation": "1.0.2", - "Microsoft.AspNetCore.Mvc": "1.1.0", - "Microsoft.AspNetCore.Server.Kestrel": "1.1.0", - "Microsoft.NETCore.App": "1.1.0", - "CacheManager.Core": "0.9.2", - "CacheManager.Microsoft.Extensions.Configuration": "0.9.2", - "CacheManager.Microsoft.Extensions.Logging": "0.9.2", - "Consul": "0.7.2.1", - "Polly": "5.0.3" - }, + "dependencies": { + "Microsoft.AspNetCore.Server.IISIntegration": "1.1.0", + "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.1.0", + "Microsoft.Extensions.Configuration.FileExtensions": "1.1.0", + "Microsoft.Extensions.Configuration.Json": "1.1.0", + "Microsoft.Extensions.Logging": "1.1.0", + "Microsoft.Extensions.Logging.Console": "1.1.0", + "Microsoft.Extensions.Logging.Debug": "1.1.0", + "Microsoft.Extensions.Options.ConfigurationExtensions": "1.1.0", + "Microsoft.AspNetCore.Http": "1.1.0", + "System.Text.RegularExpressions": "4.3.0", + "Microsoft.AspNetCore.Authentication.OAuth": "1.1.0", + "Microsoft.AspNetCore.Authentication.JwtBearer": "1.1.0", + "Microsoft.AspNetCore.Authentication.OpenIdConnect": "1.1.0", + "Microsoft.AspNetCore.Authentication.Cookies": "1.1.0", + "Microsoft.AspNetCore.Authentication.Google": "1.1.0", + "Microsoft.AspNetCore.Authentication.Facebook": "1.1.0", + "Microsoft.AspNetCore.Authentication.Twitter": "1.1.0", + "Microsoft.AspNetCore.Authentication.MicrosoftAccount": "1.1.0", + "Microsoft.AspNetCore.Authentication": "1.1.0", + "IdentityServer4.AccessTokenValidation": "1.0.2", + "Microsoft.AspNetCore.Mvc": "1.1.0", + "Microsoft.AspNetCore.Server.Kestrel": "1.1.0", + "Microsoft.NETCore.App": "1.1.0", + "CacheManager.Core": "0.9.2", + "CacheManager.Microsoft.Extensions.Configuration": "0.9.2", + "CacheManager.Microsoft.Extensions.Logging": "0.9.2", + "Consul": "0.7.2.1", + "Polly": "5.0.3" + }, "runtimes": { "win10-x64": {}, - "osx.10.11-x64":{}, + "osx.10.11-x64": {}, "win7-x64": {} }, "frameworks": { diff --git a/test/Ocelot.AcceptanceTests/configuration.json b/test/Ocelot.AcceptanceTests/configuration.json index 1244fbb8..67d0c796 100755 --- a/test/Ocelot.AcceptanceTests/configuration.json +++ b/test/Ocelot.AcceptanceTests/configuration.json @@ -1 +1 @@ -{"ReRoutes":[{"DownstreamPathTemplate":"41879/","UpstreamTemplate":"/","UpstreamHttpMethod":"Get","AuthenticationOptions":{"Provider":null,"ProviderRootUrl":null,"ScopeName":null,"RequireHttps":false,"AdditionalScopes":[],"ScopeSecret":null},"AddHeadersToRequest":{},"AddClaimsToRequest":{},"RouteClaimsRequirement":{},"AddQueriesToRequest":{},"RequestIdKey":null,"FileCacheOptions":{"TtlSeconds":0},"ReRouteIsCaseSensitive":false,"ServiceName":null,"DownstreamScheme":"http","DownstreamHost":"localhost","DownstreamPort":41879,"LoadBalancer":null, ,"ExceptionsAllowedBeforeBreaking":3,"DurationOfBreak":5,"TimeoutValue":5000}],"GlobalConfiguration":{"RequestIdKey":null,"ServiceDiscoveryProvider":{"Provider":null,"Host":null,"Port":0}}} \ No newline at end of file +{"ReRoutes":[{"DownstreamPathTemplate":"41879/","UpstreamTemplate":"/","UpstreamHttpMethod":"Get","AuthenticationOptions":{"Provider":null,"ProviderRootUrl":null,"ScopeName":null,"RequireHttps":false,"AdditionalScopes":[],"ScopeSecret":null},"AddHeadersToRequest":{},"AddClaimsToRequest":{},"RouteClaimsRequirement":{},"AddQueriesToRequest":{},"RequestIdKey":null,"FileCacheOptions":{"TtlSeconds":0},"ReRouteIsCaseSensitive":false,"ServiceName":null,"DownstreamScheme":"http","DownstreamHost":"localhost","DownstreamPort":41879,"ExceptionsAllowedBeforeBreaking":3,"DurationOfBreak":5,"TimeoutValue":5000,"LoadBalancer":null}],"GlobalConfiguration":{"RequestIdKey":null,"ServiceDiscoveryProvider":{"Provider":null,"Host":null,"Port":0}}} \ No newline at end of file From 616ca4f7305a2759076cd6390e7930bd8a3111b2 Mon Sep 17 00:00:00 2001 From: geffzhang Date: Tue, 7 Feb 2017 19:50:09 +0800 Subject: [PATCH 4/7] update sdk version --- global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global.json b/global.json index 616b2c4e..ff8d898e 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@  { "projects": [ "src", "test" ], "sdk": { - "version": "1.0.0-preview2-003131" + "version": "1.0.0-preview2-003133" } } From c839c17c6237ce70edb45e3ee7e9e9f5f33eaf65 Mon Sep 17 00:00:00 2001 From: TomPallister Date: Tue, 7 Feb 2017 20:04:08 +0000 Subject: [PATCH 5/7] test commit --- test/Ocelot.AcceptanceTests/configuration.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Ocelot.AcceptanceTests/configuration.json b/test/Ocelot.AcceptanceTests/configuration.json index 78ab541b..d7db55c7 100755 --- a/test/Ocelot.AcceptanceTests/configuration.json +++ b/test/Ocelot.AcceptanceTests/configuration.json @@ -1 +1 @@ -{"ReRoutes":[{"DownstreamPathTemplate":"41879/","UpstreamTemplate":"/","UpstreamHttpMethod":"Get","AuthenticationOptions":{"Provider":null,"ProviderRootUrl":null,"ScopeName":null,"RequireHttps":false,"AdditionalScopes":[],"ScopeSecret":null},"AddHeadersToRequest":{},"AddClaimsToRequest":{},"RouteClaimsRequirement":{},"AddQueriesToRequest":{},"RequestIdKey":null,"FileCacheOptions":{"TtlSeconds":0},"ReRouteIsCaseSensitive":false,"ServiceName":null,"DownstreamScheme":"http","DownstreamHost":"localhost","DownstreamPort":41879,"LoadBalancer":null}],"GlobalConfiguration":{"RequestIdKey":null,"ServiceDiscoveryProvider":{"Provider":null,"Host":null,"Port":0}}} +{"ReRoutes":[{"DownstreamPathTemplate":"41879/","UpstreamTemplate":"/","UpstreamHttpMethod":"Get","AuthenticationOptions":{"Provider":null,"ProviderRootUrl":null,"ScopeName":null,"RequireHttps":false,"AdditionalScopes":[],"ScopeSecret":null},"AddHeadersToRequest":{},"AddClaimsToRequest":{},"RouteClaimsRequirement":{},"AddQueriesToRequest":{},"RequestIdKey":null,"FileCacheOptions":{"TtlSeconds":0},"ReRouteIsCaseSensitive":false,"ServiceName":null,"DownstreamScheme":"http","DownstreamHost":"localhost","DownstreamPort":41879,"LoadBalancer":null}],"GlobalConfiguration":{"RequestIdKey":null,"ServiceDiscoveryProvider":{"Provider":null,"Host":null,"Port":0}}} \ No newline at end of file From caae826d7721e26660aaf3fac09840fa43fbd433 Mon Sep 17 00:00:00 2001 From: geffzhang Date: Wed, 8 Feb 2017 09:25:32 +0800 Subject: [PATCH 6/7] Refactor qos as options --- .../Configuration/Builder/ReRouteBuilder.cs | 22 +- .../Creator/FileOcelotConfigurationCreator.cs | 10 +- .../Configuration/File/FileQoSOptions.cs | 16 + src/Ocelot/Configuration/File/FileReRoute.cs | 5 +- .../QoS.cs => Configuration/QoSOptions.cs} | 8 +- src/Ocelot/Configuration/ReRoute.cs | 12 +- .../Request/Builder/HttpRequestCreator.cs | 5 +- src/Ocelot/Request/Builder/IRequestCreator.cs | 6 +- src/Ocelot/Request/Builder/RequestBuilder.cs | 14 +- .../HttpRequestBuilderMiddleware.cs | 2 +- src/Ocelot/Request/Request.cs | 9 +- src/Ocelot/Requester/HttpClientBuilder.cs | 9 +- .../Requester/HttpClientHttpRequester.cs | 7 +- .../AuthenticationTests.cs | 12 +- .../AuthorisationTests.cs | 3 - test/Ocelot.AcceptanceTests/CachingTests.cs | 6 - .../CaseSensitiveRoutingTests.cs | 18 - .../ClaimsToHeadersForwardingTests.cs | 3 - .../ClaimsToQueryStringForwardingTests.cs | 3 - .../CustomMiddlewareTests.cs | 20 +- test/Ocelot.AcceptanceTests/RequestIdTests.cs | 16 +- test/Ocelot.AcceptanceTests/RoutingTests.cs | 35 +- .../Ocelot.AcceptanceTests/configuration.json | 2 +- test/Ocelot.ManualTest/configuration.json | 551 ++++++++++-------- .../LoadBalancerMiddlewareTests.cs | 1 - .../HttpRequestBuilderMiddlewareTests.cs | 5 +- .../Request/RequestBuilderTests.cs | 27 +- .../Requester/HttpRequesterMiddlewareTests.cs | 2 +- .../ConfigurationServiceProviderTests.cs | 1 - 29 files changed, 408 insertions(+), 422 deletions(-) create mode 100644 src/Ocelot/Configuration/File/FileQoSOptions.cs rename src/Ocelot/{Values/QoS.cs => Configuration/QoSOptions.cs} (74%) diff --git a/src/Ocelot/Configuration/Builder/ReRouteBuilder.cs b/src/Ocelot/Configuration/Builder/ReRouteBuilder.cs index 9420c3f8..568e7c68 100644 --- a/src/Ocelot/Configuration/Builder/ReRouteBuilder.cs +++ b/src/Ocelot/Configuration/Builder/ReRouteBuilder.cs @@ -33,12 +33,11 @@ namespace Ocelot.Configuration.Builder private string _downstreamScheme; private string _downstreamHost; private int _dsPort; - private int _exceptionsAllowedBeforeBreaking; - private int _durationOfBreak; - private int _timeoutValue; private string _loadBalancer; private string _serviceProviderHost; private int _serviceProviderPort; + private bool _useQos; + private QoSOptions _qosOptions; public ReRouteBuilder() @@ -206,23 +205,18 @@ namespace Ocelot.Configuration.Builder return this; } - public ReRouteBuilder WithExceptionsAllowedBeforeBreaking(int exceptionsAllowedBeforeBreaking) + public ReRouteBuilder WithIsQos(bool input) { - _exceptionsAllowedBeforeBreaking = exceptionsAllowedBeforeBreaking; + _useQos = input; return this; } - public ReRouteBuilder WithDurationOfBreak(int durationOfBreak) + public ReRouteBuilder WithQosOptions(QoSOptions input) { - _durationOfBreak = durationOfBreak; - return this; - } - - public ReRouteBuilder WithTimeoutValue(int timeoutValue) - { - _timeoutValue = timeoutValue; + _qosOptions = input; return this; } + public ReRouteBuilder WithLoadBalancerKey(string loadBalancerKey) { @@ -250,7 +244,7 @@ namespace Ocelot.Configuration.Builder _isAuthorised, _claimToQueries, _requestIdHeaderKey, _isCached, _fileCacheOptions, _downstreamScheme, _loadBalancer, _downstreamHost, _dsPort, _loadBalancerKey, new ServiceProviderConfiguraion(_serviceName, _downstreamHost, _dsPort, _useServiceDiscovery, _serviceDiscoveryProvider, _serviceProviderHost, _serviceProviderPort), - _exceptionsAllowedBeforeBreaking,_durationOfBreak, _timeoutValue); + _useQos,_qosOptions); } } diff --git a/src/Ocelot/Configuration/Creator/FileOcelotConfigurationCreator.cs b/src/Ocelot/Configuration/Creator/FileOcelotConfigurationCreator.cs index 3ff3966c..f550edac 100644 --- a/src/Ocelot/Configuration/Creator/FileOcelotConfigurationCreator.cs +++ b/src/Ocelot/Configuration/Creator/FileOcelotConfigurationCreator.cs @@ -96,6 +96,8 @@ namespace Ocelot.Configuration.Creator var isCached = fileReRoute.FileCacheOptions.TtlSeconds > 0; + var isQos = fileReRoute.QoSOptions.ExceptionsAllowedBeforeBreaking > 0 && fileReRoute.QoSOptions.TimeoutValue >0; + var requestIdKey = globalRequestIdConfiguration ? globalConfiguration.RequestIdKey : fileReRoute.RequestIdKey; @@ -135,8 +137,8 @@ namespace Ocelot.Configuration.Creator requestIdKey, isCached, new CacheOptions(fileReRoute.FileCacheOptions.TtlSeconds) , fileReRoute.DownstreamScheme, fileReRoute.LoadBalancer, fileReRoute.DownstreamHost, fileReRoute.DownstreamPort, loadBalancerKey, - serviceProviderConfiguration, fileReRoute.ExceptionsAllowedBeforeBreaking, - fileReRoute.DurationOfBreak, fileReRoute.TimeoutValue); + serviceProviderConfiguration, isQos, + new QoSOptions(fileReRoute.QoSOptions.ExceptionsAllowedBeforeBreaking, fileReRoute.QoSOptions.DurationOfBreak, fileReRoute.QoSOptions.TimeoutValue)); } else { @@ -148,8 +150,8 @@ namespace Ocelot.Configuration.Creator requestIdKey, isCached, new CacheOptions(fileReRoute.FileCacheOptions.TtlSeconds), fileReRoute.DownstreamScheme, fileReRoute.LoadBalancer, fileReRoute.DownstreamHost, fileReRoute.DownstreamPort, loadBalancerKey, - serviceProviderConfiguration, fileReRoute.ExceptionsAllowedBeforeBreaking, - fileReRoute.DurationOfBreak, fileReRoute.TimeoutValue); + serviceProviderConfiguration, isQos, + new QoSOptions(fileReRoute.QoSOptions.ExceptionsAllowedBeforeBreaking, fileReRoute.QoSOptions.DurationOfBreak, fileReRoute.QoSOptions.TimeoutValue)); } var loadBalancer = await _loadBalanceFactory.Get(reRoute); diff --git a/src/Ocelot/Configuration/File/FileQoSOptions.cs b/src/Ocelot/Configuration/File/FileQoSOptions.cs new file mode 100644 index 00000000..dfac3ac6 --- /dev/null +++ b/src/Ocelot/Configuration/File/FileQoSOptions.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Ocelot.Configuration.File +{ + public class FileQoSOptions + { + public int ExceptionsAllowedBeforeBreaking { get; set; } + + public int DurationOfBreak { get; set; } + + public int TimeoutValue { get; set; } + } +} diff --git a/src/Ocelot/Configuration/File/FileReRoute.cs b/src/Ocelot/Configuration/File/FileReRoute.cs index d16f0fab..9ab898ea 100644 --- a/src/Ocelot/Configuration/File/FileReRoute.cs +++ b/src/Ocelot/Configuration/File/FileReRoute.cs @@ -12,6 +12,7 @@ namespace Ocelot.Configuration.File AddQueriesToRequest = new Dictionary(); AuthenticationOptions = new FileAuthenticationOptions(); FileCacheOptions = new FileCacheOptions(); + QoSOptions = new FileQoSOptions(); } public string DownstreamPathTemplate { get; set; } @@ -29,9 +30,7 @@ namespace Ocelot.Configuration.File public string DownstreamScheme {get;set;} public string DownstreamHost {get;set;} public int DownstreamPort { get; set; } - public int ExceptionsAllowedBeforeBreaking { get; set; } - public int DurationOfBreak { get; set; } - public int TimeoutValue { get; set; } + public FileQoSOptions QoSOptions { get; set; } public string LoadBalancer {get;set;} } } \ No newline at end of file diff --git a/src/Ocelot/Values/QoS.cs b/src/Ocelot/Configuration/QoSOptions.cs similarity index 74% rename from src/Ocelot/Values/QoS.cs rename to src/Ocelot/Configuration/QoSOptions.cs index b3e8df6a..8584c57e 100644 --- a/src/Ocelot/Values/QoS.cs +++ b/src/Ocelot/Configuration/QoSOptions.cs @@ -4,17 +4,18 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -namespace Ocelot.Values +namespace Ocelot.Configuration { - public class QoS + public class QoSOptions { - public QoS(int exceptionsAllowedBeforeBreaking, int durationofBreak, int timeoutValue, TimeoutStrategy timeoutStrategy = TimeoutStrategy.Pessimistic) + public QoSOptions(int exceptionsAllowedBeforeBreaking, int durationofBreak, int timeoutValue, TimeoutStrategy timeoutStrategy = TimeoutStrategy.Pessimistic) { ExceptionsAllowedBeforeBreaking = exceptionsAllowedBeforeBreaking; DurationOfBreak = TimeSpan.FromMilliseconds(durationofBreak); TimeoutValue = TimeSpan.FromMilliseconds(timeoutValue); TimeoutStrategy = timeoutStrategy; } + public int ExceptionsAllowedBeforeBreaking { get; private set; } @@ -23,5 +24,6 @@ namespace Ocelot.Values public TimeSpan TimeoutValue { get; private set; } public TimeoutStrategy TimeoutStrategy { get; private set; } + } } diff --git a/src/Ocelot/Configuration/ReRoute.cs b/src/Ocelot/Configuration/ReRoute.cs index 7065361b..c38d55d5 100644 --- a/src/Ocelot/Configuration/ReRoute.cs +++ b/src/Ocelot/Configuration/ReRoute.cs @@ -17,7 +17,7 @@ namespace Ocelot.Configuration string requestIdKey, bool isCached, CacheOptions fileCacheOptions, string downstreamScheme, string loadBalancer, string downstreamHost, int downstreamPort, string loadBalancerKey, ServiceProviderConfiguraion serviceProviderConfiguraion, - int exceptionsAllowedBeforeBreaking =3, int durationofBreak =8, int timeoutValue = 5000) + bool isQos,QoSOptions qos) { LoadBalancerKey = loadBalancerKey; ServiceProviderConfiguraion = serviceProviderConfiguraion; @@ -42,9 +42,8 @@ namespace Ocelot.Configuration ClaimsToHeaders = configurationHeaderExtractorProperties ?? new List(); DownstreamScheme = downstreamScheme; - ExceptionsAllowedBeforeBreaking = exceptionsAllowedBeforeBreaking; - DurationOfBreak = durationofBreak; - TimeoutValue = timeoutValue; + IsQos = isQos; + QosOptions = qos; } public string LoadBalancerKey {get;private set;} @@ -63,9 +62,8 @@ namespace Ocelot.Configuration public bool IsCached { get; private set; } public CacheOptions FileCacheOptions { get; private set; } public string DownstreamScheme {get;private set;} - public int ExceptionsAllowedBeforeBreaking { get; private set; } - public int DurationOfBreak { get; private set; } - public int TimeoutValue { get; private set; } + public bool IsQos { get; private set; } + public QoSOptions QosOptions { get; private set; } public string LoadBalancer {get;private set;} public string DownstreamHost { get; private set; } public int DownstreamPort { get; private set; } diff --git a/src/Ocelot/Request/Builder/HttpRequestCreator.cs b/src/Ocelot/Request/Builder/HttpRequestCreator.cs index 27ba4c07..f326933c 100644 --- a/src/Ocelot/Request/Builder/HttpRequestCreator.cs +++ b/src/Ocelot/Request/Builder/HttpRequestCreator.cs @@ -2,6 +2,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Ocelot.Responses; +using Ocelot.Configuration; namespace Ocelot.Request.Builder { @@ -16,7 +17,8 @@ namespace Ocelot.Request.Builder QueryString queryString, string contentType, RequestId.RequestId requestId, - Values.QoS qos) + bool isQos, + QoSOptions qos) { var request = await new RequestBuilder() .WithHttpMethod(httpMethod) @@ -27,6 +29,7 @@ namespace Ocelot.Request.Builder .WithHeaders(headers) .WithRequestId(requestId) .WithCookies(cookies) + .WithIsQos(isQos) .WithQos(qos) .Build(); diff --git a/src/Ocelot/Request/Builder/IRequestCreator.cs b/src/Ocelot/Request/Builder/IRequestCreator.cs index 858636b5..3417d933 100644 --- a/src/Ocelot/Request/Builder/IRequestCreator.cs +++ b/src/Ocelot/Request/Builder/IRequestCreator.cs @@ -2,6 +2,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Ocelot.Responses; +using Ocelot.Configuration; namespace Ocelot.Request.Builder { @@ -13,8 +14,9 @@ namespace Ocelot.Request.Builder IHeaderDictionary headers, IRequestCookieCollection cookies, QueryString queryString, - string contentType, + string contentType, RequestId.RequestId requestId, - Values.QoS qos); + bool isQos, + QoSOptions qos); } } diff --git a/src/Ocelot/Request/Builder/RequestBuilder.cs b/src/Ocelot/Request/Builder/RequestBuilder.cs index d7f35ef7..e0201bc8 100644 --- a/src/Ocelot/Request/Builder/RequestBuilder.cs +++ b/src/Ocelot/Request/Builder/RequestBuilder.cs @@ -8,6 +8,7 @@ using System.Net.Http.Headers; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Primitives; +using Ocelot.Configuration; namespace Ocelot.Request.Builder { @@ -22,7 +23,8 @@ namespace Ocelot.Request.Builder private RequestId.RequestId _requestId; private IRequestCookieCollection _cookies; private readonly string[] _unsupportedHeaders = {"host"}; - private Values.QoS _qos; + private bool _isQos; + private QoSOptions _qos; public RequestBuilder WithHttpMethod(string httpMethod) { @@ -72,7 +74,13 @@ namespace Ocelot.Request.Builder return this; } - public RequestBuilder WithQos(Values.QoS qos) + public RequestBuilder WithIsQos(bool isqos) + { + _isQos = isqos; + return this; + } + + public RequestBuilder WithQos(QoSOptions qos) { _qos = qos; return this; @@ -97,7 +105,7 @@ namespace Ocelot.Request.Builder var cookieContainer = CreateCookieContainer(uri); - return new Request(httpRequestMessage, cookieContainer, _qos); + return new Request(httpRequestMessage, cookieContainer,_isQos,_qos); } private Uri CreateUri() diff --git a/src/Ocelot/Request/Middleware/HttpRequestBuilderMiddleware.cs b/src/Ocelot/Request/Middleware/HttpRequestBuilderMiddleware.cs index a875ea8c..aafa2f3d 100644 --- a/src/Ocelot/Request/Middleware/HttpRequestBuilderMiddleware.cs +++ b/src/Ocelot/Request/Middleware/HttpRequestBuilderMiddleware.cs @@ -33,7 +33,7 @@ namespace Ocelot.Request.Middleware .Build(context.Request.Method, DownstreamUrl, context.Request.Body, context.Request.Headers, context.Request.Cookies, context.Request.QueryString, context.Request.ContentType, new RequestId.RequestId(DownstreamRoute?.ReRoute?.RequestIdKey, context.TraceIdentifier), - new Values.QoS(DownstreamRoute.ReRoute.ExceptionsAllowedBeforeBreaking, DownstreamRoute.ReRoute.DurationOfBreak, DownstreamRoute.ReRoute.TimeoutValue)); + DownstreamRoute.ReRoute.IsQos,DownstreamRoute.ReRoute.QosOptions); if (buildResult.IsError) { diff --git a/src/Ocelot/Request/Request.cs b/src/Ocelot/Request/Request.cs index 60e23b1e..a1e62834 100644 --- a/src/Ocelot/Request/Request.cs +++ b/src/Ocelot/Request/Request.cs @@ -1,4 +1,5 @@ -using Ocelot.Values; +using Ocelot.Configuration; +using Ocelot.Values; using System.Net; using System.Net.Http; @@ -6,15 +7,17 @@ namespace Ocelot.Request { public class Request { - public Request(HttpRequestMessage httpRequestMessage, CookieContainer cookieContainer, QoS qos) + public Request(HttpRequestMessage httpRequestMessage, CookieContainer cookieContainer,bool isQos, QoSOptions qos) { HttpRequestMessage = httpRequestMessage; CookieContainer = cookieContainer; + IsQos = isQos; Qos = qos; } public HttpRequestMessage HttpRequestMessage { get; private set; } public CookieContainer CookieContainer { get; private set; } - public QoS Qos { get; private set; } + public bool IsQos { get; private set; } + public QoSOptions Qos { get; private set; } } } diff --git a/src/Ocelot/Requester/HttpClientBuilder.cs b/src/Ocelot/Requester/HttpClientBuilder.cs index ebf19d24..c3c98ac0 100644 --- a/src/Ocelot/Requester/HttpClientBuilder.cs +++ b/src/Ocelot/Requester/HttpClientBuilder.cs @@ -1,4 +1,5 @@ -using Ocelot.Logging; +using Ocelot.Configuration; +using Ocelot.Logging; using Ocelot.Values; using Polly.Timeout; using System; @@ -13,15 +14,15 @@ namespace Ocelot.Requester { private readonly Dictionary> handlers = new Dictionary>(); - public HttpClientBuilder WithCircuitBreaker(QoS qos, IOcelotLogger logger, HttpMessageHandler innerHandler) + public HttpClientBuilder WithCircuitBreaker(QoSOptions qos, IOcelotLogger logger, HttpMessageHandler innerHandler) { handlers.Add(5000, () => new CircuitBreakingDelegatingHandler(qos.ExceptionsAllowedBeforeBreaking, qos.DurationOfBreak, qos.TimeoutValue, qos.TimeoutStrategy, logger, innerHandler)); return this; } - internal HttpClient Build() + internal HttpClient Build(HttpMessageHandler innerHandler) { - return handlers.Any() ? new HttpClient(CreateHttpMessageHandler()) : new HttpClient(); + return handlers.Any() ? new HttpClient(CreateHttpMessageHandler()) : new HttpClient(innerHandler); } private HttpMessageHandler CreateHttpMessageHandler() diff --git a/src/Ocelot/Requester/HttpClientHttpRequester.cs b/src/Ocelot/Requester/HttpClientHttpRequester.cs index 35c405d1..77ab90cc 100644 --- a/src/Ocelot/Requester/HttpClientHttpRequester.cs +++ b/src/Ocelot/Requester/HttpClientHttpRequester.cs @@ -23,8 +23,11 @@ namespace Ocelot.Requester using (var handler = new HttpClientHandler { CookieContainer = request.CookieContainer }) { - builder.WithCircuitBreaker(request.Qos, _logger, handler); - using (var httpClient = builder.Build()) + if (request.IsQos) + { + builder.WithCircuitBreaker(request.Qos, _logger, handler); + } + using (var httpClient = builder.Build(handler)) { try { diff --git a/test/Ocelot.AcceptanceTests/AuthenticationTests.cs b/test/Ocelot.AcceptanceTests/AuthenticationTests.cs index 4a23282c..98458f9b 100644 --- a/test/Ocelot.AcceptanceTests/AuthenticationTests.cs +++ b/test/Ocelot.AcceptanceTests/AuthenticationTests.cs @@ -125,9 +125,6 @@ namespace Ocelot.AcceptanceTests DownstreamScheme = _downstreamServiceScheme, UpstreamTemplate = "/", UpstreamHttpMethod = "Get", - ExceptionsAllowedBeforeBreaking = 3, - DurationOfBreak =5, - TimeoutValue = 5000, AuthenticationOptions = new FileAuthenticationOptions { AdditionalScopes = new List(), @@ -168,9 +165,7 @@ namespace Ocelot.AcceptanceTests DownstreamScheme = _downstreamServiceScheme, UpstreamTemplate = "/", UpstreamHttpMethod = "Post", - ExceptionsAllowedBeforeBreaking = 3, - DurationOfBreak =5, - TimeoutValue = 5000, + AuthenticationOptions = new FileAuthenticationOptions { AdditionalScopes = new List(), @@ -211,10 +206,7 @@ namespace Ocelot.AcceptanceTests DownstreamScheme = _downstreamServiceScheme, UpstreamTemplate = "/", UpstreamHttpMethod = "Post", - ExceptionsAllowedBeforeBreaking = 3, - DurationOfBreak =5, - TimeoutValue = 5000, - AuthenticationOptions = new FileAuthenticationOptions + AuthenticationOptions = new FileAuthenticationOptions { AdditionalScopes = new List(), Provider = "IdentityServer", diff --git a/test/Ocelot.AcceptanceTests/AuthorisationTests.cs b/test/Ocelot.AcceptanceTests/AuthorisationTests.cs index 17f99528..1f86c6ff 100644 --- a/test/Ocelot.AcceptanceTests/AuthorisationTests.cs +++ b/test/Ocelot.AcceptanceTests/AuthorisationTests.cs @@ -43,9 +43,6 @@ namespace Ocelot.AcceptanceTests DownstreamHost = "localhost", UpstreamTemplate = "/", UpstreamHttpMethod = "Get", - ExceptionsAllowedBeforeBreaking = 3, - DurationOfBreak =5, - TimeoutValue = 5000, AuthenticationOptions = new FileAuthenticationOptions { AdditionalScopes = new List(), diff --git a/test/Ocelot.AcceptanceTests/CachingTests.cs b/test/Ocelot.AcceptanceTests/CachingTests.cs index 46f5dc3c..e4e628af 100644 --- a/test/Ocelot.AcceptanceTests/CachingTests.cs +++ b/test/Ocelot.AcceptanceTests/CachingTests.cs @@ -37,9 +37,6 @@ namespace Ocelot.AcceptanceTests DownstreamHost = "localhost", UpstreamTemplate = "/", UpstreamHttpMethod = "Get", - ExceptionsAllowedBeforeBreaking = 3, - DurationOfBreak =5, - TimeoutValue = 5000, FileCacheOptions = new FileCacheOptions { TtlSeconds = 100 @@ -76,9 +73,6 @@ namespace Ocelot.AcceptanceTests DownstreamHost = "localhost", UpstreamTemplate = "/", UpstreamHttpMethod = "Get", - ExceptionsAllowedBeforeBreaking = 3, - DurationOfBreak =5, - TimeoutValue = 5000, FileCacheOptions = new FileCacheOptions { TtlSeconds = 1 diff --git a/test/Ocelot.AcceptanceTests/CaseSensitiveRoutingTests.cs b/test/Ocelot.AcceptanceTests/CaseSensitiveRoutingTests.cs index 9cb8e72c..ae545add 100644 --- a/test/Ocelot.AcceptanceTests/CaseSensitiveRoutingTests.cs +++ b/test/Ocelot.AcceptanceTests/CaseSensitiveRoutingTests.cs @@ -36,9 +36,6 @@ namespace Ocelot.AcceptanceTests DownstreamHost = "localhost", UpstreamTemplate = "/products/{productId}", UpstreamHttpMethod = "Get", - ExceptionsAllowedBeforeBreaking = 3, - DurationOfBreak =5, - TimeoutValue = 5000 } } }; @@ -67,9 +64,6 @@ namespace Ocelot.AcceptanceTests UpstreamTemplate = "/products/{productId}", UpstreamHttpMethod = "Get", ReRouteIsCaseSensitive = false, - ExceptionsAllowedBeforeBreaking = 3, - DurationOfBreak =5, - TimeoutValue = 5000, } } }; @@ -98,9 +92,6 @@ namespace Ocelot.AcceptanceTests UpstreamTemplate = "/products/{productId}", UpstreamHttpMethod = "Get", ReRouteIsCaseSensitive = true, - ExceptionsAllowedBeforeBreaking = 3, - DurationOfBreak =5, - TimeoutValue = 5000 } } }; @@ -129,9 +120,6 @@ namespace Ocelot.AcceptanceTests UpstreamTemplate = "/PRODUCTS/{productId}", UpstreamHttpMethod = "Get", ReRouteIsCaseSensitive = true, - ExceptionsAllowedBeforeBreaking = 3, - DurationOfBreak =5, - TimeoutValue = 5000, } } }; @@ -160,9 +148,6 @@ namespace Ocelot.AcceptanceTests UpstreamTemplate = "/products/{productId}", UpstreamHttpMethod = "Get", ReRouteIsCaseSensitive = true, - ExceptionsAllowedBeforeBreaking = 3, - DurationOfBreak =5, - TimeoutValue = 5000, } } }; @@ -191,9 +176,6 @@ namespace Ocelot.AcceptanceTests UpstreamTemplate = "/PRODUCTS/{productId}", UpstreamHttpMethod = "Get", ReRouteIsCaseSensitive = true, - ExceptionsAllowedBeforeBreaking = 3, - DurationOfBreak =5, - TimeoutValue = 5000 } } }; diff --git a/test/Ocelot.AcceptanceTests/ClaimsToHeadersForwardingTests.cs b/test/Ocelot.AcceptanceTests/ClaimsToHeadersForwardingTests.cs index 4c036eac..08bbd968 100644 --- a/test/Ocelot.AcceptanceTests/ClaimsToHeadersForwardingTests.cs +++ b/test/Ocelot.AcceptanceTests/ClaimsToHeadersForwardingTests.cs @@ -57,9 +57,6 @@ namespace Ocelot.AcceptanceTests DownstreamHost = "localhost", UpstreamTemplate = "/", UpstreamHttpMethod = "Get", - ExceptionsAllowedBeforeBreaking = 3, - DurationOfBreak =5, - TimeoutValue = 5000, AuthenticationOptions = new FileAuthenticationOptions { AdditionalScopes = new List diff --git a/test/Ocelot.AcceptanceTests/ClaimsToQueryStringForwardingTests.cs b/test/Ocelot.AcceptanceTests/ClaimsToQueryStringForwardingTests.cs index fe8ff799..04dc25db 100644 --- a/test/Ocelot.AcceptanceTests/ClaimsToQueryStringForwardingTests.cs +++ b/test/Ocelot.AcceptanceTests/ClaimsToQueryStringForwardingTests.cs @@ -57,9 +57,6 @@ namespace Ocelot.AcceptanceTests DownstreamHost = "localhost", UpstreamTemplate = "/", UpstreamHttpMethod = "Get", - ExceptionsAllowedBeforeBreaking = 3, - DurationOfBreak =5, - TimeoutValue = 5000, AuthenticationOptions = new FileAuthenticationOptions { AdditionalScopes = new List diff --git a/test/Ocelot.AcceptanceTests/CustomMiddlewareTests.cs b/test/Ocelot.AcceptanceTests/CustomMiddlewareTests.cs index 1ad929de..cee75cef 100644 --- a/test/Ocelot.AcceptanceTests/CustomMiddlewareTests.cs +++ b/test/Ocelot.AcceptanceTests/CustomMiddlewareTests.cs @@ -51,9 +51,6 @@ namespace Ocelot.AcceptanceTests DownstreamHost = "localhost", UpstreamTemplate = "/", UpstreamHttpMethod = "Get", - ExceptionsAllowedBeforeBreaking = 3, - DurationOfBreak =5, - TimeoutValue = 5000, } } }; @@ -91,9 +88,7 @@ namespace Ocelot.AcceptanceTests DownstreamHost = "localhost", UpstreamTemplate = "/", UpstreamHttpMethod = "Get", - ExceptionsAllowedBeforeBreaking = 3, - DurationOfBreak =5, - TimeoutValue = 5000, + } } }; @@ -131,9 +126,7 @@ namespace Ocelot.AcceptanceTests DownstreamHost = "localhost", UpstreamTemplate = "/", UpstreamHttpMethod = "Get", - ExceptionsAllowedBeforeBreaking = 3, - DurationOfBreak =5, - TimeoutValue = 5000, + } } }; @@ -171,9 +164,6 @@ namespace Ocelot.AcceptanceTests DownstreamHost = "localhost", UpstreamTemplate = "/", UpstreamHttpMethod = "Get", - ExceptionsAllowedBeforeBreaking = 3, - DurationOfBreak =5, - TimeoutValue = 5000, } } }; @@ -211,9 +201,6 @@ namespace Ocelot.AcceptanceTests DownstreamHost = "localhost", UpstreamTemplate = "/", UpstreamHttpMethod = "Get", - ExceptionsAllowedBeforeBreaking = 3, - DurationOfBreak =5, - TimeoutValue = 5000, } } }; @@ -251,9 +238,6 @@ namespace Ocelot.AcceptanceTests DownstreamHost = "localhost", UpstreamTemplate = "/", UpstreamHttpMethod = "Get", - ExceptionsAllowedBeforeBreaking = 3, - DurationOfBreak =5, - TimeoutValue = 5000, } } }; diff --git a/test/Ocelot.AcceptanceTests/RequestIdTests.cs b/test/Ocelot.AcceptanceTests/RequestIdTests.cs index 2273eb2c..63a40ead 100644 --- a/test/Ocelot.AcceptanceTests/RequestIdTests.cs +++ b/test/Ocelot.AcceptanceTests/RequestIdTests.cs @@ -40,10 +40,7 @@ namespace Ocelot.AcceptanceTests UpstreamTemplate = "/", UpstreamHttpMethod = "Get", RequestIdKey = _steps.RequestIdKey, - ExceptionsAllowedBeforeBreaking = 3, - DurationOfBreak =5, - TimeoutValue = 5000, - } + } } }; @@ -70,10 +67,7 @@ namespace Ocelot.AcceptanceTests DownstreamHost = "localhost", UpstreamTemplate = "/", UpstreamHttpMethod = "Get", - RequestIdKey = _steps.RequestIdKey, - ExceptionsAllowedBeforeBreaking = 3, - DurationOfBreak =5, - TimeoutValue = 5000, + } } }; @@ -101,11 +95,7 @@ namespace Ocelot.AcceptanceTests DownstreamPort = 51879, DownstreamScheme = "http", DownstreamHost = "localhost", - UpstreamTemplate = "/", - UpstreamHttpMethod = "Get", - ExceptionsAllowedBeforeBreaking = 3, - DurationOfBreak =5, - TimeoutValue = 5000, + UpstreamTemplate = "/", } }, GlobalConfiguration = new FileGlobalConfiguration diff --git a/test/Ocelot.AcceptanceTests/RoutingTests.cs b/test/Ocelot.AcceptanceTests/RoutingTests.cs index acfec46c..479c69ff 100644 --- a/test/Ocelot.AcceptanceTests/RoutingTests.cs +++ b/test/Ocelot.AcceptanceTests/RoutingTests.cs @@ -46,9 +46,7 @@ namespace Ocelot.AcceptanceTests DownstreamPort = 51879, UpstreamTemplate = "/", UpstreamHttpMethod = "Get", - ExceptionsAllowedBeforeBreaking = 3, - DurationOfBreak =5, - TimeoutValue = 5000, + } } }; @@ -77,9 +75,7 @@ namespace Ocelot.AcceptanceTests DownstreamPort = 51879, UpstreamTemplate = "/", UpstreamHttpMethod = "Get", - ExceptionsAllowedBeforeBreaking = 3, - DurationOfBreak =5, - TimeoutValue = 5000, + } } }; @@ -108,9 +104,7 @@ namespace Ocelot.AcceptanceTests DownstreamPort = 51879, UpstreamTemplate = "/", UpstreamHttpMethod = "Get", - ExceptionsAllowedBeforeBreaking = 3, - DurationOfBreak =5, - TimeoutValue = 5000, + } } }; @@ -139,9 +133,7 @@ namespace Ocelot.AcceptanceTests DownstreamPort = 51879, UpstreamTemplate = "/products/", UpstreamHttpMethod = "Get", - ExceptionsAllowedBeforeBreaking = 3, - DurationOfBreak =5, - TimeoutValue = 5000, + } } }; @@ -170,9 +162,7 @@ namespace Ocelot.AcceptanceTests DownstreamPort = 51879, UpstreamTemplate = "/products", UpstreamHttpMethod = "Get", - ExceptionsAllowedBeforeBreaking = 3, - DurationOfBreak =5, - TimeoutValue = 5000, + } } }; @@ -201,9 +191,11 @@ namespace Ocelot.AcceptanceTests DownstreamPort = 51879, UpstreamTemplate = "/products/{productId}", UpstreamHttpMethod = "Get", + QoSOptions = new FileQoSOptions() + { ExceptionsAllowedBeforeBreaking = 3, DurationOfBreak =5, - TimeoutValue = 5000, + TimeoutValue = 5000 } } } }; @@ -231,9 +223,6 @@ namespace Ocelot.AcceptanceTests DownstreamPort = 51879, UpstreamTemplate = "/products/{productId}", UpstreamHttpMethod = "Get", - ExceptionsAllowedBeforeBreaking = 3, - DurationOfBreak =5, - TimeoutValue = 5000, } } }; @@ -261,10 +250,7 @@ namespace Ocelot.AcceptanceTests DownstreamPort = 51879, DownstreamScheme = "http", UpstreamTemplate = "/", - UpstreamHttpMethod = "Post", - ExceptionsAllowedBeforeBreaking = 3, - DurationOfBreak =5, - TimeoutValue = 5000, + UpstreamHttpMethod = "Post", } } }; @@ -293,9 +279,6 @@ namespace Ocelot.AcceptanceTests DownstreamHost = "localhost", DownstreamPort = 51879, UpstreamHttpMethod = "Get", - ExceptionsAllowedBeforeBreaking = 3, - DurationOfBreak =5, - TimeoutValue = 5000, } } }; diff --git a/test/Ocelot.AcceptanceTests/configuration.json b/test/Ocelot.AcceptanceTests/configuration.json index 67d0c796..b155bee6 100755 --- a/test/Ocelot.AcceptanceTests/configuration.json +++ b/test/Ocelot.AcceptanceTests/configuration.json @@ -1 +1 @@ -{"ReRoutes":[{"DownstreamPathTemplate":"41879/","UpstreamTemplate":"/","UpstreamHttpMethod":"Get","AuthenticationOptions":{"Provider":null,"ProviderRootUrl":null,"ScopeName":null,"RequireHttps":false,"AdditionalScopes":[],"ScopeSecret":null},"AddHeadersToRequest":{},"AddClaimsToRequest":{},"RouteClaimsRequirement":{},"AddQueriesToRequest":{},"RequestIdKey":null,"FileCacheOptions":{"TtlSeconds":0},"ReRouteIsCaseSensitive":false,"ServiceName":null,"DownstreamScheme":"http","DownstreamHost":"localhost","DownstreamPort":41879,"ExceptionsAllowedBeforeBreaking":3,"DurationOfBreak":5,"TimeoutValue":5000,"LoadBalancer":null}],"GlobalConfiguration":{"RequestIdKey":null,"ServiceDiscoveryProvider":{"Provider":null,"Host":null,"Port":0}}} \ No newline at end of file +{"ReRoutes":[{"DownstreamPathTemplate":"41879/","UpstreamTemplate":"/","UpstreamHttpMethod":"Get","AuthenticationOptions":{"Provider":null,"ProviderRootUrl":null,"ScopeName":null,"RequireHttps":false,"AdditionalScopes":[],"ScopeSecret":null},"AddHeadersToRequest":{},"AddClaimsToRequest":{},"RouteClaimsRequirement":{},"AddQueriesToRequest":{},"RequestIdKey":null,"FileCacheOptions":{"TtlSeconds":0},"ReRouteIsCaseSensitive":false,"ServiceName":null,"DownstreamScheme":"http","DownstreamHost":"localhost","DownstreamPort":41879,"QoSOptions":{"ExceptionsAllowedBeforeBreaking":0,"DurationOfBreak":0,"TimeoutValue":0},"LoadBalancer":null}],"GlobalConfiguration":{"RequestIdKey":null,"ServiceDiscoveryProvider":{"Provider":null,"Host":null,"Port":0}}} \ No newline at end of file diff --git a/test/Ocelot.ManualTest/configuration.json b/test/Ocelot.ManualTest/configuration.json index a887f3fb..9b5fcb7e 100644 --- a/test/Ocelot.ManualTest/configuration.json +++ b/test/Ocelot.ManualTest/configuration.json @@ -1,268 +1,305 @@ { - "ReRoutes": [ - { - "DownstreamPathTemplate": "/", - "DownstreamScheme": "http", - "DownstreamHost": "localhost", - "DownstreamPort": 52876, - "UpstreamTemplate": "/identityserverexample", - "UpstreamHttpMethod": "Get", - "ExceptionsAllowedBeforeBreaking": 3, - "DurationOfBreak": 10, - "TimeoutValue": 5000, - "AuthenticationOptions": { - "Provider": "IdentityServer", - "ProviderRootUrl": "http://localhost:52888", - "ScopeName": "api", - "AdditionalScopes": [ - "openid", - "offline_access" - ], - "ScopeSecret": "secret" - }, - "AddHeadersToRequest": { - "CustomerId": "Claims[CustomerId] > value", - "LocationId": "Claims[LocationId] > value", - "UserType": "Claims[sub] > value[0] > |", - "UserId": "Claims[sub] > value[1] > |" - }, - "AddClaimsToRequest": { - "CustomerId": "Claims[CustomerId] > value", - "LocationId": "Claims[LocationId] > value", - "UserType": "Claims[sub] > value[0] > |", - "UserId": "Claims[sub] > value[1] > |" - }, - "AddQueriesToRequest": { - "CustomerId": "Claims[CustomerId] > value", - "LocationId": "Claims[LocationId] > value", - "UserType": "Claims[sub] > value[0] > |", - "UserId": "Claims[sub] > value[1] > |" - }, - "RouteClaimsRequirement": { - "UserType": "registered" - }, - "RequestIdKey": "OcRequestId" - }, - { - "DownstreamPathTemplate": "/posts", - "DownstreamScheme": "http", - "DownstreamHost": "jsonplaceholder.typicode.com", - "DownstreamPort": 80, - "UpstreamTemplate": "/posts", - "UpstreamHttpMethod": "Get", - "ExceptionsAllowedBeforeBreaking": 3, - "DurationOfBreak": 10, - "TimeoutValue": 5000, - "FileCacheOptions": { "TtlSeconds": 15 } - }, - { - "DownstreamPathTemplate": "/posts/{postId}", - "DownstreamScheme": "http", - "DownstreamHost": "jsonplaceholder.typicode.com", - "DownstreamPort": 80, - "UpstreamTemplate": "/posts/{postId}", - "UpstreamHttpMethod": "Get", + "ReRoutes": [ + { + "DownstreamPathTemplate": "/", + "DownstreamScheme": "http", + "DownstreamHost": "localhost", + "DownstreamPort": 52876, + "UpstreamTemplate": "/identityserverexample", + "UpstreamHttpMethod": "Get", + "QoSOptions": { "ExceptionsAllowedBeforeBreaking": 3, "DurationOfBreak": 10, "TimeoutValue": 5000 }, - { - "DownstreamPathTemplate": "/posts/{postId}/comments", - "DownstreamScheme": "http", - "DownstreamHost": "jsonplaceholder.typicode.com", - "DownstreamPort": 80, - "UpstreamTemplate": "/posts/{postId}/comments", - "UpstreamHttpMethod": "Get", + "AuthenticationOptions": { + "Provider": "IdentityServer", + "ProviderRootUrl": "http://localhost:52888", + "ScopeName": "api", + "AdditionalScopes": [ + "openid", + "offline_access" + ], + "ScopeSecret": "secret" + }, + "AddHeadersToRequest": { + "CustomerId": "Claims[CustomerId] > value", + "LocationId": "Claims[LocationId] > value", + "UserType": "Claims[sub] > value[0] > |", + "UserId": "Claims[sub] > value[1] > |" + }, + "AddClaimsToRequest": { + "CustomerId": "Claims[CustomerId] > value", + "LocationId": "Claims[LocationId] > value", + "UserType": "Claims[sub] > value[0] > |", + "UserId": "Claims[sub] > value[1] > |" + }, + "AddQueriesToRequest": { + "CustomerId": "Claims[CustomerId] > value", + "LocationId": "Claims[LocationId] > value", + "UserType": "Claims[sub] > value[0] > |", + "UserId": "Claims[sub] > value[1] > |" + }, + "RouteClaimsRequirement": { + "UserType": "registered" + }, + "RequestIdKey": "OcRequestId" + }, + { + "DownstreamPathTemplate": "/posts", + "DownstreamScheme": "http", + "DownstreamHost": "jsonplaceholder.typicode.com", + "DownstreamPort": 80, + "UpstreamTemplate": "/posts", + "UpstreamHttpMethod": "Get", + "QoSOptions": { "ExceptionsAllowedBeforeBreaking": 3, "DurationOfBreak": 10, "TimeoutValue": 5000 - }, - { - "DownstreamPathTemplate": "/comments", - "DownstreamScheme": "http", - "DownstreamHost": "jsonplaceholder.typicode.com", - "DownstreamPort": 80, - "UpstreamTemplate": "/comments", - "UpstreamHttpMethod": "Get", - "ExceptionsAllowedBeforeBreaking": 3, - "DurationOfBreak": 10, - "TimeoutValue": 5000 - }, - { - "DownstreamPathTemplate": "/posts", - "DownstreamScheme": "http", - "DownstreamHost": "jsonplaceholder.typicode.com", - "DownstreamPort": 80, - "UpstreamTemplate": "/posts", - "UpstreamHttpMethod": "Post", - "ExceptionsAllowedBeforeBreaking": 3, - "DurationOfBreak": 10, - "TimeoutValue": 5000 - }, - { - "DownstreamPathTemplate": "/posts/{postId}", - "DownstreamScheme": "http", - "DownstreamHost": "jsonplaceholder.typicode.com", - "DownstreamPort": 80, - "UpstreamTemplate": "/posts/{postId}", - "UpstreamHttpMethod": "Put", - "ExceptionsAllowedBeforeBreaking": 3, - "DurationOfBreak": 10, - "TimeoutValue": 5000 - }, - { - "DownstreamPathTemplate": "/posts/{postId}", - "DownstreamScheme": "http", - "DownstreamHost": "jsonplaceholder.typicode.com", - "DownstreamPort": 80, - "UpstreamTemplate": "/posts/{postId}", - "UpstreamHttpMethod": "Patch", - "ExceptionsAllowedBeforeBreaking": 3, - "DurationOfBreak": 10, - "TimeoutValue": 5000 - }, - { - "DownstreamPathTemplate": "/posts/{postId}", - "DownstreamScheme": "http", - "DownstreamHost": "jsonplaceholder.typicode.com", - "DownstreamPort": 80, - "UpstreamTemplate": "/posts/{postId}", - "UpstreamHttpMethod": "Delete", - "ExceptionsAllowedBeforeBreaking": 3, - "DurationOfBreak": 10, - "TimeoutValue": 5000 - }, - { - "DownstreamPathTemplate": "/api/products", - "DownstreamScheme": "http", - "DownstreamHost": "jsonplaceholder.typicode.com", - "DownstreamPort": 80, - "UpstreamTemplate": "/products", - "UpstreamHttpMethod": "Get", - "ExceptionsAllowedBeforeBreaking": 3, - "DurationOfBreak": 10, - "TimeoutValue": 5000, - "FileCacheOptions": { "TtlSeconds": 15 } - }, - { - "DownstreamPathTemplate": "/api/products/{productId}", - "DownstreamScheme": "http", - "DownstreamHost": "jsonplaceholder.typicode.com", - "DownstreamPort": 80, - "UpstreamTemplate": "/products/{productId}", - "UpstreamHttpMethod": "Get", - "FileCacheOptions": { "TtlSeconds": 15 } - }, - { - "DownstreamPathTemplate": "/api/products", - "DownstreamScheme": "http", - "DownstreamHost": "products20161126090340.azurewebsites.net", - "DownstreamPort": 80, - "UpstreamTemplate": "/products", - "UpstreamHttpMethod": "Post", - "ExceptionsAllowedBeforeBreaking": 3, - "DurationOfBreak": 10, - "TimeoutValue": 5000, - "FileCacheOptions": { "TtlSeconds": 15 } - }, - { - "DownstreamPathTemplate": "/api/products/{productId}", - "DownstreamScheme": "http", - "DownstreamHost": "products20161126090340.azurewebsites.net", - "DownstreamPort": 80, - "UpstreamTemplate": "/products/{productId}", - "UpstreamHttpMethod": "Put", - "ExceptionsAllowedBeforeBreaking": 3, - "DurationOfBreak": 10, - "TimeoutValue": 5000, - "FileCacheOptions": { "TtlSeconds": 15 } - }, - { - "DownstreamPathTemplate": "/api/products/{productId}", - "DownstreamScheme": "http", - "DownstreamHost": "products20161126090340.azurewebsites.net", - "DownstreamPort": 80, - "UpstreamTemplate": "/products/{productId}", - "UpstreamHttpMethod": "Delete", - "ExceptionsAllowedBeforeBreaking": 3, - "DurationOfBreak": 10, - "TimeoutValue": 5000, - "FileCacheOptions": { "TtlSeconds": 15 } - }, - { - "DownstreamPathTemplate": "/api/customers", - "DownstreamScheme": "http", - "DownstreamHost": "customers20161126090811.azurewebsites.net", - "DownstreamPort": 80, - "UpstreamTemplate": "/customers", - "UpstreamHttpMethod": "Get", - "ExceptionsAllowedBeforeBreaking": 3, - "DurationOfBreak": 10, - "TimeoutValue": 5000, - "FileCacheOptions": { "TtlSeconds": 15 } - }, - { - "DownstreamPathTemplate": "/api/customers/{customerId}", - "DownstreamScheme": "http", - "DownstreamHost": "customers20161126090811.azurewebsites.net", - "DownstreamPort": 80, - "UpstreamTemplate": "/customers/{customerId}", - "UpstreamHttpMethod": "Get", - "ExceptionsAllowedBeforeBreaking": 3, - "DurationOfBreak": 10, - "TimeoutValue": 5000, - "FileCacheOptions": { "TtlSeconds": 15 } - }, - { - "DownstreamPathTemplate": "/api/customers", - "DownstreamScheme": "http", - "DownstreamHost": "customers20161126090811.azurewebsites.net", - "DownstreamPort": 80, - "UpstreamTemplate": "/customers", - "UpstreamHttpMethod": "Post", - "ExceptionsAllowedBeforeBreaking": 3, - "DurationOfBreak": 10, - "TimeoutValue": 5000, - "FileCacheOptions": { "TtlSeconds": 15 } - }, - { - "DownstreamPathTemplate": "/api/customers/{customerId}", - "DownstreamScheme": "http", - "DownstreamHost": "customers20161126090811.azurewebsites.net", - "DownstreamPort": 80, - "UpstreamTemplate": "/customers/{customerId}", - "UpstreamHttpMethod": "Put", - "ExceptionsAllowedBeforeBreaking": 3, - "DurationOfBreak": 10, - "TimeoutValue": 5000, - "FileCacheOptions": { "TtlSeconds": 15 } - }, - { - "DownstreamPathTemplate": "/api/customers/{customerId}", - "DownstreamScheme": "http", - "DownstreamHost": "customers20161126090811.azurewebsites.net", - "DownstreamPort": 80, - "UpstreamTemplate": "/customers/{customerId}", - "UpstreamHttpMethod": "Delete", - "ExceptionsAllowedBeforeBreaking": 3, - "DurationOfBreak": 10, - "TimeoutValue": 5000, - "FileCacheOptions": { "TtlSeconds": 15 } - }, - { - "DownstreamPathTemplate": "/posts", - "DownstreamScheme": "http", - "DownstreamHost": "jsonplaceholder.typicode.com", - "DownstreamPort": 80, - "UpstreamTemplate": "/posts/", - "UpstreamHttpMethod": "Get", - "ExceptionsAllowedBeforeBreaking": 3, - "DurationOfBreak": 10, - "TimeoutValue": 5000, - "FileCacheOptions": { "TtlSeconds": 15 } } - ], - "GlobalConfiguration": { - "RequestIdKey": "OcRequestId" + }, + { + "DownstreamPathTemplate": "/posts/{postId}", + "DownstreamScheme": "http", + "DownstreamHost": "jsonplaceholder.typicode.com", + "DownstreamPort": 80, + "UpstreamTemplate": "/posts/{postId}", + "UpstreamHttpMethod": "Get", + "QoSOptions": { + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000 + } + }, + { + "DownstreamPathTemplate": "/posts/{postId}/comments", + "DownstreamScheme": "http", + "DownstreamHost": "jsonplaceholder.typicode.com", + "DownstreamPort": 80, + "UpstreamTemplate": "/posts/{postId}/comments", + "UpstreamHttpMethod": "Get", + "QoSOptions": { + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000 + } + }, + { + "DownstreamPathTemplate": "/comments", + "DownstreamScheme": "http", + "DownstreamHost": "jsonplaceholder.typicode.com", + "DownstreamPort": 80, + "UpstreamTemplate": "/comments", + "UpstreamHttpMethod": "Get", + "QoSOptions": { + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000 + } + }, + { + "DownstreamPathTemplate": "/posts", + "DownstreamScheme": "http", + "DownstreamHost": "jsonplaceholder.typicode.com", + "DownstreamPort": 80, + "UpstreamTemplate": "/posts", + "UpstreamHttpMethod": "Post", + "QoSOptions": { + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000 + } + }, + { + "DownstreamPathTemplate": "/posts/{postId}", + "DownstreamScheme": "http", + "DownstreamHost": "jsonplaceholder.typicode.com", + "DownstreamPort": 80, + "UpstreamTemplate": "/posts/{postId}", + "UpstreamHttpMethod": "Put", + "QoSOptions": { + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000 + } + }, + { + "DownstreamPathTemplate": "/posts/{postId}", + "DownstreamScheme": "http", + "DownstreamHost": "jsonplaceholder.typicode.com", + "DownstreamPort": 80, + "UpstreamTemplate": "/posts/{postId}", + "UpstreamHttpMethod": "Patch", + "QoSOptions": { + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000 + } + }, + { + "DownstreamPathTemplate": "/posts/{postId}", + "DownstreamScheme": "http", + "DownstreamHost": "jsonplaceholder.typicode.com", + "DownstreamPort": 80, + "UpstreamTemplate": "/posts/{postId}", + "UpstreamHttpMethod": "Delete", + "QoSOptions": { + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000 + } + }, + { + "DownstreamPathTemplate": "/api/products", + "DownstreamScheme": "http", + "DownstreamHost": "jsonplaceholder.typicode.com", + "DownstreamPort": 80, + "UpstreamTemplate": "/products", + "UpstreamHttpMethod": "Get", + "QoSOptions": { + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000 + }, + "FileCacheOptions": { "TtlSeconds": 15 } + }, + { + "DownstreamPathTemplate": "/api/products/{productId}", + "DownstreamScheme": "http", + "DownstreamHost": "jsonplaceholder.typicode.com", + "DownstreamPort": 80, + "UpstreamTemplate": "/products/{productId}", + "UpstreamHttpMethod": "Get", + "FileCacheOptions": { "TtlSeconds": 15 } + }, + { + "DownstreamPathTemplate": "/api/products", + "DownstreamScheme": "http", + "DownstreamHost": "products20161126090340.azurewebsites.net", + "DownstreamPort": 80, + "UpstreamTemplate": "/products", + "UpstreamHttpMethod": "Post", + "QoSOptions": { + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000 + } + }, + { + "DownstreamPathTemplate": "/api/products/{productId}", + "DownstreamScheme": "http", + "DownstreamHost": "products20161126090340.azurewebsites.net", + "DownstreamPort": 80, + "UpstreamTemplate": "/products/{productId}", + "UpstreamHttpMethod": "Put", + "QoSOptions": { + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000 + }, + "FileCacheOptions": { "TtlSeconds": 15 } + }, + { + "DownstreamPathTemplate": "/api/products/{productId}", + "DownstreamScheme": "http", + "DownstreamHost": "products20161126090340.azurewebsites.net", + "DownstreamPort": 80, + "UpstreamTemplate": "/products/{productId}", + "UpstreamHttpMethod": "Delete", + "QoSOptions": { + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000 + }, + "FileCacheOptions": { "TtlSeconds": 15 } + }, + { + "DownstreamPathTemplate": "/api/customers", + "DownstreamScheme": "http", + "DownstreamHost": "customers20161126090811.azurewebsites.net", + "DownstreamPort": 80, + "UpstreamTemplate": "/customers", + "UpstreamHttpMethod": "Get", + "QoSOptions": { + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000 + }, + "FileCacheOptions": { "TtlSeconds": 15 } + }, + { + "DownstreamPathTemplate": "/api/customers/{customerId}", + "DownstreamScheme": "http", + "DownstreamHost": "customers20161126090811.azurewebsites.net", + "DownstreamPort": 80, + "UpstreamTemplate": "/customers/{customerId}", + "UpstreamHttpMethod": "Get", + "QoSOptions": { + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000 + }, + "FileCacheOptions": { "TtlSeconds": 15 } + }, + { + "DownstreamPathTemplate": "/api/customers", + "DownstreamScheme": "http", + "DownstreamHost": "customers20161126090811.azurewebsites.net", + "DownstreamPort": 80, + "UpstreamTemplate": "/customers", + "UpstreamHttpMethod": "Post", + "QoSOptions": { + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000 + }, + "FileCacheOptions": { "TtlSeconds": 15 } + }, + { + "DownstreamPathTemplate": "/api/customers/{customerId}", + "DownstreamScheme": "http", + "DownstreamHost": "customers20161126090811.azurewebsites.net", + "DownstreamPort": 80, + "UpstreamTemplate": "/customers/{customerId}", + "UpstreamHttpMethod": "Put", + "QoSOptions": { + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000 + }, + "FileCacheOptions": { "TtlSeconds": 15 } + }, + { + "DownstreamPathTemplate": "/api/customers/{customerId}", + "DownstreamScheme": "http", + "DownstreamHost": "customers20161126090811.azurewebsites.net", + "DownstreamPort": 80, + "UpstreamTemplate": "/customers/{customerId}", + "UpstreamHttpMethod": "Delete", + "QoSOptions": { + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000 + }, + "FileCacheOptions": { "TtlSeconds": 15 } + }, + { + "DownstreamPathTemplate": "/posts", + "DownstreamScheme": "http", + "DownstreamHost": "jsonplaceholder.typicode.com", + "DownstreamPort": 80, + "UpstreamTemplate": "/posts/", + "UpstreamHttpMethod": "Get", + "QoSOptions": { + "ExceptionsAllowedBeforeBreaking": 3, + "DurationOfBreak": 10, + "TimeoutValue": 5000 + }, + "FileCacheOptions": { "TtlSeconds": 15 } } + ], + + "GlobalConfiguration": { + "RequestIdKey": "OcRequestId" + } } \ No newline at end of file diff --git a/test/Ocelot.UnitTests/LoadBalancer/LoadBalancerMiddlewareTests.cs b/test/Ocelot.UnitTests/LoadBalancer/LoadBalancerMiddlewareTests.cs index 5a9eec87..bd7667bf 100644 --- a/test/Ocelot.UnitTests/LoadBalancer/LoadBalancerMiddlewareTests.cs +++ b/test/Ocelot.UnitTests/LoadBalancer/LoadBalancerMiddlewareTests.cs @@ -29,7 +29,6 @@ namespace Ocelot.UnitTests.LoadBalancer private readonly HttpClient _client; private HttpResponseMessage _result; private HostAndPort _hostAndPort; - private OkResponse _request; private OkResponse _downstreamUrl; private OkResponse _downstreamRoute; private ErrorResponse _getLoadBalancerHouseError; diff --git a/test/Ocelot.UnitTests/Request/HttpRequestBuilderMiddlewareTests.cs b/test/Ocelot.UnitTests/Request/HttpRequestBuilderMiddlewareTests.cs index 406e7cb6..6d4837d8 100644 --- a/test/Ocelot.UnitTests/Request/HttpRequestBuilderMiddlewareTests.cs +++ b/test/Ocelot.UnitTests/Request/HttpRequestBuilderMiddlewareTests.cs @@ -19,6 +19,7 @@ using Ocelot.Request.Middleware; using Ocelot.Responses; using TestStack.BDDfy; using Xunit; +using Ocelot.Configuration; namespace Ocelot.UnitTests.Request { @@ -72,7 +73,7 @@ namespace Ocelot.UnitTests.Request this.Given(x => x.GivenTheDownStreamUrlIs("any old string")) .And(x => x.GivenTheDownStreamRouteIs(downstreamRoute)) - .And(x => x.GivenTheRequestBuilderReturns(new Ocelot.Request.Request(new HttpRequestMessage(), new CookieContainer(),new Values.QoS(3, 8 ,5000, Polly.Timeout.TimeoutStrategy.Pessimistic)))) + .And(x => x.GivenTheRequestBuilderReturns(new Ocelot.Request.Request(new HttpRequestMessage(), new CookieContainer(), true, new QoSOptions(3, 8 ,5000, Polly.Timeout.TimeoutStrategy.Pessimistic)))) .When(x => x.WhenICallTheMiddleware()) .Then(x => x.ThenTheScopedDataRepositoryIsCalledCorrectly()) .BDDfy(); @@ -91,7 +92,7 @@ namespace Ocelot.UnitTests.Request _request = new OkResponse(request); _requestBuilder .Setup(x => x.Build(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), - It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(),It.IsAny())) + It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(),It.IsAny(), It.IsAny())) .ReturnsAsync(_request); } diff --git a/test/Ocelot.UnitTests/Request/RequestBuilderTests.cs b/test/Ocelot.UnitTests/Request/RequestBuilderTests.cs index 55d18c38..c317c8d7 100644 --- a/test/Ocelot.UnitTests/Request/RequestBuilderTests.cs +++ b/test/Ocelot.UnitTests/Request/RequestBuilderTests.cs @@ -10,6 +10,7 @@ using Ocelot.Responses; using Shouldly; using TestStack.BDDfy; using Xunit; +using Ocelot.Configuration; namespace Ocelot.UnitTests.Request { @@ -25,7 +26,8 @@ namespace Ocelot.UnitTests.Request private readonly IRequestCreator _requestCreator; private Response _result; private Ocelot.RequestId.RequestId _requestId; - private Ocelot.Values.QoS _qos; + private bool _isQos; + private QoSOptions _qos; public RequestBuilderTests() { @@ -38,7 +40,7 @@ namespace Ocelot.UnitTests.Request { this.Given(x => x.GivenIHaveHttpMethod("GET")) .And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk")) - .And(x=> x.GivenTheQos(new Values.QoS(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic))) + .And(x=> x.GivenTheQos(true,new QoSOptions(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic))) .When(x => x.WhenICreateARequest()) .And(x => x.ThenTheCorrectDownstreamUrlIsUsed("http://www.bbc.co.uk/")) .BDDfy(); @@ -49,7 +51,7 @@ namespace Ocelot.UnitTests.Request { this.Given(x => x.GivenIHaveHttpMethod("POST")) .And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk")) - .And(x => x.GivenTheQos(new Values.QoS(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic))) + .And(x => x.GivenTheQos(true,new QoSOptions(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic))) .When(x => x.WhenICreateARequest()) .And(x => x.ThenTheCorrectHttpMethodIsUsed(HttpMethod.Post)) @@ -63,7 +65,7 @@ namespace Ocelot.UnitTests.Request .And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk")) .And(x => x.GivenIHaveTheHttpContent(new StringContent("Hi from Tom"))) .And(x => x.GivenTheContentTypeIs("application/json")) - .And(x => x.GivenTheQos(new Values.QoS(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic))) + .And(x => x.GivenTheQos(true, new QoSOptions(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic))) .When(x => x.WhenICreateARequest()) .And(x => x.ThenTheCorrectContentIsUsed(new StringContent("Hi from Tom"))) @@ -77,7 +79,7 @@ namespace Ocelot.UnitTests.Request .And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk")) .And(x => x.GivenIHaveTheHttpContent(new StringContent("Hi from Tom"))) .And(x => x.GivenTheContentTypeIs("application/json")) - .And(x => x.GivenTheQos(new Values.QoS(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic))) + .And(x => x.GivenTheQos(true, new QoSOptions(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic))) .When(x => x.WhenICreateARequest()) .And(x => x.ThenTheCorrectContentHeadersAreUsed(new HeaderDictionary @@ -96,7 +98,7 @@ namespace Ocelot.UnitTests.Request .And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk")) .And(x => x.GivenIHaveTheHttpContent(new StringContent("Hi from Tom"))) .And(x => x.GivenTheContentTypeIs("application/json; charset=utf-8")) - .And(x => x.GivenTheQos(new Values.QoS(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic))) + .And(x => x.GivenTheQos(true, new QoSOptions(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic))) .When(x => x.WhenICreateARequest()) .And(x => x.ThenTheCorrectContentHeadersAreUsed(new HeaderDictionary @@ -117,7 +119,7 @@ namespace Ocelot.UnitTests.Request { {"ChopSticks", "Bubbles" } })) - .And(x => x.GivenTheQos(new Values.QoS(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic))) + .And(x => x.GivenTheQos(true, new QoSOptions(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic))) .When(x => x.WhenICreateARequest()) .And(x => x.ThenTheCorrectHeadersAreUsed(new HeaderDictionary @@ -136,7 +138,7 @@ namespace Ocelot.UnitTests.Request .And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk")) .And(x => x.GivenTheHttpHeadersAre(new HeaderDictionary())) .And(x => x.GivenTheRequestIdIs(new Ocelot.RequestId.RequestId("RequestId", requestId))) - .And(x => x.GivenTheQos(new Values.QoS(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic))) + .And(x => x.GivenTheQos(true, new QoSOptions(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic))) .When(x => x.WhenICreateARequest()) .And(x => x.ThenTheCorrectHeadersAreUsed(new HeaderDictionary { @@ -155,7 +157,7 @@ namespace Ocelot.UnitTests.Request {"RequestId", "534534gv54gv45g" } })) .And(x => x.GivenTheRequestIdIs(new Ocelot.RequestId.RequestId("RequestId", Guid.NewGuid().ToString()))) - .And(x => x.GivenTheQos(new Values.QoS(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic))) + .And(x => x.GivenTheQos(true, new QoSOptions(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic))) .When(x => x.WhenICreateARequest()) .And(x => x.ThenTheCorrectHeadersAreUsed(new HeaderDictionary { @@ -175,7 +177,7 @@ namespace Ocelot.UnitTests.Request .And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk")) .And(x => x.GivenTheHttpHeadersAre(new HeaderDictionary())) .And(x => x.GivenTheRequestIdIs(new Ocelot.RequestId.RequestId(requestIdKey, requestIdValue))) - .And(x => x.GivenTheQos(new Values.QoS(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic))) + .And(x => x.GivenTheQos(true, new QoSOptions(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic))) .When(x => x.WhenICreateARequest()) .And(x => x.ThenTheRequestIdIsNotInTheHeaders()) .BDDfy(); @@ -186,8 +188,9 @@ namespace Ocelot.UnitTests.Request _requestId = requestId; } - private void GivenTheQos(Ocelot.Values.QoS qos) + private void GivenTheQos(bool isQos, QoSOptions qos) { + _isQos = isQos; _qos = qos; } @@ -301,7 +304,7 @@ namespace Ocelot.UnitTests.Request private void WhenICreateARequest() { _result = _requestCreator.Build(_httpMethod, _downstreamUrl, _content?.ReadAsStreamAsync().Result, _headers, - _cookies, _query, _contentType, _requestId, _qos).Result; + _cookies, _query, _contentType, _requestId,_isQos,_qos).Result; } diff --git a/test/Ocelot.UnitTests/Requester/HttpRequesterMiddlewareTests.cs b/test/Ocelot.UnitTests/Requester/HttpRequesterMiddlewareTests.cs index 66c7491e..d2d62923 100644 --- a/test/Ocelot.UnitTests/Requester/HttpRequesterMiddlewareTests.cs +++ b/test/Ocelot.UnitTests/Requester/HttpRequesterMiddlewareTests.cs @@ -61,7 +61,7 @@ namespace Ocelot.UnitTests.Requester [Fact] public void should_call_scoped_data_repository_correctly() { - this.Given(x => x.GivenTheRequestIs(new Ocelot.Request.Request(new HttpRequestMessage(),new CookieContainer(), new Values.QoS(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic)))) + this.Given(x => x.GivenTheRequestIs(new Ocelot.Request.Request(new HttpRequestMessage(),new CookieContainer(),true, new Ocelot.Configuration.QoSOptions(3, 8, 5000, Polly.Timeout.TimeoutStrategy.Pessimistic)))) .And(x => x.GivenTheRequesterReturns(new HttpResponseMessage())) .And(x => x.GivenTheScopedRepoReturns()) .When(x => x.WhenICallTheMiddleware()) diff --git a/test/Ocelot.UnitTests/ServiceDiscovery/ConfigurationServiceProviderTests.cs b/test/Ocelot.UnitTests/ServiceDiscovery/ConfigurationServiceProviderTests.cs index f1e732e7..282f8ec1 100644 --- a/test/Ocelot.UnitTests/ServiceDiscovery/ConfigurationServiceProviderTests.cs +++ b/test/Ocelot.UnitTests/ServiceDiscovery/ConfigurationServiceProviderTests.cs @@ -10,7 +10,6 @@ namespace Ocelot.UnitTests.ServiceDiscovery public class ConfigurationServiceProviderTests { private ConfigurationServiceProvider _serviceProvider; - private HostAndPort _hostAndPort; private List _result; private List _expected; From 18e0f40c9515bc3d35c19930842a8b799666b2d8 Mon Sep 17 00:00:00 2001 From: geffzhang Date: Thu, 9 Feb 2017 08:30:32 +0800 Subject: [PATCH 7/7] Fix should_use_global_request_id_and_forward not pass This test needs UpstreamHttpMethod = "Get", --- test/Ocelot.AcceptanceTests/RequestIdTests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/test/Ocelot.AcceptanceTests/RequestIdTests.cs b/test/Ocelot.AcceptanceTests/RequestIdTests.cs index 63a40ead..4ad5bd8c 100644 --- a/test/Ocelot.AcceptanceTests/RequestIdTests.cs +++ b/test/Ocelot.AcceptanceTests/RequestIdTests.cs @@ -96,6 +96,7 @@ namespace Ocelot.AcceptanceTests DownstreamScheme = "http", DownstreamHost = "localhost", UpstreamTemplate = "/", + UpstreamHttpMethod ="Get" } }, GlobalConfiguration = new FileGlobalConfiguration