made a response middlware as terminating middleware...

This commit is contained in:
TomPallister 2016-10-08 09:59:37 +01:00
parent 3685efec05
commit a7a1143823
17 changed files with 165 additions and 86 deletions

View File

@ -3,13 +3,14 @@ using System.IO;
using System.Net; using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Net.Http.Headers; using System.Net.Http.Headers;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
namespace Ocelot.Library.Infrastructure.RequestBuilder namespace Ocelot.Library.Infrastructure.RequestBuilder
{ {
public class RequestBuilder : IRequestBuilder public class HttpRequestBuilder : IRequestBuilder
{ {
public Request Build(string httpMethod, string downstreamUrl, Stream content, IHeaderDictionary headers, public async Task<Request> Build(string httpMethod, string downstreamUrl, Stream content, IHeaderDictionary headers,
IRequestCookieCollection cookies, string queryString, string contentType) IRequestCookieCollection cookies, string queryString, string contentType)
{ {
var method = new HttpMethod(httpMethod); var method = new HttpMethod(httpMethod);
@ -20,7 +21,11 @@ namespace Ocelot.Library.Infrastructure.RequestBuilder
if (content != null) if (content != null)
{ {
httpRequestMessage.Content = new StreamContent(content); using (var reader = new StreamReader(content))
{
var body = await reader.ReadToEndAsync();
httpRequestMessage.Content = new StringContent(body);
}
} }
if (!string.IsNullOrEmpty(contentType)) if (!string.IsNullOrEmpty(contentType))
@ -41,7 +46,11 @@ namespace Ocelot.Library.Infrastructure.RequestBuilder
{ {
foreach (var header in headers) foreach (var header in headers)
{ {
httpRequestMessage.Headers.Add(header.Key, header.Value.ToArray()); //todo get rid of if..
if (header.Key.ToLower() != "host")
{
httpRequestMessage.Headers.Add(header.Key, header.Value.ToArray());
}
} }
} }

View File

@ -1,11 +1,12 @@
using System.IO; using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
namespace Ocelot.Library.Infrastructure.RequestBuilder namespace Ocelot.Library.Infrastructure.RequestBuilder
{ {
public interface IRequestBuilder public interface IRequestBuilder
{ {
Request Build(string httpMethod, Task<Request> Build(string httpMethod,
string downstreamUrl, string downstreamUrl,
Stream content, Stream content,
IHeaderDictionary headers, IHeaderDictionary headers,

View File

@ -1,17 +1,32 @@
using System.Net.Http; using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
using Ocelot.Library.Infrastructure.RequestBuilder; using Ocelot.Library.Infrastructure.RequestBuilder;
using Ocelot.Library.Infrastructure.Responses;
namespace Ocelot.Library.Infrastructure.Requester namespace Ocelot.Library.Infrastructure.Requester
{ {
public class HttpClientHttpRequester : IHttpRequester public class HttpClientHttpRequester : IHttpRequester
{ {
public async Task<HttpResponseMessage> GetResponse(Request request) public async Task<Response<HttpResponseMessage>> GetResponse(Request request)
{ {
using (var handler = new HttpClientHandler { CookieContainer = request.CookieContainer }) using (var handler = new HttpClientHandler { CookieContainer = request.CookieContainer })
using (var httpClient = new HttpClient(handler)) using (var httpClient = new HttpClient(handler))
{ {
return await httpClient.SendAsync(request.HttpRequestMessage); try
{
var response = await httpClient.SendAsync(request.HttpRequestMessage);
return new OkResponse<HttpResponseMessage>(response);
}
catch (Exception exception)
{
return
new ErrorResponse<HttpResponseMessage>(new List<Error>
{
new UnableToCompleteRequestError(exception)
});
}
} }
} }
} }

View File

@ -1,11 +1,12 @@
using System.Net.Http; using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
using Ocelot.Library.Infrastructure.RequestBuilder; using Ocelot.Library.Infrastructure.RequestBuilder;
using Ocelot.Library.Infrastructure.Responses;
namespace Ocelot.Library.Infrastructure.Requester namespace Ocelot.Library.Infrastructure.Requester
{ {
public interface IHttpRequester public interface IHttpRequester
{ {
Task<HttpResponseMessage> GetResponse(Request request); Task<Response<HttpResponseMessage>> GetResponse(Request request);
} }
} }

View File

@ -0,0 +1,13 @@
using System;
using Ocelot.Library.Infrastructure.Responses;
namespace Ocelot.Library.Infrastructure.Requester
{
public class UnableToCompleteRequestError : Error
{
public UnableToCompleteRequestError(Exception exception)
: base($"Error making http request, exception: {exception.Message}")
{
}
}
}

View File

@ -11,7 +11,12 @@ namespace Ocelot.Library.Infrastructure.Responder
{ {
if (response.IsSuccessStatusCode) if (response.IsSuccessStatusCode)
{ {
context.Response.StatusCode = (int)response.StatusCode; context.Response.OnStarting(x =>
{
context.Response.StatusCode = (int)response.StatusCode;
return Task.CompletedTask;
}, context);
await context.Response.WriteAsync(await response.Content.ReadAsStringAsync()); await context.Response.WriteAsync(await response.Content.ReadAsStringAsync());
return context; return context;
} }
@ -20,7 +25,11 @@ namespace Ocelot.Library.Infrastructure.Responder
public async Task<HttpContext> CreateNotFoundResponse(HttpContext context) public async Task<HttpContext> CreateNotFoundResponse(HttpContext context)
{ {
context.Response.StatusCode = (int)HttpStatusCode.NotFound; context.Response.OnStarting(x =>
{
context.Response.StatusCode = (int)HttpStatusCode.NotFound;
return Task.CompletedTask;
}, context);
return context; return context;
} }
} }

View File

@ -2,6 +2,6 @@ namespace Ocelot.Library.Infrastructure.UrlMatcher
{ {
public interface IUrlPathToUrlTemplateMatcher public interface IUrlPathToUrlTemplateMatcher
{ {
UrlMatch Match(string upstreamUrlPath, string upstreamUrlTemplate); UrlMatch Match(string upstreamUrlPath, string upstreamUrlPathTemplate);
} }
} }

View File

@ -5,21 +5,26 @@ namespace Ocelot.Library.Infrastructure.UrlMatcher
{ {
public class UrlPathToUrlTemplateMatcher : IUrlPathToUrlTemplateMatcher public class UrlPathToUrlTemplateMatcher : IUrlPathToUrlTemplateMatcher
{ {
public UrlMatch Match(string upstreamUrlPath, string upstreamUrlTemplate) public UrlMatch Match(string upstreamUrlPath, string upstreamUrlPathTemplate)
{ {
var urlPathTemplateCopy = upstreamUrlTemplate; if (upstreamUrlPath.Length > upstreamUrlPathTemplate.Length)
{
return new UrlMatch(false, new List<TemplateVariableNameAndValue>(), string.Empty);
}
var urlPathTemplateCopy = upstreamUrlPathTemplate;
var templateKeysAndValues = new List<TemplateVariableNameAndValue>(); var templateKeysAndValues = new List<TemplateVariableNameAndValue>();
int counterForUrl = 0; int counterForUrl = 0;
for (int counterForTemplate = 0; counterForTemplate < upstreamUrlTemplate.Length; counterForTemplate++) for (int counterForTemplate = 0; counterForTemplate < upstreamUrlPathTemplate.Length; counterForTemplate++)
{ {
if (CharactersDontMatch(upstreamUrlTemplate[counterForTemplate], upstreamUrlPath[counterForUrl]) && ContinueScanningUrl(counterForUrl,upstreamUrlPath.Length)) if (CharactersDontMatch(upstreamUrlPathTemplate[counterForTemplate], upstreamUrlPath[counterForUrl]) && ContinueScanningUrl(counterForUrl,upstreamUrlPath.Length))
{ {
if (IsPlaceholder(upstreamUrlTemplate[counterForTemplate])) if (IsPlaceholder(upstreamUrlPathTemplate[counterForTemplate]))
{ {
var variableName = GetPlaceholderVariableName(upstreamUrlTemplate, counterForTemplate); var variableName = GetPlaceholderVariableName(upstreamUrlPathTemplate, counterForTemplate);
var variableValue = GetPlaceholderVariableValue(upstreamUrlPath, counterForUrl); var variableValue = GetPlaceholderVariableValue(upstreamUrlPath, counterForUrl);
@ -27,7 +32,7 @@ namespace Ocelot.Library.Infrastructure.UrlMatcher
templateKeysAndValues.Add(templateVariableNameAndValue); templateKeysAndValues.Add(templateVariableNameAndValue);
counterForTemplate = GetNextCounterPosition(upstreamUrlTemplate, counterForTemplate, '}'); counterForTemplate = GetNextCounterPosition(upstreamUrlPathTemplate, counterForTemplate, '}');
counterForUrl = GetNextCounterPosition(upstreamUrlPath, counterForUrl, '/'); counterForUrl = GetNextCounterPosition(upstreamUrlPath, counterForUrl, '/');

View File

@ -36,7 +36,7 @@ namespace Ocelot.Library.Middleware
return; return;
} }
var request = _requestBuilder var request = await _requestBuilder
.Build(context.Request.Method, downstreamUrl.Data, context.Request.Body, .Build(context.Request.Method, downstreamUrl.Data, context.Request.Body,
context.Request.Headers, context.Request.Cookies, context.Request.QueryString.Value, context.Request.ContentType); context.Request.Headers, context.Request.Cookies, context.Request.QueryString.Value, context.Request.ContentType);

View File

@ -1,3 +1,4 @@
using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Ocelot.Library.Infrastructure.Repository; using Ocelot.Library.Infrastructure.Repository;
@ -14,19 +15,16 @@ namespace Ocelot.Library.Middleware
private readonly IHttpRequester _requester; private readonly IHttpRequester _requester;
private readonly IHttpResponder _responder; private readonly IHttpResponder _responder;
private readonly IScopedRequestDataRepository _scopedRequestDataRepository; private readonly IScopedRequestDataRepository _scopedRequestDataRepository;
private readonly IRequestBuilder _requestBuilder;
public HttpRequesterMiddleware(RequestDelegate next, public HttpRequesterMiddleware(RequestDelegate next,
IHttpRequester requester, IHttpRequester requester,
IHttpResponder responder, IHttpResponder responder,
IScopedRequestDataRepository scopedRequestDataRepository, IScopedRequestDataRepository scopedRequestDataRepository)
IRequestBuilder requestBuilder)
{ {
_next = next; _next = next;
_requester = requester; _requester = requester;
_responder = responder; _responder = responder;
_scopedRequestDataRepository = scopedRequestDataRepository; _scopedRequestDataRepository = scopedRequestDataRepository;
_requestBuilder = requestBuilder;
} }
public async Task Invoke(HttpContext context) public async Task Invoke(HttpContext context)
@ -42,7 +40,7 @@ namespace Ocelot.Library.Middleware
var response = await _requester var response = await _requester
.GetResponse(request.Data); .GetResponse(request.Data);
await _responder.CreateResponse(context, response); _scopedRequestDataRepository.Add("Response", response.Data);
await _next.Invoke(context); await _next.Invoke(context);
} }

View File

@ -0,0 +1,34 @@
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Ocelot.Library.Infrastructure.Repository;
using Ocelot.Library.Infrastructure.Responder;
namespace Ocelot.Library.Middleware
{
/// <summary>
/// Terminating middleware that is responsible for returning a http response to the client
/// </summary>
public class HttpResponderMiddleware
{
private readonly RequestDelegate _next;
private readonly IHttpResponder _responder;
private readonly IScopedRequestDataRepository _scopedRequestDataRepository;
public HttpResponderMiddleware(RequestDelegate next,
IHttpResponder responder,
IScopedRequestDataRepository scopedRequestDataRepository)
{
_next = next;
_responder = responder;
_scopedRequestDataRepository = scopedRequestDataRepository;
}
public async Task Invoke(HttpContext context)
{
var response = _scopedRequestDataRepository.Get<HttpResponseMessage>("Response");
await _responder.CreateResponse(context, response.Data);
}
}
}

View File

@ -0,0 +1,12 @@
using Microsoft.AspNetCore.Builder;
namespace Ocelot.Library.Middleware
{
public static class HttpResponderMiddlewareExtensions
{
public static IApplicationBuilder UseHttpResponderMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<HttpResponderMiddleware>();
}
}
}

View File

@ -1,10 +1,5 @@
using System; using System.IO;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Builder;
namespace Ocelot namespace Ocelot
{ {

View File

@ -44,7 +44,7 @@ namespace Ocelot
services.AddSingleton<IDownstreamRouteFinder, DownstreamRouteFinder>(); services.AddSingleton<IDownstreamRouteFinder, DownstreamRouteFinder>();
services.AddSingleton<IHttpRequester, HttpClientHttpRequester>(); services.AddSingleton<IHttpRequester, HttpClientHttpRequester>();
services.AddSingleton<IHttpResponder, HttpContextResponder>(); services.AddSingleton<IHttpResponder, HttpContextResponder>();
services.AddSingleton<IRequestBuilder, RequestBuilder>(); services.AddSingleton<IRequestBuilder, HttpRequestBuilder>();
// see this for why we register this as singleton http://stackoverflow.com/questions/37371264/invalidoperationexception-unable-to-resolve-service-for-type-microsoft-aspnetc // see this for why we register this as singleton http://stackoverflow.com/questions/37371264/invalidoperationexception-unable-to-resolve-service-for-type-microsoft-aspnetc
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
@ -65,6 +65,8 @@ namespace Ocelot
app.UseHttpRequestBuilderMiddleware(); app.UseHttpRequestBuilderMiddleware();
app.UseHttpRequesterMiddleware(); app.UseHttpRequesterMiddleware();
app.UseHttpResponderMiddleware();
} }
} }
} }

View File

@ -1,4 +1,4 @@
ReRoutes: ReRoutes:
- DownstreamTemplate: http://www.bbc.co.uk - DownstreamTemplate: http://www.mattsite.dev/
UpstreamTemplate: / UpstreamTemplate: /
UpstreamHttpMethod: Get UpstreamHttpMethod: Get

View File

@ -27,7 +27,7 @@ namespace Ocelot.UnitTests.RequestBuilder
public RequestBuilderTests() public RequestBuilderTests()
{ {
_content = new StringContent(string.Empty); _content = new StringContent(string.Empty);
_requestBuilder = new Library.Infrastructure.RequestBuilder.RequestBuilder(); _requestBuilder = new Library.Infrastructure.RequestBuilder.HttpRequestBuilder();
} }
[Fact] [Fact]
@ -70,7 +70,6 @@ namespace Ocelot.UnitTests.RequestBuilder
.And(x => x.GivenIHaveTheHttpContent(new StringContent("Hi from Tom"))) .And(x => x.GivenIHaveTheHttpContent(new StringContent("Hi from Tom")))
.And(x => x.GivenTheContentTypeIs("application/json")) .And(x => x.GivenTheContentTypeIs("application/json"))
.When(x => x.WhenICreateARequest()) .When(x => x.WhenICreateARequest())
.And(x => x.ThenTheCorrectContentIsUsed(new StringContent("Hi from Tom")))
.And(x => x.ThenTheCorrectContentHeadersAreUsed(new HeaderDictionary .And(x => x.ThenTheCorrectContentHeadersAreUsed(new HeaderDictionary
{ {
{ {
@ -202,7 +201,7 @@ namespace Ocelot.UnitTests.RequestBuilder
private void WhenICreateARequest() private void WhenICreateARequest()
{ {
_result = _requestBuilder.Build(_httpMethod, _downstreamUrl, _content?.ReadAsStreamAsync().Result, _headers, _result = _requestBuilder.Build(_httpMethod, _downstreamUrl, _content?.ReadAsStreamAsync().Result, _headers,
_cookies, _query, _contentType); _cookies, _query, _contentType).Result;
} }

View File

@ -18,11 +18,21 @@ namespace Ocelot.UnitTests.UrlMatcher
_urlMatcher = new UrlPathToUrlTemplateMatcher(); _urlMatcher = new UrlPathToUrlTemplateMatcher();
} }
[Fact]
public void should_not_find_match()
{
this.Given(x => x.GivenIHaveAUpstreamPath("/api/values"))
.And(x => x.GivenIHaveAnUpstreamUrlTemplate("/"))
.When(x => x.WhenIMatchThePaths())
.And(x => x.ThenTheResultIsFalse())
.BDDfy();
}
[Fact] [Fact]
public void can_match_down_stream_url() public void can_match_down_stream_url()
{ {
this.Given(x => x.GivenIHaveADownstreamPath("")) this.Given(x => x.GivenIHaveAUpstreamPath(""))
.And(x => x.GivenIHaveAnDownstreamUrlTemplate("")) .And(x => x.GivenIHaveAnUpstreamUrlTemplate(""))
.When(x => x.WhenIMatchThePaths()) .When(x => x.WhenIMatchThePaths())
.And(x => x.ThenTheResultIsTrue()) .And(x => x.ThenTheResultIsTrue())
.And(x => x.ThenTheTemplatesVariablesAre(new List<TemplateVariableNameAndValue>())) .And(x => x.ThenTheTemplatesVariablesAre(new List<TemplateVariableNameAndValue>()))
@ -33,8 +43,8 @@ namespace Ocelot.UnitTests.UrlMatcher
[Fact] [Fact]
public void can_match_down_stream_url_with_no_slash() public void can_match_down_stream_url_with_no_slash()
{ {
this.Given(x => x.GivenIHaveADownstreamPath("api")) this.Given(x => x.GivenIHaveAUpstreamPath("api"))
.Given(x => x.GivenIHaveAnDownstreamUrlTemplate("api")) .Given(x => x.GivenIHaveAnUpstreamUrlTemplate("api"))
.When(x => x.WhenIMatchThePaths()) .When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue()) .Then(x => x.ThenTheResultIsTrue())
.And(x => x.ThenTheTemplatesVariablesAre(new List<TemplateVariableNameAndValue>())) .And(x => x.ThenTheTemplatesVariablesAre(new List<TemplateVariableNameAndValue>()))
@ -45,8 +55,8 @@ namespace Ocelot.UnitTests.UrlMatcher
[Fact] [Fact]
public void can_match_down_stream_url_with_one_slash() public void can_match_down_stream_url_with_one_slash()
{ {
this.Given(x => x.GivenIHaveADownstreamPath("api/")) this.Given(x => x.GivenIHaveAUpstreamPath("api/"))
.Given(x => x.GivenIHaveAnDownstreamUrlTemplate("api/")) .Given(x => x.GivenIHaveAnUpstreamUrlTemplate("api/"))
.When(x => x.WhenIMatchThePaths()) .When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue()) .Then(x => x.ThenTheResultIsTrue())
.And(x => x.ThenTheTemplatesVariablesAre(new List<TemplateVariableNameAndValue>())) .And(x => x.ThenTheTemplatesVariablesAre(new List<TemplateVariableNameAndValue>()))
@ -57,8 +67,8 @@ namespace Ocelot.UnitTests.UrlMatcher
[Fact] [Fact]
public void can_match_down_stream_url_with_downstream_template() public void can_match_down_stream_url_with_downstream_template()
{ {
this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/")) this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/"))
.Given(x => x.GivenIHaveAnDownstreamUrlTemplate("api/product/products/")) .Given(x => x.GivenIHaveAnUpstreamUrlTemplate("api/product/products/"))
.When(x => x.WhenIMatchThePaths()) .When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue()) .Then(x => x.ThenTheResultIsTrue())
.And(x => x.ThenTheTemplatesVariablesAre(new List<TemplateVariableNameAndValue>())) .And(x => x.ThenTheTemplatesVariablesAre(new List<TemplateVariableNameAndValue>()))
@ -66,35 +76,6 @@ namespace Ocelot.UnitTests.UrlMatcher
.BDDfy(); .BDDfy();
} }
[Fact]
public void can_match_down_stream_url_with_downstream_template_with_one_query_string_parameter()
{
this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/?soldout=false"))
.Given(x => x.GivenIHaveAnDownstreamUrlTemplate("api/product/products/"))
.When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue())
.And(x => x.ThenTheTemplatesVariablesAre(new List<TemplateVariableNameAndValue>()))
.And(x => x.ThenTheDownstreamUrlTemplateIs("api/product/products/"))
.BDDfy();
}
[Fact]
public void can_match_down_stream_url_with_downstream_template_with_one_query_string_parameter_and_one_template()
{
var expectedTemplates = new List<TemplateVariableNameAndValue>
{
new TemplateVariableNameAndValue("{productId}", "1")
};
this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/1/variants/?soldout=false"))
.Given(x => x.GivenIHaveAnDownstreamUrlTemplate("api/product/products/{productId}/variants/"))
.When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue())
.And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
.And(x => x.ThenTheDownstreamUrlTemplateIs("api/product/products/{productId}/variants/"))
.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()
{ {
@ -103,8 +84,8 @@ namespace Ocelot.UnitTests.UrlMatcher
new TemplateVariableNameAndValue("{productId}", "1") new TemplateVariableNameAndValue("{productId}", "1")
}; };
this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/1")) this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1"))
.Given(x => x.GivenIHaveAnDownstreamUrlTemplate("api/product/products/{productId}")) .Given(x => x.GivenIHaveAnUpstreamUrlTemplate("api/product/products/{productId}"))
.When(x => x.WhenIMatchThePaths()) .When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue()) .Then(x => x.ThenTheResultIsTrue())
.And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates)) .And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
@ -121,8 +102,8 @@ namespace Ocelot.UnitTests.UrlMatcher
new TemplateVariableNameAndValue("{categoryId}", "2") new TemplateVariableNameAndValue("{categoryId}", "2")
}; };
this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/1/2")) this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/2"))
.Given(x => x.GivenIHaveAnDownstreamUrlTemplate("api/product/products/{productId}/{categoryId}")) .Given(x => x.GivenIHaveAnUpstreamUrlTemplate("api/product/products/{productId}/{categoryId}"))
.When(x => x.WhenIMatchThePaths()) .When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue()) .Then(x => x.ThenTheResultIsTrue())
.And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates)) .And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
@ -139,8 +120,8 @@ namespace Ocelot.UnitTests.UrlMatcher
new TemplateVariableNameAndValue("{categoryId}", "2") new TemplateVariableNameAndValue("{categoryId}", "2")
}; };
this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/1/categories/2")) this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/categories/2"))
.And(x => x.GivenIHaveAnDownstreamUrlTemplate("api/product/products/{productId}/categories/{categoryId}")) .And(x => x.GivenIHaveAnUpstreamUrlTemplate("api/product/products/{productId}/categories/{categoryId}"))
.When(x => x.WhenIMatchThePaths()) .When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue()) .Then(x => x.ThenTheResultIsTrue())
.And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates)) .And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
@ -158,8 +139,8 @@ namespace Ocelot.UnitTests.UrlMatcher
new TemplateVariableNameAndValue("{variantId}", "123") new TemplateVariableNameAndValue("{variantId}", "123")
}; };
this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/1/categories/2/variant/123")) this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/categories/2/variant/123"))
.And(x => x.GivenIHaveAnDownstreamUrlTemplate("api/product/products/{productId}/categories/{categoryId}/variant/{variantId}")) .And(x => x.GivenIHaveAnUpstreamUrlTemplate("api/product/products/{productId}/categories/{categoryId}/variant/{variantId}"))
.When(x => x.WhenIMatchThePaths()) .When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue()) .Then(x => x.ThenTheResultIsTrue())
.And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates)) .And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
@ -176,8 +157,8 @@ namespace Ocelot.UnitTests.UrlMatcher
new TemplateVariableNameAndValue("{categoryId}", "2") new TemplateVariableNameAndValue("{categoryId}", "2")
}; };
this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/1/categories/2/variant/")) this.Given(x => x.GivenIHaveAUpstreamPath("api/product/products/1/categories/2/variant/"))
.And(x => x.GivenIHaveAnDownstreamUrlTemplate("api/product/products/{productId}/categories/{categoryId}/variant/")) .And(x => x.GivenIHaveAnUpstreamUrlTemplate("api/product/products/{productId}/categories/{categoryId}/variant/"))
.When(x => x.WhenIMatchThePaths()) .When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue()) .Then(x => x.ThenTheResultIsTrue())
.And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates)) .And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
@ -199,12 +180,12 @@ namespace Ocelot.UnitTests.UrlMatcher
{ {
_result.DownstreamUrlTemplate.ShouldBe(expectedDownstreamUrlTemplate); _result.DownstreamUrlTemplate.ShouldBe(expectedDownstreamUrlTemplate);
} }
private void GivenIHaveADownstreamPath(string downstreamPath) private void GivenIHaveAUpstreamPath(string downstreamPath)
{ {
_downstreamUrlPath = downstreamPath; _downstreamUrlPath = downstreamPath;
} }
private void GivenIHaveAnDownstreamUrlTemplate(string downstreamUrlTemplate) private void GivenIHaveAnUpstreamUrlTemplate(string downstreamUrlTemplate)
{ {
_downstreamPathTemplate = downstreamUrlTemplate; _downstreamPathTemplate = downstreamUrlTemplate;
} }
@ -218,5 +199,10 @@ namespace Ocelot.UnitTests.UrlMatcher
{ {
_result.Match.ShouldBeTrue(); _result.Match.ShouldBeTrue();
} }
private void ThenTheResultIsFalse()
{
_result.Match.ShouldBeFalse();
}
} }
} }