Feature/#574 look at httpclient cache key (#589)

* #574 consolidate some code, man the config stuff is a mess!

* #574 just use the downstream re route and the key for caching http clients

* #574 added benchmark, i was suprised to learn using a complex type was faster than a string in benchmark .net dictionary tests, hey ho probably dont have enough data in the type...
This commit is contained in:
Tom Pallister 2018-09-01 13:10:45 +01:00 committed by GitHub
parent 55277cac45
commit 66b68fc685
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 672 additions and 289 deletions

View File

@ -50,7 +50,7 @@
Logger.LogWarning("user scopes is not authorised setting pipeline error"); Logger.LogWarning("user scopes is not authorised setting pipeline error");
SetPipelineError(context, new UnauthorisedError( SetPipelineError(context, new UnauthorisedError(
$"{context.HttpContext.User.Identity.Name} unable to access {context.DownstreamReRoute.UpstreamPathTemplate.Value}")); $"{context.HttpContext.User.Identity.Name} unable to access {context.DownstreamReRoute.UpstreamPathTemplate.OriginalValue}"));
} }
} }
@ -70,19 +70,19 @@
if (IsAuthorised(authorised)) if (IsAuthorised(authorised))
{ {
Logger.LogInformation($"{context.HttpContext.User.Identity.Name} has succesfully been authorised for {context.DownstreamReRoute.UpstreamPathTemplate.Value}."); Logger.LogInformation($"{context.HttpContext.User.Identity.Name} has succesfully been authorised for {context.DownstreamReRoute.UpstreamPathTemplate.OriginalValue}.");
await _next.Invoke(context); await _next.Invoke(context);
} }
else else
{ {
Logger.LogWarning($"{context.HttpContext.User.Identity.Name} is not authorised to access {context.DownstreamReRoute.UpstreamPathTemplate.Value}. Setting pipeline error"); Logger.LogWarning($"{context.HttpContext.User.Identity.Name} is not authorised to access {context.DownstreamReRoute.UpstreamPathTemplate.OriginalValue}. Setting pipeline error");
SetPipelineError(context, new UnauthorisedError($"{context.HttpContext.User.Identity.Name} is not authorised to access {context.DownstreamReRoute.UpstreamPathTemplate.Value}")); SetPipelineError(context, new UnauthorisedError($"{context.HttpContext.User.Identity.Name} is not authorised to access {context.DownstreamReRoute.UpstreamPathTemplate.OriginalValue}"));
} }
} }
else else
{ {
Logger.LogInformation($"{context.DownstreamReRoute.DownstreamPathTemplate.Value} route does not require user to be authorised"); Logger.LogInformation($"{context.DownstreamReRoute.DownstreamDownstreamPathTemplate.Value} route does not require user to be authorised");
await _next.Invoke(context); await _next.Invoke(context);
} }
} }

View File

