Changed routing to support a catch all style (#187)

* Changed routing to support a catch all style

* refactoring placeholder tuff

* implemented simple priority in the routing
This commit is contained in:
Tom Pallister 2018-01-05 21:26:15 +00:00 committed by GitHub
parent 931a115ffa
commit fef19ddf98
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 575 additions and 165 deletions

View File

@ -63,3 +63,32 @@ In order to change this you can specify on a per ReRoute basis the following set
This means that when Ocelot tries to match the incoming upstream url with an upstream template the This means that when Ocelot tries to match the incoming upstream url with an upstream template the
evaluation will be case sensitive. This setting defaults to false so only set it if you want evaluation will be case sensitive. This setting defaults to false so only set it if you want
the ReRoute to be case sensitive is my advice! the ReRoute to be case sensitive is my advice!
Catch All
^^^^^^^^^
Ocelot's routing also supports a catch all style routing where the user can specify that they want to match all traffic if you set up your config like below the request will be proxied straight through (it doesnt have to be url any placeholder name will work).
.. code-block:: json
{
"DownstreamPathTemplate": "/{url}",
"DownstreamScheme": "https",
"DownstreamPort": 80,
"DownstreamHost" "localhost",
"UpstreamPathTemplate": "/{url}",
"UpstreamHttpMethod": [ "Get" ]
}
The catch all has a lower priority than any other ReRoute. If you also have the ReRoute below in your config then Ocelot would match it before the catch all.
.. code-block:: json
{
"DownstreamPathTemplate": "/",
"DownstreamScheme": "https",
"DownstreamPort": 80,
"DownstreamHost" "10.0.10.1",
"UpstreamPathTemplate": "/",
"UpstreamHttpMethod": [ "Get" ]
}

View File

@ -2,6 +2,7 @@
using System.Net.Http; using System.Net.Http;
using Ocelot.Values; using Ocelot.Values;
using System.Linq; using System.Linq;
using Ocelot.Configuration.Creator;
namespace Ocelot.Configuration.Builder namespace Ocelot.Configuration.Builder
{ {
@ -11,7 +12,7 @@ namespace Ocelot.Configuration.Builder
private string _loadBalancerKey; private string _loadBalancerKey;
private string _downstreamPathTemplate; private string _downstreamPathTemplate;
private string _upstreamTemplate; private string _upstreamTemplate;
private string _upstreamTemplatePattern; private UpstreamPathTemplate _upstreamTemplatePattern;
private List<HttpMethod> _upstreamHttpMethod; private List<HttpMethod> _upstreamHttpMethod;
private bool _isAuthenticated; private bool _isAuthenticated;
private List<ClaimToThing> _configHeaderExtractorProperties; private List<ClaimToThing> _configHeaderExtractorProperties;
@ -65,7 +66,7 @@ namespace Ocelot.Configuration.Builder
return this; return this;
} }
public ReRouteBuilder WithUpstreamTemplatePattern(string input) public ReRouteBuilder WithUpstreamTemplatePattern(UpstreamPathTemplate input)
{ {
_upstreamTemplatePattern = input; _upstreamTemplatePattern = input;
return this; return this;

View File

@ -1,9 +1,10 @@
using Ocelot.Configuration.File; using Ocelot.Configuration.File;
using Ocelot.Values;
namespace Ocelot.Configuration.Creator namespace Ocelot.Configuration.Creator
{ {
public interface IUpstreamTemplatePatternCreator public interface IUpstreamTemplatePatternCreator
{ {
string Create(FileReRoute reRoute); UpstreamPathTemplate Create(FileReRoute reRoute);
} }
} }

View File

@ -1,5 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using Ocelot.Configuration.File; using Ocelot.Configuration.File;
using Ocelot.Values;
namespace Ocelot.Configuration.Creator namespace Ocelot.Configuration.Creator
{ {
@ -11,7 +12,7 @@ namespace Ocelot.Configuration.Creator
private const string RegExForwardSlashOnly = "^/$"; private const string RegExForwardSlashOnly = "^/$";
private const string RegExForwardSlashAndOnePlaceHolder = "^/.*"; private const string RegExForwardSlashAndOnePlaceHolder = "^/.*";
public string Create(FileReRoute reRoute) public UpstreamPathTemplate Create(FileReRoute reRoute)
{ {
var upstreamTemplate = reRoute.UpstreamPathTemplate; var upstreamTemplate = reRoute.UpstreamPathTemplate;
@ -26,9 +27,10 @@ namespace Ocelot.Configuration.Creator
var placeHolderName = upstreamTemplate.Substring(i, difference); var placeHolderName = upstreamTemplate.Substring(i, difference);
placeholders.Add(placeHolderName); placeholders.Add(placeHolderName);
//hack to handle /{url} case
if(ForwardSlashAndOnePlaceHolder(upstreamTemplate, placeholders, postitionOfPlaceHolderClosingBracket)) if(ForwardSlashAndOnePlaceHolder(upstreamTemplate, placeholders, postitionOfPlaceHolderClosingBracket))
{ {
return RegExForwardSlashAndOnePlaceHolder; return new UpstreamPathTemplate(RegExForwardSlashAndOnePlaceHolder, 0);
} }
} }
} }
@ -40,7 +42,7 @@ namespace Ocelot.Configuration.Creator
if (upstreamTemplate == "/") if (upstreamTemplate == "/")
{ {
return RegExForwardSlashOnly; return new UpstreamPathTemplate(RegExForwardSlashOnly, 1);
} }
if(upstreamTemplate.EndsWith("/")) if(upstreamTemplate.EndsWith("/"))
@ -52,7 +54,7 @@ namespace Ocelot.Configuration.Creator
? $"^{upstreamTemplate}{RegExMatchEndString}" ? $"^{upstreamTemplate}{RegExMatchEndString}"
: $"^{RegExIgnoreCase}{upstreamTemplate}{RegExMatchEndString}"; : $"^{RegExIgnoreCase}{upstreamTemplate}{RegExMatchEndString}";
return route; return new UpstreamPathTemplate(route, 1);
} }
private bool ForwardSlashAndOnePlaceHolder(string upstreamTemplate, List<string> placeholders, int postitionOfPlaceHolderClosingBracket) private bool ForwardSlashAndOnePlaceHolder(string upstreamTemplate, List<string> placeholders, int postitionOfPlaceHolderClosingBracket)

View File

@ -1,5 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Net.Http; using System.Net.Http;
using Ocelot.Configuration.Creator;
using Ocelot.Values; using Ocelot.Values;
namespace Ocelot.Configuration namespace Ocelot.Configuration
@ -9,7 +10,7 @@ namespace Ocelot.Configuration
public ReRoute(PathTemplate downstreamPathTemplate, public ReRoute(PathTemplate downstreamPathTemplate,
PathTemplate upstreamPathTemplate, PathTemplate upstreamPathTemplate,
List<HttpMethod> upstreamHttpMethod, List<HttpMethod> upstreamHttpMethod,
string upstreamTemplatePattern, UpstreamPathTemplate upstreamTemplatePattern,
bool isAuthenticated, bool isAuthenticated,
AuthenticationOptions authenticationOptions, AuthenticationOptions authenticationOptions,
List<ClaimToThing> claimsToHeaders, List<ClaimToThing> claimsToHeaders,
@ -67,7 +68,7 @@ namespace Ocelot.Configuration
public string ReRouteKey {get;private set;} public string ReRouteKey {get;private set;}
public PathTemplate DownstreamPathTemplate { get; private set; } public PathTemplate DownstreamPathTemplate { get; private set; }
public PathTemplate UpstreamPathTemplate { get; private set; } public PathTemplate UpstreamPathTemplate { get; private set; }
public string 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 bool IsAuthenticated { get; private set; } public bool IsAuthenticated { get; private set; }
public bool IsAuthorised { get; private set; } public bool IsAuthorised { get; private set; }

View File

@ -108,7 +108,7 @@ namespace Ocelot.DependencyInjection
_services.TryAddSingleton<IAddQueriesToRequest, AddQueriesToRequest>(); _services.TryAddSingleton<IAddQueriesToRequest, AddQueriesToRequest>();
_services.TryAddSingleton<IClaimsParser, ClaimsParser>(); _services.TryAddSingleton<IClaimsParser, ClaimsParser>();
_services.TryAddSingleton<IUrlPathToUrlTemplateMatcher, RegExUrlMatcher>(); _services.TryAddSingleton<IUrlPathToUrlTemplateMatcher, RegExUrlMatcher>();
_services.TryAddSingleton<IUrlPathPlaceholderNameAndValueFinder, UrlPathPlaceholderNameAndValueFinder>(); _services.TryAddSingleton<IPlaceholderNameAndValueFinder, UrlPathPlaceholderNameAndValueFinder>();
_services.TryAddSingleton<IDownstreamPathPlaceholderReplacer, DownstreamTemplatePathPlaceholderReplacer>(); _services.TryAddSingleton<IDownstreamPathPlaceholderReplacer, DownstreamTemplatePathPlaceholderReplacer>();
_services.TryAddSingleton<IDownstreamRouteFinder, DownstreamRouteFinder.Finder.DownstreamRouteFinder>(); _services.TryAddSingleton<IDownstreamRouteFinder, DownstreamRouteFinder.Finder.DownstreamRouteFinder>();
_services.TryAddSingleton<IHttpRequester, HttpClientHttpRequester>(); _services.TryAddSingleton<IHttpRequester, HttpClientHttpRequester>();

View File

@ -6,12 +6,12 @@ namespace Ocelot.DownstreamRouteFinder
{ {
public class DownstreamRoute public class DownstreamRoute
{ {
public DownstreamRoute(List<UrlPathPlaceholderNameAndValue> templatePlaceholderNameAndValues, ReRoute reRoute) public DownstreamRoute(List<PlaceholderNameAndValue> templatePlaceholderNameAndValues, ReRoute reRoute)
{ {
TemplatePlaceholderNameAndValues = templatePlaceholderNameAndValues; TemplatePlaceholderNameAndValues = templatePlaceholderNameAndValues;
ReRoute = reRoute; ReRoute = reRoute;
} }
public List<UrlPathPlaceholderNameAndValue> TemplatePlaceholderNameAndValues { get; private set; } public List<PlaceholderNameAndValue> TemplatePlaceholderNameAndValues { get; private set; }
public ReRoute ReRoute { get; private set; } public ReRoute ReRoute { get; private set; }
} }
} }

View File

@ -13,34 +13,30 @@ namespace Ocelot.DownstreamRouteFinder.Finder
public class DownstreamRouteFinder : IDownstreamRouteFinder public class DownstreamRouteFinder : IDownstreamRouteFinder
{ {
private readonly IUrlPathToUrlTemplateMatcher _urlMatcher; private readonly IUrlPathToUrlTemplateMatcher _urlMatcher;
private readonly IUrlPathPlaceholderNameAndValueFinder _urlPathPlaceholderNameAndValueFinder; private readonly IPlaceholderNameAndValueFinder __placeholderNameAndValueFinder;
public DownstreamRouteFinder(IUrlPathToUrlTemplateMatcher urlMatcher, IUrlPathPlaceholderNameAndValueFinder urlPathPlaceholderNameAndValueFinder) public DownstreamRouteFinder(IUrlPathToUrlTemplateMatcher urlMatcher, IPlaceholderNameAndValueFinder urlPathPlaceholderNameAndValueFinder)
{ {
_urlMatcher = urlMatcher; _urlMatcher = urlMatcher;
_urlPathPlaceholderNameAndValueFinder = urlPathPlaceholderNameAndValueFinder; __placeholderNameAndValueFinder = urlPathPlaceholderNameAndValueFinder;
} }
public Response<DownstreamRoute> FindDownstreamRoute(string upstreamUrlPath, string upstreamHttpMethod, IOcelotConfiguration configuration) public Response<DownstreamRoute> FindDownstreamRoute(string path, string httpMethod, IOcelotConfiguration configuration)
{ {
var applicableReRoutes = configuration.ReRoutes.Where(r => r.UpstreamHttpMethod.Count == 0 || r.UpstreamHttpMethod.Select(x => x.Method.ToLower()).Contains(upstreamHttpMethod.ToLower())); var applicableReRoutes = configuration.ReRoutes.Where(r => r.UpstreamHttpMethod.Count == 0 || r.UpstreamHttpMethod.Select(x => x.Method.ToLower()).Contains(httpMethod.ToLower())).OrderByDescending(x => x.UpstreamTemplatePattern.Priority);
foreach (var reRoute in applicableReRoutes) foreach (var reRoute in applicableReRoutes)
{ {
if (upstreamUrlPath == reRoute.UpstreamTemplatePattern) if (path == reRoute.UpstreamTemplatePattern.Template)
{ {
var templateVariableNameAndValues = _urlPathPlaceholderNameAndValueFinder.Find(upstreamUrlPath, reRoute.UpstreamPathTemplate.Value); return GetPlaceholderNamesAndValues(path, reRoute);
return new OkResponse<DownstreamRoute>(new DownstreamRoute(templateVariableNameAndValues.Data, reRoute));
} }
var urlMatch = _urlMatcher.Match(upstreamUrlPath, reRoute.UpstreamTemplatePattern); var urlMatch = _urlMatcher.Match(path, reRoute.UpstreamTemplatePattern.Template);
if (urlMatch.Data.Match) if (urlMatch.Data.Match)
{ {
var templateVariableNameAndValues = _urlPathPlaceholderNameAndValueFinder.Find(upstreamUrlPath, reRoute.UpstreamPathTemplate.Value); return GetPlaceholderNamesAndValues(path, reRoute);
return new OkResponse<DownstreamRoute>(new DownstreamRoute(templateVariableNameAndValues.Data, reRoute));
} }
} }
@ -49,5 +45,12 @@ namespace Ocelot.DownstreamRouteFinder.Finder
new UnableToFindDownstreamRouteError() new UnableToFindDownstreamRouteError()
}); });
} }
private OkResponse<DownstreamRoute> GetPlaceholderNamesAndValues(string path, ReRoute reRoute)
{
var templatePlaceholderNameAndValues = __placeholderNameAndValueFinder.Find(path, reRoute.UpstreamPathTemplate.Value);
return new OkResponse<DownstreamRoute>(new DownstreamRoute(templatePlaceholderNameAndValues.Data, reRoute));
}
} }
} }

