Merge pull request #31 from TomPallister/feature/use-service-provider-config-builder

Feature/use service provider config builder
This commit is contained in:
Tom Pallister 2017-02-11 12:11:01 +00:00 committed by GitHub
commit 04fb12d1ac
56 changed files with 567 additions and 340 deletions

BIN
.DS_Store vendored

Binary file not shown.

6
.gitignore vendored
View File

@ -236,3 +236,9 @@ _Pvt_Extensions
# FAKE - F# Make
.fake/
tools/
# MacOS
.DS_Store
# Ocelot acceptance test config
test/Ocelot.AcceptanceTests/configuration.json

View File

@ -122,7 +122,7 @@ Ocelot's primary functionality is to take incomeing http requests and forward th
to a downstream service. At the moment in the form of another http request (in the future
this could be any transport mechanism.).
Ocelot always adds a trailing slash to an UpstreamTemplate.
Ocelot always adds a trailing slash to an UpstreamPathTemplate.
Ocelot's describes the routing of one request to another as a ReRoute. In order to get
anything working in Ocelot you need to set up a ReRoute in the configuration.
@ -140,16 +140,16 @@ the following.
"DownstreamScheme": "https",
"DownstreamPort": 80,
"DownstreamHost" "localhost"
"UpstreamTemplate": "/posts/{postId}",
"UpstreamPathTemplate": "/posts/{postId}",
"UpstreamHttpMethod": "Put"
}
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 UpstreamPathTemplate is the URL that Ocelot will use to identity which
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 :)
In Ocelot you can add placeholders for variables to your Templates in the form of {something}.
The placeholder needs to be in both the DownstreamPathTemplate and UpstreamTemplate. If it is
The placeholder needs to be in both the DownstreamPathTemplate and UpstreamPathTemplate. If it is
Ocelot will attempt to replace the placeholder with the correct variable value from the
Upstream URL when the request comes in.
@ -190,7 +190,7 @@ and LeastConnection algorithm you can use. If no load balancer is specified Ocel
{
"DownstreamPathTemplate": "/api/posts/{postId}",
"DownstreamScheme": "https",
"UpstreamTemplate": "/posts/{postId}",
"UpstreamPathTemplate": "/posts/{postId}",
"UpstreamHttpMethod": "Put",
"ServiceName": "product"
"LoadBalancer": "LeastConnection"

View File

@ -42,7 +42,7 @@ var nugetFeedStableSymbolsUploadUrl = "https://www.nuget.org/api/v2/package";
// internal build variables - don't change these.
var releaseTag = "";
var committedVersion = "0.0.0-dev";
string committedVersion = "0.0.0-dev";
var buildVersion = committedVersion;
var target = Argument("target", "Default");

View File

@ -15,7 +15,7 @@
# 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",
"UpstreamPathTemplate": "/identityserverexample",
# The method we are listening for on this re route
"UpstreamHttpMethod": "Get",
# Only support identity server at the moment

View File

@ -12,7 +12,7 @@ namespace Ocelot.Authentication.Handler.Creator
/// </summary>
public class AuthenticationHandlerCreator : IAuthenticationHandlerCreator
{
public Response<RequestDelegate> CreateIdentityServerAuthenticationHandler(IApplicationBuilder app, AuthenticationOptions authOptions)
public Response<RequestDelegate> Create(IApplicationBuilder app, AuthenticationOptions authOptions)
{
var builder = app.New();

View File

@ -8,6 +8,6 @@ namespace Ocelot.Authentication.Handler.Creator
public interface IAuthenticationHandlerCreator
{
Response<RequestDelegate> CreateIdentityServerAuthenticationHandler(IApplicationBuilder app, AuthenticationOptions authOptions);
Response<RequestDelegate> Create(IApplicationBuilder app, AuthenticationOptions authOptions);
}
}

View File

@ -19,7 +19,7 @@ namespace Ocelot.Authentication.Handler.Factory
public Response<AuthenticationHandler> Get(IApplicationBuilder app, AuthenticationOptions authOptions)
{
var handler = _creator.CreateIdentityServerAuthenticationHandler(app, authOptions);
var handler = _creator.Create(app, authOptions);
if (!handler.IsError)
{

View File

@ -2,7 +2,6 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Ocelot.Authentication.Handler.Factory;
using Ocelot.Configuration;
using Ocelot.Errors;

View File

@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using Ocelot.Errors;
using Ocelot.Responses;

View File

@ -1,5 +1,4 @@
using Microsoft.Extensions.Logging;
using Ocelot.Infrastructure.RequestData;
using Ocelot.Infrastructure.RequestData;
using Ocelot.Logging;
using Ocelot.Responses;
@ -61,7 +60,7 @@ namespace Ocelot.Authorisation.Middleware
SetPipelineError(new List<Error>
{
new UnauthorisedError(
$"{context.User.Identity.Name} unable to access {DownstreamRoute.ReRoute.UpstreamTemplate}")
$"{context.User.Identity.Name} unable to access {DownstreamRoute.ReRoute.UpstreamPathTemplate.Value}")
});
}
}

View File

@ -0,0 +1,56 @@
using System.Collections.Generic;
namespace Ocelot.Configuration.Builder
{
public class AuthenticationOptionsBuilder
{
private string _provider;
private string _providerRootUrl;
private string _scopeName;
private string _scopeSecret;
private bool _requireHttps;
private List<string> _additionalScopes;
public AuthenticationOptionsBuilder WithProvider(string provider)
{
_provider = provider;
return this;
}
public AuthenticationOptionsBuilder WithProviderRootUrl(string providerRootUrl)
{
_providerRootUrl = providerRootUrl;
return this;
}
public AuthenticationOptionsBuilder WithScopeName(string scopeName)
{
_scopeName = scopeName;
return this;
}
public AuthenticationOptionsBuilder WithScopeSecret(string scopeSecret)
{
_scopeSecret = scopeSecret;
return this;
}
public AuthenticationOptionsBuilder WithRequireHttps(bool requireHttps)
{
_requireHttps = requireHttps;
return this;
}
public AuthenticationOptionsBuilder WithAdditionalScopes(List<string> additionalScopes)
{
_additionalScopes = additionalScopes;
return this;
}
public AuthenticationOptions Build()
{
return new AuthenticationOptions(_provider, _providerRootUrl, _scopeName, _requireHttps, _additionalScopes, _scopeSecret);
}
}
}

View File

@ -1,23 +1,19 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
using Ocelot.Values;
namespace Ocelot.Configuration.Builder
{
public class ReRouteBuilder
{
private AuthenticationOptions _authenticationOptions;
private string _loadBalancerKey;
private string _downstreamPathTemplate;
private string _upstreamTemplate;
private string _upstreamTemplatePattern;
private string _upstreamHttpMethod;
private bool _isAuthenticated;
private string _authenticationProvider;
private string _authenticationProviderUrl;
private string _scopeName;
private List<string> _additionalScopes;
private bool _requireHttps;
private string _scopeSecret;
private List<ClaimToThing> _configHeaderExtractorProperties;
private List<ClaimToThing> _claimToClaims;
private Dictionary<string, string> _routeClaimRequirement;
@ -26,25 +22,15 @@ namespace Ocelot.Configuration.Builder
private string _requestIdHeaderKey;
private bool _isCached;
private CacheOptions _fileCacheOptions;
private bool _useServiceDiscovery;
private string _serviceName;
private string _serviceDiscoveryProvider;
private string _serviceDiscoveryAddress;
private string _downstreamScheme;
private string _downstreamHost;
private int _dsPort;
private int _downstreamPort;
private string _loadBalancer;
private string _serviceProviderHost;
private int _serviceProviderPort;
private ServiceProviderConfiguraion _serviceProviderConfiguraion;
private bool _useQos;
private QoSOptions _qosOptions;
public ReRouteBuilder()
{
_additionalScopes = new List<string>();
}
public ReRouteBuilder WithLoadBalancer(string loadBalancer)
{
_loadBalancer = loadBalancer;
@ -63,37 +49,19 @@ namespace Ocelot.Configuration.Builder
return this;
}
public ReRouteBuilder WithServiceDiscoveryAddress(string serviceDiscoveryAddress)
{
_serviceDiscoveryAddress = serviceDiscoveryAddress;
return this;
}
public ReRouteBuilder WithServiceDiscoveryProvider(string serviceDiscoveryProvider)
{
_serviceDiscoveryProvider = serviceDiscoveryProvider;
return this;
}
public ReRouteBuilder WithServiceName(string serviceName)
{
_serviceName = serviceName;
return this;
}
public ReRouteBuilder WithUseServiceDiscovery(bool useServiceDiscovery)
{
_useServiceDiscovery = useServiceDiscovery;
return this;
}
public ReRouteBuilder WithDownstreamPathTemplate(string input)
{
_downstreamPathTemplate = input;
return this;
}
public ReRouteBuilder WithUpstreamTemplate(string input)
public ReRouteBuilder WithUpstreamPathTemplate(string input)
{
_upstreamTemplate = input;
return this;
@ -121,42 +89,6 @@ namespace Ocelot.Configuration.Builder
return this;
}
public ReRouteBuilder WithAuthenticationProvider(string input)
{
_authenticationProvider = input;
return this;
}
public ReRouteBuilder WithAuthenticationProviderUrl(string input)
{
_authenticationProviderUrl = input;
return this;
}
public ReRouteBuilder WithAuthenticationProviderScopeName(string input)
{
_scopeName = input;
return this;
}
public ReRouteBuilder WithAuthenticationProviderAdditionalScopes(List<string> input)
{
_additionalScopes = input;
return this;
}
public ReRouteBuilder WithRequireHttps(bool input)
{
_requireHttps = input;
return this;
}
public ReRouteBuilder WithScopeSecret(string input)
{
_scopeSecret = input;
return this;
}
public ReRouteBuilder WithRequestIdKey(string input)
{
_requestIdHeaderKey = input;
@ -201,7 +133,7 @@ namespace Ocelot.Configuration.Builder
public ReRouteBuilder WithDownstreamPort(int port)
{
_dsPort = port;
_downstreamPort = port;
return this;
}
@ -224,28 +156,43 @@ namespace Ocelot.Configuration.Builder
return this;
}
public ReRouteBuilder WithServiceProviderHost(string serviceProviderHost)
public ReRouteBuilder WithServiceProviderConfiguraion(ServiceProviderConfiguraion serviceProviderConfiguraion)
{
_serviceProviderHost = serviceProviderHost;
_serviceProviderConfiguraion = serviceProviderConfiguraion;
return this;
}
public ReRouteBuilder WithServiceProviderPort(int serviceProviderPort)
public ReRouteBuilder WithAuthenticationOptions(AuthenticationOptions authenticationOptions)
{
_serviceProviderPort = serviceProviderPort;
_authenticationOptions = authenticationOptions;
return this;
}
public ReRoute Build()
{
return new ReRoute(new DownstreamPathTemplate(_downstreamPathTemplate), _upstreamTemplate, _upstreamHttpMethod, _upstreamTemplatePattern,
_isAuthenticated, new AuthenticationOptions(_authenticationProvider, _authenticationProviderUrl, _scopeName,
_requireHttps, _additionalScopes, _scopeSecret), _configHeaderExtractorProperties, _claimToClaims, _routeClaimRequirement,
_isAuthorised, _claimToQueries, _requestIdHeaderKey, _isCached, _fileCacheOptions, _downstreamScheme, _loadBalancer,
_downstreamHost, _dsPort, _loadBalancerKey, new ServiceProviderConfiguraion(_serviceName, _downstreamHost, _dsPort, _useServiceDiscovery,
_serviceDiscoveryProvider, _serviceProviderHost, _serviceProviderPort),
_useQos,_qosOptions);
return new ReRoute(
new PathTemplate(_downstreamPathTemplate),
new PathTemplate(_upstreamTemplate),
new HttpMethod(_upstreamHttpMethod),
_upstreamTemplatePattern,
_isAuthenticated,
_authenticationOptions,
_configHeaderExtractorProperties,
_claimToClaims,
_routeClaimRequirement,
_isAuthorised,
_claimToQueries,
_requestIdHeaderKey,
_isCached,
_fileCacheOptions,
_downstreamScheme,
_loadBalancer,
_downstreamHost,
_downstreamPort,
_loadBalancerKey,
_serviceProviderConfiguraion,
_useQos,
_qosOptions);
}
}
}

View File

@ -0,0 +1,62 @@
namespace Ocelot.Configuration.Builder
{
public class ServiceProviderConfiguraionBuilder
{
private string _serviceName;
private string _downstreamHost;
private int _downstreamPort;
private bool _userServiceDiscovery;
private string _serviceDiscoveryProvider;
private string _serviceDiscoveryProviderHost;
private int _serviceDiscoveryProviderPort;
public ServiceProviderConfiguraionBuilder WithServiceName(string serviceName)
{
_serviceName = serviceName;
return this;
}
public ServiceProviderConfiguraionBuilder WithDownstreamHost(string downstreamHost)
{
_downstreamHost = downstreamHost;
return this;
}
public ServiceProviderConfiguraionBuilder WithDownstreamPort(int downstreamPort)
{
_downstreamPort = downstreamPort;
return this;
}
public ServiceProviderConfiguraionBuilder WithUseServiceDiscovery(bool userServiceDiscovery)
{
_userServiceDiscovery = userServiceDiscovery;
return this;
}
public ServiceProviderConfiguraionBuilder WithServiceDiscoveryProvider(string serviceDiscoveryProvider)
{
_serviceDiscoveryProvider = serviceDiscoveryProvider;
return this;
}
public ServiceProviderConfiguraionBuilder WithServiceDiscoveryProviderHost(string serviceDiscoveryProviderHost)
{
_serviceDiscoveryProviderHost = serviceDiscoveryProviderHost;
return this;
}
public ServiceProviderConfiguraionBuilder WithServiceDiscoveryProviderPort(int serviceDiscoveryProviderPort)
{
_serviceDiscoveryProviderPort = serviceDiscoveryProviderPort;
return this;
}
public ServiceProviderConfiguraion Build()
{
return new ServiceProviderConfiguraion(_serviceName, _downstreamHost, _downstreamPort, _userServiceDiscovery,
_serviceDiscoveryProvider, _serviceDiscoveryProviderHost,_serviceDiscoveryProviderPort);
}
}
}

View File

@ -1,9 +1,11 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Ocelot.Configuration.Builder;
using Ocelot.Configuration.File;
using Ocelot.Configuration.Parser;
using Ocelot.Configuration.Validator;
@ -53,10 +55,6 @@ namespace Ocelot.Configuration.Creator
return new OkResponse<IOcelotConfiguration>(config);
}
/// <summary>
/// This method is meant to be tempoary to convert a config to an ocelot config...probably wont keep this but we will see
/// will need a refactor at some point as its crap
/// </summary>
private async Task<IOcelotConfiguration> SetUpConfiguration()
{
var response = _configurationValidator.IsValid(_options.Value);
@ -86,82 +84,129 @@ namespace Ocelot.Configuration.Creator
private async Task<ReRoute> SetUpReRoute(FileReRoute fileReRoute, FileGlobalConfiguration globalConfiguration)
{
var globalRequestIdConfiguration = !string.IsNullOrEmpty(globalConfiguration?.RequestIdKey);
var isAuthenticated = IsAuthenticated(fileReRoute);
var upstreamTemplate = BuildUpstreamTemplate(fileReRoute);
var isAuthorised = IsAuthenticated(fileReRoute);
var isAuthenticated = !string.IsNullOrEmpty(fileReRoute.AuthenticationOptions?.Provider);
var isCached = IsCached(fileReRoute);
var isAuthorised = fileReRoute.RouteClaimsRequirement?.Count > 0;
var requestIdKey = BuildRequestId(fileReRoute, globalConfiguration);
var isCached = fileReRoute.FileCacheOptions.TtlSeconds > 0;
var loadBalancerKey = BuildLoadBalancerKey(fileReRoute);
var upstreamTemplatePattern = BuildUpstreamTemplate(fileReRoute);
var isQos = fileReRoute.QoSOptions.ExceptionsAllowedBeforeBreaking > 0 && fileReRoute.QoSOptions.TimeoutValue >0;
var serviceProviderConfiguration = BuildServiceProviderConfiguration(fileReRoute, globalConfiguration);
var authOptionsForRoute = BuildAuthenticationOptions(fileReRoute);
var claimsToHeaders = BuildAddThingsToRequest(fileReRoute.AddHeadersToRequest);
var claimsToClaims = BuildAddThingsToRequest(fileReRoute.AddClaimsToRequest);
var claimsToQueries = BuildAddThingsToRequest(fileReRoute.AddQueriesToRequest);
var reRoute = new ReRouteBuilder()
.WithDownstreamPathTemplate(fileReRoute.DownstreamPathTemplate)
.WithUpstreamPathTemplate(fileReRoute.UpstreamPathTemplate)
.WithUpstreamHttpMethod(fileReRoute.UpstreamHttpMethod)
.WithUpstreamTemplatePattern(upstreamTemplatePattern)
.WithIsAuthenticated(isAuthenticated)
.WithAuthenticationOptions(authOptionsForRoute)
.WithClaimsToHeaders(claimsToHeaders)
.WithClaimsToClaims(claimsToClaims)
.WithRouteClaimsRequirement(fileReRoute.RouteClaimsRequirement)
.WithIsAuthorised(isAuthorised)
.WithClaimsToQueries(claimsToQueries)
.WithRequestIdKey(requestIdKey)
.WithIsCached(isCached)
.WithCacheOptions(new CacheOptions(fileReRoute.FileCacheOptions.TtlSeconds))
.WithDownstreamScheme(fileReRoute.DownstreamScheme)
.WithLoadBalancer(fileReRoute.LoadBalancer)
.WithDownstreamHost(fileReRoute.DownstreamHost)
.WithDownstreamPort(fileReRoute.DownstreamPort)
.WithLoadBalancerKey(loadBalancerKey)
.WithServiceProviderConfiguraion(serviceProviderConfiguration)
.Build();
await SetupLoadBalancer(reRoute);
return reRoute;
}
private bool IsAuthenticated(FileReRoute fileReRoute)
{
return !string.IsNullOrEmpty(fileReRoute.AuthenticationOptions?.Provider);
}
private bool IsAuthorised(FileReRoute fileReRoute)
{
return fileReRoute.RouteClaimsRequirement?.Count > 0;
}
private bool IsCached(FileReRoute fileReRoute)
{
return fileReRoute.FileCacheOptions.TtlSeconds > 0;
}
private string BuildRequestId(FileReRoute fileReRoute, FileGlobalConfiguration globalConfiguration)
{
var globalRequestIdConfiguration = !string.IsNullOrEmpty(globalConfiguration?.RequestIdKey);
var requestIdKey = globalRequestIdConfiguration
? globalConfiguration.RequestIdKey
: fileReRoute.RequestIdKey;
return requestIdKey;
}
private string BuildLoadBalancerKey(FileReRoute fileReRoute)
{
//note - not sure if this is the correct key, but this is probably the only unique key i can think of given my poor brain
var loadBalancerKey = $"{fileReRoute.UpstreamPathTemplate}{fileReRoute.UpstreamHttpMethod}";
return loadBalancerKey;
}
private AuthenticationOptions BuildAuthenticationOptions(FileReRoute fileReRoute)
{
return new AuthenticationOptionsBuilder()
.WithProvider(fileReRoute.AuthenticationOptions?.Provider)
.WithProviderRootUrl(fileReRoute.AuthenticationOptions?.ProviderRootUrl)
.WithScopeName(fileReRoute.AuthenticationOptions?.ScopeName)
.WithRequireHttps(fileReRoute.AuthenticationOptions.RequireHttps)
.WithAdditionalScopes(fileReRoute.AuthenticationOptions?.AdditionalScopes)
.WithScopeSecret(fileReRoute.AuthenticationOptions?.ScopeSecret)
.Build();
}
private async Task SetupLoadBalancer(ReRoute reRoute)
{
var loadBalancer = await _loadBalanceFactory.Get(reRoute);
_loadBalancerHouse.Add(reRoute.LoadBalancerKey, loadBalancer);
}
private ServiceProviderConfiguraion BuildServiceProviderConfiguration(FileReRoute fileReRoute, FileGlobalConfiguration globalConfiguration)
{
var useServiceDiscovery = !string.IsNullOrEmpty(fileReRoute.ServiceName)
&& !string.IsNullOrEmpty(globalConfiguration?.ServiceDiscoveryProvider?.Provider);
//note - not sure if this is the correct key, but this is probably the only unique key i can think of given my poor brain
var loadBalancerKey = $"{fileReRoute.UpstreamTemplate}{fileReRoute.UpstreamHttpMethod}";
ReRoute reRoute;
var serviceProviderPort = globalConfiguration?.ServiceDiscoveryProvider?.Port ?? 0;
var serviceProviderConfiguration = new ServiceProviderConfiguraion(fileReRoute.ServiceName,
fileReRoute.DownstreamHost, fileReRoute.DownstreamPort, useServiceDiscovery,
globalConfiguration?.ServiceDiscoveryProvider?.Provider, globalConfiguration?.ServiceDiscoveryProvider?.Host,
serviceProviderPort);
if (isAuthenticated)
{
var authOptionsForRoute = new AuthenticationOptions(fileReRoute.AuthenticationOptions.Provider,
fileReRoute.AuthenticationOptions.ProviderRootUrl, fileReRoute.AuthenticationOptions.ScopeName,
fileReRoute.AuthenticationOptions.RequireHttps, fileReRoute.AuthenticationOptions.AdditionalScopes,
fileReRoute.AuthenticationOptions.ScopeSecret);
var claimsToHeaders = GetAddThingsToRequest(fileReRoute.AddHeadersToRequest);
var claimsToClaims = GetAddThingsToRequest(fileReRoute.AddClaimsToRequest);
var claimsToQueries = GetAddThingsToRequest(fileReRoute.AddQueriesToRequest);
reRoute = new ReRoute(new DownstreamPathTemplate(fileReRoute.DownstreamPathTemplate),
fileReRoute.UpstreamTemplate,
fileReRoute.UpstreamHttpMethod, upstreamTemplate, isAuthenticated,
authOptionsForRoute, claimsToHeaders, claimsToClaims,
fileReRoute.RouteClaimsRequirement, isAuthorised, claimsToQueries,
requestIdKey, isCached, new CacheOptions(fileReRoute.FileCacheOptions.TtlSeconds)
, fileReRoute.DownstreamScheme,
fileReRoute.LoadBalancer, fileReRoute.DownstreamHost, fileReRoute.DownstreamPort, loadBalancerKey,
serviceProviderConfiguration, isQos,
new QoSOptions(fileReRoute.QoSOptions.ExceptionsAllowedBeforeBreaking, fileReRoute.QoSOptions.DurationOfBreak, fileReRoute.QoSOptions.TimeoutValue));
}
else
{
reRoute = new ReRoute(new DownstreamPathTemplate(fileReRoute.DownstreamPathTemplate),
fileReRoute.UpstreamTemplate,
fileReRoute.UpstreamHttpMethod, upstreamTemplate, isAuthenticated,
null, new List<ClaimToThing>(), new List<ClaimToThing>(),
fileReRoute.RouteClaimsRequirement, isAuthorised, new List<ClaimToThing>(),
requestIdKey, isCached, new CacheOptions(fileReRoute.FileCacheOptions.TtlSeconds),
fileReRoute.DownstreamScheme,
fileReRoute.LoadBalancer, fileReRoute.DownstreamHost, fileReRoute.DownstreamPort, loadBalancerKey,
serviceProviderConfiguration, isQos,
new QoSOptions(fileReRoute.QoSOptions.ExceptionsAllowedBeforeBreaking, fileReRoute.QoSOptions.DurationOfBreak, fileReRoute.QoSOptions.TimeoutValue));
}
var loadBalancer = await _loadBalanceFactory.Get(reRoute);
_loadBalancerHouse.Add(reRoute.LoadBalancerKey, loadBalancer);
return reRoute;
return new ServiceProviderConfiguraionBuilder()
.WithServiceName(fileReRoute.ServiceName)
.WithDownstreamHost(fileReRoute.DownstreamHost)
.WithDownstreamPort(fileReRoute.DownstreamPort)
.WithUseServiceDiscovery(useServiceDiscovery)
.WithServiceDiscoveryProvider(globalConfiguration?.ServiceDiscoveryProvider?.Provider)
.WithServiceDiscoveryProviderHost(globalConfiguration?.ServiceDiscoveryProvider?.Host)
.WithServiceDiscoveryProviderPort(serviceProviderPort)
.Build();
}
private string BuildUpstreamTemplate(FileReRoute reRoute)
{
var upstreamTemplate = reRoute.UpstreamTemplate;
var upstreamTemplate = reRoute.UpstreamPathTemplate;
upstreamTemplate = upstreamTemplate.SetLastCharacterAs('/');
@ -190,7 +235,7 @@ namespace Ocelot.Configuration.Creator
return route;
}
private List<ClaimToThing> GetAddThingsToRequest(Dictionary<string,string> thingBeingAdded)
private List<ClaimToThing> BuildAddThingsToRequest(Dictionary<string,string> thingBeingAdded)
{
var claimsToTHings = new List<ClaimToThing>();

View File

@ -16,7 +16,7 @@ namespace Ocelot.Configuration.File
}
public string DownstreamPathTemplate { get; set; }
public string UpstreamTemplate { get; set; }
public string UpstreamPathTemplate { get; set; }
public string UpstreamHttpMethod { get; set; }
public FileAuthenticationOptions AuthenticationOptions { get; set; }
public Dictionary<string, string> AddHeadersToRequest { get; set; }

View File

@ -1,23 +1,34 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
using Ocelot.Values;
namespace Ocelot.Configuration
{
public class ReRoute
{
public ReRoute(DownstreamPathTemplate downstreamPathTemplate,
string upstreamTemplate, string upstreamHttpMethod,
public ReRoute(PathTemplate downstreamPathTemplate,
PathTemplate upstreamTemplate,
HttpMethod upstreamHttpMethod,
string upstreamTemplatePattern,
bool isAuthenticated, AuthenticationOptions authenticationOptions,
bool isAuthenticated,
AuthenticationOptions authenticationOptions,
List<ClaimToThing> configurationHeaderExtractorProperties,
List<ClaimToThing> claimsToClaims,
Dictionary<string, string> routeClaimsRequirement, bool isAuthorised,
Dictionary<string, string> routeClaimsRequirement,
bool isAuthorised,
List<ClaimToThing> claimsToQueries,
string requestIdKey, bool isCached, CacheOptions fileCacheOptions,
string downstreamScheme, string loadBalancer, string downstreamHost,
int downstreamPort, string loadBalancerKey, ServiceProviderConfiguraion serviceProviderConfiguraion,
bool isQos,QoSOptions qos)
string requestIdKey,
bool isCached,
CacheOptions fileCacheOptions,
string downstreamScheme,
string loadBalancer,
string downstreamHost,
int downstreamPort,
string loadBalancerKey,
ServiceProviderConfiguraion serviceProviderConfiguraion,
bool isQos,
QoSOptions qos)
{
LoadBalancerKey = loadBalancerKey;
ServiceProviderConfiguraion = serviceProviderConfiguraion;
@ -25,7 +36,7 @@ namespace Ocelot.Configuration
DownstreamHost = downstreamHost;
DownstreamPort = downstreamPort;
DownstreamPathTemplate = downstreamPathTemplate;
UpstreamTemplate = upstreamTemplate;
UpstreamPathTemplate = upstreamTemplate;
UpstreamHttpMethod = upstreamHttpMethod;
UpstreamTemplatePattern = upstreamTemplatePattern;
IsAuthenticated = isAuthenticated;
@ -47,10 +58,10 @@ namespace Ocelot.Configuration
}
public string LoadBalancerKey {get;private set;}
public DownstreamPathTemplate DownstreamPathTemplate { get; private set; }
public string UpstreamTemplate { get; private set; }
public PathTemplate DownstreamPathTemplate { get; private set; }
public PathTemplate UpstreamPathTemplate { get; private set; }
public string UpstreamTemplatePattern { get; private set; }
public string UpstreamHttpMethod { get; private set; }
public HttpMethod UpstreamHttpMethod { get; private set; }
public bool IsAuthenticated { get; private set; }
public bool IsAuthorised { get; private set; }
public AuthenticationOptions AuthenticationOptions { get; private set; }

View File

@ -54,7 +54,7 @@ namespace Ocelot.Configuration.Validator
continue;
}
var error = new UnsupportedAuthenticationProviderError($"{reRoute.AuthenticationOptions?.Provider} is unsupported authentication provider, upstream template is {reRoute.UpstreamTemplate}, upstream method is {reRoute.UpstreamHttpMethod}");
var error = new UnsupportedAuthenticationProviderError($"{reRoute.AuthenticationOptions?.Provider} is unsupported authentication provider, upstream template is {reRoute.UpstreamPathTemplate}, upstream method is {reRoute.UpstreamHttpMethod}");
errors.Add(error);
}
@ -94,18 +94,18 @@ namespace Ocelot.Configuration.Validator
private ConfigurationValidationResult CheckForDupliateReRoutes(FileConfiguration configuration)
{
var hasDupes = configuration.ReRoutes
.GroupBy(x => new { x.UpstreamTemplate, x.UpstreamHttpMethod }).Any(x => x.Skip(1).Any());
.GroupBy(x => new { x.UpstreamPathTemplate, x.UpstreamHttpMethod }).Any(x => x.Skip(1).Any());
if (!hasDupes)
{
return new ConfigurationValidationResult(false);
}
var dupes = configuration.ReRoutes.GroupBy(x => new { x.UpstreamTemplate, x.UpstreamHttpMethod })
var dupes = configuration.ReRoutes.GroupBy(x => new { x.UpstreamPathTemplate, x.UpstreamHttpMethod })
.Where(x => x.Skip(1).Any());
var errors = dupes
.Select(d => new DownstreamPathTemplateAlreadyUsedError(string.Format("Duplicate DownstreamPath: {0}", d.Key.UpstreamTemplate)))
.Select(d => new DownstreamPathTemplateAlreadyUsedError(string.Format("Duplicate DownstreamPath: {0}", d.Key.UpstreamPathTemplate)))
.Cast<Error>()
.ToList();

View File

@ -26,7 +26,7 @@ namespace Ocelot.DownstreamRouteFinder.Finder
{
var configuration = await _configProvider.Get();
var applicableReRoutes = configuration.Data.ReRoutes.Where(r => string.Equals(r.UpstreamHttpMethod, upstreamHttpMethod, StringComparison.CurrentCultureIgnoreCase));
var applicableReRoutes = configuration.Data.ReRoutes.Where(r => string.Equals(r.UpstreamHttpMethod.Method, upstreamHttpMethod, StringComparison.CurrentCultureIgnoreCase));
foreach (var reRoute in applicableReRoutes)
{
@ -34,7 +34,7 @@ namespace Ocelot.DownstreamRouteFinder.Finder
if (urlMatch.Data.Match)
{
var templateVariableNameAndValues = _urlPathPlaceholderNameAndValueFinder.Find(upstreamUrlPath, reRoute.UpstreamTemplate);
var templateVariableNameAndValues = _urlPathPlaceholderNameAndValueFinder.Find(upstreamUrlPath, reRoute.UpstreamPathTemplate.Value);
return new OkResponse<DownstreamRoute>(new DownstreamRoute(templateVariableNameAndValues.Data, reRoute));
}

View File

@ -8,7 +8,7 @@ namespace Ocelot.DownstreamUrlCreator.UrlTemplateReplacer
{
public class DownstreamTemplatePathPlaceholderReplacer : IDownstreamPathPlaceholderReplacer
{
public Response<DownstreamPath> Replace(DownstreamPathTemplate downstreamPathTemplate, List<UrlPathPlaceholderNameAndValue> urlPathPlaceholderNameAndValues)
public Response<DownstreamPath> Replace(PathTemplate downstreamPathTemplate, List<UrlPathPlaceholderNameAndValue> urlPathPlaceholderNameAndValues)
{
var downstreamPath = new StringBuilder();

View File

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

View File

@ -14,16 +14,7 @@ namespace Ocelot.LoadBalancer.LoadBalancers
public async Task<ILoadBalancer> Get(ReRoute reRoute)
{
var serviceConfig = new ServiceProviderConfiguraion(
reRoute.ServiceProviderConfiguraion.ServiceName,
reRoute.ServiceProviderConfiguraion.DownstreamHost,
reRoute.ServiceProviderConfiguraion.DownstreamPort,
reRoute.ServiceProviderConfiguraion.UseServiceDiscovery,
reRoute.ServiceProviderConfiguraion.ServiceDiscoveryProvider,
reRoute.ServiceProviderConfiguraion.ServiceProviderHost,
reRoute.ServiceProviderConfiguraion.ServiceProviderPort);
var serviceProvider = _serviceProviderFactory.Get(serviceConfig);
var serviceProvider = _serviceProviderFactory.Get(reRoute.ServiceProviderConfiguraion);
switch (reRoute.LoadBalancer)
{

View File

@ -1,8 +1,8 @@
namespace Ocelot.Values
{
public class DownstreamPathTemplate
public class PathTemplate
{
public DownstreamPathTemplate(string value)
public PathTemplate(string value)
{
Value = value;
}

BIN
test/.DS_Store vendored

Binary file not shown.

View File

@ -47,7 +47,7 @@ namespace Ocelot.AcceptanceTests
DownstreamPort = _downstreamServicePort,
DownstreamHost = _downstreamServiceHost,
DownstreamScheme = _downstreamServiceScheme,
UpstreamTemplate = "/",
UpstreamPathTemplate = "/",
UpstreamHttpMethod = "Post",
AuthenticationOptions = new FileAuthenticationOptions
{
@ -85,7 +85,7 @@ namespace Ocelot.AcceptanceTests
DownstreamPort = _downstreamServicePort,
DownstreamHost = _downstreamServiceHost,
DownstreamScheme = _downstreamServiceScheme,
UpstreamTemplate = "/",
UpstreamPathTemplate = "/",
UpstreamHttpMethod = "Post",
AuthenticationOptions = new FileAuthenticationOptions
{
@ -123,7 +123,7 @@ namespace Ocelot.AcceptanceTests
DownstreamPort = _downstreamServicePort,
DownstreamHost = _downstreamServiceHost,
DownstreamScheme = _downstreamServiceScheme,
UpstreamTemplate = "/",
UpstreamPathTemplate = "/",
UpstreamHttpMethod = "Get",
AuthenticationOptions = new FileAuthenticationOptions
{
@ -163,7 +163,7 @@ namespace Ocelot.AcceptanceTests
DownstreamPort = _downstreamServicePort,
DownstreamHost = _downstreamServiceHost,
DownstreamScheme = _downstreamServiceScheme,
UpstreamTemplate = "/",
UpstreamPathTemplate = "/",
UpstreamHttpMethod = "Post",
AuthenticationOptions = new FileAuthenticationOptions
@ -204,7 +204,7 @@ namespace Ocelot.AcceptanceTests
DownstreamPort = _downstreamServicePort,
DownstreamHost = _downstreamServiceHost,
DownstreamScheme = _downstreamServiceScheme,
UpstreamTemplate = "/",
UpstreamPathTemplate = "/",
UpstreamHttpMethod = "Post",
AuthenticationOptions = new FileAuthenticationOptions
{

View File

@ -41,7 +41,7 @@ namespace Ocelot.AcceptanceTests
DownstreamPort = 51876,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/",
UpstreamPathTemplate = "/",
UpstreamHttpMethod = "Get",
AuthenticationOptions = new FileAuthenticationOptions
{
@ -98,7 +98,7 @@ namespace Ocelot.AcceptanceTests
DownstreamPort = 51876,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/",
UpstreamPathTemplate = "/",
UpstreamHttpMethod = "Get",
AuthenticationOptions = new FileAuthenticationOptions
{

View File

@ -35,7 +35,7 @@ namespace Ocelot.AcceptanceTests
DownstreamPort = 51879,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/",
UpstreamPathTemplate = "/",
UpstreamHttpMethod = "Get",
FileCacheOptions = new FileCacheOptions
{
@ -71,7 +71,7 @@ namespace Ocelot.AcceptanceTests
DownstreamPort = 51879,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/",
UpstreamPathTemplate = "/",
UpstreamHttpMethod = "Get",
FileCacheOptions = new FileCacheOptions
{

View File

@ -34,7 +34,7 @@ namespace Ocelot.AcceptanceTests
DownstreamPort = 51879,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/products/{productId}",
UpstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get",
}
}
@ -61,7 +61,7 @@ namespace Ocelot.AcceptanceTests
DownstreamPort = 51879,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/products/{productId}",
UpstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = false,
}
@ -89,7 +89,7 @@ namespace Ocelot.AcceptanceTests
DownstreamPort = 51879,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/products/{productId}",
UpstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = true,
}
@ -117,7 +117,7 @@ namespace Ocelot.AcceptanceTests
DownstreamPort = 51879,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/PRODUCTS/{productId}",
UpstreamPathTemplate = "/PRODUCTS/{productId}",
UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = true,
}
@ -145,7 +145,7 @@ namespace Ocelot.AcceptanceTests
DownstreamPort = 51879,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/products/{productId}",
UpstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = true,
}
@ -173,7 +173,7 @@ namespace Ocelot.AcceptanceTests
DownstreamPort = 51879,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/PRODUCTS/{productId}",
UpstreamPathTemplate = "/PRODUCTS/{productId}",
UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = true,
}

View File

@ -55,7 +55,7 @@ namespace Ocelot.AcceptanceTests
DownstreamPort = 52876,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/",
UpstreamPathTemplate = "/",
UpstreamHttpMethod = "Get",
AuthenticationOptions = new FileAuthenticationOptions
{

View File

@ -55,7 +55,7 @@ namespace Ocelot.AcceptanceTests
DownstreamPort = 57876,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/",
UpstreamPathTemplate = "/",
UpstreamHttpMethod = "Get",
AuthenticationOptions = new FileAuthenticationOptions
{

View File

@ -49,7 +49,7 @@ namespace Ocelot.AcceptanceTests
DownstreamPort = 41879,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/",
UpstreamPathTemplate = "/",
UpstreamHttpMethod = "Get",
}
}
@ -86,7 +86,7 @@ namespace Ocelot.AcceptanceTests
DownstreamPort = 41879,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/",
UpstreamPathTemplate = "/",
UpstreamHttpMethod = "Get",
}
@ -124,7 +124,7 @@ namespace Ocelot.AcceptanceTests
DownstreamPort = 41879,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/",
UpstreamPathTemplate = "/",
UpstreamHttpMethod = "Get",
}
@ -162,7 +162,7 @@ namespace Ocelot.AcceptanceTests
DownstreamPort = 41879,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/",
UpstreamPathTemplate = "/",
UpstreamHttpMethod = "Get",
}
}
@ -199,7 +199,7 @@ namespace Ocelot.AcceptanceTests
DownstreamPort = 41879,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/",
UpstreamPathTemplate = "/",
UpstreamHttpMethod = "Get",
}
}
@ -236,7 +236,7 @@ namespace Ocelot.AcceptanceTests
DownstreamPort = 41879,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/",
UpstreamPathTemplate = "/",
UpstreamHttpMethod = "Get",
}
}

View File

@ -37,7 +37,7 @@ namespace Ocelot.AcceptanceTests
DownstreamPort = 51879,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/",
UpstreamPathTemplate = "/",
UpstreamHttpMethod = "Get",
RequestIdKey = _steps.RequestIdKey,
}
@ -65,7 +65,7 @@ namespace Ocelot.AcceptanceTests
DownstreamPort = 51879,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/",
UpstreamPathTemplate = "/",
UpstreamHttpMethod = "Get",
}
@ -95,8 +95,8 @@ namespace Ocelot.AcceptanceTests
DownstreamPort = 51879,
DownstreamScheme = "http",
DownstreamHost = "localhost",
UpstreamTemplate = "/",
UpstreamHttpMethod ="Get"
UpstreamPathTemplate = "/",
UpstreamHttpMethod = "Get",
}
},
GlobalConfiguration = new FileGlobalConfiguration

