This commit is contained in:
Tom Gardham-Pallister 2017-01-23 12:13:24 +00:00
parent cdad892a96
commit c3a47f66c8
55 changed files with 767 additions and 258 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

View File

@ -17,8 +17,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
Ocelot.nuspec = Ocelot.nuspec Ocelot.nuspec = Ocelot.nuspec
push-to-nuget.bat = push-to-nuget.bat push-to-nuget.bat = push-to-nuget.bat
README.md = README.md README.md = README.md
run-acceptance-tests.bat = run-acceptance-tests.bat
run-benchmarks.bat = run-benchmarks.bat run-benchmarks.bat = run-benchmarks.bat
run-tests.bat = run-tests.bat run-tests.bat = run-tests.bat
run-unit-tests.bat = run-unit-tests.bat
EndProjectSection EndProjectSection
EndProject EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Ocelot", "src\Ocelot\Ocelot.xproj", "{D6DF4206-0DBA-41D8-884D-C3E08290FDBB}" Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Ocelot", "src\Ocelot\Ocelot.xproj", "{D6DF4206-0DBA-41D8-884D-C3E08290FDBB}"

View File

@ -136,17 +136,20 @@ In order to set up a ReRoute you need to add one to the json array called ReRout
the following. the following.
{ {
"DownstreamTemplate": "http://jsonplaceholder.typicode.com/posts/{postId}", "DownstreamPathTemplate": "/api/posts/{postId}",
"DownstreamScheme": "https",
"DownstreamPort": 80,
"DownstreamHost" "localhost"
"UpstreamTemplate": "/posts/{postId}", "UpstreamTemplate": "/posts/{postId}",
"UpstreamHttpMethod": "Put" "UpstreamHttpMethod": "Put"
} }
The DownstreamTemplate is the URL that this request will be forwarded to. The DownstreamPathTemplate,Scheme, Port and Host make the URL that this request will be forwarded to.
The UpstreamTemplate is the URL that Ocelot will use to identity which The UpstreamTemplate is the URL that Ocelot will use to identity which
DownstreamTemplate to use for a given request. Finally the UpstreamHttpMethod is used so DownstreamPathTemplate to use for a given request. Finally the UpstreamHttpMethod is used so
Ocelot can distinguish between requests to the same URL and is obviously needed to work :) Ocelot can distinguish between requests to the same URL and is obviously needed to work :)
In Ocelot you can add placeholders for variables to your Templates in the form of {something}. In Ocelot you can add placeholders for variables to your Templates in the form of {something}.
The placeholder needs to be in both the DownstreamTemplate and UpstreamTemplate. If it is The placeholder needs to be in both the DownstreamPathTemplate and UpstreamTemplate. If it is
Ocelot will attempt to replace the placeholder with the correct variable value from the Ocelot will attempt to replace the placeholder with the correct variable value from the
Upstream URL when the request comes in. Upstream URL when the request comes in.

View File

@ -7,6 +7,6 @@ build_script:
test_script: test_script:
- run-tests.bat - run-tests.bat
after_test: after_test:
- push-to-nuget.bat %appveyor_build_version%-rc1 %nugetApiKey% - push-to-nuget.bat %appveyor_build_version% %nugetApiKey%
cache: cache:
- '%USERPROFILE%\.nuget\packages' - '%USERPROFILE%\.nuget\packages'

View File