View File

@ -3,8 +3,8 @@ using Ocelot.Responses;
namespace Ocelot.DownstreamRouteFinder.UrlMatcher namespace Ocelot.DownstreamRouteFinder.UrlMatcher
{ {
public interface IUrlPathPlaceholderNameAndValueFinder public interface IPlaceholderNameAndValueFinder
{ {
Response<List<UrlPathPlaceholderNameAndValue>> Find(string upstreamUrlPath, string upstreamUrlPathTemplate); Response<List<PlaceholderNameAndValue>> Find(string path, string pathTemplate);
} }
} }

View File

@ -1,13 +1,13 @@
namespace Ocelot.DownstreamRouteFinder.UrlMatcher namespace Ocelot.DownstreamRouteFinder.UrlMatcher
{ {
public class UrlPathPlaceholderNameAndValue public class PlaceholderNameAndValue
{ {
public UrlPathPlaceholderNameAndValue(string templateVariableName, string templateVariableValue) public PlaceholderNameAndValue(string name, string value)
{ {
TemplateVariableName = templateVariableName; Name = name;
TemplateVariableValue = templateVariableValue; Value = value;
} }
public string TemplateVariableName {get;private set;} public string Name {get;private set;}
public string TemplateVariableValue {get;private set;} public string Value {get;private set;}
} }
} }

View File

