mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-04-22 06:22:50 +08:00
Merge pull request #85 from TomPallister/feature/config-in-consul
added a new implementation that stores the ocelot config in consul kv…
This commit is contained in:
commit
8d31b40c21
@ -5,6 +5,7 @@ namespace Ocelot.Cache
|
|||||||
public interface IOcelotCache<T>
|
public interface IOcelotCache<T>
|
||||||
{
|
{
|
||||||
void Add(string key, T value, TimeSpan ttl);
|
void Add(string key, T value, TimeSpan ttl);
|
||||||
|
void AddAndDelete(string key, T value, TimeSpan ttl);
|
||||||
T Get(string key);
|
T Get(string key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,18 @@ namespace Ocelot.Cache
|
|||||||
_cacheManager.Add(new CacheItem<T>(key, value, ExpirationMode.Absolute, ttl));
|
_cacheManager.Add(new CacheItem<T>(key, value, ExpirationMode.Absolute, ttl));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AddAndDelete(string key, T value, TimeSpan ttl)
|
||||||
|
{
|
||||||
|
var exists = _cacheManager.Get(key);
|
||||||
|
|
||||||
|
if (exists != null)
|
||||||
|
{
|
||||||
|
_cacheManager.Remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
_cacheManager.Add(new CacheItem<T>(key, value, ExpirationMode.Absolute, ttl));
|
||||||
|
}
|
||||||
|
|
||||||
public T Get(string key)
|
public T Get(string key)
|
||||||
{
|
{
|
||||||
return _cacheManager.Get<T>(key);
|
return _cacheManager.Get<T>(key);
|
||||||
|
@ -21,7 +21,7 @@ namespace Ocelot.Configuration.Creator
|
|||||||
.WithQuotaExceededMessage(globalConfiguration.RateLimitOptions.QuotaExceededMessage)
|
.WithQuotaExceededMessage(globalConfiguration.RateLimitOptions.QuotaExceededMessage)
|
||||||
.WithRateLimitCounterPrefix(globalConfiguration.RateLimitOptions.RateLimitCounterPrefix)
|
.WithRateLimitCounterPrefix(globalConfiguration.RateLimitOptions.RateLimitCounterPrefix)
|
||||||
.WithRateLimitRule(new RateLimitRule(fileReRoute.RateLimitOptions.Period,
|
.WithRateLimitRule(new RateLimitRule(fileReRoute.RateLimitOptions.Period,
|
||||||
TimeSpan.FromSeconds(fileReRoute.RateLimitOptions.PeriodTimespan),
|
fileReRoute.RateLimitOptions.PeriodTimespan,
|
||||||
fileReRoute.RateLimitOptions.Limit))
|
fileReRoute.RateLimitOptions.Limit))
|
||||||
.Build();
|
.Build();
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
using Ocelot.Responses;
|
using System.Threading.Tasks;
|
||||||
|
using Ocelot.Responses;
|
||||||
|
|
||||||
namespace Ocelot.Configuration.Provider
|
namespace Ocelot.Configuration.Provider
|
||||||
{
|
{
|
||||||
public interface IOcelotConfigurationProvider
|
public interface IOcelotConfigurationProvider
|
||||||
{
|
{
|
||||||
Response<IOcelotConfiguration> Get();
|
Task<Response<IOcelotConfiguration>> Get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using Ocelot.Configuration.Repository;
|
using System.Threading.Tasks;
|
||||||
|
using Ocelot.Configuration.Repository;
|
||||||
using Ocelot.Responses;
|
using Ocelot.Responses;
|
||||||
|
|
||||||
namespace Ocelot.Configuration.Provider
|
namespace Ocelot.Configuration.Provider
|
||||||
@ -15,9 +16,9 @@ namespace Ocelot.Configuration.Provider
|
|||||||
_repo = repo;
|
_repo = repo;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Response<IOcelotConfiguration> Get()
|
public async Task<Response<IOcelotConfiguration>> Get()
|
||||||
{
|
{
|
||||||
var repoConfig = _repo.Get();
|
var repoConfig = await _repo.Get();
|
||||||
|
|
||||||
if (repoConfig.IsError)
|
if (repoConfig.IsError)
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using Polly.Timeout;
|
||||||
using Polly.Timeout;
|
|
||||||
|
|
||||||
namespace Ocelot.Configuration
|
namespace Ocelot.Configuration
|
||||||
{
|
{
|
||||||
@ -12,17 +11,17 @@ namespace Ocelot.Configuration
|
|||||||
TimeoutStrategy timeoutStrategy = TimeoutStrategy.Pessimistic)
|
TimeoutStrategy timeoutStrategy = TimeoutStrategy.Pessimistic)
|
||||||
{
|
{
|
||||||
ExceptionsAllowedBeforeBreaking = exceptionsAllowedBeforeBreaking;
|
ExceptionsAllowedBeforeBreaking = exceptionsAllowedBeforeBreaking;
|
||||||
DurationOfBreak = TimeSpan.FromMilliseconds(durationofBreak);
|
DurationOfBreak = durationofBreak;
|
||||||
TimeoutValue = TimeSpan.FromMilliseconds(timeoutValue);
|
TimeoutValue = timeoutValue;
|
||||||
TimeoutStrategy = timeoutStrategy;
|
TimeoutStrategy = timeoutStrategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public int ExceptionsAllowedBeforeBreaking { get; private set; }
|
public int ExceptionsAllowedBeforeBreaking { get; private set; }
|
||||||
|
|
||||||
public TimeSpan DurationOfBreak { get; private set; }
|
public int DurationOfBreak { get; private set; }
|
||||||
|
|
||||||
public TimeSpan TimeoutValue { get; private set; }
|
public int TimeoutValue { get; private set; }
|
||||||
|
|
||||||
public TimeoutStrategy TimeoutStrategy { get; private set; }
|
public TimeoutStrategy TimeoutStrategy { get; private set; }
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
@ -59,25 +58,4 @@ namespace Ocelot.Configuration
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool DisableRateLimitHeaders { get; private set; }
|
public bool DisableRateLimitHeaders { get; private set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class RateLimitRule
|
|
||||||
{
|
|
||||||
public RateLimitRule(string period, TimeSpan 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 TimeSpan 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; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
25
src/Ocelot/Configuration/RateLimitRule.cs
Normal file
25
src/Ocelot/Configuration/RateLimitRule.cs
Normal file
@ -0,0 +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; }
|
||||||
|
}
|
||||||
|
}
|
@ -7,12 +7,12 @@ namespace Ocelot.Configuration
|
|||||||
public class ReRoute
|
public class ReRoute
|
||||||
{
|
{
|
||||||
public ReRoute(PathTemplate downstreamPathTemplate,
|
public ReRoute(PathTemplate downstreamPathTemplate,
|
||||||
PathTemplate upstreamTemplate,
|
PathTemplate upstreamPathTemplate,
|
||||||
HttpMethod upstreamHttpMethod,
|
HttpMethod upstreamHttpMethod,
|
||||||
string upstreamTemplatePattern,
|
string upstreamTemplatePattern,
|
||||||
bool isAuthenticated,
|
bool isAuthenticated,
|
||||||
AuthenticationOptions authenticationOptions,
|
AuthenticationOptions authenticationOptions,
|
||||||
List<ClaimToThing> configurationHeaderExtractorProperties,
|
List<ClaimToThing> claimsToHeaders,
|
||||||
List<ClaimToThing> claimsToClaims,
|
List<ClaimToThing> claimsToClaims,
|
||||||
Dictionary<string, string> routeClaimsRequirement,
|
Dictionary<string, string> routeClaimsRequirement,
|
||||||
bool isAuthorised,
|
bool isAuthorised,
|
||||||
@ -27,8 +27,8 @@ namespace Ocelot.Configuration
|
|||||||
string reRouteKey,
|
string reRouteKey,
|
||||||
ServiceProviderConfiguration serviceProviderConfiguraion,
|
ServiceProviderConfiguration serviceProviderConfiguraion,
|
||||||
bool isQos,
|
bool isQos,
|
||||||
QoSOptions qos,
|
QoSOptions qosOptions,
|
||||||
bool enableRateLimit,
|
bool enableEndpointRateLimiting,
|
||||||
RateLimitOptions ratelimitOptions)
|
RateLimitOptions ratelimitOptions)
|
||||||
{
|
{
|
||||||
ReRouteKey = reRouteKey;
|
ReRouteKey = reRouteKey;
|
||||||
@ -37,7 +37,7 @@ namespace Ocelot.Configuration
|
|||||||
DownstreamHost = downstreamHost;
|
DownstreamHost = downstreamHost;
|
||||||
DownstreamPort = downstreamPort;
|
DownstreamPort = downstreamPort;
|
||||||
DownstreamPathTemplate = downstreamPathTemplate;
|
DownstreamPathTemplate = downstreamPathTemplate;
|
||||||
UpstreamPathTemplate = upstreamTemplate;
|
UpstreamPathTemplate = upstreamPathTemplate;
|
||||||
UpstreamHttpMethod = upstreamHttpMethod;
|
UpstreamHttpMethod = upstreamHttpMethod;
|
||||||
UpstreamTemplatePattern = upstreamTemplatePattern;
|
UpstreamTemplatePattern = upstreamTemplatePattern;
|
||||||
IsAuthenticated = isAuthenticated;
|
IsAuthenticated = isAuthenticated;
|
||||||
@ -51,12 +51,12 @@ namespace Ocelot.Configuration
|
|||||||
?? new List<ClaimToThing>();
|
?? new List<ClaimToThing>();
|
||||||
ClaimsToClaims = claimsToClaims
|
ClaimsToClaims = claimsToClaims
|
||||||
?? new List<ClaimToThing>();
|
?? new List<ClaimToThing>();
|
||||||
ClaimsToHeaders = configurationHeaderExtractorProperties
|
ClaimsToHeaders = claimsToHeaders
|
||||||
?? new List<ClaimToThing>();
|
?? new List<ClaimToThing>();
|
||||||
DownstreamScheme = downstreamScheme;
|
DownstreamScheme = downstreamScheme;
|
||||||
IsQos = isQos;
|
IsQos = isQos;
|
||||||
QosOptions = qos;
|
QosOptionsOptions = qosOptions;
|
||||||
EnableEndpointRateLimiting = enableRateLimit;
|
EnableEndpointEndpointRateLimiting = enableEndpointRateLimiting;
|
||||||
RateLimitOptions = ratelimitOptions;
|
RateLimitOptions = ratelimitOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,12 +77,12 @@ namespace Ocelot.Configuration
|
|||||||
public CacheOptions FileCacheOptions { get; private set; }
|
public CacheOptions FileCacheOptions { get; private set; }
|
||||||
public string DownstreamScheme {get;private set;}
|
public string DownstreamScheme {get;private set;}
|
||||||
public bool IsQos { get; private set; }
|
public bool IsQos { get; private set; }
|
||||||
public QoSOptions QosOptions { get; private set; }
|
public QoSOptions QosOptionsOptions { get; private set; }
|
||||||
public string LoadBalancer {get;private set;}
|
public string LoadBalancer {get;private set;}
|
||||||
public string DownstreamHost { get; private set; }
|
public string DownstreamHost { get; private set; }
|
||||||
public int DownstreamPort { get; private set; }
|
public int DownstreamPort { get; private set; }
|
||||||
public ServiceProviderConfiguration ServiceProviderConfiguraion { get; private set; }
|
public ServiceProviderConfiguration ServiceProviderConfiguraion { get; private set; }
|
||||||
public bool EnableEndpointRateLimiting { get; private set; }
|
public bool EnableEndpointEndpointRateLimiting { get; private set; }
|
||||||
public RateLimitOptions RateLimitOptions { get; private set; }
|
public RateLimitOptions RateLimitOptions { get; private set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,79 @@
|
|||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Consul;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using Ocelot.Responses;
|
||||||
|
using Ocelot.ServiceDiscovery;
|
||||||
|
|
||||||
|
namespace Ocelot.Configuration.Repository
|
||||||
|
{
|
||||||
|
public class ConsulOcelotConfigurationRepository : IOcelotConfigurationRepository
|
||||||
|
{
|
||||||
|
private readonly ConsulClient _consul;
|
||||||
|
private ConsulRegistryConfiguration _configuration;
|
||||||
|
private string _ocelotConfiguration = "OcelotConfiguration";
|
||||||
|
private Cache.IOcelotCache<IOcelotConfiguration> _cache;
|
||||||
|
|
||||||
|
public ConsulOcelotConfigurationRepository(ConsulRegistryConfiguration consulRegistryConfiguration, Cache.IOcelotCache<IOcelotConfiguration> cache)
|
||||||
|
{
|
||||||
|
var consulHost = string.IsNullOrEmpty(consulRegistryConfiguration?.HostName) ? "localhost" : consulRegistryConfiguration.HostName;
|
||||||
|
var consulPort = consulRegistryConfiguration?.Port ?? 8500;
|
||||||
|
_configuration = new ConsulRegistryConfiguration(consulHost, consulPort, consulRegistryConfiguration?.ServiceName);
|
||||||
|
_cache = cache;
|
||||||
|
_consul = new ConsulClient(config =>
|
||||||
|
{
|
||||||
|
config.Address = new Uri($"http://{_configuration.HostName}:{_configuration.Port}");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Response<IOcelotConfiguration>> Get()
|
||||||
|
{
|
||||||
|
var config = _cache.Get(_ocelotConfiguration);
|
||||||
|
|
||||||
|
if (config != null)
|
||||||
|
{
|
||||||
|
return new OkResponse<IOcelotConfiguration>(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
var queryResult = await _consul.KV.Get(_ocelotConfiguration);
|
||||||
|
|
||||||
|
if (queryResult.Response == null)
|
||||||
|
{
|
||||||
|
return new OkResponse<IOcelotConfiguration>(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
var bytes = queryResult.Response.Value;
|
||||||
|
|
||||||
|
var json = Encoding.UTF8.GetString(bytes);
|
||||||
|
|
||||||
|
var consulConfig = JsonConvert.DeserializeObject<OcelotConfiguration>(json);
|
||||||
|
|
||||||
|
return new OkResponse<IOcelotConfiguration>(consulConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Response> AddOrReplace(IOcelotConfiguration 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));
|
||||||
|
|
||||||
|
return new OkResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ErrorResponse(new UnableToSetConfigInConsulError("Unable to set config in consul"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,11 @@
|
|||||||
using Ocelot.Responses;
|
using System.Threading.Tasks;
|
||||||
|
using Ocelot.Responses;
|
||||||
|
|
||||||
namespace Ocelot.Configuration.Repository
|
namespace Ocelot.Configuration.Repository
|
||||||
{
|
{
|
||||||
public interface IOcelotConfigurationRepository
|
public interface IOcelotConfigurationRepository
|
||||||
{
|
{
|
||||||
Response<IOcelotConfiguration> Get();
|
Task<Response<IOcelotConfiguration>> Get();
|
||||||
Response AddOrReplace(IOcelotConfiguration ocelotConfiguration);
|
Task<Response> AddOrReplace(IOcelotConfiguration ocelotConfiguration);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,5 @@
|
|||||||
using Ocelot.Responses;
|
using System.Threading.Tasks;
|
||||||
|
using Ocelot.Responses;
|
||||||
|
|
||||||
namespace Ocelot.Configuration.Repository
|
namespace Ocelot.Configuration.Repository
|
||||||
{
|
{
|
||||||
@ -11,12 +12,12 @@ namespace Ocelot.Configuration.Repository
|
|||||||
|
|
||||||
private IOcelotConfiguration _ocelotConfiguration;
|
private IOcelotConfiguration _ocelotConfiguration;
|
||||||
|
|
||||||
public Response<IOcelotConfiguration> Get()
|
public async Task<Response<IOcelotConfiguration>> Get()
|
||||||
{
|
{
|
||||||
return new OkResponse<IOcelotConfiguration>(_ocelotConfiguration);
|
return new OkResponse<IOcelotConfiguration>(_ocelotConfiguration);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Response AddOrReplace(IOcelotConfiguration ocelotConfiguration)
|
public async Task<Response> AddOrReplace(IOcelotConfiguration ocelotConfiguration)
|
||||||
{
|
{
|
||||||
lock (LockObject)
|
lock (LockObject)
|
||||||
{
|
{
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
using Ocelot.Errors;
|
||||||
|
|
||||||
|
namespace Ocelot.Configuration.Repository
|
||||||
|
{
|
||||||
|
public class UnableToSetConfigInConsulError : Error
|
||||||
|
{
|
||||||
|
public UnableToSetConfigInConsulError(string message)
|
||||||
|
: base(message, OcelotErrorCode.UnableToSetConfigInConsulError)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -33,7 +33,7 @@ namespace Ocelot.Configuration.Setter
|
|||||||
|
|
||||||
if(!config.IsError)
|
if(!config.IsError)
|
||||||
{
|
{
|
||||||
_configRepo.AddOrReplace(config.Data);
|
await _configRepo.AddOrReplace(config.Data);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ErrorResponse(config.Errors);
|
return new ErrorResponse(config.Errors);
|
||||||
|
@ -40,24 +40,32 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using Ocelot.Configuration;
|
||||||
using FileConfigurationProvider = Ocelot.Configuration.Provider.FileConfigurationProvider;
|
using FileConfigurationProvider = Ocelot.Configuration.Provider.FileConfigurationProvider;
|
||||||
|
|
||||||
namespace Ocelot.DependencyInjection
|
namespace Ocelot.DependencyInjection
|
||||||
{
|
{
|
||||||
public static class ServiceCollectionExtensions
|
public static class ServiceCollectionExtensions
|
||||||
{
|
{
|
||||||
public static IServiceCollection AddOcelotOutputCaching(this IServiceCollection services, Action<ConfigurationBuilderCachePart> settings)
|
public static IServiceCollection AddOcelotStoreConfigurationInConsul(this IServiceCollection services, ConsulRegistryConfiguration consulConfig)
|
||||||
{
|
{
|
||||||
var cacheManagerOutputCache = CacheFactory.Build<HttpResponseMessage>("OcelotOutputCache", settings);
|
services.AddSingleton<ConsulRegistryConfiguration>(consulConfig);
|
||||||
var ocelotCacheManager = new OcelotCacheManagerCache<HttpResponseMessage>(cacheManagerOutputCache);
|
services.AddSingleton<IOcelotConfigurationRepository, ConsulOcelotConfigurationRepository>();
|
||||||
services.TryAddSingleton<ICacheManager<HttpResponseMessage>>(cacheManagerOutputCache);
|
|
||||||
services.TryAddSingleton<IOcelotCache<HttpResponseMessage>>(ocelotCacheManager);
|
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IServiceCollection AddOcelot(this IServiceCollection services, IConfigurationRoot configurationRoot)
|
public static IServiceCollection AddOcelot(this IServiceCollection services, IConfigurationRoot configurationRoot, Action<ConfigurationBuilderCachePart> settings)
|
||||||
{
|
{
|
||||||
|
var cacheManagerOutputCache = CacheFactory.Build<HttpResponseMessage>("OcelotOutputCache", settings);
|
||||||
|
var ocelotOutputCacheManager = new OcelotCacheManagerCache<HttpResponseMessage>(cacheManagerOutputCache);
|
||||||
|
services.TryAddSingleton<ICacheManager<HttpResponseMessage>>(cacheManagerOutputCache);
|
||||||
|
services.TryAddSingleton<IOcelotCache<HttpResponseMessage>>(ocelotOutputCacheManager);
|
||||||
|
|
||||||
|
var ocelotConfigCacheManagerOutputCache = CacheFactory.Build<IOcelotConfiguration>("OcelotConfigurationCache", settings);
|
||||||
|
var ocelotConfigCacheManager = new OcelotCacheManagerCache<IOcelotConfiguration>(ocelotConfigCacheManagerOutputCache);
|
||||||
|
services.TryAddSingleton<ICacheManager<IOcelotConfiguration>>(ocelotConfigCacheManagerOutputCache);
|
||||||
|
services.TryAddSingleton<IOcelotCache<IOcelotConfiguration>>(ocelotConfigCacheManager);
|
||||||
|
|
||||||
services.Configure<FileConfiguration>(configurationRoot);
|
services.Configure<FileConfiguration>(configurationRoot);
|
||||||
services.TryAddSingleton<IOcelotConfigurationCreator, FileOcelotConfigurationCreator>();
|
services.TryAddSingleton<IOcelotConfigurationCreator, FileOcelotConfigurationCreator>();
|
||||||
services.TryAddSingleton<IOcelotConfigurationRepository, InMemoryOcelotConfigurationRepository>();
|
services.TryAddSingleton<IOcelotConfigurationRepository, InMemoryOcelotConfigurationRepository>();
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Ocelot.Configuration.Provider;
|
using Ocelot.Configuration.Provider;
|
||||||
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
using Ocelot.DownstreamRouteFinder.UrlMatcher;
|
||||||
using Ocelot.Errors;
|
using Ocelot.Errors;
|
||||||
@ -21,9 +22,9 @@ namespace Ocelot.DownstreamRouteFinder.Finder
|
|||||||
_urlPathPlaceholderNameAndValueFinder = urlPathPlaceholderNameAndValueFinder;
|
_urlPathPlaceholderNameAndValueFinder = urlPathPlaceholderNameAndValueFinder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Response<DownstreamRoute> FindDownstreamRoute(string upstreamUrlPath, string upstreamHttpMethod)
|
public async Task<Response<DownstreamRoute>> FindDownstreamRoute(string upstreamUrlPath, string upstreamHttpMethod)
|
||||||
{
|
{
|
||||||
var configuration = _configProvider.Get();
|
var configuration = await _configProvider.Get();
|
||||||
|
|
||||||
var applicableReRoutes = configuration.Data.ReRoutes.Where(r => string.Equals(r.UpstreamHttpMethod.Method.ToLower(), upstreamHttpMethod.ToLower(), StringComparison.CurrentCultureIgnoreCase));
|
var applicableReRoutes = configuration.Data.ReRoutes.Where(r => string.Equals(r.UpstreamHttpMethod.Method.ToLower(), upstreamHttpMethod.ToLower(), StringComparison.CurrentCultureIgnoreCase));
|
||||||
|
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
using Ocelot.Responses;
|
using System.Threading.Tasks;
|
||||||
|
using Ocelot.Responses;
|
||||||
|
|
||||||
namespace Ocelot.DownstreamRouteFinder.Finder
|
namespace Ocelot.DownstreamRouteFinder.Finder
|
||||||
{
|
{
|
||||||
public interface IDownstreamRouteFinder
|
public interface IDownstreamRouteFinder
|
||||||
{
|
{
|
||||||
Response<DownstreamRoute> FindDownstreamRoute(string upstreamUrlPath, string upstreamHttpMethod);
|
Task<Response<DownstreamRoute>> FindDownstreamRoute(string upstreamUrlPath, string upstreamHttpMethod);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ namespace Ocelot.DownstreamRouteFinder.Middleware
|
|||||||
|
|
||||||
_logger.LogDebug("upstream url path is {upstreamUrlPath}", upstreamUrlPath);
|
_logger.LogDebug("upstream url path is {upstreamUrlPath}", upstreamUrlPath);
|
||||||
|
|
||||||
var downstreamRoute = _downstreamRouteFinder.FindDownstreamRoute(upstreamUrlPath, context.Request.Method);
|
var downstreamRoute = await _downstreamRouteFinder.FindDownstreamRoute(upstreamUrlPath, context.Request.Method);
|
||||||
|
|
||||||
if (downstreamRoute.IsError)
|
if (downstreamRoute.IsError)
|
||||||
{
|
{
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
UnableToFindServiceDiscoveryProviderError,
|
UnableToFindServiceDiscoveryProviderError,
|
||||||
UnableToFindLoadBalancerError,
|
UnableToFindLoadBalancerError,
|
||||||
RequestTimedOutError,
|
RequestTimedOutError,
|
||||||
UnableToFindQoSProviderError
|
UnableToFindQoSProviderError,
|
||||||
|
UnableToSetConfigInConsulError
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -141,14 +141,19 @@ namespace Ocelot.Middleware
|
|||||||
|
|
||||||
var configProvider = (IOcelotConfigurationProvider)builder.ApplicationServices.GetService(typeof(IOcelotConfigurationProvider));
|
var configProvider = (IOcelotConfigurationProvider)builder.ApplicationServices.GetService(typeof(IOcelotConfigurationProvider));
|
||||||
|
|
||||||
var config = await configSetter.Set(fileConfig.Value);
|
var ocelotConfiguration = await configProvider.Get();
|
||||||
|
|
||||||
if(config == null || config.IsError)
|
if (ocelotConfiguration == null || ocelotConfiguration.Data == null || ocelotConfiguration.IsError)
|
||||||
{
|
{
|
||||||
throw new Exception("Unable to start Ocelot: configuration was not set up correctly.");
|
var config = await configSetter.Set(fileConfig.Value);
|
||||||
|
|
||||||
|
if (config == null || config.IsError)
|
||||||
|
{
|
||||||
|
throw new Exception("Unable to start Ocelot: configuration was not set up correctly.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var ocelotConfiguration = configProvider.Get();
|
ocelotConfiguration = await configProvider.Get();
|
||||||
|
|
||||||
if(ocelotConfiguration == null || ocelotConfiguration.Data == null || ocelotConfiguration.IsError)
|
if(ocelotConfiguration == null || ocelotConfiguration.Data == null || ocelotConfiguration.IsError)
|
||||||
{
|
{
|
||||||
|
@ -35,7 +35,7 @@ namespace Ocelot.RateLimit.Middleware
|
|||||||
|
|
||||||
var options = DownstreamRoute.ReRoute.RateLimitOptions;
|
var options = DownstreamRoute.ReRoute.RateLimitOptions;
|
||||||
// check if rate limiting is enabled
|
// check if rate limiting is enabled
|
||||||
if (!DownstreamRoute.ReRoute.EnableEndpointRateLimiting)
|
if (!DownstreamRoute.ReRoute.EnableEndpointEndpointRateLimiting)
|
||||||
{
|
{
|
||||||
_logger.LogDebug($"EndpointRateLimiting is not enabled for {DownstreamRoute.ReRoute.DownstreamPathTemplate}");
|
_logger.LogDebug($"EndpointRateLimiting is not enabled for {DownstreamRoute.ReRoute.DownstreamPathTemplate}");
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ namespace Ocelot.RateLimit
|
|||||||
if (entry.HasValue)
|
if (entry.HasValue)
|
||||||
{
|
{
|
||||||
// entry has not expired
|
// entry has not expired
|
||||||
if (entry.Value.Timestamp + rule.PeriodTimespan >= DateTime.UtcNow)
|
if (entry.Value.Timestamp + TimeSpan.FromSeconds(rule.PeriodTimespan) >= DateTime.UtcNow)
|
||||||
{
|
{
|
||||||
// increment request count
|
// increment request count
|
||||||
var totalRequests = entry.Value.TotalRequests + 1;
|
var totalRequests = entry.Value.TotalRequests + 1;
|
||||||
@ -45,7 +45,7 @@ namespace Ocelot.RateLimit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// stores: id (string) - timestamp (datetime) - total_requests (long)
|
// stores: id (string) - timestamp (datetime) - total_requests (long)
|
||||||
_counterHandler.Set(counterId, counter, rule.PeriodTimespan);
|
_counterHandler.Set(counterId, counter, TimeSpan.FromSeconds(rule.PeriodTimespan));
|
||||||
}
|
}
|
||||||
|
|
||||||
return counter;
|
return counter;
|
||||||
@ -95,7 +95,7 @@ namespace Ocelot.RateLimit
|
|||||||
public string RetryAfterFrom(DateTime timestamp, RateLimitRule rule)
|
public string RetryAfterFrom(DateTime timestamp, RateLimitRule rule)
|
||||||
{
|
{
|
||||||
var secondsPast = Convert.ToInt32((DateTime.UtcNow - timestamp).TotalSeconds);
|
var secondsPast = Convert.ToInt32((DateTime.UtcNow - timestamp).TotalSeconds);
|
||||||
var retryAfter = Convert.ToInt32(rule.PeriodTimespan.TotalSeconds);
|
var retryAfter = Convert.ToInt32(TimeSpan.FromSeconds(rule.PeriodTimespan).TotalSeconds);
|
||||||
retryAfter = retryAfter > 1 ? retryAfter - secondsPast : 1;
|
retryAfter = retryAfter > 1 ? retryAfter - secondsPast : 1;
|
||||||
return retryAfter.ToString(System.Globalization.CultureInfo.InvariantCulture);
|
return retryAfter.ToString(System.Globalization.CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
|
@ -57,15 +57,15 @@ namespace Ocelot.Requester.QoS
|
|||||||
{
|
{
|
||||||
_logger = loggerFactory.CreateLogger<PollyQoSProvider>();
|
_logger = loggerFactory.CreateLogger<PollyQoSProvider>();
|
||||||
|
|
||||||
_timeoutPolicy = Policy.TimeoutAsync(reRoute.QosOptions.TimeoutValue, reRoute.QosOptions.TimeoutStrategy);
|
_timeoutPolicy = Policy.TimeoutAsync(TimeSpan.FromMilliseconds(reRoute.QosOptionsOptions.TimeoutValue), reRoute.QosOptionsOptions.TimeoutStrategy);
|
||||||
|
|
||||||
_circuitBreakerPolicy = Policy
|
_circuitBreakerPolicy = Policy
|
||||||
.Handle<HttpRequestException>()
|
.Handle<HttpRequestException>()
|
||||||
.Or<TimeoutRejectedException>()
|
.Or<TimeoutRejectedException>()
|
||||||
.Or<TimeoutException>()
|
.Or<TimeoutException>()
|
||||||
.CircuitBreakerAsync(
|
.CircuitBreakerAsync(
|
||||||
exceptionsAllowedBeforeBreaking: reRoute.QosOptions.ExceptionsAllowedBeforeBreaking,
|
exceptionsAllowedBeforeBreaking: reRoute.QosOptionsOptions.ExceptionsAllowedBeforeBreaking,
|
||||||
durationOfBreak: reRoute.QosOptions.DurationOfBreak,
|
durationOfBreak: TimeSpan.FromMilliseconds(reRoute.QosOptionsOptions.DurationOfBreak),
|
||||||
onBreak: (ex, breakDelay) =>
|
onBreak: (ex, breakDelay) =>
|
||||||
{
|
{
|
||||||
_logger.LogError(
|
_logger.LogError(
|
||||||
|
171
test/Ocelot.AcceptanceTests/ConfigurationInConsulTests.cs
Normal file
171
test/Ocelot.AcceptanceTests/ConfigurationInConsulTests.cs
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net;
|
||||||
|
using System.Text;
|
||||||
|
using Consul;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Ocelot.Configuration;
|
||||||
|
using Ocelot.Configuration.File;
|
||||||
|
using Ocelot.Configuration.Repository;
|
||||||
|
using Ocelot.ServiceDiscovery;
|
||||||
|
using TestStack.BDDfy;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Ocelot.AcceptanceTests
|
||||||
|
{
|
||||||
|
public class ConfigurationInConsul : IDisposable
|
||||||
|
{
|
||||||
|
private IWebHost _builder;
|
||||||
|
private readonly Steps _steps;
|
||||||
|
private IWebHost _fakeConsulBuilder;
|
||||||
|
private IOcelotConfiguration _config;
|
||||||
|
|
||||||
|
public ConfigurationInConsul()
|
||||||
|
{
|
||||||
|
_steps = new Steps();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void should_return_response_200_with_simple_url()
|
||||||
|
{
|
||||||
|
var configuration = new FileConfiguration
|
||||||
|
{
|
||||||
|
ReRoutes = new List<FileReRoute>
|
||||||
|
{
|
||||||
|
new FileReRoute
|
||||||
|
{
|
||||||
|
DownstreamPathTemplate = "/",
|
||||||
|
DownstreamScheme = "http",
|
||||||
|
DownstreamHost = "localhost",
|
||||||
|
DownstreamPort = 51779,
|
||||||
|
UpstreamPathTemplate = "/",
|
||||||
|
UpstreamHttpMethod = "Get",
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
GlobalConfiguration = new FileGlobalConfiguration()
|
||||||
|
{
|
||||||
|
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider()
|
||||||
|
{
|
||||||
|
Provider = "Consul",
|
||||||
|
Host = "localhost",
|
||||||
|
Port = 9500
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var fakeConsulServiceDiscoveryUrl = "http://localhost:9500";
|
||||||
|
|
||||||
|
var consulConfig = new ConsulRegistryConfiguration("localhost", 9500, "Ocelot");
|
||||||
|
|
||||||
|
this.Given(x => GivenThereIsAFakeConsulServiceDiscoveryProvider(fakeConsulServiceDiscoveryUrl))
|
||||||
|
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51779", 200, "Hello from Laura"))
|
||||||
|
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||||
|
.And(x => _steps.GivenOcelotIsRunningUsingConsulToStoreConfig(consulConfig))
|
||||||
|
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
||||||
|
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
||||||
|
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
|
||||||
|
.BDDfy();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenThereIsAFakeConsulServiceDiscoveryProvider(string url)
|
||||||
|
{
|
||||||
|
_fakeConsulBuilder = new WebHostBuilder()
|
||||||
|
.UseUrls(url)
|
||||||
|
.UseKestrel()
|
||||||
|
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||||
|
.UseIISIntegration()
|
||||||
|
.UseUrls(url)
|
||||||
|
.Configure(app =>
|
||||||
|
{
|
||||||
|
app.Run(async context =>
|
||||||
|
{
|
||||||
|
if (context.Request.Method.ToLower() == "get" && context.Request.Path.Value == "/v1/kv/OcelotConfiguration")
|
||||||
|
{
|
||||||
|
var json = JsonConvert.SerializeObject(_config);
|
||||||
|
|
||||||
|
var bytes = Encoding.UTF8.GetBytes(json);
|
||||||
|
|
||||||
|
var base64 = Convert.ToBase64String(bytes);
|
||||||
|
|
||||||
|
var kvp = new FakeConsulGetResponse(base64);
|
||||||
|
|
||||||
|
await context.Response.WriteJsonAsync(new FakeConsulGetResponse[]{kvp});
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (context.Request.Method.ToLower() == "put" && context.Request.Path.Value == "/v1/kv/OcelotConfiguration")
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var reader = new StreamReader(context.Request.Body);
|
||||||
|
|
||||||
|
var json = reader.ReadToEnd();
|
||||||
|
|
||||||
|
_config = JsonConvert.DeserializeObject<OcelotConfiguration>(json);
|
||||||
|
|
||||||
|
var response = JsonConvert.SerializeObject(true);
|
||||||
|
|
||||||
|
await context.Response.WriteAsync(response);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
_fakeConsulBuilder.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class FakeConsulGetResponse
|
||||||
|
{
|
||||||
|
public FakeConsulGetResponse(string value)
|
||||||
|
{
|
||||||
|
Value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int CreateIndex => 100;
|
||||||
|
public int ModifyIndex => 200;
|
||||||
|
public int LockIndex => 200;
|
||||||
|
public string Key => "OcelotConfiguration";
|
||||||
|
public int Flags => 0;
|
||||||
|
public string Value { get; private set; }
|
||||||
|
public string Session => "adf4238a-882b-9ddc-4a9d-5b6758e4159e";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GivenThereIsAServiceRunningOn(string url, int statusCode, string responseBody)
|
||||||
|
{
|
||||||
|
_builder = new WebHostBuilder()
|
||||||
|
.UseUrls(url)
|
||||||
|
.UseKestrel()
|
||||||
|
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||||
|
.UseIISIntegration()
|
||||||
|
.UseUrls(url)
|
||||||
|
.Configure(app =>
|
||||||
|
{
|
||||||
|
app.Run(async context =>
|
||||||
|
{
|
||||||
|
context.Response.StatusCode = statusCode;
|
||||||
|
await context.Response.WriteAsync(responseBody);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
_builder.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_builder?.Dispose();
|
||||||
|
_steps.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -15,9 +15,11 @@ using Microsoft.Extensions.DependencyInjection;
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
|
using Ocelot.Configuration.Repository;
|
||||||
using Ocelot.DependencyInjection;
|
using Ocelot.DependencyInjection;
|
||||||
using Ocelot.ManualTest;
|
using Ocelot.ManualTest;
|
||||||
using Ocelot.Middleware;
|
using Ocelot.Middleware;
|
||||||
|
using Ocelot.ServiceDiscovery;
|
||||||
using Shouldly;
|
using Shouldly;
|
||||||
using ConfigurationBuilder = Microsoft.Extensions.Configuration.ConfigurationBuilder;
|
using ConfigurationBuilder = Microsoft.Extensions.Configuration.ConfigurationBuilder;
|
||||||
|
|
||||||
@ -84,6 +86,22 @@ namespace Ocelot.AcceptanceTests
|
|||||||
_ocelotClient = _ocelotServer.CreateClient();
|
_ocelotClient = _ocelotServer.CreateClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void GivenOcelotIsRunningUsingConsulToStoreConfig(ConsulRegistryConfiguration consulConfig)
|
||||||
|
{
|
||||||
|
_webHostBuilder = new WebHostBuilder();
|
||||||
|
|
||||||
|
_webHostBuilder.ConfigureServices(s =>
|
||||||
|
{
|
||||||
|
s.AddSingleton(_webHostBuilder);
|
||||||
|
s.AddOcelotStoreConfigurationInConsul(consulConfig);
|
||||||
|
});
|
||||||
|
|
||||||
|
_ocelotServer = new TestServer(_webHostBuilder
|
||||||
|
.UseStartup<Startup>());
|
||||||
|
|
||||||
|
_ocelotClient = _ocelotServer.CreateClient();
|
||||||
|
}
|
||||||
|
|
||||||
internal void ThenTheResponseShouldBe(FileConfiguration expected)
|
internal void ThenTheResponseShouldBe(FileConfiguration expected)
|
||||||
{
|
{
|
||||||
var response = JsonConvert.DeserializeObject<FileConfiguration>(_response.Content.ReadAsStringAsync().Result);
|
var response = JsonConvert.DeserializeObject<FileConfiguration>(_response.Content.ReadAsStringAsync().Result);
|
||||||
@ -138,8 +156,7 @@ namespace Ocelot.AcceptanceTests
|
|||||||
.WithDictionaryHandle();
|
.WithDictionaryHandle();
|
||||||
};
|
};
|
||||||
|
|
||||||
s.AddOcelotOutputCaching(settings);
|
s.AddOcelot(configuration, settings);
|
||||||
s.AddOcelot(configuration);
|
|
||||||
})
|
})
|
||||||
.ConfigureLogging(l =>
|
.ConfigureLogging(l =>
|
||||||
{
|
{
|
||||||
|
@ -37,8 +37,8 @@ namespace Ocelot.ManualTest
|
|||||||
})
|
})
|
||||||
.WithDictionaryHandle();
|
.WithDictionaryHandle();
|
||||||
};
|
};
|
||||||
services.AddOcelotOutputCaching(settings);
|
|
||||||
services.AddOcelot(Configuration);
|
services.AddOcelot(Configuration, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
|
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
|
||||||
|
@ -690,10 +690,10 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
|
|
||||||
private void ThenTheQosOptionsAre(QoSOptions qosOptions)
|
private void ThenTheQosOptionsAre(QoSOptions qosOptions)
|
||||||
{
|
{
|
||||||
_config.Data.ReRoutes[0].QosOptions.DurationOfBreak.ShouldBe(qosOptions.DurationOfBreak);
|
_config.Data.ReRoutes[0].QosOptionsOptions.DurationOfBreak.ShouldBe(qosOptions.DurationOfBreak);
|
||||||
|
|
||||||
_config.Data.ReRoutes[0].QosOptions.ExceptionsAllowedBeforeBreaking.ShouldBe(qosOptions.ExceptionsAllowedBeforeBreaking);
|
_config.Data.ReRoutes[0].QosOptionsOptions.ExceptionsAllowedBeforeBreaking.ShouldBe(qosOptions.ExceptionsAllowedBeforeBreaking);
|
||||||
_config.Data.ReRoutes[0].QosOptions.TimeoutValue.ShouldBe(qosOptions.TimeoutValue);
|
_config.Data.ReRoutes[0].QosOptionsOptions.TimeoutValue.ShouldBe(qosOptions.TimeoutValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
|
|
||||||
private void WhenIGetTheConfiguration()
|
private void WhenIGetTheConfiguration()
|
||||||
{
|
{
|
||||||
_getResult = _repo.Get();
|
_getResult = _repo.Get().Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenThereIsASavedConfiguration()
|
private void GivenThereIsASavedConfiguration()
|
||||||
@ -65,7 +65,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
|
|
||||||
private void WhenIAddOrReplaceTheConfig()
|
private void WhenIAddOrReplaceTheConfig()
|
||||||
{
|
{
|
||||||
_result = _repo.AddOrReplace(_config);
|
_result = _repo.AddOrReplace(_config).Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ThenNoErrorsAreReturned()
|
private void ThenNoErrorsAreReturned()
|
||||||
|
@ -53,12 +53,12 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
{
|
{
|
||||||
_configurationRepository
|
_configurationRepository
|
||||||
.Setup(x => x.Get())
|
.Setup(x => x.Get())
|
||||||
.Returns(config);
|
.ReturnsAsync(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WhenIGetTheConfig()
|
private void WhenIGetTheConfig()
|
||||||
{
|
{
|
||||||
_result = _ocelotConfigurationProvider.Get();
|
_result = _ocelotConfigurationProvider.Get().Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TheFollowingIsReturned(Response<IOcelotConfiguration> expected)
|
private void TheFollowingIsReturned(Response<IOcelotConfiguration> expected)
|
||||||
|
@ -59,7 +59,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
.WithQuotaExceededMessage("QuotaExceededMessage")
|
.WithQuotaExceededMessage("QuotaExceededMessage")
|
||||||
.WithRateLimitCounterPrefix("RateLimitCounterPrefix")
|
.WithRateLimitCounterPrefix("RateLimitCounterPrefix")
|
||||||
.WithRateLimitRule(new RateLimitRule(fileReRoute.RateLimitOptions.Period,
|
.WithRateLimitRule(new RateLimitRule(fileReRoute.RateLimitOptions.Period,
|
||||||
TimeSpan.FromSeconds(fileReRoute.RateLimitOptions.PeriodTimespan),
|
fileReRoute.RateLimitOptions.PeriodTimespan,
|
||||||
fileReRoute.RateLimitOptions.Limit))
|
fileReRoute.RateLimitOptions.Limit))
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
@ -102,7 +102,7 @@ namespace Ocelot.UnitTests.Configuration
|
|||||||
_result.RateLimitCounterPrefix.ShouldBe(expected.RateLimitCounterPrefix);
|
_result.RateLimitCounterPrefix.ShouldBe(expected.RateLimitCounterPrefix);
|
||||||
_result.RateLimitRule.Limit.ShouldBe(expected.RateLimitRule.Limit);
|
_result.RateLimitRule.Limit.ShouldBe(expected.RateLimitRule.Limit);
|
||||||
_result.RateLimitRule.Period.ShouldBe(expected.RateLimitRule.Period);
|
_result.RateLimitRule.Period.ShouldBe(expected.RateLimitRule.Period);
|
||||||
_result.RateLimitRule.PeriodTimespan.Ticks.ShouldBe(expected.RateLimitRule.PeriodTimespan.Ticks);
|
TimeSpan.FromSeconds(_result.RateLimitRule.PeriodTimespan).Ticks.ShouldBe(TimeSpan.FromSeconds(expected.RateLimitRule.PeriodTimespan).Ticks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
|
|||||||
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
|
_downstreamRoute = new OkResponse<DownstreamRoute>(downstreamRoute);
|
||||||
_downstreamRouteFinder
|
_downstreamRouteFinder
|
||||||
.Setup(x => x.FindDownstreamRoute(It.IsAny<string>(), It.IsAny<string>()))
|
.Setup(x => x.FindDownstreamRoute(It.IsAny<string>(), It.IsAny<string>()))
|
||||||
.Returns(_downstreamRoute);
|
.ReturnsAsync(_downstreamRoute);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
@ -199,7 +199,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
|
|||||||
_reRoutesConfig = reRoutesConfig;
|
_reRoutesConfig = reRoutesConfig;
|
||||||
_mockConfig
|
_mockConfig
|
||||||
.Setup(x => x.Get())
|
.Setup(x => x.Get())
|
||||||
.Returns(new OkResponse<IOcelotConfiguration>(new OcelotConfiguration(_reRoutesConfig, adminPath)));
|
.ReturnsAsync(new OkResponse<IOcelotConfiguration>(new OcelotConfiguration(_reRoutesConfig, adminPath)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenThereIsAnUpstreamUrlPath(string upstreamUrlPath)
|
private void GivenThereIsAnUpstreamUrlPath(string upstreamUrlPath)
|
||||||
@ -209,7 +209,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
|
|||||||
|
|
||||||
private void WhenICallTheFinder()
|
private void WhenICallTheFinder()
|
||||||
{
|
{
|
||||||
_result = _downstreamRouteFinder.FindDownstreamRoute(_upstreamUrlPath, _upstreamHttpMethod);
|
_result = _downstreamRouteFinder.FindDownstreamRoute(_upstreamUrlPath, _upstreamHttpMethod).Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ThenTheFollowingIsReturned(DownstreamRoute expected)
|
private void ThenTheFollowingIsReturned(DownstreamRoute expected)
|
||||||
|
@ -71,7 +71,7 @@ namespace Ocelot.UnitTests.RateLimit
|
|||||||
{
|
{
|
||||||
var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.UrlPathPlaceholderNameAndValue>(),
|
var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.UrlPathPlaceholderNameAndValue>(),
|
||||||
new ReRouteBuilder().WithEnableRateLimiting(true).WithRateLimitOptions(
|
new ReRouteBuilder().WithEnableRateLimiting(true).WithRateLimitOptions(
|
||||||
new Ocelot.Configuration.RateLimitOptions(true, "ClientId", new List<string>(), false, "", "", new Ocelot.Configuration.RateLimitRule("1s", TimeSpan.FromSeconds(100), 3), 429))
|
new Ocelot.Configuration.RateLimitOptions(true, "ClientId", new List<string>(), false, "", "", new Ocelot.Configuration.RateLimitRule("1s", 100, 3), 429))
|
||||||
.WithUpstreamHttpMethod("Get")
|
.WithUpstreamHttpMethod("Get")
|
||||||
.Build());
|
.Build());
|
||||||
|
|
||||||
@ -88,7 +88,7 @@ namespace Ocelot.UnitTests.RateLimit
|
|||||||
{
|
{
|
||||||
var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.UrlPathPlaceholderNameAndValue>(),
|
var downstreamRoute = new DownstreamRoute(new List<Ocelot.DownstreamRouteFinder.UrlMatcher.UrlPathPlaceholderNameAndValue>(),
|
||||||
new ReRouteBuilder().WithEnableRateLimiting(true).WithRateLimitOptions(
|
new ReRouteBuilder().WithEnableRateLimiting(true).WithRateLimitOptions(
|
||||||
new Ocelot.Configuration.RateLimitOptions(true, "ClientId", new List<string>() { "ocelotclient2" }, false, "", "", new RateLimitRule( "1s", TimeSpan.FromSeconds(100),3),429))
|
new Ocelot.Configuration.RateLimitOptions(true, "ClientId", new List<string>() { "ocelotclient2" }, false, "", "", new RateLimitRule( "1s", 100,3),429))
|
||||||
.WithUpstreamHttpMethod("Get")
|
.WithUpstreamHttpMethod("Get")
|
||||||
.Build());
|
.Build());
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user