@ -1,11 +1,20 @@
{ {
"ReRoutes": [ "ReRoutes": [
{ {
# The url we are forwarding the request to, ocelot will not add a trailing slash # The downstream path we are forwarding the request to, ocelot will not add a trailing slash.
"DownstreamTemplate": "http://somehost.com/identityserverexample", # Ocelot replaces any placeholders {etc} with matched values from the incoming request.
# The path we are listening on for this re route, Ocelot will add a trailing slash to "DownstreamPathTemplate": "/identityserverexample/{someid}/something",
# this property. Then when a request is made Ocelot makes sure a trailing slash is added # The scheme you want Ocelot to use when making the downstream request
# to that so everything matches "DownstreamScheme": "https",
# The port you want Ocelot to use when making the downstream request, will default to
# scheme if nothing set
"DownstreamPort": 80,
# The host address of the downstream service, should not have a trailing slash or scheme
# if there is a trailing slash Ocelot will remove it.
"DownstreamHost" "localhost"
# The path template we are listening on for this re route, Ocelot will add a trailing
# slash to this property. Then when a request is made Ocelot makes sure a trailing
# slash is added, so everything matches
"UpstreamTemplate": "/identityserverexample", "UpstreamTemplate": "/identityserverexample",
# The method we are listening for on this re route # The method we are listening for on this re route
"UpstreamHttpMethod": "Get", "UpstreamHttpMethod": "Get",

View File

@ -1,11 +1,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Ocelot.Values;
namespace Ocelot.Configuration.Builder namespace Ocelot.Configuration.Builder
{ {
public class ReRouteBuilder public class ReRouteBuilder
{ {
private string _downstreamTemplate; private string _downstreamPathTemplate;
private string _upstreamTemplate; private string _upstreamTemplate;
private string _upstreamTemplatePattern; private string _upstreamTemplatePattern;
private string _upstreamHttpMethod; private string _upstreamHttpMethod;
@ -30,6 +31,7 @@ namespace Ocelot.Configuration.Builder
private string _serviceDiscoveryAddress; private string _serviceDiscoveryAddress;
private string _downstreamScheme; private string _downstreamScheme;
private string _downstreamHost; private string _downstreamHost;
private int _dsPort;
public ReRouteBuilder() public ReRouteBuilder()
{ {
@ -72,9 +74,9 @@ namespace Ocelot.Configuration.Builder
return this; return this;
} }
public ReRouteBuilder WithDownstreamTemplate(string input) public ReRouteBuilder WithDownstreamPathTemplate(string input)
{ {
_downstreamTemplate = input; _downstreamPathTemplate = input;
return this; return this;
} }
@ -184,11 +186,17 @@ namespace Ocelot.Configuration.Builder
return this; return this;
} }
public ReRouteBuilder WithDownstreamPort(int port)
{
_dsPort = port;
return this;
}
public ReRoute Build() public ReRoute Build()
{ {
Func<string> downstreamHostFunc = () => { return _downstreamHost; }; Func<HostAndPort> downstreamHostFunc = () => new HostAndPort(_downstreamHost, _dsPort);
return new ReRoute(_downstreamTemplate, _upstreamTemplate, _upstreamHttpMethod, _upstreamTemplatePattern, return new ReRoute(new DownstreamPathTemplate(_downstreamPathTemplate), _upstreamTemplate, _upstreamHttpMethod, _upstreamTemplatePattern,
_isAuthenticated, new AuthenticationOptions(_authenticationProvider, _authenticationProviderUrl, _scopeName, _isAuthenticated, new AuthenticationOptions(_authenticationProvider, _authenticationProviderUrl, _scopeName,
_requireHttps, _additionalScopes, _scopeSecret), _configHeaderExtractorProperties, _claimToClaims, _routeClaimRequirement, _requireHttps, _additionalScopes, _scopeSecret), _configHeaderExtractorProperties, _claimToClaims, _routeClaimRequirement,
_isAuthorised, _claimToQueries, _requestIdHeaderKey, _isCached, _fileCacheOptions, _serviceName, _isAuthorised, _claimToQueries, _requestIdHeaderKey, _isCached, _fileCacheOptions, _serviceName,

View File

@ -8,6 +8,7 @@ using Ocelot.Configuration.Parser;
using Ocelot.Configuration.Validator; using Ocelot.Configuration.Validator;
using Ocelot.Responses; using Ocelot.Responses;
using Ocelot.Utilities; using Ocelot.Utilities;
using Ocelot.Values;
namespace Ocelot.Configuration.Creator namespace Ocelot.Configuration.Creator
{ {
@ -96,7 +97,7 @@ namespace Ocelot.Configuration.Creator
&& !string.IsNullOrEmpty(globalConfiguration?.ServiceDiscoveryProvider?.Provider); && !string.IsNullOrEmpty(globalConfiguration?.ServiceDiscoveryProvider?.Provider);
Func<string> downstreamHostFunc = () => { return reRoute.DownstreamHost; }; Func<HostAndPort> downstreamHostAndPortFunc = () => new HostAndPort(reRoute.DownstreamHost.Trim('/'), reRoute.DownstreamPort);
if (isAuthenticated) if (isAuthenticated)
{ {
@ -109,22 +110,22 @@ namespace Ocelot.Configuration.Creator
var claimsToClaims = GetAddThingsToRequest(reRoute.AddClaimsToRequest); var claimsToClaims = GetAddThingsToRequest(reRoute.AddClaimsToRequest);
var claimsToQueries = GetAddThingsToRequest(reRoute.AddQueriesToRequest); var claimsToQueries = GetAddThingsToRequest(reRoute.AddQueriesToRequest);
return new ReRoute(reRoute.DownstreamTemplate, reRoute.UpstreamTemplate, return new ReRoute(new DownstreamPathTemplate(reRoute.DownstreamPathTemplate), reRoute.UpstreamTemplate,
reRoute.UpstreamHttpMethod, upstreamTemplate, isAuthenticated, reRoute.UpstreamHttpMethod, upstreamTemplate, isAuthenticated,
authOptionsForRoute, claimsToHeaders, claimsToClaims, authOptionsForRoute, claimsToHeaders, claimsToClaims,
reRoute.RouteClaimsRequirement, isAuthorised, claimsToQueries, reRoute.RouteClaimsRequirement, isAuthorised, claimsToQueries,
requestIdKey, isCached, new CacheOptions(reRoute.FileCacheOptions.TtlSeconds), requestIdKey, isCached, new CacheOptions(reRoute.FileCacheOptions.TtlSeconds),
reRoute.ServiceName, useServiceDiscovery, globalConfiguration?.ServiceDiscoveryProvider?.Provider, reRoute.ServiceName, useServiceDiscovery, globalConfiguration?.ServiceDiscoveryProvider?.Provider,
globalConfiguration?.ServiceDiscoveryProvider?.Address, downstreamHostFunc, reRoute.DownstreamScheme); globalConfiguration?.ServiceDiscoveryProvider?.Address, downstreamHostAndPortFunc, reRoute.DownstreamScheme);
} }
return new ReRoute(reRoute.DownstreamTemplate, reRoute.UpstreamTemplate, return new ReRoute(new DownstreamPathTemplate(reRoute.DownstreamPathTemplate), reRoute.UpstreamTemplate,
reRoute.UpstreamHttpMethod, upstreamTemplate, isAuthenticated, reRoute.UpstreamHttpMethod, upstreamTemplate, isAuthenticated,
null, new List<ClaimToThing>(), new List<ClaimToThing>(), null, new List<ClaimToThing>(), new List<ClaimToThing>(),
reRoute.RouteClaimsRequirement, isAuthorised, new List<ClaimToThing>(), reRoute.RouteClaimsRequirement, isAuthorised, new List<ClaimToThing>(),
requestIdKey, isCached, new CacheOptions(reRoute.FileCacheOptions.TtlSeconds), requestIdKey, isCached, new CacheOptions(reRoute.FileCacheOptions.TtlSeconds),
reRoute.ServiceName, useServiceDiscovery, globalConfiguration?.ServiceDiscoveryProvider?.Provider, reRoute.ServiceName, useServiceDiscovery, globalConfiguration?.ServiceDiscoveryProvider?.Provider,
globalConfiguration?.ServiceDiscoveryProvider?.Address, downstreamHostFunc, reRoute.DownstreamScheme); globalConfiguration?.ServiceDiscoveryProvider?.Address, downstreamHostAndPortFunc, reRoute.DownstreamScheme);
} }
private string BuildUpstreamTemplate(FileReRoute reRoute) private string BuildUpstreamTemplate(FileReRoute reRoute)

View File

@ -14,7 +14,7 @@ namespace Ocelot.Configuration.File
FileCacheOptions = new FileCacheOptions(); FileCacheOptions = new FileCacheOptions();
} }
public string DownstreamTemplate { get; set; } public string DownstreamPathTemplate { get; set; }
public string UpstreamTemplate { get; set; } public string UpstreamTemplate { get; set; }
public string UpstreamHttpMethod { get; set; } public string UpstreamHttpMethod { get; set; }
public FileAuthenticationOptions AuthenticationOptions { get; set; } public FileAuthenticationOptions AuthenticationOptions { get; set; }
@ -28,5 +28,6 @@ namespace Ocelot.Configuration.File
public string ServiceName { get; set; } public string ServiceName { get; set; }
public string DownstreamScheme {get;set;} public string DownstreamScheme {get;set;}
public string DownstreamHost {get;set;} public string DownstreamHost {get;set;}
public int DownstreamPort { get; set; }
} }
} }

View File

@ -1,17 +1,18 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Ocelot.Values;
namespace Ocelot.Configuration namespace Ocelot.Configuration
{ {
public class ReRoute public class ReRoute
{ {
public ReRoute(string downstreamTemplate, string upstreamTemplate, string upstreamHttpMethod, string upstreamTemplatePattern, public ReRoute(DownstreamPathTemplate downstreamPathTemplate, string upstreamTemplate, string upstreamHttpMethod, string upstreamTemplatePattern,
bool isAuthenticated, AuthenticationOptions authenticationOptions, List<ClaimToThing> configurationHeaderExtractorProperties, bool isAuthenticated, AuthenticationOptions authenticationOptions, List<ClaimToThing> configurationHeaderExtractorProperties,
List<ClaimToThing> claimsToClaims, Dictionary<string, string> routeClaimsRequirement, bool isAuthorised, List<ClaimToThing> claimsToQueries, List<ClaimToThing> claimsToClaims, Dictionary<string, string> routeClaimsRequirement, bool isAuthorised, List<ClaimToThing> claimsToQueries,
string requestIdKey, bool isCached, CacheOptions fileCacheOptions, string serviceName, bool useServiceDiscovery, string requestIdKey, bool isCached, CacheOptions fileCacheOptions, string serviceName, bool useServiceDiscovery,
string serviceDiscoveryProvider, string serviceDiscoveryAddress, Func<string> downstreamHost, string downstreamScheme) string serviceDiscoveryProvider, string serviceDiscoveryAddress, Func<HostAndPort> downstreamHostAndPort, string downstreamScheme)
{ {
DownstreamTemplate = downstreamTemplate; DownstreamPathTemplate = downstreamPathTemplate;
UpstreamTemplate = upstreamTemplate; UpstreamTemplate = upstreamTemplate;
UpstreamHttpMethod = upstreamHttpMethod; UpstreamHttpMethod = upstreamHttpMethod;
UpstreamTemplatePattern = upstreamTemplatePattern; UpstreamTemplatePattern = upstreamTemplatePattern;
@ -32,11 +33,11 @@ namespace Ocelot.Configuration
UseServiceDiscovery = useServiceDiscovery; UseServiceDiscovery = useServiceDiscovery;
ServiceDiscoveryProvider = serviceDiscoveryProvider; ServiceDiscoveryProvider = serviceDiscoveryProvider;
ServiceDiscoveryAddress = serviceDiscoveryAddress; ServiceDiscoveryAddress = serviceDiscoveryAddress;
DownstreamHost = downstreamHost; DownstreamHostAndPort = downstreamHostAndPort;
DownstreamScheme = downstreamScheme; DownstreamScheme = downstreamScheme;
} }
public string DownstreamTemplate { get; private set; } public DownstreamPathTemplate DownstreamPathTemplate { get; private set; }
public string UpstreamTemplate { get; private set; } public string UpstreamTemplate { get; private set; }
public string UpstreamTemplatePattern { get; private set; } public string UpstreamTemplatePattern { get; private set; }
public string UpstreamHttpMethod { get; private set; } public string UpstreamHttpMethod { get; private set; }
@ -54,7 +55,7 @@ namespace Ocelot.Configuration
public bool UseServiceDiscovery { get; private set;} public bool UseServiceDiscovery { get; private set;}
public string ServiceDiscoveryProvider { get; private set;} public string ServiceDiscoveryProvider { get; private set;}
public string ServiceDiscoveryAddress { get; private set;} public string ServiceDiscoveryAddress { get; private set;}
public Func<string> DownstreamHost {get;private set;} public Func<HostAndPort> DownstreamHostAndPort {get;private set;}
public string DownstreamScheme {get;private set;} public string DownstreamScheme {get;private set;}
} }
} }

View File

@ -0,0 +1,11 @@
using Ocelot.Errors;
namespace Ocelot.Configuration.Validator
{
public class DownstreamPathTemplateAlreadyUsedError : Error
{
public DownstreamPathTemplateAlreadyUsedError(string message) : base(message, OcelotErrorCode.DownstreampathTemplateAlreadyUsedError)
{
}
}
}

View File

@ -0,0 +1,12 @@
using Ocelot.Errors;
namespace Ocelot.Configuration.Validator
{
public class DownstreamPathTemplateContainsSchemeError : Error
{
public DownstreamPathTemplateContainsSchemeError(string message)
: base(message, OcelotErrorCode.DownstreamPathTemplateContainsSchemeError)
{
}
}
}

View File

@ -1,11 +0,0 @@
using Ocelot.Errors;
namespace Ocelot.Configuration.Validator
{
public class DownstreamTemplateAlreadyUsedError : Error
{
public DownstreamTemplateAlreadyUsedError(string message) : base(message, OcelotErrorCode.DownstreamTemplateAlreadyUsedError)
{
}
}
}

View File

@ -1,12 +0,0 @@
using Ocelot.Errors;
namespace Ocelot.Configuration.Validator
{
public class DownstreamTemplateContainsHostError : Error
{
public DownstreamTemplateContainsHostError(string message)
: base(message, OcelotErrorCode.DownstreamTemplateContainsHostError)
{
}
}
}

View File

@ -1,12 +0,0 @@
using Ocelot.Errors;
namespace Ocelot.Configuration.Validator
{
public class DownstreamTemplateContainsSchemeError : Error
{
public DownstreamTemplateContainsSchemeError(string message)
: base(message, OcelotErrorCode.DownstreamTemplateContainsSchemeError)
{
}
}
}

View File

@ -26,7 +26,7 @@ namespace Ocelot.Configuration.Validator
return new OkResponse<ConfigurationValidationResult>(result); return new OkResponse<ConfigurationValidationResult>(result);
} }
result = CheckForReRoutesContainingDownstreamScheme(configuration); result = CheckForReRoutesContainingDownstreamSchemeInDownstreamPathTemplate(configuration);
if (result.IsError) if (result.IsError)
{ {
@ -70,25 +70,25 @@ namespace Ocelot.Configuration.Validator
return Enum.TryParse(provider, true, out supportedProvider); return Enum.TryParse(provider, true, out supportedProvider);
} }
private ConfigurationValidationResult CheckForReRoutesContainingDownstreamScheme(FileConfiguration configuration) private ConfigurationValidationResult CheckForReRoutesContainingDownstreamSchemeInDownstreamPathTemplate(FileConfiguration configuration)
{ {
var errors = new List<Error>(); var errors = new List<Error>();
foreach(var reRoute in configuration.ReRoutes) foreach(var reRoute in configuration.ReRoutes)
{ {
if(reRoute.DownstreamTemplate.Contains("https://") if(reRoute.DownstreamPathTemplate.Contains("https://")
|| reRoute.DownstreamTemplate.Contains("http://")) || reRoute.DownstreamPathTemplate.Contains("http://"))
{ {
errors.Add(new DownstreamTemplateContainsSchemeError($"{reRoute.DownstreamTemplate} contains scheme")); errors.Add(new DownstreamPathTemplateContainsSchemeError($"{reRoute.DownstreamPathTemplate} contains scheme"));
} }
} }
if(errors.Any()) if(errors.Any())
{ {
return new ConfigurationValidationResult(false, errors); return new ConfigurationValidationResult(true, errors);
} }
return new ConfigurationValidationResult(true, errors); return new ConfigurationValidationResult(false, errors);
} }
private ConfigurationValidationResult CheckForDupliateReRoutes(FileConfiguration configuration) private ConfigurationValidationResult CheckForDupliateReRoutes(FileConfiguration configuration)
@ -105,7 +105,7 @@ namespace Ocelot.Configuration.Validator
.Where(x => x.Skip(1).Any()); .Where(x => x.Skip(1).Any());
var errors = dupes var errors = dupes
.Select(d => new DownstreamTemplateAlreadyUsedError(string.Format("Duplicate DownstreamTemplate: {0}", d.Key.UpstreamTemplate))) .Select(d => new DownstreamPathTemplateAlreadyUsedError(string.Format("Duplicate DownstreamPath: {0}", d.Key.UpstreamTemplate)))
.Cast<Error>() .Cast<Error>()
.ToList(); .ToList();

View File

@ -18,6 +18,7 @@ using Ocelot.Configuration.Repository;
using Ocelot.Configuration.Validator; using Ocelot.Configuration.Validator;
using Ocelot.DownstreamRouteFinder.Finder; using Ocelot.DownstreamRouteFinder.Finder;
using Ocelot.DownstreamRouteFinder.UrlMatcher; using Ocelot.DownstreamRouteFinder.UrlMatcher;
using Ocelot.DownstreamUrlCreator;
using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer; using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer;
using Ocelot.Headers; using Ocelot.Headers;
using Ocelot.Infrastructure.Claims.Parser; using Ocelot.Infrastructure.Claims.Parser;
@ -59,6 +60,7 @@ namespace Ocelot.DependencyInjection
services.AddMvcCore().AddJsonFormatters(); services.AddMvcCore().AddJsonFormatters();
services.AddLogging(); services.AddLogging();
services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>(); services.AddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
services.AddSingleton<IUrlBuilder, UrlBuilder>();
services.AddSingleton<IRemoveOutputHeaders, RemoveOutputHeaders>(); services.AddSingleton<IRemoveOutputHeaders, RemoveOutputHeaders>();
services.AddSingleton<IOcelotConfigurationProvider, OcelotConfigurationProvider>(); services.AddSingleton<IOcelotConfigurationProvider, OcelotConfigurationProvider>();
services.AddSingleton<IClaimToThingConfigurationParser, ClaimToThingConfigurationParser>(); services.AddSingleton<IClaimToThingConfigurationParser, ClaimToThingConfigurationParser>();
@ -69,7 +71,7 @@ namespace Ocelot.DependencyInjection
services.AddSingleton<IClaimsParser, ClaimsParser>(); services.AddSingleton<IClaimsParser, ClaimsParser>();
services.AddSingleton<IUrlPathToUrlTemplateMatcher, RegExUrlMatcher>(); services.AddSingleton<IUrlPathToUrlTemplateMatcher, RegExUrlMatcher>();
services.AddSingleton<IUrlPathPlaceholderNameAndValueFinder, UrlPathPlaceholderNameAndValueFinder>(); services.AddSingleton<IUrlPathPlaceholderNameAndValueFinder, UrlPathPlaceholderNameAndValueFinder>();
services.AddSingleton<IDownstreamUrlPathPlaceholderReplacer, DownstreamUrlPathPlaceholderReplacer>(); services.AddSingleton<IDownstreamPathPlaceholderReplacer, DownstreamTemplatePathPlaceholderReplacer>();
services.AddSingleton<IDownstreamRouteFinder, DownstreamRouteFinder.Finder.DownstreamRouteFinder>(); services.AddSingleton<IDownstreamRouteFinder, DownstreamRouteFinder.Finder.DownstreamRouteFinder>();
services.AddSingleton<IHttpRequester, HttpClientHttpRequester>(); services.AddSingleton<IHttpRequester, HttpClientHttpRequester>();
services.AddSingleton<IHttpResponder, HttpContextResponder>(); services.AddSingleton<IHttpResponder, HttpContextResponder>();

View File

@ -44,7 +44,7 @@ namespace Ocelot.DownstreamRouteFinder.Middleware
return; return;
} }
_logger.LogDebug("downstream template is {downstreamRoute.Data.ReRoute.DownstreamTemplate}", downstreamRoute.Data.ReRoute.DownstreamTemplate); _logger.LogDebug("downstream template is {downstreamRoute.Data.ReRoute.DownstreamPath}", downstreamRoute.Data.ReRoute.DownstreamPathTemplate);
SetDownstreamRouteForThisRequest(downstreamRoute.Data); SetDownstreamRouteForThisRequest(downstreamRoute.Data);

View File

@ -0,0 +1,12 @@
using Ocelot.Errors;
namespace Ocelot.DownstreamUrlCreator
{
public class DownstreamHostNullOrEmptyError : Error
{
public DownstreamHostNullOrEmptyError()
: base("downstream host was null or empty", OcelotErrorCode.DownstreamHostNullOrEmptyError)
{
}
}
}

View File

@ -0,0 +1,12 @@
using Ocelot.Errors;
namespace Ocelot.DownstreamUrlCreator
{
public class DownstreamPathNullOrEmptyError : Error
{
public DownstreamPathNullOrEmptyError()
: base("downstream path was null or empty", OcelotErrorCode.DownstreamPathNullOrEmptyError)
{
}
}
}

View File

@ -0,0 +1,12 @@
using Ocelot.Errors;
namespace Ocelot.DownstreamUrlCreator
{
public class DownstreamSchemeNullOrEmptyError : Error
{
public DownstreamSchemeNullOrEmptyError()
: base("downstream scheme was null or empty", OcelotErrorCode.DownstreamSchemeNullOrEmptyError)
{
}
}
}

View File

@ -0,0 +1,12 @@
using Ocelot.Configuration;
using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer;
using Ocelot.Responses;
using Ocelot.Values;
namespace Ocelot.DownstreamUrlCreator
{
public interface IUrlBuilder
{
Response<DownstreamUrl> Build(string downstreamPath, string downstreamScheme, HostAndPort downstreamHostAndPort);
}
}

View File

@ -1,6 +1,7 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Ocelot.Configuration;
using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer; using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer;
using Ocelot.Infrastructure.RequestData; using Ocelot.Infrastructure.RequestData;
using Ocelot.Logging; using Ocelot.Logging;
@ -11,17 +12,20 @@ namespace Ocelot.DownstreamUrlCreator.Middleware
public class DownstreamUrlCreatorMiddleware : OcelotMiddleware public class DownstreamUrlCreatorMiddleware : OcelotMiddleware
{ {
private readonly RequestDelegate _next; private readonly RequestDelegate _next;
private readonly IDownstreamUrlPathPlaceholderReplacer _urlReplacer; private readonly IDownstreamPathPlaceholderReplacer _replacer;
private readonly IOcelotLogger _logger; private readonly IOcelotLogger _logger;
private readonly IUrlBuilder _urlBuilder;
public DownstreamUrlCreatorMiddleware(RequestDelegate next, public DownstreamUrlCreatorMiddleware(RequestDelegate next,
IOcelotLoggerFactory loggerFactory, IOcelotLoggerFactory loggerFactory,
IDownstreamUrlPathPlaceholderReplacer urlReplacer, IDownstreamPathPlaceholderReplacer replacer,
IRequestScopedDataRepository requestScopedDataRepository) IRequestScopedDataRepository requestScopedDataRepository,
IUrlBuilder urlBuilder)
:base(requestScopedDataRepository) :base(requestScopedDataRepository)
{ {
_next = next; _next = next;
_urlReplacer = urlReplacer; _replacer = replacer;
_urlBuilder = urlBuilder;
_logger = loggerFactory.CreateLogger<DownstreamUrlCreatorMiddleware>(); _logger = loggerFactory.CreateLogger<DownstreamUrlCreatorMiddleware>();
} }
@ -29,19 +33,34 @@ namespace Ocelot.DownstreamUrlCreator.Middleware
{ {
_logger.LogDebug("started calling downstream url creator middleware"); _logger.LogDebug("started calling downstream url creator middleware");
var downstreamUrl = _urlReplacer.Replace(DownstreamRoute.ReRoute.DownstreamTemplate, DownstreamRoute.TemplatePlaceholderNameAndValues); var dsPath = _replacer
.Replace(DownstreamRoute.ReRoute.DownstreamPathTemplate, DownstreamRoute.TemplatePlaceholderNameAndValues);
if (downstreamUrl.IsError) if (dsPath.IsError)
{ {
_logger.LogDebug("IDownstreamUrlPathPlaceholderReplacer returned an error, setting pipeline error"); _logger.LogDebug("IDownstreamPathPlaceholderReplacer returned an error, setting pipeline error");
SetPipelineError(downstreamUrl.Errors); SetPipelineError(dsPath.Errors);
return; return;
} }
_logger.LogDebug("downstream url is {downstreamUrl.Data.Value}", downstreamUrl.Data.Value); var dsScheme = DownstreamRoute.ReRoute.DownstreamScheme;
SetDownstreamUrlForThisRequest(downstreamUrl.Data.Value); var dsHostAndPort = DownstreamRoute.ReRoute.DownstreamHostAndPort();
var dsUrl = _urlBuilder.Build(dsPath.Data.Value, dsScheme, dsHostAndPort);
if (dsUrl.IsError)
{
_logger.LogDebug("IUrlBuilder returned an error, setting pipeline error");
SetPipelineError(dsUrl.Errors);
return;
}
_logger.LogDebug("downstream url is {downstreamUrl.Data.Value}", dsUrl.Data.Value);
SetDownstreamUrlForThisRequest(dsUrl.Data.Value);
_logger.LogDebug("calling next middleware"); _logger.LogDebug("calling next middleware");

View File

@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using Ocelot.Configuration;
using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer;
using Ocelot.Errors;
using Ocelot.Responses;
using Ocelot.Values;
namespace Ocelot.DownstreamUrlCreator
{
public class UrlBuilder : IUrlBuilder
{
public Response<DownstreamUrl> Build(string downstreamPath, string downstreamScheme, HostAndPort downstreamHostAndPort)
{
if (string.IsNullOrEmpty(downstreamPath))
{
return new ErrorResponse<DownstreamUrl>(new List<Error> {new DownstreamPathNullOrEmptyError()});
}
if (string.IsNullOrEmpty(downstreamScheme))
{
return new ErrorResponse<DownstreamUrl>(new List<Error> { new DownstreamSchemeNullOrEmptyError() });
}
if (string.IsNullOrEmpty(downstreamHostAndPort.DownstreamHost))
{
return new ErrorResponse<DownstreamUrl>(new List<Error> { new DownstreamHostNullOrEmptyError() });
}
var builder = new UriBuilder
{
Host = downstreamHostAndPort.DownstreamHost,
Path = downstreamPath,
Scheme = downstreamScheme
};
if (downstreamHostAndPort.DownstreamPort > 0)
{
builder.Port = downstreamHostAndPort.DownstreamPort;
}
var url = builder.Uri.ToString();
return new OkResponse<DownstreamUrl>(new DownstreamUrl(url));
}
}
}

View File

@ -1,25 +1,25 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using Ocelot.DownstreamRouteFinder;
using Ocelot.DownstreamRouteFinder.UrlMatcher; using Ocelot.DownstreamRouteFinder.UrlMatcher;
using Ocelot.Responses; using Ocelot.Responses;
using Ocelot.Values;
namespace Ocelot.DownstreamUrlCreator.UrlTemplateReplacer namespace Ocelot.DownstreamUrlCreator.UrlTemplateReplacer
{ {
public class DownstreamUrlPathPlaceholderReplacer : IDownstreamUrlPathPlaceholderReplacer public class DownstreamTemplatePathPlaceholderReplacer : IDownstreamPathPlaceholderReplacer
{ {
public Response<DownstreamUrl> Replace(string downstreamTemplate, List<UrlPathPlaceholderNameAndValue> urlPathPlaceholderNameAndValues) public Response<DownstreamPath> Replace(DownstreamPathTemplate downstreamPathTemplate, List<UrlPathPlaceholderNameAndValue> urlPathPlaceholderNameAndValues)
{ {
var upstreamUrl = new StringBuilder(); var downstreamPath = new StringBuilder();
upstreamUrl.Append(downstreamTemplate); downstreamPath.Append(downstreamPathTemplate.Value);
foreach (var placeholderVariableAndValue in urlPathPlaceholderNameAndValues) foreach (var placeholderVariableAndValue in urlPathPlaceholderNameAndValues)
{ {
upstreamUrl.Replace(placeholderVariableAndValue.TemplateVariableName, placeholderVariableAndValue.TemplateVariableValue); downstreamPath.Replace(placeholderVariableAndValue.TemplateVariableName, placeholderVariableAndValue.TemplateVariableValue);
} }
return new OkResponse<DownstreamUrl>(new DownstreamUrl(upstreamUrl.ToString())); return new OkResponse<DownstreamPath>(new DownstreamPath(downstreamPath.ToString()));
} }
} }
} }

View File

@ -1,11 +1,12 @@
using System.Collections.Generic; using System.Collections.Generic;
using Ocelot.DownstreamRouteFinder.UrlMatcher; using Ocelot.DownstreamRouteFinder.UrlMatcher;
using Ocelot.Responses; using Ocelot.Responses;
using Ocelot.Values;
namespace Ocelot.DownstreamUrlCreator.UrlTemplateReplacer namespace Ocelot.DownstreamUrlCreator.UrlTemplateReplacer
{ {
public interface IDownstreamUrlPathPlaceholderReplacer public interface IDownstreamPathPlaceholderReplacer
{ {
Response<DownstreamUrl> Replace(string downstreamTemplate, List<UrlPathPlaceholderNameAndValue> urlPathPlaceholderNameAndValues); Response<DownstreamPath> Replace(DownstreamPathTemplate downstreamPathTemplate, List<UrlPathPlaceholderNameAndValue> urlPathPlaceholderNameAndValues);
} }
} }

View File

@ -4,7 +4,7 @@
{ {
UnauthenticatedError, UnauthenticatedError,
UnknownError, UnknownError,
DownstreamTemplateAlreadyUsedError, DownstreampathTemplateAlreadyUsedError,
UnableToFindDownstreamRouteError, UnableToFindDownstreamRouteError,
CannotAddDataError, CannotAddDataError,
CannotFindDataError, CannotFindDataError,
@ -18,7 +18,9 @@
UnauthorizedError, UnauthorizedError,
ClaimValueNotAuthorisedError, ClaimValueNotAuthorisedError,
UserDoesNotHaveClaimError, UserDoesNotHaveClaimError,
DownstreamTemplateContainsSchemeError, DownstreamPathTemplateContainsSchemeError,
DownstreamTemplateContainsHostError DownstreamPathNullOrEmptyError,
DownstreamSchemeNullOrEmptyError,
DownstreamHostNullOrEmptyError
} }
} }

View File

@ -0,0 +1,12 @@
namespace Ocelot.Values
{
public class DownstreamPath
{
public DownstreamPath(string value)
{
Value = value;
}
public string Value { get; private set; }
}
}

View File

@ -0,0 +1,12 @@
namespace Ocelot.Values
{
public class DownstreamPathTemplate
{
public DownstreamPathTemplate(string value)
{
Value = value;
}
public string Value { get; private set; }
}
}

View File

@ -1,4 +1,4 @@
namespace Ocelot.DownstreamUrlCreator.UrlTemplateReplacer namespace Ocelot.Values
{ {
public class DownstreamUrl public class DownstreamUrl
{ {

View File

@ -0,0 +1,14 @@
namespace Ocelot.Values
{
public class HostAndPort
{
public HostAndPort(string downstreamHost, int downstreamPort)
{
DownstreamHost = downstreamHost;
DownstreamPort = downstreamPort;
}
public string DownstreamHost { get; private set; }
public int DownstreamPort { get; private set; }
}
}

BIN
test/.DS_Store vendored Normal file

Binary file not shown.

View File

@ -23,7 +23,11 @@ namespace Ocelot.AcceptanceTests
private readonly Steps _steps; private readonly Steps _steps;
private IWebHost _identityServerBuilder; private IWebHost _identityServerBuilder;
private string _identityServerRootUrl = "http://localhost:51888"; private string _identityServerRootUrl = "http://localhost:51888";
private string _downstreamServiceRootUrl = "http://localhost:51876/"; private string _downstreamServicePath = "/";
private string _downstreamServiceHost = "localhost";
private int _downstreamServicePort = 51876;
private string _downstreamServiceScheme = "http";
private string _downstreamServiceUrl = "http://localhost:51876";
public AuthenticationTests() public AuthenticationTests()
{ {
@ -39,7 +43,10 @@ namespace Ocelot.AcceptanceTests
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = _downstreamServiceRootUrl, DownstreamPathTemplate = _downstreamServicePath,
DownstreamPort = _downstreamServicePort,
DownstreamHost = _downstreamServiceHost,
DownstreamScheme = _downstreamServiceScheme,
UpstreamTemplate = "/", UpstreamTemplate = "/",
UpstreamHttpMethod = "Post", UpstreamHttpMethod = "Post",
AuthenticationOptions = new FileAuthenticationOptions AuthenticationOptions = new FileAuthenticationOptions
@ -56,7 +63,7 @@ namespace Ocelot.AcceptanceTests
}; };
this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", AccessTokenType.Jwt)) this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", AccessTokenType.Jwt))
.And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceRootUrl, 201, string.Empty)) .And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceUrl, 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"))
@ -74,7 +81,10 @@ namespace Ocelot.AcceptanceTests
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = _downstreamServiceRootUrl, DownstreamPathTemplate = _downstreamServicePath,
DownstreamPort = _downstreamServicePort,
DownstreamHost = _downstreamServiceHost,
DownstreamScheme = _downstreamServiceScheme,
UpstreamTemplate = "/", UpstreamTemplate = "/",
UpstreamHttpMethod = "Post", UpstreamHttpMethod = "Post",
AuthenticationOptions = new FileAuthenticationOptions AuthenticationOptions = new FileAuthenticationOptions
@ -91,7 +101,7 @@ namespace Ocelot.AcceptanceTests
}; };
this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", AccessTokenType.Reference)) this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", AccessTokenType.Reference))
.And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceRootUrl, 201, string.Empty)) .And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceUrl, 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"))
@ -109,7 +119,10 @@ namespace Ocelot.AcceptanceTests
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = _downstreamServiceRootUrl, DownstreamPathTemplate = _downstreamServicePath,
DownstreamPort = _downstreamServicePort,
DownstreamHost = _downstreamServiceHost,
DownstreamScheme = _downstreamServiceScheme,
UpstreamTemplate = "/", UpstreamTemplate = "/",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
AuthenticationOptions = new FileAuthenticationOptions AuthenticationOptions = new FileAuthenticationOptions
@ -126,7 +139,7 @@ namespace Ocelot.AcceptanceTests
}; };
this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", AccessTokenType.Jwt)) this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", AccessTokenType.Jwt))
.And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceRootUrl, 200, "Hello from Laura")) .And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceUrl, 200, "Hello from Laura"))
.And(x => _steps.GivenIHaveAToken(_identityServerRootUrl)) .And(x => _steps.GivenIHaveAToken(_identityServerRootUrl))
.And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning()) .And(x => _steps.GivenOcelotIsRunning())
@ -146,7 +159,10 @@ namespace Ocelot.AcceptanceTests
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = _downstreamServiceRootUrl, DownstreamPathTemplate = _downstreamServicePath,
DownstreamPort = _downstreamServicePort,
DownstreamHost = _downstreamServiceHost,
DownstreamScheme = _downstreamServiceScheme,
UpstreamTemplate = "/", UpstreamTemplate = "/",
UpstreamHttpMethod = "Post", UpstreamHttpMethod = "Post",
AuthenticationOptions = new FileAuthenticationOptions AuthenticationOptions = new FileAuthenticationOptions
@ -163,7 +179,7 @@ namespace Ocelot.AcceptanceTests
}; };
this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", AccessTokenType.Jwt)) this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", AccessTokenType.Jwt))
.And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceRootUrl, 201, string.Empty)) .And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceUrl, 201, string.Empty))
.And(x => _steps.GivenIHaveAToken(_identityServerRootUrl)) .And(x => _steps.GivenIHaveAToken(_identityServerRootUrl))
.And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning()) .And(x => _steps.GivenOcelotIsRunning())
@ -183,7 +199,10 @@ namespace Ocelot.AcceptanceTests
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = _downstreamServiceRootUrl, DownstreamPathTemplate = _downstreamServicePath,
DownstreamPort = _downstreamServicePort,
DownstreamHost = _downstreamServiceHost,
DownstreamScheme = _downstreamServiceScheme,
UpstreamTemplate = "/", UpstreamTemplate = "/",
UpstreamHttpMethod = "Post", UpstreamHttpMethod = "Post",
AuthenticationOptions = new FileAuthenticationOptions AuthenticationOptions = new FileAuthenticationOptions
@ -200,7 +219,7 @@ namespace Ocelot.AcceptanceTests
}; };
this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", AccessTokenType.Reference)) this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", AccessTokenType.Reference))
.And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceRootUrl, 201, string.Empty)) .And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceUrl, 201, string.Empty))
.And(x => _steps.GivenIHaveAToken(_identityServerRootUrl)) .And(x => _steps.GivenIHaveAToken(_identityServerRootUrl))
.And(x => _steps.GivenThereIsAConfiguration(configuration)) .And(x => _steps.GivenThereIsAConfiguration(configuration))
.And(x => _steps.GivenOcelotIsRunning()) .And(x => _steps.GivenOcelotIsRunning())