@ -11,7 +11,6 @@ namespace Ocelot.Configuration.Builder
private AuthenticationOptions _authenticationOptions; private AuthenticationOptions _authenticationOptions;
private string _loadBalancerKey; private string _loadBalancerKey;
private string _downstreamPathTemplate; private string _downstreamPathTemplate;
private string _upstreamTemplate;
private UpstreamPathTemplate _upstreamTemplatePattern; private UpstreamPathTemplate _upstreamTemplatePattern;
private List<HttpMethod> _upstreamHttpMethod; private List<HttpMethod> _upstreamHttpMethod;
private bool _isAuthenticated; private bool _isAuthenticated;
@ -79,12 +78,6 @@ namespace Ocelot.Configuration.Builder
return this; return this;
} }
public DownstreamReRouteBuilder WithUpstreamPathTemplate(string input)
{
_upstreamTemplate = input;
return this;
}
public DownstreamReRouteBuilder WithUpstreamTemplatePattern(UpstreamPathTemplate input) public DownstreamReRouteBuilder WithUpstreamTemplatePattern(UpstreamPathTemplate input)
{ {
_upstreamTemplatePattern = input; _upstreamTemplatePattern = input;
@ -245,7 +238,7 @@ namespace Ocelot.Configuration.Builder
{ {
return new DownstreamReRoute( return new DownstreamReRoute(
_key, _key,
new PathTemplate(_upstreamTemplate), _upstreamTemplatePattern,
_upstreamHeaderFindAndReplace, _upstreamHeaderFindAndReplace,
_downstreamHeaderFindAndReplace, _downstreamHeaderFindAndReplace,
_downstreamAddresses, _downstreamAddresses,
@ -267,7 +260,7 @@ namespace Ocelot.Configuration.Builder
_isAuthenticated, _isAuthenticated,
_isAuthorised, _isAuthorised,
_authenticationOptions, _authenticationOptions,
new PathTemplate(_downstreamPathTemplate), new DownstreamPathTemplate(_downstreamPathTemplate),
_loadBalancerKey, _loadBalancerKey,
_delegatingHandlers, _delegatingHandlers,
_addHeadersToDownstream, _addHeadersToDownstream,

View File

@ -1,15 +1,12 @@
using System.Collections.Generic; namespace Ocelot.Configuration.Builder
using System.Net.Http;
using Ocelot.Values;
using System.Linq;
using Ocelot.Configuration.Creator;
using System;
namespace Ocelot.Configuration.Builder
{ {
using System.Collections.Generic;
using System.Net.Http;
using Ocelot.Values;
using System.Linq;
public class ReRouteBuilder public class ReRouteBuilder
{ {
private string _upstreamTemplate;
private UpstreamPathTemplate _upstreamTemplatePattern; private UpstreamPathTemplate _upstreamTemplatePattern;
private List<HttpMethod> _upstreamHttpMethod; private List<HttpMethod> _upstreamHttpMethod;
private string _upstreamHost; private string _upstreamHost;
@ -39,12 +36,6 @@ namespace Ocelot.Configuration.Builder
return this; return this;
} }
public ReRouteBuilder WithUpstreamPathTemplate(string input)
{
_upstreamTemplate = input;
return this;
}
public ReRouteBuilder WithUpstreamTemplatePattern(UpstreamPathTemplate input) public ReRouteBuilder WithUpstreamTemplatePattern(UpstreamPathTemplate input)
{ {
_upstreamTemplatePattern = input; _upstreamTemplatePattern = input;
@ -67,7 +58,6 @@ namespace Ocelot.Configuration.Builder
{ {
return new ReRoute( return new ReRoute(
_downstreamReRoutes, _downstreamReRoutes,
new PathTemplate(_upstreamTemplate),
_upstreamHttpMethod, _upstreamHttpMethod,
_upstreamTemplatePattern, _upstreamTemplatePattern,
_upstreamHost, _upstreamHost,

View File

@ -0,0 +1,41 @@
namespace Ocelot.Configuration.Builder
{
using Values;
public class UpstreamPathTemplateBuilder
{
private string _template;
private int _priority;
private bool _containsQueryString;
private string _originalValue;
public UpstreamPathTemplateBuilder WithTemplate(string template)
{
_template = template;
return this;
}
public UpstreamPathTemplateBuilder WithPriority(int priority)
{
_priority = priority;
return this;
}
public UpstreamPathTemplateBuilder WithContainsQueryString(bool containsQueryString)
{
_containsQueryString = containsQueryString;
return this;
}
public UpstreamPathTemplateBuilder WithOriginalValue(string originalValue)
{
_originalValue = originalValue;
return this;
}
public UpstreamPathTemplate Build()
{
return new UpstreamPathTemplate(_template, _priority, _containsQueryString, _originalValue);
}
}
}

View File

@ -166,7 +166,6 @@ namespace Ocelot.Configuration.Creator
var upstreamTemplatePattern = _upstreamTemplatePatternCreator.Create(aggregateReRoute); var upstreamTemplatePattern = _upstreamTemplatePatternCreator.Create(aggregateReRoute);
var reRoute = new ReRouteBuilder() var reRoute = new ReRouteBuilder()
.WithUpstreamPathTemplate(aggregateReRoute.UpstreamPathTemplate)
.WithUpstreamHttpMethod(aggregateReRoute.UpstreamHttpMethod) .WithUpstreamHttpMethod(aggregateReRoute.UpstreamHttpMethod)
.WithUpstreamTemplatePattern(upstreamTemplatePattern) .WithUpstreamTemplatePattern(upstreamTemplatePattern)
.WithDownstreamReRoutes(applicableReRoutes) .WithDownstreamReRoutes(applicableReRoutes)
@ -182,7 +181,6 @@ namespace Ocelot.Configuration.Creator
var upstreamTemplatePattern = _upstreamTemplatePatternCreator.Create(fileReRoute); var upstreamTemplatePattern = _upstreamTemplatePatternCreator.Create(fileReRoute);
var reRoute = new ReRouteBuilder() var reRoute = new ReRouteBuilder()
.WithUpstreamPathTemplate(fileReRoute.UpstreamPathTemplate)
.WithUpstreamHttpMethod(fileReRoute.UpstreamHttpMethod) .WithUpstreamHttpMethod(fileReRoute.UpstreamHttpMethod)
.WithUpstreamTemplatePattern(upstreamTemplatePattern) .WithUpstreamTemplatePattern(upstreamTemplatePattern)
.WithDownstreamReRoute(downstreamReRoutes) .WithDownstreamReRoute(downstreamReRoutes)
@ -229,7 +227,6 @@ namespace Ocelot.Configuration.Creator
var reRoute = new DownstreamReRouteBuilder() var reRoute = new DownstreamReRouteBuilder()
.WithKey(fileReRoute.Key) .WithKey(fileReRoute.Key)
.WithDownstreamPathTemplate(fileReRoute.DownstreamPathTemplate) .WithDownstreamPathTemplate(fileReRoute.DownstreamPathTemplate)
.WithUpstreamPathTemplate(fileReRoute.UpstreamPathTemplate)
.WithUpstreamHttpMethod(fileReRoute.UpstreamHttpMethod) .WithUpstreamHttpMethod(fileReRoute.UpstreamHttpMethod)
.WithUpstreamTemplatePattern(upstreamTemplatePattern) .WithUpstreamTemplatePattern(upstreamTemplatePattern)
.WithIsAuthenticated(fileReRouteOptions.IsAuthenticated) .WithIsAuthenticated(fileReRouteOptions.IsAuthenticated)

View File

@ -31,7 +31,7 @@ namespace Ocelot.Configuration.Creator
//hack to handle /{url} case //hack to handle /{url} case
if(ForwardSlashAndOnePlaceHolder(upstreamTemplate, placeholders, postitionOfPlaceHolderClosingBracket)) if(ForwardSlashAndOnePlaceHolder(upstreamTemplate, placeholders, postitionOfPlaceHolderClosingBracket))
{ {
return new UpstreamPathTemplate(RegExForwardSlashAndOnePlaceHolder, 0, false); return new UpstreamPathTemplate(RegExForwardSlashAndOnePlaceHolder, 0, false, reRoute.UpstreamPathTemplate);
} }
} }
} }
@ -60,7 +60,7 @@ namespace Ocelot.Configuration.Creator
if (upstreamTemplate == "/") if (upstreamTemplate == "/")
{ {
return new UpstreamPathTemplate(RegExForwardSlashOnly, reRoute.Priority, containsQueryString); return new UpstreamPathTemplate(RegExForwardSlashOnly, reRoute.Priority, containsQueryString, reRoute.UpstreamPathTemplate);
} }
if(upstreamTemplate.EndsWith("/")) if(upstreamTemplate.EndsWith("/"))
@ -72,7 +72,7 @@ namespace Ocelot.Configuration.Creator
? $"^{upstreamTemplate}{RegExMatchEndString}" ? $"^{upstreamTemplate}{RegExMatchEndString}"
: $"^{RegExIgnoreCase}{upstreamTemplate}{RegExMatchEndString}"; : $"^{RegExIgnoreCase}{upstreamTemplate}{RegExMatchEndString}";
return new UpstreamPathTemplate(route, reRoute.Priority, containsQueryString); return new UpstreamPathTemplate(route, reRoute.Priority, containsQueryString, reRoute.UpstreamPathTemplate);
} }
private bool ForwardSlashAndOnePlaceHolder(string upstreamTemplate, List<string> placeholders, int postitionOfPlaceHolderClosingBracket) private bool ForwardSlashAndOnePlaceHolder(string upstreamTemplate, List<string> placeholders, int postitionOfPlaceHolderClosingBracket)

View File

@ -8,7 +8,7 @@ namespace Ocelot.Configuration
{ {
public DownstreamReRoute( public DownstreamReRoute(
string key, string key,
PathTemplate upstreamPathTemplate, UpstreamPathTemplate upstreamPathTemplate,
List<HeaderFindAndReplace> upstreamHeadersFindAndReplace, List<HeaderFindAndReplace> upstreamHeadersFindAndReplace,
List<HeaderFindAndReplace> downstreamHeadersFindAndReplace, List<HeaderFindAndReplace> downstreamHeadersFindAndReplace,
List<DownstreamHostAndPort> downstreamAddresses, List<DownstreamHostAndPort> downstreamAddresses,
@ -30,7 +30,7 @@ namespace Ocelot.Configuration
bool isAuthenticated, bool isAuthenticated,
bool isAuthorised, bool isAuthorised,
AuthenticationOptions authenticationOptions, AuthenticationOptions authenticationOptions,
PathTemplate downstreamPathTemplate, DownstreamPathTemplate downstreamDownstreamPathTemplate,
string loadBalancerKey, string loadBalancerKey,
List<string> delegatingHandlers, List<string> delegatingHandlers,
List<AddHeader> addHeadersToDownstream, List<AddHeader> addHeadersToDownstream,
@ -63,13 +63,13 @@ namespace Ocelot.Configuration
IsAuthenticated = isAuthenticated; IsAuthenticated = isAuthenticated;
IsAuthorised = isAuthorised; IsAuthorised = isAuthorised;
AuthenticationOptions = authenticationOptions; AuthenticationOptions = authenticationOptions;
DownstreamPathTemplate = downstreamPathTemplate; DownstreamDownstreamPathTemplate = downstreamDownstreamPathTemplate;
LoadBalancerKey = loadBalancerKey; LoadBalancerKey = loadBalancerKey;
AddHeadersToUpstream = addHeadersToUpstream; AddHeadersToUpstream = addHeadersToUpstream;
} }
public string Key { get; } public string Key { get; }
public PathTemplate UpstreamPathTemplate { get; } public UpstreamPathTemplate UpstreamPathTemplate { get; }
public List<HeaderFindAndReplace> UpstreamHeadersFindAndReplace { get; } public List<HeaderFindAndReplace> UpstreamHeadersFindAndReplace { get; }
public List<HeaderFindAndReplace> DownstreamHeadersFindAndReplace { get; } public List<HeaderFindAndReplace> DownstreamHeadersFindAndReplace { get; }
public List<DownstreamHostAndPort> DownstreamAddresses { get; } public List<DownstreamHostAndPort> DownstreamAddresses { get; }
@ -91,7 +91,7 @@ namespace Ocelot.Configuration
public bool IsAuthenticated { get; } public bool IsAuthenticated { get; }
public bool IsAuthorised { get; } public bool IsAuthorised { get; }
public AuthenticationOptions AuthenticationOptions { get; } public AuthenticationOptions AuthenticationOptions { get; }
public PathTemplate DownstreamPathTemplate { get; } public DownstreamPathTemplate DownstreamDownstreamPathTemplate { get; }
public string LoadBalancerKey { get; } public string LoadBalancerKey { get; }
public List<string> DelegatingHandlers { get; } public List<string> DelegatingHandlers { get; }
public List<AddHeader> AddHeadersToDownstream { get; } public List<AddHeader> AddHeadersToDownstream { get; }

View File

@ -1,15 +1,12 @@
using System.Collections.Generic; namespace Ocelot.Configuration
using System.Net.Http;
using Ocelot.Configuration.Creator;
using Ocelot.Requester.QoS;
using Ocelot.Values;
namespace Ocelot.Configuration
{ {
using System.Collections.Generic;
using System.Net.Http;
using Ocelot.Values;
public class ReRoute public class ReRoute
{ {
public ReRoute(List<DownstreamReRoute> downstreamReRoute, public ReRoute(List<DownstreamReRoute> downstreamReRoute,
PathTemplate upstreamPathTemplate,
List<HttpMethod> upstreamHttpMethod, List<HttpMethod> upstreamHttpMethod,
UpstreamPathTemplate upstreamTemplatePattern, UpstreamPathTemplate upstreamTemplatePattern,
string upstreamHost, string upstreamHost,
@ -17,13 +14,11 @@ namespace Ocelot.Configuration
{ {
UpstreamHost = upstreamHost; UpstreamHost = upstreamHost;
DownstreamReRoute = downstreamReRoute; DownstreamReRoute = downstreamReRoute;
UpstreamPathTemplate = upstreamPathTemplate;
UpstreamHttpMethod = upstreamHttpMethod; UpstreamHttpMethod = upstreamHttpMethod;
UpstreamTemplatePattern = upstreamTemplatePattern; UpstreamTemplatePattern = upstreamTemplatePattern;
Aggregator = aggregator; Aggregator = aggregator;
} }
public PathTemplate UpstreamPathTemplate { get; private set; }
public UpstreamPathTemplate UpstreamTemplatePattern { get; private set; } public UpstreamPathTemplate UpstreamTemplatePattern { get; private set; }
public List<HttpMethod> UpstreamHttpMethod { get; private set; } public List<HttpMethod> UpstreamHttpMethod { get; private set; }
public string UpstreamHost { get; private set; } public string UpstreamHost { get; private set; }

View File

@ -55,7 +55,7 @@ namespace Ocelot.DownstreamRouteFinder.Finder
private DownstreamRoute GetPlaceholderNamesAndValues(string path, string query, ReRoute reRoute) private DownstreamRoute GetPlaceholderNamesAndValues(string path, string query, ReRoute reRoute)
{ {
var templatePlaceholderNameAndValues = _placeholderNameAndValueFinder.Find(path, query, reRoute.UpstreamPathTemplate.Value); var templatePlaceholderNameAndValues = _placeholderNameAndValueFinder.Find(path, query, reRoute.UpstreamTemplatePattern.OriginalValue);
return new DownstreamRoute(templatePlaceholderNameAndValues.Data, reRoute); return new DownstreamRoute(templatePlaceholderNameAndValues.Data, reRoute);
} }

View File

@ -10,7 +10,7 @@
public class DownstreamRouteProviderFactory : IDownstreamRouteProviderFactory public class DownstreamRouteProviderFactory : IDownstreamRouteProviderFactory
{ {
private readonly Dictionary<string, IDownstreamRouteProvider> _providers; private readonly Dictionary<string, IDownstreamRouteProvider> _providers;
private IOcelotLogger _logger; private readonly IOcelotLogger _logger;
public DownstreamRouteProviderFactory(IServiceProvider provider, IOcelotLoggerFactory factory) public DownstreamRouteProviderFactory(IServiceProvider provider, IOcelotLoggerFactory factory)
{ {
@ -22,7 +22,7 @@
{ {
//todo - this is a bit hacky we are saying there are no reRoutes or there are reRoutes but none of them have //todo - this is a bit hacky we are saying there are no reRoutes or there are reRoutes but none of them have
//an upstream path template which means they are dyanmic and service discovery is on... //an upstream path template which means they are dyanmic and service discovery is on...
if((!config.ReRoutes.Any() || config.ReRoutes.All(x => string.IsNullOrEmpty(x.UpstreamPathTemplate.Value))) && IsServiceDiscovery(config.ServiceProviderConfiguration)) if((!config.ReRoutes.Any() || config.ReRoutes.All(x => string.IsNullOrEmpty(x.UpstreamTemplatePattern?.OriginalValue))) && IsServiceDiscovery(config.ServiceProviderConfiguration))
{ {
_logger.LogInformation($"Selected {nameof(DownstreamRouteCreator)} as DownstreamRouteProvider for this request"); _logger.LogInformation($"Selected {nameof(DownstreamRouteCreator)} as DownstreamRouteProvider for this request");
return _providers[nameof(DownstreamRouteCreator)]; return _providers[nameof(DownstreamRouteCreator)];

View File

@ -51,7 +51,7 @@ namespace Ocelot.DownstreamRouteFinder.Middleware
return; return;
} }
var downstreamPathTemplates = string.Join(", ", downstreamRoute.Data.ReRoute.DownstreamReRoute.Select(r => r.DownstreamPathTemplate.Value)); var downstreamPathTemplates = string.Join(", ", downstreamRoute.Data.ReRoute.DownstreamReRoute.Select(r => r.DownstreamDownstreamPathTemplate.Value));
Logger.LogDebug($"downstream templates are {downstreamPathTemplates}"); Logger.LogDebug($"downstream templates are {downstreamPathTemplates}");

View File

@ -27,7 +27,7 @@ namespace Ocelot.DownstreamUrlCreator.Middleware
public async Task Invoke(DownstreamContext context) public async Task Invoke(DownstreamContext context)
{ {
var response = _replacer var response = _replacer
.Replace(context.DownstreamReRoute.DownstreamPathTemplate, context.TemplatePlaceholderNameAndValues); .Replace(context.DownstreamReRoute.DownstreamDownstreamPathTemplate, context.TemplatePlaceholderNameAndValues);
if (response.IsError) if (response.IsError)
{ {

View File

@ -8,11 +8,11 @@ namespace Ocelot.DownstreamUrlCreator.UrlTemplateReplacer
{ {
public class DownstreamTemplatePathPlaceholderReplacer : IDownstreamPathPlaceholderReplacer public class DownstreamTemplatePathPlaceholderReplacer : IDownstreamPathPlaceholderReplacer
{ {
public Response<DownstreamPath> Replace(PathTemplate downstreamPathTemplate, List<PlaceholderNameAndValue> urlPathPlaceholderNameAndValues) public Response<DownstreamPath> Replace(DownstreamPathTemplate downstreamDownstreamPathTemplate, List<PlaceholderNameAndValue> urlPathPlaceholderNameAndValues)
{ {
var downstreamPath = new StringBuilder(); var downstreamPath = new StringBuilder();
downstreamPath.Append(downstreamPathTemplate.Value); downstreamPath.Append(downstreamDownstreamPathTemplate.Value);
foreach (var placeholderVariableAndValue in urlPathPlaceholderNameAndValues) foreach (var placeholderVariableAndValue in urlPathPlaceholderNameAndValues)
{ {

View File

@ -7,6 +7,6 @@ namespace Ocelot.DownstreamUrlCreator.UrlTemplateReplacer
{ {
public interface IDownstreamPathPlaceholderReplacer public interface IDownstreamPathPlaceholderReplacer
{ {
Response<DownstreamPath> Replace(PathTemplate downstreamPathTemplate, List<PlaceholderNameAndValue> urlPathPlaceholderNameAndValues); Response<DownstreamPath> Replace(DownstreamPathTemplate downstreamDownstreamPathTemplate, List<PlaceholderNameAndValue> urlPathPlaceholderNameAndValues);
} }
} }

View File

@ -26,7 +26,7 @@ namespace Ocelot.Headers.Middleware
{ {
if (context.DownstreamReRoute.ClaimsToHeaders.Any()) if (context.DownstreamReRoute.ClaimsToHeaders.Any())
{ {
Logger.LogInformation($"{context.DownstreamReRoute.DownstreamPathTemplate.Value} has instructions to convert claims to headers"); Logger.LogInformation($"{context.DownstreamReRoute.DownstreamDownstreamPathTemplate.Value} has instructions to convert claims to headers");
var response = _addHeadersToRequest.SetHeadersOnDownstreamRequest(context.DownstreamReRoute.ClaimsToHeaders, context.HttpContext.User.Claims, context.DownstreamRequest); var response = _addHeadersToRequest.SetHeadersOnDownstreamRequest(context.DownstreamReRoute.ClaimsToHeaders, context.HttpContext.User.Claims, context.DownstreamRequest);

View File

@ -26,7 +26,7 @@ namespace Ocelot.QueryStrings.Middleware
{ {
if (context.DownstreamReRoute.ClaimsToQueries.Any()) if (context.DownstreamReRoute.ClaimsToQueries.Any())
{ {
Logger.LogInformation($"{context.DownstreamReRoute.DownstreamPathTemplate.Value} has instructions to convert claims to queries"); Logger.LogInformation($"{context.DownstreamReRoute.DownstreamDownstreamPathTemplate.Value} has instructions to convert claims to queries");
var response = _addQueriesToRequest.SetQueriesOnDownstreamRequest(context.DownstreamReRoute.ClaimsToQueries, context.HttpContext.User.Claims, context.DownstreamRequest); var response = _addQueriesToRequest.SetQueriesOnDownstreamRequest(context.DownstreamReRoute.ClaimsToQueries, context.HttpContext.User.Claims, context.DownstreamRequest);

View File

@ -34,7 +34,7 @@ namespace Ocelot.RateLimit.Middleware
// check if rate limiting is enabled // check if rate limiting is enabled
if (!context.DownstreamReRoute.EnableEndpointEndpointRateLimiting) if (!context.DownstreamReRoute.EnableEndpointEndpointRateLimiting)
{ {
Logger.LogInformation($"EndpointRateLimiting is not enabled for {context.DownstreamReRoute.DownstreamPathTemplate.Value}"); Logger.LogInformation($"EndpointRateLimiting is not enabled for {context.DownstreamReRoute.DownstreamDownstreamPathTemplate.Value}");
await _next.Invoke(context); await _next.Invoke(context);
return; return;
} }
@ -45,7 +45,7 @@ namespace Ocelot.RateLimit.Middleware
// check white list // check white list
if (IsWhitelisted(identity, options)) if (IsWhitelisted(identity, options))
{ {
Logger.LogInformation($"{context.DownstreamReRoute.DownstreamPathTemplate.Value} is white listed from rate limiting"); Logger.LogInformation($"{context.DownstreamReRoute.DownstreamDownstreamPathTemplate.Value} is white listed from rate limiting");
await _next.Invoke(context); await _next.Invoke(context);
return; return;
} }
@ -112,7 +112,7 @@ namespace Ocelot.RateLimit.Middleware
public virtual void LogBlockedRequest(HttpContext httpContext, ClientRequestIdentity identity, RateLimitCounter counter, RateLimitRule rule, DownstreamReRoute downstreamReRoute) public virtual void LogBlockedRequest(HttpContext httpContext, ClientRequestIdentity identity, RateLimitCounter counter, RateLimitRule rule, DownstreamReRoute downstreamReRoute)
{ {
Logger.LogInformation( Logger.LogInformation(
$"Request {identity.HttpVerb}:{identity.Path} from ClientId {identity.ClientId} has been blocked, quota {rule.Limit}/{rule.Period} exceeded by {counter.TotalRequests}. Blocked by rule { downstreamReRoute.UpstreamPathTemplate.Value }, TraceIdentifier {httpContext.TraceIdentifier}."); $"Request {identity.HttpVerb}:{identity.Path} from ClientId {identity.ClientId} has been blocked, quota {rule.Limit}/{rule.Period} exceeded by {counter.TotalRequests}. Blocked by rule { downstreamReRoute.UpstreamPathTemplate.OriginalValue }, TraceIdentifier {httpContext.TraceIdentifier}.");
} }
public virtual Task ReturnQuotaExceededResponse(HttpContext httpContext, RateLimitOptions option, string retryAfter) public virtual Task ReturnQuotaExceededResponse(HttpContext httpContext, RateLimitOptions option, string retryAfter)

View File

@ -13,7 +13,7 @@ namespace Ocelot.Requester
private readonly IDelegatingHandlerHandlerFactory _factory; private readonly IDelegatingHandlerHandlerFactory _factory;
private readonly IHttpClientCache _cacheHandlers; private readonly IHttpClientCache _cacheHandlers;
private readonly IOcelotLogger _logger; private readonly IOcelotLogger _logger;
private string _cacheKey; private DownstreamReRoute _cacheKey;
private HttpClient _httpClient; private HttpClient _httpClient;
private IHttpClient _client; private IHttpClient _client;
private readonly TimeSpan _defaultTimeout; private readonly TimeSpan _defaultTimeout;
@ -34,7 +34,7 @@ namespace Ocelot.Requester
public IHttpClient Create(DownstreamContext context) public IHttpClient Create(DownstreamContext context)
{ {
_cacheKey = GetCacheKey(context); _cacheKey = context.DownstreamReRoute;
var httpClient = _cacheHandlers.Get(_cacheKey); var httpClient = _cacheHandlers.Get(_cacheKey);
@ -51,7 +51,7 @@ namespace Ocelot.Requester
handler.ServerCertificateCustomValidationCallback = (request, certificate, chain, errors) => true; handler.ServerCertificateCustomValidationCallback = (request, certificate, chain, errors) => true;
_logger _logger
.LogWarning($"You have ignored all SSL warnings by using DangerousAcceptAnyServerCertificateValidator for this DownstreamReRoute, UpstreamPathTemplate: {context.DownstreamReRoute.UpstreamPathTemplate}, DownstreamPathTemplate: {context.DownstreamReRoute.DownstreamPathTemplate}"); .LogWarning($"You have ignored all SSL warnings by using DangerousAcceptAnyServerCertificateValidator for this DownstreamReRoute, UpstreamPathTemplate: {context.DownstreamReRoute.UpstreamPathTemplate}, DownstreamDownstreamPathTemplate: {context.DownstreamReRoute.DownstreamDownstreamPathTemplate}");
} }
var timeout = context.DownstreamReRoute.QosOptions.TimeoutValue == 0 var timeout = context.DownstreamReRoute.QosOptions.TimeoutValue == 0
@ -127,14 +127,5 @@ namespace Ocelot.Requester
}); });
return httpMessageHandler; return httpMessageHandler;
} }
private string GetCacheKey(DownstreamContext request)
{
var cacheKey = $"{request.DownstreamRequest.Method}:{request.DownstreamRequest.OriginalString}";
_logger.LogDebug($"Cache key for request is {cacheKey}");
return cacheKey;
}
} }
} }

View File

@ -1,10 +1,11 @@
namespace Ocelot.Requester namespace Ocelot.Requester
{ {
using System; using System;
using Configuration;
public interface IHttpClientCache public interface IHttpClientCache
{ {
IHttpClient Get(string key); IHttpClient Get(DownstreamReRoute key);
void Set(string key, IHttpClient handler, TimeSpan expirationTime); void Set(DownstreamReRoute key, IHttpClient handler, TimeSpan expirationTime);
} }
} }

View File

@ -2,22 +2,23 @@
{ {
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using Configuration;
public class MemoryHttpClientCache : IHttpClientCache public class MemoryHttpClientCache : IHttpClientCache
{ {
private readonly ConcurrentDictionary<string, IHttpClient> _httpClientsCache; private readonly ConcurrentDictionary<DownstreamReRoute, IHttpClient> _httpClientsCache;
public MemoryHttpClientCache() public MemoryHttpClientCache()
{ {
_httpClientsCache = new ConcurrentDictionary<string, IHttpClient>(); _httpClientsCache = new ConcurrentDictionary<DownstreamReRoute, IHttpClient>();
} }
public void Set(string key, IHttpClient client, TimeSpan expirationTime) public void Set(DownstreamReRoute key, IHttpClient client, TimeSpan expirationTime)
{ {
_httpClientsCache.AddOrUpdate(key, client, (k, oldValue) => client); _httpClientsCache.AddOrUpdate(key, client, (k, oldValue) => client);
} }
public IHttpClient Get(string key) public IHttpClient Get(DownstreamReRoute key)
{ {
//todo handle error? //todo handle error?
return _httpClientsCache.TryGetValue(key, out var client) ? client : null; return _httpClientsCache.TryGetValue(key, out var client) ? client : null;

View File

@ -27,7 +27,7 @@ namespace Ocelot.Requester.QoS
return new OkResponse<DelegatingHandler>(handler(request, _ocelotLoggerFactory)); return new OkResponse<DelegatingHandler>(handler(request, _ocelotLoggerFactory));
} }
return new ErrorResponse<DelegatingHandler>(new UnableToFindQoSProviderError($"could not find qosProvider for {request.DownstreamScheme}{request.DownstreamAddresses}{request.DownstreamPathTemplate}")); return new ErrorResponse<DelegatingHandler>(new UnableToFindQoSProviderError($"could not find qosProvider for {request.DownstreamScheme}{request.DownstreamAddresses}{request.DownstreamDownstreamPathTemplate}"));
} }
} }
} }

View File

@ -1,8 +1,8 @@
namespace Ocelot.Values namespace Ocelot.Values
{ {
public class PathTemplate public class DownstreamPathTemplate
{ {
public PathTemplate(string value) public DownstreamPathTemplate(string value)
{ {
Value = value; Value = value;
} }

View File

@ -2,16 +2,20 @@ namespace Ocelot.Values
{ {
public class UpstreamPathTemplate public class UpstreamPathTemplate
{ {
public UpstreamPathTemplate(string template, int priority, bool containsQueryString) public UpstreamPathTemplate(string template, int priority, bool containsQueryString, string originalValue)
{ {
Template = template; Template = template;
Priority = priority; Priority = priority;
ContainsQueryString = containsQueryString; ContainsQueryString = containsQueryString;
OriginalValue = originalValue;
} }
public string Template { get; } public string Template { get; }
public int Priority { get; } public int Priority { get; }
public bool ContainsQueryString { get; } public bool ContainsQueryString { get; }
public string OriginalValue { get; }
} }
} }

View File

@ -0,0 +1,163 @@
namespace Ocelot.AcceptanceTests
{
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Net;
using Configuration;
using Microsoft.AspNetCore.Http;
using Ocelot.Configuration.File;
using Requester;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
public class HttpClientCachingTests : IDisposable
{
private readonly Steps _steps;
private string _downstreamPath;
private readonly ServiceHandler _serviceHandler;
public HttpClientCachingTests()
{
_serviceHandler = new ServiceHandler();
_steps = new Steps();
}
[Fact]
public void should_cache_one_http_client_same_re_route()
{
var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/",
DownstreamScheme = "http",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 51879,
}
},
UpstreamPathTemplate = "/",
UpstreamHttpMethod = new List<string> { "Get" },
}
}
};
var cache = new FakeHttpClientCache();
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", 200, "Hello from Laura"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunningWithFakeHttpClientCache(cache))
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
.And(x => cache.Count.ShouldBe(1))
.BDDfy();
}
[Fact]
public void should_cache_two_http_client_different_re_route()
{
var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/",
DownstreamScheme = "http",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 51879,
}
},
UpstreamPathTemplate = "/",
UpstreamHttpMethod = new List<string> { "Get" },
},
new FileReRoute
{
DownstreamPathTemplate = "/two",
DownstreamScheme = "http",
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 51879,
}
},
UpstreamPathTemplate = "/two",
UpstreamHttpMethod = new List<string> { "Get" },
}
}
};
var cache = new FakeHttpClientCache();
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", 200, "Hello from Laura"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunningWithFakeHttpClientCache(cache))
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/two"))
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/two"))
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/two"))
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
.And(x => cache.Count.ShouldBe(2))
.BDDfy();
}
private void GivenThereIsAServiceRunningOn(string baseUrl, int statusCode, string responseBody)
{
_serviceHandler.GivenThereIsAServiceRunningOn(baseUrl, async context =>
{
context.Response.StatusCode = statusCode;
await context.Response.WriteAsync(responseBody);
});
}
public void Dispose()
{
_serviceHandler.Dispose();
_steps.Dispose();
}
public class FakeHttpClientCache : IHttpClientCache
{
private readonly ConcurrentDictionary<DownstreamReRoute, IHttpClient> _httpClientsCache;
public FakeHttpClientCache()
{
_httpClientsCache = new ConcurrentDictionary<DownstreamReRoute, IHttpClient>();
}
public void Set(DownstreamReRoute key, IHttpClient client, TimeSpan expirationTime)
{
_httpClientsCache.AddOrUpdate(key, client, (k, oldValue) => client);
}
public IHttpClient Get(DownstreamReRoute key)
{
//todo handle error?
return _httpClientsCache.TryGetValue(key, out var client) ? client : null;
}
public int Count => _httpClientsCache.Count;
}
}
}

View File

@ -29,6 +29,7 @@
using static Ocelot.Infrastructure.Wait; using static Ocelot.Infrastructure.Wait;
using Configuration.Repository; using Configuration.Repository;
using Ocelot.Configuration.Creator; using Ocelot.Configuration.Creator;
using Requester;
using CookieHeaderValue = System.Net.Http.Headers.CookieHeaderValue; using CookieHeaderValue = System.Net.Http.Headers.CookieHeaderValue;
using MediaTypeHeaderValue = System.Net.Http.Headers.MediaTypeHeaderValue; using MediaTypeHeaderValue = System.Net.Http.Headers.MediaTypeHeaderValue;
@ -182,6 +183,35 @@
_ocelotClient = _ocelotServer.CreateClient(); _ocelotClient = _ocelotServer.CreateClient();
} }
public void GivenOcelotIsRunningWithFakeHttpClientCache(IHttpClientCache cache)
{
_webHostBuilder = new WebHostBuilder();
_webHostBuilder
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
var env = hostingContext.HostingEnvironment;
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
config.AddJsonFile("ocelot.json", false, false);
config.AddEnvironmentVariables();
})
.ConfigureServices(s =>
{
s.AddSingleton<IHttpClientCache>(cache);
s.AddOcelot();
})
.Configure(app =>
{
app.UseOcelot().Wait();
});
_ocelotServer = new TestServer(_webHostBuilder);
_ocelotClient = _ocelotServer.CreateClient();
}
internal void GivenIWait(int wait) internal void GivenIWait(int wait)
{ {
Thread.Sleep(wait); Thread.Sleep(wait);

View File

@ -0,0 +1,77 @@
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Columns;
using BenchmarkDotNet.Configs;
using System.Net.Http;
using BenchmarkDotNet.Diagnosers;
using BenchmarkDotNet.Validators;
namespace Ocelot.Benchmarks
{
using System.Collections.Concurrent;
using Configuration;
using Configuration.Builder;
using Requester;
[Config(typeof(DictionaryBenchmarks))]
public class DictionaryBenchmarks : ManualConfig
{
private ConcurrentDictionary<DownstreamReRoute, IHttpClient> _downstreamReRouteDictionary;
private ConcurrentDictionary<string, IHttpClient> _stringReRouteDictionary;
private HttpClientWrapper _client;
private string _stringKey;
private DownstreamReRoute _downstreamReRouteKey;
public DictionaryBenchmarks()
{
Add(StatisticColumn.AllStatistics);
Add(MemoryDiagnoser.Default);
Add(BaselineValidator.FailOnError);
}
[GlobalSetup]
public void SetUp()
{
_downstreamReRouteKey = new DownstreamReRouteBuilder().Build();
_stringKey = "test";
_client = new HttpClientWrapper(new HttpClient());
_downstreamReRouteDictionary = new ConcurrentDictionary<DownstreamReRoute, IHttpClient>();
_downstreamReRouteDictionary.TryAdd(new DownstreamReRouteBuilder().Build(), new HttpClientWrapper(new HttpClient()));
_downstreamReRouteDictionary.TryAdd(new DownstreamReRouteBuilder().Build(), new HttpClientWrapper(new HttpClient()));
_downstreamReRouteDictionary.TryAdd(new DownstreamReRouteBuilder().Build(), new HttpClientWrapper(new HttpClient()));
_downstreamReRouteDictionary.TryAdd(new DownstreamReRouteBuilder().Build(), new HttpClientWrapper(new HttpClient()));
_downstreamReRouteDictionary.TryAdd(new DownstreamReRouteBuilder().Build(), new HttpClientWrapper(new HttpClient()));
_downstreamReRouteDictionary.TryAdd(new DownstreamReRouteBuilder().Build(), new HttpClientWrapper(new HttpClient()));
_downstreamReRouteDictionary.TryAdd(new DownstreamReRouteBuilder().Build(), new HttpClientWrapper(new HttpClient()));
_downstreamReRouteDictionary.TryAdd(new DownstreamReRouteBuilder().Build(), new HttpClientWrapper(new HttpClient()));
_downstreamReRouteDictionary.TryAdd(new DownstreamReRouteBuilder().Build(), new HttpClientWrapper(new HttpClient()));
_downstreamReRouteDictionary.TryAdd(new DownstreamReRouteBuilder().Build(), new HttpClientWrapper(new HttpClient()));
_stringReRouteDictionary = new ConcurrentDictionary<string, IHttpClient>();
_stringReRouteDictionary.TryAdd("1", new HttpClientWrapper(new HttpClient()));
_stringReRouteDictionary.TryAdd("2", new HttpClientWrapper(new HttpClient()));
_stringReRouteDictionary.TryAdd("3", new HttpClientWrapper(new HttpClient()));
_stringReRouteDictionary.TryAdd("4", new HttpClientWrapper(new HttpClient()));
_stringReRouteDictionary.TryAdd("5", new HttpClientWrapper(new HttpClient()));
_stringReRouteDictionary.TryAdd("6", new HttpClientWrapper(new HttpClient()));
_stringReRouteDictionary.TryAdd("7", new HttpClientWrapper(new HttpClient()));
_stringReRouteDictionary.TryAdd("8", new HttpClientWrapper(new HttpClient()));
_stringReRouteDictionary.TryAdd("9", new HttpClientWrapper(new HttpClient()));
_stringReRouteDictionary.TryAdd("10", new HttpClientWrapper(new HttpClient()));
}
[Benchmark(Baseline = true)]
public IHttpClient StringKey()
{
_stringReRouteDictionary.AddOrUpdate(_stringKey, _client, (k, oldValue) => _client);
return _stringReRouteDictionary.TryGetValue(_stringKey, out var client) ? client : null;
}
[Benchmark]
public IHttpClient DownstreamReRouteKey()
{
_downstreamReRouteDictionary.AddOrUpdate(_downstreamReRouteKey, _client, (k, oldValue) => _client);
return _downstreamReRouteDictionary.TryGetValue(_downstreamReRouteKey, out var client) ? client : null;
}
}
}

View File

@ -7,6 +7,7 @@ namespace Ocelot.Benchmarks
public static void Main(string[] args) public static void Main(string[] args)
{ {
var switcher = new BenchmarkSwitcher(new[] { var switcher = new BenchmarkSwitcher(new[] {
typeof(DictionaryBenchmarks),
typeof(UrlPathToUrlPathTemplateMatcherBenchmarks), typeof(UrlPathToUrlPathTemplateMatcherBenchmarks),
typeof(AllTheThingsBenchmarks), typeof(AllTheThingsBenchmarks),
typeof(ExceptionHandlerMiddlewareBenchmarks) typeof(ExceptionHandlerMiddlewareBenchmarks)

View File

@ -16,6 +16,7 @@ namespace Ocelot.UnitTests.Authorization
using Xunit; using Xunit;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Ocelot.Configuration; using Ocelot.Configuration;
using Values;
public class AuthorisationMiddlewareTests public class AuthorisationMiddlewareTests
{ {
@ -44,6 +45,7 @@ namespace Ocelot.UnitTests.Authorization
{ {
this.Given(x => x.GivenTheDownStreamRouteIs(new List<PlaceholderNameAndValue>(), this.Given(x => x.GivenTheDownStreamRouteIs(new List<PlaceholderNameAndValue>(),
new DownstreamReRouteBuilder() new DownstreamReRouteBuilder()
.WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().Build())
.WithIsAuthorised(true) .WithIsAuthorised(true)
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.Build())) .Build()))

View File

@ -13,7 +13,6 @@
using Shouldly; using Shouldly;
using TestStack.BDDfy; using TestStack.BDDfy;
using Xunit; using Xunit;
using Ocelot.DependencyInjection;
using Ocelot.Errors; using Ocelot.Errors;
using Ocelot.UnitTests.TestData; using Ocelot.UnitTests.TestData;
using Ocelot.Values; using Ocelot.Values;
@ -83,9 +82,9 @@
.Build(); .Build();
var downstreamReRoute = new DownstreamReRouteBuilder() var downstreamReRoute = new DownstreamReRouteBuilder()
.WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithTemplate("woop").WithOriginalValue("/api/products/{productId}").Build())
.WithDownstreamAddresses(new List<DownstreamHostAndPort>() { new DownstreamHostAndPort("127.0.0.1", 80) }) .WithDownstreamAddresses(new List<DownstreamHostAndPort>() { new DownstreamHostAndPort("127.0.0.1", 80) })
.WithDownstreamPathTemplate("/products/{productId}") .WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithLoadBalancerKey("CookieStickySessions:sessionid") .WithLoadBalancerKey("CookieStickySessions:sessionid")
.Build(); .Build();
@ -116,6 +115,7 @@
}, },
})) }))
.And(x => x.GivenTheConfigIsValid()) .And(x => x.GivenTheConfigIsValid())
.And(x => GivenTheUpstreamTemplatePatternCreatorReturns("woop", "/api/products/{productId}"))
.And(x => GivenTheDownstreamAddresses()) .And(x => GivenTheDownstreamAddresses())
.And(x => GivenTheHeaderFindAndReplaceCreatorReturns()) .And(x => GivenTheHeaderFindAndReplaceCreatorReturns())
.And(x => x.GivenTheFollowingOptionsAreReturned(reRouteOptions)) .And(x => x.GivenTheFollowingOptionsAreReturned(reRouteOptions))
@ -124,7 +124,7 @@
{ {
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamReRoute(downstreamReRoute) .WithDownstreamReRoute(downstreamReRoute)
.WithUpstreamPathTemplate("/api/products/{productId}") .WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithTemplate("woop").WithOriginalValue("/api/products/{productId}").Build())
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.Build() .Build()
})) }))
@ -206,7 +206,7 @@
var lauraReRoute = new ReRouteBuilder() var lauraReRoute = new ReRouteBuilder()
.WithUpstreamHttpMethod(new List<string>() { "Get" }) .WithUpstreamHttpMethod(new List<string>() { "Get" })
.WithUpstreamHost("localhost") .WithUpstreamHost("localhost")
.WithUpstreamPathTemplate("/laura") .WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithTemplate("woop").WithOriginalValue("/laura").Build())
.WithDownstreamReRoute(lauraDownstreamReRoute) .WithDownstreamReRoute(lauraDownstreamReRoute)
.Build(); .Build();
@ -225,14 +225,14 @@
var tomReRoute = new ReRouteBuilder() var tomReRoute = new ReRouteBuilder()
.WithUpstreamHttpMethod(new List<string>() { "Get" }) .WithUpstreamHttpMethod(new List<string>() { "Get" })
.WithUpstreamHost("localhost") .WithUpstreamHost("localhost")
.WithUpstreamPathTemplate("/tom") .WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithTemplate("woop").WithOriginalValue("/tom").Build())
.WithDownstreamReRoute(tomDownstreamReRoute) .WithDownstreamReRoute(tomDownstreamReRoute)
.Build(); .Build();
expected.Add(tomReRoute); expected.Add(tomReRoute);
var aggregateReReRoute = new ReRouteBuilder() var aggregateReReRoute = new ReRouteBuilder()
.WithUpstreamPathTemplate("/") .WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithTemplate("woop").WithOriginalValue("/").Build())
.WithUpstreamHost("localhost") .WithUpstreamHost("localhost")
.WithDownstreamReRoute(lauraDownstreamReRoute) .WithDownstreamReRoute(lauraDownstreamReRoute)
.WithDownstreamReRoute(tomDownstreamReRoute) .WithDownstreamReRoute(tomDownstreamReRoute)
@ -241,7 +241,18 @@
expected.Add(aggregateReReRoute); expected.Add(aggregateReReRoute);
var tupleList = new List<(string, string)>
{
("woop", "/laura"),
("woop", "/laura"),
("woop", "/tom"),
("woop", "/tom"),
("woop", "/"),
("woop", "/")
};
this.Given(x => x.GivenTheConfigIs(configuration)) this.Given(x => x.GivenTheConfigIs(configuration))
.And(x => GivenTheUpstreamTemplatePatternCreatorReturns(tupleList.ToArray()))
.And(x => x.GivenTheFollowingOptionsAreReturned(new ReRouteOptionsBuilder().Build())) .And(x => x.GivenTheFollowingOptionsAreReturned(new ReRouteOptionsBuilder().Build()))
.And(x => x.GivenTheFollowingIsReturned(serviceProviderConfig)) .And(x => x.GivenTheFollowingIsReturned(serviceProviderConfig))
.And(x => GivenTheDownstreamAddresses()) .And(x => GivenTheDownstreamAddresses())
@ -249,7 +260,7 @@
.And(x => x.GivenTheConfigIsValid()) .And(x => x.GivenTheConfigIsValid())
.When(x => x.WhenICreateTheConfig()) .When(x => x.WhenICreateTheConfig())
.Then(x => x.ThenTheServiceProviderCreatorIsCalledCorrectly()) .Then(x => x.ThenTheServiceProviderCreatorIsCalledCorrectly())
.Then(x => x.ThenTheReRoutesAre(expected)) .Then(x => x.ThenTheAggregateReRoutesAre(expected))
.BDDfy(); .BDDfy();
} }
@ -406,9 +417,9 @@
.Build(); .Build();
var downstreamReRoute = new DownstreamReRouteBuilder() var downstreamReRoute = new DownstreamReRouteBuilder()
.WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithTemplate("woop").WithOriginalValue("/api/products/{productId}").Build())
.WithDownstreamAddresses(new List<DownstreamHostAndPort>() {new DownstreamHostAndPort("127.0.0.1", 80)}) .WithDownstreamAddresses(new List<DownstreamHostAndPort>() {new DownstreamHostAndPort("127.0.0.1", 80)})
.WithDownstreamPathTemplate("/products/{productId}") .WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod(new List<string> {"Get"}) .WithUpstreamHttpMethod(new List<string> {"Get"})
.WithLoadBalancerKey("/api/products/{productId}|Get|127.0.0.1:0") .WithLoadBalancerKey("/api/products/{productId}|Get|127.0.0.1:0")
.Build(); .Build();
@ -433,6 +444,7 @@
}, },
})) }))
.And(x => x.GivenTheConfigIsValid()) .And(x => x.GivenTheConfigIsValid())
.And(x => GivenTheUpstreamTemplatePatternCreatorReturns("woop", "/api/products/{productId}"))
.And(x => GivenTheDownstreamAddresses()) .And(x => GivenTheDownstreamAddresses())
.And(x => GivenTheHeaderFindAndReplaceCreatorReturns()) .And(x => GivenTheHeaderFindAndReplaceCreatorReturns())
.And(x => x.GivenTheFollowingOptionsAreReturned(reRouteOptions)) .And(x => x.GivenTheFollowingOptionsAreReturned(reRouteOptions))
@ -441,7 +453,7 @@
{ {
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamReRoute(downstreamReRoute) .WithDownstreamReRoute(downstreamReRoute)
.WithUpstreamPathTemplate("/api/products/{productId}") .WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithTemplate("woop").WithOriginalValue("/api/products/{productId}").Build())
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.Build() .Build()
})) }))
@ -459,7 +471,7 @@
var downstreamReRoute = new DownstreamReRouteBuilder() var downstreamReRoute = new DownstreamReRouteBuilder()
.WithDownstreamScheme("https") .WithDownstreamScheme("https")
.WithDownstreamPathTemplate("/products/{productId}") .WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}") .WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithTemplate("woop").WithOriginalValue("/api/products/{productId}").Build())
.WithUpstreamHttpMethod(new List<string> {"Get"}) .WithUpstreamHttpMethod(new List<string> {"Get"})
.WithDelegatingHandlers(handlers) .WithDelegatingHandlers(handlers)
.WithLoadBalancerKey("/api/products/{productId}|Get|") .WithLoadBalancerKey("/api/products/{productId}|Get|")
@ -480,6 +492,7 @@
}, },
})) }))
.And(x => x.GivenTheConfigIsValid()) .And(x => x.GivenTheConfigIsValid())
.And(x => GivenTheUpstreamTemplatePatternCreatorReturns("woop", "/api/products/{productId}"))
.And(x => GivenTheDownstreamAddresses()) .And(x => GivenTheDownstreamAddresses())
.And(x => GivenTheHeaderFindAndReplaceCreatorReturns()) .And(x => GivenTheHeaderFindAndReplaceCreatorReturns())
.And(x => x.GivenTheFollowingOptionsAreReturned(reRouteOptions)) .And(x => x.GivenTheFollowingOptionsAreReturned(reRouteOptions))
@ -488,7 +501,7 @@
{ {
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamReRoute(downstreamReRoute) .WithDownstreamReRoute(downstreamReRoute)
.WithUpstreamPathTemplate("/api/products/{productId}") .WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithTemplate("woop").WithOriginalValue("/api/products/{productId}").Build())
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.Build() .Build()
})) }))
@ -503,7 +516,7 @@
var downstreamReRoute = new DownstreamReRouteBuilder() var downstreamReRoute = new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("/products/{productId}") .WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}") .WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithTemplate("woop").WithOriginalValue("/api/products/{productId}").Build())
.WithUpstreamHttpMethod(new List<string> {"Get"}) .WithUpstreamHttpMethod(new List<string> {"Get"})
.WithUseServiceDiscovery(true) .WithUseServiceDiscovery(true)
.WithServiceName("ProductService") .WithServiceName("ProductService")
@ -532,6 +545,7 @@
} }
})) }))
.And(x => x.GivenTheConfigIsValid()) .And(x => x.GivenTheConfigIsValid())
.And(x => GivenTheUpstreamTemplatePatternCreatorReturns("woop", "/api/products/{productId}"))
.And(x => GivenTheDownstreamAddresses()) .And(x => GivenTheDownstreamAddresses())
.And(x => GivenTheHeaderFindAndReplaceCreatorReturns()) .And(x => GivenTheHeaderFindAndReplaceCreatorReturns())
.And(x => x.GivenTheFollowingOptionsAreReturned(reRouteOptions)) .And(x => x.GivenTheFollowingOptionsAreReturned(reRouteOptions))
@ -540,7 +554,7 @@
{ {
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamReRoute(downstreamReRoute) .WithDownstreamReRoute(downstreamReRoute)
.WithUpstreamPathTemplate("/api/products/{productId}") .WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithTemplate("woop").WithOriginalValue("/api/products/{productId}").Build())
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.Build() .Build()
})) }))
@ -555,7 +569,7 @@
var downstreamReRoute = new DownstreamReRouteBuilder() var downstreamReRoute = new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("/products/{productId}") .WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}") .WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithTemplate("woop").WithOriginalValue("/api/products/{productId}").Build())
.WithUpstreamHttpMethod(new List<string> {"Get"}) .WithUpstreamHttpMethod(new List<string> {"Get"})
.WithUseServiceDiscovery(false) .WithUseServiceDiscovery(false)
.WithLoadBalancerKey("/api/products/{productId}|Get|") .WithLoadBalancerKey("/api/products/{productId}|Get|")
@ -575,6 +589,7 @@
} }
})) }))
.And(x => x.GivenTheConfigIsValid()) .And(x => x.GivenTheConfigIsValid())
.And(x => GivenTheUpstreamTemplatePatternCreatorReturns("woop", "/api/products/{productId}"))
.And(x => GivenTheDownstreamAddresses()) .And(x => GivenTheDownstreamAddresses())
.And(x => GivenTheHeaderFindAndReplaceCreatorReturns()) .And(x => GivenTheHeaderFindAndReplaceCreatorReturns())
.And(x => x.GivenTheFollowingOptionsAreReturned(reRouteOptions)) .And(x => x.GivenTheFollowingOptionsAreReturned(reRouteOptions))
@ -583,7 +598,7 @@
{ {
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamReRoute(downstreamReRoute) .WithDownstreamReRoute(downstreamReRoute)
.WithUpstreamPathTemplate("/api/products/{productId}") .WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithTemplate("woop").WithOriginalValue("/api/products/{productId}").Build())
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.Build() .Build()
})) }))
@ -598,9 +613,9 @@
var downstreamReRoute = new DownstreamReRouteBuilder() var downstreamReRoute = new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("/products/{productId}") .WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}") .WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithOriginalValue("/api/products/{productId}").Build())
.WithUpstreamHttpMethod(new List<string> {"Get"}) .WithUpstreamHttpMethod(new List<string> {"Get"})
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("(?i)/api/products/.*/$", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("(?i)/api/products/.*/$", 1, false, "/api/products/{productId}"))
.WithLoadBalancerKey("/api/products/{productId}|Get|") .WithLoadBalancerKey("/api/products/{productId}|Get|")
.Build(); .Build();
@ -621,15 +636,15 @@
.And(x => GivenTheDownstreamAddresses()) .And(x => GivenTheDownstreamAddresses())
.And(x => GivenTheHeaderFindAndReplaceCreatorReturns()) .And(x => GivenTheHeaderFindAndReplaceCreatorReturns())
.And(x => x.GivenTheFollowingOptionsAreReturned(reRouteOptions)) .And(x => x.GivenTheFollowingOptionsAreReturned(reRouteOptions))
.And(x => x.GivenTheUpstreamTemplatePatternCreatorReturns("(?i)/api/products/.*/$")) .And(x => x.GivenTheUpstreamTemplatePatternCreatorReturns("(?i)/api/products/.*/$", "/api/products/{productId}"))
.When(x => x.WhenICreateTheConfig()) .When(x => x.WhenICreateTheConfig())
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute> .Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
{ {
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamReRoute(downstreamReRoute) .WithDownstreamReRoute(downstreamReRoute)
.WithUpstreamPathTemplate("/api/products/{productId}") .WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithOriginalValue("/api/products/{productId}").Build())
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("(?i)/api/products/.*/$", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("(?i)/api/products/.*/$", 1, false, "/api/products/{productId}"))
.Build() .Build()
})) }))
.BDDfy(); .BDDfy();
@ -643,7 +658,7 @@
var downstreamReRoute = new DownstreamReRouteBuilder() var downstreamReRoute = new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("/products/{productId}") .WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}") .WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithTemplate("woop").WithOriginalValue("/api/products/{productId}").Build())
.WithUpstreamHttpMethod(new List<string> {"Get"}) .WithUpstreamHttpMethod(new List<string> {"Get"})
.WithRequestIdKey("blahhhh") .WithRequestIdKey("blahhhh")
.WithLoadBalancerKey("/api/products/{productId}|Get|") .WithLoadBalancerKey("/api/products/{productId}|Get|")
@ -667,6 +682,7 @@
} }
})) }))
.And(x => x.GivenTheConfigIsValid()) .And(x => x.GivenTheConfigIsValid())
.And(x => GivenTheUpstreamTemplatePatternCreatorReturns("woop", "/api/products/{productId}"))
.And(x => GivenTheDownstreamAddresses()) .And(x => GivenTheDownstreamAddresses())
.And(x => GivenTheHeaderFindAndReplaceCreatorReturns()) .And(x => GivenTheHeaderFindAndReplaceCreatorReturns())
.And(x => x.GivenTheFollowingOptionsAreReturned(reRouteOptions)) .And(x => x.GivenTheFollowingOptionsAreReturned(reRouteOptions))
@ -676,7 +692,7 @@
{ {
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamReRoute(downstreamReRoute) .WithDownstreamReRoute(downstreamReRoute)
.WithUpstreamPathTemplate("/api/products/{productId}") .WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithTemplate("woop").WithOriginalValue("/api/products/{productId}").Build())
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.Build() .Build()
})) }))
@ -734,7 +750,7 @@
var downstreamReRoute = new DownstreamReRouteBuilder() var downstreamReRoute = new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("/products/{productId}") .WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}") .WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithTemplate("woop").WithOriginalValue("/api/products/{productId}").Build())
.WithUpstreamHttpMethod(new List<string> {"Get"}) .WithUpstreamHttpMethod(new List<string> {"Get"})
.WithAuthenticationOptions(authenticationOptions) .WithAuthenticationOptions(authenticationOptions)
.WithClaimsToHeaders(new List<ClaimToThing> .WithClaimsToHeaders(new List<ClaimToThing>
@ -748,12 +764,13 @@
{ {
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamReRoute(downstreamReRoute) .WithDownstreamReRoute(downstreamReRoute)
.WithUpstreamPathTemplate("/api/products/{productId}") .WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithTemplate("woop").WithOriginalValue("/api/products/{productId}").Build())
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.Build() .Build()
}; };
this.Given(x => x.GivenTheConfigIs(fileConfig)) this.Given(x => x.GivenTheConfigIs(fileConfig))
.And(x => GivenTheUpstreamTemplatePatternCreatorReturns("woop", "/api/products/{productId}"))
.And(x => GivenTheDownstreamAddresses()) .And(x => GivenTheDownstreamAddresses())
.And(x => x.GivenTheConfigIsValid()) .And(x => x.GivenTheConfigIsValid())
.And(x => GivenTheHeaderFindAndReplaceCreatorReturns()) .And(x => GivenTheHeaderFindAndReplaceCreatorReturns())
@ -781,7 +798,7 @@
var downstreamReRoute = new DownstreamReRouteBuilder() var downstreamReRoute = new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("/products/{productId}") .WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}") .WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithTemplate("woop").WithOriginalValue("/api/products/{productId}").Build())
.WithUpstreamHttpMethod(new List<string> {"Get"}) .WithUpstreamHttpMethod(new List<string> {"Get"})
.WithAuthenticationOptions(authenticationOptions) .WithAuthenticationOptions(authenticationOptions)
.WithLoadBalancerKey("/api/products/{productId}|Get|") .WithLoadBalancerKey("/api/products/{productId}|Get|")
@ -791,12 +808,13 @@
{ {
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamReRoute(downstreamReRoute) .WithDownstreamReRoute(downstreamReRoute)
.WithUpstreamPathTemplate("/api/products/{productId}") .WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithTemplate("woop").WithOriginalValue("/api/products/{productId}").Build())
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.Build() .Build()
}; };
this.Given(x => x.GivenTheConfigIs(fileConfig)) this.Given(x => x.GivenTheConfigIs(fileConfig))
.And(x => GivenTheUpstreamTemplatePatternCreatorReturns("woop", "/api/products/{productId}"))
.And(x => GivenTheDownstreamAddresses()) .And(x => GivenTheDownstreamAddresses())
.And(x => x.GivenTheConfigIsValid()) .And(x => x.GivenTheConfigIsValid())
.And(x => GivenTheHeaderFindAndReplaceCreatorReturns()) .And(x => GivenTheHeaderFindAndReplaceCreatorReturns())
@ -828,11 +846,6 @@
var reRouteOptions = new ReRouteOptionsBuilder() var reRouteOptions = new ReRouteOptionsBuilder()
.Build(); .Build();
var downstreamReRoute = new DownstreamReRouteBuilder()
.WithEnableRateLimiting(true)
.WithRateLimitOptions(new RateLimitOptionsBuilder().Build())
.Build();
var rateLimitOptions = new RateLimitOptionsBuilder() var rateLimitOptions = new RateLimitOptionsBuilder()
.WithRateLimitRule(new RateLimitRule("1s", 1, 1)) .WithRateLimitRule(new RateLimitRule("1s", 1, 1))
.Build(); .Build();
@ -923,6 +936,31 @@
dynamic.RateLimitOptions.RateLimitRule.PeriodTimespan.ShouldBe(rateLimitOptions.PeriodTimespan); dynamic.RateLimitOptions.RateLimitRule.PeriodTimespan.ShouldBe(rateLimitOptions.PeriodTimespan);
} }
private void ThenTheAggregateReRoutesAre(List<ReRoute> expectedReRoutes)
{
for (int i = 0; i < _config.Data.ReRoutes.Count; i++)
{
var result = _config.Data.ReRoutes[i];
var expected = expectedReRoutes[i];
result.DownstreamReRoute.Count.ShouldBe(expected.DownstreamReRoute.Count);
result.UpstreamHttpMethod.ShouldBe(expected.UpstreamHttpMethod);
result.UpstreamTemplatePattern.OriginalValue.ShouldBe(expected.UpstreamTemplatePattern.OriginalValue);
result.UpstreamTemplatePattern.Template.ShouldBe(expected.UpstreamTemplatePattern.Template);
result.DownstreamReRoute[0].DownstreamDownstreamPathTemplate.Value.ShouldBe(expected.DownstreamReRoute[0].DownstreamDownstreamPathTemplate.Value);
result.DownstreamReRoute[0].ClaimsToClaims.Count.ShouldBe(expected.DownstreamReRoute[0].ClaimsToClaims.Count);
result.DownstreamReRoute[0].ClaimsToHeaders.Count.ShouldBe(expected.DownstreamReRoute[0].ClaimsToHeaders.Count);
result.DownstreamReRoute[0].ClaimsToQueries.Count.ShouldBe(expected.DownstreamReRoute[0].ClaimsToQueries.Count);
result.DownstreamReRoute[0].RequestIdKey.ShouldBe(expected.DownstreamReRoute[0].RequestIdKey);
result.DownstreamReRoute[0].LoadBalancerKey.ShouldBe(expected.DownstreamReRoute[0].LoadBalancerKey);
result.DownstreamReRoute[0].DelegatingHandlers.ShouldBe(expected.DownstreamReRoute[0].DelegatingHandlers);
result.DownstreamReRoute[0].AddHeadersToDownstream.ShouldBe(expected.DownstreamReRoute[0].AddHeadersToDownstream);
result.DownstreamReRoute[0].AddHeadersToUpstream.ShouldBe(expected.DownstreamReRoute[0].AddHeadersToUpstream, "AddHeadersToUpstream should be set");
}
}
private void ThenTheReRoutesAre(List<ReRoute> expectedReRoutes) private void ThenTheReRoutesAre(List<ReRoute> expectedReRoutes)
{ {
for (int i = 0; i < _config.Data.ReRoutes.Count; i++) for (int i = 0; i < _config.Data.ReRoutes.Count; i++)
@ -932,10 +970,11 @@
result.DownstreamReRoute.Count.ShouldBe(expected.DownstreamReRoute.Count); result.DownstreamReRoute.Count.ShouldBe(expected.DownstreamReRoute.Count);
result.DownstreamReRoute[0].DownstreamPathTemplate.Value.ShouldBe(expected.DownstreamReRoute[0].DownstreamPathTemplate.Value);
result.UpstreamHttpMethod.ShouldBe(expected.UpstreamHttpMethod); result.UpstreamHttpMethod.ShouldBe(expected.UpstreamHttpMethod);
result.UpstreamPathTemplate.Value.ShouldBe(expected.UpstreamPathTemplate.Value); result.UpstreamTemplatePattern.OriginalValue.ShouldBe(expected.UpstreamTemplatePattern.OriginalValue);
result.UpstreamTemplatePattern?.Template.ShouldBe(expected.UpstreamTemplatePattern?.Template); result.UpstreamTemplatePattern.Template.ShouldBe(expected.UpstreamTemplatePattern.Template);
result.DownstreamReRoute[0].DownstreamDownstreamPathTemplate.Value.ShouldBe(expected.DownstreamReRoute[0].DownstreamDownstreamPathTemplate.Value);
result.DownstreamReRoute[0].ClaimsToClaims.Count.ShouldBe(expected.DownstreamReRoute[0].ClaimsToClaims.Count); result.DownstreamReRoute[0].ClaimsToClaims.Count.ShouldBe(expected.DownstreamReRoute[0].ClaimsToClaims.Count);
result.DownstreamReRoute[0].ClaimsToHeaders.Count.ShouldBe(expected.DownstreamReRoute[0].ClaimsToHeaders.Count); result.DownstreamReRoute[0].ClaimsToHeaders.Count.ShouldBe(expected.DownstreamReRoute[0].ClaimsToHeaders.Count);
result.DownstreamReRoute[0].ClaimsToQueries.Count.ShouldBe(expected.DownstreamReRoute[0].ClaimsToQueries.Count); result.DownstreamReRoute[0].ClaimsToQueries.Count.ShouldBe(expected.DownstreamReRoute[0].ClaimsToQueries.Count);
@ -977,11 +1016,22 @@
.Verify(x => x.Create(_fileConfiguration.ReRoutes[0]), Times.Once); .Verify(x => x.Create(_fileConfiguration.ReRoutes[0]), Times.Once);
} }
private void GivenTheUpstreamTemplatePatternCreatorReturns(string pattern) private void GivenTheUpstreamTemplatePatternCreatorReturns(string pattern, string original)
{ {
_upstreamTemplatePatternCreator _upstreamTemplatePatternCreator
.Setup(x => x.Create(It.IsAny<FileReRoute>())) .Setup(x => x.Create(It.IsAny<FileReRoute>()))
.Returns(new UpstreamPathTemplate(pattern, 1, false)); .Returns(new UpstreamPathTemplate(pattern, 1, false, original));
}
private void GivenTheUpstreamTemplatePatternCreatorReturns(params (string pattern, string original)[] list)
{
var builder = _upstreamTemplatePatternCreator
.SetupSequence(x => x.Create(It.IsAny<IReRoute>()));
foreach (var p in list)
{
builder.Returns(new UpstreamPathTemplate(p.pattern, 1, false, p.original));
}
} }
private void ThenTheRequestIdKeyCreatorIsCalledCorrectly() private void ThenTheRequestIdKeyCreatorIsCalledCorrectly()

