simplifying stuff after i realised i added loads of crap i dont need

This commit is contained in:
Tom Gardham-Pallister 2016-08-27 14:13:45 +01:00
parent 267ad5e98b
commit c4e0bae4ce
36 changed files with 302 additions and 668 deletions

View File

@ -1,14 +0,0 @@
namespace Ocelot.Library.Infrastructure.HostUrlRepository
{
public class HostUrlMap
{
public HostUrlMap(string urlPathTemplate, string upstreamHostUrl)
{
UrlPathTemplate = urlPathTemplate;
UpstreamHostUrl = upstreamHostUrl;
}
public string UrlPathTemplate {get;private set;}
public string UpstreamHostUrl {get;private set;}
}
}

View File

@ -1,12 +0,0 @@
using Ocelot.Library.Infrastructure.Responses;
namespace Ocelot.Library.Infrastructure.HostUrlRepository
{
public class HostUrlMapKeyAlreadyExists : Error
{
public HostUrlMapKeyAlreadyExists()
: base("This key has already been used")
{
}
}
}

View File

@ -1,12 +0,0 @@
using Ocelot.Library.Infrastructure.Responses;
namespace Ocelot.Library.Infrastructure.HostUrlRepository
{
public class HostUrlMapKeyDoesNotExist : Error
{
public HostUrlMapKeyDoesNotExist()
: base("This key does not exist")
{
}
}
}

View File

@ -1,10 +0,0 @@
using Ocelot.Library.Infrastructure.Responses;
namespace Ocelot.Library.Infrastructure.HostUrlRepository
{
public interface IHostUrlMapRepository
{
Response AddBaseUrlMap(HostUrlMap baseUrlMap);
Response<HostUrlMap> GetBaseUrlMap(string urlPathTemplate);
}
}

View File

@ -1,37 +0,0 @@
using System.Collections.Generic;
using Ocelot.Library.Infrastructure.Responses;
namespace Ocelot.Library.Infrastructure.HostUrlRepository
{
public class InMemoryHostUrlMapRepository : IHostUrlMapRepository
{
private readonly Dictionary<string, string> _routes;
public InMemoryHostUrlMapRepository()
{
_routes = new Dictionary<string,string>();
}
public Response AddBaseUrlMap(HostUrlMap baseUrlMap)
{
if(_routes.ContainsKey(baseUrlMap.UrlPathTemplate))
{
return new ErrorResponse(new List<Error>(){new HostUrlMapKeyAlreadyExists()});
}
_routes.Add(baseUrlMap.UrlPathTemplate, baseUrlMap.UpstreamHostUrl);
return new OkResponse();
}
public Response<HostUrlMap> GetBaseUrlMap(string urlPathTemplate)
{
string upstreamUrl = null;
if(_routes.TryGetValue(urlPathTemplate, out upstreamUrl))
{
return new OkResponse<HostUrlMap>(new HostUrlMap(urlPathTemplate, upstreamUrl));
}
return new ErrorResponse<HostUrlMap>(new List<Error>(){new HostUrlMapKeyDoesNotExist()});
}
}
}

View File

@ -1,9 +0,0 @@
using Ocelot.Library.Infrastructure.Responses;
namespace Ocelot.Library.Infrastructure.UrlFinder
{
public interface IUpstreamHostUrlFinder
{
Response<string> FindUpstreamHostUrl(string downstreamHostUrl);
}
}

View File

@ -1,12 +0,0 @@
using Ocelot.Library.Infrastructure.Responses;
namespace Ocelot.Library.Infrastructure.UrlFinder
{
public class UnableToFindUpstreamHostUrl : Error
{
public UnableToFindUpstreamHostUrl()
: base("Unable to find upstream base url")
{
}
}
}

View File

@ -1,28 +0,0 @@
using System;
using System.Collections.Generic;
using Ocelot.Library.Infrastructure.HostUrlRepository;
using Ocelot.Library.Infrastructure.Responses;
namespace Ocelot.Library.Infrastructure.UrlFinder
{
public class UpstreamHostUrlFinder : IUpstreamHostUrlFinder
{
private readonly IHostUrlMapRepository _hostUrlMapRepository;
public UpstreamHostUrlFinder(IHostUrlMapRepository hostUrlMapRepository)
{
_hostUrlMapRepository = hostUrlMapRepository;
}
public Response<string> FindUpstreamHostUrl(string downstreamBaseUrl)
{
var baseUrl = _hostUrlMapRepository.GetBaseUrlMap(downstreamBaseUrl);
if(baseUrl.IsError)
{
return new ErrorResponse<string>(new List<Error> {new UnableToFindUpstreamHostUrl()});
}
return new OkResponse<string>(baseUrl.Data.UpstreamHostUrl);
}
}
}

View File

@ -0,0 +1,7 @@
namespace Ocelot.Library.Infrastructure.UrlMatcher
{
public interface IUrlPathToUrlTemplateMatcher
{
UrlMatch Match(string downstreamUrlPath, string downstreamUrlTemplate);
}
}

View File