View File

@ -37,7 +37,10 @@ namespace Ocelot.AcceptanceTests
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = "http://localhost:51876/", DownstreamPathTemplate = "/",
DownstreamPort = 51876,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/", UpstreamTemplate = "/",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
AuthenticationOptions = new FileAuthenticationOptions AuthenticationOptions = new FileAuthenticationOptions
@ -91,7 +94,10 @@ namespace Ocelot.AcceptanceTests
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = "http://localhost:51876/", DownstreamPathTemplate = "/",
DownstreamPort = 51876,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/", UpstreamTemplate = "/",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
AuthenticationOptions = new FileAuthenticationOptions AuthenticationOptions = new FileAuthenticationOptions

View File

@ -31,7 +31,10 @@ namespace Ocelot.AcceptanceTests
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = "http://localhost:51879/", DownstreamPathTemplate = "/",
DownstreamPort = 51879,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/", UpstreamTemplate = "/",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
FileCacheOptions = new FileCacheOptions FileCacheOptions = new FileCacheOptions
@ -64,7 +67,10 @@ namespace Ocelot.AcceptanceTests
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = "http://localhost:51879/", DownstreamPathTemplate = "/",
DownstreamPort = 51879,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/", UpstreamTemplate = "/",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
FileCacheOptions = new FileCacheOptions FileCacheOptions = new FileCacheOptions