View File

@ -42,7 +42,7 @@ namespace Ocelot.UnitTests.Configuration
private void ThenTheConfigurationIsReturned() private void ThenTheConfigurationIsReturned()
{ {
_getResult.Data.ReRoutes[0].DownstreamReRoute[0].DownstreamPathTemplate.Value.ShouldBe("initial"); _getResult.Data.ReRoutes[0].DownstreamReRoute[0].DownstreamDownstreamPathTemplate.Value.ShouldBe("initial");
} }
private void WhenIGetTheConfiguration() private void WhenIGetTheConfiguration()

View File

@ -85,7 +85,7 @@
new FileReRoute new FileReRoute
{ {
DownstreamScheme = "DownstreamScheme", DownstreamScheme = "DownstreamScheme",
DownstreamPathTemplate = "DownstreamPathTemplate", DownstreamPathTemplate = "DownstreamDownstreamPathTemplate",
Key = "Key", Key = "Key",
UpstreamHost = "UpstreamHost", UpstreamHost = "UpstreamHost",
UpstreamHttpMethod = new List<string> UpstreamHttpMethod = new List<string>

View File

@ -211,7 +211,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
private void ThenTheDownstreamRouteIsCreated() private void ThenTheDownstreamRouteIsCreated()
{ {
_result.Data.ReRoute.DownstreamReRoute[0].DownstreamPathTemplate.Value.ShouldBe("/test"); _result.Data.ReRoute.DownstreamReRoute[0].DownstreamDownstreamPathTemplate.Value.ShouldBe("/test");
_result.Data.ReRoute.UpstreamHttpMethod[0].ShouldBe(HttpMethod.Get); _result.Data.ReRoute.UpstreamHttpMethod[0].ShouldBe(HttpMethod.Get);
_result.Data.ReRoute.DownstreamReRoute[0].ServiceName.ShouldBe("auth"); _result.Data.ReRoute.DownstreamReRoute[0].ServiceName.ShouldBe("auth");
_result.Data.ReRoute.DownstreamReRoute[0].LoadBalancerKey.ShouldBe("/auth/test|GET"); _result.Data.ReRoute.DownstreamReRoute[0].LoadBalancerKey.ShouldBe("/auth/test|GET");
@ -226,21 +226,21 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
private void ThenTheDownstreamPathIsForwardSlash() private void ThenTheDownstreamPathIsForwardSlash()
{ {
_result.Data.ReRoute.DownstreamReRoute[0].DownstreamPathTemplate.Value.ShouldBe("/"); _result.Data.ReRoute.DownstreamReRoute[0].DownstreamDownstreamPathTemplate.Value.ShouldBe("/");
_result.Data.ReRoute.DownstreamReRoute[0].ServiceName.ShouldBe("auth"); _result.Data.ReRoute.DownstreamReRoute[0].ServiceName.ShouldBe("auth");
_result.Data.ReRoute.DownstreamReRoute[0].LoadBalancerKey.ShouldBe("/auth/|GET"); _result.Data.ReRoute.DownstreamReRoute[0].LoadBalancerKey.ShouldBe("/auth/|GET");
} }
private void ThenThePathDoesNotHaveTrailingSlash() private void ThenThePathDoesNotHaveTrailingSlash()
{ {
_result.Data.ReRoute.DownstreamReRoute[0].DownstreamPathTemplate.Value.ShouldBe("/test"); _result.Data.ReRoute.DownstreamReRoute[0].DownstreamDownstreamPathTemplate.Value.ShouldBe("/test");
_result.Data.ReRoute.DownstreamReRoute[0].ServiceName.ShouldBe("auth"); _result.Data.ReRoute.DownstreamReRoute[0].ServiceName.ShouldBe("auth");
_result.Data.ReRoute.DownstreamReRoute[0].LoadBalancerKey.ShouldBe("/auth/test|GET"); _result.Data.ReRoute.DownstreamReRoute[0].LoadBalancerKey.ShouldBe("/auth/test|GET");
} }
private void ThenTheQueryStringIsRemoved() private void ThenTheQueryStringIsRemoved()
{ {
_result.Data.ReRoute.DownstreamReRoute[0].DownstreamPathTemplate.Value.ShouldBe("/test"); _result.Data.ReRoute.DownstreamReRoute[0].DownstreamDownstreamPathTemplate.Value.ShouldBe("/test");
_result.Data.ReRoute.DownstreamReRoute[0].ServiceName.ShouldBe("auth"); _result.Data.ReRoute.DownstreamReRoute[0].ServiceName.ShouldBe("auth");
_result.Data.ReRoute.DownstreamReRoute[0].LoadBalancerKey.ShouldBe("/auth/test|GET"); _result.Data.ReRoute.DownstreamReRoute[0].LoadBalancerKey.ShouldBe("/auth/test|GET");
} }

View File

@ -47,24 +47,20 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder() .WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" }) .WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1, false, "someUpstreamPath"))
.Build()) .Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" }) .WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1, false, "someUpstreamPath"))
.Build(), .Build(),
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder() .WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" }) .WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 0, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 0, false, "someUpstreamPath"))
.Build()) .Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" }) .WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 0, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 0, false, "someUpstreamPath"))
.Build() .Build()
}, string.Empty, serviceProviderConfig)) }, string.Empty, serviceProviderConfig))
.And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(true)))) .And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(true))))
@ -74,13 +70,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder() .WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1, false, "someUpstreamPath"))
.WithUpstreamHttpMethod(new List<string> { "Post" }) .WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1, false))
.Build()) .Build())
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1, false, "someUpstreamPath"))
.WithUpstreamHttpMethod(new List<string> { "Post" }) .WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1, false))
.Build() .Build()
))) )))
.BDDfy(); .BDDfy();
@ -99,24 +93,20 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder() .WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" }) .WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 0, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 0, false, "someUpstreamPath"))
.Build()) .Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" }) .WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 0, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 0, false, "someUpstreamPath"))
.Build(), .Build(),
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder() .WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" }) .WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1, false, "someUpstreamPath"))
.Build()) .Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" }) .WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1, false, "someUpstreamPath"))
.Build() .Build()
}, string.Empty, serviceProviderConfig)) }, string.Empty, serviceProviderConfig))
.And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(true)))) .And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(true))))
@ -126,10 +116,10 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder() .WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1, false, "someUpstreamPath"))
.WithUpstreamHttpMethod(new List<string> { "Post" }) .WithUpstreamHttpMethod(new List<string> { "Post" })
.Build()) .Build())
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1, false, "someUpstreamPath"))
.WithUpstreamHttpMethod(new List<string> { "Post" }) .WithUpstreamHttpMethod(new List<string> { "Post" })
.Build() .Build()
))) )))
@ -150,13 +140,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder() .WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath"))
.Build()) .Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath"))
.Build() .Build()
}, string.Empty, serviceProviderConfig }, string.Empty, serviceProviderConfig
)) ))
@ -170,10 +158,10 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamReRoute(new DownstreamReRouteBuilder() .WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath"))
.Build()) .Build())
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath"))
.Build() .Build()
))) )))
.And(x => x.ThenTheUrlMatcherIsCalledCorrectly()) .And(x => x.ThenTheUrlMatcherIsCalledCorrectly())
@ -194,13 +182,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder() .WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath"))
.Build()) .Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath"))
.Build() .Build()
}, string.Empty, serviceProviderConfig }, string.Empty, serviceProviderConfig
)) ))
@ -214,10 +200,10 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamReRoute(new DownstreamReRouteBuilder() .WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath"))
.Build()) .Build())
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath"))
.Build() .Build()
))) )))
.And(x => x.ThenTheUrlMatcherIsCalledCorrectly("matchInUrlMatcher")) .And(x => x.ThenTheUrlMatcherIsCalledCorrectly("matchInUrlMatcher"))
@ -239,13 +225,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder() .WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath"))
.Build()) .Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath"))
.Build() .Build()
}, string.Empty, serviceProviderConfig }, string.Empty, serviceProviderConfig
)) ))
@ -258,10 +242,10 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamReRoute(new DownstreamReRouteBuilder() .WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath"))
.Build()) .Build())
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath"))
.Build() .Build()
))) )))
.BDDfy(); .BDDfy();
@ -282,24 +266,20 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder() .WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false, "someUpstreamPath"))
.Build()) .Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false, "someUpstreamPath"))
.Build(), .Build(),
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder() .WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPathForAPost") .WithDownstreamPathTemplate("someDownstreamPathForAPost")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" }) .WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false, "someUpstreamPath"))
.Build()) .Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" }) .WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false, "someUpstreamPath"))
.Build() .Build()
}, string.Empty, serviceProviderConfig }, string.Empty, serviceProviderConfig
)) ))
@ -312,10 +292,10 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamReRoute(new DownstreamReRouteBuilder() .WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPathForAPost") .WithDownstreamPathTemplate("someDownstreamPathForAPost")
.WithUpstreamHttpMethod(new List<string> { "Post" }) .WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false, "someUpstreamPath"))
.Build()) .Build())
.WithUpstreamHttpMethod(new List<string> { "Post" }) .WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false, "someUpstreamPath"))
.Build() .Build()
))) )))
.BDDfy(); .BDDfy();
@ -332,13 +312,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder() .WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("somPath") .WithDownstreamPathTemplate("somPath")
.WithUpstreamPathTemplate("somePath")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("somePath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("somePath", 1, false, "someUpstreamPath"))
.Build()) .Build())
.WithUpstreamPathTemplate("somePath")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("somePath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("somePath", 1, false, "someUpstreamPath"))
.Build(), .Build(),
}, string.Empty, serviceProviderConfig }, string.Empty, serviceProviderConfig
)) ))
@ -366,13 +344,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder() .WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get", "Post" }) .WithUpstreamHttpMethod(new List<string> { "Get", "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false, "someUpstreamPath"))
.Build()) .Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get", "Post" }) .WithUpstreamHttpMethod(new List<string> { "Get", "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false, "someUpstreamPath"))
.Build() .Build()
}, string.Empty, serviceProviderConfig }, string.Empty, serviceProviderConfig
)) ))
@ -385,10 +361,10 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamReRoute(new DownstreamReRouteBuilder() .WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" }) .WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false, "someUpstreamPath"))
.Build()) .Build())
.WithUpstreamHttpMethod(new List<string> { "Post" }) .WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false, "someUpstreamPath"))
.Build() .Build()
))) )))
.BDDfy(); .BDDfy();
@ -409,13 +385,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder() .WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string>()) .WithUpstreamHttpMethod(new List<string>())
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false, "someUpstreamPath"))
.Build()) .Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string>()) .WithUpstreamHttpMethod(new List<string>())
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false, "someUpstreamPath"))
.Build() .Build()
}, string.Empty, serviceProviderConfig }, string.Empty, serviceProviderConfig
)) ))
@ -428,10 +402,10 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamReRoute(new DownstreamReRouteBuilder() .WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" }) .WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false, "someUpstreamPath"))
.Build()) .Build())
.WithUpstreamHttpMethod(new List<string> { "Post" }) .WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false, "someUpstreamPath"))
.Build() .Build()
))) )))
.BDDfy(); .BDDfy();
@ -452,13 +426,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder() .WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get", "Patch", "Delete" }) .WithUpstreamHttpMethod(new List<string> { "Get", "Patch", "Delete" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false, "someUpstreamPath"))
.Build()) .Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get", "Patch", "Delete" }) .WithUpstreamHttpMethod(new List<string> { "Get", "Patch", "Delete" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1, false, "someUpstreamPath"))
.Build() .Build()
}, string.Empty, serviceProviderConfig }, string.Empty, serviceProviderConfig
)) ))
@ -485,14 +457,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder() .WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath"))
.WithUpstreamHost("MATCH") .WithUpstreamHost("MATCH")
.Build()) .Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath"))
.WithUpstreamHost("MATCH") .WithUpstreamHost("MATCH")
.Build() .Build()
}, string.Empty, serviceProviderConfig }, string.Empty, serviceProviderConfig
@ -507,10 +477,10 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamReRoute(new DownstreamReRouteBuilder() .WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath"))
.Build()) .Build())
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath"))
.Build() .Build()
))) )))
.And(x => x.ThenTheUrlMatcherIsCalledCorrectly()) .And(x => x.ThenTheUrlMatcherIsCalledCorrectly())
@ -532,13 +502,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder() .WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath"))
.Build()) .Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath"))
.Build() .Build()
}, string.Empty, serviceProviderConfig }, string.Empty, serviceProviderConfig
)) ))
@ -552,10 +520,10 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamReRoute(new DownstreamReRouteBuilder() .WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath"))
.Build()) .Build())
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath"))
.Build() .Build()
))) )))
.And(x => x.ThenTheUrlMatcherIsCalledCorrectly()) .And(x => x.ThenTheUrlMatcherIsCalledCorrectly())
@ -575,27 +543,23 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder() .WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath"))
.WithUpstreamHost("MATCH") .WithUpstreamHost("MATCH")
.Build()) .Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath"))
.WithUpstreamHost("MATCH") .WithUpstreamHost("MATCH")
.Build(), .Build(),
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder() .WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { }) // empty list of methods .WithUpstreamHttpMethod(new List<string> { }) // empty list of methods
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath"))
.WithUpstreamHost("MATCH") .WithUpstreamHost("MATCH")
.Build()) .Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { }) // empty list of methods .WithUpstreamHttpMethod(new List<string> { }) // empty list of methods
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath"))
.WithUpstreamHost("MATCH") .WithUpstreamHost("MATCH")
.Build() .Build()
}, string.Empty, serviceProviderConfig }, string.Empty, serviceProviderConfig
@ -621,14 +585,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder() .WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string>()) .WithUpstreamHttpMethod(new List<string>())
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath"))
.WithUpstreamHost("MATCH") .WithUpstreamHost("MATCH")
.Build()) .Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string>()) .WithUpstreamHttpMethod(new List<string>())
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath"))
.WithUpstreamHost("MATCH") .WithUpstreamHost("MATCH")
.Build() .Build()
}, string.Empty, serviceProviderConfig }, string.Empty, serviceProviderConfig
@ -654,14 +616,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder() .WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string>()) .WithUpstreamHttpMethod(new List<string>())
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath"))
.WithUpstreamHost("MATCH") .WithUpstreamHost("MATCH")
.Build()) .Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string>()) .WithUpstreamHttpMethod(new List<string>())
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath"))
.WithUpstreamHost("MATCH") .WithUpstreamHost("MATCH")
.Build() .Build()
}, string.Empty, serviceProviderConfig }, string.Empty, serviceProviderConfig
@ -688,25 +648,21 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder() .WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("THENULLPATH") .WithDownstreamPathTemplate("THENULLPATH")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath"))
.Build()) .Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath"))
.Build(), .Build(),
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder() .WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath"))
.WithUpstreamHost("MATCH") .WithUpstreamHost("MATCH")
.Build()) .Build())
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false, "someUpstreamPath"))
.WithUpstreamHost("MATCH") .WithUpstreamHost("MATCH")
.Build() .Build()
}, string.Empty, serviceProviderConfig }, string.Empty, serviceProviderConfig
@ -721,10 +677,10 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamReRoute(new DownstreamReRouteBuilder() .WithDownstreamReRoute(new DownstreamReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false, "test"))
.Build()) .Build())
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false)) .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1, false, "test"))
.Build() .Build()
))) )))
.And(x => x.ThenTheUrlMatcherIsCalledCorrectly(2)) .And(x => x.ThenTheUrlMatcherIsCalledCorrectly(2))
@ -756,25 +712,25 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
private void ThenTheUrlMatcherIsCalledCorrectly() private void ThenTheUrlMatcherIsCalledCorrectly()
{ {
_mockMatcher _mockMatcher
.Verify(x => x.Match(_upstreamUrlPath, _upstreamQuery, _reRoutesConfig[0].UpstreamPathTemplate.Value, _reRoutesConfig[0].UpstreamTemplatePattern.ContainsQueryString), Times.Once); .Verify(x => x.Match(_upstreamUrlPath, _upstreamQuery, _reRoutesConfig[0].UpstreamTemplatePattern.Template, _reRoutesConfig[0].UpstreamTemplatePattern.ContainsQueryString), Times.Once);
} }
private void ThenTheUrlMatcherIsCalledCorrectly(int times) private void ThenTheUrlMatcherIsCalledCorrectly(int times)
{ {
_mockMatcher _mockMatcher
.Verify(x => x.Match(_upstreamUrlPath, _upstreamQuery, _reRoutesConfig[0].UpstreamPathTemplate.Value, _reRoutesConfig[0].UpstreamTemplatePattern.ContainsQueryString), Times.Exactly(times)); .Verify(x => x.Match(_upstreamUrlPath, _upstreamQuery, _reRoutesConfig[0].UpstreamTemplatePattern.OriginalValue, _reRoutesConfig[0].UpstreamTemplatePattern.ContainsQueryString), Times.Exactly(times));
} }
private void ThenTheUrlMatcherIsCalledCorrectly(string expectedUpstreamUrlPath) private void ThenTheUrlMatcherIsCalledCorrectly(string expectedUpstreamUrlPath)
{ {
_mockMatcher _mockMatcher
.Verify(x => x.Match(expectedUpstreamUrlPath, _upstreamQuery, _reRoutesConfig[0].UpstreamPathTemplate.Value, _reRoutesConfig[0].UpstreamTemplatePattern.ContainsQueryString), Times.Once); .Verify(x => x.Match(expectedUpstreamUrlPath, _upstreamQuery, _reRoutesConfig[0].UpstreamTemplatePattern.OriginalValue, _reRoutesConfig[0].UpstreamTemplatePattern.ContainsQueryString), Times.Once);
} }
private void ThenTheUrlMatcherIsNotCalled() private void ThenTheUrlMatcherIsNotCalled()
{ {
_mockMatcher _mockMatcher
.Verify(x => x.Match(_upstreamUrlPath, _upstreamQuery, _reRoutesConfig[0].UpstreamPathTemplate.Value, _reRoutesConfig[0].UpstreamTemplatePattern.ContainsQueryString), Times.Never); .Verify(x => x.Match(_upstreamUrlPath, _upstreamQuery, _reRoutesConfig[0].UpstreamTemplatePattern.OriginalValue, _reRoutesConfig[0].UpstreamTemplatePattern.ContainsQueryString), Times.Never);
} }
private void GivenTheUrlMatcherReturns(Response<UrlMatch> match) private void GivenTheUrlMatcherReturns(Response<UrlMatch> match)
@ -803,7 +759,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
private void ThenTheFollowingIsReturned(DownstreamRoute expected) private void ThenTheFollowingIsReturned(DownstreamRoute expected)
{ {
_result.Data.ReRoute.DownstreamReRoute[0].DownstreamPathTemplate.Value.ShouldBe(expected.ReRoute.DownstreamReRoute[0].DownstreamPathTemplate.Value); _result.Data.ReRoute.DownstreamReRoute[0].DownstreamDownstreamPathTemplate.Value.ShouldBe(expected.ReRoute.DownstreamReRoute[0].DownstreamDownstreamPathTemplate.Value);
_result.Data.ReRoute.UpstreamTemplatePattern.Priority.ShouldBe(expected.ReRoute.UpstreamTemplatePattern.Priority); _result.Data.ReRoute.UpstreamTemplatePattern.Priority.ShouldBe(expected.ReRoute.UpstreamTemplatePattern.Priority);
for (int i = 0; i < _result.Data.TemplatePlaceholderNameAndValues.Count; i++) for (int i = 0; i < _result.Data.TemplatePlaceholderNameAndValues.Count; i++)

View File

@ -5,11 +5,8 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
using Moq; using Moq;
using Ocelot.Configuration; using Ocelot.Configuration;
using Ocelot.Configuration.Builder; using Ocelot.Configuration.Builder;
using Ocelot.DownstreamRouteFinder;
using Ocelot.DownstreamRouteFinder.Finder; using Ocelot.DownstreamRouteFinder.Finder;
using Ocelot.DownstreamRouteFinder.UrlMatcher; using Ocelot.DownstreamRouteFinder.UrlMatcher;
using Ocelot.Responses;
using Ocelot.Values;
using Shouldly; using Shouldly;
using TestStack.BDDfy; using TestStack.BDDfy;
using Xunit; using Xunit;
@ -30,8 +27,8 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
services.AddSingleton<IPlaceholderNameAndValueFinder, UrlPathPlaceholderNameAndValueFinder>(); services.AddSingleton<IPlaceholderNameAndValueFinder, UrlPathPlaceholderNameAndValueFinder>();
services.AddSingleton<IUrlPathToUrlTemplateMatcher, RegExUrlMatcher>(); services.AddSingleton<IUrlPathToUrlTemplateMatcher, RegExUrlMatcher>();
services.AddSingleton<IQoSOptionsCreator, QoSOptionsCreator>(); services.AddSingleton<IQoSOptionsCreator, QoSOptionsCreator>();
services.AddSingleton<IDownstreamRouteProvider, Ocelot.DownstreamRouteFinder.Finder.DownstreamRouteFinder>(); services.AddSingleton<IDownstreamRouteProvider, DownstreamRouteFinder>();
services.AddSingleton<IDownstreamRouteProvider, Ocelot.DownstreamRouteFinder.Finder.DownstreamRouteCreator>(); services.AddSingleton<IDownstreamRouteProvider, DownstreamRouteCreator>();
var provider = services.BuildServiceProvider(); var provider = services.BuildServiceProvider();
_logger = new Mock<IOcelotLogger>(); _logger = new Mock<IOcelotLogger>();
_loggerFactory = new Mock<IOcelotLoggerFactory>(); _loggerFactory = new Mock<IOcelotLoggerFactory>();
@ -49,7 +46,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
this.Given(_ => GivenTheReRoutes(reRoutes)) this.Given(_ => GivenTheReRoutes(reRoutes))
.When(_ => WhenIGet()) .When(_ => WhenIGet())
.Then(_ => ThenTheResultShouldBe<Ocelot.DownstreamRouteFinder.Finder.DownstreamRouteFinder>()) .Then(_ => ThenTheResultShouldBe<DownstreamRouteFinder>())
.BDDfy(); .BDDfy();
} }
@ -59,12 +56,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
var spConfig = new ServiceProviderConfigurationBuilder().WithHost("test").WithPort(50).WithType("test").Build(); var spConfig = new ServiceProviderConfigurationBuilder().WithHost("test").WithPort(50).WithType("test").Build();
var reRoutes = new List<ReRoute> var reRoutes = new List<ReRoute>
{ {
new ReRouteBuilder().WithUpstreamPathTemplate("woot").Build() new ReRouteBuilder().WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithOriginalValue("woot").Build()).Build()
}; };
this.Given(_ => GivenTheReRoutes(reRoutes, spConfig)) this.Given(_ => GivenTheReRoutes(reRoutes, spConfig))
.When(_ => WhenIGet()) .When(_ => WhenIGet())
.Then(_ => ThenTheResultShouldBe<Ocelot.DownstreamRouteFinder.Finder.DownstreamRouteFinder>()) .Then(_ => ThenTheResultShouldBe<DownstreamRouteFinder>())
.BDDfy(); .BDDfy();
} }
@ -76,7 +73,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
this.Given(_ => GivenTheReRoutes(reRoutes, spConfig)) this.Given(_ => GivenTheReRoutes(reRoutes, spConfig))
.When(_ => WhenIGet()) .When(_ => WhenIGet())
.Then(_ => ThenTheResultShouldBe<Ocelot.DownstreamRouteFinder.Finder.DownstreamRouteFinder>()) .Then(_ => ThenTheResultShouldBe<DownstreamRouteFinder>())
.BDDfy(); .BDDfy();
} }
@ -88,7 +85,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
this.Given(_ => GivenTheReRoutes(reRoutes, spConfig)) this.Given(_ => GivenTheReRoutes(reRoutes, spConfig))
.When(_ => WhenIGet()) .When(_ => WhenIGet())
.Then(_ => ThenTheResultShouldBe<Ocelot.DownstreamRouteFinder.Finder.DownstreamRouteFinder>()) .Then(_ => ThenTheResultShouldBe<DownstreamRouteFinder>())
.BDDfy(); .BDDfy();
} }
@ -100,7 +97,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
this.Given(_ => GivenTheReRoutes(reRoutes, spConfig)) this.Given(_ => GivenTheReRoutes(reRoutes, spConfig))
.When(_ => WhenIGet()) .When(_ => WhenIGet())
.Then(_ => ThenTheResultShouldBe<Ocelot.DownstreamRouteFinder.Finder.DownstreamRouteFinder>()) .Then(_ => ThenTheResultShouldBe<DownstreamRouteFinder>())
.BDDfy(); .BDDfy();
} }
@ -112,7 +109,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
this.Given(_ => GivenTheReRoutes(reRoutes, spConfig)) this.Given(_ => GivenTheReRoutes(reRoutes, spConfig))
.When(_ => WhenIGet()) .When(_ => WhenIGet())
.Then(_ => ThenTheResultShouldBe<Ocelot.DownstreamRouteFinder.Finder.DownstreamRouteCreator>()) .Then(_ => ThenTheResultShouldBe<DownstreamRouteCreator>())
.BDDfy(); .BDDfy();
} }
@ -127,7 +124,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
this.Given(_ => GivenTheReRoutes(reRoutes, spConfig)) this.Given(_ => GivenTheReRoutes(reRoutes, spConfig))
.When(_ => WhenIGet()) .When(_ => WhenIGet())
.Then(_ => ThenTheResultShouldBe<Ocelot.DownstreamRouteFinder.Finder.DownstreamRouteCreator>()) .Then(_ => ThenTheResultShouldBe<DownstreamRouteCreator>())
.BDDfy(); .BDDfy();
} }