@ -3,44 +3,72 @@ using Ocelot.Responses;
namespace Ocelot.DownstreamRouteFinder.UrlMatcher namespace Ocelot.DownstreamRouteFinder.UrlMatcher
{ {
public class UrlPathPlaceholderNameAndValueFinder : IUrlPathPlaceholderNameAndValueFinder public class UrlPathPlaceholderNameAndValueFinder : IPlaceholderNameAndValueFinder
{ {
public Response<List<UrlPathPlaceholderNameAndValue>> Find(string upstreamUrlPath, string upstreamUrlPathTemplate) public Response<List<PlaceholderNameAndValue>> Find(string path, string pathTemplate)
{ {
var templateKeysAndValues = new List<UrlPathPlaceholderNameAndValue>(); var placeHolderNameAndValues = new List<PlaceholderNameAndValue>();
int counterForUrl = 0; int counterForPath = 0;
for (int counterForTemplate = 0; counterForTemplate < upstreamUrlPathTemplate.Length; counterForTemplate++) for (int counterForTemplate = 0; counterForTemplate < pathTemplate.Length; counterForTemplate++)
{ {
if ((upstreamUrlPath.Length > counterForUrl) && CharactersDontMatch(upstreamUrlPathTemplate[counterForTemplate], upstreamUrlPath[counterForUrl]) && ContinueScanningUrl(counterForUrl,upstreamUrlPath.Length)) if ((path.Length > counterForPath) && CharactersDontMatch(pathTemplate[counterForTemplate], path[counterForPath]) && ContinueScanningUrl(counterForPath,path.Length))
{ {
if (IsPlaceholder(upstreamUrlPathTemplate[counterForTemplate])) if (IsPlaceholder(pathTemplate[counterForTemplate]))
{ {
var variableName = GetPlaceholderVariableName(upstreamUrlPathTemplate, counterForTemplate); var placeholderName = GetPlaceholderName(pathTemplate, counterForTemplate);
var variableValue = GetPlaceholderVariableValue(upstreamUrlPathTemplate, variableName, upstreamUrlPath, counterForUrl); var placeholderValue = GetPlaceholderValue(pathTemplate, placeholderName, path, counterForPath);
var templateVariableNameAndValue = new UrlPathPlaceholderNameAndValue(variableName, variableValue); placeHolderNameAndValues.Add(new PlaceholderNameAndValue(placeholderName, placeholderValue));
templateKeysAndValues.Add(templateVariableNameAndValue); counterForTemplate = GetNextCounterPosition(pathTemplate, counterForTemplate, '}');
counterForTemplate = GetNextCounterPosition(upstreamUrlPathTemplate, counterForTemplate, '}'); counterForPath = GetNextCounterPosition(path, counterForPath, '/');
counterForUrl = GetNextCounterPosition(upstreamUrlPath, counterForUrl, '/');
continue; continue;
} }
return new OkResponse<List<UrlPathPlaceholderNameAndValue>>(templateKeysAndValues); return new OkResponse<List<PlaceholderNameAndValue>>(placeHolderNameAndValues);
} }
counterForUrl++; else if(IsCatchAll(path, counterForPath, pathTemplate))
{
var endOfPlaceholder = GetNextCounterPosition(pathTemplate, counterForTemplate, '}');
var placeholderName = GetPlaceholderName(pathTemplate, 1);
if(NothingAfterFirstForwardSlash(path))
{
placeHolderNameAndValues.Add(new PlaceholderNameAndValue(placeholderName, ""));
}
else
{
var placeholderValue = GetPlaceholderValue(pathTemplate, placeholderName, path, counterForPath + 1);
placeHolderNameAndValues.Add(new PlaceholderNameAndValue(placeholderName, placeholderValue));
} }
return new OkResponse<List<UrlPathPlaceholderNameAndValue>>(templateKeysAndValues); counterForTemplate = endOfPlaceholder;
}
counterForPath++;
} }
private string GetPlaceholderVariableValue(string urlPathTemplate, string variableName, string urlPath, int counterForUrl) return new OkResponse<List<PlaceholderNameAndValue>>(placeHolderNameAndValues);
}
private bool IsCatchAll(string path, int counterForPath, string pathTemplate)
{
return string.IsNullOrEmpty(path) || (path.Length > counterForPath && path[counterForPath] == '/') && pathTemplate.Length > 1
&& pathTemplate.Substring(0, 2) == "/{"
&& pathTemplate.IndexOf('}') == pathTemplate.Length - 1;
}
private bool NothingAfterFirstForwardSlash(string path)
{
return path.Length == 1 || path.Length == 0;
}
private string GetPlaceholderValue(string urlPathTemplate, string variableName, string urlPath, int counterForUrl)
{ {
var positionOfNextSlash = urlPath.IndexOf('/', counterForUrl); var positionOfNextSlash = urlPath.IndexOf('/', counterForUrl);
@ -54,7 +82,7 @@ namespace Ocelot.DownstreamRouteFinder.UrlMatcher
return variableValue; return variableValue;
} }
private string GetPlaceholderVariableName(string urlPathTemplate, int counterForTemplate) private string GetPlaceholderName(string urlPathTemplate, int counterForTemplate)
{ {
var postitionOfPlaceHolderClosingBracket = urlPathTemplate.IndexOf('}', counterForTemplate) + 1; var postitionOfPlaceHolderClosingBracket = urlPathTemplate.IndexOf('}', counterForTemplate) + 1;

View File

@ -8,7 +8,7 @@ namespace Ocelot.DownstreamUrlCreator.UrlTemplateReplacer
{ {
public class DownstreamTemplatePathPlaceholderReplacer : IDownstreamPathPlaceholderReplacer public class DownstreamTemplatePathPlaceholderReplacer : IDownstreamPathPlaceholderReplacer
{ {
public Response<DownstreamPath> Replace(PathTemplate downstreamPathTemplate, List<UrlPathPlaceholderNameAndValue> urlPathPlaceholderNameAndValues) public Response<DownstreamPath> Replace(PathTemplate downstreamPathTemplate, List<PlaceholderNameAndValue> urlPathPlaceholderNameAndValues)
{ {
var downstreamPath = new StringBuilder(); var downstreamPath = new StringBuilder();
@ -16,7 +16,7 @@ namespace Ocelot.DownstreamUrlCreator.UrlTemplateReplacer
foreach (var placeholderVariableAndValue in urlPathPlaceholderNameAndValues) foreach (var placeholderVariableAndValue in urlPathPlaceholderNameAndValues)
{ {
downstreamPath.Replace(placeholderVariableAndValue.TemplateVariableName, placeholderVariableAndValue.TemplateVariableValue); downstreamPath.Replace(placeholderVariableAndValue.Name, placeholderVariableAndValue.Value);
} }
return new OkResponse<DownstreamPath>(new DownstreamPath(downstreamPath.ToString())); return new OkResponse<DownstreamPath>(new DownstreamPath(downstreamPath.ToString()));

View File

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

View File

@ -0,0 +1,14 @@
namespace Ocelot.Values
{
public class UpstreamPathTemplate
{
public UpstreamPathTemplate(string template, int priority)
{
Template = template;
Priority = priority;
}
public string Template {get;}
public int Priority {get;}
}
}

View File

@ -52,7 +52,7 @@ namespace Ocelot.AcceptanceTests
} }
}; };
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "", 200, "Hello from Laura")) this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879/", "/", 200, "Hello from Laura"))
.And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning()) .And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
@ -61,6 +61,145 @@ namespace Ocelot.AcceptanceTests
.BDDfy(); .BDDfy();
} }
[Fact]
public void should_return_response_200_favouring_forward_slash_with_path_route()
{
var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/{url}",
DownstreamScheme = "http",
DownstreamHost = "localhost",
DownstreamPort = 51880,
UpstreamPathTemplate = "/{url}",
UpstreamHttpMethod = new List<string> { "Get" },
},
new FileReRoute
{
DownstreamPathTemplate = "/",
DownstreamScheme = "http",
DownstreamHost = "localhost",
DownstreamPort = 51879,
UpstreamPathTemplate = "/",
UpstreamHttpMethod = new List<string> { "Get" },
}
}
};
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51880/", "/test", 200, "Hello from Laura"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/test"))
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
.BDDfy();
}
[Fact]
public void should_return_response_200_favouring_forward_slash()
{
var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/{url}",
DownstreamScheme = "http",
DownstreamHost = "localhost",
DownstreamPort = 51880,
UpstreamPathTemplate = "/{url}",
UpstreamHttpMethod = new List<string> { "Get" },
},
new FileReRoute
{
DownstreamPathTemplate = "/",
DownstreamScheme = "http",
DownstreamHost = "localhost",
DownstreamPort = 51879,
UpstreamPathTemplate = "/",
UpstreamHttpMethod = new List<string> { "Get" },
}
}
};
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879/", "/", 200, "Hello from Laura"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
.BDDfy();
}
[Fact]
public void should_return_response_200_favouring_forward_slash_route_because_it_is_first()
{
var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/",
DownstreamScheme = "http",
DownstreamHost = "localhost",
DownstreamPort = 51880,
UpstreamPathTemplate = "/",
UpstreamHttpMethod = new List<string> { "Get" },
},
new FileReRoute
{
DownstreamPathTemplate = "/{url}",
DownstreamScheme = "http",
DownstreamHost = "localhost",
DownstreamPort = 51879,
UpstreamPathTemplate = "/{url}",
UpstreamHttpMethod = new List<string> { "Get" },
}
}
};
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51880/", "/", 200, "Hello from Laura"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
.BDDfy();
}
[Fact]
public void should_return_response_200_with_nothing_and_placeholder_only()
{
var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/{url}",
DownstreamScheme = "http",
DownstreamHost = "localhost",
DownstreamPort = 51879,
UpstreamPathTemplate = "/{url}",
UpstreamHttpMethod = new List<string> { "Get" },
}
}
};
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/", 200, "Hello from Laura"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway(""))
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
.BDDfy();
}
[Fact] [Fact]
public void should_return_response_200_with_simple_url() public void should_return_response_200_with_simple_url()
{ {
@ -80,7 +219,7 @@ namespace Ocelot.AcceptanceTests
} }
}; };
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "", 200, "Hello from Laura")) this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/", 200, "Hello from Laura"))
.And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning()) .And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
@ -378,7 +517,7 @@ namespace Ocelot.AcceptanceTests
} }
}; };
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "", 201, string.Empty)) this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/", 201, string.Empty))
.And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning()) .And(x => _steps.GivenOcelotIsRunning())
.And(x => _steps.GivenThePostHasContent("postContent")) .And(x => _steps.GivenThePostHasContent("postContent"))
@ -406,7 +545,7 @@ namespace Ocelot.AcceptanceTests
} }
}; };
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "", 200, "Hello from Laura")) this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/newThing", 200, "Hello from Laura"))
.And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning()) .And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/newThing?DeviceType=IphoneApp&Browser=moonpigIphone&BrowserString=-&CountryCode=123&DeviceName=iPhone 5 (GSM+CDMA)&OperatingSystem=iPhone OS 7.1.2&BrowserVersion=3708AdHoc&ipAddress=-")) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/newThing?DeviceType=IphoneApp&Browser=moonpigIphone&BrowserString=-&CountryCode=123&DeviceName=iPhone 5 (GSM+CDMA)&OperatingSystem=iPhone OS 7.1.2&BrowserVersion=3708AdHoc&ipAddress=-"))
@ -434,7 +573,7 @@ namespace Ocelot.AcceptanceTests
} }
}; };
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/myApp1Name/api/products/1", 200, "Some Product")) this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/api/products/1", 200, "Some Product"))
.And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning()) .And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/myApp1Name/api/products/1")) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/myApp1Name/api/products/1"))
@ -490,7 +629,7 @@ namespace Ocelot.AcceptanceTests
} }
}; };
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "", 200, "Hello from Laura")) this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", "/", 200, "Hello from Laura"))
.And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning()) .And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/")) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
@ -564,7 +703,7 @@ namespace Ocelot.AcceptanceTests
} }
}; };
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51899", "", 200, "Hello from Laura")) this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51899", "/api/swagger/lib/backbone-min.js", 200, "Hello from Laura"))
.And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning()) .And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/platform/swagger/lib/backbone-min.js")) .When(x => _steps.WhenIGetUrlOnTheApiGateway("/platform/swagger/lib/backbone-min.js"))
@ -587,8 +726,17 @@ namespace Ocelot.AcceptanceTests
app.Run(async context => app.Run(async context =>
{ {
_downstreamPath = !string.IsNullOrEmpty(context.Request.PathBase.Value) ? context.Request.PathBase.Value : context.Request.Path.Value; _downstreamPath = !string.IsNullOrEmpty(context.Request.PathBase.Value) ? context.Request.PathBase.Value : context.Request.Path.Value;
if(_downstreamPath != basePath)
{
context.Response.StatusCode = statusCode;
await context.Response.WriteAsync("downstream path didnt match base path");
}
else
{
context.Response.StatusCode = statusCode; context.Response.StatusCode = statusCode;
await context.Response.WriteAsync(responseBody); await context.Response.WriteAsync(responseBody);
}
}); });
}) })
.Build(); .Build();