View File

@ -30,7 +30,10 @@ namespace Ocelot.AcceptanceTests
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = "http://localhost:51879/api/products/{productId}", DownstreamPathTemplate = "/api/products/{productId}",
DownstreamPort = 51879,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/products/{productId}", UpstreamTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get" UpstreamHttpMethod = "Get"
} }
@ -54,7 +57,10 @@ namespace Ocelot.AcceptanceTests
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = "http://localhost:51879/api/products/{productId}", DownstreamPathTemplate = "/api/products/{productId}",
DownstreamPort = 51879,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/products/{productId}", UpstreamTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = false ReRouteIsCaseSensitive = false
@ -79,7 +85,10 @@ namespace Ocelot.AcceptanceTests
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = "http://localhost:51879/api/products/{productId}", DownstreamPathTemplate = "/api/products/{productId}",
DownstreamPort = 51879,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/products/{productId}", UpstreamTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = true ReRouteIsCaseSensitive = true
@ -104,7 +113,10 @@ namespace Ocelot.AcceptanceTests
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = "http://localhost:51879/api/products/{productId}", DownstreamPathTemplate = "/api/products/{productId}",
DownstreamPort = 51879,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/PRODUCTS/{productId}", UpstreamTemplate = "/PRODUCTS/{productId}",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = true ReRouteIsCaseSensitive = true
@ -129,7 +141,10 @@ namespace Ocelot.AcceptanceTests
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = "http://localhost:51879/api/products/{productId}", DownstreamPathTemplate = "/api/products/{productId}",
DownstreamPort = 51879,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/products/{productId}", UpstreamTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = true ReRouteIsCaseSensitive = true
@ -154,7 +169,10 @@ namespace Ocelot.AcceptanceTests
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = "http://localhost:51879/api/products/{productId}", DownstreamPathTemplate = "/api/products/{productId}",
DownstreamPort = 51879,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/PRODUCTS/{productId}", UpstreamTemplate = "/PRODUCTS/{productId}",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = true ReRouteIsCaseSensitive = true

View File

@ -51,7 +51,10 @@ namespace Ocelot.AcceptanceTests
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = "http://localhost:52876/", DownstreamPathTemplate = "/",
DownstreamPort = 52876,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/", UpstreamTemplate = "/",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
AuthenticationOptions = new FileAuthenticationOptions AuthenticationOptions = new FileAuthenticationOptions

View File

@ -51,7 +51,10 @@ namespace Ocelot.AcceptanceTests
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = "http://localhost:57876/", DownstreamPathTemplate = "/",
DownstreamPort = 57876,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/", UpstreamTemplate = "/",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
AuthenticationOptions = new FileAuthenticationOptions AuthenticationOptions = new FileAuthenticationOptions

View File

@ -45,7 +45,10 @@ namespace Ocelot.AcceptanceTests
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = "http://localhost:41879/", DownstreamPathTemplate = "/",
DownstreamPort = 41879,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/", UpstreamTemplate = "/",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
} }
@ -79,7 +82,10 @@ namespace Ocelot.AcceptanceTests
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = "http://localhost:41879/", DownstreamPathTemplate = "/",
DownstreamPort = 41879,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/", UpstreamTemplate = "/",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
} }
@ -113,7 +119,10 @@ namespace Ocelot.AcceptanceTests
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = "http://localhost:41879/", DownstreamPathTemplate = "41879/",
DownstreamPort = 41879,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/", UpstreamTemplate = "/",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
} }
@ -147,7 +156,10 @@ namespace Ocelot.AcceptanceTests
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = "http://localhost:41879/", DownstreamPathTemplate = "/",
DownstreamPort = 41879,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/", UpstreamTemplate = "/",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
} }
@ -181,7 +193,10 @@ namespace Ocelot.AcceptanceTests
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = "http://localhost:41879/", DownstreamPathTemplate = "/",
DownstreamPort = 41879,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/", UpstreamTemplate = "/",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
} }
@ -215,7 +230,10 @@ namespace Ocelot.AcceptanceTests
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = "http://localhost:41879/", DownstreamPathTemplate = "/",
DownstreamPort = 41879,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/", UpstreamTemplate = "/",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
} }

View File

@ -33,7 +33,10 @@ namespace Ocelot.AcceptanceTests
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = "http://localhost:51879/", DownstreamPathTemplate = "/",
DownstreamPort = 51879,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/", UpstreamTemplate = "/",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
RequestIdKey = _steps.RequestIdKey RequestIdKey = _steps.RequestIdKey
@ -58,7 +61,10 @@ namespace Ocelot.AcceptanceTests
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = "http://localhost:51879/", DownstreamPathTemplate = "/",
DownstreamPort = 51879,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/", UpstreamTemplate = "/",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
RequestIdKey = _steps.RequestIdKey RequestIdKey = _steps.RequestIdKey
@ -85,7 +91,10 @@ namespace Ocelot.AcceptanceTests
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = "http://localhost:51879/", DownstreamPathTemplate = "/",
DownstreamPort = 51879,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/", UpstreamTemplate = "/",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
} }

View File

@ -29,7 +29,7 @@ namespace Ocelot.AcceptanceTests
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = "http://localhost:53876/", DownstreamPathTemplate = "http://localhost:53876/",
UpstreamTemplate = "/", UpstreamTemplate = "/",
UpstreamHttpMethod = "Get" UpstreamHttpMethod = "Get"
} }

View File

@ -40,7 +40,10 @@ namespace Ocelot.AcceptanceTests
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = "http://localhost:51879/", DownstreamPathTemplate = "/",
DownstreamScheme = "http",
DownstreamHost = "localhost",
DownstreamPort = 51879,
UpstreamTemplate = "/", UpstreamTemplate = "/",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
} }
@ -56,6 +59,62 @@ namespace Ocelot.AcceptanceTests
.BDDfy(); .BDDfy();
} }
[Fact]
public void should_return_response_200_when_path_missing_forward_slash_as_first_char()
{
var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "api/products",
DownstreamScheme = "http",
DownstreamHost = "localhost",
DownstreamPort = 51879,
UpstreamTemplate = "/",
UpstreamHttpMethod = "Get",
}
}
};
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879/api/products", 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_when_host_has_trailing_slash()
{
var configuration = new FileConfiguration
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamPathTemplate = "/api/products",
DownstreamScheme = "http",
DownstreamHost = "localhost/",
DownstreamPort = 51879,
UpstreamTemplate = "/",
UpstreamHttpMethod = "Get",
}
}
};
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879/api/products", 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_not_care_about_no_trailing() public void should_not_care_about_no_trailing()
{ {
@ -65,7 +124,10 @@ namespace Ocelot.AcceptanceTests
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = "http://localhost:51879/products", DownstreamPathTemplate = "/products",
DownstreamScheme = "http",
DownstreamHost = "localhost",
DownstreamPort = 51879,
UpstreamTemplate = "/products/", UpstreamTemplate = "/products/",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
} }
@ -90,7 +152,10 @@ namespace Ocelot.AcceptanceTests
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = "http://localhost:51879/products", DownstreamPathTemplate = "/products",
DownstreamScheme = "http",
DownstreamHost = "localhost",
DownstreamPort = 51879,
UpstreamTemplate = "/products", UpstreamTemplate = "/products",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
} }
@ -115,7 +180,10 @@ namespace Ocelot.AcceptanceTests
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = "http://localhost:51879/products", DownstreamPathTemplate = "/products",
DownstreamScheme = "http",
DownstreamHost = "localhost",
DownstreamPort = 51879,
UpstreamTemplate = "/products/{productId}", UpstreamTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
} }
@ -139,7 +207,10 @@ namespace Ocelot.AcceptanceTests
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = "http://localhost:51879/api/products/{productId}", DownstreamPathTemplate = "/api/products/{productId}",
DownstreamScheme = "http",
DownstreamHost = "localhost",
DownstreamPort = 51879,
UpstreamTemplate = "/products/{productId}", UpstreamTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get" UpstreamHttpMethod = "Get"
} }
@ -164,7 +235,10 @@ namespace Ocelot.AcceptanceTests
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = "http://localhost:51879/", DownstreamPathTemplate = "/",
DownstreamHost = "localhost",
DownstreamPort = 51879,
DownstreamScheme = "http",
UpstreamTemplate = "/", UpstreamTemplate = "/",
UpstreamHttpMethod = "Post" UpstreamHttpMethod = "Post"
} }
@ -189,8 +263,11 @@ namespace Ocelot.AcceptanceTests
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = "http://localhost:51879/newThing", DownstreamPathTemplate = "/newThing",
UpstreamTemplate = "/newThing", UpstreamTemplate = "/newThing",
DownstreamScheme = "http",
DownstreamHost = "localhost",
DownstreamPort = 51879,
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
} }
} }

View File