View File

@ -296,7 +296,7 @@
.WithDownstreamPathTemplate("/Authorized/{action}?server={server}") .WithDownstreamPathTemplate("/Authorized/{action}?server={server}")
.WithUpstreamHttpMethod(new List<string> { "Post", "Get" }) .WithUpstreamHttpMethod(new List<string> { "Post", "Get" })
.WithDownstreamScheme("http") .WithDownstreamScheme("http")
.WithUpstreamPathTemplate("/uc/Authorized/{server}/{action}") .WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithOriginalValue("/uc/Authorized/{server}/{action}").Build())
.Build(); .Build();
var config = new ServiceProviderConfigurationBuilder() var config = new ServiceProviderConfigurationBuilder()
@ -350,7 +350,7 @@
{ {
_downstreamPath = new OkResponse<DownstreamPath>(new DownstreamPath(path)); _downstreamPath = new OkResponse<DownstreamPath>(new DownstreamPath(path));
_downstreamUrlTemplateVariableReplacer _downstreamUrlTemplateVariableReplacer
.Setup(x => x.Replace(It.IsAny<PathTemplate>(), It.IsAny<List<PlaceholderNameAndValue>>())) .Setup(x => x.Replace(It.IsAny<DownstreamPathTemplate>(), It.IsAny<List<PlaceholderNameAndValue>>()))
.Returns(_downstreamPath); .Returns(_downstreamPath);
} }

