Merge branch 'release-5.0.1'

This commit is contained in:
Tom Gardham-Pallister 2018-03-13 20:32:56 +00:00
commit 43bac3602e
8 changed files with 129 additions and 4 deletions

View File

@ -2,7 +2,7 @@ Delegating Handers
================== ==================
Ocelot allows the user to add delegating handlers to the HttpClient transport. This feature was requested `GitHub #208 <https://github.com/TomPallister/Ocelot/issues/208>`_ Ocelot allows the user to add delegating handlers to the HttpClient transport. This feature was requested `GitHub #208 <https://github.com/TomPallister/Ocelot/issues/208>`_
and I decided that it was going to be useful in various ways. Since then we extended it in `GitHub #208 <https://github.com/TomPallister/Ocelot/issues/264>`_. and I decided that it was going to be useful in various ways. Since then we extended it in `GitHub #264 <https://github.com/TomPallister/Ocelot/issues/264>`_.
Usage Usage
^^^^^ ^^^^^

View File

@ -140,3 +140,41 @@ If you do not set UpstreamHost on a ReRoue then any host header can match it. Th
preservers existing functionality at the time of building the feature. This means that if you have two ReRoutes that are the same apart from the UpstreamHost where one is null and the other set. Ocelot will favour the one that has been set. preservers existing functionality at the time of building the feature. This means that if you have two ReRoutes that are the same apart from the UpstreamHost where one is null and the other set. Ocelot will favour the one that has been set.
This feature was requested as part of `Issue 216 <https://github.com/TomPallister/Ocelot/pull/216>`_ . This feature was requested as part of `Issue 216 <https://github.com/TomPallister/Ocelot/pull/216>`_ .
Priority
^^^^^^^^
In `Issue 270 <https://github.com/TomPallister/Ocelot/pull/270>`_ I finally decided to expose the ReRoute priority in
configuration.json. This means you can decide in what order you want your ReRoutes to match the Upstream HttpRequest.
In order to get this working add the following to a ReRoute in configuration.json, 0 is just an example value here but will explain below.
.. code-block:: json
{
"Priority": 0
}
0 is the lowest priority, Ocelot will always use 0 for /{catchAll} ReRoutes and this is still hardcoded. After that you are free
to set any priority you wish.
e.g. you could have
.. code-block:: json
{
"UpstreamPathTemplate": "/goods/{catchAll}"
"Priority": 0
}
and
.. code-block:: json
{
"UpstreamPathTemplate": "/goods/delete"
"Priority": 1
}
In the example above if you make a request into Ocelot on /goods/delete Ocelot will match /goods/delete ReRoute. Previously it would have
matched /goods/{catchAll} (because this is the first ReRoute in the list!).

View File

@ -42,7 +42,7 @@ namespace Ocelot.Configuration.Creator
if (upstreamTemplate == "/") if (upstreamTemplate == "/")
{ {
return new UpstreamPathTemplate(RegExForwardSlashOnly, 1); return new UpstreamPathTemplate(RegExForwardSlashOnly, reRoute.Priority);
} }
if(upstreamTemplate.EndsWith("/")) if(upstreamTemplate.EndsWith("/"))
@ -54,7 +54,7 @@ namespace Ocelot.Configuration.Creator
? $"^{upstreamTemplate}{RegExMatchEndString}" ? $"^{upstreamTemplate}{RegExMatchEndString}"
: $"^{RegExIgnoreCase}{upstreamTemplate}{RegExMatchEndString}"; : $"^{RegExIgnoreCase}{upstreamTemplate}{RegExMatchEndString}";
return new UpstreamPathTemplate(route, 1); return new UpstreamPathTemplate(route, reRoute.Priority);
} }
private bool ForwardSlashAndOnePlaceHolder(string upstreamTemplate, List<string> placeholders, int postitionOfPlaceHolderClosingBracket) private bool ForwardSlashAndOnePlaceHolder(string upstreamTemplate, List<string> placeholders, int postitionOfPlaceHolderClosingBracket)