View File

@ -29,7 +29,7 @@
{ {
this.Given(x => x.GivenTheDownStreamRouteIs( this.Given(x => x.GivenTheDownStreamRouteIs(
new DownstreamRoute( new DownstreamRoute(
new List<UrlPathPlaceholderNameAndValue>(), new List<PlaceholderNameAndValue>(),
new ReRouteBuilder().WithUpstreamHttpMethod(new List<string> { "Get" }).Build()))) new ReRouteBuilder().WithUpstreamHttpMethod(new List<string> { "Get" }).Build())))
.When(x => x.WhenICallTheMiddleware()) .When(x => x.WhenICallTheMiddleware())
.Then(x => x.ThenTheUserIsAuthenticated()) .Then(x => x.ThenTheUserIsAuthenticated())

View File

@ -32,7 +32,7 @@
[Fact] [Fact]
public void should_call_authorisation_service() public void should_call_authorisation_service()
{ {
this.Given(x => x.GivenTheDownStreamRouteIs(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), this.Given(x => x.GivenTheDownStreamRouteIs(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder() new ReRouteBuilder()
.WithIsAuthorised(true) .WithIsAuthorised(true)
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })

View File

@ -94,7 +94,7 @@
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.Build(); .Build();
var downstreamRoute = new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), reRoute); var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(), reRoute);
ScopedRepository ScopedRepository
.Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>())) .Setup(x => x.Get<DownstreamRoute>(It.IsAny<string>()))

View File

@ -31,7 +31,7 @@
[Fact] [Fact]
public void should_call_claims_to_request_correctly() public void should_call_claims_to_request_correctly()
{ {
var downstreamRoute = new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamPathTemplate("any old string") .WithDownstreamPathTemplate("any old string")
.WithClaimsToClaims(new List<ClaimToThing> .WithClaimsToClaims(new List<ClaimToThing>

View File

@ -18,6 +18,7 @@ namespace Ocelot.UnitTests.Configuration
using Ocelot.DependencyInjection; using Ocelot.DependencyInjection;
using Ocelot.Errors; using Ocelot.Errors;
using Ocelot.UnitTests.TestData; using Ocelot.UnitTests.TestData;
using Ocelot.Values;
public class FileConfigurationCreatorTests public class FileConfigurationCreatorTests
{ {
@ -367,7 +368,7 @@ namespace Ocelot.UnitTests.Configuration
.WithDownstreamPathTemplate("/products/{productId}") .WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}") .WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern("(?i)/api/products/.*/$") .WithUpstreamTemplatePattern(new UpstreamPathTemplate("(?i)/api/products/.*/$", 1))
.Build() .Build()
})) }))
.BDDfy(); .BDDfy();
@ -580,7 +581,7 @@ namespace Ocelot.UnitTests.Configuration
result.DownstreamPathTemplate.Value.ShouldBe(expected.DownstreamPathTemplate.Value); result.DownstreamPathTemplate.Value.ShouldBe(expected.DownstreamPathTemplate.Value);
result.UpstreamHttpMethod.ShouldBe(expected.UpstreamHttpMethod); result.UpstreamHttpMethod.ShouldBe(expected.UpstreamHttpMethod);
result.UpstreamPathTemplate.Value.ShouldBe(expected.UpstreamPathTemplate.Value); result.UpstreamPathTemplate.Value.ShouldBe(expected.UpstreamPathTemplate.Value);
result.UpstreamTemplatePattern.ShouldBe(expected.UpstreamTemplatePattern); result.UpstreamTemplatePattern?.Template.ShouldBe(expected.UpstreamTemplatePattern?.Template);
result.ClaimsToClaims.Count.ShouldBe(expected.ClaimsToClaims.Count); result.ClaimsToClaims.Count.ShouldBe(expected.ClaimsToClaims.Count);
result.ClaimsToHeaders.Count.ShouldBe(expected.ClaimsToHeaders.Count); result.ClaimsToHeaders.Count.ShouldBe(expected.ClaimsToHeaders.Count);
result.ClaimsToQueries.Count.ShouldBe(expected.ClaimsToQueries.Count); result.ClaimsToQueries.Count.ShouldBe(expected.ClaimsToQueries.Count);
@ -623,7 +624,7 @@ namespace Ocelot.UnitTests.Configuration
{ {
_upstreamTemplatePatternCreator _upstreamTemplatePatternCreator
.Setup(x => x.Create(It.IsAny<FileReRoute>())) .Setup(x => x.Create(It.IsAny<FileReRoute>()))
.Returns(pattern); .Returns(new UpstreamPathTemplate(pattern, 1));
} }
private void ThenTheRequestIdKeyCreatorIsCalledCorrectly() private void ThenTheRequestIdKeyCreatorIsCalledCorrectly()

View File

@ -1,5 +1,7 @@
using System;
using Ocelot.Configuration.Creator; using Ocelot.Configuration.Creator;
using Ocelot.Configuration.File; using Ocelot.Configuration.File;
using Ocelot.Values;
using Shouldly; using Shouldly;
using TestStack.BDDfy; using TestStack.BDDfy;
using Xunit; using Xunit;
@ -10,7 +12,7 @@ namespace Ocelot.UnitTests.Configuration
{ {
private FileReRoute _fileReRoute; private FileReRoute _fileReRoute;
private UpstreamTemplatePatternCreator _creator; private UpstreamTemplatePatternCreator _creator;
private string _result; private UpstreamPathTemplate _result;
public UpstreamTemplatePatternCreatorTests() public UpstreamTemplatePatternCreatorTests()
{ {
@ -29,6 +31,7 @@ namespace Ocelot.UnitTests.Configuration
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute)) this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
.When(x => x.WhenICreateTheTemplatePattern()) .When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/PRODUCTS/[0-9a-zA-Z].*$")) .Then(x => x.ThenTheFollowingIsReturned("^(?i)/PRODUCTS/[0-9a-zA-Z].*$"))
.And(x => ThenThePriorityIs(1))
.BDDfy(); .BDDfy();
} }
@ -45,6 +48,7 @@ namespace Ocelot.UnitTests.Configuration
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute)) this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
.When(x => x.WhenICreateTheTemplatePattern()) .When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/PRODUCTS(/|)$")) .Then(x => x.ThenTheFollowingIsReturned("^(?i)/PRODUCTS(/|)$"))
.And(x => ThenThePriorityIs(1))
.BDDfy(); .BDDfy();
} }
@ -59,6 +63,7 @@ namespace Ocelot.UnitTests.Configuration
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute)) this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
.When(x => x.WhenICreateTheTemplatePattern()) .When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^/PRODUCTS/[0-9a-zA-Z].*$")) .Then(x => x.ThenTheFollowingIsReturned("^/PRODUCTS/[0-9a-zA-Z].*$"))
.And(x => ThenThePriorityIs(1))
.BDDfy(); .BDDfy();
} }
@ -74,6 +79,7 @@ namespace Ocelot.UnitTests.Configuration
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute)) this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
.When(x => x.WhenICreateTheTemplatePattern()) .When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^/api/products/[0-9a-zA-Z].*$")) .Then(x => x.ThenTheFollowingIsReturned("^/api/products/[0-9a-zA-Z].*$"))
.And(x => ThenThePriorityIs(1))
.BDDfy(); .BDDfy();
} }
@ -89,6 +95,7 @@ namespace Ocelot.UnitTests.Configuration
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute)) this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
.When(x => x.WhenICreateTheTemplatePattern()) .When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^/api/products/[0-9a-zA-Z].*/variants/[0-9a-zA-Z].*$")) .Then(x => x.ThenTheFollowingIsReturned("^/api/products/[0-9a-zA-Z].*/variants/[0-9a-zA-Z].*$"))
.And(x => ThenThePriorityIs(1))
.BDDfy(); .BDDfy();
} }
@ -104,6 +111,7 @@ namespace Ocelot.UnitTests.Configuration
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute)) this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
.When(x => x.WhenICreateTheTemplatePattern()) .When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^/api/products/[0-9a-zA-Z].*/variants/[0-9a-zA-Z].*(/|)$")) .Then(x => x.ThenTheFollowingIsReturned("^/api/products/[0-9a-zA-Z].*/variants/[0-9a-zA-Z].*(/|)$"))
.And(x => ThenThePriorityIs(1))
.BDDfy(); .BDDfy();
} }
@ -118,6 +126,7 @@ namespace Ocelot.UnitTests.Configuration
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute)) this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
.When(x => x.WhenICreateTheTemplatePattern()) .When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^/$")) .Then(x => x.ThenTheFollowingIsReturned("^/$"))
.And(x => ThenThePriorityIs(1))
.BDDfy(); .BDDfy();
} }
@ -132,6 +141,7 @@ namespace Ocelot.UnitTests.Configuration
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute)) this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
.When(x => x.WhenICreateTheTemplatePattern()) .When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^/.*")) .Then(x => x.ThenTheFollowingIsReturned("^/.*"))
.And(x => ThenThePriorityIs(0))
.BDDfy(); .BDDfy();
} }
@ -147,6 +157,7 @@ namespace Ocelot.UnitTests.Configuration
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute)) this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
.When(x => x.WhenICreateTheTemplatePattern()) .When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^/[0-9a-zA-Z].*/products/variants/[0-9a-zA-Z].*(/|)$")) .Then(x => x.ThenTheFollowingIsReturned("^/[0-9a-zA-Z].*/products/variants/[0-9a-zA-Z].*(/|)$"))
.And(x => ThenThePriorityIs(1))
.BDDfy(); .BDDfy();
} }
@ -162,7 +173,12 @@ namespace Ocelot.UnitTests.Configuration
private void ThenTheFollowingIsReturned(string expected) private void ThenTheFollowingIsReturned(string expected)
{ {
_result.ShouldBe(expected); _result.Template.ShouldBe(expected);
}
private void ThenThePriorityIs(int v)
{
_result.Priority.ShouldBe(v);
} }
} }
} }