View File

@ -199,7 +199,7 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
private void WhenIReplaceTheTemplateVariables() private void WhenIReplaceTheTemplateVariables()
{ {
_result = _downstreamPathReplacer.Replace(_downstreamRoute.ReRoute.DownstreamReRoute[0].DownstreamPathTemplate, _downstreamRoute.TemplatePlaceholderNameAndValues); _result = _downstreamPathReplacer.Replace(_downstreamRoute.ReRoute.DownstreamReRoute[0].DownstreamDownstreamPathTemplate, _downstreamRoute.TemplatePlaceholderNameAndValues);
} }
private void ThenTheDownstreamUrlPathIsReturned(string expected) private void ThenTheDownstreamUrlPathIsReturned(string expected)

View File

@ -50,14 +50,21 @@ namespace Ocelot.UnitTests.RateLimit
[Fact] [Fact]
public void should_call_middleware_and_ratelimiting() public void should_call_middleware_and_ratelimiting()
{ {
var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>(), var upstreamTemplate = new UpstreamPathTemplateBuilder().Build();
new ReRouteBuilder()
.WithDownstreamReRoute(new DownstreamReRouteBuilder().WithEnableRateLimiting(true).WithRateLimitOptions( var downstreamReRoute = new DownstreamReRouteBuilder()
new RateLimitOptions(true, "ClientId", new List<string>(), false, "", "", new RateLimitRule("1s", 100, 3), 429)) .WithEnableRateLimiting(true)
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithRateLimitOptions(new RateLimitOptions(true, "ClientId", new List<string>(), false, "", "", new RateLimitRule("1s", 100, 3), 429))
.Build()) .WithUpstreamHttpMethod(new List<string> {"Get"})
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamTemplatePattern(upstreamTemplate)
.Build()); .Build();
var reRoute = new ReRouteBuilder()
.WithDownstreamReRoute(downstreamReRoute)
.WithUpstreamHttpMethod(new List<string> {"Get"})
.Build();
var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>(), reRoute);
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute)) this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
.When(x => x.WhenICallTheMiddlewareMultipleTime(2)) .When(x => x.WhenICallTheMiddlewareMultipleTime(2))