@ -1,4 +1,4 @@
namespace Ocelot.Library.Infrastructure.UrlPathMatcher namespace Ocelot.Library.Infrastructure.UrlMatcher
{ {
public class TemplateVariableNameAndValue public class TemplateVariableNameAndValue
{ {

View File

@ -0,0 +1,17 @@
using System.Collections.Generic;
namespace Ocelot.Library.Infrastructure.UrlMatcher
{
public class UrlMatch
{
public UrlMatch(bool match, List<TemplateVariableNameAndValue> templateVariableNameAndValues, string downstreamUrlTemplate)
{
Match = match;
TemplateVariableNameAndValues = templateVariableNameAndValues;
DownstreamUrlTemplate = downstreamUrlTemplate;
}
public bool Match {get;private set;}
public List<TemplateVariableNameAndValue> TemplateVariableNameAndValues {get;private set;}
public string DownstreamUrlTemplate {get;private set;}
}
}

View File

@ -1,25 +1,25 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Ocelot.Library.Infrastructure.UrlPathMatcher namespace Ocelot.Library.Infrastructure.UrlMatcher
{ {
public class UrlPathToUrlPathTemplateMatcher : IUrlPathToUrlPathTemplateMatcher public class UrlPathToUrlTemplateMatcher : IUrlPathToUrlTemplateMatcher
{ {
public UrlPathMatch Match(string downstreamUrlPath, string downstreamUrlPathTemplate) public UrlMatch Match(string downstreamUrlPath, string downstreamUrlTemplate)
{ {
var urlPathTemplateCopy = downstreamUrlPathTemplate; var urlPathTemplateCopy = downstreamUrlTemplate;
var templateKeysAndValues = new List<TemplateVariableNameAndValue>(); var templateKeysAndValues = new List<TemplateVariableNameAndValue>();
int counterForUrl = 0; int counterForUrl = 0;
for (int counterForTemplate = 0; counterForTemplate < downstreamUrlPathTemplate.Length; counterForTemplate++) for (int counterForTemplate = 0; counterForTemplate < downstreamUrlTemplate.Length; counterForTemplate++)
{ {
if (CharactersDontMatch(downstreamUrlPathTemplate[counterForTemplate], downstreamUrlPath[counterForUrl]) && ContinueScanningUrl(counterForUrl,downstreamUrlPath.Length)) if (CharactersDontMatch(downstreamUrlTemplate[counterForTemplate], downstreamUrlPath[counterForUrl]) && ContinueScanningUrl(counterForUrl,downstreamUrlPath.Length))
{ {
if (IsPlaceholder(downstreamUrlPathTemplate[counterForTemplate])) if (IsPlaceholder(downstreamUrlTemplate[counterForTemplate]))
{ {
var variableName = GetPlaceholderVariableName(downstreamUrlPathTemplate, counterForTemplate); var variableName = GetPlaceholderVariableName(downstreamUrlTemplate, counterForTemplate);
var variableValue = GetPlaceholderVariableValue(downstreamUrlPath, counterForUrl); var variableValue = GetPlaceholderVariableValue(downstreamUrlPath, counterForUrl);
@ -27,7 +27,7 @@ namespace Ocelot.Library.Infrastructure.UrlPathMatcher
templateKeysAndValues.Add(templateVariableNameAndValue); templateKeysAndValues.Add(templateVariableNameAndValue);
counterForTemplate = GetNextCounterPosition(downstreamUrlPathTemplate, counterForTemplate, '}'); counterForTemplate = GetNextCounterPosition(downstreamUrlTemplate, counterForTemplate, '}');
counterForUrl = GetNextCounterPosition(downstreamUrlPath, counterForUrl, '/'); counterForUrl = GetNextCounterPosition(downstreamUrlPath, counterForUrl, '/');
@ -35,12 +35,12 @@ namespace Ocelot.Library.Infrastructure.UrlPathMatcher
} }
else else
{ {
return new UrlPathMatch(false, templateKeysAndValues, string.Empty); return new UrlMatch(false, templateKeysAndValues, string.Empty);
} }
} }
counterForUrl++; counterForUrl++;
} }
return new UrlPathMatch(true, templateKeysAndValues, urlPathTemplateCopy); return new UrlMatch(true, templateKeysAndValues, urlPathTemplateCopy);
} }
private string GetPlaceholderVariableValue(string urlPath, int counterForUrl) private string GetPlaceholderVariableValue(string urlPath, int counterForUrl)

View File

@ -1,7 +0,0 @@
namespace Ocelot.Library.Infrastructure.UrlPathMatcher
{
public interface IUrlPathToUrlPathTemplateMatcher
{
UrlPathMatch Match(string downstreamUrlPath, string downStreamUrlPathTemplate);
}
}

View File

@ -1,17 +0,0 @@
using System.Collections.Generic;
namespace Ocelot.Library.Infrastructure.UrlPathMatcher
{
public class UrlPathMatch
{
public UrlPathMatch(bool match, List<TemplateVariableNameAndValue> templateVariableNameAndValues, string downstreamUrlPathTemplate)
{
Match = match;
TemplateVariableNameAndValues = templateVariableNameAndValues;
DownstreamUrlPathTemplate = downstreamUrlPathTemplate;
}
public bool Match {get;private set;}
public List<TemplateVariableNameAndValue> TemplateVariableNameAndValues {get;private set;}
public string DownstreamUrlPathTemplate {get;private set;}
}
}

View File

@ -1,10 +0,0 @@
using Ocelot.Library.Infrastructure.UrlPathMatcher;
namespace Ocelot.Library.Infrastructure.UrlPathReplacer
{
public interface IUpstreamUrlPathTemplateVariableReplacer
{
string ReplaceTemplateVariable(string upstreamPathTemplate, UrlPathMatch urlPathMatch);
}
}

View File

@ -1,22 +0,0 @@
using System;
using System.Text;
using Ocelot.Library.Infrastructure.UrlPathMatcher;
namespace Ocelot.Library.Infrastructure.UrlPathReplacer
{
public class UpstreamUrlPathTemplateVariableReplacer : IUpstreamUrlPathTemplateVariableReplacer
{
public string ReplaceTemplateVariable(string upstreamPathTemplate, UrlPathMatch urlPathMatch)
{
var upstreamUrl = new StringBuilder();
upstreamUrl.Append(upstreamPathTemplate);
foreach (var templateVarAndValue in urlPathMatch.TemplateVariableNameAndValues)
{
upstreamUrl.Replace(templateVarAndValue.TemplateVariableName, templateVarAndValue.TemplateVariableValue);
}
return upstreamUrl.ToString();
}
}
}

View File

@ -1,12 +0,0 @@
using Ocelot.Library.Infrastructure.Responses;
namespace Ocelot.Library.Infrastructure.UrlPathTemplateRepository
{
public class DownstreamUrlPathTemplateAlreadyExists : Error
{
public DownstreamUrlPathTemplateAlreadyExists()
: base("This key has already been used")
{
}
}
}

View File

@ -1,12 +0,0 @@
using Ocelot.Library.Infrastructure.Responses;
namespace Ocelot.Library.Infrastructure.UrlPathTemplateRepository
{
public class DownstreamUrlPathTemplateDoesNotExist : Error
{
public DownstreamUrlPathTemplateDoesNotExist()
: base("This key does not exist")
{
}
}
}

View File

@ -1,12 +0,0 @@
using System.Collections.Generic;
using Ocelot.Library.Infrastructure.Responses;
namespace Ocelot.Library.Infrastructure.UrlPathTemplateRepository
{
public interface IUrlPathTemplateMapRepository
{
Response AddUrlPathTemplateMap(UrlPathTemplateMap urlPathMap);
Response<UrlPathTemplateMap> GetUrlPathTemplateMap(string downstreamUrlPathTemplate);
Response<List<UrlPathTemplateMap>> All { get; }
}
}

View File

@ -1,51 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Ocelot.Library.Infrastructure.Responses;
namespace Ocelot.Library.Infrastructure.UrlPathTemplateRepository
{
public class InMemoryUrlPathTemplateMapRepository : IUrlPathTemplateMapRepository
{
private readonly Dictionary<string, string> _routes;
public InMemoryUrlPathTemplateMapRepository()
{
_routes = new Dictionary<string,string>();
}
public Response<List<UrlPathTemplateMap>> All
{
get
{
var routes = _routes
.Select(r => new UrlPathTemplateMap(r.Key, r.Value))
.ToList();
return new OkResponse<List<UrlPathTemplateMap>>(routes);
}
}
public Response AddUrlPathTemplateMap(UrlPathTemplateMap urlPathMap)
{
if(_routes.ContainsKey(urlPathMap.DownstreamUrlPathTemplate))
{
return new ErrorResponse(new List<Error>(){new DownstreamUrlPathTemplateAlreadyExists()});
}
_routes.Add(urlPathMap.DownstreamUrlPathTemplate, urlPathMap.UpstreamUrlPathTemplate);
return new OkResponse();
}
public Response<UrlPathTemplateMap> GetUrlPathTemplateMap(string downstreamUrlPathTemplate)
{
string upstreamUrlPathTemplate = null;
if(_routes.TryGetValue(downstreamUrlPathTemplate, out upstreamUrlPathTemplate))
{
return new OkResponse<UrlPathTemplateMap>(new UrlPathTemplateMap(downstreamUrlPathTemplate, upstreamUrlPathTemplate));
}
return new ErrorResponse<UrlPathTemplateMap>(new List<Error>(){new DownstreamUrlPathTemplateDoesNotExist()});
}
}
}

View File

@ -1,14 +0,0 @@
namespace Ocelot.Library.Infrastructure.UrlPathTemplateRepository
{
public class UrlPathTemplateMap
{
public UrlPathTemplateMap(string downstreamUrlPathTemplate, string upstreamUrlPathTemplate)
{
DownstreamUrlPathTemplate = downstreamUrlPathTemplate;
UpstreamUrlPathTemplate = upstreamUrlPathTemplate;
}
public string DownstreamUrlPathTemplate {get;private set;}
public string UpstreamUrlPathTemplate {get;private set;}
}
}

View File

@ -0,0 +1,22 @@
using System.Text;
using Ocelot.Library.Infrastructure.UrlMatcher;
namespace Ocelot.Library.Infrastructure.UrlTemplateReplacer
{
public class DownstreamUrlTemplateVariableReplacer : IDownstreamUrlTemplateVariableReplacer
{
public string ReplaceTemplateVariable(string downstreamPathTemplate, UrlMatch urlMatch)
{
var upstreamUrl = new StringBuilder();
upstreamUrl.Append(downstreamPathTemplate);
foreach (var templateVarAndValue in urlMatch.TemplateVariableNameAndValues)
{
upstreamUrl.Replace(templateVarAndValue.TemplateVariableName, templateVarAndValue.TemplateVariableValue);
}
return upstreamUrl.ToString();
}
}
}

View File

@ -0,0 +1,9 @@
using Ocelot.Library.Infrastructure.UrlMatcher;
namespace Ocelot.Library.Infrastructure.UrlTemplateReplacer
{
public interface IDownstreamUrlTemplateVariableReplacer
{
string ReplaceTemplateVariable(string downstreamPathTemplate, UrlMatch urlMatch);
}
}

View File

@ -0,0 +1,12 @@
using Ocelot.Library.Infrastructure.Responses;
namespace Ocelot.Library.Infrastructure.UrlTemplateRepository
{
public class DownstreamUrlTemplateAlreadyExists : Error
{
public DownstreamUrlTemplateAlreadyExists()
: base("This key has already been used")
{
}
}
}

View File

@ -0,0 +1,12 @@
using Ocelot.Library.Infrastructure.Responses;
namespace Ocelot.Library.Infrastructure.UrlTemplateRepository
{
public class DownstreamUrlTemplateDoesNotExist : Error
{
public DownstreamUrlTemplateDoesNotExist()
: base("This key does not exist")
{
}
}
}

View File

@ -0,0 +1,11 @@
using System.Collections.Generic;
using Ocelot.Library.Infrastructure.Responses;
namespace Ocelot.Library.Infrastructure.UrlTemplateRepository
{
public interface IUrlTemplateMapRepository
{
Response AddUrlTemplateMap(UrlTemplateMap urlPathMap);
Response<List<UrlTemplateMap>> All { get; }
}
}

View File

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Ocelot.Library.Infrastructure.Responses;
namespace Ocelot.Library.Infrastructure.UrlTemplateRepository
{
public class InMemoryUrlTemplateMapRepository : IUrlTemplateMapRepository
{
private readonly Dictionary<string, string> _urlTemplates;
public InMemoryUrlTemplateMapRepository()
{
_urlTemplates = new Dictionary<string,string>();
}
public Response<List<UrlTemplateMap>> All
{
get
{
var routes = _urlTemplates
.Select(r => new UrlTemplateMap(r.Key, r.Value))
.ToList();
return new OkResponse<List<UrlTemplateMap>>(routes);
}
}
public Response AddUrlTemplateMap(UrlTemplateMap urlMap)
{
if(_urlTemplates.ContainsKey(urlMap.DownstreamUrlTemplate))
{
return new ErrorResponse(new List<Error>(){new DownstreamUrlTemplateAlreadyExists()});
}
_urlTemplates.Add(urlMap.DownstreamUrlTemplate, urlMap.UpstreamUrlPathTemplate);
return new OkResponse();
}
}
}

View File

@ -0,0 +1,14 @@
namespace Ocelot.Library.Infrastructure.UrlTemplateRepository
{
public class UrlTemplateMap
{
public UrlTemplateMap(string downstreamUrlTemplate, string upstreamUrlPathTemplate)
{
DownstreamUrlTemplate = downstreamUrlTemplate;
UpstreamUrlPathTemplate = upstreamUrlPathTemplate;
}
public string DownstreamUrlTemplate {get;private set;}
public string UpstreamUrlPathTemplate {get;private set;}
}
}

View File

@ -1,10 +1,8 @@
using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Ocelot.Library.Infrastructure.HostUrlRepository; using Ocelot.Library.Infrastructure.UrlMatcher;
using Ocelot.Library.Infrastructure.UrlPathMatcher; using Ocelot.Library.Infrastructure.UrlTemplateRepository;
using Ocelot.Library.Infrastructure.UrlPathReplacer; using Ocelot.Library.Infrastructure.UrlTemplateReplacer;
using Ocelot.Library.Infrastructure.UrlPathTemplateRepository;
namespace Ocelot.Library.Middleware namespace Ocelot.Library.Middleware
{ {
@ -13,53 +11,48 @@ namespace Ocelot.Library.Middleware
public class ProxyMiddleware public class ProxyMiddleware
{ {
private readonly RequestDelegate _next; private readonly RequestDelegate _next;
private readonly IUrlPathToUrlPathTemplateMatcher _urlMatcher; private readonly IUrlPathToUrlTemplateMatcher _urlMatcher;
private readonly IUrlPathTemplateMapRepository _urlPathRepository; private readonly IUrlTemplateMapRepository _urlTemplateMapRepository;
private readonly IHostUrlMapRepository _hostUrlRepository; private readonly IDownstreamUrlTemplateVariableReplacer _urlReplacer;
private readonly IUpstreamUrlPathTemplateVariableReplacer _urlReplacer;
public ProxyMiddleware(RequestDelegate next, public ProxyMiddleware(RequestDelegate next,
IUrlPathToUrlPathTemplateMatcher urlMatcher, IUrlPathToUrlTemplateMatcher urlMatcher,
IUrlPathTemplateMapRepository urlPathRepository, IUrlTemplateMapRepository urlPathRepository,
IHostUrlMapRepository hostUrlRepository, IDownstreamUrlTemplateVariableReplacer urlReplacer)
IUpstreamUrlPathTemplateVariableReplacer urlReplacer)
{ {
_next = next; _next = next;
_urlMatcher = urlMatcher; _urlMatcher = urlMatcher;
_urlPathRepository = urlPathRepository; _urlTemplateMapRepository = urlPathRepository;
_hostUrlRepository = hostUrlRepository;
_urlReplacer = urlReplacer; _urlReplacer = urlReplacer;
} }
public async Task Invoke(HttpContext context) public async Task Invoke(HttpContext context)
{ {
var downstreamUrlPath = context.Request.Path.ToString();
var path = context.Request.Path.ToString(); var upstreamUrlTemplates = _urlTemplateMapRepository.All;
var urlPathTemplateMaps = _urlPathRepository.All; UrlMatch urlMatch = null;
UrlPathMatch urlPathMatch = null; string downstreamUrlTemplate = string.Empty;
string upstreamPathUrlTemplate = string.Empty;
foreach (var template in urlPathTemplateMaps.Data) foreach (var template in upstreamUrlTemplates.Data)
{ {
urlPathMatch = _urlMatcher.Match(path, template.DownstreamUrlPathTemplate); urlMatch = _urlMatcher.Match(downstreamUrlPath, template.DownstreamUrlTemplate);
if (urlPathMatch.Match) if (urlMatch.Match)
{ {
upstreamPathUrlTemplate = template.UpstreamUrlPathTemplate; downstreamUrlTemplate = template.DownstreamUrlTemplate;
break; break;
} }
} }
if (urlPathMatch == null || !urlPathMatch.Match) if (urlMatch == null || !urlMatch.Match)
{ {
context.Response.StatusCode = (int)HttpStatusCode.NotFound; context.Response.StatusCode = (int)HttpStatusCode.NotFound;
return; return;
} }
var upstreamHostUrl = _hostUrlRepository.GetBaseUrlMap(urlPathMatch.DownstreamUrlPathTemplate); var downstreamUrl = _urlReplacer.ReplaceTemplateVariable(downstreamUrlTemplate, urlMatch);
var pathUrl = _urlReplacer.ReplaceTemplateVariable(upstreamPathUrlTemplate, urlPathMatch);
//make a http request to this endpoint...maybe bring in a library //make a http request to this endpoint...maybe bring in a library

View File

@ -8,10 +8,9 @@ using Ocelot.Library.Middleware;
namespace Ocelot namespace Ocelot
{ {
using Library.Infrastructure.HostUrlRepository; using Library.Infrastructure.UrlMatcher;
using Library.Infrastructure.UrlPathMatcher; using Library.Infrastructure.UrlTemplateReplacer;
using Library.Infrastructure.UrlPathReplacer; using Library.Infrastructure.UrlTemplateRepository;
using Library.Infrastructure.UrlPathTemplateRepository;
public class Startup public class Startup
{ {
@ -31,11 +30,9 @@ namespace Ocelot
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
// Add framework services. // Add framework services.
services.AddSingleton<IHostUrlMapRepository, InMemoryHostUrlMapRepository>(); services.AddSingleton<IUrlPathToUrlTemplateMatcher, UrlPathToUrlTemplateMatcher>();
services.AddSingleton<IUrlPathToUrlPathTemplateMatcher, UrlPathToUrlPathTemplateMatcher>(); services.AddSingleton<IDownstreamUrlTemplateVariableReplacer, DownstreamUrlTemplateVariableReplacer>();
services.AddSingleton<IHostUrlMapRepository, InMemoryHostUrlMapRepository>(); services.AddSingleton<IUrlTemplateMapRepository, InMemoryUrlTemplateMapRepository>();
services.AddSingleton<IUpstreamUrlPathTemplateVariableReplacer, UpstreamUrlPathTemplateVariableReplacer>();
services.AddSingleton<IUrlPathTemplateMapRepository, InMemoryUrlPathTemplateMapRepository>();
} }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.

View File

@ -11,14 +11,14 @@ namespace Ocelot.AcceptanceTests
using System.Net; using System.Net;
using TestStack.BDDfy; using TestStack.BDDfy;
public class RouterTests : IDisposable public class OcelotTests : IDisposable
{ {
private readonly FakeService _fakeService; private readonly FakeService _fakeService;
private readonly TestServer _server; private readonly TestServer _server;
private readonly HttpClient _client; private readonly HttpClient _client;
private HttpResponseMessage _response; private HttpResponseMessage _response;
public RouterTests() public OcelotTests()
{ {
_server = new TestServer(new WebHostBuilder() _server = new TestServer(new WebHostBuilder()
.UseStartup<Startup>()); .UseStartup<Startup>());
@ -36,6 +36,15 @@ namespace Ocelot.AcceptanceTests
.BDDfy(); .BDDfy();
} }
[Fact]
public void should_return_response_200()
{
this.When(x => x.WhenIRequestTheUrl("/"))
.Then(x => x.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
.And(x => x.ThenTheResponseBodyShouldBe("Hello from Laura"))
.BDDfy();
}
private void WhenIRequestTheUrl(string url) private void WhenIRequestTheUrl(string url)
{ {
_response = _client.GetAsync("/").Result; _response = _client.GetAsync("/").Result;
@ -46,6 +55,11 @@ namespace Ocelot.AcceptanceTests
_response.StatusCode.ShouldBe(expectedHttpStatusCode); _response.StatusCode.ShouldBe(expectedHttpStatusCode);
} }
private void ThenTheResponseBodyShouldBe(string expectedBody)
{
_response.Content.ReadAsStringAsync().Result.ShouldBe(expectedBody);
}
public void Dispose() public void Dispose()
{ {
_fakeService.Stop(); _fakeService.Stop();

View File

@ -1,117 +0,0 @@
using Ocelot.Library.Infrastructure.Responses;
using Ocelot.Library.Infrastructure.HostUrlRepository;
using Shouldly;
using Xunit;
namespace Ocelot.UnitTests
{
using TestStack.BDDfy;
public class HostUrlMapRepositoryTests
{
private string _upstreamBaseUrl;
private string _downstreamBaseUrl;
private readonly IHostUrlMapRepository _repository;
private Response _response;
private Response<HostUrlMap> _getRouteResponse;
public HostUrlMapRepositoryTests()
{
_repository = new InMemoryHostUrlMapRepository();
}
[Fact]
public void can_add_route()
{
this.Given(x => x.GivenIHaveAnUpstreamBaseUrl("www.someapi.com"))
.And(x => x.GivenIWantToRouteRequestsFromMyDownstreamBaseUrl("api"))
.When(x => x.WhenIAddTheConfiguration())
.Then(x => x.ThenTheResponseIsSuccesful())
.BDDfy();
}
[Fact]
public void can_get_route_by_key()
{
this.Given(x => x.GivenIHaveSetUpAnApiKeyAndUpstreamUrl("api2", "www.someapi.com"))
.When(x => x.WhenIRetrieveTheRouteByKey())
.Then(x => x.ThenTheRouteIsReturned())
.BDDfy();
}
[Fact]
public void should_return_error_response_when_key_already_used()
{
this.Given(x => x.GivenIHaveSetUpAnApiKeyAndUpstreamUrl("api2", "www.someapi.com"))
.When(x => x.WhenITryToUseTheSameKey())
.Then(x => x.ThenTheKeyHasAlreadyBeenUsed())
.BDDfy();
}
[Fact]
public void should_return_error_response_if_key_doesnt_exist()
{
this.Given(x => x.GivenIWantToRouteRequestsFromMyDownstreamBaseUrl("api"))
.When(x => x.WhenIRetrieveTheRouteByKey())
.Then(x => x.ThenTheKeyDoesNotExist())
.BDDfy();
}
private void WhenITryToUseTheSameKey()
{
WhenIAddTheConfiguration();
}
private void ThenTheKeyHasAlreadyBeenUsed()
{
_response.ShouldNotBeNull();
_response.ShouldBeOfType<ErrorResponse>();
_response.Errors[0].Message.ShouldBe("This key has already been used");
}
private void ThenTheKeyDoesNotExist()
{
_getRouteResponse.ShouldNotBeNull();
_getRouteResponse.ShouldBeOfType<ErrorResponse<HostUrlMap>>();
_getRouteResponse.Errors[0].Message.ShouldBe("This key does not exist");
}
private void WhenIRetrieveTheRouteByKey()
{
_getRouteResponse = _repository.GetBaseUrlMap(_downstreamBaseUrl);
}
private void ThenTheRouteIsReturned()
{
_getRouteResponse.Data.UrlPathTemplate.ShouldBe(_downstreamBaseUrl);
_getRouteResponse.Data.UpstreamHostUrl.ShouldBe(_upstreamBaseUrl);
}
private void GivenIHaveSetUpAnApiKeyAndUpstreamUrl(string apiKey, string upstreamUrl)
{
GivenIHaveAnUpstreamBaseUrl(upstreamUrl);
GivenIWantToRouteRequestsFromMyDownstreamBaseUrl(apiKey);
WhenIAddTheConfiguration();
}
private void GivenIHaveAnUpstreamBaseUrl(string upstreamApiUrl)
{
_upstreamBaseUrl = upstreamApiUrl;
}
private void GivenIWantToRouteRequestsFromMyDownstreamBaseUrl(string downstreamBaseUrl)
{
_downstreamBaseUrl = downstreamBaseUrl;
}
private void WhenIAddTheConfiguration()
{
_response = _repository.AddBaseUrlMap(new HostUrlMap(_downstreamBaseUrl, _upstreamBaseUrl));
}
private void ThenTheResponseIsSuccesful()
{
_response.ShouldBeOfType<OkResponse>();
}
}
}

View File

@ -1,68 +0,0 @@
using Ocelot.Library.Infrastructure.HostUrlRepository;
using Ocelot.Library.Infrastructure.UrlFinder;
using Ocelot.Library.Infrastructure.Responses;
using Xunit;
using Shouldly;
using TestStack.BDDfy;
namespace Ocelot.UnitTests
{
public class UpstreamBaseUrlFinderTests
{
private readonly IUpstreamHostUrlFinder _upstreamBaseUrlFinder;
private readonly IHostUrlMapRepository _hostUrlMapRepository;
private string _downstreamBaseUrl;
private Response<string> _result;
public UpstreamBaseUrlFinderTests()
{
_hostUrlMapRepository = new InMemoryHostUrlMapRepository();
_upstreamBaseUrlFinder = new UpstreamHostUrlFinder(_hostUrlMapRepository);
}
[Fact]
public void can_find_base_url()
{
this.Given(x => x.GivenTheBaseUrlMapExists(new HostUrlMap("api.tom.com", "api.laura.com")))
.And(x => x.GivenTheDownstreamBaseUrlIs("api.tom.com"))
.When(x => x.WhenIFindTheMatchingUpstreamBaseUrl())
.Then(x => x.ThenTheFollowingIsReturned("api.laura.com"))
.BDDfy();
}
[Fact]
public void cant_find_base_url()
{
this.Given(x => x.GivenTheDownstreamBaseUrlIs("api.tom.com"))
.When(x => x.WhenIFindTheMatchingUpstreamBaseUrl())
.Then(x => x.ThenAnErrorIsReturned())
.BDDfy();
}
private void ThenAnErrorIsReturned()
{
_result.Errors.Count.ShouldBe(1);
}
private void GivenTheBaseUrlMapExists(HostUrlMap baseUrlMap)
{
_hostUrlMapRepository.AddBaseUrlMap(baseUrlMap);
}
private void GivenTheDownstreamBaseUrlIs(string downstreamBaseUrl)
{
_downstreamBaseUrl = downstreamBaseUrl;
}
private void WhenIFindTheMatchingUpstreamBaseUrl()
{
_result = _upstreamBaseUrlFinder.FindUpstreamHostUrl(_downstreamBaseUrl);
}
private void ThenTheFollowingIsReturned(string expectedBaseUrl)
{
_result.Data.ShouldBe(expectedBaseUrl);
}
}
}

View File

@ -1,6 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using Ocelot.Library.Infrastructure.UrlPathMatcher; using Ocelot.Library.Infrastructure.UrlMatcher;
using Ocelot.Library.Infrastructure.UrlPathReplacer; using Ocelot.Library.Infrastructure.UrlTemplateReplacer;
using Shouldly; using Shouldly;
using Xunit; using Xunit;
@ -10,53 +10,53 @@ namespace Ocelot.UnitTests
public class UpstreamUrlPathTemplateVariableReplacerTests public class UpstreamUrlPathTemplateVariableReplacerTests
{ {
private string _upstreamUrlPath; private string _downstreamUrlTemplate;
private UrlPathMatch _urlPathMatch; private UrlMatch _urlMatch;
private string _result; private string _result;
private readonly IUpstreamUrlPathTemplateVariableReplacer _upstreamUrlPathReplacer; private readonly IDownstreamUrlTemplateVariableReplacer _downstreamUrlPathReplacer;
public UpstreamUrlPathTemplateVariableReplacerTests() public UpstreamUrlPathTemplateVariableReplacerTests()
{ {
_upstreamUrlPathReplacer = new UpstreamUrlPathTemplateVariableReplacer(); _downstreamUrlPathReplacer = new DownstreamUrlTemplateVariableReplacer();
} }
[Fact] [Fact]
public void can_replace_no_template_variables() public void can_replace_no_template_variables()
{ {
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("")) this.Given(x => x.GivenThereIsADownstreamUrl(""))
.And(x => x.GivenThereIsAUrlPathMatch(new UrlPathMatch(true, new List<TemplateVariableNameAndValue>(), ""))) .And(x => x.GivenThereIsAUrlMatch(new UrlMatch(true, new List<TemplateVariableNameAndValue>(), "")))
.When(x => x.WhenIReplaceTheTemplateVariables()) .When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheUpstreamUrlPathIsReturned("")) .Then(x => x.ThenTheDownstreamUrlPathIsReturned(""))
.BDDfy(); .BDDfy();
} }
[Fact] [Fact]
public void can_replace_url_no_slash() public void can_replace_url_no_slash()
{ {
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("api")) this.Given(x => x.GivenThereIsADownstreamUrl("api"))
.And(x => x.GivenThereIsAUrlPathMatch(new UrlPathMatch(true, new List<TemplateVariableNameAndValue>(), "api"))) .And(x => x.GivenThereIsAUrlMatch(new UrlMatch(true, new List<TemplateVariableNameAndValue>(), "api")))
.When(x => x.WhenIReplaceTheTemplateVariables()) .When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheUpstreamUrlPathIsReturned("api")) .Then(x => x.ThenTheDownstreamUrlPathIsReturned("api"))
.BDDfy(); .BDDfy();
} }
[Fact] [Fact]
public void can_replace_url_one_slash() public void can_replace_url_one_slash()
{ {
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("api/")) this.Given(x => x.GivenThereIsADownstreamUrl("api/"))
.And(x => x.GivenThereIsAUrlPathMatch(new UrlPathMatch(true, new List<TemplateVariableNameAndValue>(), "api/"))) .And(x => x.GivenThereIsAUrlMatch(new UrlMatch(true, new List<TemplateVariableNameAndValue>(), "api/")))
.When(x => x.WhenIReplaceTheTemplateVariables()) .When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheUpstreamUrlPathIsReturned("api/")) .Then(x => x.ThenTheDownstreamUrlPathIsReturned("api/"))
.BDDfy(); .BDDfy();
} }
[Fact] [Fact]
public void can_replace_url_multiple_slash() public void can_replace_url_multiple_slash()
{ {
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("api/product/products/")) this.Given(x => x.GivenThereIsADownstreamUrl("api/product/products/"))
.And(x => x.GivenThereIsAUrlPathMatch(new UrlPathMatch(true, new List<TemplateVariableNameAndValue>(), "api/product/products/"))) .And(x => x.GivenThereIsAUrlMatch(new UrlMatch(true, new List<TemplateVariableNameAndValue>(), "api/product/products/")))
.When(x => x.WhenIReplaceTheTemplateVariables()) .When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheUpstreamUrlPathIsReturned("api/product/products/")) .Then(x => x.ThenTheDownstreamUrlPathIsReturned("api/product/products/"))
.BDDfy(); .BDDfy();
} }
@ -68,10 +68,10 @@ namespace Ocelot.UnitTests
new TemplateVariableNameAndValue("{productId}", "1") new TemplateVariableNameAndValue("{productId}", "1")
}; };
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("productservice/products/{productId}/")) this.Given(x => x.GivenThereIsADownstreamUrl("productservice/products/{productId}/"))
.And(x => x.GivenThereIsAUrlPathMatch(new UrlPathMatch(true, templateVariables, "api/products/{productId}/"))) .And(x => x.GivenThereIsAUrlMatch(new UrlMatch(true, templateVariables, "api/products/{productId}/")))
.When(x => x.WhenIReplaceTheTemplateVariables()) .When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheUpstreamUrlPathIsReturned("productservice/products/1/")) .Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/products/1/"))
.BDDfy(); .BDDfy();
} }
@ -83,10 +83,10 @@ namespace Ocelot.UnitTests
new TemplateVariableNameAndValue("{productId}", "1") new TemplateVariableNameAndValue("{productId}", "1")
}; };
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("productservice/products/{productId}/variants")) this.Given(x => x.GivenThereIsADownstreamUrl("productservice/products/{productId}/variants"))
.And(x => x.GivenThereIsAUrlPathMatch(new UrlPathMatch(true, templateVariables, "api/products/{productId}/"))) .And(x => x.GivenThereIsAUrlMatch(new UrlMatch(true, templateVariables, "api/products/{productId}/")))
.When(x => x.WhenIReplaceTheTemplateVariables()) .When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheUpstreamUrlPathIsReturned("productservice/products/1/variants")) .Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/products/1/variants"))
.BDDfy(); .BDDfy();
} }
@ -99,10 +99,10 @@ namespace Ocelot.UnitTests
new TemplateVariableNameAndValue("{variantId}", "12") new TemplateVariableNameAndValue("{variantId}", "12")
}; };
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("productservice/products/{productId}/variants/{variantId}")) this.Given(x => x.GivenThereIsADownstreamUrl("productservice/products/{productId}/variants/{variantId}"))
.And(x => x.GivenThereIsAUrlPathMatch(new UrlPathMatch(true, templateVariables, "api/products/{productId}/{variantId}"))) .And(x => x.GivenThereIsAUrlMatch(new UrlMatch(true, templateVariables, "api/products/{productId}/{variantId}")))
.When(x => x.WhenIReplaceTheTemplateVariables()) .When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheUpstreamUrlPathIsReturned("productservice/products/1/variants/12")) .Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/products/1/variants/12"))
.BDDfy(); .BDDfy();
} }
@ -116,29 +116,29 @@ namespace Ocelot.UnitTests
new TemplateVariableNameAndValue("{categoryId}", "34") new TemplateVariableNameAndValue("{categoryId}", "34")
}; };
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("productservice/category/{categoryId}/products/{productId}/variants/{variantId}")) this.Given(x => x.GivenThereIsADownstreamUrl("productservice/category/{categoryId}/products/{productId}/variants/{variantId}"))
.And(x => x.GivenThereIsAUrlPathMatch(new UrlPathMatch(true, templateVariables, "api/products/{categoryId}/{productId}/{variantId}"))) .And(x => x.GivenThereIsAUrlMatch(new UrlMatch(true, templateVariables, "api/products/{categoryId}/{productId}/{variantId}")))
.When(x => x.WhenIReplaceTheTemplateVariables()) .When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheUpstreamUrlPathIsReturned("productservice/category/34/products/1/variants/12")) .Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/category/34/products/1/variants/12"))
.BDDfy(); .BDDfy();
} }
private void GivenThereIsAnUpstreamUrlPath(string upstreamUrlPath) private void GivenThereIsADownstreamUrl(string downstreamUrlTemplate)
{ {
_upstreamUrlPath = upstreamUrlPath; _downstreamUrlTemplate = downstreamUrlTemplate;
} }
private void GivenThereIsAUrlPathMatch(UrlPathMatch urlPathMatch) private void GivenThereIsAUrlMatch(UrlMatch urlMatch)
{ {
_urlPathMatch = urlPathMatch; _urlMatch = urlMatch;
} }
private void WhenIReplaceTheTemplateVariables() private void WhenIReplaceTheTemplateVariables()
{ {
_result = _upstreamUrlPathReplacer.ReplaceTemplateVariable(_upstreamUrlPath, _urlPathMatch); _result = _downstreamUrlPathReplacer.ReplaceTemplateVariable(_downstreamUrlTemplate, _urlMatch);
} }
private void ThenTheUpstreamUrlPathIsReturned(string expected) private void ThenTheDownstreamUrlPathIsReturned(string expected)
{ {
_result.ShouldBe(expected); _result.ShouldBe(expected);
} }