View File

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

View File

@ -44,7 +44,7 @@ namespace Ocelot.AcceptanceTests
DownstreamScheme = "http",
DownstreamHost = "localhost",
DownstreamPort = 51879,
UpstreamTemplate = "/",
UpstreamPathTemplate = "/",
UpstreamHttpMethod = "Get",
}
@ -73,7 +73,7 @@ namespace Ocelot.AcceptanceTests
DownstreamScheme = "http",
DownstreamHost = "localhost",
DownstreamPort = 51879,
UpstreamTemplate = "/",
UpstreamPathTemplate = "/",
UpstreamHttpMethod = "Get",
}
@ -102,7 +102,7 @@ namespace Ocelot.AcceptanceTests
DownstreamScheme = "http",
DownstreamHost = "localhost/",
DownstreamPort = 51879,
UpstreamTemplate = "/",
UpstreamPathTemplate = "/",
UpstreamHttpMethod = "Get",
}
@ -131,7 +131,7 @@ namespace Ocelot.AcceptanceTests
DownstreamScheme = "http",
DownstreamHost = "localhost",
DownstreamPort = 51879,
UpstreamTemplate = "/products/",
UpstreamPathTemplate = "/products/",
UpstreamHttpMethod = "Get",
}
@ -160,9 +160,8 @@ namespace Ocelot.AcceptanceTests
DownstreamScheme = "http",
DownstreamHost = "localhost",
DownstreamPort = 51879,
UpstreamTemplate = "/products",
UpstreamPathTemplate = "/products",
UpstreamHttpMethod = "Get",
}
}
};
@ -189,13 +188,14 @@ namespace Ocelot.AcceptanceTests
DownstreamScheme = "http",
DownstreamHost = "localhost",
DownstreamPort = 51879,
UpstreamTemplate = "/products/{productId}",
UpstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get",
QoSOptions = new FileQoSOptions()
{
ExceptionsAllowedBeforeBreaking = 3,
DurationOfBreak =5,
TimeoutValue = 5000 }
DurationOfBreak = 5,
TimeoutValue = 5000
}
}
}
};
@ -221,7 +221,7 @@ namespace Ocelot.AcceptanceTests
DownstreamScheme = "http",
DownstreamHost = "localhost",
DownstreamPort = 51879,
UpstreamTemplate = "/products/{productId}",
UpstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get",
}
}
@ -249,7 +249,7 @@ namespace Ocelot.AcceptanceTests
DownstreamHost = "localhost",
DownstreamPort = 51879,
DownstreamScheme = "http",
UpstreamTemplate = "/",
UpstreamPathTemplate = "/",
UpstreamHttpMethod = "Post",
}
}
@ -274,7 +274,7 @@ namespace Ocelot.AcceptanceTests
new FileReRoute
{
DownstreamPathTemplate = "/newThing",
UpstreamTemplate = "/newThing",
UpstreamPathTemplate = "/newThing",
DownstreamScheme = "http",
DownstreamHost = "localhost",
DownstreamPort = 51879,

View File

@ -68,7 +68,7 @@ namespace Ocelot.AcceptanceTests
{
DownstreamPathTemplate = "/",
DownstreamScheme = "http",
UpstreamTemplate = "/",
UpstreamPathTemplate = "/",
UpstreamHttpMethod = "Get",
ServiceName = serviceName,
LoadBalancer = "LeastConnection",

View File

@ -1 +0,0 @@
{"ReRoutes":[{"DownstreamPathTemplate":"41879/","UpstreamTemplate":"/","UpstreamHttpMethod":"Get","AuthenticationOptions":{"Provider":null,"ProviderRootUrl":null,"ScopeName":null,"RequireHttps":false,"AdditionalScopes":[],"ScopeSecret":null},"AddHeadersToRequest":{},"AddClaimsToRequest":{},"RouteClaimsRequirement":{},"AddQueriesToRequest":{},"RequestIdKey":null,"FileCacheOptions":{"TtlSeconds":0},"ReRouteIsCaseSensitive":false,"ServiceName":null,"DownstreamScheme":"http","DownstreamHost":"localhost","DownstreamPort":41879,"QoSOptions":{"ExceptionsAllowedBeforeBreaking":0,"DurationOfBreak":0,"TimeoutValue":0},"LoadBalancer":null}],"GlobalConfiguration":{"RequestIdKey":null,"ServiceDiscoveryProvider":{"Provider":null,"Host":null,"Port":0}}}

View File

@ -6,6 +6,7 @@ using Moq;
using Ocelot.Authentication.Handler;
using Ocelot.Authentication.Handler.Creator;
using Ocelot.Authentication.Handler.Factory;
using Ocelot.Configuration.Builder;
using Ocelot.Errors;
using Ocelot.Responses;
using Shouldly;
@ -33,7 +34,11 @@ namespace Ocelot.UnitTests.Authentication
[Fact]
public void should_return_identity_server_access_token_handler()
{
this.Given(x => x.GivenTheAuthenticationOptionsAre(new AuthenticationOptions("IdentityServer", "","",false, new List<string>(), "")))
var authenticationOptions = new AuthenticationOptionsBuilder()
.WithProvider("IdentityServer")
.Build();
this.Given(x => x.GivenTheAuthenticationOptionsAre(authenticationOptions))
.And(x => x.GivenTheCreatorReturns())
.When(x => x.WhenIGetFromTheFactory())
.Then(x => x.ThenTheHandlerIsReturned("IdentityServer"))
@ -43,7 +48,10 @@ namespace Ocelot.UnitTests.Authentication
[Fact]
public void should_return_error_if_cannot_create_handler()
{
this.Given(x => x.GivenTheAuthenticationOptionsAre(new AuthenticationOptions("IdentityServer", "", "", false, new List<string>(), "")))
var authenticationOptions = new AuthenticationOptionsBuilder()
.Build();
this.Given(x => x.GivenTheAuthenticationOptionsAre(authenticationOptions))
.And(x => x.GivenTheCreatorReturnsAnError())
.When(x => x.WhenIGetFromTheFactory())
.Then(x => x.ThenAnErrorResponseIsReturned())
@ -58,7 +66,7 @@ namespace Ocelot.UnitTests.Authentication
private void GivenTheCreatorReturnsAnError()
{
_creator
.Setup(x => x.CreateIdentityServerAuthenticationHandler(It.IsAny<IApplicationBuilder>(), It.IsAny<AuthenticationOptions>()))
.Setup(x => x.Create(It.IsAny<IApplicationBuilder>(), It.IsAny<AuthenticationOptions>()))
.Returns(new ErrorResponse<RequestDelegate>(new List<Error>
{
new UnableToCreateAuthenticationHandlerError($"Unable to create authentication handler for xxx")
@ -68,7 +76,7 @@ namespace Ocelot.UnitTests.Authentication
private void GivenTheCreatorReturns()
{
_creator
.Setup(x => x.CreateIdentityServerAuthenticationHandler(It.IsAny<IApplicationBuilder>(), It.IsAny<AuthenticationOptions>()))
.Setup(x => x.Create(It.IsAny<IApplicationBuilder>(), It.IsAny<AuthenticationOptions>()))
.Returns(new OkResponse<RequestDelegate>(x => Task.CompletedTask));
}

View File

@ -71,7 +71,9 @@ namespace Ocelot.UnitTests.Authentication
[Fact]
public void should_call_next_middleware_if_route_is_not_authenticated()
{
this.Given(x => x.GivenTheDownStreamRouteIs(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), new ReRouteBuilder().Build())))
this.Given(x => x.GivenTheDownStreamRouteIs(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), new ReRouteBuilder()
.WithUpstreamHttpMethod("Get")
.Build())))
.When(x => x.WhenICallTheMiddleware())
.Then(x => x.ThenTheUserIsAuthenticated())
.BDDfy();

View File

@ -63,7 +63,11 @@ namespace Ocelot.UnitTests.Authorization
[Fact]
public void should_call_authorisation_service()
{
this.Given(x => x.GivenTheDownStreamRouteIs(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), new ReRouteBuilder().WithIsAuthorised(true).Build())))
this.Given(x => x.GivenTheDownStreamRouteIs(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithIsAuthorised(true)
.WithUpstreamHttpMethod("Get") .WithUpstreamHttpMethod("Get")
.Build())))
.And(x => x.GivenTheAuthServiceReturns(new OkResponse<bool>(true)))
.When(x => x.WhenICallTheMiddleware())
.Then(x => x.ThenTheAuthServiceIsCalledCorrectly())

View File

@ -87,7 +87,12 @@ namespace Ocelot.UnitTests.Cache
private void GivenTheDownstreamRouteIs()
{
var reRoute = new ReRouteBuilder().WithIsCached(true).WithCacheOptions(new CacheOptions(100)).Build();
var reRoute = new ReRouteBuilder()
.WithIsCached(true)
.WithCacheOptions(new CacheOptions(100))
.WithUpstreamHttpMethod("Get")
.Build();
var downstreamRoute = new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), reRoute);
_scopedRepo

View File

@ -72,6 +72,7 @@ namespace Ocelot.UnitTests.Claims
{
new ClaimToThing("sub", "UserType", "|", 0)
})
.WithUpstreamHttpMethod("Get")
.Build());
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))

