hacked together load balancing reroutes in fileconfig (#211)

* hacked together load balancing reroutes in fileconfig

* some renaming and refactoring

* more renames

* hacked away the old config json

* test for issue 213

* renamed key

* dont share ports

* oops

* updated docs

* mvoed docs around

* port being used
This commit is contained in:
Tom Pallister
2018-01-31 20:34:55 +00:00
committed by GitHub
parent f572d1b0ca
commit 3ac9b3bd87
440 changed files with 29740 additions and 28464 deletions

View File

@ -1,16 +1,16 @@
using Newtonsoft.Json;
namespace Ocelot.Authentication
{
class BearerToken
{
[JsonProperty("access_token")]
public string AccessToken { get; set; }
[JsonProperty("expires_in")]
public int ExpiresIn { get; set; }
[JsonProperty("token_type")]
public string TokenType { get; set; }
}
using Newtonsoft.Json;
namespace Ocelot.Authentication
{
class BearerToken
{
[JsonProperty("access_token")]
public string AccessToken { get; set; }
[JsonProperty("expires_in")]
public int ExpiresIn { get; set; }
[JsonProperty("token_type")]
public string TokenType { get; set; }
}
}

View File

@ -1,8 +1,8 @@
namespace Ocelot.Authentication.Handler
{
public enum SupportedAuthenticationProviders
{
IdentityServer,
Jwt
}
}
namespace Ocelot.Authentication.Handler
{
public enum SupportedAuthenticationProviders
{
IdentityServer,
Jwt
}
}

View File

@ -1,12 +1,12 @@
using Microsoft.AspNetCore.Builder;
namespace Ocelot.Authentication.Middleware
{
public static class AuthenticationMiddlewareMiddlewareExtensions
{
public static IApplicationBuilder UseAuthenticationMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<AuthenticationMiddleware>(builder);
}
}
using Microsoft.AspNetCore.Builder;
namespace Ocelot.Authentication.Middleware
{
public static class AuthenticationMiddlewareMiddlewareExtensions
{
public static IApplicationBuilder UseAuthenticationMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<AuthenticationMiddleware>(builder);
}
}
}

View File

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

View File

@ -1,53 +1,53 @@
using System.Collections.Generic;
using System.Security.Claims;
using Ocelot.Errors;
using Ocelot.Responses;
namespace Ocelot.Authorisation
{
using Infrastructure.Claims.Parser;
public class ClaimsAuthoriser : IClaimsAuthoriser
{
private readonly IClaimsParser _claimsParser;
public ClaimsAuthoriser(IClaimsParser claimsParser)
{
_claimsParser = claimsParser;
}
public Response<bool> Authorise(ClaimsPrincipal claimsPrincipal, Dictionary<string, string> routeClaimsRequirement)
{
foreach (var required in routeClaimsRequirement)
{
var value = _claimsParser.GetValue(claimsPrincipal.Claims, required.Key, string.Empty, 0);
if (value.IsError)
{
return new ErrorResponse<bool>(value.Errors);
}
if (value.Data != null)
{
var authorised = value.Data == required.Value;
if (!authorised)
{
return new ErrorResponse<bool>(new List<Error>
{
new ClaimValueNotAuthorisedError(
$"claim value: {value.Data} is not the same as required value: {required.Value} for type: {required.Key}")
});
}
}
else
{
return new ErrorResponse<bool>(new List<Error>
{
new UserDoesNotHaveClaimError($"user does not have claim {required.Key}")
});
}
}
return new OkResponse<bool>(true);
}
}
using System.Collections.Generic;
using System.Security.Claims;
using Ocelot.Errors;
using Ocelot.Responses;
namespace Ocelot.Authorisation
{
using Infrastructure.Claims.Parser;
public class ClaimsAuthoriser : IClaimsAuthoriser
{
private readonly IClaimsParser _claimsParser;
public ClaimsAuthoriser(IClaimsParser claimsParser)
{
_claimsParser = claimsParser;
}
public Response<bool> Authorise(ClaimsPrincipal claimsPrincipal, Dictionary<string, string> routeClaimsRequirement)
{
foreach (var required in routeClaimsRequirement)
{
var value = _claimsParser.GetValue(claimsPrincipal.Claims, required.Key, string.Empty, 0);
if (value.IsError)
{
return new ErrorResponse<bool>(value.Errors);
}
if (value.Data != null)
{
var authorised = value.Data == required.Value;
if (!authorised)
{
return new ErrorResponse<bool>(new List<Error>
{
new ClaimValueNotAuthorisedError(
$"claim value: {value.Data} is not the same as required value: {required.Value} for type: {required.Key}")
});
}
}
else
{
return new ErrorResponse<bool>(new List<Error>
{
new UserDoesNotHaveClaimError($"user does not have claim {required.Key}")
});
}
}
return new OkResponse<bool>(true);
}
}
}

View File

@ -1,12 +1,12 @@
using System.Security.Claims;
using Ocelot.Responses;
namespace Ocelot.Authorisation
{
using System.Collections.Generic;
public interface IClaimsAuthoriser
{
Response<bool> Authorise(ClaimsPrincipal claimsPrincipal, Dictionary<string, string> routeClaimsRequirement);
}
}
using System.Security.Claims;
using Ocelot.Responses;
namespace Ocelot.Authorisation
{
using System.Collections.Generic;
public interface IClaimsAuthoriser
{
Response<bool> Authorise(ClaimsPrincipal claimsPrincipal, Dictionary<string, string> routeClaimsRequirement);
}
}

View File

@ -1,12 +1,12 @@
using System.Security.Claims;
using Ocelot.Responses;
namespace Ocelot.Authorisation
{
using System.Collections.Generic;
public interface IScopesAuthoriser
{
Response<bool> Authorise(ClaimsPrincipal claimsPrincipal, List<string> routeAllowedScopes);
}
}
using System.Security.Claims;
using Ocelot.Responses;
namespace Ocelot.Authorisation
{
using System.Collections.Generic;
public interface IScopesAuthoriser
{
Response<bool> Authorise(ClaimsPrincipal claimsPrincipal, List<string> routeAllowedScopes);
}
}

View File

@ -1,117 +1,117 @@
using Ocelot.Infrastructure.RequestData;
using Ocelot.Logging;
using Ocelot.Responses;
using Ocelot.Configuration;
namespace Ocelot.Authorisation.Middleware
{
using System.Collections.Generic;
using System.Threading.Tasks;
using Errors;
using Microsoft.AspNetCore.Http;
using Ocelot.Middleware;
public class AuthorisationMiddleware : OcelotMiddleware
{
private readonly RequestDelegate _next;
private readonly IClaimsAuthoriser _claimsAuthoriser;
private readonly IScopesAuthoriser _scopesAuthoriser;
private readonly IOcelotLogger _logger;
public AuthorisationMiddleware(RequestDelegate next,
IRequestScopedDataRepository requestScopedDataRepository,
IClaimsAuthoriser claimsAuthoriser,
IScopesAuthoriser scopesAuthoriser,
IOcelotLoggerFactory loggerFactory)
: base(requestScopedDataRepository)
{
_next = next;
_claimsAuthoriser = claimsAuthoriser;
_scopesAuthoriser = scopesAuthoriser;
_logger = loggerFactory.CreateLogger<AuthorisationMiddleware>();
}
public async Task Invoke(HttpContext context)
{
if (IsAuthenticatedRoute(DownstreamRoute.ReRoute))
{
_logger.LogDebug("route is authenticated scopes must be checked");
var authorised = _scopesAuthoriser.Authorise(context.User, DownstreamRoute.ReRoute.AuthenticationOptions.AllowedScopes);
if (authorised.IsError)
{
_logger.LogDebug("error authorising user scopes");
SetPipelineError(authorised.Errors);
return;
}
if (IsAuthorised(authorised))
{
_logger.LogDebug("user scopes is authorised calling next authorisation checks");
}
else
{
_logger.LogDebug("user scopes is not authorised setting pipeline error");
SetPipelineError(new List<Error>
{
new UnauthorisedError(
$"{context.User.Identity.Name} unable to access {DownstreamRoute.ReRoute.UpstreamPathTemplate.Value}")
});
}
}
if (IsAuthorisedRoute(DownstreamRoute.ReRoute))
{
_logger.LogDebug("route is authorised");
var authorised = _claimsAuthoriser.Authorise(context.User, DownstreamRoute.ReRoute.RouteClaimsRequirement);
if (authorised.IsError)
{
_logger.LogDebug($"Error whilst authorising {context.User.Identity.Name} for {context.User.Identity.Name}. Setting pipeline error");
SetPipelineError(authorised.Errors);
return;
}
if (IsAuthorised(authorised))
{
_logger.LogDebug($"{context.User.Identity.Name} has succesfully been authorised for {DownstreamRoute.ReRoute.UpstreamPathTemplate.Value}. Calling next middleware");
await _next.Invoke(context);
}
else
{
_logger.LogDebug($"{context.User.Identity.Name} is not authorised to access {DownstreamRoute.ReRoute.UpstreamPathTemplate.Value}. Setting pipeline error");
SetPipelineError(new List<Error>
{
new UnauthorisedError($"{context.User.Identity.Name} is not authorised to access {DownstreamRoute.ReRoute.UpstreamPathTemplate.Value}")
});
}
}
else
{
_logger.LogDebug($"{DownstreamRoute.ReRoute.DownstreamPathTemplate.Value} route does not require user to be authorised");
await _next.Invoke(context);
}
}
private static bool IsAuthorised(Response<bool> authorised)
{
return authorised.Data;
}
private static bool IsAuthenticatedRoute(ReRoute reRoute)
{
return reRoute.IsAuthenticated;
}
private static bool IsAuthorisedRoute(ReRoute reRoute)
{
return reRoute.IsAuthorised;
}
}
}
using Ocelot.Infrastructure.RequestData;
using Ocelot.Logging;
using Ocelot.Responses;
using Ocelot.Configuration;
namespace Ocelot.Authorisation.Middleware
{
using System.Collections.Generic;
using System.Threading.Tasks;
using Errors;
using Microsoft.AspNetCore.Http;
using Ocelot.Middleware;
public class AuthorisationMiddleware : OcelotMiddleware
{
private readonly RequestDelegate _next;
private readonly IClaimsAuthoriser _claimsAuthoriser;
private readonly IScopesAuthoriser _scopesAuthoriser;
private readonly IOcelotLogger _logger;
public AuthorisationMiddleware(RequestDelegate next,
IRequestScopedDataRepository requestScopedDataRepository,
IClaimsAuthoriser claimsAuthoriser,
IScopesAuthoriser scopesAuthoriser,
IOcelotLoggerFactory loggerFactory)
: base(requestScopedDataRepository)
{
_next = next;
_claimsAuthoriser = claimsAuthoriser;
_scopesAuthoriser = scopesAuthoriser;
_logger = loggerFactory.CreateLogger<AuthorisationMiddleware>();
}
public async Task Invoke(HttpContext context)
{
if (IsAuthenticatedRoute(DownstreamRoute.ReRoute))
{
_logger.LogDebug("route is authenticated scopes must be checked");
var authorised = _scopesAuthoriser.Authorise(context.User, DownstreamRoute.ReRoute.AuthenticationOptions.AllowedScopes);
if (authorised.IsError)
{
_logger.LogDebug("error authorising user scopes");
SetPipelineError(authorised.Errors);
return;
}
if (IsAuthorised(authorised))
{
_logger.LogDebug("user scopes is authorised calling next authorisation checks");
}
else
{
_logger.LogDebug("user scopes is not authorised setting pipeline error");
SetPipelineError(new List<Error>
{
new UnauthorisedError(
$"{context.User.Identity.Name} unable to access {DownstreamRoute.ReRoute.UpstreamPathTemplate.Value}")
});
}
}
if (IsAuthorisedRoute(DownstreamRoute.ReRoute))
{
_logger.LogDebug("route is authorised");
var authorised = _claimsAuthoriser.Authorise(context.User, DownstreamRoute.ReRoute.RouteClaimsRequirement);
if (authorised.IsError)
{
_logger.LogDebug($"Error whilst authorising {context.User.Identity.Name} for {context.User.Identity.Name}. Setting pipeline error");
SetPipelineError(authorised.Errors);
return;
}
if (IsAuthorised(authorised))
{
_logger.LogDebug($"{context.User.Identity.Name} has succesfully been authorised for {DownstreamRoute.ReRoute.UpstreamPathTemplate.Value}. Calling next middleware");
await _next.Invoke(context);
}
else
{
_logger.LogDebug($"{context.User.Identity.Name} is not authorised to access {DownstreamRoute.ReRoute.UpstreamPathTemplate.Value}. Setting pipeline error");
SetPipelineError(new List<Error>
{
new UnauthorisedError($"{context.User.Identity.Name} is not authorised to access {DownstreamRoute.ReRoute.UpstreamPathTemplate.Value}")
});
}
}
else
{
_logger.LogDebug($"{DownstreamRoute.ReRoute.DownstreamPathTemplate.Value} route does not require user to be authorised");
await _next.Invoke(context);
}
}
private static bool IsAuthorised(Response<bool> authorised)
{
return authorised.Data;
}
private static bool IsAuthenticatedRoute(ReRoute reRoute)
{
return reRoute.IsAuthenticated;
}
private static bool IsAuthorisedRoute(ReRoute reRoute)
{
return reRoute.IsAuthorised;
}
}
}

View File

@ -1,12 +1,12 @@
namespace Ocelot.Authorisation.Middleware
{
using Microsoft.AspNetCore.Builder;
public static class AuthorisationMiddlewareMiddlewareExtensions
{
public static IApplicationBuilder UseAuthorisationMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<AuthorisationMiddleware>();
}
}
namespace Ocelot.Authorisation.Middleware
{
using Microsoft.AspNetCore.Builder;
public static class AuthorisationMiddlewareMiddlewareExtensions
{
public static IApplicationBuilder UseAuthorisationMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<AuthorisationMiddleware>();
}
}
}

View File

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

View File

@ -1,51 +1,51 @@
using IdentityModel;
using Ocelot.Errors;
using Ocelot.Responses;
using System.Collections.Generic;
using System.Security.Claims;
using System.Linq;
namespace Ocelot.Authorisation
{
using Infrastructure.Claims.Parser;
public class ScopesAuthoriser : IScopesAuthoriser
{
private readonly IClaimsParser _claimsParser;
public ScopesAuthoriser(IClaimsParser claimsParser)
{
_claimsParser = claimsParser;
}
public Response<bool> Authorise(ClaimsPrincipal claimsPrincipal, List<string> routeAllowedScopes)
{
if (routeAllowedScopes == null || routeAllowedScopes.Count == 0)
{
return new OkResponse<bool>(true);
}
var values = _claimsParser.GetValuesByClaimType(claimsPrincipal.Claims, JwtClaimTypes.Scope);
if (values.IsError)
{
return new ErrorResponse<bool>(values.Errors);
}
var userScopes = values.Data;
List<string> matchesScopes = routeAllowedScopes.Intersect(userScopes).ToList();
if (matchesScopes == null || matchesScopes.Count == 0)
{
return new ErrorResponse<bool>(new List<Error>
{
new ScopeNotAuthorisedError(
$"no one user scope: '{string.Join(",", userScopes)}' match with some allowed scope: '{string.Join(",", routeAllowedScopes)}'")
});
}
return new OkResponse<bool>(true);
}
}
using IdentityModel;
using Ocelot.Errors;
using Ocelot.Responses;
using System.Collections.Generic;
using System.Security.Claims;
using System.Linq;
namespace Ocelot.Authorisation
{
using Infrastructure.Claims.Parser;
public class ScopesAuthoriser : IScopesAuthoriser
{
private readonly IClaimsParser _claimsParser;
public ScopesAuthoriser(IClaimsParser claimsParser)
{
_claimsParser = claimsParser;
}
public Response<bool> Authorise(ClaimsPrincipal claimsPrincipal, List<string> routeAllowedScopes)
{
if (routeAllowedScopes == null || routeAllowedScopes.Count == 0)
{
return new OkResponse<bool>(true);
}
var values = _claimsParser.GetValuesByClaimType(claimsPrincipal.Claims, JwtClaimTypes.Scope);
if (values.IsError)
{
return new ErrorResponse<bool>(values.Errors);
}
var userScopes = values.Data;
List<string> matchesScopes = routeAllowedScopes.Intersect(userScopes).ToList();
if (matchesScopes == null || matchesScopes.Count == 0)
{
return new ErrorResponse<bool>(new List<Error>
{
new ScopeNotAuthorisedError(
$"no one user scope: '{string.Join(",", userScopes)}' match with some allowed scope: '{string.Join(",", routeAllowedScopes)}'")
});
}
return new OkResponse<bool>(true);
}
}
}

View File

@ -1,12 +1,12 @@
using Ocelot.Errors;
namespace Ocelot.Authorisation
{
public class UnauthorisedError : Error
{
public UnauthorisedError(string message)
: base(message, OcelotErrorCode.UnauthorizedError)
{
}
}
}
using Ocelot.Errors;
namespace Ocelot.Authorisation
{
public class UnauthorisedError : Error
{
public UnauthorisedError(string message)
: base(message, OcelotErrorCode.UnauthorizedError)
{
}
}
}

View File

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

View File

@ -1,25 +1,25 @@
using System.Collections.Generic;
using System.Net;
namespace Ocelot.Cache
{
public class CachedResponse
{
public CachedResponse(
HttpStatusCode statusCode = HttpStatusCode.OK,
Dictionary<string, IEnumerable<string>> headers = null,
string body = null
)
{
StatusCode = statusCode;
Headers = headers ?? new Dictionary<string, IEnumerable<string>>();
Body = body ?? "";
}
public HttpStatusCode StatusCode { get; private set; }
public Dictionary<string, IEnumerable<string>> Headers { get; private set; }
public string Body { get; private set; }
}
}
using System.Collections.Generic;
using System.Net;
namespace Ocelot.Cache
{
public class CachedResponse
{
public CachedResponse(
HttpStatusCode statusCode = HttpStatusCode.OK,
Dictionary<string, IEnumerable<string>> headers = null,
string body = null
)
{
StatusCode = statusCode;
Headers = headers ?? new Dictionary<string, IEnumerable<string>>();
Body = body ?? "";
}
public HttpStatusCode StatusCode { get; private set; }
public Dictionary<string, IEnumerable<string>> Headers { get; private set; }
public string Body { get; private set; }
}
}

View File

@ -1,13 +1,13 @@
using System;
using System.Collections.Generic;
namespace Ocelot.Cache
{
public interface IOcelotCache<T>
{
void Add(string key, T value, TimeSpan ttl, string region);
void AddAndDelete(string key, T value, TimeSpan ttl, string region);
T Get(string key, string region);
void ClearRegion(string region);
}
}
using System;
using System.Collections.Generic;
namespace Ocelot.Cache
{
public interface IOcelotCache<T>
{
void Add(string key, T value, TimeSpan ttl, string region);
void AddAndDelete(string key, T value, TimeSpan ttl, string region);
T Get(string key, string region);
void ClearRegion(string region);
}
}

View File

@ -1,9 +1,9 @@
using Ocelot.Configuration.File;
namespace Ocelot.Cache
{
public interface IRegionCreator
{
string Create(FileReRoute reRoute);
}
using Ocelot.Configuration.File;
namespace Ocelot.Cache
{
public interface IRegionCreator
{
string Create(FileReRoute reRoute);
}
}

View File

@ -1,116 +1,116 @@
using System;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Ocelot.Infrastructure.RequestData;
using Ocelot.Logging;
using Ocelot.Middleware;
using System.IO;
namespace Ocelot.Cache.Middleware
{
public class OutputCacheMiddleware : OcelotMiddleware
{
private readonly RequestDelegate _next;
private readonly IOcelotLogger _logger;
private readonly IOcelotCache<CachedResponse> _outputCache;
private readonly IRegionCreator _regionCreator;
public OutputCacheMiddleware(RequestDelegate next,
IOcelotLoggerFactory loggerFactory,
IRequestScopedDataRepository scopedDataRepository,
IOcelotCache<CachedResponse> outputCache,
IRegionCreator regionCreator)
: base(scopedDataRepository)
{
_next = next;
_outputCache = outputCache;
_logger = loggerFactory.CreateLogger<OutputCacheMiddleware>();
_regionCreator = regionCreator;
}
public async Task Invoke(HttpContext context)
{
if (!DownstreamRoute.ReRoute.IsCached)
{
await _next.Invoke(context);
return;
}
var downstreamUrlKey = $"{DownstreamRequest.Method.Method}-{DownstreamRequest.RequestUri.OriginalString}";
_logger.LogDebug("started checking cache for {downstreamUrlKey}", downstreamUrlKey);
var cached = _outputCache.Get(downstreamUrlKey, DownstreamRoute.ReRoute.CacheOptions.Region);
if (cached != null)
{
_logger.LogDebug("cache entry exists for {downstreamUrlKey}", downstreamUrlKey);
var response = CreateHttpResponseMessage(cached);
SetHttpResponseMessageThisRequest(response);
_logger.LogDebug("finished returned cached response for {downstreamUrlKey}", downstreamUrlKey);
return;
}
_logger.LogDebug("no resonse cached for {downstreamUrlKey}", downstreamUrlKey);
await _next.Invoke(context);
if (PipelineError)
{
_logger.LogDebug("there was a pipeline error for {downstreamUrlKey}", downstreamUrlKey);
return;
}
cached = await CreateCachedResponse(HttpResponseMessage);
_outputCache.Add(downstreamUrlKey, cached, TimeSpan.FromSeconds(DownstreamRoute.ReRoute.CacheOptions.TtlSeconds), DownstreamRoute.ReRoute.CacheOptions.Region);
_logger.LogDebug("finished response added to cache for {downstreamUrlKey}", downstreamUrlKey);
}
internal HttpResponseMessage CreateHttpResponseMessage(CachedResponse cached)
{
if (cached == null)
{
return null;
}
var response = new HttpResponseMessage(cached.StatusCode);
foreach (var header in cached.Headers)
{
response.Headers.Add(header.Key, header.Value);
}
var content = new MemoryStream(Convert.FromBase64String(cached.Body));
response.Content = new StreamContent(content);
return response;
}
internal async Task<CachedResponse> CreateCachedResponse(HttpResponseMessage response)
{
if (response == null)
{
return null;
}
var statusCode = response.StatusCode;
var headers = response.Headers.ToDictionary(v => v.Key, v => v.Value);
string body = null;
if (response.Content != null)
{
var content = await response.Content.ReadAsByteArrayAsync();
body = Convert.ToBase64String(content);
}
var cached = new CachedResponse(statusCode, headers, body);
return cached;
}
}
}
using System;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Ocelot.Infrastructure.RequestData;
using Ocelot.Logging;
using Ocelot.Middleware;
using System.IO;
namespace Ocelot.Cache.Middleware
{
public class OutputCacheMiddleware : OcelotMiddleware
{
private readonly RequestDelegate _next;
private readonly IOcelotLogger _logger;
private readonly IOcelotCache<CachedResponse> _outputCache;
private readonly IRegionCreator _regionCreator;
public OutputCacheMiddleware(RequestDelegate next,
IOcelotLoggerFactory loggerFactory,
IRequestScopedDataRepository scopedDataRepository,
IOcelotCache<CachedResponse> outputCache,
IRegionCreator regionCreator)
: base(scopedDataRepository)
{
_next = next;
_outputCache = outputCache;
_logger = loggerFactory.CreateLogger<OutputCacheMiddleware>();
_regionCreator = regionCreator;
}
public async Task Invoke(HttpContext context)
{
if (!DownstreamRoute.ReRoute.IsCached)
{
await _next.Invoke(context);
return;
}
var downstreamUrlKey = $"{DownstreamRequest.Method.Method}-{DownstreamRequest.RequestUri.OriginalString}";
_logger.LogDebug("started checking cache for {downstreamUrlKey}", downstreamUrlKey);
var cached = _outputCache.Get(downstreamUrlKey, DownstreamRoute.ReRoute.CacheOptions.Region);
if (cached != null)
{
_logger.LogDebug("cache entry exists for {downstreamUrlKey}", downstreamUrlKey);
var response = CreateHttpResponseMessage(cached);
SetHttpResponseMessageThisRequest(response);
_logger.LogDebug("finished returned cached response for {downstreamUrlKey}", downstreamUrlKey);
return;
}
_logger.LogDebug("no resonse cached for {downstreamUrlKey}", downstreamUrlKey);
await _next.Invoke(context);
if (PipelineError)
{
_logger.LogDebug("there was a pipeline error for {downstreamUrlKey}", downstreamUrlKey);
return;
}
cached = await CreateCachedResponse(HttpResponseMessage);
_outputCache.Add(downstreamUrlKey, cached, TimeSpan.FromSeconds(DownstreamRoute.ReRoute.CacheOptions.TtlSeconds), DownstreamRoute.ReRoute.CacheOptions.Region);
_logger.LogDebug("finished response added to cache for {downstreamUrlKey}", downstreamUrlKey);
}
internal HttpResponseMessage CreateHttpResponseMessage(CachedResponse cached)
{
if (cached == null)
{
return null;
}
var response = new HttpResponseMessage(cached.StatusCode);
foreach (var header in cached.Headers)
{
response.Headers.Add(header.Key, header.Value);
}
var content = new MemoryStream(Convert.FromBase64String(cached.Body));
response.Content = new StreamContent(content);
return response;
}
internal async Task<CachedResponse> CreateCachedResponse(HttpResponseMessage response)
{
if (response == null)
{
return null;
}
var statusCode = response.StatusCode;
var headers = response.Headers.ToDictionary(v => v.Key, v => v.Value);
string body = null;
if (response.Content != null)
{
var content = await response.Content.ReadAsByteArrayAsync();
body = Convert.ToBase64String(content);
}
var cached = new CachedResponse(statusCode, headers, body);
return cached;
}
}
}

View File

@ -1,12 +1,12 @@
using Microsoft.AspNetCore.Builder;
namespace Ocelot.Cache.Middleware
{
public static class OutputCacheMiddlewareExtensions
{
public static IApplicationBuilder UseOutputCacheMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<OutputCacheMiddleware>();
}
}
}
using Microsoft.AspNetCore.Builder;
namespace Ocelot.Cache.Middleware
{
public static class OutputCacheMiddlewareExtensions
{
public static IApplicationBuilder UseOutputCacheMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<OutputCacheMiddleware>();
}
}
}

View File

@ -1,44 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using CacheManager.Core;
namespace Ocelot.Cache
{
public class OcelotCacheManagerCache<T> : IOcelotCache<T>
{
private readonly ICacheManager<T> _cacheManager;
public OcelotCacheManagerCache(ICacheManager<T> cacheManager)
{
_cacheManager = cacheManager;
}
public void Add(string key, T value, TimeSpan ttl, string region)
{
_cacheManager.Add(new CacheItem<T>(key, region, value, ExpirationMode.Absolute, ttl));
}
public void AddAndDelete(string key, T value, TimeSpan ttl, string region)
{
var exists = _cacheManager.Get(key);
if (exists != null)
{
_cacheManager.Remove(key);
}
Add(key, value, ttl, region);
}
public T Get(string key, string region)
{
return _cacheManager.Get<T>(key, region);
}
public void ClearRegion(string region)
{
_cacheManager.ClearRegion(region);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using CacheManager.Core;
namespace Ocelot.Cache
{
public class OcelotCacheManagerCache<T> : IOcelotCache<T>
{
private readonly ICacheManager<T> _cacheManager;
public OcelotCacheManagerCache(ICacheManager<T> cacheManager)
{
_cacheManager = cacheManager;
}
public void Add(string key, T value, TimeSpan ttl, string region)
{
_cacheManager.Add(new CacheItem<T>(key, region, value, ExpirationMode.Absolute, ttl));
}
public void AddAndDelete(string key, T value, TimeSpan ttl, string region)
{
var exists = _cacheManager.Get(key);
if (exists != null)
{
_cacheManager.Remove(key);
}
Add(key, value, ttl, region);
}
public T Get(string key, string region)
{
return _cacheManager.Get<T>(key, region);
}
public void ClearRegion(string region)
{
_cacheManager.ClearRegion(region);
}
}
}

View File

@ -1,29 +1,29 @@
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Ocelot.Cache;
using Ocelot.Configuration.Provider;
namespace Ocelot.Cache
{
[Authorize]
[Route("outputcache")]
public class OutputCacheController : Controller
{
private IOcelotCache<CachedResponse> _cache;
public OutputCacheController(IOcelotCache<CachedResponse> cache)
{
_cache = cache;
}
[HttpDelete]
[Route("{region}")]
public IActionResult Delete(string region)
{
_cache.ClearRegion(region);
return new NoContentResult();
}
}
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Ocelot.Cache;
using Ocelot.Configuration.Provider;
namespace Ocelot.Cache
{
[Authorize]
[Route("outputcache")]
public class OutputCacheController : Controller
{
private IOcelotCache<CachedResponse> _cache;
public OutputCacheController(IOcelotCache<CachedResponse> cache)
{
_cache = cache;
}
[HttpDelete]
[Route("{region}")]
public IActionResult Delete(string region)
{
_cache.ClearRegion(region);
return new NoContentResult();
}
}
}

View File

@ -1,24 +1,24 @@
using System.Linq;
using Ocelot.Configuration;
using Ocelot.Configuration.File;
namespace Ocelot.Cache
{
public class RegionCreator : IRegionCreator
{
public string Create(FileReRoute reRoute)
{
if(!string.IsNullOrEmpty(reRoute?.FileCacheOptions?.Region))
{
return reRoute?.FileCacheOptions?.Region;
}
var methods = string.Join("", reRoute.UpstreamHttpMethod.Select(m => m));
var region = $"{methods}{reRoute.UpstreamPathTemplate.Replace("/", "")}";
return region;
}
}
using System.Linq;
using Ocelot.Configuration;
using Ocelot.Configuration.File;
namespace Ocelot.Cache
{
public class RegionCreator : IRegionCreator
{
public string Create(FileReRoute reRoute)
{
if(!string.IsNullOrEmpty(reRoute?.FileCacheOptions?.Region))
{
return reRoute?.FileCacheOptions?.Region;
}
var methods = string.Join("", reRoute.UpstreamHttpMethod.Select(m => m));
var region = $"{methods}{reRoute.UpstreamPathTemplate.Replace("/", "")}";
return region;
}
}
}

View File

@ -1,13 +1,13 @@
using System.Collections.Generic;
namespace Ocelot.Cache
{
public class Regions
{
public Regions(List<string> value)
{
Value = value;
}
public List<string> Value {get;private set;}
}
using System.Collections.Generic;
namespace Ocelot.Cache
{
public class Regions
{
public Regions(List<string> value)
{
Value = value;
}
public List<string> Value {get;private set;}
}
}

View File

@ -1,46 +1,46 @@
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using Microsoft.AspNetCore.Http;
using Ocelot.Configuration;
using Ocelot.Infrastructure.Claims.Parser;
using Ocelot.Responses;
namespace Ocelot.Claims
{
public class AddClaimsToRequest : IAddClaimsToRequest
{
private readonly IClaimsParser _claimsParser;
public AddClaimsToRequest(IClaimsParser claimsParser)
{
_claimsParser = claimsParser;
}
public Response SetClaimsOnContext(List<ClaimToThing> claimsToThings, HttpContext context)
{
foreach (var config in claimsToThings)
{
var value = _claimsParser.GetValue(context.User.Claims, config.NewKey, config.Delimiter, config.Index);
if (value.IsError)
{
return new ErrorResponse(value.Errors);
}
var exists = context.User.Claims.FirstOrDefault(x => x.Type == config.ExistingKey);
var identity = context.User.Identity as ClaimsIdentity;
if (exists != null)
{
identity?.RemoveClaim(exists);
}
identity?.AddClaim(new System.Security.Claims.Claim(config.ExistingKey, value.Data));
}
return new OkResponse();
}
}
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using Microsoft.AspNetCore.Http;
using Ocelot.Configuration;
using Ocelot.Infrastructure.Claims.Parser;
using Ocelot.Responses;
namespace Ocelot.Claims
{
public class AddClaimsToRequest : IAddClaimsToRequest
{
private readonly IClaimsParser _claimsParser;
public AddClaimsToRequest(IClaimsParser claimsParser)
{
_claimsParser = claimsParser;
}
public Response SetClaimsOnContext(List<ClaimToThing> claimsToThings, HttpContext context)
{
foreach (var config in claimsToThings)
{
var value = _claimsParser.GetValue(context.User.Claims, config.NewKey, config.Delimiter, config.Index);
if (value.IsError)
{
return new ErrorResponse(value.Errors);
}
var exists = context.User.Claims.FirstOrDefault(x => x.Type == config.ExistingKey);
var identity = context.User.Identity as ClaimsIdentity;
if (exists != null)
{
identity?.RemoveClaim(exists);
}
identity?.AddClaim(new System.Security.Claims.Claim(config.ExistingKey, value.Data));
}
return new OkResponse();
}
}
}

View File

@ -1,13 +1,13 @@
using System.Collections.Generic;
using Microsoft.AspNetCore.Http;
using Ocelot.Configuration;
using Ocelot.Responses;
namespace Ocelot.Claims
{
public interface IAddClaimsToRequest
{
Response SetClaimsOnContext(List<ClaimToThing> claimsToThings,
HttpContext context);
}
}
using System.Collections.Generic;
using Microsoft.AspNetCore.Http;
using Ocelot.Configuration;
using Ocelot.Responses;
namespace Ocelot.Claims
{
public interface IAddClaimsToRequest
{
Response SetClaimsOnContext(List<ClaimToThing> claimsToThings,
HttpContext context);
}
}

View File

@ -1,46 +1,46 @@
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Ocelot.Infrastructure.RequestData;
using Ocelot.Logging;
using Ocelot.Middleware;
namespace Ocelot.Claims.Middleware
{
public class ClaimsBuilderMiddleware : OcelotMiddleware
{
private readonly RequestDelegate _next;
private readonly IAddClaimsToRequest _addClaimsToRequest;
private readonly IOcelotLogger _logger;
public ClaimsBuilderMiddleware(RequestDelegate next,
IRequestScopedDataRepository requestScopedDataRepository,
IOcelotLoggerFactory loggerFactory,
IAddClaimsToRequest addClaimsToRequest)
: base(requestScopedDataRepository)
{
_next = next;
_addClaimsToRequest = addClaimsToRequest;
_logger = loggerFactory.CreateLogger<ClaimsBuilderMiddleware>();
}
public async Task Invoke(HttpContext context)
{
if (DownstreamRoute.ReRoute.ClaimsToClaims.Any())
{
_logger.LogDebug("this route has instructions to convert claims to other claims");
var result = _addClaimsToRequest.SetClaimsOnContext(DownstreamRoute.ReRoute.ClaimsToClaims, context);
if (result.IsError)
{
_logger.LogDebug("error converting claims to other claims, setting pipeline error");
SetPipelineError(result.Errors);
return;
}
}
await _next.Invoke(context);
}
}
}
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Ocelot.Infrastructure.RequestData;
using Ocelot.Logging;
using Ocelot.Middleware;
namespace Ocelot.Claims.Middleware
{
public class ClaimsBuilderMiddleware : OcelotMiddleware
{
private readonly RequestDelegate _next;
private readonly IAddClaimsToRequest _addClaimsToRequest;
private readonly IOcelotLogger _logger;
public ClaimsBuilderMiddleware(RequestDelegate next,
IRequestScopedDataRepository requestScopedDataRepository,
IOcelotLoggerFactory loggerFactory,
IAddClaimsToRequest addClaimsToRequest)
: base(requestScopedDataRepository)
{
_next = next;
_addClaimsToRequest = addClaimsToRequest;
_logger = loggerFactory.CreateLogger<ClaimsBuilderMiddleware>();
}
public async Task Invoke(HttpContext context)
{
if (DownstreamRoute.ReRoute.ClaimsToClaims.Any())
{
_logger.LogDebug("this route has instructions to convert claims to other claims");
var result = _addClaimsToRequest.SetClaimsOnContext(DownstreamRoute.ReRoute.ClaimsToClaims, context);
if (result.IsError)
{
_logger.LogDebug("error converting claims to other claims, setting pipeline error");
SetPipelineError(result.Errors);
return;
}
}
await _next.Invoke(context);
}
}
}

View File

@ -1,12 +1,12 @@
using Microsoft.AspNetCore.Builder;
namespace Ocelot.Claims.Middleware
{
public static class ClaimsBuilderMiddlewareExtensions
{
public static IApplicationBuilder UseClaimsBuilderMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<ClaimsBuilderMiddleware>();
}
}
using Microsoft.AspNetCore.Builder;
namespace Ocelot.Claims.Middleware
{
public static class ClaimsBuilderMiddlewareExtensions
{
public static IApplicationBuilder UseClaimsBuilderMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<ClaimsBuilderMiddleware>();
}
}
}

View File

@ -1,22 +1,22 @@
using System;
using Microsoft.AspNetCore.Cryptography.KeyDerivation;
namespace Ocelot.Configuration.Authentication
{
public class HashMatcher : IHashMatcher
{
public bool Match(string password, string salt, string hash)
{
byte[] s = Convert.FromBase64String(salt);
string hashed = Convert.ToBase64String(KeyDerivation.Pbkdf2(
password: password,
salt: s,
prf: KeyDerivationPrf.HMACSHA256,
iterationCount: 10000,
numBytesRequested: 256 / 8));
return hashed == hash;
}
}
using System;
using Microsoft.AspNetCore.Cryptography.KeyDerivation;
namespace Ocelot.Configuration.Authentication
{
public class HashMatcher : IHashMatcher
{
public bool Match(string password, string salt, string hash)
{
byte[] s = Convert.FromBase64String(salt);
string hashed = Convert.ToBase64String(KeyDerivation.Pbkdf2(
password: password,
salt: s,
prf: KeyDerivationPrf.HMACSHA256,
iterationCount: 10000,
numBytesRequested: 256 / 8));
return hashed == hash;
}
}
}

View File

@ -1,7 +1,7 @@
namespace Ocelot.Configuration.Authentication
{
public interface IHashMatcher
{
bool Match(string password, string salt, string hash);
}
namespace Ocelot.Configuration.Authentication
{
public interface IHashMatcher
{
bool Match(string password, string salt, string hash);
}
}

View File

@ -1,16 +1,16 @@
using System.Collections.Generic;
namespace Ocelot.Configuration
{
public class AuthenticationOptions
{
public AuthenticationOptions(List<string> allowedScopes, string authenticationProviderKey)
{
AllowedScopes = allowedScopes;
AuthenticationProviderKey = authenticationProviderKey;
}
public List<string> AllowedScopes { get; private set; }
public string AuthenticationProviderKey { get; private set; }
}
}
using System.Collections.Generic;
namespace Ocelot.Configuration
{
public class AuthenticationOptions
{
public AuthenticationOptions(List<string> allowedScopes, string authenticationProviderKey)
{
AllowedScopes = allowedScopes;
AuthenticationProviderKey = authenticationProviderKey;
}
public List<string> AllowedScopes { get; private set; }
public string AuthenticationProviderKey { get; private set; }
}
}

View File

@ -1,27 +1,27 @@
using System.Collections.Generic;
namespace Ocelot.Configuration.Builder
{
public class AuthenticationOptionsBuilder
{
private List<string> _allowedScopes = new List<string>();
private string _authenticationProviderKey;
public AuthenticationOptionsBuilder WithAllowedScopes(List<string> allowedScopes)
{
_allowedScopes = allowedScopes;
return this;
}
public AuthenticationOptionsBuilder WithAuthenticationProviderKey(string authenticationProviderKey)
{
_authenticationProviderKey = authenticationProviderKey;
return this;
}
public AuthenticationOptions Build()
{
return new AuthenticationOptions(_allowedScopes, _authenticationProviderKey);
}
}
using System.Collections.Generic;
namespace Ocelot.Configuration.Builder
{
public class AuthenticationOptionsBuilder
{
private List<string> _allowedScopes = new List<string>();
private string _authenticationProviderKey;
public AuthenticationOptionsBuilder WithAllowedScopes(List<string> allowedScopes)
{
_allowedScopes = allowedScopes;
return this;
}
public AuthenticationOptionsBuilder WithAuthenticationProviderKey(string authenticationProviderKey)
{
_authenticationProviderKey = authenticationProviderKey;
return this;
}
public AuthenticationOptions Build()
{
return new AuthenticationOptions(_allowedScopes, _authenticationProviderKey);
}
}
}

View File

@ -1,34 +1,34 @@
namespace Ocelot.Configuration.Builder
{
public class QoSOptionsBuilder
{
private int _exceptionsAllowedBeforeBreaking;
private int _durationOfBreak;
private int _timeoutValue;
public QoSOptionsBuilder WithExceptionsAllowedBeforeBreaking(int exceptionsAllowedBeforeBreaking)
{
_exceptionsAllowedBeforeBreaking = exceptionsAllowedBeforeBreaking;
return this;
}
public QoSOptionsBuilder WithDurationOfBreak(int durationOfBreak)
{
_durationOfBreak = durationOfBreak;
return this;
}
public QoSOptionsBuilder WithTimeoutValue(int timeoutValue)
{
_timeoutValue = timeoutValue;
return this;
}
public QoSOptions Build()
{
return new QoSOptions(_exceptionsAllowedBeforeBreaking, _durationOfBreak, _timeoutValue);
}
}
}
namespace Ocelot.Configuration.Builder
{
public class QoSOptionsBuilder
{
private int _exceptionsAllowedBeforeBreaking;
private int _durationOfBreak;
private int _timeoutValue;
public QoSOptionsBuilder WithExceptionsAllowedBeforeBreaking(int exceptionsAllowedBeforeBreaking)
{
_exceptionsAllowedBeforeBreaking = exceptionsAllowedBeforeBreaking;
return this;
}
public QoSOptionsBuilder WithDurationOfBreak(int durationOfBreak)
{
_durationOfBreak = durationOfBreak;
return this;
}
public QoSOptionsBuilder WithTimeoutValue(int timeoutValue)
{
_timeoutValue = timeoutValue;
return this;
}
public QoSOptions Build()
{
return new QoSOptions(_exceptionsAllowedBeforeBreaking, _durationOfBreak, _timeoutValue);
}
}
}

View File

@ -1,71 +1,71 @@
using System.Collections.Generic;
namespace Ocelot.Configuration.Builder
{
public class RateLimitOptionsBuilder
{
private bool _enableRateLimiting;
private string _clientIdHeader;
private List<string> _clientWhitelist;
private bool _disableRateLimitHeaders;
private string _quotaExceededMessage;
private string _rateLimitCounterPrefix;
private RateLimitRule _rateLimitRule;
private int _httpStatusCode;
public RateLimitOptionsBuilder WithEnableRateLimiting(bool enableRateLimiting)
{
_enableRateLimiting = enableRateLimiting;
return this;
}
public RateLimitOptionsBuilder WithClientIdHeader(string clientIdheader)
{
_clientIdHeader = clientIdheader;
return this;
}
public RateLimitOptionsBuilder WithClientWhiteList(List<string> clientWhitelist)
{
_clientWhitelist = clientWhitelist;
return this;
}
public RateLimitOptionsBuilder WithDisableRateLimitHeaders(bool disableRateLimitHeaders)
{
_disableRateLimitHeaders = disableRateLimitHeaders;
return this;
}
public RateLimitOptionsBuilder WithQuotaExceededMessage(string quotaExceededMessage)
{
_quotaExceededMessage = quotaExceededMessage;
return this;
}
public RateLimitOptionsBuilder WithRateLimitCounterPrefix(string rateLimitCounterPrefix)
{
_rateLimitCounterPrefix = rateLimitCounterPrefix;
return this;
}
public RateLimitOptionsBuilder WithRateLimitRule(RateLimitRule rateLimitRule)
{
_rateLimitRule = rateLimitRule;
return this;
}
public RateLimitOptionsBuilder WithHttpStatusCode(int httpStatusCode)
{
_httpStatusCode = httpStatusCode;
return this;
}
public RateLimitOptions Build()
{
return new RateLimitOptions(_enableRateLimiting, _clientIdHeader, _clientWhitelist,
_disableRateLimitHeaders, _quotaExceededMessage, _rateLimitCounterPrefix,
_rateLimitRule, _httpStatusCode);
}
}
}
using System.Collections.Generic;
namespace Ocelot.Configuration.Builder
{
public class RateLimitOptionsBuilder
{
private bool _enableRateLimiting;
private string _clientIdHeader;
private List<string> _clientWhitelist;
private bool _disableRateLimitHeaders;
private string _quotaExceededMessage;
private string _rateLimitCounterPrefix;
private RateLimitRule _rateLimitRule;
private int _httpStatusCode;
public RateLimitOptionsBuilder WithEnableRateLimiting(bool enableRateLimiting)
{
_enableRateLimiting = enableRateLimiting;
return this;
}
public RateLimitOptionsBuilder WithClientIdHeader(string clientIdheader)
{
_clientIdHeader = clientIdheader;
return this;
}
public RateLimitOptionsBuilder WithClientWhiteList(List<string> clientWhitelist)
{
_clientWhitelist = clientWhitelist;
return this;
}
public RateLimitOptionsBuilder WithDisableRateLimitHeaders(bool disableRateLimitHeaders)
{
_disableRateLimitHeaders = disableRateLimitHeaders;
return this;
}
public RateLimitOptionsBuilder WithQuotaExceededMessage(string quotaExceededMessage)
{
_quotaExceededMessage = quotaExceededMessage;
return this;
}
public RateLimitOptionsBuilder WithRateLimitCounterPrefix(string rateLimitCounterPrefix)
{
_rateLimitCounterPrefix = rateLimitCounterPrefix;
return this;
}
public RateLimitOptionsBuilder WithRateLimitRule(RateLimitRule rateLimitRule)
{
_rateLimitRule = rateLimitRule;
return this;
}
public RateLimitOptionsBuilder WithHttpStatusCode(int httpStatusCode)
{
_httpStatusCode = httpStatusCode;
return this;
}
public RateLimitOptions Build()
{
return new RateLimitOptions(_enableRateLimiting, _clientIdHeader, _clientWhitelist,
_disableRateLimitHeaders, _quotaExceededMessage, _rateLimitCounterPrefix,
_rateLimitRule, _httpStatusCode);
}
}
}

View File

@ -1,249 +1,239 @@
using System.Collections.Generic;
using System.Net.Http;
using Ocelot.Values;
using System.Linq;
using Ocelot.Configuration.Creator;
namespace Ocelot.Configuration.Builder
{
public class ReRouteBuilder
{
private AuthenticationOptions _authenticationOptions;
private string _loadBalancerKey;
private string _downstreamPathTemplate;
private string _upstreamTemplate;
private UpstreamPathTemplate _upstreamTemplatePattern;
private List<HttpMethod> _upstreamHttpMethod;
private bool _isAuthenticated;
private List<ClaimToThing> _configHeaderExtractorProperties;
private List<ClaimToThing> _claimToClaims;
private Dictionary<string, string> _routeClaimRequirement;
private bool _isAuthorised;
private List<ClaimToThing> _claimToQueries;
private string _requestIdHeaderKey;
private bool _isCached;
private CacheOptions _fileCacheOptions;
private string _downstreamScheme;
private string _downstreamHost;
private int _downstreamPort;
private string _loadBalancer;
private bool _useQos;
private QoSOptions _qosOptions;
private HttpHandlerOptions _httpHandlerOptions;
public bool _enableRateLimiting;
public RateLimitOptions _rateLimitOptions;
private string _authenticationProviderKey;
private bool _useServiceDiscovery;
private string _serviceName;
private List<HeaderFindAndReplace> _upstreamHeaderFindAndReplace;
private List<HeaderFindAndReplace> _downstreamHeaderFindAndReplace;
public ReRouteBuilder WithLoadBalancer(string loadBalancer)
{
_loadBalancer = loadBalancer;
return this;
}
public ReRouteBuilder WithDownstreamScheme(string downstreamScheme)
{
_downstreamScheme = downstreamScheme;
return this;
}
public ReRouteBuilder WithDownstreamHost(string downstreamHost)
{
_downstreamHost = downstreamHost;
return this;
}
public ReRouteBuilder WithDownstreamPathTemplate(string input)
{
_downstreamPathTemplate = input;
return this;
}
public ReRouteBuilder WithUpstreamPathTemplate(string input)
{
_upstreamTemplate = input;
return this;
}
public ReRouteBuilder WithUpstreamTemplatePattern(UpstreamPathTemplate input)
{
_upstreamTemplatePattern = input;
return this;
}
public ReRouteBuilder WithUpstreamHttpMethod(List<string> input)
{
_upstreamHttpMethod = (input.Count == 0) ? new List<HttpMethod>() : input.Select(x => new HttpMethod(x.Trim())).ToList();
return this;
}
public ReRouteBuilder WithIsAuthenticated(bool input)
{
_isAuthenticated = input;
return this;
}
public ReRouteBuilder WithIsAuthorised(bool input)
{
_isAuthorised = input;
return this;
}
public ReRouteBuilder WithRequestIdKey(string input)
{
_requestIdHeaderKey = input;
return this;
}
public ReRouteBuilder WithClaimsToHeaders(List<ClaimToThing> input)
{
_configHeaderExtractorProperties = input;
return this;
}
public ReRouteBuilder WithClaimsToClaims(List<ClaimToThing> input)
{
_claimToClaims = input;
return this;
}
public ReRouteBuilder WithRouteClaimsRequirement(Dictionary<string, string> input)
{
_routeClaimRequirement = input;
return this;
}
public ReRouteBuilder WithClaimsToQueries(List<ClaimToThing> input)
{
_claimToQueries = input;
return this;
}
public ReRouteBuilder WithIsCached(bool input)
{
_isCached = input;
return this;
}
public ReRouteBuilder WithCacheOptions(CacheOptions input)
{
_fileCacheOptions = input;
return this;
}
public ReRouteBuilder WithDownstreamPort(int port)
{
_downstreamPort = port;
return this;
}
public ReRouteBuilder WithIsQos(bool input)
{
_useQos = input;
return this;
}
public ReRouteBuilder WithQosOptions(QoSOptions input)
{
_qosOptions = input;
return this;
}
public ReRouteBuilder WithReRouteKey(string loadBalancerKey)
{
_loadBalancerKey = loadBalancerKey;
return this;
}
public ReRouteBuilder WithAuthenticationOptions(AuthenticationOptions authenticationOptions)
{
_authenticationOptions = authenticationOptions;
return this;
}
public ReRouteBuilder WithEnableRateLimiting(bool input)
{
_enableRateLimiting = input;
return this;
}
public ReRouteBuilder WithRateLimitOptions(RateLimitOptions input)
{
_rateLimitOptions = input;
return this;
}
public ReRouteBuilder WithAuthenticationProviderKey(string authenticationProviderKey)
{
_authenticationProviderKey = authenticationProviderKey;
return this;
}
public ReRouteBuilder WithHttpHandlerOptions(HttpHandlerOptions input)
{
_httpHandlerOptions = input;
return this;
}
public ReRouteBuilder WithUseServiceDiscovery(bool useServiceDiscovery)
{
_useServiceDiscovery = useServiceDiscovery;
return this;
}
public ReRouteBuilder WithServiceName(string serviceName)
{
_serviceName = serviceName;
return this;
}
public ReRouteBuilder WithUpstreamHeaderFindAndReplace(List<HeaderFindAndReplace> upstreamHeaderFindAndReplace)
{
_upstreamHeaderFindAndReplace = upstreamHeaderFindAndReplace;
return this;
}
public ReRouteBuilder WithDownstreamHeaderFindAndReplace(List<HeaderFindAndReplace> downstreamHeaderFindAndReplace)
{
_downstreamHeaderFindAndReplace = downstreamHeaderFindAndReplace;
return this;
}
public ReRoute Build()
{
return new ReRoute(
new PathTemplate(_downstreamPathTemplate),
new PathTemplate(_upstreamTemplate),
_upstreamHttpMethod,
_upstreamTemplatePattern,
_isAuthenticated,
_authenticationOptions,
_configHeaderExtractorProperties,
_claimToClaims,
_routeClaimRequirement,
_isAuthorised,
_claimToQueries,
_requestIdHeaderKey,
_isCached,
_fileCacheOptions,
_downstreamScheme,
_loadBalancer,
_downstreamHost,
_downstreamPort,
_loadBalancerKey,
_useQos,
_qosOptions,
_enableRateLimiting,
_rateLimitOptions,
_httpHandlerOptions,
_useServiceDiscovery,
_serviceName,
_upstreamHeaderFindAndReplace,
_downstreamHeaderFindAndReplace);
}
}
}
using System.Collections.Generic;
using System.Net.Http;
using Ocelot.Values;
using System.Linq;
using Ocelot.Configuration.Creator;
using System;
namespace Ocelot.Configuration.Builder
{
public class ReRouteBuilder
{
private AuthenticationOptions _authenticationOptions;
private string _loadBalancerKey;
private string _downstreamPathTemplate;
private string _upstreamTemplate;
private UpstreamPathTemplate _upstreamTemplatePattern;
private List<HttpMethod> _upstreamHttpMethod;
private bool _isAuthenticated;
private List<ClaimToThing> _configHeaderExtractorProperties;
private List<ClaimToThing> _claimToClaims;
private Dictionary<string, string> _routeClaimRequirement;
private bool _isAuthorised;
private List<ClaimToThing> _claimToQueries;
private string _requestIdHeaderKey;
private bool _isCached;
private CacheOptions _fileCacheOptions;
private string _downstreamScheme;
private string _loadBalancer;
private bool _useQos;
private QoSOptions _qosOptions;
private HttpHandlerOptions _httpHandlerOptions;
private bool _enableRateLimiting;
private RateLimitOptions _rateLimitOptions;
private bool _useServiceDiscovery;
private string _serviceName;
private List<HeaderFindAndReplace> _upstreamHeaderFindAndReplace;
private List<HeaderFindAndReplace> _downstreamHeaderFindAndReplace;
private readonly List<DownstreamHostAndPort> _downstreamAddresses;
public ReRouteBuilder()
{
_downstreamAddresses = new List<DownstreamHostAndPort>();
}
public ReRouteBuilder WithDownstreamAddresses(List<DownstreamHostAndPort> downstreamAddresses)
{
_downstreamAddresses.AddRange(downstreamAddresses);
return this;
}
public ReRouteBuilder WithLoadBalancer(string loadBalancer)
{
_loadBalancer = loadBalancer;
return this;
}
public ReRouteBuilder WithDownstreamScheme(string downstreamScheme)
{
_downstreamScheme = downstreamScheme;
return this;
}
public ReRouteBuilder WithDownstreamPathTemplate(string input)
{
_downstreamPathTemplate = input;
return this;
}
public ReRouteBuilder WithUpstreamPathTemplate(string input)
{
_upstreamTemplate = input;
return this;
}
public ReRouteBuilder WithUpstreamTemplatePattern(UpstreamPathTemplate input)
{
_upstreamTemplatePattern = input;
return this;
}
public ReRouteBuilder WithUpstreamHttpMethod(List<string> input)
{
_upstreamHttpMethod = (input.Count == 0) ? new List<HttpMethod>() : input.Select(x => new HttpMethod(x.Trim())).ToList();
return this;
}
public ReRouteBuilder WithIsAuthenticated(bool input)
{
_isAuthenticated = input;
return this;
}
public ReRouteBuilder WithIsAuthorised(bool input)
{
_isAuthorised = input;
return this;
}
public ReRouteBuilder WithRequestIdKey(string input)
{
_requestIdHeaderKey = input;
return this;
}
public ReRouteBuilder WithClaimsToHeaders(List<ClaimToThing> input)
{
_configHeaderExtractorProperties = input;
return this;
}
public ReRouteBuilder WithClaimsToClaims(List<ClaimToThing> input)
{
_claimToClaims = input;
return this;
}
public ReRouteBuilder WithRouteClaimsRequirement(Dictionary<string, string> input)
{
_routeClaimRequirement = input;
return this;
}
public ReRouteBuilder WithClaimsToQueries(List<ClaimToThing> input)
{
_claimToQueries = input;
return this;
}
public ReRouteBuilder WithIsCached(bool input)
{
_isCached = input;
return this;
}
public ReRouteBuilder WithCacheOptions(CacheOptions input)
{
_fileCacheOptions = input;
return this;
}
public ReRouteBuilder WithIsQos(bool input)
{
_useQos = input;
return this;
}
public ReRouteBuilder WithQosOptions(QoSOptions input)
{
_qosOptions = input;
return this;
}
public ReRouteBuilder WithReRouteKey(string loadBalancerKey)
{
_loadBalancerKey = loadBalancerKey;
return this;
}
public ReRouteBuilder WithAuthenticationOptions(AuthenticationOptions authenticationOptions)
{
_authenticationOptions = authenticationOptions;
return this;
}
public ReRouteBuilder WithEnableRateLimiting(bool input)
{
_enableRateLimiting = input;
return this;
}
public ReRouteBuilder WithRateLimitOptions(RateLimitOptions input)
{
_rateLimitOptions = input;
return this;
}
public ReRouteBuilder WithHttpHandlerOptions(HttpHandlerOptions input)
{
_httpHandlerOptions = input;
return this;
}
public ReRouteBuilder WithUseServiceDiscovery(bool useServiceDiscovery)
{
_useServiceDiscovery = useServiceDiscovery;
return this;
}
public ReRouteBuilder WithServiceName(string serviceName)
{
_serviceName = serviceName;
return this;
}
public ReRouteBuilder WithUpstreamHeaderFindAndReplace(List<HeaderFindAndReplace> upstreamHeaderFindAndReplace)
{
_upstreamHeaderFindAndReplace = upstreamHeaderFindAndReplace;
return this;
}
public ReRouteBuilder WithDownstreamHeaderFindAndReplace(List<HeaderFindAndReplace> downstreamHeaderFindAndReplace)
{
_downstreamHeaderFindAndReplace = downstreamHeaderFindAndReplace;
return this;
}
public ReRoute Build()
{
return new ReRoute(
new PathTemplate(_downstreamPathTemplate),
new PathTemplate(_upstreamTemplate),
_upstreamHttpMethod,
_upstreamTemplatePattern,
_isAuthenticated,
_authenticationOptions,
_configHeaderExtractorProperties,
_claimToClaims,
_routeClaimRequirement,
_isAuthorised,
_claimToQueries,
_requestIdHeaderKey,
_isCached,
_fileCacheOptions,
_downstreamScheme,
_loadBalancer,
_loadBalancerKey,
_useQos,
_qosOptions,
_enableRateLimiting,
_rateLimitOptions,
_httpHandlerOptions,
_useServiceDiscovery,
_serviceName,
_upstreamHeaderFindAndReplace,
_downstreamHeaderFindAndReplace,
_downstreamAddresses);
}
}
}

View File

@ -1,46 +1,46 @@
namespace Ocelot.Configuration.Builder
{
public class ReRouteOptionsBuilder
{
private bool _isAuthenticated;
private bool _isAuthorised;
private bool _isCached;
private bool _isQoS;
private bool _enableRateLimiting;
public ReRouteOptionsBuilder WithIsCached(bool isCached)
{
_isCached = isCached;
return this;
}
public ReRouteOptionsBuilder WithIsAuthenticated(bool isAuthenticated)
{
_isAuthenticated = isAuthenticated;
return this;
}
public ReRouteOptionsBuilder WithIsAuthorised(bool isAuthorised)
{
_isAuthorised = isAuthorised;
return this;
}
public ReRouteOptionsBuilder WithIsQos(bool isQoS)
{
_isQoS = isQoS;
return this;
}
public ReRouteOptionsBuilder WithRateLimiting(bool enableRateLimiting)
{
_enableRateLimiting = enableRateLimiting;
return this;
}
public ReRouteOptions Build()
{
return new ReRouteOptions(_isAuthenticated, _isAuthorised, _isCached, _isQoS, _enableRateLimiting);
}
}
namespace Ocelot.Configuration.Builder
{
public class ReRouteOptionsBuilder
{
private bool _isAuthenticated;
private bool _isAuthorised;
private bool _isCached;
private bool _isQoS;
private bool _enableRateLimiting;
public ReRouteOptionsBuilder WithIsCached(bool isCached)
{
_isCached = isCached;
return this;
}
public ReRouteOptionsBuilder WithIsAuthenticated(bool isAuthenticated)
{
_isAuthenticated = isAuthenticated;
return this;
}
public ReRouteOptionsBuilder WithIsAuthorised(bool isAuthorised)
{
_isAuthorised = isAuthorised;
return this;
}
public ReRouteOptionsBuilder WithIsQos(bool isQoS)
{
_isQoS = isQoS;
return this;
}
public ReRouteOptionsBuilder WithRateLimiting(bool enableRateLimiting)
{
_enableRateLimiting = enableRateLimiting;
return this;
}
public ReRouteOptions Build()
{
return new ReRouteOptions(_isAuthenticated, _isAuthorised, _isCached, _isQoS, _enableRateLimiting);
}
}
}

View File

@ -1,25 +1,25 @@
namespace Ocelot.Configuration.Builder
{
public class ServiceProviderConfigurationBuilder
{
private string _serviceDiscoveryProviderHost;
private int _serviceDiscoveryProviderPort;
public ServiceProviderConfigurationBuilder WithServiceDiscoveryProviderHost(string serviceDiscoveryProviderHost)
{
_serviceDiscoveryProviderHost = serviceDiscoveryProviderHost;
return this;
}
public ServiceProviderConfigurationBuilder WithServiceDiscoveryProviderPort(int serviceDiscoveryProviderPort)
{
_serviceDiscoveryProviderPort = serviceDiscoveryProviderPort;
return this;
}
public ServiceProviderConfiguration Build()
{
return new ServiceProviderConfiguration(_serviceDiscoveryProviderHost,_serviceDiscoveryProviderPort);
}
}
namespace Ocelot.Configuration.Builder
{
public class ServiceProviderConfigurationBuilder
{
private string _serviceDiscoveryProviderHost;
private int _serviceDiscoveryProviderPort;
public ServiceProviderConfigurationBuilder WithServiceDiscoveryProviderHost(string serviceDiscoveryProviderHost)
{
_serviceDiscoveryProviderHost = serviceDiscoveryProviderHost;
return this;
}
public ServiceProviderConfigurationBuilder WithServiceDiscoveryProviderPort(int serviceDiscoveryProviderPort)
{
_serviceDiscoveryProviderPort = serviceDiscoveryProviderPort;
return this;
}
public ServiceProviderConfiguration Build()
{
return new ServiceProviderConfiguration(_serviceDiscoveryProviderHost,_serviceDiscoveryProviderPort);
}
}
}

View File

@ -1,14 +1,14 @@
namespace Ocelot.Configuration
{
public class CacheOptions
{
public CacheOptions(int ttlSeconds, string region)
{
TtlSeconds = ttlSeconds;
Region = region;
}
public int TtlSeconds { get; private set; }
public string Region {get;private set;}
}
}
namespace Ocelot.Configuration
{
public class CacheOptions
{
public CacheOptions(int ttlSeconds, string region)
{
TtlSeconds = ttlSeconds;
Region = region;
}
public int TtlSeconds { get; private set; }
public string Region {get;private set;}
}
}

View File

@ -1,18 +1,18 @@
namespace Ocelot.Configuration
{
public class ClaimToThing
{
public ClaimToThing(string existingKey, string newKey, string delimiter, int index)
{
NewKey = newKey;
Delimiter = delimiter;
Index = index;
ExistingKey = existingKey;
}
public string ExistingKey { get; private set; }
public string NewKey { get; private set; }
public string Delimiter { get; private set; }
public int Index { get; private set; }
}
}
namespace Ocelot.Configuration
{
public class ClaimToThing
{
public ClaimToThing(string existingKey, string newKey, string delimiter, int index)
{
NewKey = newKey;
Delimiter = delimiter;
Index = index;
ExistingKey = existingKey;
}
public string ExistingKey { get; private set; }
public string NewKey { get; private set; }
public string Delimiter { get; private set; }
public int Index { get; private set; }
}
}

View File

@ -1,12 +1,12 @@
using Ocelot.Configuration.File;
namespace Ocelot.Configuration.Creator
{
public class AuthenticationOptionsCreator : IAuthenticationOptionsCreator
{
public AuthenticationOptions Create(FileReRoute reRoute)
{
return new AuthenticationOptions(reRoute.AuthenticationOptions.AllowedScopes, reRoute.AuthenticationOptions.AuthenticationProviderKey);
}
}
using Ocelot.Configuration.File;
namespace Ocelot.Configuration.Creator
{
public class AuthenticationOptionsCreator : IAuthenticationOptionsCreator
{
public AuthenticationOptions Create(FileReRoute reRoute)
{
return new AuthenticationOptions(reRoute.AuthenticationOptions.AllowedScopes, reRoute.AuthenticationOptions.AuthenticationProviderKey);
}
}
}

View File

@ -1,41 +1,41 @@
using System.Collections.Generic;
using Ocelot.Configuration.Parser;
using Ocelot.Logging;
namespace Ocelot.Configuration.Creator
{
public class ClaimsToThingCreator : IClaimsToThingCreator
{
private readonly IClaimToThingConfigurationParser _claimToThingConfigParser;
private readonly IOcelotLogger _logger;
public ClaimsToThingCreator(IClaimToThingConfigurationParser claimToThingConfigurationParser,
IOcelotLoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger<ClaimsToThingCreator>();
_claimToThingConfigParser = claimToThingConfigurationParser;
}
public List<ClaimToThing> Create(Dictionary<string,string> inputToBeParsed)
{
var claimsToThings = new List<ClaimToThing>();
foreach (var input in inputToBeParsed)
{
var claimToThing = _claimToThingConfigParser.Extract(input.Key, input.Value);
if (claimToThing.IsError)
{
_logger.LogDebug("ClaimsToThingCreator.BuildAddThingsToRequest",
$"Unable to extract configuration for key: {input.Key} and value: {input.Value} your configuration file is incorrect");
}
else
{
claimsToThings.Add(claimToThing.Data);
}
}
return claimsToThings;
}
}
using System.Collections.Generic;
using Ocelot.Configuration.Parser;
using Ocelot.Logging;
namespace Ocelot.Configuration.Creator
{
public class ClaimsToThingCreator : IClaimsToThingCreator
{
private readonly IClaimToThingConfigurationParser _claimToThingConfigParser;
private readonly IOcelotLogger _logger;
public ClaimsToThingCreator(IClaimToThingConfigurationParser claimToThingConfigurationParser,
IOcelotLoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger<ClaimsToThingCreator>();
_claimToThingConfigParser = claimToThingConfigurationParser;
}
public List<ClaimToThing> Create(Dictionary<string,string> inputToBeParsed)
{
var claimsToThings = new List<ClaimToThing>();
foreach (var input in inputToBeParsed)
{
var claimToThing = _claimToThingConfigParser.Extract(input.Key, input.Value);
if (claimToThing.IsError)
{
_logger.LogDebug("ClaimsToThingCreator.BuildAddThingsToRequest",
$"Unable to extract configuration for key: {input.Key} and value: {input.Value} your configuration file is incorrect");
}
else
{
claimsToThings.Add(claimToThing.Data);
}
}
return claimsToThings;
}
}
}

View File

@ -0,0 +1,14 @@
using System.Collections.Generic;
using System.Linq;
using Ocelot.Configuration.File;
namespace Ocelot.Configuration.Creator
{
public class DownstreamAddressesCreator : IDownstreamAddressesCreator
{
public List<DownstreamHostAndPort> Create(FileReRoute reRoute)
{
return reRoute.DownstreamHostAndPorts.Select(hostAndPort => new DownstreamHostAndPort(hostAndPort.Host, hostAndPort.Port)).ToList();
}
}
}

View File

@ -38,6 +38,7 @@ namespace Ocelot.Configuration.Creator
private readonly IHttpHandlerOptionsCreator _httpHandlerOptionsCreator;
private readonly IAdministrationPath _adminPath;
private readonly IHeaderFindAndReplaceCreator _headerFAndRCreator;
private readonly IDownstreamAddressesCreator _downstreamAddressesCreator;
public FileOcelotConfigurationCreator(
@ -55,9 +56,11 @@ namespace Ocelot.Configuration.Creator
IRegionCreator regionCreator,
IHttpHandlerOptionsCreator httpHandlerOptionsCreator,
IAdministrationPath adminPath,
IHeaderFindAndReplaceCreator headerFAndRCreator
IHeaderFindAndReplaceCreator headerFAndRCreator,
IDownstreamAddressesCreator downstreamAddressesCreator
)
{
_downstreamAddressesCreator = downstreamAddressesCreator;
_headerFAndRCreator = headerFAndRCreator;
_adminPath = adminPath;
_regionCreator = regionCreator;
@ -133,6 +136,8 @@ namespace Ocelot.Configuration.Creator
var hAndRs = _headerFAndRCreator.Create(fileReRoute);
var downstreamAddresses = _downstreamAddressesCreator.Create(fileReRoute);
var reRoute = new ReRouteBuilder()
.WithDownstreamPathTemplate(fileReRoute.DownstreamPathTemplate)
.WithUpstreamPathTemplate(fileReRoute.UpstreamPathTemplate)
@ -150,8 +155,7 @@ namespace Ocelot.Configuration.Creator
.WithCacheOptions(new CacheOptions(fileReRoute.FileCacheOptions.TtlSeconds, region))
.WithDownstreamScheme(fileReRoute.DownstreamScheme)
.WithLoadBalancer(fileReRoute.LoadBalancer)
.WithDownstreamHost(fileReRoute.DownstreamHost)
.WithDownstreamPort(fileReRoute.DownstreamPort)
.WithDownstreamAddresses(downstreamAddresses)
.WithReRouteKey(reRouteKey)
.WithIsQos(fileReRouteOptions.IsQos)
.WithQosOptions(qosOptions)

View File

@ -1,68 +1,68 @@
using System;
using System.Collections.Generic;
using Ocelot.Configuration.File;
using Ocelot.Middleware;
namespace Ocelot.Configuration.Creator
{
public class HeaderFindAndReplaceCreator : IHeaderFindAndReplaceCreator
{
private IBaseUrlFinder _finder;
private Dictionary<string, Func<string>> _placeholders;
public HeaderFindAndReplaceCreator(IBaseUrlFinder finder)
{
_finder = finder;
_placeholders = new Dictionary<string, Func<string>>();
_placeholders.Add("{BaseUrl}", () => {
return _finder.Find();
});
}
public HeaderTransformations Create(FileReRoute fileReRoute)
{
var upstream = new List<HeaderFindAndReplace>();
foreach(var input in fileReRoute.UpstreamHeaderTransform)
{
var hAndr = Map(input);
upstream.Add(hAndr);
}
var downstream = new List<HeaderFindAndReplace>();
foreach(var input in fileReRoute.DownstreamHeaderTransform)
{
var hAndr = Map(input);
downstream.Add(hAndr);
}
return new HeaderTransformations(upstream, downstream);
}
private HeaderFindAndReplace Map(KeyValuePair<string,string> input)
{
var findAndReplace = input.Value.Split(",");
var replace = findAndReplace[1].TrimStart();
var startOfPlaceholder = replace.IndexOf("{");
if(startOfPlaceholder > -1)
{
var endOfPlaceholder = replace.IndexOf("}", startOfPlaceholder);
var placeholder = replace.Substring(startOfPlaceholder, startOfPlaceholder + (endOfPlaceholder + 1));
if(_placeholders.ContainsKey(placeholder))
{
var value = _placeholders[placeholder].Invoke();
replace = replace.Replace(placeholder, value);
}
}
var hAndr = new HeaderFindAndReplace(input.Key, findAndReplace[0], replace, 0);
return hAndr;
}
}
}
using System;
using System.Collections.Generic;
using Ocelot.Configuration.File;
using Ocelot.Middleware;
namespace Ocelot.Configuration.Creator
{
public class HeaderFindAndReplaceCreator : IHeaderFindAndReplaceCreator
{
private IBaseUrlFinder _finder;
private Dictionary<string, Func<string>> _placeholders;
public HeaderFindAndReplaceCreator(IBaseUrlFinder finder)
{
_finder = finder;
_placeholders = new Dictionary<string, Func<string>>();
_placeholders.Add("{BaseUrl}", () => {
return _finder.Find();
});
}
public HeaderTransformations Create(FileReRoute fileReRoute)
{
var upstream = new List<HeaderFindAndReplace>();
foreach(var input in fileReRoute.UpstreamHeaderTransform)
{
var hAndr = Map(input);
upstream.Add(hAndr);
}
var downstream = new List<HeaderFindAndReplace>();
foreach(var input in fileReRoute.DownstreamHeaderTransform)
{
var hAndr = Map(input);
downstream.Add(hAndr);
}
return new HeaderTransformations(upstream, downstream);
}
private HeaderFindAndReplace Map(KeyValuePair<string,string> input)
{
var findAndReplace = input.Value.Split(",");
var replace = findAndReplace[1].TrimStart();
var startOfPlaceholder = replace.IndexOf("{");
if(startOfPlaceholder > -1)
{
var endOfPlaceholder = replace.IndexOf("}", startOfPlaceholder);
var placeholder = replace.Substring(startOfPlaceholder, startOfPlaceholder + (endOfPlaceholder + 1));
if(_placeholders.ContainsKey(placeholder))
{
var value = _placeholders[placeholder].Invoke();
replace = replace.Replace(placeholder, value);
}
}
var hAndr = new HeaderFindAndReplace(input.Key, findAndReplace[0], replace, 0);
return hAndr;
}
}
}

View File

@ -1,17 +1,17 @@
using System.Collections.Generic;
namespace Ocelot.Configuration.Creator
{
public class HeaderTransformations
{
public HeaderTransformations(List<HeaderFindAndReplace> upstream, List<HeaderFindAndReplace> downstream)
{
Upstream = upstream;
Downstream = downstream;
}
public List<HeaderFindAndReplace> Upstream {get;private set;}
public List<HeaderFindAndReplace> Downstream {get;private set;}
}
}
using System.Collections.Generic;
namespace Ocelot.Configuration.Creator
{
public class HeaderTransformations
{
public HeaderTransformations(List<HeaderFindAndReplace> upstream, List<HeaderFindAndReplace> downstream)
{
Upstream = upstream;
Downstream = downstream;
}
public List<HeaderFindAndReplace> Upstream {get;private set;}
public List<HeaderFindAndReplace> Downstream {get;private set;}
}
}

View File

@ -1,10 +1,10 @@
using System.Collections.Generic;
using Ocelot.Configuration.File;
namespace Ocelot.Configuration.Creator
{
public interface IAuthenticationOptionsCreator
{
AuthenticationOptions Create(FileReRoute reRoute);
}
using System.Collections.Generic;
using Ocelot.Configuration.File;
namespace Ocelot.Configuration.Creator
{
public interface IAuthenticationOptionsCreator
{
AuthenticationOptions Create(FileReRoute reRoute);
}
}

View File

@ -1,9 +1,9 @@
using System.Collections.Generic;
namespace Ocelot.Configuration.Creator
{
public interface IClaimsToThingCreator
{
List<ClaimToThing> Create(Dictionary<string,string> thingsBeingAdded);
}
using System.Collections.Generic;
namespace Ocelot.Configuration.Creator
{
public interface IClaimsToThingCreator
{
List<ClaimToThing> Create(Dictionary<string,string> thingsBeingAdded);
}
}

View File

@ -0,0 +1,10 @@
using System.Collections.Generic;
using Ocelot.Configuration.File;
namespace Ocelot.Configuration.Creator
{
public interface IDownstreamAddressesCreator
{
List<DownstreamHostAndPort> Create(FileReRoute reRoute);
}
}

View File

@ -1,10 +1,10 @@
using System.Collections.Generic;
using Ocelot.Configuration.File;
namespace Ocelot.Configuration.Creator
{
public interface IHeaderFindAndReplaceCreator
{
HeaderTransformations Create(FileReRoute fileReRoute);
}
}
using System.Collections.Generic;
using Ocelot.Configuration.File;
namespace Ocelot.Configuration.Creator
{
public interface IHeaderFindAndReplaceCreator
{
HeaderTransformations Create(FileReRoute fileReRoute);
}
}

View File

@ -1,11 +1,11 @@
using System.Threading.Tasks;
using Ocelot.Configuration.File;
using Ocelot.Responses;
namespace Ocelot.Configuration.Creator
{
public interface IOcelotConfigurationCreator
{
Task<Response<IOcelotConfiguration>> Create(FileConfiguration fileConfiguration);
}
using System.Threading.Tasks;
using Ocelot.Configuration.File;
using Ocelot.Responses;
namespace Ocelot.Configuration.Creator
{
public interface IOcelotConfigurationCreator
{
Task<Response<IOcelotConfiguration>> Create(FileConfiguration fileConfiguration);
}
}

View File

@ -1,9 +1,9 @@
using Ocelot.Configuration.File;
namespace Ocelot.Configuration.Creator
{
public interface IQoSOptionsCreator
{
QoSOptions Create(FileReRoute fileReRoute);
}
using Ocelot.Configuration.File;
namespace Ocelot.Configuration.Creator
{
public interface IQoSOptionsCreator
{
QoSOptions Create(FileReRoute fileReRoute);
}
}

View File

@ -1,9 +1,9 @@
using Ocelot.Configuration.File;
namespace Ocelot.Configuration.Creator
{
public interface IRateLimitOptionsCreator
{
RateLimitOptions Create(FileReRoute fileReRoute, FileGlobalConfiguration globalConfiguration, bool enableRateLimiting);
}
using Ocelot.Configuration.File;
namespace Ocelot.Configuration.Creator
{
public interface IRateLimitOptionsCreator
{
RateLimitOptions Create(FileReRoute fileReRoute, FileGlobalConfiguration globalConfiguration, bool enableRateLimiting);
}
}

View File

@ -1,9 +1,9 @@
using Ocelot.Configuration.File;
namespace Ocelot.Configuration.Creator
{
public interface IReRouteOptionsCreator
{
ReRouteOptions Create(FileReRoute fileReRoute);
}
using Ocelot.Configuration.File;
namespace Ocelot.Configuration.Creator
{
public interface IReRouteOptionsCreator
{
ReRouteOptions Create(FileReRoute fileReRoute);
}
}

View File

@ -1,9 +1,9 @@
using Ocelot.Configuration.File;
namespace Ocelot.Configuration.Creator
{
public interface IRequestIdKeyCreator
{
string Create(FileReRoute fileReRoute, FileGlobalConfiguration globalConfiguration);
}
using Ocelot.Configuration.File;
namespace Ocelot.Configuration.Creator
{
public interface IRequestIdKeyCreator
{
string Create(FileReRoute fileReRoute, FileGlobalConfiguration globalConfiguration);
}
}

View File

@ -1,9 +1,9 @@
using Ocelot.Configuration.File;
namespace Ocelot.Configuration.Creator
{
public interface IServiceProviderConfigurationCreator
{
ServiceProviderConfiguration Create(FileGlobalConfiguration globalConfiguration);
}
using Ocelot.Configuration.File;
namespace Ocelot.Configuration.Creator
{
public interface IServiceProviderConfigurationCreator
{
ServiceProviderConfiguration Create(FileGlobalConfiguration globalConfiguration);
}
}

View File

@ -1,10 +1,10 @@
using Ocelot.Configuration.File;
using Ocelot.Values;
namespace Ocelot.Configuration.Creator
{
public interface IUpstreamTemplatePatternCreator
{
UpstreamPathTemplate Create(FileReRoute reRoute);
}
using Ocelot.Configuration.File;
using Ocelot.Values;
namespace Ocelot.Configuration.Creator
{
public interface IUpstreamTemplatePatternCreator
{
UpstreamPathTemplate Create(FileReRoute reRoute);
}
}

View File

@ -1,26 +1,26 @@
using System;
using System.Collections.Generic;
using IdentityServer4.AccessTokenValidation;
using IdentityServer4.Models;
using Ocelot.Configuration.Provider;
namespace Ocelot.Configuration.Creator
{
public static class IdentityServerConfigurationCreator
{
public static IdentityServerConfiguration GetIdentityServerConfiguration(string secret)
{
var credentialsSigningCertificateLocation = Environment.GetEnvironmentVariable("OCELOT_CERTIFICATE");
var credentialsSigningCertificatePassword = Environment.GetEnvironmentVariable("OCELOT_CERTIFICATE_PASSWORD");
return new IdentityServerConfiguration(
"admin",
false,
secret,
new List<string> { "admin", "openid", "offline_access" },
credentialsSigningCertificateLocation,
credentialsSigningCertificatePassword
);
}
}
}
using System;
using System.Collections.Generic;
using IdentityServer4.AccessTokenValidation;
using IdentityServer4.Models;
using Ocelot.Configuration.Provider;
namespace Ocelot.Configuration.Creator
{
public static class IdentityServerConfigurationCreator
{
public static IdentityServerConfiguration GetIdentityServerConfiguration(string secret)
{
var credentialsSigningCertificateLocation = Environment.GetEnvironmentVariable("OCELOT_CERTIFICATE");
var credentialsSigningCertificatePassword = Environment.GetEnvironmentVariable("OCELOT_CERTIFICATE_PASSWORD");
return new IdentityServerConfiguration(
"admin",
false,
secret,
new List<string> { "admin", "openid", "offline_access" },
credentialsSigningCertificateLocation,
credentialsSigningCertificatePassword
);
}
}
}

View File

@ -1,17 +1,17 @@
using Ocelot.Configuration.Builder;
using Ocelot.Configuration.File;
namespace Ocelot.Configuration.Creator
{
public class QoSOptionsCreator : IQoSOptionsCreator
{
public QoSOptions Create(FileReRoute fileReRoute)
{
return new QoSOptionsBuilder()
.WithExceptionsAllowedBeforeBreaking(fileReRoute.QoSOptions.ExceptionsAllowedBeforeBreaking)
.WithDurationOfBreak(fileReRoute.QoSOptions.DurationOfBreak)
.WithTimeoutValue(fileReRoute.QoSOptions.TimeoutValue)
.Build();
}
}
using Ocelot.Configuration.Builder;
using Ocelot.Configuration.File;
namespace Ocelot.Configuration.Creator
{
public class QoSOptionsCreator : IQoSOptionsCreator
{
public QoSOptions Create(FileReRoute fileReRoute)
{
return new QoSOptionsBuilder()
.WithExceptionsAllowedBeforeBreaking(fileReRoute.QoSOptions.ExceptionsAllowedBeforeBreaking)
.WithDurationOfBreak(fileReRoute.QoSOptions.DurationOfBreak)
.WithTimeoutValue(fileReRoute.QoSOptions.TimeoutValue)
.Build();
}
}
}

View File

@ -1,32 +1,32 @@
using System;
using Ocelot.Configuration.Builder;
using Ocelot.Configuration.File;
namespace Ocelot.Configuration.Creator
{
public class RateLimitOptionsCreator : IRateLimitOptionsCreator
{
public RateLimitOptions Create(FileReRoute fileReRoute, FileGlobalConfiguration globalConfiguration, bool enableRateLimiting)
{
RateLimitOptions rateLimitOption = null;
if (enableRateLimiting)
{
rateLimitOption = new RateLimitOptionsBuilder()
.WithClientIdHeader(globalConfiguration.RateLimitOptions.ClientIdHeader)
.WithClientWhiteList(fileReRoute.RateLimitOptions.ClientWhitelist)
.WithDisableRateLimitHeaders(globalConfiguration.RateLimitOptions.DisableRateLimitHeaders)
.WithEnableRateLimiting(fileReRoute.RateLimitOptions.EnableRateLimiting)
.WithHttpStatusCode(globalConfiguration.RateLimitOptions.HttpStatusCode)
.WithQuotaExceededMessage(globalConfiguration.RateLimitOptions.QuotaExceededMessage)
.WithRateLimitCounterPrefix(globalConfiguration.RateLimitOptions.RateLimitCounterPrefix)
.WithRateLimitRule(new RateLimitRule(fileReRoute.RateLimitOptions.Period,
fileReRoute.RateLimitOptions.PeriodTimespan,
fileReRoute.RateLimitOptions.Limit))
.Build();
}
return rateLimitOption;
}
}
}
using System;
using Ocelot.Configuration.Builder;
using Ocelot.Configuration.File;
namespace Ocelot.Configuration.Creator
{
public class RateLimitOptionsCreator : IRateLimitOptionsCreator
{
public RateLimitOptions Create(FileReRoute fileReRoute, FileGlobalConfiguration globalConfiguration, bool enableRateLimiting)
{
RateLimitOptions rateLimitOption = null;
if (enableRateLimiting)
{
rateLimitOption = new RateLimitOptionsBuilder()
.WithClientIdHeader(globalConfiguration.RateLimitOptions.ClientIdHeader)
.WithClientWhiteList(fileReRoute.RateLimitOptions.ClientWhitelist)
.WithDisableRateLimitHeaders(globalConfiguration.RateLimitOptions.DisableRateLimitHeaders)
.WithEnableRateLimiting(fileReRoute.RateLimitOptions.EnableRateLimiting)
.WithHttpStatusCode(globalConfiguration.RateLimitOptions.HttpStatusCode)
.WithQuotaExceededMessage(globalConfiguration.RateLimitOptions.QuotaExceededMessage)
.WithRateLimitCounterPrefix(globalConfiguration.RateLimitOptions.RateLimitCounterPrefix)
.WithRateLimitRule(new RateLimitRule(fileReRoute.RateLimitOptions.Period,
fileReRoute.RateLimitOptions.PeriodTimespan,
fileReRoute.RateLimitOptions.Limit))
.Build();
}
return rateLimitOption;
}
}
}

View File

@ -1,52 +1,52 @@
using Ocelot.Configuration.Builder;
using Ocelot.Configuration.File;
namespace Ocelot.Configuration.Creator
{
public class ReRouteOptionsCreator : IReRouteOptionsCreator
{
public ReRouteOptions Create(FileReRoute fileReRoute)
{
var isAuthenticated = IsAuthenticated(fileReRoute);
var isAuthorised = IsAuthorised(fileReRoute);
var isCached = IsCached(fileReRoute);
var isQos = IsQoS(fileReRoute);
var enableRateLimiting = IsEnableRateLimiting(fileReRoute);
var options = new ReRouteOptionsBuilder()
.WithIsAuthenticated(isAuthenticated)
.WithIsAuthorised(isAuthorised)
.WithIsCached(isCached)
.WithIsQos(isQos)
.WithRateLimiting(enableRateLimiting)
.Build();
return options;
}
private static bool IsEnableRateLimiting(FileReRoute fileReRoute)
{
return (fileReRoute.RateLimitOptions != null && fileReRoute.RateLimitOptions.EnableRateLimiting) ? true : false;
}
private bool IsQoS(FileReRoute fileReRoute)
{
return fileReRoute.QoSOptions?.ExceptionsAllowedBeforeBreaking > 0 && fileReRoute.QoSOptions?.TimeoutValue > 0;
}
private bool IsAuthenticated(FileReRoute fileReRoute)
{
return !string.IsNullOrEmpty(fileReRoute.AuthenticationOptions?.AuthenticationProviderKey);
}
private bool IsAuthorised(FileReRoute fileReRoute)
{
return fileReRoute.RouteClaimsRequirement?.Count > 0;
}
private bool IsCached(FileReRoute fileReRoute)
{
return fileReRoute.FileCacheOptions.TtlSeconds > 0;
}
}
using Ocelot.Configuration.Builder;
using Ocelot.Configuration.File;
namespace Ocelot.Configuration.Creator
{
public class ReRouteOptionsCreator : IReRouteOptionsCreator
{
public ReRouteOptions Create(FileReRoute fileReRoute)
{
var isAuthenticated = IsAuthenticated(fileReRoute);
var isAuthorised = IsAuthorised(fileReRoute);
var isCached = IsCached(fileReRoute);
var isQos = IsQoS(fileReRoute);
var enableRateLimiting = IsEnableRateLimiting(fileReRoute);
var options = new ReRouteOptionsBuilder()
.WithIsAuthenticated(isAuthenticated)
.WithIsAuthorised(isAuthorised)
.WithIsCached(isCached)
.WithIsQos(isQos)
.WithRateLimiting(enableRateLimiting)
.Build();
return options;
}
private static bool IsEnableRateLimiting(FileReRoute fileReRoute)
{
return (fileReRoute.RateLimitOptions != null && fileReRoute.RateLimitOptions.EnableRateLimiting) ? true : false;
}
private bool IsQoS(FileReRoute fileReRoute)
{
return fileReRoute.QoSOptions?.ExceptionsAllowedBeforeBreaking > 0 && fileReRoute.QoSOptions?.TimeoutValue > 0;
}
private bool IsAuthenticated(FileReRoute fileReRoute)
{
return !string.IsNullOrEmpty(fileReRoute.AuthenticationOptions?.AuthenticationProviderKey);
}
private bool IsAuthorised(FileReRoute fileReRoute)
{
return fileReRoute.RouteClaimsRequirement?.Count > 0;
}
private bool IsCached(FileReRoute fileReRoute)
{
return fileReRoute.FileCacheOptions.TtlSeconds > 0;
}
}
}

View File

@ -1,18 +1,18 @@
using Ocelot.Configuration.File;
namespace Ocelot.Configuration.Creator
{
public class RequestIdKeyCreator : IRequestIdKeyCreator
{
public string Create(FileReRoute fileReRoute, FileGlobalConfiguration globalConfiguration)
{
var reRouteId = !string.IsNullOrEmpty(fileReRoute.RequestIdKey);
var requestIdKey = reRouteId
? fileReRoute.RequestIdKey
: globalConfiguration.RequestIdKey;
return requestIdKey;
}
}
using Ocelot.Configuration.File;
namespace Ocelot.Configuration.Creator
{
public class RequestIdKeyCreator : IRequestIdKeyCreator
{
public string Create(FileReRoute fileReRoute, FileGlobalConfiguration globalConfiguration)
{
var reRouteId = !string.IsNullOrEmpty(fileReRoute.RequestIdKey);
var requestIdKey = reRouteId
? fileReRoute.RequestIdKey
: globalConfiguration.RequestIdKey;
return requestIdKey;
}
}
}

View File

@ -1,18 +1,18 @@
using Ocelot.Configuration.Builder;
using Ocelot.Configuration.File;
namespace Ocelot.Configuration.Creator
{
public class ServiceProviderConfigurationCreator : IServiceProviderConfigurationCreator
{
public ServiceProviderConfiguration Create(FileGlobalConfiguration globalConfiguration)
{
var serviceProviderPort = globalConfiguration?.ServiceDiscoveryProvider?.Port ?? 0;
return new ServiceProviderConfigurationBuilder()
.WithServiceDiscoveryProviderHost(globalConfiguration?.ServiceDiscoveryProvider?.Host)
.WithServiceDiscoveryProviderPort(serviceProviderPort)
.Build();
}
}
using Ocelot.Configuration.Builder;
using Ocelot.Configuration.File;
namespace Ocelot.Configuration.Creator
{
public class ServiceProviderConfigurationCreator : IServiceProviderConfigurationCreator
{
public ServiceProviderConfiguration Create(FileGlobalConfiguration globalConfiguration)
{
var serviceProviderPort = globalConfiguration?.ServiceDiscoveryProvider?.Port ?? 0;
return new ServiceProviderConfigurationBuilder()
.WithServiceDiscoveryProviderHost(globalConfiguration?.ServiceDiscoveryProvider?.Host)
.WithServiceDiscoveryProviderPort(serviceProviderPort)
.Build();
}
}
}

View File

@ -1,76 +1,76 @@
using System.Collections.Generic;
using Ocelot.Configuration.File;
using Ocelot.Values;
namespace Ocelot.Configuration.Creator
{
public class UpstreamTemplatePatternCreator : IUpstreamTemplatePatternCreator
{
private const string RegExMatchEverything = "[0-9a-zA-Z].*";
private const string RegExMatchEndString = "$";
private const string RegExIgnoreCase = "(?i)";
private const string RegExForwardSlashOnly = "^/$";
private const string RegExForwardSlashAndOnePlaceHolder = "^/.*";
public UpstreamPathTemplate Create(FileReRoute reRoute)
{
var upstreamTemplate = reRoute.UpstreamPathTemplate;
var placeholders = new List<string>();
for (var i = 0; i < upstreamTemplate.Length; i++)
{
if (IsPlaceHolder(upstreamTemplate, i))
{
var postitionOfPlaceHolderClosingBracket = upstreamTemplate.IndexOf('}', i);
var difference = postitionOfPlaceHolderClosingBracket - i + 1;
var placeHolderName = upstreamTemplate.Substring(i, difference);
placeholders.Add(placeHolderName);
//hack to handle /{url} case
if(ForwardSlashAndOnePlaceHolder(upstreamTemplate, placeholders, postitionOfPlaceHolderClosingBracket))
{
return new UpstreamPathTemplate(RegExForwardSlashAndOnePlaceHolder, 0);
}
}
}
foreach (var placeholder in placeholders)
{
upstreamTemplate = upstreamTemplate.Replace(placeholder, RegExMatchEverything);
}
if (upstreamTemplate == "/")
{
return new UpstreamPathTemplate(RegExForwardSlashOnly, 1);
}
if(upstreamTemplate.EndsWith("/"))
{
upstreamTemplate = upstreamTemplate.Remove(upstreamTemplate.Length -1, 1) + "(/|)";
}
var route = reRoute.ReRouteIsCaseSensitive
? $"^{upstreamTemplate}{RegExMatchEndString}"
: $"^{RegExIgnoreCase}{upstreamTemplate}{RegExMatchEndString}";
return new UpstreamPathTemplate(route, 1);
}
private bool ForwardSlashAndOnePlaceHolder(string upstreamTemplate, List<string> placeholders, int postitionOfPlaceHolderClosingBracket)
{
if(upstreamTemplate.Substring(0, 2) == "/{" && placeholders.Count == 1 && upstreamTemplate.Length == postitionOfPlaceHolderClosingBracket + 1)
{
return true;
}
return false;
}
private bool IsPlaceHolder(string upstreamTemplate, int i)
{
return upstreamTemplate[i] == '{';
}
}
using System.Collections.Generic;
using Ocelot.Configuration.File;
using Ocelot.Values;
namespace Ocelot.Configuration.Creator
{
public class UpstreamTemplatePatternCreator : IUpstreamTemplatePatternCreator
{
private const string RegExMatchEverything = "[0-9a-zA-Z].*";
private const string RegExMatchEndString = "$";
private const string RegExIgnoreCase = "(?i)";
private const string RegExForwardSlashOnly = "^/$";
private const string RegExForwardSlashAndOnePlaceHolder = "^/.*";
public UpstreamPathTemplate Create(FileReRoute reRoute)
{
var upstreamTemplate = reRoute.UpstreamPathTemplate;
var placeholders = new List<string>();
for (var i = 0; i < upstreamTemplate.Length; i++)
{
if (IsPlaceHolder(upstreamTemplate, i))
{
var postitionOfPlaceHolderClosingBracket = upstreamTemplate.IndexOf('}', i);
var difference = postitionOfPlaceHolderClosingBracket - i + 1;
var placeHolderName = upstreamTemplate.Substring(i, difference);
placeholders.Add(placeHolderName);
//hack to handle /{url} case
if(ForwardSlashAndOnePlaceHolder(upstreamTemplate, placeholders, postitionOfPlaceHolderClosingBracket))
{
return new UpstreamPathTemplate(RegExForwardSlashAndOnePlaceHolder, 0);
}
}
}
foreach (var placeholder in placeholders)
{
upstreamTemplate = upstreamTemplate.Replace(placeholder, RegExMatchEverything);
}
if (upstreamTemplate == "/")
{
return new UpstreamPathTemplate(RegExForwardSlashOnly, 1);
}
if(upstreamTemplate.EndsWith("/"))
{
upstreamTemplate = upstreamTemplate.Remove(upstreamTemplate.Length -1, 1) + "(/|)";
}
var route = reRoute.ReRouteIsCaseSensitive
? $"^{upstreamTemplate}{RegExMatchEndString}"
: $"^{RegExIgnoreCase}{upstreamTemplate}{RegExMatchEndString}";
return new UpstreamPathTemplate(route, 1);
}
private bool ForwardSlashAndOnePlaceHolder(string upstreamTemplate, List<string> placeholders, int postitionOfPlaceHolderClosingBracket)
{
if(upstreamTemplate.Substring(0, 2) == "/{" && placeholders.Count == 1 && upstreamTemplate.Length == postitionOfPlaceHolderClosingBracket + 1)
{
return true;
}
return false;
}
private bool IsPlaceHolder(string upstreamTemplate, int i)
{
return upstreamTemplate[i] == '{';
}
}
}

View File

@ -0,0 +1,13 @@
namespace Ocelot.Configuration
{
public class DownstreamHostAndPort
{
public DownstreamHostAndPort(string host, int port)
{
Host = host;
Port = port;
}
public string Host { get; private set; }
public int Port { get; private set; }
}
}

View File

@ -1,25 +1,25 @@
using System.Collections.Generic;
using System.Text;
namespace Ocelot.Configuration.File
{
public class FileAuthenticationOptions
{
public FileAuthenticationOptions()
{
AllowedScopes = new List<string>();
}
public string AuthenticationProviderKey {get; set;}
public List<string> AllowedScopes { get; set; }
public override string ToString()
{
var sb = new StringBuilder();
sb.Append($"{nameof(AuthenticationProviderKey)}:{AuthenticationProviderKey},{nameof(AllowedScopes)}:[");
sb.AppendJoin(',', AllowedScopes);
sb.Append("]");
return sb.ToString();
}
}
}
using System.Collections.Generic;
using System.Text;
namespace Ocelot.Configuration.File
{
public class FileAuthenticationOptions
{
public FileAuthenticationOptions()
{
AllowedScopes = new List<string>();
}
public string AuthenticationProviderKey {get; set;}
public List<string> AllowedScopes { get; set; }
public override string ToString()
{
var sb = new StringBuilder();
sb.Append($"{nameof(AuthenticationProviderKey)}:{AuthenticationProviderKey},{nameof(AllowedScopes)}:[");
sb.AppendJoin(',', AllowedScopes);
sb.Append("]");
return sb.ToString();
}
}
}

View File

@ -1,8 +1,8 @@
namespace Ocelot.Configuration.File
{
public class FileCacheOptions
{
public int TtlSeconds { get; set; }
public string Region {get; set;}
}
}
namespace Ocelot.Configuration.File
{
public class FileCacheOptions
{
public int TtlSeconds { get; set; }
public string Region {get; set;}
}
}

View File

@ -1,16 +1,16 @@
using System.Collections.Generic;
namespace Ocelot.Configuration.File
{
public class FileConfiguration
{
public FileConfiguration()
{
ReRoutes = new List<FileReRoute>();
GlobalConfiguration = new FileGlobalConfiguration();
}
public List<FileReRoute> ReRoutes { get; set; }
public FileGlobalConfiguration GlobalConfiguration { get; set; }
}
}
using System.Collections.Generic;
namespace Ocelot.Configuration.File
{
public class FileConfiguration
{
public FileConfiguration()
{
ReRoutes = new List<FileReRoute>();
GlobalConfiguration = new FileGlobalConfiguration();
}
public List<FileReRoute> ReRoutes { get; set; }
public FileGlobalConfiguration GlobalConfiguration { get; set; }
}
}

View File

@ -1,18 +1,18 @@

namespace Ocelot.Configuration.File
{
public class FileGlobalConfiguration
{
public FileGlobalConfiguration()
{
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider();
RateLimitOptions = new FileRateLimitOptions();
}
public string RequestIdKey { get; set; }
public FileServiceDiscoveryProvider ServiceDiscoveryProvider {get;set;}
public FileRateLimitOptions RateLimitOptions { get; set; }
}
}

namespace Ocelot.Configuration.File
{
public class FileGlobalConfiguration
{
public FileGlobalConfiguration()
{
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider();
RateLimitOptions = new FileRateLimitOptions();
}
public string RequestIdKey { get; set; }
public FileServiceDiscoveryProvider ServiceDiscoveryProvider {get;set;}
public FileRateLimitOptions RateLimitOptions { get; set; }
}
}

View File

@ -0,0 +1,8 @@
namespace Ocelot.Configuration.File
{
public class FileHostAndPort
{
public string Host {get;set;}
public int Port { get; set; }
}
}

View File

@ -1,10 +1,10 @@
namespace Ocelot.Configuration.File
{
public class FileIdentityServerConfig
{
public string ProviderRootUrl { get; set; }
public string ApiName { get; set; }
public bool RequireHttps { get; set; }
public string ApiSecret { get; set; }
}
namespace Ocelot.Configuration.File
{
public class FileIdentityServerConfig
{
public string ProviderRootUrl { get; set; }
public string ApiName { get; set; }
public bool RequireHttps { get; set; }
public string ApiSecret { get; set; }
}
}

View File

@ -1,9 +1,9 @@
namespace Ocelot.Configuration.File
{
public class FileJwtConfig
{
public string Authority { get; set; }
public string Audience { get; set; }
}
namespace Ocelot.Configuration.File
{
public class FileJwtConfig
{
public string Authority { get; set; }
public string Audience { get; set; }
}
}

View File

@ -1,11 +1,11 @@
namespace Ocelot.Configuration.File
{
public class FileQoSOptions
{
public int ExceptionsAllowedBeforeBreaking { get; set; }
public int DurationOfBreak { get; set; }
public int TimeoutValue { get; set; }
}
}
namespace Ocelot.Configuration.File
{
public class FileQoSOptions
{
public int ExceptionsAllowedBeforeBreaking { get; set; }
public int DurationOfBreak { get; set; }
public int TimeoutValue { get; set; }
}
}

View File

@ -1,39 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Ocelot.Configuration.File
{
public class FileRateLimitOptions
{
/// <summary>
/// Gets or sets the HTTP header that holds the client identifier, by default is X-ClientId
/// </summary>
public string ClientIdHeader { get; set; } = "ClientId";
/// <summary>
/// Gets or sets a value that will be used as a formatter for the QuotaExceeded response message.
/// If none specified the default will be:
/// API calls quota exceeded! maximum admitted {0} per {1}
/// </summary>
public string QuotaExceededMessage { get; set; }
/// <summary>
/// Gets or sets the counter prefix, used to compose the rate limit counter cache key
/// </summary>
public string RateLimitCounterPrefix { get; set; } = "ocelot";
/// <summary>
/// Disables X-Rate-Limit and Rety-After headers
/// </summary>
public bool DisableRateLimitHeaders { get; set; }
/// <summary>
/// Gets or sets the HTTP Status code returned when rate limiting occurs, by default value is set to 429 (Too Many Requests)
/// </summary>
public int HttpStatusCode { get; set; } = 429;
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Ocelot.Configuration.File
{
public class FileRateLimitOptions
{
/// <summary>
/// Gets or sets the HTTP header that holds the client identifier, by default is X-ClientId
/// </summary>
public string ClientIdHeader { get; set; } = "ClientId";
/// <summary>
/// Gets or sets a value that will be used as a formatter for the QuotaExceeded response message.
/// If none specified the default will be:
/// API calls quota exceeded! maximum admitted {0} per {1}
/// </summary>
public string QuotaExceededMessage { get; set; }
/// <summary>
/// Gets or sets the counter prefix, used to compose the rate limit counter cache key
/// </summary>
public string RateLimitCounterPrefix { get; set; } = "ocelot";
/// <summary>
/// Disables X-Rate-Limit and Rety-After headers
/// </summary>
public bool DisableRateLimitHeaders { get; set; }
/// <summary>
/// Gets or sets the HTTP Status code returned when rate limiting occurs, by default value is set to 429 (Too Many Requests)
/// </summary>
public int HttpStatusCode { get; set; } = 429;
}
}

View File

@ -1,50 +1,50 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Ocelot.Configuration.File
{
public class FileRateLimitRule
{
public FileRateLimitRule()
{
ClientWhitelist = new List<string>();
}
public List<string> ClientWhitelist { get; set; }
/// <summary>
/// Enables endpoint rate limiting based URL path and HTTP verb
/// </summary>
public bool EnableRateLimiting { get; set; }
/// <summary>
/// Rate limit period as in 1s, 1m, 1h
/// </summary>
public string Period { get; set; }
public double PeriodTimespan { get; set; }
/// <summary>
/// Maximum number of requests that a client can make in a defined period
/// </summary>
public long Limit { get; set; }
public override string ToString()
{
if (!EnableRateLimiting)
{
return string.Empty;
}
var sb = new StringBuilder();
sb.Append(
$"{nameof(Period)}:{Period},{nameof(PeriodTimespan)}:{PeriodTimespan:F},{nameof(Limit)}:{Limit},{nameof(ClientWhitelist)}:[");
sb.AppendJoin(',', ClientWhitelist);
sb.Append(']');
return sb.ToString();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Ocelot.Configuration.File
{
public class FileRateLimitRule
{
public FileRateLimitRule()
{
ClientWhitelist = new List<string>();
}
public List<string> ClientWhitelist { get; set; }
/// <summary>
/// Enables endpoint rate limiting based URL path and HTTP verb
/// </summary>
public bool EnableRateLimiting { get; set; }
/// <summary>
/// Rate limit period as in 1s, 1m, 1h
/// </summary>
public string Period { get; set; }
public double PeriodTimespan { get; set; }
/// <summary>
/// Maximum number of requests that a client can make in a defined period
/// </summary>
public long Limit { get; set; }
public override string ToString()
{
if (!EnableRateLimiting)
{
return string.Empty;
}
var sb = new StringBuilder();
sb.Append(
$"{nameof(Period)}:{Period},{nameof(PeriodTimespan)}:{PeriodTimespan:F},{nameof(Limit)}:{Limit},{nameof(ClientWhitelist)}:[");
sb.AppendJoin(',', ClientWhitelist);
sb.Append(']');
return sb.ToString();
}
}
}

View File

@ -1,46 +1,46 @@
using System.Collections.Generic;
namespace Ocelot.Configuration.File
{
public class FileReRoute
{
public FileReRoute()
{
UpstreamHttpMethod = new List<string>();
AddHeadersToRequest = new Dictionary<string, string>();
AddClaimsToRequest = new Dictionary<string, string>();
RouteClaimsRequirement = new Dictionary<string, string>();
AddQueriesToRequest = new Dictionary<string, string>();
DownstreamHeaderTransform = new Dictionary<string, string>();
FileCacheOptions = new FileCacheOptions();
QoSOptions = new FileQoSOptions();
RateLimitOptions = new FileRateLimitRule();
AuthenticationOptions = new FileAuthenticationOptions();
HttpHandlerOptions = new FileHttpHandlerOptions();
UpstreamHeaderTransform = new Dictionary<string, string>();
}
public string DownstreamPathTemplate { get; set; }
public string UpstreamPathTemplate { get; set; }
public List<string> UpstreamHttpMethod { get; set; }
public Dictionary<string, string> AddHeadersToRequest { get; set; }
public Dictionary<string, string> UpstreamHeaderTransform { get; set; }
public Dictionary<string, string> DownstreamHeaderTransform { get; set; }
public Dictionary<string, string> AddClaimsToRequest { get; set; }
public Dictionary<string, string> RouteClaimsRequirement { get; set; }
public Dictionary<string, string> AddQueriesToRequest { get; set; }
public string RequestIdKey { get; set; }
public FileCacheOptions FileCacheOptions { get; set; }
public bool ReRouteIsCaseSensitive { get; set; }
public string ServiceName { get; set; }
public string DownstreamScheme {get;set;}
public string DownstreamHost {get;set;}
public int DownstreamPort { get; set; }
public FileQoSOptions QoSOptions { get; set; }
public string LoadBalancer {get;set;}
public FileRateLimitRule RateLimitOptions { get; set; }
public FileAuthenticationOptions AuthenticationOptions { get; set; }
public FileHttpHandlerOptions HttpHandlerOptions { get; set; }
public bool UseServiceDiscovery {get;set;}
}
}
using System.Collections.Generic;
namespace Ocelot.Configuration.File
{
public class FileReRoute
{
public FileReRoute()
{
UpstreamHttpMethod = new List<string>();
AddHeadersToRequest = new Dictionary<string, string>();
AddClaimsToRequest = new Dictionary<string, string>();
RouteClaimsRequirement = new Dictionary<string, string>();
AddQueriesToRequest = new Dictionary<string, string>();
DownstreamHeaderTransform = new Dictionary<string, string>();
FileCacheOptions = new FileCacheOptions();
QoSOptions = new FileQoSOptions();
RateLimitOptions = new FileRateLimitRule();
AuthenticationOptions = new FileAuthenticationOptions();
HttpHandlerOptions = new FileHttpHandlerOptions();
UpstreamHeaderTransform = new Dictionary<string, string>();
DownstreamHostAndPorts = new List<FileHostAndPort>();
}
public string DownstreamPathTemplate { get; set; }
public string UpstreamPathTemplate { get; set; }
public List<string> UpstreamHttpMethod { get; set; }
public Dictionary<string, string> AddHeadersToRequest { get; set; }
public Dictionary<string, string> UpstreamHeaderTransform { get; set; }
public Dictionary<string, string> DownstreamHeaderTransform { get; set; }
public Dictionary<string, string> AddClaimsToRequest { get; set; }
public Dictionary<string, string> RouteClaimsRequirement { get; set; }
public Dictionary<string, string> AddQueriesToRequest { get; set; }
public string RequestIdKey { get; set; }
public FileCacheOptions FileCacheOptions { get; set; }
public bool ReRouteIsCaseSensitive { get; set; }
public string ServiceName { get; set; }
public string DownstreamScheme {get;set;}
public FileQoSOptions QoSOptions { get; set; }
public string LoadBalancer {get;set;}
public FileRateLimitRule RateLimitOptions { get; set; }
public FileAuthenticationOptions AuthenticationOptions { get; set; }
public FileHttpHandlerOptions HttpHandlerOptions { get; set; }
public bool UseServiceDiscovery {get;set;}
public List<FileHostAndPort> DownstreamHostAndPorts {get;set;}
}
}

View File

@ -1,8 +1,8 @@
namespace Ocelot.Configuration.File
{
public class FileServiceDiscoveryProvider
{
public string Host {get;set;}
public int Port { get; set; }
}
namespace Ocelot.Configuration.File
{
public class FileServiceDiscoveryProvider
{
public string Host {get;set;}
public int Port { get; set; }
}
}

View File

@ -1,69 +1,69 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Ocelot.Configuration.File;
using Ocelot.Configuration.Provider;
using Ocelot.Configuration.Setter;
using Ocelot.Raft;
using Rafty.Concensus;
namespace Ocelot.Configuration
{
[Authorize]
[Route("configuration")]
public class FileConfigurationController : Controller
{
private readonly IFileConfigurationProvider _configGetter;
private readonly IFileConfigurationSetter _configSetter;
private readonly IServiceProvider _serviceProvider;
public FileConfigurationController(IFileConfigurationProvider getFileConfig, IFileConfigurationSetter configSetter, IServiceProvider serviceProvider)
{
_configGetter = getFileConfig;
_configSetter = configSetter;
_serviceProvider = serviceProvider;
}
[HttpGet]
public async Task<IActionResult> Get()
{
var response = await _configGetter.Get();
if(response.IsError)
{
return new BadRequestObjectResult(response.Errors);
}
return new OkObjectResult(response.Data);
}
[HttpPost]
public async Task<IActionResult> Post([FromBody]FileConfiguration fileConfiguration)
{
//todo - this code is a bit shit sort it out..
var test = _serviceProvider.GetService(typeof(INode));
if (test != null)
{
var node = (INode)test;
var result = node.Accept(new UpdateFileConfiguration(fileConfiguration));
if (result.GetType() == typeof(Rafty.Concensus.ErrorResponse<UpdateFileConfiguration>))
{
return new BadRequestObjectResult("There was a problem. This error message sucks raise an issue in GitHub.");
}
return new OkObjectResult(result.Command.Configuration);
}
var response = await _configSetter.Set(fileConfiguration);
if (response.IsError)
{
return new BadRequestObjectResult(response.Errors);
}
return new OkObjectResult(fileConfiguration);
}
}
}
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Ocelot.Configuration.File;
using Ocelot.Configuration.Provider;
using Ocelot.Configuration.Setter;
using Ocelot.Raft;
using Rafty.Concensus;
namespace Ocelot.Configuration
{
[Authorize]
[Route("configuration")]
public class FileConfigurationController : Controller
{
private readonly IFileConfigurationProvider _configGetter;
private readonly IFileConfigurationSetter _configSetter;
private readonly IServiceProvider _serviceProvider;
public FileConfigurationController(IFileConfigurationProvider getFileConfig, IFileConfigurationSetter configSetter, IServiceProvider serviceProvider)
{
_configGetter = getFileConfig;
_configSetter = configSetter;
_serviceProvider = serviceProvider;
}
[HttpGet]
public async Task<IActionResult> Get()
{
var response = await _configGetter.Get();
if(response.IsError)
{
return new BadRequestObjectResult(response.Errors);
}
return new OkObjectResult(response.Data);
}
[HttpPost]
public async Task<IActionResult> Post([FromBody]FileConfiguration fileConfiguration)
{
//todo - this code is a bit shit sort it out..
var test = _serviceProvider.GetService(typeof(INode));
if (test != null)
{
var node = (INode)test;
var result = node.Accept(new UpdateFileConfiguration(fileConfiguration));
if (result.GetType() == typeof(Rafty.Concensus.ErrorResponse<UpdateFileConfiguration>))
{
return new BadRequestObjectResult("There was a problem. This error message sucks raise an issue in GitHub.");
}
return new OkObjectResult(result.Command.Configuration);
}
var response = await _configSetter.Set(fileConfiguration);
if (response.IsError)
{
return new BadRequestObjectResult(response.Errors);
}
return new OkObjectResult(fileConfiguration);
}
}
}

View File

@ -1,20 +1,20 @@
namespace Ocelot.Configuration
{
public class HeaderFindAndReplace
{
public HeaderFindAndReplace(string key, string find, string replace, int index)
{
Key = key;
Find = find;
Replace = replace;
Index = index;
}
public string Key {get;}
public string Find {get;}
public string Replace {get;}
// only index 0 for now..
public int Index {get;}
}
namespace Ocelot.Configuration
{
public class HeaderFindAndReplace
{
public HeaderFindAndReplace(string key, string find, string replace, int index)
{
Key = key;
Find = find;
Replace = replace;
Index = index;
}
public string Key {get;}
public string Find {get;}
public string Replace {get;}
// only index 0 for now..
public int Index {get;}
}
}

View File

@ -1,12 +1,12 @@
using System.Collections.Generic;
namespace Ocelot.Configuration
{
public interface IOcelotConfiguration
{
List<ReRoute> ReRoutes { get; }
string AdministrationPath {get;}
ServiceProviderConfiguration ServiceProviderConfiguration {get;}
string RequestId {get;}
}
using System.Collections.Generic;
namespace Ocelot.Configuration
{
public interface IOcelotConfiguration
{
List<ReRoute> ReRoutes { get; }
string AdministrationPath {get;}
ServiceProviderConfiguration ServiceProviderConfiguration {get;}
string RequestId {get;}
}
}

View File

@ -1,20 +1,20 @@
using System.Collections.Generic;
namespace Ocelot.Configuration
{
public class OcelotConfiguration : IOcelotConfiguration
{
public OcelotConfiguration(List<ReRoute> reRoutes, string administrationPath, ServiceProviderConfiguration serviceProviderConfiguration, string requestId)
{
ReRoutes = reRoutes;
AdministrationPath = administrationPath;
ServiceProviderConfiguration = serviceProviderConfiguration;
RequestId = requestId;
}
public List<ReRoute> ReRoutes { get; }
public string AdministrationPath {get;}
public ServiceProviderConfiguration ServiceProviderConfiguration {get;}
public string RequestId {get;}
}
using System.Collections.Generic;
namespace Ocelot.Configuration
{
public class OcelotConfiguration : IOcelotConfiguration
{
public OcelotConfiguration(List<ReRoute> reRoutes, string administrationPath, ServiceProviderConfiguration serviceProviderConfiguration, string requestId)
{
ReRoutes = reRoutes;
AdministrationPath = administrationPath;
ServiceProviderConfiguration = serviceProviderConfiguration;
RequestId = requestId;
}
public List<ReRoute> ReRoutes { get; }
public string AdministrationPath {get;}
public ServiceProviderConfiguration ServiceProviderConfiguration {get;}
public string RequestId {get;}
}
}

View File

@ -1,73 +1,73 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Ocelot.Errors;
using Ocelot.Responses;
namespace Ocelot.Configuration.Parser
{
public class ClaimToThingConfigurationParser : IClaimToThingConfigurationParser
{
private readonly Regex _claimRegex = new Regex("Claims\\[.*\\]");
private readonly Regex _indexRegex = new Regex("value\\[.*\\]");
private const string SplitToken = ">";
public Response<ClaimToThing> Extract(string existingKey, string value)
{
try
{
var instructions = value.Split(SplitToken.ToCharArray());
if (instructions.Length <= 1)
{
return new ErrorResponse<ClaimToThing>(
new List<Error>
{
new NoInstructionsError(SplitToken)
});
}
var claimMatch = _claimRegex.IsMatch(instructions[0]);
if (!claimMatch)
{
return new ErrorResponse<ClaimToThing>(
new List<Error>
{
new InstructionNotForClaimsError()
});
}
var newKey = GetIndexValue(instructions[0]);
var index = 0;
var delimiter = string.Empty;
if (instructions.Length > 2 && _indexRegex.IsMatch(instructions[1]))
{
index = int.Parse(GetIndexValue(instructions[1]));
delimiter = instructions[2].Trim();
}
return new OkResponse<ClaimToThing>(
new ClaimToThing(existingKey, newKey, delimiter, index));
}
catch (Exception exception)
{
return new ErrorResponse<ClaimToThing>(
new List<Error>
{
new ParsingConfigurationHeaderError(exception)
});
}
}
private string GetIndexValue(string instruction)
{
var firstIndexer = instruction.IndexOf("[", StringComparison.Ordinal);
var lastIndexer = instruction.IndexOf("]", StringComparison.Ordinal);
var length = lastIndexer - firstIndexer;
var claimKey = instruction.Substring(firstIndexer + 1, length - 1);
return claimKey;
}
}
}
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Ocelot.Errors;
using Ocelot.Responses;
namespace Ocelot.Configuration.Parser
{
public class ClaimToThingConfigurationParser : IClaimToThingConfigurationParser
{
private readonly Regex _claimRegex = new Regex("Claims\\[.*\\]");
private readonly Regex _indexRegex = new Regex("value\\[.*\\]");
private const string SplitToken = ">";
public Response<ClaimToThing> Extract(string existingKey, string value)
{
try
{
var instructions = value.Split(SplitToken.ToCharArray());
if (instructions.Length <= 1)
{
return new ErrorResponse<ClaimToThing>(
new List<Error>
{
new NoInstructionsError(SplitToken)
});
}
var claimMatch = _claimRegex.IsMatch(instructions[0]);
if (!claimMatch)
{
return new ErrorResponse<ClaimToThing>(
new List<Error>
{
new InstructionNotForClaimsError()
});
}
var newKey = GetIndexValue(instructions[0]);
var index = 0;
var delimiter = string.Empty;
if (instructions.Length > 2 && _indexRegex.IsMatch(instructions[1]))
{
index = int.Parse(GetIndexValue(instructions[1]));
delimiter = instructions[2].Trim();
}
return new OkResponse<ClaimToThing>(
new ClaimToThing(existingKey, newKey, delimiter, index));
}
catch (Exception exception)
{
return new ErrorResponse<ClaimToThing>(
new List<Error>
{
new ParsingConfigurationHeaderError(exception)
});
}
}
private string GetIndexValue(string instruction)
{
var firstIndexer = instruction.IndexOf("[", StringComparison.Ordinal);
var lastIndexer = instruction.IndexOf("]", StringComparison.Ordinal);
var length = lastIndexer - firstIndexer;
var claimKey = instruction.Substring(firstIndexer + 1, length - 1);
return claimKey;
}
}
}

View File

@ -1,9 +1,9 @@
using Ocelot.Responses;
namespace Ocelot.Configuration.Parser
{
public interface IClaimToThingConfigurationParser
{
Response<ClaimToThing> Extract(string existingKey, string value);
}
using Ocelot.Responses;
namespace Ocelot.Configuration.Parser
{
public interface IClaimToThingConfigurationParser
{
Response<ClaimToThing> Extract(string existingKey, string value);
}
}

View File

@ -1,12 +1,12 @@
using Ocelot.Errors;
namespace Ocelot.Configuration.Parser
{
public class InstructionNotForClaimsError : Error
{
public InstructionNotForClaimsError()
: base("instructions did not contain claims, at the moment we only support claims extraction", OcelotErrorCode.InstructionNotForClaimsError)
{
}
}
}
using Ocelot.Errors;
namespace Ocelot.Configuration.Parser
{
public class InstructionNotForClaimsError : Error
{
public InstructionNotForClaimsError()
: base("instructions did not contain claims, at the moment we only support claims extraction", OcelotErrorCode.InstructionNotForClaimsError)
{
}
}
}

View File

@ -1,12 +1,12 @@
using Ocelot.Errors;
namespace Ocelot.Configuration.Parser
{
public class NoInstructionsError : Error
{
public NoInstructionsError(string splitToken)
: base($"There we no instructions splitting on {splitToken}", OcelotErrorCode.NoInstructionsError)
{
}
}
}
using Ocelot.Errors;
namespace Ocelot.Configuration.Parser
{
public class NoInstructionsError : Error
{
public NoInstructionsError(string splitToken)
: base($"There we no instructions splitting on {splitToken}", OcelotErrorCode.NoInstructionsError)
{
}
}
}

View File

@ -1,13 +1,13 @@
using System;
using Ocelot.Errors;
namespace Ocelot.Configuration.Parser
{
public class ParsingConfigurationHeaderError : Error
{
public ParsingConfigurationHeaderError(Exception exception)
: base($"error parsing configuration eception is {exception.Message}", OcelotErrorCode.ParsingConfigurationHeaderError)
{
}
}
}
using System;
using Ocelot.Errors;
namespace Ocelot.Configuration.Parser
{
public class ParsingConfigurationHeaderError : Error
{
public ParsingConfigurationHeaderError(Exception exception)
: base($"error parsing configuration eception is {exception.Message}", OcelotErrorCode.ParsingConfigurationHeaderError)
{
}
}
}

View File

@ -1,26 +1,26 @@
using System;
using System.IO;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Ocelot.Configuration.File;
using Ocelot.Configuration.Repository;
using Ocelot.Responses;
namespace Ocelot.Configuration.Provider
{
public class FileConfigurationProvider : IFileConfigurationProvider
{
private IFileConfigurationRepository _repo;
public FileConfigurationProvider(IFileConfigurationRepository repo)
{
_repo = repo;
}
public async Task<Response<FileConfiguration>> Get()
{
var fileConfig = await _repo.Get();
return new OkResponse<FileConfiguration>(fileConfig.Data);
}
}
using System;
using System.IO;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Ocelot.Configuration.File;
using Ocelot.Configuration.Repository;
using Ocelot.Responses;
namespace Ocelot.Configuration.Provider
{
public class FileConfigurationProvider : IFileConfigurationProvider
{
private IFileConfigurationRepository _repo;
public FileConfigurationProvider(IFileConfigurationRepository repo)
{
_repo = repo;
}
public async Task<Response<FileConfiguration>> Get()
{
var fileConfig = await _repo.Get();
return new OkResponse<FileConfiguration>(fileConfig.Data);
}
}
}

View File

@ -1,11 +1,11 @@
using System.Threading.Tasks;
using Ocelot.Configuration.File;
using Ocelot.Responses;
namespace Ocelot.Configuration.Provider
{
public interface IFileConfigurationProvider
{
Task<Response<FileConfiguration>> Get();
}
using System.Threading.Tasks;
using Ocelot.Configuration.File;
using Ocelot.Responses;
namespace Ocelot.Configuration.Provider
{
public interface IFileConfigurationProvider
{
Task<Response<FileConfiguration>> Get();
}
}

View File

@ -1,16 +1,16 @@
using System.Collections.Generic;
using IdentityServer4.AccessTokenValidation;
using IdentityServer4.Models;
namespace Ocelot.Configuration.Provider
{
public interface IIdentityServerConfiguration
{
string ApiName { get; }
string ApiSecret { get; }
bool RequireHttps { get; }
List<string> AllowedScopes { get; }
string CredentialsSigningCertificateLocation { get; }
string CredentialsSigningCertificatePassword { get; }
}
using System.Collections.Generic;
using IdentityServer4.AccessTokenValidation;
using IdentityServer4.Models;
namespace Ocelot.Configuration.Provider
{
public interface IIdentityServerConfiguration
{
string ApiName { get; }
string ApiSecret { get; }
bool RequireHttps { get; }
List<string> AllowedScopes { get; }
string CredentialsSigningCertificateLocation { get; }
string CredentialsSigningCertificatePassword { get; }
}
}

View File

@ -1,11 +1,11 @@
using System.Threading.Tasks;
using Ocelot.Configuration.File;
using Ocelot.Responses;
namespace Ocelot.Configuration.Provider
{
public interface IOcelotConfigurationProvider
{
Task<Response<IOcelotConfiguration>> Get();
}
}
using System.Threading.Tasks;
using Ocelot.Configuration.File;
using Ocelot.Responses;
namespace Ocelot.Configuration.Provider
{
public interface IOcelotConfigurationProvider
{
Task<Response<IOcelotConfiguration>> Get();
}
}

View File

@ -1,32 +1,32 @@
using System.Collections.Generic;
using IdentityServer4.AccessTokenValidation;
using IdentityServer4.Models;
namespace Ocelot.Configuration.Provider
{
public class IdentityServerConfiguration : IIdentityServerConfiguration
{
public IdentityServerConfiguration(
string apiName,
bool requireHttps,
string apiSecret,
List<string> allowedScopes,
string credentialsSigningCertificateLocation,
string credentialsSigningCertificatePassword)
{
ApiName = apiName;
RequireHttps = requireHttps;
ApiSecret = apiSecret;
AllowedScopes = allowedScopes;
CredentialsSigningCertificateLocation = credentialsSigningCertificateLocation;
CredentialsSigningCertificatePassword = credentialsSigningCertificatePassword;
}
public string ApiName { get; private set; }
public bool RequireHttps { get; private set; }
public List<string> AllowedScopes { get; private set; }
public string ApiSecret { get; private set; }
public string CredentialsSigningCertificateLocation { get; private set; }
public string CredentialsSigningCertificatePassword { get; private set; }
}
using System.Collections.Generic;
using IdentityServer4.AccessTokenValidation;
using IdentityServer4.Models;
namespace Ocelot.Configuration.Provider
{
public class IdentityServerConfiguration : IIdentityServerConfiguration
{
public IdentityServerConfiguration(
string apiName,
bool requireHttps,
string apiSecret,
List<string> allowedScopes,
string credentialsSigningCertificateLocation,
string credentialsSigningCertificatePassword)
{
ApiName = apiName;
RequireHttps = requireHttps;
ApiSecret = apiSecret;
AllowedScopes = allowedScopes;
CredentialsSigningCertificateLocation = credentialsSigningCertificateLocation;
CredentialsSigningCertificatePassword = credentialsSigningCertificatePassword;
}
public string ApiName { get; private set; }
public bool RequireHttps { get; private set; }
public List<string> AllowedScopes { get; private set; }
public string ApiSecret { get; private set; }
public string CredentialsSigningCertificateLocation { get; private set; }
public string CredentialsSigningCertificatePassword { get; private set; }
}
}

View File

@ -1,32 +1,32 @@
using System.Threading.Tasks;
using Ocelot.Configuration.File;
using Ocelot.Configuration.Repository;
using Ocelot.Responses;
namespace Ocelot.Configuration.Provider
{
/// <summary>
/// Register as singleton
/// </summary>
public class OcelotConfigurationProvider : IOcelotConfigurationProvider
{
private readonly IOcelotConfigurationRepository _config;
public OcelotConfigurationProvider(IOcelotConfigurationRepository repo)
{
_config = repo;
}
public async Task<Response<IOcelotConfiguration>> Get()
{
var repoConfig = await _config.Get();
if (repoConfig.IsError)
{
return new ErrorResponse<IOcelotConfiguration>(repoConfig.Errors);
}
return new OkResponse<IOcelotConfiguration>(repoConfig.Data);
}
}
using System.Threading.Tasks;
using Ocelot.Configuration.File;
using Ocelot.Configuration.Repository;
using Ocelot.Responses;
namespace Ocelot.Configuration.Provider
{
/// <summary>
/// Register as singleton
/// </summary>
public class OcelotConfigurationProvider : IOcelotConfigurationProvider
{
private readonly IOcelotConfigurationRepository _config;
public OcelotConfigurationProvider(IOcelotConfigurationRepository repo)
{
_config = repo;
}
public async Task<Response<IOcelotConfiguration>> Get()
{
var repoConfig = await _config.Get();
if (repoConfig.IsError)
{
return new ErrorResponse<IOcelotConfiguration>(repoConfig.Errors);
}
return new OkResponse<IOcelotConfiguration>(repoConfig.Data);
}
}
}

View File

@ -1,29 +1,29 @@
using Polly.Timeout;
namespace Ocelot.Configuration
{
public class QoSOptions
{
public QoSOptions(
int exceptionsAllowedBeforeBreaking,
int durationofBreak,
int timeoutValue,
TimeoutStrategy timeoutStrategy = TimeoutStrategy.Pessimistic)
{
ExceptionsAllowedBeforeBreaking = exceptionsAllowedBeforeBreaking;
DurationOfBreak = durationofBreak;
TimeoutValue = timeoutValue;
TimeoutStrategy = timeoutStrategy;
}
public int ExceptionsAllowedBeforeBreaking { get; private set; }
public int DurationOfBreak { get; private set; }
public int TimeoutValue { get; private set; }
public TimeoutStrategy TimeoutStrategy { get; private set; }
}
}
using Polly.Timeout;
namespace Ocelot.Configuration
{
public class QoSOptions
{
public QoSOptions(
int exceptionsAllowedBeforeBreaking,
int durationofBreak,
int timeoutValue,
TimeoutStrategy timeoutStrategy = TimeoutStrategy.Pessimistic)
{
ExceptionsAllowedBeforeBreaking = exceptionsAllowedBeforeBreaking;
DurationOfBreak = durationofBreak;
TimeoutValue = timeoutValue;
TimeoutStrategy = timeoutStrategy;
}
public int ExceptionsAllowedBeforeBreaking { get; private set; }
public int DurationOfBreak { get; private set; }
public int TimeoutValue { get; private set; }
public TimeoutStrategy TimeoutStrategy { get; private set; }
}
}

View File

@ -1,61 +1,61 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Ocelot.Configuration
{
/// <summary>
/// RateLimit Options
/// </summary>
public class RateLimitOptions
{
public RateLimitOptions(bool enbleRateLimiting, string clientIdHeader, List<string> clientWhitelist,bool disableRateLimitHeaders,
string quotaExceededMessage, string rateLimitCounterPrefix, RateLimitRule rateLimitRule, int httpStatusCode)
{
EnableRateLimiting = enbleRateLimiting;
ClientIdHeader = clientIdHeader;
ClientWhitelist = clientWhitelist?? new List<string>();
DisableRateLimitHeaders = disableRateLimitHeaders;
QuotaExceededMessage = quotaExceededMessage;
RateLimitCounterPrefix = rateLimitCounterPrefix;
RateLimitRule = rateLimitRule;
HttpStatusCode = httpStatusCode;
}
public RateLimitRule RateLimitRule { get; private set; }
public List<string> ClientWhitelist { get; private set; }
/// <summary>
/// Gets or sets the HTTP header that holds the client identifier, by default is X-ClientId
/// </summary>
public string ClientIdHeader { get; private set; }
/// <summary>
/// Gets or sets the HTTP Status code returned when rate limiting occurs, by default value is set to 429 (Too Many Requests)
/// </summary>
public int HttpStatusCode { get; private set; }
/// <summary>
/// Gets or sets a value that will be used as a formatter for the QuotaExceeded response message.
/// If none specified the default will be:
/// API calls quota exceeded! maximum admitted {0} per {1}
/// </summary>
public string QuotaExceededMessage { get; private set; }
/// <summary>
/// Gets or sets the counter prefix, used to compose the rate limit counter cache key
/// </summary>
public string RateLimitCounterPrefix { get; private set; }
/// <summary>
/// Enables endpoint rate limiting based URL path and HTTP verb
/// </summary>
public bool EnableRateLimiting { get; private set; }
/// <summary>
/// Disables X-Rate-Limit and Rety-After headers
/// </summary>
public bool DisableRateLimitHeaders { get; private set; }
}
}
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Ocelot.Configuration
{
/// <summary>
/// RateLimit Options
/// </summary>
public class RateLimitOptions
{
public RateLimitOptions(bool enbleRateLimiting, string clientIdHeader, List<string> clientWhitelist,bool disableRateLimitHeaders,
string quotaExceededMessage, string rateLimitCounterPrefix, RateLimitRule rateLimitRule, int httpStatusCode)
{
EnableRateLimiting = enbleRateLimiting;
ClientIdHeader = clientIdHeader;
ClientWhitelist = clientWhitelist?? new List<string>();
DisableRateLimitHeaders = disableRateLimitHeaders;
QuotaExceededMessage = quotaExceededMessage;
RateLimitCounterPrefix = rateLimitCounterPrefix;
RateLimitRule = rateLimitRule;
HttpStatusCode = httpStatusCode;
}
public RateLimitRule RateLimitRule { get; private set; }
public List<string> ClientWhitelist { get; private set; }
/// <summary>
/// Gets or sets the HTTP header that holds the client identifier, by default is X-ClientId
/// </summary>
public string ClientIdHeader { get; private set; }
/// <summary>
/// Gets or sets the HTTP Status code returned when rate limiting occurs, by default value is set to 429 (Too Many Requests)
/// </summary>
public int HttpStatusCode { get; private set; }
/// <summary>
/// Gets or sets a value that will be used as a formatter for the QuotaExceeded response message.
/// If none specified the default will be:
/// API calls quota exceeded! maximum admitted {0} per {1}
/// </summary>
public string QuotaExceededMessage { get; private set; }
/// <summary>
/// Gets or sets the counter prefix, used to compose the rate limit counter cache key
/// </summary>
public string RateLimitCounterPrefix { get; private set; }
/// <summary>
/// Enables endpoint rate limiting based URL path and HTTP verb
/// </summary>
public bool EnableRateLimiting { get; private set; }
/// <summary>
/// Disables X-Rate-Limit and Rety-After headers
/// </summary>
public bool DisableRateLimitHeaders { get; private set; }
}
}

View File

@ -1,25 +1,25 @@
using System;
namespace Ocelot.Configuration
{
public class RateLimitRule
{
public RateLimitRule(string period, double periodTimespan, long limit)
{
Period = period;
PeriodTimespan = periodTimespan;
Limit = limit;
}
/// <summary>
/// Rate limit period as in 1s, 1m, 1h,1d
/// </summary>
public string Period { get; private set; }
public double PeriodTimespan { get; private set; }
/// <summary>
/// Maximum number of requests that a client can make in a defined period
/// </summary>
public long Limit { get; private set; }
}
using System;
namespace Ocelot.Configuration
{
public class RateLimitRule
{
public RateLimitRule(string period, double periodTimespan, long limit)
{
Period = period;
PeriodTimespan = periodTimespan;
Limit = limit;
}
/// <summary>
/// Rate limit period as in 1s, 1m, 1h,1d
/// </summary>
public string Period { get; private set; }
public double PeriodTimespan { get; private set; }
/// <summary>
/// Maximum number of requests that a client can make in a defined period
/// </summary>
public long Limit { get; private set; }
}
}

View File

@ -1,102 +1,99 @@
using System.Collections.Generic;
using System.Net.Http;
using Ocelot.Configuration.Creator;
using Ocelot.Values;
namespace Ocelot.Configuration
{
public class ReRoute
{
public ReRoute(PathTemplate downstreamPathTemplate,
PathTemplate upstreamPathTemplate,
List<HttpMethod> upstreamHttpMethod,
UpstreamPathTemplate upstreamTemplatePattern,
bool isAuthenticated,
AuthenticationOptions authenticationOptions,
List<ClaimToThing> claimsToHeaders,
List<ClaimToThing> claimsToClaims,
Dictionary<string, string> routeClaimsRequirement,
bool isAuthorised,
List<ClaimToThing> claimsToQueries,
string requestIdKey,
bool isCached,
CacheOptions cacheOptions,
string downstreamScheme,
string loadBalancer,
string downstreamHost,
int downstreamPort,
string reRouteKey,
bool isQos,
QoSOptions qosOptions,
bool enableEndpointRateLimiting,
RateLimitOptions ratelimitOptions,
HttpHandlerOptions httpHandlerOptions,
bool useServiceDiscovery,
string serviceName,
List<HeaderFindAndReplace> upstreamHeadersFindAndReplace,
List<HeaderFindAndReplace> downstreamHeadersFindAndReplace)
{
DownstreamHeadersFindAndReplace = downstreamHeadersFindAndReplace;
UpstreamHeadersFindAndReplace = upstreamHeadersFindAndReplace;
ServiceName = serviceName;
UseServiceDiscovery = useServiceDiscovery;
ReRouteKey = reRouteKey;
LoadBalancer = loadBalancer;
DownstreamHost = downstreamHost;
DownstreamPort = downstreamPort;
DownstreamPathTemplate = downstreamPathTemplate;
UpstreamPathTemplate = upstreamPathTemplate;
UpstreamHttpMethod = upstreamHttpMethod;
UpstreamTemplatePattern = upstreamTemplatePattern;
IsAuthenticated = isAuthenticated;
AuthenticationOptions = authenticationOptions;
RouteClaimsRequirement = routeClaimsRequirement;
IsAuthorised = isAuthorised;
RequestIdKey = requestIdKey;
IsCached = isCached;
CacheOptions = cacheOptions;
ClaimsToQueries = claimsToQueries
?? new List<ClaimToThing>();
ClaimsToClaims = claimsToClaims
?? new List<ClaimToThing>();
ClaimsToHeaders = claimsToHeaders
?? new List<ClaimToThing>();
DownstreamScheme = downstreamScheme;
IsQos = isQos;
QosOptionsOptions = qosOptions;
EnableEndpointEndpointRateLimiting = enableEndpointRateLimiting;
RateLimitOptions = ratelimitOptions;
HttpHandlerOptions = httpHandlerOptions;
}
public string ReRouteKey {get;private set;}
public PathTemplate DownstreamPathTemplate { get; private set; }
public PathTemplate UpstreamPathTemplate { get; private set; }
public UpstreamPathTemplate UpstreamTemplatePattern { get; private set; }
public List<HttpMethod> UpstreamHttpMethod { get; private set; }
public bool IsAuthenticated { get; private set; }
public bool IsAuthorised { get; private set; }
public AuthenticationOptions AuthenticationOptions { get; private set; }
public List<ClaimToThing> ClaimsToQueries { get; private set; }
public List<ClaimToThing> ClaimsToHeaders { get; private set; }
public List<ClaimToThing> ClaimsToClaims { get; private set; }
public Dictionary<string, string> RouteClaimsRequirement { get; private set; }
public string RequestIdKey { get; private set; }
public bool IsCached { get; private set; }
public CacheOptions CacheOptions { get; private set; }
public string DownstreamScheme {get;private set;}
public bool IsQos { get; private set; }
public QoSOptions QosOptionsOptions { get; private set; }
public string LoadBalancer {get;private set;}
public string DownstreamHost { get; private set; }
public int DownstreamPort { get; private set; }
public bool EnableEndpointEndpointRateLimiting { get; private set; }
public RateLimitOptions RateLimitOptions { get; private set; }
public HttpHandlerOptions HttpHandlerOptions { get; private set; }
public bool UseServiceDiscovery {get;private set;}
public string ServiceName {get;private set;}
public List<HeaderFindAndReplace> UpstreamHeadersFindAndReplace {get;private set;}
public List<HeaderFindAndReplace> DownstreamHeadersFindAndReplace {get;private set;}
}
}
using System.Collections.Generic;
using System.Net.Http;
using Ocelot.Configuration.Creator;
using Ocelot.Values;
namespace Ocelot.Configuration
{
public class ReRoute
{
public ReRoute(PathTemplate downstreamPathTemplate,
PathTemplate upstreamPathTemplate,
List<HttpMethod> upstreamHttpMethod,
UpstreamPathTemplate upstreamTemplatePattern,
bool isAuthenticated,
AuthenticationOptions authenticationOptions,
List<ClaimToThing> claimsToHeaders,
List<ClaimToThing> claimsToClaims,
Dictionary<string, string> routeClaimsRequirement,
bool isAuthorised,
List<ClaimToThing> claimsToQueries,
string requestIdKey,
bool isCached,
CacheOptions cacheOptions,
string downstreamScheme,
string loadBalancer,
string reRouteKey,
bool isQos,
QoSOptions qosOptions,
bool enableEndpointRateLimiting,
RateLimitOptions ratelimitOptions,
HttpHandlerOptions httpHandlerOptions,
bool useServiceDiscovery,
string serviceName,
List<HeaderFindAndReplace> upstreamHeadersFindAndReplace,
List<HeaderFindAndReplace> downstreamHeadersFindAndReplace,
List<DownstreamHostAndPort> downstreamAddresses)
{
DownstreamHeadersFindAndReplace = downstreamHeadersFindAndReplace;
UpstreamHeadersFindAndReplace = upstreamHeadersFindAndReplace;
ServiceName = serviceName;
UseServiceDiscovery = useServiceDiscovery;
ReRouteKey = reRouteKey;
LoadBalancer = loadBalancer;
DownstreamAddresses = downstreamAddresses;
DownstreamPathTemplate = downstreamPathTemplate;
UpstreamPathTemplate = upstreamPathTemplate;
UpstreamHttpMethod = upstreamHttpMethod;
UpstreamTemplatePattern = upstreamTemplatePattern;
IsAuthenticated = isAuthenticated;
AuthenticationOptions = authenticationOptions;
RouteClaimsRequirement = routeClaimsRequirement;
IsAuthorised = isAuthorised;
RequestIdKey = requestIdKey;
IsCached = isCached;
CacheOptions = cacheOptions;
ClaimsToQueries = claimsToQueries
?? new List<ClaimToThing>();
ClaimsToClaims = claimsToClaims
?? new List<ClaimToThing>();
ClaimsToHeaders = claimsToHeaders
?? new List<ClaimToThing>();
DownstreamScheme = downstreamScheme;
IsQos = isQos;
QosOptionsOptions = qosOptions;
EnableEndpointEndpointRateLimiting = enableEndpointRateLimiting;
RateLimitOptions = ratelimitOptions;
HttpHandlerOptions = httpHandlerOptions;
}
public string ReRouteKey {get;private set;}
public PathTemplate DownstreamPathTemplate { get; private set; }
public PathTemplate UpstreamPathTemplate { get; private set; }
public UpstreamPathTemplate UpstreamTemplatePattern { get; private set; }
public List<HttpMethod> UpstreamHttpMethod { get; private set; }
public bool IsAuthenticated { get; private set; }
public bool IsAuthorised { get; private set; }
public AuthenticationOptions AuthenticationOptions { get; private set; }
public List<ClaimToThing> ClaimsToQueries { get; private set; }
public List<ClaimToThing> ClaimsToHeaders { get; private set; }
public List<ClaimToThing> ClaimsToClaims { get; private set; }
public Dictionary<string, string> RouteClaimsRequirement { get; private set; }
public string RequestIdKey { get; private set; }
public bool IsCached { get; private set; }
public CacheOptions CacheOptions { get; private set; }
public string DownstreamScheme {get;private set;}
public bool IsQos { get; private set; }
public QoSOptions QosOptionsOptions { get; private set; }
public string LoadBalancer {get;private set;}
public bool EnableEndpointEndpointRateLimiting { get; private set; }
public RateLimitOptions RateLimitOptions { get; private set; }
public HttpHandlerOptions HttpHandlerOptions { get; private set; }
public bool UseServiceDiscovery {get;private set;}
public string ServiceName {get;private set;}
public List<HeaderFindAndReplace> UpstreamHeadersFindAndReplace {get;private set;}
public List<HeaderFindAndReplace> DownstreamHeadersFindAndReplace {get;private set;}
public List<DownstreamHostAndPort> DownstreamAddresses {get;private set;}
}
}

View File

@ -1,20 +1,20 @@
namespace Ocelot.Configuration
{
public class ReRouteOptions
{
public ReRouteOptions(bool isAuthenticated, bool isAuthorised, bool isCached, bool isQos, bool isEnableRateLimiting)
{
IsAuthenticated = isAuthenticated;
IsAuthorised = isAuthorised;
IsCached = isCached;
IsQos = isQos;
EnableRateLimiting = isEnableRateLimiting;
}
public bool IsAuthenticated { get; private set; }
public bool IsAuthorised { get; private set; }
public bool IsCached { get; private set; }
public bool IsQos { get; private set; }
public bool EnableRateLimiting { get; private set; }
}
namespace Ocelot.Configuration
{
public class ReRouteOptions
{
public ReRouteOptions(bool isAuthenticated, bool isAuthorised, bool isCached, bool isQos, bool isEnableRateLimiting)
{
IsAuthenticated = isAuthenticated;
IsAuthorised = isAuthorised;
IsCached = isCached;
IsQos = isQos;
EnableRateLimiting = isEnableRateLimiting;
}
public bool IsAuthenticated { get; private set; }
public bool IsAuthorised { get; private set; }
public bool IsCached { get; private set; }
public bool IsQos { get; private set; }
public bool EnableRateLimiting { get; private set; }
}
}

View File

@ -1,80 +1,80 @@
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Ocelot.Configuration.File;
using Ocelot.Configuration.Setter;
using Ocelot.Logging;
namespace Ocelot.Configuration.Repository
{
public class ConsulFileConfigurationPoller : IDisposable
{
private IOcelotLogger _logger;
private IFileConfigurationRepository _repo;
private IFileConfigurationSetter _setter;
private string _previousAsJson;
private Timer _timer;
private bool _polling;
public ConsulFileConfigurationPoller(IOcelotLoggerFactory factory, IFileConfigurationRepository repo, IFileConfigurationSetter setter)
{
_setter = setter;
_logger = factory.CreateLogger<ConsulFileConfigurationPoller>();
_repo = repo;
_previousAsJson = "";
_timer = new Timer(async x =>
{
if(_polling)
{
return;
}
_polling = true;
await Poll();
_polling = false;
}, null, 0, 1000);
}
private async Task Poll()
{
_logger.LogDebug("Started polling consul");
var fileConfig = await _repo.Get();
if(fileConfig.IsError)
{
_logger.LogDebug($"error geting file config, errors are {string.Join(",", fileConfig.Errors.Select(x => x.Message))}");
return;
}
var asJson = ToJson(fileConfig.Data);
if(!fileConfig.IsError && asJson != _previousAsJson)
{
await _setter.Set(fileConfig.Data);
_previousAsJson = asJson;
}
_logger.LogDebug("Finished polling consul");
}
/// <summary>
/// We could do object comparison here but performance isnt really a problem. This might be an issue one day!
/// </summary>
/// <param name="config"></param>
/// <returns></returns>
private string ToJson(FileConfiguration config)
{
var currentHash = JsonConvert.SerializeObject(config);
return currentHash;
}
public void Dispose()
{
_timer.Dispose();
}
}
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Ocelot.Configuration.File;
using Ocelot.Configuration.Setter;
using Ocelot.Logging;
namespace Ocelot.Configuration.Repository
{
public class ConsulFileConfigurationPoller : IDisposable
{
private IOcelotLogger _logger;
private IFileConfigurationRepository _repo;
private IFileConfigurationSetter _setter;
private string _previousAsJson;
private Timer _timer;
private bool _polling;
public ConsulFileConfigurationPoller(IOcelotLoggerFactory factory, IFileConfigurationRepository repo, IFileConfigurationSetter setter)
{
_setter = setter;
_logger = factory.CreateLogger<ConsulFileConfigurationPoller>();
_repo = repo;
_previousAsJson = "";
_timer = new Timer(async x =>
{
if(_polling)
{
return;
}
_polling = true;
await Poll();
_polling = false;
}, null, 0, 1000);
}
private async Task Poll()
{
_logger.LogDebug("Started polling consul");
var fileConfig = await _repo.Get();
if(fileConfig.IsError)
{
_logger.LogDebug($"error geting file config, errors are {string.Join(",", fileConfig.Errors.Select(x => x.Message))}");
return;
}
var asJson = ToJson(fileConfig.Data);
if(!fileConfig.IsError && asJson != _previousAsJson)
{
await _setter.Set(fileConfig.Data);
_previousAsJson = asJson;
}
_logger.LogDebug("Finished polling consul");
}
/// <summary>
/// We could do object comparison here but performance isnt really a problem. This might be an issue one day!
/// </summary>
/// <param name="config"></param>
/// <returns></returns>
private string ToJson(FileConfiguration config)
{
var currentHash = JsonConvert.SerializeObject(config);
return currentHash;
}
public void Dispose()
{
_timer.Dispose();
}
}
}

View File

@ -1,79 +1,79 @@
using System;
using System.Text;
using System.Threading.Tasks;
using Consul;
using Newtonsoft.Json;
using Ocelot.Configuration.File;
using Ocelot.Responses;
using Ocelot.ServiceDiscovery;
namespace Ocelot.Configuration.Repository
{
public class ConsulFileConfigurationRepository : IFileConfigurationRepository
{
private readonly ConsulClient _consul;
private string _ocelotConfiguration = "OcelotConfiguration";
private readonly Cache.IOcelotCache<FileConfiguration> _cache;
public ConsulFileConfigurationRepository(Cache.IOcelotCache<FileConfiguration> cache, ServiceProviderConfiguration serviceProviderConfig)
{
var consulHost = string.IsNullOrEmpty(serviceProviderConfig?.ServiceProviderHost) ? "localhost" : serviceProviderConfig?.ServiceProviderHost;
var consulPort = serviceProviderConfig?.ServiceProviderPort ?? 8500;
var configuration = new ConsulRegistryConfiguration(consulHost, consulPort, _ocelotConfiguration);
_cache = cache;
_consul = new ConsulClient(c =>
{
c.Address = new Uri($"http://{configuration.HostName}:{configuration.Port}");
});
}
public async Task<Response<FileConfiguration>> Get()
{
var config = _cache.Get(_ocelotConfiguration, _ocelotConfiguration);
if (config != null)
{
return new OkResponse<FileConfiguration>(config);
}
var queryResult = await _consul.KV.Get(_ocelotConfiguration);
if (queryResult.Response == null)
{
return new OkResponse<FileConfiguration>(null);
}
var bytes = queryResult.Response.Value;
var json = Encoding.UTF8.GetString(bytes);
var consulConfig = JsonConvert.DeserializeObject<FileConfiguration>(json);
return new OkResponse<FileConfiguration>(consulConfig);
}
public async Task<Response> Set(FileConfiguration ocelotConfiguration)
{
var json = JsonConvert.SerializeObject(ocelotConfiguration);
var bytes = Encoding.UTF8.GetBytes(json);
var kvPair = new KVPair(_ocelotConfiguration)
{
Value = bytes
};
var result = await _consul.KV.Put(kvPair);
if (result.Response)
{
_cache.AddAndDelete(_ocelotConfiguration, ocelotConfiguration, TimeSpan.FromSeconds(3), _ocelotConfiguration);
return new OkResponse();
}
return new ErrorResponse(new UnableToSetConfigInConsulError($"Unable to set FileConfiguration in consul, response status code from consul was {result.StatusCode}"));
}
}
using System;
using System.Text;
using System.Threading.Tasks;
using Consul;
using Newtonsoft.Json;
using Ocelot.Configuration.File;
using Ocelot.Responses;
using Ocelot.ServiceDiscovery;
namespace Ocelot.Configuration.Repository
{
public class ConsulFileConfigurationRepository : IFileConfigurationRepository
{
private readonly ConsulClient _consul;
private string _ocelotConfiguration = "OcelotConfiguration";
private readonly Cache.IOcelotCache<FileConfiguration> _cache;
public ConsulFileConfigurationRepository(Cache.IOcelotCache<FileConfiguration> cache, ServiceProviderConfiguration serviceProviderConfig)
{
var consulHost = string.IsNullOrEmpty(serviceProviderConfig?.ServiceProviderHost) ? "localhost" : serviceProviderConfig?.ServiceProviderHost;
var consulPort = serviceProviderConfig?.ServiceProviderPort ?? 8500;
var configuration = new ConsulRegistryConfiguration(consulHost, consulPort, _ocelotConfiguration);
_cache = cache;
_consul = new ConsulClient(c =>
{
c.Address = new Uri($"http://{configuration.HostName}:{configuration.Port}");
});
}
public async Task<Response<FileConfiguration>> Get()
{
var config = _cache.Get(_ocelotConfiguration, _ocelotConfiguration);
if (config != null)
{
return new OkResponse<FileConfiguration>(config);
}
var queryResult = await _consul.KV.Get(_ocelotConfiguration);
if (queryResult.Response == null)
{
return new OkResponse<FileConfiguration>(null);
}
var bytes = queryResult.Response.Value;
var json = Encoding.UTF8.GetString(bytes);
var consulConfig = JsonConvert.DeserializeObject<FileConfiguration>(json);
return new OkResponse<FileConfiguration>(consulConfig);
}
public async Task<Response> Set(FileConfiguration ocelotConfiguration)
{
var json = JsonConvert.SerializeObject(ocelotConfiguration);
var bytes = Encoding.UTF8.GetBytes(json);
var kvPair = new KVPair(_ocelotConfiguration)
{
Value = bytes
};
var result = await _consul.KV.Put(kvPair);
if (result.Response)
{
_cache.AddAndDelete(_ocelotConfiguration, ocelotConfiguration, TimeSpan.FromSeconds(3), _ocelotConfiguration);
return new OkResponse();
}
return new ErrorResponse(new UnableToSetConfigInConsulError($"Unable to set FileConfiguration in consul, response status code from consul was {result.StatusCode}"));
}
}
}

View File

@ -1,52 +1,52 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Newtonsoft.Json;
using Ocelot.Configuration.File;
using Ocelot.Responses;
namespace Ocelot.Configuration.Repository
{
public class FileConfigurationRepository : IFileConfigurationRepository
{
private readonly string _configFilePath;
private static readonly object _lock = new object();
public FileConfigurationRepository(IHostingEnvironment hostingEnvironment)
{
_configFilePath = $"{AppContext.BaseDirectory}/configuration{(string.IsNullOrEmpty(hostingEnvironment.EnvironmentName) ? string.Empty : ".")}{hostingEnvironment.EnvironmentName}.json";
}
public async Task<Response<FileConfiguration>> Get()
{
string jsonConfiguration;
lock(_lock)
{
jsonConfiguration = System.IO.File.ReadAllText(_configFilePath);
}
var fileConfiguration = JsonConvert.DeserializeObject<FileConfiguration>(jsonConfiguration);
return new OkResponse<FileConfiguration>(fileConfiguration);
}
public async Task<Response> Set(FileConfiguration fileConfiguration)
{
string jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration);
lock(_lock)
{
if (System.IO.File.Exists(_configFilePath))
{
System.IO.File.Delete(_configFilePath);
}
System.IO.File.WriteAllText(_configFilePath, jsonConfiguration);
}
return new OkResponse();
}
}
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Newtonsoft.Json;
using Ocelot.Configuration.File;
using Ocelot.Responses;
namespace Ocelot.Configuration.Repository
{
public class FileConfigurationRepository : IFileConfigurationRepository
{
private readonly string _configFilePath;
private static readonly object _lock = new object();
public FileConfigurationRepository(IHostingEnvironment hostingEnvironment)
{
_configFilePath = $"{AppContext.BaseDirectory}/configuration{(string.IsNullOrEmpty(hostingEnvironment.EnvironmentName) ? string.Empty : ".")}{hostingEnvironment.EnvironmentName}.json";
}
public async Task<Response<FileConfiguration>> Get()
{
string jsonConfiguration;
lock(_lock)
{
jsonConfiguration = System.IO.File.ReadAllText(_configFilePath);
}
var fileConfiguration = JsonConvert.DeserializeObject<FileConfiguration>(jsonConfiguration);
return new OkResponse<FileConfiguration>(fileConfiguration);
}
public async Task<Response> Set(FileConfiguration fileConfiguration)
{
string jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration);
lock(_lock)
{
if (System.IO.File.Exists(_configFilePath))
{
System.IO.File.Delete(_configFilePath);
}
System.IO.File.WriteAllText(_configFilePath, jsonConfiguration);
}
return new OkResponse();
}
}
}

View File

@ -1,12 +1,12 @@
using System.Threading.Tasks;
using Ocelot.Configuration.File;
using Ocelot.Responses;
namespace Ocelot.Configuration.Repository
{
public interface IFileConfigurationRepository
{
Task<Response<FileConfiguration>> Get();
Task<Response> Set(FileConfiguration fileConfiguration);
}
using System.Threading.Tasks;
using Ocelot.Configuration.File;
using Ocelot.Responses;
namespace Ocelot.Configuration.Repository
{
public interface IFileConfigurationRepository
{
Task<Response<FileConfiguration>> Get();
Task<Response> Set(FileConfiguration fileConfiguration);
}
}

View File

@ -1,12 +1,12 @@
using System.Threading.Tasks;
using Ocelot.Configuration.File;
using Ocelot.Responses;
namespace Ocelot.Configuration.Repository
{
public interface IOcelotConfigurationRepository
{
Task<Response<IOcelotConfiguration>> Get();
Task<Response> AddOrReplace(IOcelotConfiguration ocelotConfiguration);
}
using System.Threading.Tasks;
using Ocelot.Configuration.File;
using Ocelot.Responses;
namespace Ocelot.Configuration.Repository
{
public interface IOcelotConfigurationRepository
{
Task<Response<IOcelotConfiguration>> Get();
Task<Response> AddOrReplace(IOcelotConfiguration ocelotConfiguration);
}
}

View File

@ -1,30 +1,30 @@
using System.Threading.Tasks;
using Ocelot.Responses;
namespace Ocelot.Configuration.Repository
{
/// <summary>
/// Register as singleton
/// </summary>
public class InMemoryOcelotConfigurationRepository : IOcelotConfigurationRepository
{
private static readonly object LockObject = new object();
private IOcelotConfiguration _ocelotConfiguration;
public async Task<Response<IOcelotConfiguration>> Get()
{
return new OkResponse<IOcelotConfiguration>(_ocelotConfiguration);
}
public async Task<Response> AddOrReplace(IOcelotConfiguration ocelotConfiguration)
{
lock (LockObject)
{
_ocelotConfiguration = ocelotConfiguration;
}
return new OkResponse();
}
}
using System.Threading.Tasks;
using Ocelot.Responses;
namespace Ocelot.Configuration.Repository
{
/// <summary>
/// Register as singleton
/// </summary>
public class InMemoryOcelotConfigurationRepository : IOcelotConfigurationRepository
{
private static readonly object LockObject = new object();
private IOcelotConfiguration _ocelotConfiguration;
public async Task<Response<IOcelotConfiguration>> Get()
{
return new OkResponse<IOcelotConfiguration>(_ocelotConfiguration);
}
public async Task<Response> AddOrReplace(IOcelotConfiguration ocelotConfiguration)
{
lock (LockObject)
{
_ocelotConfiguration = ocelotConfiguration;
}
return new OkResponse();
}
}
}

Some files were not shown because too many files have changed in this diff Show More