View File

@ -1,6 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using Ocelot.Library.Infrastructure.Responses; using Ocelot.Library.Infrastructure.Responses;
using Ocelot.Library.Infrastructure.UrlPathTemplateRepository; using Ocelot.Library.Infrastructure.UrlTemplateRepository;
using Shouldly; using Shouldly;
using Xunit; using Xunit;
@ -10,41 +10,31 @@ namespace Ocelot.UnitTests
public class UrlPathTemplateMapRepositoryTests public class UrlPathTemplateMapRepositoryTests
{ {
private string _upstreamUrlPath; private string _upstreamUrlPathTemplate;
private string _downstreamUrlPath; private string _downstreamUrlTemplate;
private IUrlPathTemplateMapRepository _repository; private IUrlTemplateMapRepository _repository;
private Response _response; private Response _response;
private Response<UrlPathTemplateMap> _getResponse; private Response<List<UrlTemplateMap>> _listResponse;
private Response<List<UrlPathTemplateMap>> _listResponse;
public UrlPathTemplateMapRepositoryTests() public UrlPathTemplateMapRepositoryTests()
{ {
_repository = new InMemoryUrlPathTemplateMapRepository(); _repository = new InMemoryUrlTemplateMapRepository();
} }
[Fact] [Fact]
public void can_add_url_path() public void can_add_url_path()
{ {
this.Given(x => x.GivenIHaveAnUpstreamUrlPath("/api/products/products/{productId}")) this.Given(x => x.GivenIHaveAnUpstreamUrlPathTemplate("/api/products/products/{productId}"))
.And(x => x.GivenIWantToRouteRequestsToMyUpstreamUrlPath("/api/products/{productId}")) .And(x => x.GivenADownstreamUrlTemplate("/api/products/{productId}"))
.When(x => x.WhenIAddTheConfiguration()) .When(x => x.WhenIAddTheConfiguration())
.Then(x => x.ThenTheResponseIsSuccesful()) .Then(x => x.ThenTheResponseIsSuccesful())
.BDDfy(); .BDDfy();
} }
[Fact]
public void can_get_url_path()
{
this.Given(x => x.GivenIHaveSetUpADownstreamUrlPathAndAnUpstreamUrlPath("/api2", "http://www.someapi.com/api2"))
.When(x => x.WhenIRetrieveTheUrlPathByDownstreamUrl())
.Then(x => x.ThenTheUrlPathIsReturned())
.BDDfy();
}
[Fact] [Fact]
public void can_get_all_urls() public void can_get_all_urls()
{ {
this.Given(x => x.GivenIHaveSetUpADownstreamUrlPathAndAnUpstreamUrlPath("/api2", "http://www.someapi.com/api2")) this.Given(x => x.GivenIHaveSetUpADownstreamUrlTemplateAndAnUpstreamUrlPathTemplate("/api2", "http://www.someapi.com/api2"))
.When(x => x.WhenIRetrieveTheUrls()) .When(x => x.WhenIRetrieveTheUrls())
.Then(x => x.ThenTheUrlsAreReturned()) .Then(x => x.ThenTheUrlsAreReturned())
.BDDfy(); .BDDfy();
@ -53,21 +43,12 @@ namespace Ocelot.UnitTests
[Fact] [Fact]
public void should_return_error_response_when_url_path_already_used() public void should_return_error_response_when_url_path_already_used()
{ {
this.Given(x => x.GivenIHaveSetUpADownstreamUrlPathAndAnUpstreamUrlPath("/api2", "http://www.someapi.com/api2")) this.Given(x => x.GivenIHaveSetUpADownstreamUrlTemplateAndAnUpstreamUrlPathTemplate("/api2", "http://www.someapi.com/api2"))
.When(x => x.WhenITryToUseTheSameDownstreamUrl()) .When(x => x.WhenITryToUseTheSameDownstreamUrl())
.Then(x => x.ThenTheDownstreamUrlAlreadyBeenUsed()) .Then(x => x.ThenTheDownstreamUrlAlreadyBeenUsed())
.BDDfy(); .BDDfy();
} }
[Fact]
public void should_return_error_response_if_key_doesnt_exist()
{
this.Given(x => x.GivenIWantToRouteRequestsToMyUpstreamUrlPath("/api"))
.When(x => x.WhenIRetrieveTheUrlPathByDownstreamUrl())
.Then(x => x.ThenTheKeyDoesNotExist())
.BDDfy();
}
private void WhenITryToUseTheSameDownstreamUrl() private void WhenITryToUseTheSameDownstreamUrl()
{ {
WhenIAddTheConfiguration(); WhenIAddTheConfiguration();
@ -80,54 +61,36 @@ namespace Ocelot.UnitTests
_response.Errors[0].Message.ShouldBe("This key has already been used"); _response.Errors[0].Message.ShouldBe("This key has already been used");
} }
private void ThenTheKeyDoesNotExist()
{
_getResponse.ShouldNotBeNull();
_getResponse.ShouldBeOfType<ErrorResponse<UrlPathTemplateMap>>();
_getResponse.Errors[0].Message.ShouldBe("This key does not exist");
}
private void WhenIRetrieveTheUrlPathByDownstreamUrl()
{
_getResponse = _repository.GetUrlPathTemplateMap(_downstreamUrlPath);
}
private void WhenIRetrieveTheUrls() private void WhenIRetrieveTheUrls()
{ {
_listResponse = _repository.All; _listResponse = _repository.All;
} }
private void ThenTheUrlPathIsReturned()
{
_getResponse.Data.DownstreamUrlPathTemplate.ShouldBe(_downstreamUrlPath);
_getResponse.Data.UpstreamUrlPathTemplate.ShouldBe(_upstreamUrlPath);
}
private void ThenTheUrlsAreReturned() private void ThenTheUrlsAreReturned()
{ {
_listResponse.Data.Count.ShouldBeGreaterThan(0); _listResponse.Data.Count.ShouldBeGreaterThan(0);
} }
private void GivenIHaveSetUpADownstreamUrlPathAndAnUpstreamUrlPath(string downstream, string upstreamApiUrl) private void GivenIHaveSetUpADownstreamUrlTemplateAndAnUpstreamUrlPathTemplate(string downstreamUrlTemplate, string upstreamUrlPathTemplate)
{ {
GivenIHaveAnUpstreamUrlPath(upstreamApiUrl); GivenIHaveAnUpstreamUrlPathTemplate(upstreamUrlPathTemplate);
GivenIWantToRouteRequestsToMyUpstreamUrlPath(downstream); GivenADownstreamUrlTemplate(downstreamUrlTemplate);
WhenIAddTheConfiguration(); WhenIAddTheConfiguration();
} }
private void GivenIHaveAnUpstreamUrlPath(string upstreamApiUrl) private void GivenIHaveAnUpstreamUrlPathTemplate(string upstreamUrlPathTemplate)
{ {
_upstreamUrlPath = upstreamApiUrl; _upstreamUrlPathTemplate = upstreamUrlPathTemplate;
} }
private void GivenIWantToRouteRequestsToMyUpstreamUrlPath(string apiKey) private void GivenADownstreamUrlTemplate(string downstreamUrlTemplate)
{ {
_downstreamUrlPath = apiKey; _downstreamUrlTemplate = downstreamUrlTemplate;
} }
private void WhenIAddTheConfiguration() private void WhenIAddTheConfiguration()
{ {
_response = _repository.AddUrlPathTemplateMap(new UrlPathTemplateMap(_downstreamUrlPath, _upstreamUrlPath)); _response = _repository.AddUrlTemplateMap(new UrlTemplateMap(_downstreamUrlTemplate, _upstreamUrlPathTemplate));
} }
private void ThenTheResponseIsSuccesful() private void ThenTheResponseIsSuccesful()

View File

@ -1,6 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Ocelot.Library.Infrastructure.UrlPathMatcher; using Ocelot.Library.Infrastructure.UrlMatcher;
using Shouldly; using Shouldly;
using Xunit; using Xunit;
@ -8,26 +8,26 @@ namespace Ocelot.UnitTests
{ {
using TestStack.BDDfy; using TestStack.BDDfy;
public class UrlPathToUrlPathTemplateMatcherTests public class UrlPathToUrlTemplateMatcherTests
{ {
private readonly IUrlPathToUrlPathTemplateMatcher _urlMapper; private readonly IUrlPathToUrlTemplateMatcher _urlMatcher;
private string _downstreamPath; private string _downstreamUrlPath;
private string _downstreamPathTemplate; private string _downstreamPathTemplate;
private UrlPathMatch _result; private UrlMatch _result;
public UrlPathToUrlPathTemplateMatcherTests() public UrlPathToUrlTemplateMatcherTests()
{ {
_urlMapper = new UrlPathToUrlPathTemplateMatcher(); _urlMatcher = new UrlPathToUrlTemplateMatcher();
} }
[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.GivenIHaveADownstreamPath(""))
.And(x => x.GivenIHaveAnDownstreamPathTemplate("")) .And(x => x.GivenIHaveAnDownstreamUrlTemplate(""))
.When(x => x.WhenIMatchThePaths()) .When(x => x.WhenIMatchThePaths())
.And(x => x.ThenTheResultIsTrue()) .And(x => x.ThenTheResultIsTrue())
.And(x => x.ThenTheTemplatesDictionaryIs(new List<TemplateVariableNameAndValue>())) .And(x => x.ThenTheTemplatesVariablesAre(new List<TemplateVariableNameAndValue>()))
.And(x => x.ThenTheUrlPathTemplateIs("")) .And(x => x.ThenTheDownstreamUrlTemplateIs(""))
.BDDfy(); .BDDfy();
} }
@ -35,11 +35,11 @@ namespace Ocelot.UnitTests
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.GivenIHaveADownstreamPath("api"))
.Given(x => x.GivenIHaveAnDownstreamPathTemplate("api")) .Given(x => x.GivenIHaveAnDownstreamUrlTemplate("api"))
.When(x => x.WhenIMatchThePaths()) .When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue()) .Then(x => x.ThenTheResultIsTrue())
.And(x => x.ThenTheTemplatesDictionaryIs(new List<TemplateVariableNameAndValue>())) .And(x => x.ThenTheTemplatesVariablesAre(new List<TemplateVariableNameAndValue>()))
.And(x => x.ThenTheUrlPathTemplateIs("api")) .And(x => x.ThenTheDownstreamUrlTemplateIs("api"))
.BDDfy(); .BDDfy();
} }
@ -47,11 +47,11 @@ namespace Ocelot.UnitTests
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.GivenIHaveADownstreamPath("api/"))
.Given(x => x.GivenIHaveAnDownstreamPathTemplate("api/")) .Given(x => x.GivenIHaveAnDownstreamUrlTemplate("api/"))
.When(x => x.WhenIMatchThePaths()) .When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue()) .Then(x => x.ThenTheResultIsTrue())
.And(x => x.ThenTheTemplatesDictionaryIs(new List<TemplateVariableNameAndValue>())) .And(x => x.ThenTheTemplatesVariablesAre(new List<TemplateVariableNameAndValue>()))
.And(x => x.ThenTheUrlPathTemplateIs("api/")) .And(x => x.ThenTheDownstreamUrlTemplateIs("api/"))
.BDDfy(); .BDDfy();
} }
@ -59,11 +59,11 @@ namespace Ocelot.UnitTests
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.GivenIHaveADownstreamPath("api/product/products/"))
.Given(x => x.GivenIHaveAnDownstreamPathTemplate("api/product/products/")) .Given(x => x.GivenIHaveAnDownstreamUrlTemplate("api/product/products/"))
.When(x => x.WhenIMatchThePaths()) .When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue()) .Then(x => x.ThenTheResultIsTrue())
.And(x => x.ThenTheTemplatesDictionaryIs(new List<TemplateVariableNameAndValue>())) .And(x => x.ThenTheTemplatesVariablesAre(new List<TemplateVariableNameAndValue>()))
.And(x => x.ThenTheUrlPathTemplateIs("api/product/products/")) .And(x => x.ThenTheDownstreamUrlTemplateIs("api/product/products/"))
.BDDfy(); .BDDfy();
} }
@ -71,11 +71,11 @@ namespace Ocelot.UnitTests
public void can_match_down_stream_url_with_downstream_template_with_one_query_string_parameter() 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")) this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/?soldout=false"))
.Given(x => x.GivenIHaveAnDownstreamPathTemplate("api/product/products/")) .Given(x => x.GivenIHaveAnDownstreamUrlTemplate("api/product/products/"))
.When(x => x.WhenIMatchThePaths()) .When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue()) .Then(x => x.ThenTheResultIsTrue())
.And(x => x.ThenTheTemplatesDictionaryIs(new List<TemplateVariableNameAndValue>())) .And(x => x.ThenTheTemplatesVariablesAre(new List<TemplateVariableNameAndValue>()))
.And(x => x.ThenTheUrlPathTemplateIs("api/product/products/")) .And(x => x.ThenTheDownstreamUrlTemplateIs("api/product/products/"))
.BDDfy(); .BDDfy();
} }
@ -88,11 +88,11 @@ namespace Ocelot.UnitTests
}; };
this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/1/variants/?soldout=false")) this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/1/variants/?soldout=false"))
.Given(x => x.GivenIHaveAnDownstreamPathTemplate("api/product/products/{productId}/variants/")) .Given(x => x.GivenIHaveAnDownstreamUrlTemplate("api/product/products/{productId}/variants/"))
.When(x => x.WhenIMatchThePaths()) .When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue()) .Then(x => x.ThenTheResultIsTrue())
.And(x => x.ThenTheTemplatesDictionaryIs(expectedTemplates)) .And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
.And(x => x.ThenTheUrlPathTemplateIs("api/product/products/{productId}/variants/")) .And(x => x.ThenTheDownstreamUrlTemplateIs("api/product/products/{productId}/variants/"))
.BDDfy(); .BDDfy();
} }
@ -105,11 +105,11 @@ namespace Ocelot.UnitTests
}; };
this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/1")) this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/1"))
.Given(x => x.GivenIHaveAnDownstreamPathTemplate("api/product/products/{productId}")) .Given(x => x.GivenIHaveAnDownstreamUrlTemplate("api/product/products/{productId}"))
.When(x => x.WhenIMatchThePaths()) .When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue()) .Then(x => x.ThenTheResultIsTrue())
.And(x => x.ThenTheTemplatesDictionaryIs(expectedTemplates)) .And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
.And(x => x.ThenTheUrlPathTemplateIs("api/product/products/{productId}")) .And(x => x.ThenTheDownstreamUrlTemplateIs("api/product/products/{productId}"))
.BDDfy(); .BDDfy();
} }
@ -123,11 +123,11 @@ namespace Ocelot.UnitTests
}; };
this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/1/2")) this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/1/2"))
.Given(x => x.GivenIHaveAnDownstreamPathTemplate("api/product/products/{productId}/{categoryId}")) .Given(x => x.GivenIHaveAnDownstreamUrlTemplate("api/product/products/{productId}/{categoryId}"))
.When(x => x.WhenIMatchThePaths()) .When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue()) .Then(x => x.ThenTheResultIsTrue())
.And(x => x.ThenTheTemplatesDictionaryIs(expectedTemplates)) .And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
.And(x => x.ThenTheUrlPathTemplateIs("api/product/products/{productId}/{categoryId}")) .And(x => x.ThenTheDownstreamUrlTemplateIs("api/product/products/{productId}/{categoryId}"))
.BDDfy(); .BDDfy();
} }
@ -141,11 +141,11 @@ namespace Ocelot.UnitTests
}; };
this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/1/categories/2")) this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/1/categories/2"))
.And(x => x.GivenIHaveAnDownstreamPathTemplate("api/product/products/{productId}/categories/{categoryId}")) .And(x => x.GivenIHaveAnDownstreamUrlTemplate("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.ThenTheTemplatesDictionaryIs(expectedTemplates)) .And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
.And(x => x.ThenTheUrlPathTemplateIs("api/product/products/{productId}/categories/{categoryId}")) .And(x => x.ThenTheDownstreamUrlTemplateIs("api/product/products/{productId}/categories/{categoryId}"))
.BDDfy(); .BDDfy();
} }
@ -160,11 +160,11 @@ namespace Ocelot.UnitTests
}; };
this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/1/categories/2/variant/123")) this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/1/categories/2/variant/123"))
.And(x => x.GivenIHaveAnDownstreamPathTemplate("api/product/products/{productId}/categories/{categoryId}/variant/{variantId}")) .And(x => x.GivenIHaveAnDownstreamUrlTemplate("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.ThenTheTemplatesDictionaryIs(expectedTemplates)) .And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
.And(x => x.ThenTheUrlPathTemplateIs("api/product/products/{productId}/categories/{categoryId}/variant/{variantId}")) .And(x => x.ThenTheDownstreamUrlTemplateIs("api/product/products/{productId}/categories/{categoryId}/variant/{variantId}"))
.BDDfy(); .BDDfy();
} }
@ -178,15 +178,15 @@ namespace Ocelot.UnitTests
}; };
this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/1/categories/2/variant/")) this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/1/categories/2/variant/"))
.And(x => x.GivenIHaveAnDownstreamPathTemplate("api/product/products/{productId}/categories/{categoryId}/variant/")) .And(x => x.GivenIHaveAnDownstreamUrlTemplate("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.ThenTheTemplatesDictionaryIs(expectedTemplates)) .And(x => x.ThenTheTemplatesVariablesAre(expectedTemplates))
.And(x => x.ThenTheUrlPathTemplateIs("api/product/products/{productId}/categories/{categoryId}/variant/")) .And(x => x.ThenTheDownstreamUrlTemplateIs("api/product/products/{productId}/categories/{categoryId}/variant/"))
.BDDfy(); .BDDfy();
} }
private void ThenTheTemplatesDictionaryIs(List<TemplateVariableNameAndValue> expectedResults) private void ThenTheTemplatesVariablesAre(List<TemplateVariableNameAndValue> expectedResults)
{ {
foreach (var expectedResult in expectedResults) foreach (var expectedResult in expectedResults)
{ {
@ -196,23 +196,23 @@ namespace Ocelot.UnitTests
} }
} }
private void ThenTheUrlPathTemplateIs(string expectedUrlPathTemplate) private void ThenTheDownstreamUrlTemplateIs(string expectedDownstreamUrlTemplate)
{ {
_result.DownstreamUrlPathTemplate.ShouldBe(expectedUrlPathTemplate); _result.DownstreamUrlTemplate.ShouldBe(expectedDownstreamUrlTemplate);
} }
private void GivenIHaveADownstreamPath(string downstreamPath) private void GivenIHaveADownstreamPath(string downstreamPath)
{ {
_downstreamPath = downstreamPath; _downstreamUrlPath = downstreamPath;
} }
private void GivenIHaveAnDownstreamPathTemplate(string downstreamTemplate) private void GivenIHaveAnDownstreamUrlTemplate(string downstreamUrlTemplate)
{ {
_downstreamPathTemplate = downstreamTemplate; _downstreamPathTemplate = downstreamUrlTemplate;
} }
private void WhenIMatchThePaths() private void WhenIMatchThePaths()
{ {
_result = _urlMapper.Match(_downstreamPath, _downstreamPathTemplate); _result = _urlMatcher.Match(_downstreamUrlPath, _downstreamPathTemplate);
} }
private void ThenTheResultIsTrue() private void ThenTheResultIsTrue()