View File

@ -29,7 +29,7 @@ namespace Ocelot.UnitTests.Configuration
new FileReRoute
{
DownstreamPathTemplate = "http://www.bbc.co.uk/api/products/{productId}",
UpstreamTemplate = "http://asdf.com"
UpstreamPathTemplate = "http://asdf.com"
}
}
}))
@ -48,7 +48,7 @@ namespace Ocelot.UnitTests.Configuration
new FileReRoute
{
DownstreamPathTemplate = "/api/products/",
UpstreamTemplate = "http://asdf.com"
UpstreamPathTemplate = "http://asdf.com"
}
}
}))
@ -67,7 +67,7 @@ namespace Ocelot.UnitTests.Configuration
new FileReRoute
{
DownstreamPathTemplate = "/api/products/",
UpstreamTemplate = "http://asdf.com",
UpstreamPathTemplate = "http://asdf.com",
AuthenticationOptions = new FileAuthenticationOptions
{
Provider = "IdentityServer"
@ -90,7 +90,7 @@ namespace Ocelot.UnitTests.Configuration
new FileReRoute
{
DownstreamPathTemplate = "/api/products/",
UpstreamTemplate = "http://asdf.com",
UpstreamPathTemplate = "http://asdf.com",
AuthenticationOptions = new FileAuthenticationOptions
{
Provider = "BootyBootyBottyRockinEverywhere"
@ -114,12 +114,12 @@ namespace Ocelot.UnitTests.Configuration
new FileReRoute
{
DownstreamPathTemplate = "/api/products/",
UpstreamTemplate = "http://asdf.com"
UpstreamPathTemplate = "http://asdf.com"
},
new FileReRoute
{
DownstreamPathTemplate = "http://www.bbc.co.uk",
UpstreamTemplate = "http://asdf.com"
UpstreamPathTemplate = "http://asdf.com"
}
}
}))