View File

@ -38,7 +38,7 @@
this.Given(x => x.GivenTheDownStreamRouteFinderReturns( this.Given(x => x.GivenTheDownStreamRouteFinderReturns(
new DownstreamRoute( new DownstreamRoute(
new List<UrlPathPlaceholderNameAndValue>(), new List<PlaceholderNameAndValue>(),
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamPathTemplate("any old string") .WithDownstreamPathTemplate("any old string")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })

View File

@ -2,11 +2,13 @@
using Moq; using Moq;
using Ocelot.Configuration; using Ocelot.Configuration;
using Ocelot.Configuration.Builder; using Ocelot.Configuration.Builder;
using Ocelot.Configuration.Creator;
using Ocelot.Configuration.Provider; using Ocelot.Configuration.Provider;
using Ocelot.DownstreamRouteFinder; using Ocelot.DownstreamRouteFinder;
using Ocelot.DownstreamRouteFinder.Finder; using Ocelot.DownstreamRouteFinder.Finder;
using Ocelot.DownstreamRouteFinder.UrlMatcher; using Ocelot.DownstreamRouteFinder.UrlMatcher;
using Ocelot.Responses; using Ocelot.Responses;
using Ocelot.Values;
using Shouldly; using Shouldly;
using TestStack.BDDfy; using TestStack.BDDfy;
using Xunit; using Xunit;
@ -17,7 +19,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
{ {
private readonly IDownstreamRouteFinder _downstreamRouteFinder; private readonly IDownstreamRouteFinder _downstreamRouteFinder;
private readonly Mock<IUrlPathToUrlTemplateMatcher> _mockMatcher; private readonly Mock<IUrlPathToUrlTemplateMatcher> _mockMatcher;
private readonly Mock<IUrlPathPlaceholderNameAndValueFinder> _finder; private readonly Mock<IPlaceholderNameAndValueFinder> _finder;
private string _upstreamUrlPath; private string _upstreamUrlPath;
private Response<DownstreamRoute> _result; private Response<DownstreamRoute> _result;
private List<ReRoute> _reRoutesConfig; private List<ReRoute> _reRoutesConfig;
@ -28,10 +30,84 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
public DownstreamRouteFinderTests() public DownstreamRouteFinderTests()
{ {
_mockMatcher = new Mock<IUrlPathToUrlTemplateMatcher>(); _mockMatcher = new Mock<IUrlPathToUrlTemplateMatcher>();
_finder = new Mock<IUrlPathPlaceholderNameAndValueFinder>(); _finder = new Mock<IPlaceholderNameAndValueFinder>();
_downstreamRouteFinder = new Ocelot.DownstreamRouteFinder.Finder.DownstreamRouteFinder(_mockMatcher.Object, _finder.Object); _downstreamRouteFinder = new Ocelot.DownstreamRouteFinder.Finder.DownstreamRouteFinder(_mockMatcher.Object, _finder.Object);
} }
[Fact]
public void should_return_highest_priority_when_first()
{
var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("someUpstreamPath"))
.And(x => x.GivenTheTemplateVariableAndNameFinderReturns(
new OkResponse<List<PlaceholderNameAndValue>>(new List<PlaceholderNameAndValue>())))
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
.Build(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 0))
.Build()
}, string.Empty, serviceProviderConfig))
.And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(true))))
.And(x => x.GivenTheUpstreamHttpMethodIs("Post"))
.When(x => x.WhenICallTheFinder())
.Then(x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
.Build()
)))
.BDDfy();
}
[Fact]
public void should_return_highest_priority_when_lowest()
{
var serviceProviderConfig = new ServiceProviderConfigurationBuilder().Build();
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("someUpstreamPath"))
.And(x => x.GivenTheTemplateVariableAndNameFinderReturns(
new OkResponse<List<PlaceholderNameAndValue>>(new List<PlaceholderNameAndValue>())))
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 0))
.Build(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
.Build()
}, string.Empty, serviceProviderConfig))
.And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(true))))
.And(x => x.GivenTheUpstreamHttpMethodIs("Post"))
.When(x => x.WhenICallTheFinder())
.Then(x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("test", 1))
.WithUpstreamHttpMethod(new List<string> { "Post" })
.Build()
)))
.BDDfy();
}
[Fact] [Fact]
public void should_return_route() public void should_return_route()
{ {
@ -39,15 +115,15 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("matchInUrlMatcher/")) this.Given(x => x.GivenThereIsAnUpstreamUrlPath("matchInUrlMatcher/"))
.And(x =>x.GivenTheTemplateVariableAndNameFinderReturns( .And(x =>x.GivenTheTemplateVariableAndNameFinderReturns(
new OkResponse<List<UrlPathPlaceholderNameAndValue>>( new OkResponse<List<PlaceholderNameAndValue>>(
new List<UrlPathPlaceholderNameAndValue>()))) new List<PlaceholderNameAndValue>())))
.And(x => x.GivenTheConfigurationIs(new List<ReRoute> .And(x => x.GivenTheConfigurationIs(new List<ReRoute>
{ {
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath") .WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern("someUpstreamPath") .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.Build() .Build()
}, string.Empty, serviceProviderConfig }, string.Empty, serviceProviderConfig
)) ))
@ -56,10 +132,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.When(x => x.WhenICallTheFinder()) .When(x => x.WhenICallTheFinder())
.Then( .Then(
x => x.ThenTheFollowingIsReturned(new DownstreamRoute( x => x.ThenTheFollowingIsReturned(new DownstreamRoute(
new List<UrlPathPlaceholderNameAndValue>(), new List<PlaceholderNameAndValue>(),
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.Build() .Build()
))) )))
.And(x => x.ThenTheUrlMatcherIsCalledCorrectly()) .And(x => x.ThenTheUrlMatcherIsCalledCorrectly())
@ -74,15 +151,15 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("matchInUrlMatcher")) this.Given(x => x.GivenThereIsAnUpstreamUrlPath("matchInUrlMatcher"))
.And(x =>x.GivenTheTemplateVariableAndNameFinderReturns( .And(x =>x.GivenTheTemplateVariableAndNameFinderReturns(
new OkResponse<List<UrlPathPlaceholderNameAndValue>>( new OkResponse<List<PlaceholderNameAndValue>>(
new List<UrlPathPlaceholderNameAndValue>()))) new List<PlaceholderNameAndValue>())))
.And(x => x.GivenTheConfigurationIs(new List<ReRoute> .And(x => x.GivenTheConfigurationIs(new List<ReRoute>
{ {
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath") .WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern("someUpstreamPath") .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.Build() .Build()
}, string.Empty, serviceProviderConfig }, string.Empty, serviceProviderConfig
)) ))
@ -91,10 +168,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.When(x => x.WhenICallTheFinder()) .When(x => x.WhenICallTheFinder())
.Then( .Then(
x => x.ThenTheFollowingIsReturned(new DownstreamRoute( x => x.ThenTheFollowingIsReturned(new DownstreamRoute(
new List<UrlPathPlaceholderNameAndValue>(), new List<PlaceholderNameAndValue>(),
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.Build() .Build()
))) )))
.And(x => x.ThenTheUrlMatcherIsCalledCorrectly("matchInUrlMatcher")) .And(x => x.ThenTheUrlMatcherIsCalledCorrectly("matchInUrlMatcher"))
@ -110,14 +188,14 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.And( .And(
x => x =>
x.GivenTheTemplateVariableAndNameFinderReturns( x.GivenTheTemplateVariableAndNameFinderReturns(
new OkResponse<List<UrlPathPlaceholderNameAndValue>>(new List<UrlPathPlaceholderNameAndValue>()))) new OkResponse<List<PlaceholderNameAndValue>>(new List<PlaceholderNameAndValue>())))
.And(x => x.GivenTheConfigurationIs(new List<ReRoute> .And(x => x.GivenTheConfigurationIs(new List<ReRoute>
{ {
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath") .WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern("someUpstreamPath") .WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.Build() .Build()
}, string.Empty, serviceProviderConfig }, string.Empty, serviceProviderConfig
)) ))
@ -125,10 +203,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.And(x => x.GivenTheUpstreamHttpMethodIs("Get")) .And(x => x.GivenTheUpstreamHttpMethodIs("Get"))
.When(x => x.WhenICallTheFinder()) .When(x => x.WhenICallTheFinder())
.Then( .Then(
x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("someUpstreamPath", 1))
.Build() .Build()
))) )))
.And(x => x.ThenTheUrlMatcherIsNotCalled()) .And(x => x.ThenTheUrlMatcherIsNotCalled())
@ -144,20 +223,20 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.And( .And(
x => x =>
x.GivenTheTemplateVariableAndNameFinderReturns( x.GivenTheTemplateVariableAndNameFinderReturns(
new OkResponse<List<UrlPathPlaceholderNameAndValue>>(new List<UrlPathPlaceholderNameAndValue>()))) new OkResponse<List<PlaceholderNameAndValue>>(new List<PlaceholderNameAndValue>())))
.And(x => x.GivenTheConfigurationIs(new List<ReRoute> .And(x => x.GivenTheConfigurationIs(new List<ReRoute>
{ {
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath") .WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern("") .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.Build(), .Build(),
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPathForAPost") .WithDownstreamPathTemplate("someDownstreamPathForAPost")
.WithUpstreamPathTemplate("someUpstreamPath") .WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" }) .WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern("") .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.Build() .Build()
}, string.Empty, serviceProviderConfig }, string.Empty, serviceProviderConfig
)) ))
@ -165,10 +244,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.And(x => x.GivenTheUpstreamHttpMethodIs("Post")) .And(x => x.GivenTheUpstreamHttpMethodIs("Post"))
.When(x => x.WhenICallTheFinder()) .When(x => x.WhenICallTheFinder())
.Then( .Then(
x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPathForAPost") .WithDownstreamPathTemplate("someDownstreamPathForAPost")
.WithUpstreamHttpMethod(new List<string> { "Post" }) .WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.Build() .Build()
))) )))
.BDDfy(); .BDDfy();
@ -186,7 +266,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.WithDownstreamPathTemplate("somPath") .WithDownstreamPathTemplate("somPath")
.WithUpstreamPathTemplate("somePath") .WithUpstreamPathTemplate("somePath")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.WithUpstreamTemplatePattern("somePath") .WithUpstreamTemplatePattern(new UpstreamPathTemplate("somePath", 1))
.Build(), .Build(),
}, string.Empty, serviceProviderConfig }, string.Empty, serviceProviderConfig
)) ))
@ -208,14 +288,14 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.And( .And(
x => x =>
x.GivenTheTemplateVariableAndNameFinderReturns( x.GivenTheTemplateVariableAndNameFinderReturns(
new OkResponse<List<UrlPathPlaceholderNameAndValue>>(new List<UrlPathPlaceholderNameAndValue>()))) new OkResponse<List<PlaceholderNameAndValue>>(new List<PlaceholderNameAndValue>())))
.And(x => x.GivenTheConfigurationIs(new List<ReRoute> .And(x => x.GivenTheConfigurationIs(new List<ReRoute>
{ {
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath") .WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get", "Post" }) .WithUpstreamHttpMethod(new List<string> { "Get", "Post" })
.WithUpstreamTemplatePattern("") .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.Build() .Build()
}, string.Empty, serviceProviderConfig }, string.Empty, serviceProviderConfig
)) ))
@ -223,10 +303,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.And(x => x.GivenTheUpstreamHttpMethodIs("Post")) .And(x => x.GivenTheUpstreamHttpMethodIs("Post"))
.When(x => x.WhenICallTheFinder()) .When(x => x.WhenICallTheFinder())
.Then( .Then(
x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" }) .WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.Build() .Build()
))) )))
.BDDfy(); .BDDfy();
@ -241,14 +322,14 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.And( .And(
x => x =>
x.GivenTheTemplateVariableAndNameFinderReturns( x.GivenTheTemplateVariableAndNameFinderReturns(
new OkResponse<List<UrlPathPlaceholderNameAndValue>>(new List<UrlPathPlaceholderNameAndValue>()))) new OkResponse<List<PlaceholderNameAndValue>>(new List<PlaceholderNameAndValue>())))
.And(x => x.GivenTheConfigurationIs(new List<ReRoute> .And(x => x.GivenTheConfigurationIs(new List<ReRoute>
{ {
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath") .WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string>()) .WithUpstreamHttpMethod(new List<string>())
.WithUpstreamTemplatePattern("") .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.Build() .Build()
}, string.Empty, serviceProviderConfig }, string.Empty, serviceProviderConfig
)) ))
@ -256,10 +337,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.And(x => x.GivenTheUpstreamHttpMethodIs("Post")) .And(x => x.GivenTheUpstreamHttpMethodIs("Post"))
.When(x => x.WhenICallTheFinder()) .When(x => x.WhenICallTheFinder())
.Then( .Then(
x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Post" }) .WithUpstreamHttpMethod(new List<string> { "Post" })
.WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.Build() .Build()
))) )))
.BDDfy(); .BDDfy();
@ -274,14 +356,14 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.And( .And(
x => x =>
x.GivenTheTemplateVariableAndNameFinderReturns( x.GivenTheTemplateVariableAndNameFinderReturns(
new OkResponse<List<UrlPathPlaceholderNameAndValue>>(new List<UrlPathPlaceholderNameAndValue>()))) new OkResponse<List<PlaceholderNameAndValue>>(new List<PlaceholderNameAndValue>())))
.And(x => x.GivenTheConfigurationIs(new List<ReRoute> .And(x => x.GivenTheConfigurationIs(new List<ReRoute>
{ {
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath") .WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod(new List<string> { "Get", "Patch", "Delete" }) .WithUpstreamHttpMethod(new List<string> { "Get", "Patch", "Delete" })
.WithUpstreamTemplatePattern("") .WithUpstreamTemplatePattern(new UpstreamPathTemplate("", 1))
.Build() .Build()
}, string.Empty, serviceProviderConfig }, string.Empty, serviceProviderConfig
)) ))
@ -294,7 +376,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.BDDfy(); .BDDfy();
} }
private void GivenTheTemplateVariableAndNameFinderReturns(Response<List<UrlPathPlaceholderNameAndValue>> response) private void GivenTheTemplateVariableAndNameFinderReturns(Response<List<PlaceholderNameAndValue>> response)
{ {
_finder _finder
.Setup(x => x.Find(It.IsAny<string>(), It.IsAny<string>())) .Setup(x => x.Find(It.IsAny<string>(), It.IsAny<string>()))
@ -356,14 +438,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
private void ThenTheFollowingIsReturned(DownstreamRoute expected) private void ThenTheFollowingIsReturned(DownstreamRoute expected)
{ {
_result.Data.ReRoute.DownstreamPathTemplate.Value.ShouldBe(expected.ReRoute.DownstreamPathTemplate.Value); _result.Data.ReRoute.DownstreamPathTemplate.Value.ShouldBe(expected.ReRoute.DownstreamPathTemplate.Value);
_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++)
{ {
_result.Data.TemplatePlaceholderNameAndValues[i].TemplateVariableName.ShouldBe( _result.Data.TemplatePlaceholderNameAndValues[i].Name.ShouldBe(expected.TemplatePlaceholderNameAndValues[i].Name);
expected.TemplatePlaceholderNameAndValues[i].TemplateVariableName); _result.Data.TemplatePlaceholderNameAndValues[i].Value.ShouldBe(expected.TemplatePlaceholderNameAndValues[i].Value);
_result.Data.TemplatePlaceholderNameAndValues[i].TemplateVariableValue.ShouldBe(
expected.TemplatePlaceholderNameAndValues[i].TemplateVariableValue);
} }
_result.IsError.ShouldBeFalse(); _result.IsError.ShouldBeFalse();

View File

@ -18,6 +18,18 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
_urlMatcher = new RegExUrlMatcher(); _urlMatcher = new RegExUrlMatcher();
} }
[Fact]
public void should_not_match_slash_becaue_we_need_to_match_something_after_it()
{
const string RegExForwardSlashAndOnePlaceHolder = "^/[0-9a-zA-Z].*";
this.Given(x => x.GivenIHaveAUpstreamPath("/"))
.And(x => x.GivenIHaveAnUpstreamUrlTemplatePattern(RegExForwardSlashAndOnePlaceHolder))
.When(x => x.WhenIMatchThePaths())
.And(x => x.ThenTheResultIsFalse())
.BDDfy();
}
[Fact] [Fact]
public void should_not_match_forward_slash_only_regex() public void should_not_match_forward_slash_only_regex()
{ {

View File

@ -8,14 +8,14 @@ using Xunit;
namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
{ {
public class UrlPathToUrlTemplateMatcherTests public class UrlPathPlaceholderNameAndValueFinderTests
{ {
private readonly IUrlPathPlaceholderNameAndValueFinder _finder; private readonly IPlaceholderNameAndValueFinder _finder;
private string _downstreamUrlPath; private string _downstreamUrlPath;
private string _downstreamPathTemplate; private string _downstreamPathTemplate;
private Response<List<UrlPathPlaceholderNameAndValue>> _result; private Response<List<PlaceholderNameAndValue>> _result;
public UrlPathToUrlTemplateMatcherTests() public UrlPathPlaceholderNameAndValueFinderTests()
{ {
_finder = new UrlPathPlaceholderNameAndValueFinder(); _finder = new UrlPathPlaceholderNameAndValueFinder();
} }
@ -26,7 +26,82 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
this.Given(x => x.GivenIHaveAUpstreamPath("")) this.Given(x => x.GivenIHaveAUpstreamPath(""))
.And(x => x.GivenIHaveAnUpstreamUrlTemplate("")) .And(x => x.GivenIHaveAnUpstreamUrlTemplate(""))
.When(x => x.WhenIFindTheUrlVariableNamesAndValues()) .When(x => x.WhenIFindTheUrlVariableNamesAndValues())
.And(x => x.ThenTheTemplatesVariablesAre(new List<UrlPathPlaceholderNameAndValue>())) .And(x => x.ThenTheTemplatesVariablesAre(new List<PlaceholderNameAndValue>()))
.BDDfy();
}
[Fact]
public void can_match_down_stream_url_with_nothing_then_placeholder_no_value_is_blank()
{
var expectedTemplates = new List<PlaceholderNameAndValue>
{
new PlaceholderNameAndValue("{url}", "")
};
this.Given(x => x.GivenIHaveAUpstreamPath(""))
.And(x => x.GivenIHaveAnUpstreamUrlTemplate("/{url}"))
.When(x => x.WhenIFindTheUrlVariableNamesAndValues())
.And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
.BDDfy();
}
[Fact]
public void can_match_down_stream_url_with_nothing_then_placeholder_value_is_test()
{
var expectedTemplates = new List<PlaceholderNameAndValue>
{
new PlaceholderNameAndValue("{url}", "test")
};
this.Given(x => x.GivenIHaveAUpstreamPath("/test"))
.And(x => x.GivenIHaveAnUpstreamUrlTemplate("/{url}"))
.When(x => x.WhenIFindTheUrlVariableNamesAndValues())
.And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
.BDDfy();
}
[Fact]
public void can_match_down_stream_url_with_forward_slash_then_placeholder_no_value_is_blank()
{
var expectedTemplates = new List<PlaceholderNameAndValue>
{
new PlaceholderNameAndValue("{url}", "")
};
this.Given(x => x.GivenIHaveAUpstreamPath("/"))
.And(x => x.GivenIHaveAnUpstreamUrlTemplate("/{url}"))
.When(x => x.WhenIFindTheUrlVariableNamesAndValues())
.And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
.BDDfy();
}
[Fact]
public void can_match_down_stream_url_with_forward_slash()
{
var expectedTemplates = new List<PlaceholderNameAndValue>
{
};
this.Given(x => x.GivenIHaveAUpstreamPath("/"))
.And(x => x.GivenIHaveAnUpstreamUrlTemplate("/"))
.When(x => x.WhenIFindTheUrlVariableNamesAndValues())
.And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
.BDDfy();
}
[Fact]
public void can_match_down_stream_url_with_forward_slash_then_placeholder_then_another_value()
{
var expectedTemplates = new List<PlaceholderNameAndValue>
{
new PlaceholderNameAndValue("{url}", "1")
};
this.Given(x => x.GivenIHaveAUpstreamPath("/1/products"))
.And(x => x.GivenIHaveAnUpstreamUrlTemplate("/{url}/products"))
.When(x => x.WhenIFindTheUrlVariableNamesAndValues())
.And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
.BDDfy(); .BDDfy();
} }
@ -36,7 +111,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
this.Given(x => x.GivenIHaveAUpstreamPath("/products")) this.Given(x => x.GivenIHaveAUpstreamPath("/products"))
.And(x => x.GivenIHaveAnUpstreamUrlTemplate("/products/")) .And(x => x.GivenIHaveAnUpstreamUrlTemplate("/products/"))
.When(x => x.WhenIFindTheUrlVariableNamesAndValues()) .When(x => x.WhenIFindTheUrlVariableNamesAndValues())
.And(x => x.ThenTheTemplatesVariablesAre(new List<UrlPathPlaceholderNameAndValue>())) .And(x => x.ThenTheTemplatesVariablesAre(new List<PlaceholderNameAndValue>()))
.BDDfy(); .BDDfy();
} }
@ -46,7 +121,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
this.Given(x => x.GivenIHaveAUpstreamPath("api")) this.Given(x => x.GivenIHaveAUpstreamPath("api"))
.Given(x => x.GivenIHaveAnUpstreamUrlTemplate("api")) .Given(x => x.GivenIHaveAnUpstreamUrlTemplate("api"))
.When(x => x.WhenIFindTheUrlVariableNamesAndValues()) .When(x => x.WhenIFindTheUrlVariableNamesAndValues())
.And(x => x.ThenTheTemplatesVariablesAre(new List<UrlPathPlaceholderNameAndValue>())) .And(x => x.ThenTheTemplatesVariablesAre(new List<PlaceholderNameAndValue>()))
.BDDfy(); .BDDfy();
} }
@ -56,7 +131,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
this.Given(x => x.GivenIHaveAUpstreamPath("api/")) this.Given(x => x.GivenIHaveAUpstreamPath("api/"))
.Given(x => x.GivenIHaveAnUpstreamUrlTemplate("api/")) .Given(x => x.GivenIHaveAnUpstreamUrlTemplate("api/"))
.When(x => x.WhenIFindTheUrlVariableNamesAndValues()) .When(x => x.WhenIFindTheUrlVariableNamesAndValues())
.And(x => x.ThenTheTemplatesVariablesAre(new List<UrlPathPlaceholderNameAndValue>())) .And(x => x.ThenTheTemplatesVariablesAre(new List<PlaceholderNameAndValue>()))
.BDDfy(); .BDDfy();
} }
@ -66,16 +141,16 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/")) this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/"))
.Given(x => x.GivenIHaveAnUpstreamUrlTemplate("api/product/products/")) .Given(x => x.GivenIHaveAnUpstreamUrlTemplate("api/product/products/"))
.When(x => x.WhenIFindTheUrlVariableNamesAndValues()) .When(x => x.WhenIFindTheUrlVariableNamesAndValues())
.And(x => x.ThenTheTemplatesVariablesAre(new List<UrlPathPlaceholderNameAndValue>())) .And(x => x.ThenTheTemplatesVariablesAre(new List<PlaceholderNameAndValue>()))
.BDDfy(); .BDDfy();
} }
[Fact] [Fact]
public void can_match_down_stream_url_with_downstream_template_with_one_place_holder() public void can_match_down_stream_url_with_downstream_template_with_one_place_holder()
{ {
var expectedTemplates = new List<UrlPathPlaceholderNameAndValue> var expectedTemplates = new List<PlaceholderNameAndValue>
{ {
new UrlPathPlaceholderNameAndValue("{productId}", "1") new PlaceholderNameAndValue("{productId}", "1")
}; };
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1")) this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1"))
@ -88,10 +163,10 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
[Fact] [Fact]
public void can_match_down_stream_url_with_downstream_template_with_two_place_holders() public void can_match_down_stream_url_with_downstream_template_with_two_place_holders()
{ {
var expectedTemplates = new List<UrlPathPlaceholderNameAndValue> var expectedTemplates = new List<PlaceholderNameAndValue>
{ {
new UrlPathPlaceholderNameAndValue("{productId}", "1"), new PlaceholderNameAndValue("{productId}", "1"),
new UrlPathPlaceholderNameAndValue("{categoryId}", "2") new PlaceholderNameAndValue("{categoryId}", "2")
}; };
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/2")) this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/2"))
@ -104,10 +179,10 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
[Fact] [Fact]
public void can_match_down_stream_url_with_downstream_template_with_two_place_holders_seperated_by_something() public void can_match_down_stream_url_with_downstream_template_with_two_place_holders_seperated_by_something()
{ {
var expectedTemplates = new List<UrlPathPlaceholderNameAndValue> var expectedTemplates = new List<PlaceholderNameAndValue>
{ {
new UrlPathPlaceholderNameAndValue("{productId}", "1"), new PlaceholderNameAndValue("{productId}", "1"),
new UrlPathPlaceholderNameAndValue("{categoryId}", "2") new PlaceholderNameAndValue("{categoryId}", "2")
}; };
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/categories/2")) this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/categories/2"))
@ -120,11 +195,11 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
[Fact] [Fact]
public void can_match_down_stream_url_with_downstream_template_with_three_place_holders_seperated_by_something() public void can_match_down_stream_url_with_downstream_template_with_three_place_holders_seperated_by_something()
{ {
var expectedTemplates = new List<UrlPathPlaceholderNameAndValue> var expectedTemplates = new List<PlaceholderNameAndValue>
{ {
new UrlPathPlaceholderNameAndValue("{productId}", "1"), new PlaceholderNameAndValue("{productId}", "1"),
new UrlPathPlaceholderNameAndValue("{categoryId}", "2"), new PlaceholderNameAndValue("{categoryId}", "2"),
new UrlPathPlaceholderNameAndValue("{variantId}", "123") new PlaceholderNameAndValue("{variantId}", "123")
}; };
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/categories/2/variant/123")) this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/categories/2/variant/123"))
@ -137,10 +212,10 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
[Fact] [Fact]
public void can_match_down_stream_url_with_downstream_template_with_three_place_holders() public void can_match_down_stream_url_with_downstream_template_with_three_place_holders()
{ {
var expectedTemplates = new List<UrlPathPlaceholderNameAndValue> var expectedTemplates = new List<PlaceholderNameAndValue>
{ {
new UrlPathPlaceholderNameAndValue("{productId}", "1"), new PlaceholderNameAndValue("{productId}", "1"),
new UrlPathPlaceholderNameAndValue("{categoryId}", "2") new PlaceholderNameAndValue("{categoryId}", "2")
}; };
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/categories/2/variant/")) this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/categories/2/variant/"))
@ -153,9 +228,9 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
[Fact] [Fact]
public void can_match_down_stream_url_with_downstream_template_with_place_holder_to_final_url_path() public void can_match_down_stream_url_with_downstream_template_with_place_holder_to_final_url_path()
{ {
var expectedTemplates = new List<UrlPathPlaceholderNameAndValue> var expectedTemplates = new List<PlaceholderNameAndValue>
{ {
new UrlPathPlaceholderNameAndValue("{finalUrlPath}", "product/products/categories/"), new PlaceholderNameAndValue("{finalUrlPath}", "product/products/categories/"),
}; };
this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/categories/")) this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/categories/"))
@ -165,13 +240,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder.UrlMatcher
.BDDfy(); .BDDfy();
} }
private void ThenTheTemplatesVariablesAre(List<UrlPathPlaceholderNameAndValue> expectedResults) private void ThenTheTemplatesVariablesAre(List<PlaceholderNameAndValue> expectedResults)
{ {
foreach (var expectedResult in expectedResults) foreach (var expectedResult in expectedResults)
{ {
var result = _result.Data var result = _result.Data.First(t => t.Name == expectedResult.Name);
.First(t => t.TemplateVariableName == expectedResult.TemplateVariableName); result.Value.ShouldBe(expectedResult.Value);
result.TemplateVariableValue.ShouldBe(expectedResult.TemplateVariableValue);
} }
} }