@ -10,7 +10,6 @@ namespace Ocelot.ManualTest
var host = new WebHostBuilder() var host = new WebHostBuilder()
.UseKestrel() .UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory()) .UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>() .UseStartup<Startup>()
.Build(); .Build();

View File

@ -1,7 +1,10 @@
{ {
"ReRoutes": [ "ReRoutes": [
{ {
"DownstreamTemplate": "http://localhost:52876/", "DownstreamPathTemplate": "/",
"DownstreamScheme": "http",
"DownstreamHost": "localhost",
"DownstreamPort": 52876,
"UpstreamTemplate": "/identityserverexample", "UpstreamTemplate": "/identityserverexample",
"UpstreamHttpMethod": "Get", "UpstreamHttpMethod": "Get",
"AuthenticationOptions": { "AuthenticationOptions": {
@ -38,108 +41,165 @@
"RequestIdKey": "OcRequestId" "RequestIdKey": "OcRequestId"
}, },
{ {
"DownstreamTemplate": "http://jsonplaceholder.typicode.com/posts", "DownstreamPathTemplate": "/posts",
"DownstreamScheme": "http",
"DownstreamHost": "jsonplaceholder.typicode.com",
"DownstreamPort": 80,
"UpstreamTemplate": "/posts", "UpstreamTemplate": "/posts",
"UpstreamHttpMethod": "Get", "UpstreamHttpMethod": "Get",
"FileCacheOptions": { "TtlSeconds": 15 } "FileCacheOptions": { "TtlSeconds": 15 }
}, },
{ {
"DownstreamTemplate": "http://jsonplaceholder.typicode.com/posts/{postId}", "DownstreamPathTemplate": "/posts/{postId}",
"DownstreamScheme": "http",
"DownstreamHost": "jsonplaceholder.typicode.com",
"DownstreamPort": 80,
"UpstreamTemplate": "/posts/{postId}", "UpstreamTemplate": "/posts/{postId}",
"UpstreamHttpMethod": "Get" "UpstreamHttpMethod": "Get"
}, },
{ {
"DownstreamTemplate": "http://jsonplaceholder.typicode.com/posts/{postId}/comments", "DownstreamPathTemplate": "/posts/{postId}/comments",
"DownstreamScheme": "http",
"DownstreamHost": "jsonplaceholder.typicode.com",
"DownstreamPort": 80,
"UpstreamTemplate": "/posts/{postId}/comments", "UpstreamTemplate": "/posts/{postId}/comments",
"UpstreamHttpMethod": "Get" "UpstreamHttpMethod": "Get"
}, },
{ {
"DownstreamTemplate": "http://jsonplaceholder.typicode.com/comments", "DownstreamPathTemplate": "/comments",
"DownstreamScheme": "http",
"DownstreamHost": "jsonplaceholder.typicode.com",
"DownstreamPort": 80,
"UpstreamTemplate": "/comments", "UpstreamTemplate": "/comments",
"UpstreamHttpMethod": "Get" "UpstreamHttpMethod": "Get"
}, },
{ {
"DownstreamTemplate": "http://jsonplaceholder.typicode.com/posts", "DownstreamPathTemplate": "/posts",
"DownstreamScheme": "http",
"DownstreamHost": "jsonplaceholder.typicode.com",
"DownstreamPort": 80,
"UpstreamTemplate": "/posts", "UpstreamTemplate": "/posts",
"UpstreamHttpMethod": "Post" "UpstreamHttpMethod": "Post"
}, },
{ {
"DownstreamTemplate": "http://jsonplaceholder.typicode.com/posts/{postId}", "DownstreamPathTemplate": "/posts/{postId}",
"DownstreamScheme": "http",
"DownstreamHost": "jsonplaceholder.typicode.com",
"DownstreamPort": 80,
"UpstreamTemplate": "/posts/{postId}", "UpstreamTemplate": "/posts/{postId}",
"UpstreamHttpMethod": "Put" "UpstreamHttpMethod": "Put"
}, },
{ {
"DownstreamTemplate": "http://jsonplaceholder.typicode.com/posts/{postId}", "DownstreamPathTemplate": "/posts/{postId}",
"DownstreamScheme": "http",
"DownstreamHost": "jsonplaceholder.typicode.com",
"DownstreamPort": 80,
"UpstreamTemplate": "/posts/{postId}", "UpstreamTemplate": "/posts/{postId}",
"UpstreamHttpMethod": "Patch" "UpstreamHttpMethod": "Patch"
}, },
{ {
"DownstreamTemplate": "http://jsonplaceholder.typicode.com/posts/{postId}", "DownstreamPathTemplate": "/posts/{postId}",
"DownstreamScheme": "http",
"DownstreamHost": "jsonplaceholder.typicode.com",
"DownstreamPort": 80,
"UpstreamTemplate": "/posts/{postId}", "UpstreamTemplate": "/posts/{postId}",
"UpstreamHttpMethod": "Delete" "UpstreamHttpMethod": "Delete"
}, },
{ {
"DownstreamTemplate": "http://products20161126090340.azurewebsites.net/api/products", "DownstreamPathTemplate": "/api/products",
"DownstreamScheme": "http",
"DownstreamHost": "jsonplaceholder.typicode.com",
"DownstreamPort": 80,
"UpstreamTemplate": "/products", "UpstreamTemplate": "/products",
"UpstreamHttpMethod": "Get", "UpstreamHttpMethod": "Get",
"FileCacheOptions": { "TtlSeconds": 15 } "FileCacheOptions": { "TtlSeconds": 15 }
}, },
{ {
"DownstreamTemplate": "http://products20161126090340.azurewebsites.net/api/products/{productId}", "DownstreamPathTemplate": "/api/products/{productId}",
"DownstreamScheme": "http",
"DownstreamHost": "jsonplaceholder.typicode.com",
"DownstreamPort": 80,
"UpstreamTemplate": "/products/{productId}", "UpstreamTemplate": "/products/{productId}",
"UpstreamHttpMethod": "Get", "UpstreamHttpMethod": "Get",
"FileCacheOptions": { "TtlSeconds": 15 } "FileCacheOptions": { "TtlSeconds": 15 }
}, },
{ {
"DownstreamTemplate": "http://products20161126090340.azurewebsites.net/api/products", "DownstreamPathTemplate": "/api/products",
"DownstreamScheme": "http",
"DownstreamHost": "products20161126090340.azurewebsites.net",
"DownstreamPort": 80,
"UpstreamTemplate": "/products", "UpstreamTemplate": "/products",
"UpstreamHttpMethod": "Post", "UpstreamHttpMethod": "Post",
"FileCacheOptions": { "TtlSeconds": 15 } "FileCacheOptions": { "TtlSeconds": 15 }
}, },
{ {
"DownstreamTemplate": "http://products20161126090340.azurewebsites.net/api/products/{productId}", "DownstreamPathTemplate": "/api/products/{productId}",
"DownstreamScheme": "http",
"DownstreamHost": "products20161126090340.azurewebsites.net",
"DownstreamPort": 80,
"UpstreamTemplate": "/products/{productId}", "UpstreamTemplate": "/products/{productId}",
"UpstreamHttpMethod": "Put", "UpstreamHttpMethod": "Put",
"FileCacheOptions": { "TtlSeconds": 15 } "FileCacheOptions": { "TtlSeconds": 15 }
}, },
{ {
"DownstreamTemplate": "http://products20161126090340.azurewebsites.net/api/products/{productId}", "DownstreamPathTemplate": "/api/products/{productId}",
"DownstreamScheme": "http",
"DownstreamHost": "products20161126090340.azurewebsites.net",
"DownstreamPort": 80,
"UpstreamTemplate": "/products/{productId}", "UpstreamTemplate": "/products/{productId}",
"UpstreamHttpMethod": "Delete", "UpstreamHttpMethod": "Delete",
"FileCacheOptions": { "TtlSeconds": 15 } "FileCacheOptions": { "TtlSeconds": 15 }
}, },
{ {
"DownstreamTemplate": "http://customers20161126090811.azurewebsites.net/api/customers", "DownstreamPathTemplate": "/api/customers",
"DownstreamScheme": "http",
"DownstreamHost": "customers20161126090811.azurewebsites.net",
"DownstreamPort": 80,
"UpstreamTemplate": "/customers", "UpstreamTemplate": "/customers",
"UpstreamHttpMethod": "Get", "UpstreamHttpMethod": "Get",
"FileCacheOptions": { "TtlSeconds": 15 } "FileCacheOptions": { "TtlSeconds": 15 }
}, },
{ {
"DownstreamTemplate": "http://customers20161126090811.azurewebsites.net/api/customers/{customerId}", "DownstreamPathTemplate": "/api/customers/{customerId}",
"DownstreamScheme": "http",
"DownstreamHost": "customers20161126090811.azurewebsites.net",
"DownstreamPort": 80,
"UpstreamTemplate": "/customers/{customerId}", "UpstreamTemplate": "/customers/{customerId}",
"UpstreamHttpMethod": "Get", "UpstreamHttpMethod": "Get",
"FileCacheOptions": { "TtlSeconds": 15 } "FileCacheOptions": { "TtlSeconds": 15 }
}, },
{ {
"DownstreamTemplate": "http://customers20161126090811.azurewebsites.net/api/customers", "DownstreamPathTemplate": "/api/customers",
"DownstreamScheme": "http",
"DownstreamHost": "customers20161126090811.azurewebsites.net",
"DownstreamPort": 80,
"UpstreamTemplate": "/customers", "UpstreamTemplate": "/customers",
"UpstreamHttpMethod": "Post", "UpstreamHttpMethod": "Post",
"FileCacheOptions": { "TtlSeconds": 15 } "FileCacheOptions": { "TtlSeconds": 15 }
}, },
{ {
"DownstreamTemplate": "http://customers20161126090811.azurewebsites.net/api/customers/{customerId}", "DownstreamPathTemplate": "/api/customers/{customerId}",
"DownstreamScheme": "http",
"DownstreamHost": "customers20161126090811.azurewebsites.net",
"DownstreamPort": 80,
"UpstreamTemplate": "/customers/{customerId}", "UpstreamTemplate": "/customers/{customerId}",
"UpstreamHttpMethod": "Put", "UpstreamHttpMethod": "Put",
"FileCacheOptions": { "TtlSeconds": 15 } "FileCacheOptions": { "TtlSeconds": 15 }
}, },
{ {
"DownstreamTemplate": "http://customers20161126090811.azurewebsites.net/api/customers/{customerId}", "DownstreamPathTemplate": "/api/customers/{customerId}",
"DownstreamScheme": "http",
"DownstreamHost": "customers20161126090811.azurewebsites.net",
"DownstreamPort": 80,
"UpstreamTemplate": "/customers/{customerId}", "UpstreamTemplate": "/customers/{customerId}",
"UpstreamHttpMethod": "Delete", "UpstreamHttpMethod": "Delete",
"FileCacheOptions": { "TtlSeconds": 15 } "FileCacheOptions": { "TtlSeconds": 15 }
}, },
{ {
"DownstreamTemplate": "http://jsonplaceholder.typicode.com/posts", "DownstreamPathTemplate": "/posts",
"DownstreamScheme": "http",
"DownstreamHost": "jsonplaceholder.typicode.com",
"DownstreamPort": 80,
"UpstreamTemplate": "/posts/", "UpstreamTemplate": "/posts/",
"UpstreamHttpMethod": "Get", "UpstreamHttpMethod": "Get",
"FileCacheOptions": { "TtlSeconds": 15 } "FileCacheOptions": { "TtlSeconds": 15 }

View File

@ -67,7 +67,7 @@ namespace Ocelot.UnitTests.Claims
{ {
var downstreamRoute = new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), var downstreamRoute = new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(),
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamTemplate("any old string") .WithDownstreamPathTemplate("any old string")
.WithClaimsToClaims(new List<ClaimToThing> .WithClaimsToClaims(new List<ClaimToThing>
{ {
new ClaimToThing("sub", "UserType", "|", 0) new ClaimToThing("sub", "UserType", "|", 0)

View File

@ -10,8 +10,8 @@ namespace Ocelot.UnitTests.Configuration
{ {
public class ConfigurationValidationTests public class ConfigurationValidationTests
{ {
private FileConfiguration _fileConfiguration;
private readonly IConfigurationValidator _configurationValidator; private readonly IConfigurationValidator _configurationValidator;
private FileConfiguration _fileConfiguration;
private Response<ConfigurationValidationResult> _result; private Response<ConfigurationValidationResult> _result;
public ConfigurationValidationTests() public ConfigurationValidationTests()
@ -22,32 +22,13 @@ namespace Ocelot.UnitTests.Configuration
[Fact] [Fact]
public void configuration_is_invalid_if_scheme_in_downstream_template() public void configuration_is_invalid_if_scheme_in_downstream_template()
{ {
this.Given(x => x.GivenAConfiguration(new FileConfiguration() this.Given(x => x.GivenAConfiguration(new FileConfiguration
{ {
ReRoutes = new List<FileReRoute> ReRoutes = new List<FileReRoute>
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = "http://www.bbc.co.uk/api/products/{productId}", DownstreamPathTemplate = "http://www.bbc.co.uk/api/products/{productId}",
UpstreamTemplate = "http://asdf.com"
}
}
}))
.When(x => x.WhenIValidateTheConfiguration())
.Then(x => x.ThenTheResultIsNotValid())
.BDDfy();
}
[Fact]
public void configuration_is_invalid_if_host_in_downstream_template()
{
this.Given(x => x.GivenAConfiguration(new FileConfiguration()
{
ReRoutes = new List<FileReRoute>
{
new FileReRoute
{
DownstreamTemplate = "www.bbc.co.uk/api/products/{productId}",
UpstreamTemplate = "http://asdf.com" UpstreamTemplate = "http://asdf.com"
} }
} }
@ -60,13 +41,13 @@ namespace Ocelot.UnitTests.Configuration
[Fact] [Fact]
public void configuration_is_valid_with_one_reroute() public void configuration_is_valid_with_one_reroute()
{ {
this.Given(x => x.GivenAConfiguration(new FileConfiguration() this.Given(x => x.GivenAConfiguration(new FileConfiguration
{ {
ReRoutes = new List<FileReRoute> ReRoutes = new List<FileReRoute>
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = "/api/products/", DownstreamPathTemplate = "/api/products/",
UpstreamTemplate = "http://asdf.com" UpstreamTemplate = "http://asdf.com"
} }
} }
@ -79,13 +60,13 @@ namespace Ocelot.UnitTests.Configuration
[Fact] [Fact]
public void configuration_is_valid_with_valid_authentication_provider() public void configuration_is_valid_with_valid_authentication_provider()
{ {
this.Given(x => x.GivenAConfiguration(new FileConfiguration() this.Given(x => x.GivenAConfiguration(new FileConfiguration
{ {
ReRoutes = new List<FileReRoute> ReRoutes = new List<FileReRoute>
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = "/api/products/", DownstreamPathTemplate = "/api/products/",
UpstreamTemplate = "http://asdf.com", UpstreamTemplate = "http://asdf.com",
AuthenticationOptions = new FileAuthenticationOptions AuthenticationOptions = new FileAuthenticationOptions
{ {
@ -102,13 +83,13 @@ namespace Ocelot.UnitTests.Configuration
[Fact] [Fact]
public void configuration_is_invalid_with_invalid_authentication_provider() public void configuration_is_invalid_with_invalid_authentication_provider()
{ {
this.Given(x => x.GivenAConfiguration(new FileConfiguration() this.Given(x => x.GivenAConfiguration(new FileConfiguration
{ {
ReRoutes = new List<FileReRoute> ReRoutes = new List<FileReRoute>
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = "/api/products/", DownstreamPathTemplate = "/api/products/",
UpstreamTemplate = "http://asdf.com", UpstreamTemplate = "http://asdf.com",
AuthenticationOptions = new FileAuthenticationOptions AuthenticationOptions = new FileAuthenticationOptions
{ {
@ -126,25 +107,25 @@ namespace Ocelot.UnitTests.Configuration
[Fact] [Fact]
public void configuration_is_not_valid_with_duplicate_reroutes() public void configuration_is_not_valid_with_duplicate_reroutes()
{ {
this.Given(x => x.GivenAConfiguration(new FileConfiguration() this.Given(x => x.GivenAConfiguration(new FileConfiguration
{ {
ReRoutes = new List<FileReRoute> ReRoutes = new List<FileReRoute>
{ {
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = "/api/products/", DownstreamPathTemplate = "/api/products/",
UpstreamTemplate = "http://asdf.com" UpstreamTemplate = "http://asdf.com"
}, },
new FileReRoute new FileReRoute
{ {
DownstreamTemplate = "http://www.bbc.co.uk", DownstreamPathTemplate = "http://www.bbc.co.uk",
UpstreamTemplate = "http://asdf.com" UpstreamTemplate = "http://asdf.com"
} }
} }
})) }))
.When(x => x.WhenIValidateTheConfiguration()) .When(x => x.WhenIValidateTheConfiguration())
.Then(x => x.ThenTheResultIsNotValid()) .Then(x => x.ThenTheResultIsNotValid())
.And(x => x.ThenTheErrorIs<DownstreamTemplateAlreadyUsedError>()) .And(x => x.ThenTheErrorIs<DownstreamPathTemplateAlreadyUsedError>())
.BDDfy(); .BDDfy();
} }

View File

@ -46,7 +46,7 @@ namespace Ocelot.UnitTests.Configuration
{ {
DownstreamHost = "127.0.0.1", DownstreamHost = "127.0.0.1",
UpstreamTemplate = "/api/products/{productId}", UpstreamTemplate = "/api/products/{productId}",
DownstreamTemplate = "/products/{productId}", DownstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
} }
}, },
@ -57,7 +57,7 @@ namespace Ocelot.UnitTests.Configuration
{ {
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamHost("127.0.0.1") .WithDownstreamHost("127.0.0.1")
.WithDownstreamTemplate("/products/{productId}") .WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamTemplate("/api/products/{productId}") .WithUpstreamTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod("Get") .WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("(?i)/api/products/.*/$") .WithUpstreamTemplatePattern("(?i)/api/products/.*/$")
@ -76,7 +76,7 @@ namespace Ocelot.UnitTests.Configuration
{ {
DownstreamScheme = "https", DownstreamScheme = "https",
UpstreamTemplate = "/api/products/{productId}", UpstreamTemplate = "/api/products/{productId}",
DownstreamTemplate = "/products/{productId}", DownstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
} }
}, },
@ -87,7 +87,7 @@ namespace Ocelot.UnitTests.Configuration
{ {
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamScheme("https") .WithDownstreamScheme("https")
.WithDownstreamTemplate("/products/{productId}") .WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamTemplate("/api/products/{productId}") .WithUpstreamTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod("Get") .WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("(?i)/api/products/.*/$") .WithUpstreamTemplatePattern("(?i)/api/products/.*/$")
@ -106,7 +106,7 @@ namespace Ocelot.UnitTests.Configuration
new FileReRoute new FileReRoute
{ {
UpstreamTemplate = "/api/products/{productId}", UpstreamTemplate = "/api/products/{productId}",
DownstreamTemplate = "/products/{productId}", DownstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = false, ReRouteIsCaseSensitive = false,
ServiceName = "ProductService" ServiceName = "ProductService"
@ -126,7 +126,7 @@ namespace Ocelot.UnitTests.Configuration
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute> .Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
{ {
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamTemplate("/products/{productId}") .WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamTemplate("/api/products/{productId}") .WithUpstreamTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod("Get") .WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("(?i)/api/products/.*/$") .WithUpstreamTemplatePattern("(?i)/api/products/.*/$")
@ -149,7 +149,7 @@ namespace Ocelot.UnitTests.Configuration
new FileReRoute new FileReRoute
{ {
UpstreamTemplate = "/api/products/{productId}", UpstreamTemplate = "/api/products/{productId}",
DownstreamTemplate = "/products/{productId}", DownstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = false, ReRouteIsCaseSensitive = false,
} }
@ -160,7 +160,7 @@ namespace Ocelot.UnitTests.Configuration
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute> .Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
{ {
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamTemplate("/products/{productId}") .WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamTemplate("/api/products/{productId}") .WithUpstreamTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod("Get") .WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("(?i)/api/products/.*/$") .WithUpstreamTemplatePattern("(?i)/api/products/.*/$")
@ -182,7 +182,7 @@ namespace Ocelot.UnitTests.Configuration
new FileReRoute new FileReRoute
{ {
UpstreamTemplate = "/api/products/{productId}", UpstreamTemplate = "/api/products/{productId}",
DownstreamTemplate = "/products/{productId}", DownstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = false ReRouteIsCaseSensitive = false
} }
@ -193,7 +193,7 @@ namespace Ocelot.UnitTests.Configuration
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute> .Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
{ {
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamTemplate("/products/{productId}") .WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamTemplate("/api/products/{productId}") .WithUpstreamTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod("Get") .WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("(?i)/api/products/.*/$") .WithUpstreamTemplatePattern("(?i)/api/products/.*/$")
@ -212,7 +212,7 @@ namespace Ocelot.UnitTests.Configuration
new FileReRoute new FileReRoute
{ {
UpstreamTemplate = "/api/products/{productId}", UpstreamTemplate = "/api/products/{productId}",
DownstreamTemplate = "/products/{productId}", DownstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get" UpstreamHttpMethod = "Get"
} }
} }
@ -222,7 +222,7 @@ namespace Ocelot.UnitTests.Configuration
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute> .Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
{ {
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamTemplate("/products/{productId}") .WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamTemplate("/api/products/{productId}") .WithUpstreamTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod("Get") .WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("(?i)/api/products/.*/$") .WithUpstreamTemplatePattern("(?i)/api/products/.*/$")
@ -241,7 +241,7 @@ namespace Ocelot.UnitTests.Configuration
new FileReRoute new FileReRoute
{ {
UpstreamTemplate = "/api/products/{productId}", UpstreamTemplate = "/api/products/{productId}",
DownstreamTemplate = "/products/{productId}", DownstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = true ReRouteIsCaseSensitive = true
} }
@ -252,7 +252,7 @@ namespace Ocelot.UnitTests.Configuration
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute> .Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
{ {
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamTemplate("/products/{productId}") .WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamTemplate("/api/products/{productId}") .WithUpstreamTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod("Get") .WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("/api/products/.*/$") .WithUpstreamTemplatePattern("/api/products/.*/$")
@ -271,7 +271,7 @@ namespace Ocelot.UnitTests.Configuration
new FileReRoute new FileReRoute
{ {
UpstreamTemplate = "/api/products/{productId}", UpstreamTemplate = "/api/products/{productId}",
DownstreamTemplate = "/products/{productId}", DownstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = true ReRouteIsCaseSensitive = true
} }
@ -286,7 +286,7 @@ namespace Ocelot.UnitTests.Configuration
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute> .Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
{ {
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamTemplate("/products/{productId}") .WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamTemplate("/api/products/{productId}") .WithUpstreamTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod("Get") .WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("/api/products/.*/$") .WithUpstreamTemplatePattern("/api/products/.*/$")
@ -306,7 +306,7 @@ namespace Ocelot.UnitTests.Configuration
new FileReRoute new FileReRoute
{ {
UpstreamTemplate = "/api/products/{productId}", UpstreamTemplate = "/api/products/{productId}",
DownstreamTemplate = "/products/{productId}", DownstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = true ReRouteIsCaseSensitive = true
} }
@ -317,7 +317,7 @@ namespace Ocelot.UnitTests.Configuration
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute> .Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
{ {
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamTemplate("/products/{productId}") .WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamTemplate("/api/products/{productId}") .WithUpstreamTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod("Get") .WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("/api/products/.*/$") .WithUpstreamTemplatePattern("/api/products/.*/$")
@ -332,7 +332,7 @@ namespace Ocelot.UnitTests.Configuration
var expected = new List<ReRoute> var expected = new List<ReRoute>
{ {
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamTemplate("/products/{productId}") .WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamTemplate("/api/products/{productId}") .WithUpstreamTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod("Get") .WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("/api/products/.*/$") .WithUpstreamTemplatePattern("/api/products/.*/$")
@ -355,7 +355,7 @@ namespace Ocelot.UnitTests.Configuration
new FileReRoute new FileReRoute
{ {
UpstreamTemplate = "/api/products/{productId}", UpstreamTemplate = "/api/products/{productId}",
DownstreamTemplate = "/products/{productId}", DownstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = true, ReRouteIsCaseSensitive = true,
AuthenticationOptions = new FileAuthenticationOptions AuthenticationOptions = new FileAuthenticationOptions
@ -395,7 +395,7 @@ namespace Ocelot.UnitTests.Configuration
var expected = new List<ReRoute> var expected = new List<ReRoute>
{ {
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamTemplate("/products/{productId}") .WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamTemplate("/api/products/{productId}") .WithUpstreamTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod("Get") .WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("/api/products/.*/$") .WithUpstreamTemplatePattern("/api/products/.*/$")
@ -414,7 +414,7 @@ namespace Ocelot.UnitTests.Configuration
new FileReRoute new FileReRoute
{ {
UpstreamTemplate = "/api/products/{productId}", UpstreamTemplate = "/api/products/{productId}",
DownstreamTemplate = "/products/{productId}", DownstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = true, ReRouteIsCaseSensitive = true,
AuthenticationOptions = new FileAuthenticationOptions AuthenticationOptions = new FileAuthenticationOptions
@ -446,7 +446,7 @@ namespace Ocelot.UnitTests.Configuration
new FileReRoute new FileReRoute
{ {
UpstreamTemplate = "/api/products/{productId}/variants/{variantId}", UpstreamTemplate = "/api/products/{productId}/variants/{variantId}",
DownstreamTemplate = "/products/{productId}", DownstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = true ReRouteIsCaseSensitive = true
} }
@ -457,7 +457,7 @@ namespace Ocelot.UnitTests.Configuration
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute> .Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
{ {
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamTemplate("/products/{productId}") .WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamTemplate("/api/products/{productId}/variants/{variantId}") .WithUpstreamTemplate("/api/products/{productId}/variants/{variantId}")
.WithUpstreamHttpMethod("Get") .WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("/api/products/.*/variants/.*/$") .WithUpstreamTemplatePattern("/api/products/.*/variants/.*/$")
@ -476,7 +476,7 @@ namespace Ocelot.UnitTests.Configuration
new FileReRoute new FileReRoute
{ {
UpstreamTemplate = "/api/products/{productId}/variants/{variantId}/", UpstreamTemplate = "/api/products/{productId}/variants/{variantId}/",
DownstreamTemplate = "/products/{productId}", DownstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = true ReRouteIsCaseSensitive = true
} }
@ -487,7 +487,7 @@ namespace Ocelot.UnitTests.Configuration
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute> .Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
{ {
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamTemplate("/products/{productId}") .WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamTemplate("/api/products/{productId}/variants/{variantId}/") .WithUpstreamTemplate("/api/products/{productId}/variants/{variantId}/")
.WithUpstreamHttpMethod("Get") .WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("/api/products/.*/variants/.*/$") .WithUpstreamTemplatePattern("/api/products/.*/variants/.*/$")
@ -506,7 +506,7 @@ namespace Ocelot.UnitTests.Configuration
new FileReRoute new FileReRoute
{ {
UpstreamTemplate = "/", UpstreamTemplate = "/",
DownstreamTemplate = "/api/products/", DownstreamPathTemplate = "/api/products/",
UpstreamHttpMethod = "Get", UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = true ReRouteIsCaseSensitive = true
} }
@ -517,7 +517,7 @@ namespace Ocelot.UnitTests.Configuration
.Then(x => x.ThenTheReRoutesAre(new List<ReRoute> .Then(x => x.ThenTheReRoutesAre(new List<ReRoute>
{ {
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamTemplate("/api/products/") .WithDownstreamPathTemplate("/api/products/")
.WithUpstreamTemplate("/") .WithUpstreamTemplate("/")
.WithUpstreamHttpMethod("Get") .WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("/$") .WithUpstreamTemplatePattern("/$")
@ -553,7 +553,7 @@ namespace Ocelot.UnitTests.Configuration
var result = _config.Data.ReRoutes[i]; var result = _config.Data.ReRoutes[i];
var expected = expectedReRoutes[i]; var expected = expectedReRoutes[i];
result.DownstreamTemplate.ShouldBe(expected.DownstreamTemplate); result.DownstreamPathTemplate.Value.ShouldBe(expected.DownstreamPathTemplate.Value);
result.UpstreamHttpMethod.ShouldBe(expected.UpstreamHttpMethod); result.UpstreamHttpMethod.ShouldBe(expected.UpstreamHttpMethod);
result.UpstreamTemplate.ShouldBe(expected.UpstreamTemplate); result.UpstreamTemplate.ShouldBe(expected.UpstreamTemplate);
result.UpstreamTemplatePattern.ShouldBe(expected.UpstreamTemplatePattern); result.UpstreamTemplatePattern.ShouldBe(expected.UpstreamTemplatePattern);

View File

@ -44,7 +44,7 @@ namespace Ocelot.UnitTests.Configuration
private void ThenTheConfigurationIsReturned() private void ThenTheConfigurationIsReturned()
{ {
_getResult.Data.ReRoutes[0].DownstreamTemplate.ShouldBe("initial"); _getResult.Data.ReRoutes[0].DownstreamPathTemplate.Value.ShouldBe("initial");
} }
private void WhenIGetTheConfiguration() private void WhenIGetTheConfiguration()
@ -75,16 +75,16 @@ namespace Ocelot.UnitTests.Configuration
class FakeConfig : IOcelotConfiguration class FakeConfig : IOcelotConfiguration
{ {
private readonly string _downstreamTemplate; private readonly string _downstreamTemplatePath;
public FakeConfig(string downstreamTemplate) public FakeConfig(string downstreamTemplatePath)
{ {
_downstreamTemplate = downstreamTemplate; _downstreamTemplatePath = downstreamTemplatePath;
} }
public List<ReRoute> ReRoutes => new List<ReRoute> public List<ReRoute> ReRoutes => new List<ReRoute>
{ {
new ReRouteBuilder().WithDownstreamTemplate(_downstreamTemplate).Build() new ReRouteBuilder().WithDownstreamPathTemplate(_downstreamTemplatePath).Build()
}; };
} }
} }

View File

@ -61,7 +61,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
[Fact] [Fact]
public void should_call_scoped_data_repository_correctly() public void should_call_scoped_data_repository_correctly()
{ {
this.Given(x => x.GivenTheDownStreamRouteFinderReturns(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), new ReRouteBuilder().WithDownstreamTemplate("any old string").Build()))) this.Given(x => x.GivenTheDownStreamRouteFinderReturns(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), new ReRouteBuilder().WithDownstreamPathTemplate("any old string").Build())))
.When(x => x.WhenICallTheMiddleware()) .When(x => x.WhenICallTheMiddleware())
.Then(x => x.ThenTheScopedDataRepositoryIsCalledCorrectly()) .Then(x => x.ThenTheScopedDataRepositoryIsCalledCorrectly())
.BDDfy(); .BDDfy();

View File

@ -44,7 +44,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.And(x => x.GivenTheConfigurationIs(new List<ReRoute> .And(x => x.GivenTheConfigurationIs(new List<ReRoute>
{ {
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamTemplate("someUpstreamPath") .WithUpstreamTemplate("someUpstreamPath")
.WithUpstreamHttpMethod("Get") .WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("someUpstreamPath") .WithUpstreamTemplatePattern("someUpstreamPath")
@ -57,7 +57,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.Then( .Then(
x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(),
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.Build() .Build()
))) )))
.And(x => x.ThenTheUrlMatcherIsCalledCorrectly()) .And(x => x.ThenTheUrlMatcherIsCalledCorrectly())
@ -75,13 +75,13 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.And(x => x.GivenTheConfigurationIs(new List<ReRoute> .And(x => x.GivenTheConfigurationIs(new List<ReRoute>
{ {
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamTemplate("someDownstreamPath") .WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamTemplate("someUpstreamPath") .WithUpstreamTemplate("someUpstreamPath")
.WithUpstreamHttpMethod("Get") .WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("") .WithUpstreamTemplatePattern("")
.Build(), .Build(),
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamTemplate("someDownstreamPathForAPost") .WithDownstreamPathTemplate("someDownstreamPathForAPost")
.WithUpstreamTemplate("someUpstreamPath") .WithUpstreamTemplate("someUpstreamPath")
.WithUpstreamHttpMethod("Post") .WithUpstreamHttpMethod("Post")
.WithUpstreamTemplatePattern("") .WithUpstreamTemplatePattern("")
@ -94,7 +94,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.Then( .Then(
x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(),
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamTemplate("someDownstreamPathForAPost") .WithDownstreamPathTemplate("someDownstreamPathForAPost")
.Build() .Build()
))) )))
.BDDfy(); .BDDfy();
@ -107,7 +107,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
.And(x => x.GivenTheConfigurationIs(new List<ReRoute> .And(x => x.GivenTheConfigurationIs(new List<ReRoute>
{ {
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamTemplate("somPath") .WithDownstreamPathTemplate("somPath")
.WithUpstreamTemplate("somePath") .WithUpstreamTemplate("somePath")
.WithUpstreamHttpMethod("Get") .WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("somePath") .WithUpstreamTemplatePattern("somePath")
@ -174,7 +174,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
private void ThenTheFollowingIsReturned(DownstreamRoute expected) private void ThenTheFollowingIsReturned(DownstreamRoute expected)
{ {
_result.Data.ReRoute.DownstreamTemplate.ShouldBe(expected.ReRoute.DownstreamTemplate); _result.Data.ReRoute.DownstreamPathTemplate.Value.ShouldBe(expected.ReRoute.DownstreamPathTemplate.Value);
for (int i = 0; i < _result.Data.TemplatePlaceholderNameAndValues.Count; i++) for (int i = 0; i < _result.Data.TemplatePlaceholderNameAndValues.Count; i++)
{ {

View File

@ -7,15 +7,18 @@ using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Moq; using Moq;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder; using Ocelot.Configuration.Builder;
using Ocelot.DownstreamRouteFinder; using Ocelot.DownstreamRouteFinder;
using Ocelot.DownstreamRouteFinder.Middleware; using Ocelot.DownstreamRouteFinder.Middleware;
using Ocelot.DownstreamRouteFinder.UrlMatcher; using Ocelot.DownstreamRouteFinder.UrlMatcher;
using Ocelot.DownstreamUrlCreator;
using Ocelot.DownstreamUrlCreator.Middleware; using Ocelot.DownstreamUrlCreator.Middleware;
using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer; using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer;
using Ocelot.Infrastructure.RequestData; using Ocelot.Infrastructure.RequestData;
using Ocelot.Logging; using Ocelot.Logging;
using Ocelot.Responses; using Ocelot.Responses;
using Ocelot.Values;
using TestStack.BDDfy; using TestStack.BDDfy;
using Xunit; using Xunit;
@ -23,21 +26,23 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator
{ {
public class DownstreamUrlCreatorMiddlewareTests : IDisposable public class DownstreamUrlCreatorMiddlewareTests : IDisposable
{ {
private readonly Mock<IDownstreamUrlPathPlaceholderReplacer> _downstreamUrlTemplateVariableReplacer; private readonly Mock<IDownstreamPathPlaceholderReplacer> _downstreamUrlTemplateVariableReplacer;
private readonly Mock<IRequestScopedDataRepository> _scopedRepository; private readonly Mock<IRequestScopedDataRepository> _scopedRepository;
private readonly Mock<IUrlBuilder> _urlBuilder;
private readonly string _url; private readonly string _url;
private readonly TestServer _server; private readonly TestServer _server;
private readonly HttpClient _client; private readonly HttpClient _client;
private Response<DownstreamRoute> _downstreamRoute; private Response<DownstreamRoute> _downstreamRoute;
private HttpResponseMessage _result; private HttpResponseMessage _result;
private OkResponse<DownstreamPath> _downstreamPath;
private OkResponse<DownstreamUrl> _downstreamUrl; private OkResponse<DownstreamUrl> _downstreamUrl;
public DownstreamUrlCreatorMiddlewareTests() public DownstreamUrlCreatorMiddlewareTests()
{ {
_url = "http://localhost:51879"; _url = "http://localhost:51879";
_downstreamUrlTemplateVariableReplacer = new Mock<IDownstreamUrlPathPlaceholderReplacer>(); _downstreamUrlTemplateVariableReplacer = new Mock<IDownstreamPathPlaceholderReplacer>();
_scopedRepository = new Mock<IRequestScopedDataRepository>(); _scopedRepository = new Mock<IRequestScopedDataRepository>();
_urlBuilder = new Mock<IUrlBuilder>();
var builder = new WebHostBuilder() var builder = new WebHostBuilder()
.ConfigureServices(x => .ConfigureServices(x =>
{ {
@ -45,6 +50,7 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator
x.AddLogging(); x.AddLogging();
x.AddSingleton(_downstreamUrlTemplateVariableReplacer.Object); x.AddSingleton(_downstreamUrlTemplateVariableReplacer.Object);
x.AddSingleton(_scopedRepository.Object); x.AddSingleton(_scopedRepository.Object);
x.AddSingleton(_urlBuilder.Object);
}) })
.UseUrls(_url) .UseUrls(_url)
.UseKestrel() .UseKestrel()
@ -61,21 +67,30 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator
} }
[Fact] [Fact]
public void should_call_scoped_data_repository_correctly() public void should_call_dependencies_correctly()
{ {
this.Given(x => x.GivenTheDownStreamRouteIs(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), new ReRouteBuilder().WithDownstreamTemplate("any old string").Build()))) this.Given(x => x.GivenTheDownStreamRouteIs(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), new ReRouteBuilder().WithDownstreamPathTemplate("any old string").Build())))
.And(x => x.TheUrlReplacerReturns("any old string")) .And(x => x.TheUrlReplacerReturns("/api/products/1"))
.And(x => x.TheUrlBuilderReturns("http://www.bbc.co.uk/api/products/1"))
.When(x => x.WhenICallTheMiddleware()) .When(x => x.WhenICallTheMiddleware())
.Then(x => x.ThenTheScopedDataRepositoryIsCalledCorrectly()) .Then(x => x.ThenTheScopedDataRepositoryIsCalledCorrectly())
.BDDfy(); .BDDfy();
} }
private void TheUrlBuilderReturns(string dsUrl)
{
_downstreamUrl = new OkResponse<DownstreamUrl>(new DownstreamUrl(dsUrl));
_urlBuilder
.Setup(x => x.Build(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<HostAndPort>()))
.Returns(_downstreamUrl);
}
private void TheUrlReplacerReturns(string downstreamUrl) private void TheUrlReplacerReturns(string downstreamUrl)
{ {
_downstreamUrl = new OkResponse<DownstreamUrl>(new DownstreamUrl(downstreamUrl)); _downstreamPath = new OkResponse<DownstreamPath>(new DownstreamPath(downstreamUrl));
_downstreamUrlTemplateVariableReplacer _downstreamUrlTemplateVariableReplacer
.Setup(x => x.Replace(It.IsAny<string>(), It.IsAny<List<UrlPathPlaceholderNameAndValue>>())) .Setup(x => x.Replace(It.IsAny<DownstreamPathTemplate>(), It.IsAny<List<UrlPathPlaceholderNameAndValue>>()))
.Returns(_downstreamUrl); .Returns(_downstreamPath);
} }
private void ThenTheScopedDataRepositoryIsCalledCorrectly() private void ThenTheScopedDataRepositoryIsCalledCorrectly()

View File

@ -0,0 +1,124 @@
using System;
using Ocelot.Configuration;
using Ocelot.DownstreamUrlCreator;
using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer;
using Ocelot.Responses;
using Ocelot.Values;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.DownstreamUrlCreator
{
public class UrlBuilderTests
{
private readonly IUrlBuilder _urlBuilder;
private string _dsPath;
private string _dsScheme;
private string _dsHost;
private int _dsPort;
private Response<DownstreamUrl> _result;
public UrlBuilderTests()
{
_urlBuilder = new UrlBuilder();
}
[Fact]
public void should_return_error_when_downstream_path_is_null()
{
this.Given(x => x.GivenADownstreamPath(null))
.When(x => x.WhenIBuildTheUrl())
.Then(x => x.ThenThereIsAnErrorOfType<DownstreamPathNullOrEmptyError>())
.BDDfy();
}
[Fact]
public void should_return_error_when_downstream_scheme_is_null()
{
this.Given(x => x.GivenADownstreamScheme(null))
.And(x => x.GivenADownstreamPath("test"))
.When(x => x.WhenIBuildTheUrl())
.Then(x => x.ThenThereIsAnErrorOfType<DownstreamSchemeNullOrEmptyError>())
.BDDfy();
}
[Fact]
public void should_return_error_when_downstream_host_is_null()
{
this.Given(x => x.GivenADownstreamScheme(null))
.And(x => x.GivenADownstreamPath("test"))
.And(x => x.GivenADownstreamScheme("test"))
.When(x => x.WhenIBuildTheUrl())
.Then(x => x.ThenThereIsAnErrorOfType<DownstreamHostNullOrEmptyError>())
.BDDfy();
}
[Fact]
public void should_not_use_port_if_zero()
{
this.Given(x => x.GivenADownstreamPath("/api/products/1"))
.And(x => x.GivenADownstreamScheme("http"))
.And(x => x.GivenADownstreamHost("127.0.0.1"))
.And(x => x.GivenADownstreamPort(0))
.When(x => x.WhenIBuildTheUrl())
.Then(x => x.ThenTheUrlIsReturned("http://127.0.0.1/api/products/1"))
.And(x => x.ThenTheUrlIsWellFormed())
.BDDfy();
}
[Fact]
public void should_build_well_formed_uri()
{
this.Given(x => x.GivenADownstreamPath("/api/products/1"))
.And(x => x.GivenADownstreamScheme("http"))
.And(x => x.GivenADownstreamHost("127.0.0.1"))
.And(x => x.GivenADownstreamPort(5000))
.When(x => x.WhenIBuildTheUrl())
.Then(x => x.ThenTheUrlIsReturned("http://127.0.0.1:5000/api/products/1"))
.And(x => x.ThenTheUrlIsWellFormed())
.BDDfy();
}
private void ThenThereIsAnErrorOfType<T>()
{
_result.Errors[0].ShouldBeOfType<T>();
}
private void GivenADownstreamPath(string dsPath)
{
_dsPath = dsPath;
}
private void GivenADownstreamScheme(string dsScheme)
{
_dsScheme = dsScheme;
}
private void GivenADownstreamHost(string dsHost)
{
_dsHost = dsHost;
}
private void GivenADownstreamPort(int dsPort)
{
_dsPort = dsPort;
}
private void WhenIBuildTheUrl()
{
_result = _urlBuilder.Build(_dsPath, _dsScheme, new HostAndPort(_dsHost, _dsPort));
}
private void ThenTheUrlIsReturned(string expected)
{
_result.Data.Value.ShouldBe(expected);
}
private void ThenTheUrlIsWellFormed()
{
Uri.IsWellFormedUriString(_result.Data.Value, UriKind.Absolute).ShouldBeTrue();
}
}
}

View File

@ -4,6 +4,7 @@ using Ocelot.DownstreamRouteFinder;
using Ocelot.DownstreamRouteFinder.UrlMatcher; using Ocelot.DownstreamRouteFinder.UrlMatcher;
using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer; using Ocelot.DownstreamUrlCreator.UrlTemplateReplacer;
using Ocelot.Responses; using Ocelot.Responses;
using Ocelot.Values;
using Shouldly; using Shouldly;
using TestStack.BDDfy; using TestStack.BDDfy;
using Xunit; using Xunit;
@ -13,12 +14,12 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
public class UpstreamUrlPathTemplateVariableReplacerTests public class UpstreamUrlPathTemplateVariableReplacerTests
{ {
private DownstreamRoute _downstreamRoute; private DownstreamRoute _downstreamRoute;
private Response<DownstreamUrl> _result; private Response<DownstreamPath> _result;
private readonly IDownstreamUrlPathPlaceholderReplacer _downstreamUrlPathReplacer; private readonly IDownstreamPathPlaceholderReplacer _downstreamPathReplacer;
public UpstreamUrlPathTemplateVariableReplacerTests() public UpstreamUrlPathTemplateVariableReplacerTests()
{ {
_downstreamUrlPathReplacer = new DownstreamUrlPathPlaceholderReplacer(); _downstreamPathReplacer = new DownstreamTemplatePathPlaceholderReplacer();
} }
[Fact] [Fact]
@ -33,7 +34,7 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
[Fact] [Fact]
public void can_replace_no_template_variables_with_slash() public void can_replace_no_template_variables_with_slash()
{ {
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), new ReRouteBuilder().WithDownstreamTemplate("/").Build()))) this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), new ReRouteBuilder().WithDownstreamPathTemplate("/").Build())))
.When(x => x.WhenIReplaceTheTemplateVariables()) .When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("/")) .Then(x => x.ThenTheDownstreamUrlPathIsReturned("/"))
.BDDfy(); .BDDfy();
@ -42,7 +43,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>(), new ReRouteBuilder().WithDownstreamTemplate("api").Build()))) this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), new ReRouteBuilder().WithDownstreamPathTemplate("api").Build())))
.When(x => x.WhenIReplaceTheTemplateVariables()) .When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("api")) .Then(x => x.ThenTheDownstreamUrlPathIsReturned("api"))
.BDDfy(); .BDDfy();
@ -51,7 +52,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>(), new ReRouteBuilder().WithDownstreamTemplate("api/").Build()))) this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), new ReRouteBuilder().WithDownstreamPathTemplate("api/").Build())))
.When(x => x.WhenIReplaceTheTemplateVariables()) .When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("api/")) .Then(x => x.ThenTheDownstreamUrlPathIsReturned("api/"))
.BDDfy(); .BDDfy();
@ -60,7 +61,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>(), new ReRouteBuilder().WithDownstreamTemplate("api/product/products/").Build()))) this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), new ReRouteBuilder().WithDownstreamPathTemplate("api/product/products/").Build())))
.When(x => x.WhenIReplaceTheTemplateVariables()) .When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("api/product/products/")) .Then(x => x.ThenTheDownstreamUrlPathIsReturned("api/product/products/"))
.BDDfy(); .BDDfy();
@ -74,7 +75,7 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
new UrlPathPlaceholderNameAndValue("{productId}", "1") new UrlPathPlaceholderNameAndValue("{productId}", "1")
}; };
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables, new ReRouteBuilder().WithDownstreamTemplate("productservice/products/{productId}/").Build()))) this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables, new ReRouteBuilder().WithDownstreamPathTemplate("productservice/products/{productId}/").Build())))
.When(x => x.WhenIReplaceTheTemplateVariables()) .When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/products/1/")) .Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/products/1/"))
.BDDfy(); .BDDfy();
@ -88,7 +89,7 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
new UrlPathPlaceholderNameAndValue("{productId}", "1") new UrlPathPlaceholderNameAndValue("{productId}", "1")
}; };
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables, new ReRouteBuilder().WithDownstreamTemplate("productservice/products/{productId}/variants").Build()))) this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables, new ReRouteBuilder().WithDownstreamPathTemplate("productservice/products/{productId}/variants").Build())))
.When(x => x.WhenIReplaceTheTemplateVariables()) .When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/products/1/variants")) .Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/products/1/variants"))
.BDDfy(); .BDDfy();
@ -103,7 +104,7 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
new UrlPathPlaceholderNameAndValue("{variantId}", "12") new UrlPathPlaceholderNameAndValue("{variantId}", "12")
}; };
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables, new ReRouteBuilder().WithDownstreamTemplate("productservice/products/{productId}/variants/{variantId}").Build()))) this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables, new ReRouteBuilder().WithDownstreamPathTemplate("productservice/products/{productId}/variants/{variantId}").Build())))
.When(x => x.WhenIReplaceTheTemplateVariables()) .When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/products/1/variants/12")) .Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/products/1/variants/12"))
.BDDfy(); .BDDfy();
@ -119,7 +120,7 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
new UrlPathPlaceholderNameAndValue("{categoryId}", "34") new UrlPathPlaceholderNameAndValue("{categoryId}", "34")
}; };
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables, new ReRouteBuilder().WithDownstreamTemplate("productservice/category/{categoryId}/products/{productId}/variants/{variantId}").Build()))) this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables, new ReRouteBuilder().WithDownstreamPathTemplate("productservice/category/{categoryId}/products/{productId}/variants/{variantId}").Build())))
.When(x => x.WhenIReplaceTheTemplateVariables()) .When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/category/34/products/1/variants/12")) .Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/category/34/products/1/variants/12"))
.BDDfy(); .BDDfy();
@ -132,7 +133,7 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
private void WhenIReplaceTheTemplateVariables() private void WhenIReplaceTheTemplateVariables()
{ {
_result = _downstreamUrlPathReplacer.Replace(_downstreamRoute.ReRoute.DownstreamTemplate, _downstreamRoute.TemplatePlaceholderNameAndValues); _result = _downstreamPathReplacer.Replace(_downstreamRoute.ReRoute.DownstreamPathTemplate, _downstreamRoute.TemplatePlaceholderNameAndValues);
} }
private void ThenTheDownstreamUrlPathIsReturned(string expected) private void ThenTheDownstreamUrlPathIsReturned(string expected)

View File

@ -67,7 +67,7 @@ namespace Ocelot.UnitTests.Headers
{ {
var downstreamRoute = new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), var downstreamRoute = new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(),
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamTemplate("any old string") .WithDownstreamPathTemplate("any old string")
.WithClaimsToHeaders(new List<ClaimToThing> .WithClaimsToHeaders(new List<ClaimToThing>
{ {
new ClaimToThing("UserId", "Subject", "", 0) new ClaimToThing("UserId", "Subject", "", 0)

View File

@ -65,7 +65,7 @@ namespace Ocelot.UnitTests.QueryStrings
{ {
var downstreamRoute = new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), var downstreamRoute = new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(),
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamTemplate("any old string") .WithDownstreamPathTemplate("any old string")
.WithClaimsToQueries(new List<ClaimToThing> .WithClaimsToQueries(new List<ClaimToThing>
{ {
new ClaimToThing("UserId", "Subject", "", 0) new ClaimToThing("UserId", "Subject", "", 0)

View File

@ -71,7 +71,7 @@ namespace Ocelot.UnitTests.RequestId
{ {
var downstreamRoute = new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), var downstreamRoute = new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(),
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamTemplate("any old string") .WithDownstreamPathTemplate("any old string")
.WithRequestIdKey("LSRequestId").Build()); .WithRequestIdKey("LSRequestId").Build());
var requestId = Guid.NewGuid().ToString(); var requestId = Guid.NewGuid().ToString();
@ -88,7 +88,7 @@ namespace Ocelot.UnitTests.RequestId
{ {
var downstreamRoute = new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), var downstreamRoute = new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(),
new ReRouteBuilder() new ReRouteBuilder()
.WithDownstreamTemplate("any old string") .WithDownstreamPathTemplate("any old string")
.WithRequestIdKey("LSRequestId").Build()); .WithRequestIdKey("LSRequestId").Build());
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute)) this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))