View File

@ -53,7 +53,7 @@ namespace Ocelot.UnitTests.Configuration
new FileReRoute
{
DownstreamHost = "127.0.0.1",
UpstreamTemplate = "/api/products/{productId}",
UpstreamPathTemplate = "/api/products/{productId}",
DownstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get",
}
@ -78,7 +78,7 @@ namespace Ocelot.UnitTests.Configuration
new FileReRoute
{
DownstreamHost = "127.0.0.1",
UpstreamTemplate = "/api/products/{productId}",
UpstreamPathTemplate = "/api/products/{productId}",
DownstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get",
}
@ -91,7 +91,7 @@ namespace Ocelot.UnitTests.Configuration
new ReRouteBuilder()
.WithDownstreamHost("127.0.0.1")
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamTemplate("/api/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("(?i)/api/products/.*/$")
.Build()
@ -109,7 +109,7 @@ namespace Ocelot.UnitTests.Configuration
new FileReRoute
{
DownstreamScheme = "https",
UpstreamTemplate = "/api/products/{productId}",
UpstreamPathTemplate = "/api/products/{productId}",
DownstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get",
}
@ -122,7 +122,7 @@ namespace Ocelot.UnitTests.Configuration
new ReRouteBuilder()
.WithDownstreamScheme("https")
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamTemplate("/api/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("(?i)/api/products/.*/$")
.Build()
@ -139,7 +139,7 @@ namespace Ocelot.UnitTests.Configuration
{
new FileReRoute
{
UpstreamTemplate = "/api/products/{productId}",
UpstreamPathTemplate = "/api/products/{productId}",
DownstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = false,
@ -161,13 +161,15 @@ namespace Ocelot.UnitTests.Configuration
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamTemplate("/api/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("(?i)/api/products/.*/$")
.WithServiceName("ProductService")
.WithServiceProviderConfiguraion(new ServiceProviderConfiguraionBuilder()
.WithUseServiceDiscovery(true)
.WithServiceDiscoveryProvider("consul")
.WithServiceDiscoveryAddress("127.0.01")
.WithServiceDiscoveryProviderHost("127.0.0.1")
.Build())
.Build()
}))
.BDDfy();
@ -182,7 +184,7 @@ namespace Ocelot.UnitTests.Configuration
{
new FileReRoute
{
UpstreamTemplate = "/api/products/{productId}",
UpstreamPathTemplate = "/api/products/{productId}",
DownstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = false,
@ -195,12 +197,12 @@ namespace Ocelot.UnitTests.Configuration
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamTemplate("/api/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("(?i)/api/products/.*/$")
.WithServiceProviderConfiguraion(new ServiceProviderConfiguraionBuilder()
.WithUseServiceDiscovery(false)
.WithServiceDiscoveryProvider(null)
.WithServiceDiscoveryAddress(null)
.Build())
.Build()
}))
.BDDfy();
@ -215,7 +217,7 @@ namespace Ocelot.UnitTests.Configuration
{
new FileReRoute
{
UpstreamTemplate = "/api/products/{productId}",
UpstreamPathTemplate = "/api/products/{productId}",
DownstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = false
@ -228,7 +230,7 @@ namespace Ocelot.UnitTests.Configuration
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamTemplate("/api/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("(?i)/api/products/.*/$")
.Build()
@ -245,7 +247,7 @@ namespace Ocelot.UnitTests.Configuration
{
new FileReRoute
{
UpstreamTemplate = "/api/products/{productId}",
UpstreamPathTemplate = "/api/products/{productId}",
DownstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get"
}
@ -257,7 +259,7 @@ namespace Ocelot.UnitTests.Configuration
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamTemplate("/api/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("(?i)/api/products/.*/$")
.Build()
@ -274,7 +276,7 @@ namespace Ocelot.UnitTests.Configuration
{
new FileReRoute
{
UpstreamTemplate = "/api/products/{productId}",
UpstreamPathTemplate = "/api/products/{productId}",
DownstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = true
@ -287,7 +289,7 @@ namespace Ocelot.UnitTests.Configuration
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamTemplate("/api/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("/api/products/.*/$")
.Build()
@ -304,7 +306,7 @@ namespace Ocelot.UnitTests.Configuration
{
new FileReRoute
{
UpstreamTemplate = "/api/products/{productId}",
UpstreamPathTemplate = "/api/products/{productId}",
DownstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = true
@ -321,7 +323,7 @@ namespace Ocelot.UnitTests.Configuration
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamTemplate("/api/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("/api/products/.*/$")
.WithRequestIdKey("blahhhh")
@ -339,7 +341,7 @@ namespace Ocelot.UnitTests.Configuration
{
new FileReRoute
{
UpstreamTemplate = "/api/products/{productId}",
UpstreamPathTemplate = "/api/products/{productId}",
DownstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = true
@ -352,7 +354,7 @@ namespace Ocelot.UnitTests.Configuration
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamTemplate("/api/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("/api/products/.*/$")
.Build()
@ -363,18 +365,23 @@ namespace Ocelot.UnitTests.Configuration
[Fact]
public void should_create_with_headers_to_extract()
{
var authenticationOptions = new AuthenticationOptionsBuilder()
.WithProvider("IdentityServer")
.WithProviderRootUrl("http://localhost:51888")
.WithRequireHttps(false)
.WithScopeSecret("secret")
.WithScopeName("api")
.WithAdditionalScopes(new List<string>())
.Build();
var expected = new List<ReRoute>
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamTemplate("/api/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("/api/products/.*/$")
.WithAuthenticationProvider("IdentityServer")
.WithAuthenticationProviderUrl("http://localhost:51888")
.WithRequireHttps(false)
.WithScopeSecret("secret")
.WithAuthenticationProviderScopeName("api")
.WithAuthenticationOptions(authenticationOptions)
.WithClaimsToHeaders(new List<ClaimToThing>
{
new ClaimToThing("CustomerId", "CustomerId", "", 0),
@ -388,7 +395,7 @@ namespace Ocelot.UnitTests.Configuration
{
new FileReRoute
{
UpstreamTemplate = "/api/products/{productId}",
UpstreamPathTemplate = "/api/products/{productId}",
DownstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = true,
@ -427,18 +434,23 @@ namespace Ocelot.UnitTests.Configuration
[Fact]
public void should_create_with_authentication_properties()
{
var authenticationOptions = new AuthenticationOptionsBuilder()
.WithProvider("IdentityServer")
.WithProviderRootUrl("http://localhost:51888")
.WithRequireHttps(false)
.WithScopeSecret("secret")
.WithScopeName("api")
.WithAdditionalScopes(new List<string>())
.Build();
var expected = new List<ReRoute>
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamTemplate("/api/products/{productId}")
.WithUpstreamPathTemplate("/api/products/{productId}")
.WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("/api/products/.*/$")
.WithAuthenticationProvider("IdentityServer")
.WithAuthenticationProviderUrl("http://localhost:51888")
.WithRequireHttps(false)
.WithScopeSecret("secret")
.WithAuthenticationProviderScopeName("api")
.WithAuthenticationOptions(authenticationOptions)
.Build()
};
@ -448,7 +460,7 @@ namespace Ocelot.UnitTests.Configuration
{
new FileReRoute
{
UpstreamTemplate = "/api/products/{productId}",
UpstreamPathTemplate = "/api/products/{productId}",
DownstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = true,
@ -481,7 +493,7 @@ namespace Ocelot.UnitTests.Configuration
{
new FileReRoute
{
UpstreamTemplate = "/api/products/{productId}/variants/{variantId}",
UpstreamPathTemplate = "/api/products/{productId}/variants/{variantId}",
DownstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = true
@ -494,7 +506,7 @@ namespace Ocelot.UnitTests.Configuration
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamTemplate("/api/products/{productId}/variants/{variantId}")
.WithUpstreamPathTemplate("/api/products/{productId}/variants/{variantId}")
.WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("/api/products/.*/variants/.*/$")
.Build()
@ -511,7 +523,7 @@ namespace Ocelot.UnitTests.Configuration
{
new FileReRoute
{
UpstreamTemplate = "/api/products/{productId}/variants/{variantId}/",
UpstreamPathTemplate = "/api/products/{productId}/variants/{variantId}/",
DownstreamPathTemplate = "/products/{productId}",
UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = true
@ -524,7 +536,7 @@ namespace Ocelot.UnitTests.Configuration
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("/products/{productId}")
.WithUpstreamTemplate("/api/products/{productId}/variants/{variantId}/")
.WithUpstreamPathTemplate("/api/products/{productId}/variants/{variantId}/")
.WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("/api/products/.*/variants/.*/$")
.Build()
@ -541,7 +553,7 @@ namespace Ocelot.UnitTests.Configuration
{
new FileReRoute
{
UpstreamTemplate = "/",
UpstreamPathTemplate = "/",
DownstreamPathTemplate = "/api/products/",
UpstreamHttpMethod = "Get",
ReRouteIsCaseSensitive = true
@ -554,7 +566,7 @@ namespace Ocelot.UnitTests.Configuration
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("/api/products/")
.WithUpstreamTemplate("/")
.WithUpstreamPathTemplate("/")
.WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("/$")
.Build()
@ -591,7 +603,7 @@ namespace Ocelot.UnitTests.Configuration
result.DownstreamPathTemplate.Value.ShouldBe(expected.DownstreamPathTemplate.Value);
result.UpstreamHttpMethod.ShouldBe(expected.UpstreamHttpMethod);
result.UpstreamTemplate.ShouldBe(expected.UpstreamTemplate);
result.UpstreamPathTemplate.Value.ShouldBe(expected.UpstreamPathTemplate.Value);
result.UpstreamTemplatePattern.ShouldBe(expected.UpstreamTemplatePattern);
}
}

View File

@ -84,7 +84,10 @@ namespace Ocelot.UnitTests.Configuration
public List<ReRoute> ReRoutes => new List<ReRoute>
{
new ReRouteBuilder().WithDownstreamPathTemplate(_downstreamTemplatePath).Build()
new ReRouteBuilder()
.WithDownstreamPathTemplate(_downstreamTemplatePath)
.WithUpstreamHttpMethod("Get")
.Build()
};
}
}

View File

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

View File

@ -45,7 +45,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamTemplate("someUpstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("someUpstreamPath")
.Build()
@ -58,6 +58,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamHttpMethod("Get")
.Build()
)))
.And(x => x.ThenTheUrlMatcherIsCalledCorrectly())
@ -76,13 +77,13 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPath")
.WithUpstreamTemplate("someUpstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("")
.Build(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPathForAPost")
.WithUpstreamTemplate("someUpstreamPath")
.WithUpstreamPathTemplate("someUpstreamPath")
.WithUpstreamHttpMethod("Post")
.WithUpstreamTemplatePattern("")
.Build()
@ -95,6 +96,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
x => x.ThenTheFollowingIsReturned(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("someDownstreamPathForAPost")
.WithUpstreamHttpMethod("Post")
.Build()
)))
.BDDfy();
@ -108,7 +110,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
{
new ReRouteBuilder()
.WithDownstreamPathTemplate("somPath")
.WithUpstreamTemplate("somePath")
.WithUpstreamPathTemplate("somePath")
.WithUpstreamHttpMethod("Get")
.WithUpstreamTemplatePattern("somePath")
.Build(),
@ -143,7 +145,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
private void ThenTheUrlMatcherIsCalledCorrectly()
{
_mockMatcher
.Verify(x => x.Match(_upstreamUrlPath, _reRoutesConfig[0].UpstreamTemplate), Times.Once);
.Verify(x => x.Match(_upstreamUrlPath, _reRoutesConfig[0].UpstreamPathTemplate.Value), Times.Once);
}
private void GivenTheUrlMatcherReturns(Response<UrlMatch> match)

View File

@ -72,7 +72,13 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator
{
var hostAndPort = new HostAndPort("127.0.0.1", 80);
this.Given(x => x.GivenTheDownStreamRouteIs(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), new ReRouteBuilder().WithDownstreamPathTemplate("any old string").Build())))
this.Given(x => x.GivenTheDownStreamRouteIs(
new DownstreamRoute(
new List<UrlPathPlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("any old string")
.WithUpstreamHttpMethod("Get")
.Build())))
.And(x => x.GivenTheHostAndPortIs(hostAndPort))
.And(x => x.TheUrlReplacerReturns("/api/products/1"))
.And(x => x.TheUrlBuilderReturns("http://127.0.0.1:80/api/products/1"))
@ -101,7 +107,7 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator
{
_downstreamPath = new OkResponse<DownstreamPath>(new DownstreamPath(downstreamUrl));
_downstreamUrlTemplateVariableReplacer
.Setup(x => x.Replace(It.IsAny<DownstreamPathTemplate>(), It.IsAny<List<UrlPathPlaceholderNameAndValue>>()))
.Setup(x => x.Replace(It.IsAny<PathTemplate>(), It.IsAny<List<UrlPathPlaceholderNameAndValue>>()))
.Returns(_downstreamPath);
}

View File

@ -25,7 +25,12 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
[Fact]
public void can_replace_no_template_variables()
{
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), new ReRouteBuilder().Build())))
this.Given(x => x.GivenThereIsAUrlMatch(
new DownstreamRoute(
new List<UrlPathPlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithUpstreamHttpMethod("Get")
.Build())))
.When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheDownstreamUrlPathIsReturned(""))
.BDDfy();
@ -34,7 +39,13 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
[Fact]
public void can_replace_no_template_variables_with_slash()
{
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), new ReRouteBuilder().WithDownstreamPathTemplate("/").Build())))
this.Given(x => x.GivenThereIsAUrlMatch(
new DownstreamRoute(
new List<UrlPathPlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("/")
.WithUpstreamHttpMethod("Get")
.Build())))
.When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("/"))
.BDDfy();
@ -43,7 +54,11 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
[Fact]
public void can_replace_url_no_slash()
{
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), new ReRouteBuilder().WithDownstreamPathTemplate("api").Build())))
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("api")
.WithUpstreamHttpMethod("Get")
.Build())))
.When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("api"))
.BDDfy();
@ -52,7 +67,11 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
[Fact]
public void can_replace_url_one_slash()
{
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), new ReRouteBuilder().WithDownstreamPathTemplate("api/").Build())))
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("api/")
.WithUpstreamHttpMethod("Get")
.Build())))
.When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("api/"))
.BDDfy();
@ -61,7 +80,11 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
[Fact]
public void can_replace_url_multiple_slash()
{
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(), new ReRouteBuilder().WithDownstreamPathTemplate("api/product/products/").Build())))
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("api/product/products/")
.WithUpstreamHttpMethod("Get")
.Build())))
.When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("api/product/products/"))
.BDDfy();
@ -75,7 +98,11 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
new UrlPathPlaceholderNameAndValue("{productId}", "1")
};
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables, new ReRouteBuilder().WithDownstreamPathTemplate("productservice/products/{productId}/").Build())))
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables,
new ReRouteBuilder()
.WithDownstreamPathTemplate("productservice/products/{productId}/")
.WithUpstreamHttpMethod("Get")
.Build())))
.When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/products/1/"))
.BDDfy();
@ -89,7 +116,11 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
new UrlPathPlaceholderNameAndValue("{productId}", "1")
};
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables, new ReRouteBuilder().WithDownstreamPathTemplate("productservice/products/{productId}/variants").Build())))
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables,
new ReRouteBuilder()
.WithDownstreamPathTemplate("productservice/products/{productId}/variants")
.WithUpstreamHttpMethod("Get")
.Build())))
.When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/products/1/variants"))
.BDDfy();
@ -104,7 +135,11 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
new UrlPathPlaceholderNameAndValue("{variantId}", "12")
};
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables, new ReRouteBuilder().WithDownstreamPathTemplate("productservice/products/{productId}/variants/{variantId}").Build())))
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables,
new ReRouteBuilder()
.WithDownstreamPathTemplate("productservice/products/{productId}/variants/{variantId}")
.WithUpstreamHttpMethod("Get")
.Build())))
.When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/products/1/variants/12"))
.BDDfy();
@ -120,7 +155,11 @@ namespace Ocelot.UnitTests.DownstreamUrlCreator.UrlTemplateReplacer
new UrlPathPlaceholderNameAndValue("{categoryId}", "34")
};
this.Given(x => x.GivenThereIsAUrlMatch(new DownstreamRoute(templateVariables, new ReRouteBuilder().WithDownstreamPathTemplate("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}")
.WithUpstreamHttpMethod("Get")
.Build())))
.When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/category/34/products/1/variants/12"))
.BDDfy();