View File

@ -47,7 +47,7 @@
{ {
this.Given(x => x.GivenTheDownStreamRouteIs( this.Given(x => x.GivenTheDownStreamRouteIs(
new DownstreamRoute( new DownstreamRoute(
new List<UrlPathPlaceholderNameAndValue>(), new List<PlaceholderNameAndValue>(),
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamPathTemplate("any old string") .WithDownstreamPathTemplate("any old string")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
@ -91,7 +91,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<UrlPathPlaceholderNameAndValue>>())) .Setup(x => x.Replace(It.IsAny<PathTemplate>(), It.IsAny<List<PlaceholderNameAndValue>>()))
.Returns(_downstreamPath); .Returns(_downstreamPath);
} }

View File

@ -27,7 +27,7 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
{ {
this.Given(x => x.GivenThereIsAUrlMatch( this.Given(x => x.GivenThereIsAUrlMatch(
new DownstreamRoute( new DownstreamRoute(
new List<UrlPathPlaceholderNameAndValue>(), new List<PlaceholderNameAndValue>(),
new ReRouteBuilder() new ReRouteBuilder()
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.Build()))) .Build())))
@ -41,7 +41,7 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
{ {
this.Given(x => x.GivenThereIsAUrlMatch( this.Given(x => x.GivenThereIsAUrlMatch(
new DownstreamRoute( new DownstreamRoute(
new List<UrlPathPlaceholderNameAndValue>(), new List<PlaceholderNameAndValue>(),
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamPathTemplate("/") .WithDownstreamPathTemplate("/")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
@ -54,7 +54,7 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
[Fact] [Fact]
public void can_replace_url_no_slash() public void can_replace_url_no_slash()
{ {
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamPathTemplate("api") .WithDownstreamPathTemplate("api")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
@ -67,7 +67,7 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
[Fact] [Fact]
public void can_replace_url_one_slash() public void can_replace_url_one_slash()
{ {
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamPathTemplate("api/") .WithDownstreamPathTemplate("api/")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
@ -80,7 +80,7 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
[Fact] [Fact]
public void can_replace_url_multiple_slash() public void can_replace_url_multiple_slash()
{ {
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamPathTemplate("api/product/products/") .WithDownstreamPathTemplate("api/product/products/")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
@ -93,9 +93,9 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
[Fact] [Fact]
public void can_replace_url_one_template_variable() public void can_replace_url_one_template_variable()
{ {
var templateVariables = new List<UrlPathPlaceholderNameAndValue>() var templateVariables = new List<PlaceholderNameAndValue>()
{ {
new UrlPathPlaceholderNameAndValue("{productId}", "1") new PlaceholderNameAndValue("{productId}", "1")
}; };
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables, this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables,
@ -111,9 +111,9 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
[Fact] [Fact]
public void can_replace_url_one_template_variable_with_path_after() public void can_replace_url_one_template_variable_with_path_after()
{ {
var templateVariables = new List<UrlPathPlaceholderNameAndValue>() var templateVariables = new List<PlaceholderNameAndValue>()
{ {
new UrlPathPlaceholderNameAndValue("{productId}", "1") new PlaceholderNameAndValue("{productId}", "1")
}; };
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables, this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables,
@ -129,10 +129,10 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
[Fact] [Fact]
public void can_replace_url_two_template_variable() public void can_replace_url_two_template_variable()
{ {
var templateVariables = new List<UrlPathPlaceholderNameAndValue>() var templateVariables = new List<PlaceholderNameAndValue>()
{ {
new UrlPathPlaceholderNameAndValue("{productId}", "1"), new PlaceholderNameAndValue("{productId}", "1"),
new UrlPathPlaceholderNameAndValue("{variantId}", "12") new PlaceholderNameAndValue("{variantId}", "12")
}; };
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables, this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables,
@ -148,11 +148,11 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
[Fact] [Fact]
public void can_replace_url_three_template_variable() public void can_replace_url_three_template_variable()
{ {
var templateVariables = new List<UrlPathPlaceholderNameAndValue>() var templateVariables = new List<PlaceholderNameAndValue>()
{ {
new UrlPathPlaceholderNameAndValue("{productId}", "1"), new PlaceholderNameAndValue("{productId}", "1"),
new UrlPathPlaceholderNameAndValue("{variantId}", "12"), new PlaceholderNameAndValue("{variantId}", "12"),
new UrlPathPlaceholderNameAndValue("{categoryId}", "34") new PlaceholderNameAndValue("{categoryId}", "34")
}; };
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables, this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables,

View File

@ -37,7 +37,7 @@
[Fact] [Fact]
public void should_call_add_headers_to_request_correctly() public void should_call_add_headers_to_request_correctly()
{ {
var downstreamRoute = new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamPathTemplate("any old string") .WithDownstreamPathTemplate("any old string")
.WithClaimsToHeaders(new List<ClaimToThing> .WithClaimsToHeaders(new List<ClaimToThing>

View File

@ -47,7 +47,7 @@ namespace Ocelot.UnitTests.LoadBalancer
[Fact] [Fact]
public void should_call_scoped_data_repository_correctly() public void should_call_scoped_data_repository_correctly()
{ {
var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.UrlPathPlaceholderNameAndValue>(), var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>(),
new ReRouteBuilder() new ReRouteBuilder()
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.Build()); .Build());
@ -68,7 +68,7 @@ namespace Ocelot.UnitTests.LoadBalancer
[Fact] [Fact]
public void should_set_pipeline_error_if_cannot_get_load_balancer() public void should_set_pipeline_error_if_cannot_get_load_balancer()
{ {
var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.UrlPathPlaceholderNameAndValue>(), var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>(),
new ReRouteBuilder() new ReRouteBuilder()
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.Build()); .Build());
@ -88,7 +88,7 @@ namespace Ocelot.UnitTests.LoadBalancer
[Fact] [Fact]
public void should_set_pipeline_error_if_cannot_get_least() public void should_set_pipeline_error_if_cannot_get_least()
{ {
var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.UrlPathPlaceholderNameAndValue>(), var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>(),
new ReRouteBuilder() new ReRouteBuilder()
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
.Build()); .Build());

View File

@ -37,7 +37,7 @@
[Fact] [Fact]
public void should_call_add_queries_correctly() public void should_call_add_queries_correctly()
{ {
var downstreamRoute = new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamPathTemplate("any old string") .WithDownstreamPathTemplate("any old string")
.WithClaimsToQueries(new List<ClaimToThing> .WithClaimsToQueries(new List<ClaimToThing>

View File

@ -31,7 +31,7 @@
[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.UrlPathPlaceholderNameAndValue>(), var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>(),
new ReRouteBuilder().WithEnableRateLimiting(true).WithRateLimitOptions( new ReRouteBuilder().WithEnableRateLimiting(true).WithRateLimitOptions(
new Ocelot.Configuration.RateLimitOptions(true, "ClientId", new List<string>(), false, "", "", new Ocelot.Configuration.RateLimitRule("1s", 100, 3), 429)) new Ocelot.Configuration.RateLimitOptions(true, "ClientId", new List<string>(), false, "", "", new Ocelot.Configuration.RateLimitRule("1s", 100, 3), 429))
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })
@ -48,7 +48,7 @@
[Fact] [Fact]
public void should_call_middleware_withWhitelistClient() public void should_call_middleware_withWhitelistClient()
{ {
var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.UrlPathPlaceholderNameAndValue>(), var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.PlaceholderNameAndValue>(),
new ReRouteBuilder().WithEnableRateLimiting(true).WithRateLimitOptions( new ReRouteBuilder().WithEnableRateLimiting(true).WithRateLimitOptions(
new Ocelot.Configuration.RateLimitOptions(true, "ClientId", new List<string>() { "ocelotclient2" }, false, "", "", new RateLimitRule( "1s", 100,3),429)) new Ocelot.Configuration.RateLimitOptions(true, "ClientId", new List<string>() { "ocelotclient2" }, false, "", "", new RateLimitRule( "1s", 100,3),429))
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })

View File

@ -47,7 +47,7 @@
public void should_call_scoped_data_repository_correctly() public void should_call_scoped_data_repository_correctly()
{ {
var downstreamRoute = new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder() new ReRouteBuilder()
.WithRequestIdKey("LSRequestId") .WithRequestIdKey("LSRequestId")
.WithUpstreamHttpMethod(new List<string> { "Get" }) .WithUpstreamHttpMethod(new List<string> { "Get" })

View File

@ -40,7 +40,7 @@
[Fact] [Fact]
public void should_pass_down_request_id_from_upstream_request() public void should_pass_down_request_id_from_upstream_request()
{ {
var downstreamRoute = new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamPathTemplate("any old string") .WithDownstreamPathTemplate("any old string")
.WithRequestIdKey("LSRequestId") .WithRequestIdKey("LSRequestId")
@ -59,7 +59,7 @@
[Fact] [Fact]
public void should_add_request_id_when_not_on_upstream_request() public void should_add_request_id_when_not_on_upstream_request()
{ {
var downstreamRoute = new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), var downstreamRoute = new DownstreamRoute(new List<PlaceholderNameAndValue>(),
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamPathTemplate("any old string") .WithDownstreamPathTemplate("any old string")
.WithRequestIdKey("LSRequestId") .WithRequestIdKey("LSRequestId")