mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-06-19 07:48:16 +08:00
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:
@ -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; }
|
||||
}
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
namespace Ocelot.Authentication.Handler
|
||||
{
|
||||
public enum SupportedAuthenticationProviders
|
||||
{
|
||||
IdentityServer,
|
||||
Jwt
|
||||
}
|
||||
}
|
||||
namespace Ocelot.Authentication.Handler
|
||||
{
|
||||
public enum SupportedAuthenticationProviders
|
||||
{
|
||||
IdentityServer,
|
||||
Jwt
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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>();
|
||||
}
|
||||
}
|
||||
}
|
@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;}
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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>();
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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;}
|
||||
}
|
||||
}
|
||||
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
using System.Collections.Generic;
|
||||
using Ocelot.Configuration.File;
|
||||
|
||||
namespace Ocelot.Configuration.Creator
|
||||
{
|
||||
public interface IDownstreamAddressesCreator
|
||||
{
|
||||
List<DownstreamHostAndPort> Create(FileReRoute reRoute);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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] == '{';
|
||||
}
|
||||
}
|
||||
}
|
13
src/Ocelot/Configuration/DownstreamHostAndPort.cs
Normal file
13
src/Ocelot/Configuration/DownstreamHostAndPort.cs
Normal 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; }
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;}
|
||||
}
|
||||
}
|
||||
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
8
src/Ocelot/Configuration/File/FileHostAndPort.cs
Normal file
8
src/Ocelot/Configuration/File/FileHostAndPort.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace Ocelot.Configuration.File
|
||||
{
|
||||
public class FileHostAndPort
|
||||
{
|
||||
public string Host {get;set;}
|
||||
public int Port { get; set; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;}
|
||||
}
|
||||
}
|
||||
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;}
|
||||
}
|
||||
}
|
@ -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;}
|
||||
}
|
||||
}
|
@ -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;}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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; }
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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;}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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; }
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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}"));
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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
Reference in New Issue
Block a user