View File

@ -72,6 +72,7 @@ namespace Ocelot.UnitTests.Headers
{
new ClaimToThing("UserId", "Subject", "", 0)
})
.WithUpstreamHttpMethod("Get")
.Build());
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))

View File

@ -24,17 +24,12 @@ namespace Ocelot.UnitTests.LoadBalancer
_factory = new LoadBalancerFactory(_serviceProviderFactory.Object);
}
private void GivenTheServiceProviderFactoryReturns()
{
_serviceProviderFactory
.Setup(x => x.Get(It.IsAny<ServiceProviderConfiguraion>()))
.Returns(_serviceProvider.Object);
}
[Fact]
public void should_return_no_load_balancer()
{
var reRoute = new ReRouteBuilder()
.WithServiceProviderConfiguraion(new ServiceProviderConfiguraionBuilder().Build())
.WithUpstreamHttpMethod("Get")
.Build();
this.Given(x => x.GivenAReRoute(reRoute))
@ -49,6 +44,8 @@ namespace Ocelot.UnitTests.LoadBalancer
{
var reRoute = new ReRouteBuilder()
.WithLoadBalancer("RoundRobin")
.WithUpstreamHttpMethod("Get")
.WithServiceProviderConfiguraion(new ServiceProviderConfiguraionBuilder().Build())
.Build();
this.Given(x => x.GivenAReRoute(reRoute))
@ -63,6 +60,8 @@ namespace Ocelot.UnitTests.LoadBalancer
{
var reRoute = new ReRouteBuilder()
.WithLoadBalancer("LeastConnection")
.WithUpstreamHttpMethod("Get")
.WithServiceProviderConfiguraion(new ServiceProviderConfiguraionBuilder().Build())
.Build();
this.Given(x => x.GivenAReRoute(reRoute))
@ -77,6 +76,8 @@ namespace Ocelot.UnitTests.LoadBalancer
{
var reRoute = new ReRouteBuilder()
.WithLoadBalancer("RoundRobin")
.WithUpstreamHttpMethod("Get")
.WithServiceProviderConfiguraion(new ServiceProviderConfiguraionBuilder().Build())
.Build();
this.Given(x => x.GivenAReRoute(reRoute))
@ -86,6 +87,13 @@ namespace Ocelot.UnitTests.LoadBalancer
.BDDfy();
}
private void GivenTheServiceProviderFactoryReturns()
{
_serviceProviderFactory
.Setup(x => x.Get(It.IsAny<ServiceProviderConfiguraion>()))
.Returns(_serviceProvider.Object);
}
private void ThenTheServiceProviderIsCalledCorrectly()
{
_serviceProviderFactory

View File

@ -68,6 +68,7 @@ namespace Ocelot.UnitTests.LoadBalancer
{
var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.UrlPathPlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithUpstreamHttpMethod("Get")
.Build());
this.Given(x => x.GivenTheDownStreamUrlIs("any old string"))
@ -84,6 +85,7 @@ namespace Ocelot.UnitTests.LoadBalancer
{
var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.UrlPathPlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithUpstreamHttpMethod("Get")
.Build());
this.Given(x => x.GivenTheDownStreamUrlIs("any old string"))
@ -99,6 +101,7 @@ namespace Ocelot.UnitTests.LoadBalancer
{
var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.UrlPathPlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithUpstreamHttpMethod("Get")
.Build());
this.Given(x => x.GivenTheDownStreamUrlIs("any old string"))

View File

@ -70,6 +70,7 @@ namespace Ocelot.UnitTests.QueryStrings
{
new ClaimToThing("UserId", "Subject", "", 0)
})
.WithUpstreamHttpMethod("Get")
.Build());
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))