View File

@ -54,6 +54,7 @@ namespace Ocelot.UnitTests.Requester
.WithQosOptions(qosOptions) .WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true)) .WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true))
.WithLoadBalancerKey("") .WithLoadBalancerKey("")
.WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithOriginalValue("").Build())
.WithQosOptions(new QoSOptionsBuilder().Build()) .WithQosOptions(new QoSOptionsBuilder().Build())
.Build(); .Build();
@ -74,6 +75,7 @@ namespace Ocelot.UnitTests.Requester
.WithQosOptions(qosOptions) .WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true)) .WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true))
.WithLoadBalancerKey("") .WithLoadBalancerKey("")
.WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithOriginalValue("").Build())
.WithQosOptions(new QoSOptionsBuilder().Build()) .WithQosOptions(new QoSOptionsBuilder().Build())
.Build(); .Build();
@ -89,6 +91,68 @@ namespace Ocelot.UnitTests.Requester
.BDDfy(); .BDDfy();
} }
[Fact]
public void should_get_from_cache_with_different_query_string()
{
var qosOptions = new QoSOptionsBuilder()
.Build();
var reRoute = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true))
.WithLoadBalancerKey("")
.WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithOriginalValue("").Build())
.WithQosOptions(new QoSOptionsBuilder().Build())
.Build();
this.Given(x => GivenARealCache())
.And(x => GivenTheFactoryReturns())
.And(x => GivenARequest(reRoute, "http://wwww.someawesomewebsite.com/woot?badman=1"))
.And(x => WhenIBuildTheFirstTime())
.And(x => WhenISave())
.And(x => WhenIBuildAgain())
.And(x => GivenARequest(reRoute, "http://wwww.someawesomewebsite.com/woot?badman=2"))
.And(x => WhenISave())
.When(x => WhenIBuildAgain())
.Then(x => ThenTheHttpClientIsFromTheCache())
.BDDfy();
}
[Fact]
public void should_not_get_from_cache_with_different_query_string()
{
var qosOptions = new QoSOptionsBuilder()
.Build();
var reRouteA = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true))
.WithLoadBalancerKey("")
.WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithContainsQueryString(true).WithOriginalValue("").Build())
.WithQosOptions(new QoSOptionsBuilder().Build())
.Build();
var reRouteB = new DownstreamReRouteBuilder()
.WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true))
.WithLoadBalancerKey("")
.WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithContainsQueryString(true).WithOriginalValue("").Build())
.WithQosOptions(new QoSOptionsBuilder().Build())
.Build();
this.Given(x => GivenARealCache())
.And(x => GivenTheFactoryReturns())
.And(x => GivenARequest(reRouteA, "http://wwww.someawesomewebsite.com/woot?badman=1"))
.And(x => WhenIBuildTheFirstTime())
.And(x => WhenISave())
.And(x => WhenIBuildAgain())
.And(x => GivenARequest(reRouteB, "http://wwww.someawesomewebsite.com/woot?badman=2"))
.And(x => WhenISave())
.When(x => WhenIBuildAgain())
.Then(x => ThenTheHttpClientIsNotFromTheCache())
.BDDfy();
}
[Fact] [Fact]
public void should_log_if_ignoring_ssl_errors() public void should_log_if_ignoring_ssl_errors()
{ {
@ -99,6 +163,7 @@ namespace Ocelot.UnitTests.Requester
.WithQosOptions(qosOptions) .WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true)) .WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true))
.WithLoadBalancerKey("") .WithLoadBalancerKey("")
.WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithOriginalValue("").Build())
.WithQosOptions(new QoSOptionsBuilder().Build()) .WithQosOptions(new QoSOptionsBuilder().Build())
.WithDangerousAcceptAnyServerCertificateValidator(true) .WithDangerousAcceptAnyServerCertificateValidator(true)
.Build(); .Build();
@ -121,6 +186,7 @@ namespace Ocelot.UnitTests.Requester
.WithQosOptions(qosOptions) .WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true)) .WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true))
.WithLoadBalancerKey("") .WithLoadBalancerKey("")
.WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithOriginalValue("").Build())
.WithQosOptions(new QoSOptionsBuilder().Build()) .WithQosOptions(new QoSOptionsBuilder().Build())
.Build(); .Build();
@ -152,6 +218,7 @@ namespace Ocelot.UnitTests.Requester
.WithQosOptions(qosOptions) .WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, true, false, true)) .WithHttpHandlerOptions(new HttpHandlerOptions(false, true, false, true))
.WithLoadBalancerKey("") .WithLoadBalancerKey("")
.WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithOriginalValue("").Build())
.WithQosOptions(new QoSOptionsBuilder().Build()) .WithQosOptions(new QoSOptionsBuilder().Build())
.Build(); .Build();
@ -176,9 +243,9 @@ namespace Ocelot.UnitTests.Requester
[InlineData("PATCH")] [InlineData("PATCH")]
public void should_add_verb_to_cache_key(string verb) public void should_add_verb_to_cache_key(string verb)
{ {
var client = "http://localhost:5012"; var downstreamUrl = "http://localhost:5012/";
HttpMethod method = new HttpMethod(verb); var method = new HttpMethod(verb);
var qosOptions = new QoSOptionsBuilder() var qosOptions = new QoSOptionsBuilder()
.Build(); .Build();
@ -187,14 +254,15 @@ namespace Ocelot.UnitTests.Requester
.WithQosOptions(qosOptions) .WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true)) .WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true))
.WithLoadBalancerKey("") .WithLoadBalancerKey("")
.WithUpstreamTemplatePattern(new UpstreamPathTemplateBuilder().WithOriginalValue("").Build())
.WithQosOptions(new QoSOptionsBuilder().Build()) .WithQosOptions(new QoSOptionsBuilder().Build())
.Build(); .Build();
this.Given(_ => GivenADownstreamService()) this.Given(_ => GivenADownstreamService())
.And(_ => GivenARequestWithAUrlAndMethod(reRoute, client, method)) .And(_ => GivenARequestWithAUrlAndMethod(reRoute, downstreamUrl, method))
.And(_ => GivenTheFactoryReturnsNothing()) .And(_ => GivenTheFactoryReturnsNothing())
.And(_ => WhenIBuild()) .And(_ => WhenIBuild())
.And(_ => GivenCacheIsCalledWithExpectedKey($"{method.ToString()}:{client}")) .And(_ => GivenCacheIsCalledWithExpectedKey($"{method.ToString()}:{downstreamUrl}"))
.BDDfy(); .BDDfy();
} }
@ -209,6 +277,11 @@ namespace Ocelot.UnitTests.Requester
_againHttpClient.ShouldBe(_firstHttpClient); _againHttpClient.ShouldBe(_firstHttpClient);
} }
private void ThenTheHttpClientIsNotFromTheCache()
{
_againHttpClient.ShouldNotBe(_firstHttpClient);
}
private void WhenISave() private void WhenISave()
{ {
_builder.Save(); _builder.Save();
@ -216,17 +289,17 @@ namespace Ocelot.UnitTests.Requester
private void GivenCacheIsCalledWithExpectedKey(string expectedKey) private void GivenCacheIsCalledWithExpectedKey(string expectedKey)
{ {
_cacheHandlers.Verify(x => x.Get(It.Is<string>(p => p.Equals(expectedKey, StringComparison.OrdinalIgnoreCase))), Times.Once); _cacheHandlers.Verify(x => x.Get(It.IsAny<DownstreamReRoute>()), Times.Once);
} }
private void ThenTheDangerousAcceptAnyServerCertificateValidatorWarningIsLogged() private void ThenTheDangerousAcceptAnyServerCertificateValidatorWarningIsLogged()
{ {
_logger.Verify(x => x.LogWarning($"You have ignored all SSL warnings by using DangerousAcceptAnyServerCertificateValidator for this DownstreamReRoute, UpstreamPathTemplate: {_context.DownstreamReRoute.UpstreamPathTemplate}, DownstreamPathTemplate: {_context.DownstreamReRoute.DownstreamPathTemplate}"), Times.Once); _logger.Verify(x => x.LogWarning($"You have ignored all SSL warnings by using DangerousAcceptAnyServerCertificateValidator for this DownstreamReRoute, UpstreamPathTemplate: {_context.DownstreamReRoute.UpstreamPathTemplate}, DownstreamDownstreamPathTemplate: {_context.DownstreamReRoute.DownstreamDownstreamPathTemplate}"), Times.Once);
} }
private void GivenTheClientIsCached() private void GivenTheClientIsCached()
{ {
_cacheHandlers.Setup(x => x.Get(It.IsAny<string>())).Returns(_httpClient); _cacheHandlers.Setup(x => x.Get(It.IsAny<DownstreamReRoute>())).Returns(_httpClient);
} }
private void ThenTheCookieIsSet() private void ThenTheCookieIsSet()
@ -287,7 +360,12 @@ namespace Ocelot.UnitTests.Requester
private void GivenARequest(DownstreamReRoute downstream) private void GivenARequest(DownstreamReRoute downstream)
{ {
GivenARequestWithAUrlAndMethod(downstream, "http://localhost:5003", HttpMethod.Get); GivenARequest(downstream, "http://localhost:5003");
}
private void GivenARequest(DownstreamReRoute downstream, string downstreamUrl)
{
GivenARequestWithAUrlAndMethod(downstream, downstreamUrl, HttpMethod.Get);
} }
private void GivenARequestWithAUrlAndMethod(DownstreamReRoute downstream, string url, HttpMethod method) private void GivenARequestWithAUrlAndMethod(DownstreamReRoute downstream, string url, HttpMethod method)

View File

@ -50,6 +50,8 @@ namespace Ocelot.UnitTests.Requester
[Fact] [Fact]
public void should_call_request_correctly() public void should_call_request_correctly()
{ {
var upstreamTemplate = new UpstreamPathTemplateBuilder().WithOriginalValue("").Build();
var qosOptions = new QoSOptionsBuilder() var qosOptions = new QoSOptionsBuilder()
.Build(); .Build();
@ -57,6 +59,7 @@ namespace Ocelot.UnitTests.Requester
.WithQosOptions(qosOptions) .WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true)) .WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true))
.WithLoadBalancerKey("") .WithLoadBalancerKey("")
.WithUpstreamTemplatePattern(upstreamTemplate)
.WithQosOptions(new QoSOptionsBuilder().Build()) .WithQosOptions(new QoSOptionsBuilder().Build())
.Build(); .Build();
@ -76,6 +79,8 @@ namespace Ocelot.UnitTests.Requester
[Fact] [Fact]
public void should_call_request_unable_to_complete_request() public void should_call_request_unable_to_complete_request()
{ {
var upstreamTemplate = new UpstreamPathTemplateBuilder().WithOriginalValue("").Build();
var qosOptions = new QoSOptionsBuilder() var qosOptions = new QoSOptionsBuilder()
.Build(); .Build();
@ -83,6 +88,7 @@ namespace Ocelot.UnitTests.Requester
.WithQosOptions(qosOptions) .WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true)) .WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true))
.WithLoadBalancerKey("") .WithLoadBalancerKey("")
.WithUpstreamTemplatePattern(upstreamTemplate)
.WithQosOptions(new QoSOptionsBuilder().Build()) .WithQosOptions(new QoSOptionsBuilder().Build())
.Build(); .Build();
@ -101,6 +107,8 @@ namespace Ocelot.UnitTests.Requester
[Fact] [Fact]
public void http_client_request_times_out() public void http_client_request_times_out()
{ {
var upstreamTemplate = new UpstreamPathTemplateBuilder().WithOriginalValue("").Build();
var qosOptions = new QoSOptionsBuilder() var qosOptions = new QoSOptionsBuilder()
.Build(); .Build();
@ -108,6 +116,7 @@ namespace Ocelot.UnitTests.Requester
.WithQosOptions(qosOptions) .WithQosOptions(qosOptions)
.WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true)) .WithHttpHandlerOptions(new HttpHandlerOptions(false, false, false, true))
.WithLoadBalancerKey("") .WithLoadBalancerKey("")
.WithUpstreamTemplatePattern(upstreamTemplate)
.WithQosOptions(new QoSOptionsBuilder().WithTimeoutValue(1).Build()) .WithQosOptions(new QoSOptionsBuilder().WithTimeoutValue(1).Build())
.Build(); .Build();
@ -132,7 +141,7 @@ namespace Ocelot.UnitTests.Requester
private void WhenIGetResponse() private void WhenIGetResponse()
{ {
_response = _httpClientRequester.GetResponse(_request).Result; _response = _httpClientRequester.GetResponse(_request).GetAwaiter().GetResult();
} }
private void ThenTheResponseIsCalledCorrectly() private void ThenTheResponseIsCalledCorrectly()