View File

@ -14,5 +14,7 @@ namespace Ocelot.Configuration.File
{ {
get { return new List<string> {"Get"}; } get { return new List<string> {"Get"}; }
} }
public int Priority {get;set;} = 1;
} }
} }

View File

@ -20,6 +20,7 @@ namespace Ocelot.Configuration.File
UpstreamHeaderTransform = new Dictionary<string, string>(); UpstreamHeaderTransform = new Dictionary<string, string>();
DownstreamHostAndPorts = new List<FileHostAndPort>(); DownstreamHostAndPorts = new List<FileHostAndPort>();
DelegatingHandlers = new List<string>(); DelegatingHandlers = new List<string>();
Priority = 1;
} }
public string DownstreamPathTemplate { get; set; } public string DownstreamPathTemplate { get; set; }
@ -46,5 +47,6 @@ namespace Ocelot.Configuration.File
public string UpstreamHost { get; set; } public string UpstreamHost { get; set; }
public string Key { get;set; } public string Key { get;set; }
public List<string> DelegatingHandlers {get;set;} public List<string> DelegatingHandlers {get;set;}
public int Priority { get;set; }
} }
} }

View File

@ -4,5 +4,6 @@
{ {
string UpstreamPathTemplate { get; set; } string UpstreamPathTemplate { get; set; }
bool ReRouteIsCaseSensitive { get; set; } bool ReRouteIsCaseSensitive { get; set; }
int Priority {get;set;}
} }
} }

View File

@ -872,6 +872,56 @@ namespace Ocelot.AcceptanceTests
.BDDfy(); .BDDfy();
} }
[Fact]
public void should_use_priority()
{
var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/goods/{url}",
DownstreamScheme = "http",
UpstreamPathTemplate = "/goods/{url}",
UpstreamHttpMethod = new List<string> { "Get" },
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 53879,
}
},
Priority = 0
},
new FileReRoute
{
DownstreamPathTemplate = "/goods/delete",
DownstreamScheme = "http",
UpstreamPathTemplate = "/goods/delete",
UpstreamHttpMethod = new List<string> { "Get" },
DownstreamHostAndPorts = new List<FileHostAndPort>
{
new FileHostAndPort
{
Host = "localhost",
Port = 52879,
}
},
}
}
};
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:52879/", "/goods/delete", 200, "Hello from Laura"))
.And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/goods/delete"))
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
.BDDfy();
}
private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int statusCode, string responseBody) private void GivenThereIsAServiceRunningOn(string baseUrl, string basePath, int statusCode, string responseBody)
{ {
_builder = new WebHostBuilder() _builder = new WebHostBuilder()

View File

@ -19,6 +19,38 @@ namespace Ocelot.UnitTests.Configuration
_creator = new UpstreamTemplatePatternCreator(); _creator = new UpstreamTemplatePatternCreator();
} }
[Fact]
public void should_use_re_route_priority()
{
var fileReRoute = new FileReRoute
{
UpstreamPathTemplate = "/orders/{catchAll}",
Priority = 0
};
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^(?i)/orders/[0-9a-zA-Z].*$"))
.And(x => ThenThePriorityIs(0))
.BDDfy();
}
[Fact]
public void should_use_zero_priority()
{
var fileReRoute = new FileReRoute
{
UpstreamPathTemplate = "/{catchAll}",
Priority = 1
};
this.Given(x => x.GivenTheFollowingFileReRoute(fileReRoute))
.When(x => x.WhenICreateTheTemplatePattern())
.Then(x => x.ThenTheFollowingIsReturned("^/.*"))
.And(x => ThenThePriorityIs(0))
.BDDfy();
}
[Fact] [Fact]
public void should_set_upstream_template_pattern_to_ignore_case_sensitivity() public void should_set_upstream_template_pattern_to_ignore_case_sensitivity()
{ {