View File

@ -68,7 +68,9 @@ namespace Ocelot.UnitTests.Request
var downstreamRoute = new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithRequestIdKey("LSRequestId").Build());
.WithRequestIdKey("LSRequestId")
.WithUpstreamHttpMethod("Get")
.Build());
this.Given(x => x.GivenTheDownStreamUrlIs("any old string"))

View File

@ -72,7 +72,9 @@ namespace Ocelot.UnitTests.RequestId
var downstreamRoute = new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("any old string")
.WithRequestIdKey("LSRequestId").Build());
.WithRequestIdKey("LSRequestId")
.WithUpstreamHttpMethod("Get")
.Build());
var requestId = Guid.NewGuid().ToString();
@ -89,7 +91,9 @@ namespace Ocelot.UnitTests.RequestId
var downstreamRoute = new DownstreamRoute(new List<UrlPathPlaceholderNameAndValue>(),
new ReRouteBuilder()
.WithDownstreamPathTemplate("any old string")
.WithRequestIdKey("LSRequestId").Build());
.WithRequestIdKey("LSRequestId")
.WithUpstreamHttpMethod("Get")
.Build());
this.Given(x => x.GivenTheDownStreamRouteIs(downstreamRoute))
.When(x => x.WhenICallTheMiddleware())

View File

@ -1,7 +1,4 @@
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using Microsoft.AspNetCore.Http;
using Ocelot.Errors;
using Ocelot.Middleware;
using Ocelot.Responder;

View File

@ -1,4 +1,5 @@
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.ServiceDiscovery;
using Shouldly;
using TestStack.BDDfy;
@ -20,7 +21,11 @@ namespace Ocelot.UnitTests.ServiceDiscovery
[Fact]
public void should_return_no_service_provider()
{
var serviceConfig = new ServiceProviderConfiguraion("product", "127.0.0.1", 80, false, "Does not matter", string.Empty, 0);
var serviceConfig = new ServiceProviderConfiguraionBuilder()
.WithDownstreamHost("127.0.0.1")
.WithDownstreamPort(80)
.WithUseServiceDiscovery(false)
.Build();
this.Given(x => x.GivenTheReRoute(serviceConfig))
.When(x => x.WhenIGetTheServiceProvider())
@ -31,7 +36,11 @@ namespace Ocelot.UnitTests.ServiceDiscovery
[Fact]
public void should_return_consul_service_provider()
{
var serviceConfig = new ServiceProviderConfiguraion("product", string.Empty, 0, true, "Consul", string.Empty, 0);
var serviceConfig = new ServiceProviderConfiguraionBuilder()
.WithServiceName("product")
.WithUseServiceDiscovery(true)
.WithServiceDiscoveryProvider("Consul")
.Build();
this.Given(x => x.GivenTheReRoute(serviceConfig))
.When(x => x.WhenIGetTheServiceProvider())