mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-04-22 06:42:50 +08:00
parent
2673aebee2
commit
d4b65198f3
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Ocelot.Cache
|
namespace Ocelot.Cache
|
||||||
{
|
{
|
||||||
@ -10,4 +9,24 @@ namespace Ocelot.Cache
|
|||||||
T Get(string key, string region);
|
T Get(string key, string region);
|
||||||
void ClearRegion(string region);
|
void ClearRegion(string region);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class NoCache<T> : IOcelotCache<T>
|
||||||
|
{
|
||||||
|
public void Add(string key, T value, TimeSpan ttl, string region)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddAndDelete(string key, T value, TimeSpan ttl, string region)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClearRegion(string region)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public T Get(string key, string region)
|
||||||
|
{
|
||||||
|
return default(T);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,29 +1,25 @@
|
|||||||
using System;
|
namespace Ocelot.Cache.Middleware
|
||||||
using System.Linq;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Ocelot.Logging;
|
|
||||||
using Ocelot.Middleware;
|
|
||||||
using System.IO;
|
|
||||||
using Ocelot.Middleware.Multiplexer;
|
|
||||||
|
|
||||||
namespace Ocelot.Cache.Middleware
|
|
||||||
{
|
{
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Ocelot.Logging;
|
||||||
|
using Ocelot.Middleware;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
public class OutputCacheMiddleware : OcelotMiddleware
|
public class OutputCacheMiddleware : OcelotMiddleware
|
||||||
{
|
{
|
||||||
private readonly OcelotRequestDelegate _next;
|
private readonly OcelotRequestDelegate _next;
|
||||||
private readonly IOcelotCache<CachedResponse> _outputCache;
|
private readonly IOcelotCache<CachedResponse> _outputCache;
|
||||||
private readonly IRegionCreator _regionCreator;
|
|
||||||
|
|
||||||
public OutputCacheMiddleware(OcelotRequestDelegate next,
|
public OutputCacheMiddleware(OcelotRequestDelegate next,
|
||||||
IOcelotLoggerFactory loggerFactory,
|
IOcelotLoggerFactory loggerFactory,
|
||||||
IOcelotCache<CachedResponse> outputCache,
|
IOcelotCache<CachedResponse> outputCache)
|
||||||
IRegionCreator regionCreator)
|
|
||||||
:base(loggerFactory.CreateLogger<OutputCacheMiddleware>())
|
:base(loggerFactory.CreateLogger<OutputCacheMiddleware>())
|
||||||
{
|
{
|
||||||
_next = next;
|
_next = next;
|
||||||
_outputCache = outputCache;
|
_outputCache = outputCache;
|
||||||
_regionCreator = regionCreator;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Invoke(DownstreamContext context)
|
public async Task Invoke(DownstreamContext context)
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
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,7 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Ocelot.Cache
|
namespace Ocelot.Cache
|
||||||
{
|
{
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
public class Regions
|
public class Regions
|
||||||
{
|
{
|
||||||
public Regions(List<string> value)
|
public Regions(List<string> value)
|
||||||
@ -9,6 +9,6 @@ namespace Ocelot.Cache
|
|||||||
Value = value;
|
Value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<string> Value {get;private set;}
|
public List<string> Value { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int TtlSeconds { get; private set; }
|
public int TtlSeconds { get; private set; }
|
||||||
public string Region {get;private set;}
|
|
||||||
|
public string Region { get; private set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
using CacheManager.Core;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using IdentityServer4.AccessTokenValidation;
|
using IdentityServer4.AccessTokenValidation;
|
||||||
@ -14,8 +13,6 @@ namespace Ocelot.DependencyInjection
|
|||||||
IConfiguration Configuration { get; }
|
IConfiguration Configuration { get; }
|
||||||
IOcelotBuilder AddStoreOcelotConfigurationInConsul();
|
IOcelotBuilder AddStoreOcelotConfigurationInConsul();
|
||||||
|
|
||||||
IOcelotBuilder AddCacheManager(Action<ConfigurationBuilderCachePart> settings);
|
|
||||||
|
|
||||||
IOcelotAdministrationBuilder AddAdministration(string path, string secret);
|
IOcelotAdministrationBuilder AddAdministration(string path, string secret);
|
||||||
|
|
||||||
IOcelotAdministrationBuilder AddAdministration(string path, Action<IdentityServerAuthenticationOptions> configOptions);
|
IOcelotAdministrationBuilder AddAdministration(string path, Action<IdentityServerAuthenticationOptions> configOptions);
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
namespace Ocelot.DependencyInjection
|
namespace Ocelot.DependencyInjection
|
||||||
{
|
{
|
||||||
using CacheManager.Core;
|
|
||||||
using IdentityServer4.Models;
|
using IdentityServer4.Models;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
@ -50,118 +49,110 @@ namespace Ocelot.DependencyInjection
|
|||||||
|
|
||||||
public class OcelotBuilder : IOcelotBuilder
|
public class OcelotBuilder : IOcelotBuilder
|
||||||
{
|
{
|
||||||
private readonly IServiceCollection _services;
|
public IServiceCollection Services { get; }
|
||||||
private readonly IConfiguration _configurationRoot;
|
public IConfiguration Configuration { get; }
|
||||||
|
|
||||||
public IServiceCollection Services => _services;
|
|
||||||
|
|
||||||
public IConfiguration Configuration => _configurationRoot;
|
|
||||||
|
|
||||||
public OcelotBuilder(IServiceCollection services, IConfiguration configurationRoot)
|
public OcelotBuilder(IServiceCollection services, IConfiguration configurationRoot)
|
||||||
{
|
{
|
||||||
_configurationRoot = configurationRoot;
|
Configuration = configurationRoot;
|
||||||
_services = services;
|
Services = services;
|
||||||
|
|
||||||
//add default cache settings...
|
Services.Configure<FileConfiguration>(configurationRoot);
|
||||||
Action<ConfigurationBuilderCachePart> defaultCachingSettings = x =>
|
|
||||||
{
|
|
||||||
x.WithDictionaryHandle();
|
|
||||||
};
|
|
||||||
|
|
||||||
AddCacheManager(defaultCachingSettings);
|
//default no caches...
|
||||||
|
Services.TryAddSingleton<IOcelotCache<FileConfiguration>, NoCache<FileConfiguration>>();
|
||||||
|
Services.TryAddSingleton<IOcelotCache<CachedResponse>, NoCache<CachedResponse>>();
|
||||||
|
|
||||||
//add ocelot services...
|
Services.TryAddSingleton<IHttpResponseHeaderReplacer, HttpResponseHeaderReplacer>();
|
||||||
_services.Configure<FileConfiguration>(configurationRoot);
|
Services.TryAddSingleton<IHttpContextRequestHeaderReplacer, HttpContextRequestHeaderReplacer>();
|
||||||
_services.TryAddSingleton<IHttpResponseHeaderReplacer, HttpResponseHeaderReplacer>();
|
Services.TryAddSingleton<IHeaderFindAndReplaceCreator, HeaderFindAndReplaceCreator>();
|
||||||
_services.TryAddSingleton<IHttpContextRequestHeaderReplacer, HttpContextRequestHeaderReplacer>();
|
Services.TryAddSingleton<IInternalConfigurationCreator, FileInternalConfigurationCreator>();
|
||||||
_services.TryAddSingleton<IHeaderFindAndReplaceCreator, HeaderFindAndReplaceCreator>();
|
Services.TryAddSingleton<IInternalConfigurationRepository, InMemoryInternalConfigurationRepository>();
|
||||||
_services.TryAddSingleton<IInternalConfigurationCreator, FileInternalConfigurationCreator>();
|
Services.TryAddSingleton<IConfigurationValidator, FileConfigurationFluentValidator>();
|
||||||
_services.TryAddSingleton<IInternalConfigurationRepository, InMemoryInternalConfigurationRepository>();
|
Services.TryAddSingleton<IClaimsToThingCreator, ClaimsToThingCreator>();
|
||||||
_services.TryAddSingleton<IConfigurationValidator, FileConfigurationFluentValidator>();
|
Services.TryAddSingleton<IAuthenticationOptionsCreator, AuthenticationOptionsCreator>();
|
||||||
_services.TryAddSingleton<IClaimsToThingCreator, ClaimsToThingCreator>();
|
Services.TryAddSingleton<IUpstreamTemplatePatternCreator, UpstreamTemplatePatternCreator>();
|
||||||
_services.TryAddSingleton<IAuthenticationOptionsCreator, AuthenticationOptionsCreator>();
|
Services.TryAddSingleton<IRequestIdKeyCreator, RequestIdKeyCreator>();
|
||||||
_services.TryAddSingleton<IUpstreamTemplatePatternCreator, UpstreamTemplatePatternCreator>();
|
Services.TryAddSingleton<IServiceProviderConfigurationCreator,ServiceProviderConfigurationCreator>();
|
||||||
_services.TryAddSingleton<IRequestIdKeyCreator, RequestIdKeyCreator>();
|
Services.TryAddSingleton<IQoSOptionsCreator, QoSOptionsCreator>();
|
||||||
_services.TryAddSingleton<IServiceProviderConfigurationCreator,ServiceProviderConfigurationCreator>();
|
Services.TryAddSingleton<IReRouteOptionsCreator, ReRouteOptionsCreator>();
|
||||||
_services.TryAddSingleton<IQoSOptionsCreator, QoSOptionsCreator>();
|
Services.TryAddSingleton<IRateLimitOptionsCreator, RateLimitOptionsCreator>();
|
||||||
_services.TryAddSingleton<IReRouteOptionsCreator, ReRouteOptionsCreator>();
|
Services.TryAddSingleton<IBaseUrlFinder, BaseUrlFinder>();
|
||||||
_services.TryAddSingleton<IRateLimitOptionsCreator, RateLimitOptionsCreator>();
|
Services.TryAddSingleton<IRegionCreator, RegionCreator>();
|
||||||
_services.TryAddSingleton<IBaseUrlFinder, BaseUrlFinder>();
|
Services.TryAddSingleton<IFileConfigurationRepository, DiskFileConfigurationRepository>();
|
||||||
_services.TryAddSingleton<IRegionCreator, RegionCreator>();
|
Services.TryAddSingleton<IFileConfigurationSetter, FileAndInternalConfigurationSetter>();
|
||||||
_services.TryAddSingleton<IFileConfigurationRepository, DiskFileConfigurationRepository>();
|
Services.TryAddSingleton<IQosProviderHouse, QosProviderHouse>();
|
||||||
_services.TryAddSingleton<IFileConfigurationSetter, FileAndInternalConfigurationSetter>();
|
Services.TryAddSingleton<IQoSProviderFactory, QoSProviderFactory>();
|
||||||
_services.TryAddSingleton<IQosProviderHouse, QosProviderHouse>();
|
Services.TryAddSingleton<IServiceDiscoveryProviderFactory, ServiceDiscoveryProviderFactory>();
|
||||||
_services.TryAddSingleton<IQoSProviderFactory, QoSProviderFactory>();
|
Services.TryAddSingleton<ILoadBalancerFactory, LoadBalancerFactory>();
|
||||||
_services.TryAddSingleton<IServiceDiscoveryProviderFactory, ServiceDiscoveryProviderFactory>();
|
Services.TryAddSingleton<ILoadBalancerHouse, LoadBalancerHouse>();
|
||||||
_services.TryAddSingleton<ILoadBalancerFactory, LoadBalancerFactory>();
|
Services.TryAddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
||||||
_services.TryAddSingleton<ILoadBalancerHouse, LoadBalancerHouse>();
|
Services.TryAddSingleton<IRemoveOutputHeaders, RemoveOutputHeaders>();
|
||||||
_services.TryAddSingleton<IOcelotLoggerFactory, AspDotNetLoggerFactory>();
|
Services.TryAddSingleton<IClaimToThingConfigurationParser, ClaimToThingConfigurationParser>();
|
||||||
_services.TryAddSingleton<IRemoveOutputHeaders, RemoveOutputHeaders>();
|
Services.TryAddSingleton<IClaimsAuthoriser, ClaimsAuthoriser>();
|
||||||
_services.TryAddSingleton<IClaimToThingConfigurationParser, ClaimToThingConfigurationParser>();
|
Services.TryAddSingleton<IScopesAuthoriser, ScopesAuthoriser>();
|
||||||
_services.TryAddSingleton<IClaimsAuthoriser, ClaimsAuthoriser>();
|
Services.TryAddSingleton<IAddClaimsToRequest, AddClaimsToRequest>();
|
||||||
_services.TryAddSingleton<IScopesAuthoriser, ScopesAuthoriser>();
|
Services.TryAddSingleton<IAddHeadersToRequest, AddHeadersToRequest>();
|
||||||
_services.TryAddSingleton<IAddClaimsToRequest, AddClaimsToRequest>();
|
Services.TryAddSingleton<IAddQueriesToRequest, AddQueriesToRequest>();
|
||||||
_services.TryAddSingleton<IAddHeadersToRequest, AddHeadersToRequest>();
|
Services.TryAddSingleton<IClaimsParser, ClaimsParser>();
|
||||||
_services.TryAddSingleton<IAddQueriesToRequest, AddQueriesToRequest>();
|
Services.TryAddSingleton<IUrlPathToUrlTemplateMatcher, RegExUrlMatcher>();
|
||||||
_services.TryAddSingleton<IClaimsParser, ClaimsParser>();
|
Services.TryAddSingleton<IPlaceholderNameAndValueFinder, UrlPathPlaceholderNameAndValueFinder>();
|
||||||
_services.TryAddSingleton<IUrlPathToUrlTemplateMatcher, RegExUrlMatcher>();
|
Services.TryAddSingleton<IDownstreamPathPlaceholderReplacer, DownstreamTemplatePathPlaceholderReplacer>();
|
||||||
_services.TryAddSingleton<IPlaceholderNameAndValueFinder, UrlPathPlaceholderNameAndValueFinder>();
|
Services.AddSingleton<IDownstreamRouteProvider, DownstreamRouteFinder>();
|
||||||
_services.TryAddSingleton<IDownstreamPathPlaceholderReplacer, DownstreamTemplatePathPlaceholderReplacer>();
|
Services.AddSingleton<IDownstreamRouteProvider, DownstreamRouteCreator>();
|
||||||
_services.AddSingleton<IDownstreamRouteProvider, DownstreamRouteFinder>();
|
Services.TryAddSingleton<IDownstreamRouteProviderFactory, DownstreamRouteProviderFactory>();
|
||||||
_services.AddSingleton<IDownstreamRouteProvider, Ocelot.DownstreamRouteFinder.Finder.DownstreamRouteCreator>();
|
Services.TryAddSingleton<IHttpRequester, HttpClientHttpRequester>();
|
||||||
_services.TryAddSingleton<IDownstreamRouteProviderFactory, Ocelot.DownstreamRouteFinder.Finder.DownstreamRouteProviderFactory>();
|
Services.TryAddSingleton<IHttpResponder, HttpContextResponder>();
|
||||||
_services.TryAddSingleton<IHttpRequester, HttpClientHttpRequester>();
|
Services.TryAddSingleton<IErrorsToHttpStatusCodeMapper, ErrorsToHttpStatusCodeMapper>();
|
||||||
_services.TryAddSingleton<IHttpResponder, HttpContextResponder>();
|
Services.TryAddSingleton<IRateLimitCounterHandler, MemoryCacheRateLimitCounterHandler>();
|
||||||
_services.TryAddSingleton<IErrorsToHttpStatusCodeMapper, ErrorsToHttpStatusCodeMapper>();
|
Services.TryAddSingleton<IHttpClientCache, MemoryHttpClientCache>();
|
||||||
_services.TryAddSingleton<IRateLimitCounterHandler, MemoryCacheRateLimitCounterHandler>();
|
Services.TryAddSingleton<IRequestMapper, RequestMapper>();
|
||||||
_services.TryAddSingleton<IHttpClientCache, MemoryHttpClientCache>();
|
Services.TryAddSingleton<IHttpHandlerOptionsCreator, HttpHandlerOptionsCreator>();
|
||||||
_services.TryAddSingleton<IRequestMapper, RequestMapper>();
|
Services.TryAddSingleton<IDownstreamAddressesCreator, DownstreamAddressesCreator>();
|
||||||
_services.TryAddSingleton<IHttpHandlerOptionsCreator, HttpHandlerOptionsCreator>();
|
Services.TryAddSingleton<IDelegatingHandlerHandlerFactory, DelegatingHandlerHandlerFactory>();
|
||||||
_services.TryAddSingleton<IDownstreamAddressesCreator, DownstreamAddressesCreator>();
|
|
||||||
_services.TryAddSingleton<IDelegatingHandlerHandlerFactory, DelegatingHandlerHandlerFactory>();
|
|
||||||
|
|
||||||
if (UsingEurekaServiceDiscoveryProvider(configurationRoot))
|
if (UsingEurekaServiceDiscoveryProvider(configurationRoot))
|
||||||
{
|
{
|
||||||
_services.AddDiscoveryClient(configurationRoot);
|
Services.AddDiscoveryClient(configurationRoot);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_services.TryAddSingleton<IDiscoveryClient, FakeEurekaDiscoveryClient>();
|
Services.TryAddSingleton<IDiscoveryClient, FakeEurekaDiscoveryClient>();
|
||||||
}
|
}
|
||||||
|
|
||||||
_services.TryAddSingleton<IHttpRequester, HttpClientHttpRequester>();
|
Services.TryAddSingleton<IHttpRequester, HttpClientHttpRequester>();
|
||||||
|
|
||||||
// see this for why we register this as singleton http://stackoverflow.com/questions/37371264/invalidoperationexception-unable-to-resolve-service-for-type-microsoft-aspnetc
|
// see this for why we register this as singleton http://stackoverflow.com/questions/37371264/invalidoperationexception-unable-to-resolve-service-for-type-microsoft-aspnetc
|
||||||
// could maybe use a scoped data repository
|
// could maybe use a scoped data repository
|
||||||
_services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
Services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
||||||
_services.TryAddSingleton<IRequestScopedDataRepository, HttpDataRepository>();
|
Services.TryAddSingleton<IRequestScopedDataRepository, HttpDataRepository>();
|
||||||
_services.AddMemoryCache();
|
Services.AddMemoryCache();
|
||||||
_services.TryAddSingleton<OcelotDiagnosticListener>();
|
Services.TryAddSingleton<OcelotDiagnosticListener>();
|
||||||
|
|
||||||
//add asp.net services..
|
//add asp.net services..
|
||||||
var assembly = typeof(FileConfigurationController).GetTypeInfo().Assembly;
|
var assembly = typeof(FileConfigurationController).GetTypeInfo().Assembly;
|
||||||
|
|
||||||
_services.AddMvcCore()
|
Services.AddMvcCore()
|
||||||
.AddApplicationPart(assembly)
|
.AddApplicationPart(assembly)
|
||||||
.AddControllersAsServices()
|
.AddControllersAsServices()
|
||||||
.AddAuthorization()
|
.AddAuthorization()
|
||||||
.AddJsonFormatters();
|
.AddJsonFormatters();
|
||||||
|
|
||||||
_services.AddLogging();
|
Services.AddLogging();
|
||||||
_services.AddMiddlewareAnalysis();
|
Services.AddMiddlewareAnalysis();
|
||||||
_services.AddWebEncoders();
|
Services.AddWebEncoders();
|
||||||
|
|
||||||
_services.TryAddSingleton<IMultiplexer, Multiplexer>();
|
Services.TryAddSingleton<IMultiplexer, Multiplexer>();
|
||||||
_services.TryAddSingleton<IResponseAggregator, SimpleJsonResponseAggregator>();
|
Services.TryAddSingleton<IResponseAggregator, SimpleJsonResponseAggregator>();
|
||||||
_services.AddSingleton<ITracingHandlerFactory, TracingHandlerFactory>();
|
Services.AddSingleton<ITracingHandlerFactory, TracingHandlerFactory>();
|
||||||
_services.TryAddSingleton<IFileConfigurationPollerOptions, InMemoryFileConfigurationPollerOptions>();
|
Services.TryAddSingleton<IFileConfigurationPollerOptions, InMemoryFileConfigurationPollerOptions>();
|
||||||
_services.TryAddSingleton<IAddHeadersToResponse, AddHeadersToResponse>();
|
Services.TryAddSingleton<IAddHeadersToResponse, AddHeadersToResponse>();
|
||||||
_services.TryAddSingleton<IPlaceholders, Placeholders>();
|
Services.TryAddSingleton<IPlaceholders, Placeholders>();
|
||||||
_services.TryAddSingleton<IConsulClientFactory, ConsulClientFactory>();
|
Services.TryAddSingleton<IConsulClientFactory, ConsulClientFactory>();
|
||||||
_services.TryAddSingleton<IResponseAggregatorFactory, InMemoryResponseAggregatorFactory>();
|
Services.TryAddSingleton<IResponseAggregatorFactory, InMemoryResponseAggregatorFactory>();
|
||||||
_services.TryAddSingleton<IDefinedAggregatorProvider, ServiceLocatorDefinedAggregatorProvider>();
|
Services.TryAddSingleton<IDefinedAggregatorProvider, ServiceLocatorDefinedAggregatorProvider>();
|
||||||
_services.TryAddSingleton<IDownstreamRequestCreator, DownstreamRequestCreator>();
|
Services.TryAddSingleton<IDownstreamRequestCreator, DownstreamRequestCreator>();
|
||||||
_services.TryAddSingleton<IFrameworkDescription, FrameworkDescription>();
|
Services.TryAddSingleton<IFrameworkDescription, FrameworkDescription>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IOcelotAdministrationBuilder AddAdministration(string path, string secret)
|
public IOcelotAdministrationBuilder AddAdministration(string path, string secret)
|
||||||
@ -176,8 +167,8 @@ namespace Ocelot.DependencyInjection
|
|||||||
AddIdentityServer(identityServerConfiguration, administrationPath);
|
AddIdentityServer(identityServerConfiguration, administrationPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
_services.AddSingleton<IAdministrationPath>(administrationPath);
|
Services.AddSingleton<IAdministrationPath>(administrationPath);
|
||||||
return new OcelotAdministrationBuilder(_services, _configurationRoot);
|
return new OcelotAdministrationBuilder(Services, Configuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IOcelotAdministrationBuilder AddAdministration(string path, Action<IdentityServerAuthenticationOptions> configureOptions)
|
public IOcelotAdministrationBuilder AddAdministration(string path, Action<IdentityServerAuthenticationOptions> configureOptions)
|
||||||
@ -189,21 +180,21 @@ namespace Ocelot.DependencyInjection
|
|||||||
AddIdentityServer(configureOptions);
|
AddIdentityServer(configureOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
_services.AddSingleton<IAdministrationPath>(administrationPath);
|
Services.AddSingleton<IAdministrationPath>(administrationPath);
|
||||||
return new OcelotAdministrationBuilder(_services, _configurationRoot);
|
return new OcelotAdministrationBuilder(Services, Configuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IOcelotBuilder AddSingletonDefinedAggregator<T>()
|
public IOcelotBuilder AddSingletonDefinedAggregator<T>()
|
||||||
where T : class, IDefinedAggregator
|
where T : class, IDefinedAggregator
|
||||||
{
|
{
|
||||||
_services.AddSingleton<IDefinedAggregator, T>();
|
Services.AddSingleton<IDefinedAggregator, T>();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IOcelotBuilder AddTransientDefinedAggregator<T>()
|
public IOcelotBuilder AddTransientDefinedAggregator<T>()
|
||||||
where T : class, IDefinedAggregator
|
where T : class, IDefinedAggregator
|
||||||
{
|
{
|
||||||
_services.AddTransient<IDefinedAggregator, T>();
|
Services.AddTransient<IDefinedAggregator, T>();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,15 +203,15 @@ namespace Ocelot.DependencyInjection
|
|||||||
{
|
{
|
||||||
if(global)
|
if(global)
|
||||||
{
|
{
|
||||||
_services.AddTransient<THandler>();
|
Services.AddTransient<THandler>();
|
||||||
_services.AddTransient<GlobalDelegatingHandler>(s => {
|
Services.AddTransient<GlobalDelegatingHandler>(s => {
|
||||||
var service = s.GetService<THandler>();
|
var service = s.GetService<THandler>();
|
||||||
return new GlobalDelegatingHandler(service);
|
return new GlobalDelegatingHandler(service);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_services.AddTransient<DelegatingHandler, THandler>();
|
Services.AddTransient<DelegatingHandler, THandler>();
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
@ -228,59 +219,33 @@ namespace Ocelot.DependencyInjection
|
|||||||
|
|
||||||
public IOcelotBuilder AddStoreOcelotConfigurationInConsul()
|
public IOcelotBuilder AddStoreOcelotConfigurationInConsul()
|
||||||
{
|
{
|
||||||
_services.AddHostedService<FileConfigurationPoller>();
|
Services.AddHostedService<FileConfigurationPoller>();
|
||||||
_services.AddSingleton<IFileConfigurationRepository, ConsulFileConfigurationRepository>();
|
Services.AddSingleton<IFileConfigurationRepository, ConsulFileConfigurationRepository>();
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IOcelotBuilder AddCacheManager(Action<ConfigurationBuilderCachePart> settings)
|
|
||||||
{
|
|
||||||
var cacheManagerOutputCache = CacheFactory.Build<CachedResponse>("OcelotOutputCache", settings);
|
|
||||||
var ocelotOutputCacheManager = new OcelotCacheManagerCache<CachedResponse>(cacheManagerOutputCache);
|
|
||||||
|
|
||||||
_services.RemoveAll(typeof(ICacheManager<CachedResponse>));
|
|
||||||
_services.RemoveAll(typeof(IOcelotCache<CachedResponse>));
|
|
||||||
_services.AddSingleton<ICacheManager<CachedResponse>>(cacheManagerOutputCache);
|
|
||||||
_services.AddSingleton<IOcelotCache<CachedResponse>>(ocelotOutputCacheManager);
|
|
||||||
|
|
||||||
var ocelotConfigCacheManagerOutputCache = CacheFactory.Build<IInternalConfiguration>("OcelotConfigurationCache", settings);
|
|
||||||
var ocelotConfigCacheManager = new OcelotCacheManagerCache<IInternalConfiguration>(ocelotConfigCacheManagerOutputCache);
|
|
||||||
_services.RemoveAll(typeof(ICacheManager<IInternalConfiguration>));
|
|
||||||
_services.RemoveAll(typeof(IOcelotCache<IInternalConfiguration>));
|
|
||||||
_services.AddSingleton<ICacheManager<IInternalConfiguration>>(ocelotConfigCacheManagerOutputCache);
|
|
||||||
_services.AddSingleton<IOcelotCache<IInternalConfiguration>>(ocelotConfigCacheManager);
|
|
||||||
|
|
||||||
var fileConfigCacheManagerOutputCache = CacheFactory.Build<FileConfiguration>("FileConfigurationCache", settings);
|
|
||||||
var fileConfigCacheManager = new OcelotCacheManagerCache<FileConfiguration>(fileConfigCacheManagerOutputCache);
|
|
||||||
_services.RemoveAll(typeof(ICacheManager<FileConfiguration>));
|
|
||||||
_services.RemoveAll(typeof(IOcelotCache<FileConfiguration>));
|
|
||||||
_services.AddSingleton<ICacheManager<FileConfiguration>>(fileConfigCacheManagerOutputCache);
|
|
||||||
_services.AddSingleton<IOcelotCache<FileConfiguration>>(fileConfigCacheManager);
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddIdentityServer(Action<IdentityServerAuthenticationOptions> configOptions)
|
private void AddIdentityServer(Action<IdentityServerAuthenticationOptions> configOptions)
|
||||||
{
|
{
|
||||||
_services
|
Services
|
||||||
.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
|
.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
|
||||||
.AddIdentityServerAuthentication(configOptions);
|
.AddIdentityServerAuthentication(configOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddIdentityServer(IIdentityServerConfiguration identityServerConfiguration, IAdministrationPath adminPath)
|
private void AddIdentityServer(IIdentityServerConfiguration identityServerConfiguration, IAdministrationPath adminPath)
|
||||||
{
|
{
|
||||||
_services.TryAddSingleton<IIdentityServerConfiguration>(identityServerConfiguration);
|
Services.TryAddSingleton<IIdentityServerConfiguration>(identityServerConfiguration);
|
||||||
var identityServerBuilder = _services
|
var identityServerBuilder = Services
|
||||||
.AddIdentityServer(o => {
|
.AddIdentityServer(o => {
|
||||||
o.IssuerUri = "Ocelot";
|
o.IssuerUri = "Ocelot";
|
||||||
})
|
})
|
||||||
.AddInMemoryApiResources(Resources(identityServerConfiguration))
|
.AddInMemoryApiResources(Resources(identityServerConfiguration))
|
||||||
.AddInMemoryClients(Client(identityServerConfiguration));
|
.AddInMemoryClients(Client(identityServerConfiguration));
|
||||||
|
|
||||||
var urlFinder = new BaseUrlFinder(_configurationRoot);
|
var urlFinder = new BaseUrlFinder(Configuration);
|
||||||
var baseSchemeUrlAndPort = urlFinder.Find();
|
var baseSchemeUrlAndPort = urlFinder.Find();
|
||||||
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
|
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
|
||||||
|
|
||||||
_services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
|
Services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
|
||||||
.AddIdentityServerAuthentication(o =>
|
.AddIdentityServerAuthentication(o =>
|
||||||
{
|
{
|
||||||
o.Authority = baseSchemeUrlAndPort + adminPath.Path;
|
o.Authority = baseSchemeUrlAndPort + adminPath.Path;
|
||||||
|
@ -45,9 +45,6 @@
|
|||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.0" />
|
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.0" />
|
||||||
<PackageReference Include="CacheManager.Core" Version="1.1.2" />
|
|
||||||
<PackageReference Include="CacheManager.Microsoft.Extensions.Configuration" Version="1.1.2" />
|
|
||||||
<PackageReference Include="CacheManager.Microsoft.Extensions.Logging" Version="1.1.2" />
|
|
||||||
<PackageReference Include="Consul" Version="0.7.2.5" />
|
<PackageReference Include="Consul" Version="0.7.2.5" />
|
||||||
<PackageReference Include="Polly" Version="6.0.1" />
|
<PackageReference Include="Polly" Version="6.0.1" />
|
||||||
<PackageReference Include="IdentityServer4" Version="2.2.0" />
|
<PackageReference Include="IdentityServer4" Version="2.2.0" />
|
||||||
|
@ -1,137 +0,0 @@
|
|||||||
using CacheManager.Core;
|
|
||||||
using CacheManager.Core.Internal;
|
|
||||||
using CacheManager.Core.Logging;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Linq;
|
|
||||||
using static CacheManager.Core.Utility.Guard;
|
|
||||||
|
|
||||||
namespace Ocelot.AcceptanceTests.Caching
|
|
||||||
{
|
|
||||||
public class InMemoryJsonHandle<TCacheValue> : BaseCacheHandle<TCacheValue>
|
|
||||||
{
|
|
||||||
private readonly ICacheSerializer _serializer;
|
|
||||||
private readonly ConcurrentDictionary<string, Tuple<Type, byte[]>> _cache;
|
|
||||||
|
|
||||||
public InMemoryJsonHandle(
|
|
||||||
ICacheManagerConfiguration managerConfiguration,
|
|
||||||
CacheHandleConfiguration configuration,
|
|
||||||
ICacheSerializer serializer,
|
|
||||||
ILoggerFactory loggerFactory) : base(managerConfiguration, configuration)
|
|
||||||
{
|
|
||||||
_cache = new ConcurrentDictionary<string, Tuple<Type, byte[]>>();
|
|
||||||
_serializer = serializer;
|
|
||||||
Logger = loggerFactory.CreateLogger(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int Count => _cache.Count;
|
|
||||||
|
|
||||||
protected override ILogger Logger { get; }
|
|
||||||
|
|
||||||
public override void Clear() => _cache.Clear();
|
|
||||||
|
|
||||||
public override void ClearRegion(string region)
|
|
||||||
{
|
|
||||||
NotNullOrWhiteSpace(region, nameof(region));
|
|
||||||
|
|
||||||
var key = string.Concat(region, ":");
|
|
||||||
foreach (var item in _cache.Where(p => p.Key.StartsWith(key, StringComparison.OrdinalIgnoreCase)))
|
|
||||||
{
|
|
||||||
_cache.TryRemove(item.Key, out Tuple<Type, byte[]> val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Exists(string key)
|
|
||||||
{
|
|
||||||
NotNullOrWhiteSpace(key, nameof(key));
|
|
||||||
|
|
||||||
return _cache.ContainsKey(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Exists(string key, string region)
|
|
||||||
{
|
|
||||||
NotNullOrWhiteSpace(region, nameof(region));
|
|
||||||
var fullKey = GetKey(key, region);
|
|
||||||
return _cache.ContainsKey(fullKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool AddInternalPrepared(CacheItem<TCacheValue> item)
|
|
||||||
{
|
|
||||||
NotNull(item, nameof(item));
|
|
||||||
|
|
||||||
var key = GetKey(item.Key, item.Region);
|
|
||||||
|
|
||||||
var serializedItem = _serializer.SerializeCacheItem(item);
|
|
||||||
|
|
||||||
return _cache.TryAdd(key, new Tuple<Type, byte[]>(item.Value.GetType(), serializedItem));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override CacheItem<TCacheValue> GetCacheItemInternal(string key) => GetCacheItemInternal(key, null);
|
|
||||||
|
|
||||||
protected override CacheItem<TCacheValue> GetCacheItemInternal(string key, string region)
|
|
||||||
{
|
|
||||||
var fullKey = GetKey(key, region);
|
|
||||||
|
|
||||||
CacheItem<TCacheValue> deserializedResult = null;
|
|
||||||
|
|
||||||
if (_cache.TryGetValue(fullKey, out Tuple<Type, byte[]> result))
|
|
||||||
{
|
|
||||||
deserializedResult = _serializer.DeserializeCacheItem<TCacheValue>(result.Item2, result.Item1);
|
|
||||||
|
|
||||||
if (deserializedResult.ExpirationMode != ExpirationMode.None && IsExpired(deserializedResult, DateTime.UtcNow))
|
|
||||||
{
|
|
||||||
_cache.TryRemove(fullKey, out Tuple<Type, byte[]> removeResult);
|
|
||||||
TriggerCacheSpecificRemove(key, region, CacheItemRemovedReason.Expired, deserializedResult.Value);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return deserializedResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void PutInternalPrepared(CacheItem<TCacheValue> item)
|
|
||||||
{
|
|
||||||
NotNull(item, nameof(item));
|
|
||||||
|
|
||||||
var serializedItem = _serializer.SerializeCacheItem<TCacheValue>(item);
|
|
||||||
|
|
||||||
_cache[GetKey(item.Key, item.Region)] = new Tuple<Type, byte[]>(item.Value.GetType(), serializedItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool RemoveInternal(string key) => RemoveInternal(key, null);
|
|
||||||
|
|
||||||
protected override bool RemoveInternal(string key, string region)
|
|
||||||
{
|
|
||||||
var fullKey = GetKey(key, region);
|
|
||||||
return _cache.TryRemove(fullKey, out Tuple<Type, byte[]> val);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetKey(string key, string region)
|
|
||||||
{
|
|
||||||
NotNullOrWhiteSpace(key, nameof(key));
|
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(region))
|
|
||||||
{
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
return string.Concat(region, ":", key);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool IsExpired(CacheItem<TCacheValue> item, DateTime now)
|
|
||||||
{
|
|
||||||
if (item.ExpirationMode == ExpirationMode.Absolute
|
|
||||||
&& item.CreatedUtc.Add(item.ExpirationTimeout) < now)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (item.ExpirationMode == ExpirationMode.Sliding
|
|
||||||
&& item.LastAccessedUtc.Add(item.ExpirationTimeout) < now)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,225 +0,0 @@
|
|||||||
namespace Ocelot.AcceptanceTests
|
|
||||||
{
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Net;
|
|
||||||
using System.Threading;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Ocelot.Configuration.File;
|
|
||||||
using TestStack.BDDfy;
|
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
public class CachingTests : IDisposable
|
|
||||||
{
|
|
||||||
private readonly Steps _steps;
|
|
||||||
private readonly ServiceHandler _serviceHandler;
|
|
||||||
|
|
||||||
public CachingTests()
|
|
||||||
{
|
|
||||||
_serviceHandler = new ServiceHandler();
|
|
||||||
_steps = new Steps();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void should_return_cached_response()
|
|
||||||
{
|
|
||||||
var configuration = new FileConfiguration
|
|
||||||
{
|
|
||||||
ReRoutes = new List<FileReRoute>
|
|
||||||
{
|
|
||||||
new FileReRoute
|
|
||||||
{
|
|
||||||
DownstreamPathTemplate = "/",
|
|
||||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
|
||||||
{
|
|
||||||
new FileHostAndPort
|
|
||||||
{
|
|
||||||
Host = "localhost",
|
|
||||||
Port = 51899,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
DownstreamScheme = "http",
|
|
||||||
UpstreamPathTemplate = "/",
|
|
||||||
UpstreamHttpMethod = new List<string> { "Get" },
|
|
||||||
FileCacheOptions = new FileCacheOptions
|
|
||||||
{
|
|
||||||
TtlSeconds = 100
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51899", 200, "Hello from Laura", null, null))
|
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
|
||||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
|
||||||
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
|
|
||||||
.Given(x => x.GivenTheServiceNowReturns("http://localhost:51899", 200, "Hello from Tom"))
|
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
|
||||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
|
||||||
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
|
|
||||||
.And(x => _steps.ThenTheContentLengthIs(16))
|
|
||||||
.BDDfy();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void should_return_cached_response_with_expires_header()
|
|
||||||
{
|
|
||||||
var configuration = new FileConfiguration
|
|
||||||
{
|
|
||||||
ReRoutes = new List<FileReRoute>
|
|
||||||
{
|
|
||||||
new FileReRoute
|
|
||||||
{
|
|
||||||
DownstreamPathTemplate = "/",
|
|
||||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
|
||||||
{
|
|
||||||
new FileHostAndPort
|
|
||||||
{
|
|
||||||
Host = "localhost",
|
|
||||||
Port = 52839,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
DownstreamScheme = "http",
|
|
||||||
UpstreamPathTemplate = "/",
|
|
||||||
UpstreamHttpMethod = new List<string> { "Get" },
|
|
||||||
FileCacheOptions = new FileCacheOptions
|
|
||||||
{
|
|
||||||
TtlSeconds = 100
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:52839", 200, "Hello from Laura", "Expires", "-1"))
|
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
|
||||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
|
||||||
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
|
|
||||||
.Given(x => x.GivenTheServiceNowReturns("http://localhost:52839", 200, "Hello from Tom"))
|
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
|
||||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
|
||||||
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
|
|
||||||
.And(x => _steps.ThenTheContentLengthIs(16))
|
|
||||||
.And(x => _steps.ThenTheResponseBodyHeaderIs("Expires", "-1"))
|
|
||||||
.BDDfy();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void should_return_cached_response_when_using_jsonserialized_cache()
|
|
||||||
{
|
|
||||||
var configuration = new FileConfiguration
|
|
||||||
{
|
|
||||||
ReRoutes = new List<FileReRoute>
|
|
||||||
{
|
|
||||||
new FileReRoute
|
|
||||||
{
|
|
||||||
DownstreamPathTemplate = "/",
|
|
||||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
|
||||||
{
|
|
||||||
new FileHostAndPort
|
|
||||||
{
|
|
||||||
Host = "localhost",
|
|
||||||
Port = 51899,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
DownstreamScheme = "http",
|
|
||||||
UpstreamPathTemplate = "/",
|
|
||||||
UpstreamHttpMethod = new List<string> { "Get" },
|
|
||||||
FileCacheOptions = new FileCacheOptions
|
|
||||||
{
|
|
||||||
TtlSeconds = 100
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51899", 200, "Hello from Laura", null, null))
|
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
|
||||||
.And(x => _steps.GivenOcelotIsRunningUsingJsonSerializedCache())
|
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
|
||||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
|
||||||
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
|
|
||||||
.Given(x => x.GivenTheServiceNowReturns("http://localhost:51899", 200, "Hello from Tom"))
|
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
|
||||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
|
||||||
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
|
|
||||||
.BDDfy();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void should_not_return_cached_response_as_ttl_expires()
|
|
||||||
{
|
|
||||||
var configuration = new FileConfiguration
|
|
||||||
{
|
|
||||||
ReRoutes = new List<FileReRoute>
|
|
||||||
{
|
|
||||||
new FileReRoute
|
|
||||||
{
|
|
||||||
DownstreamPathTemplate = "/",
|
|
||||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
|
||||||
{
|
|
||||||
new FileHostAndPort
|
|
||||||
{
|
|
||||||
Host = "localhost",
|
|
||||||
Port = 51899,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
DownstreamScheme = "http",
|
|
||||||
UpstreamPathTemplate = "/",
|
|
||||||
UpstreamHttpMethod = new List<string> { "Get" },
|
|
||||||
FileCacheOptions = new FileCacheOptions
|
|
||||||
{
|
|
||||||
TtlSeconds = 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51899", 200, "Hello from Laura", null, null))
|
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
|
||||||
.And(x => _steps.GivenOcelotIsRunning())
|
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
|
||||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
|
||||||
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
|
|
||||||
.Given(x => x.GivenTheServiceNowReturns("http://localhost:51899", 200, "Hello from Tom"))
|
|
||||||
.And(x => x.GivenTheCacheExpires())
|
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
|
||||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
|
||||||
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Tom"))
|
|
||||||
.BDDfy();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GivenTheCacheExpires()
|
|
||||||
{
|
|
||||||
Thread.Sleep(1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GivenTheServiceNowReturns(string url, int statusCode, string responseBody)
|
|
||||||
{
|
|
||||||
_serviceHandler.Dispose();
|
|
||||||
GivenThereIsAServiceRunningOn(url, statusCode, responseBody, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GivenThereIsAServiceRunningOn(string url, int statusCode, string responseBody, string key, string value)
|
|
||||||
{
|
|
||||||
_serviceHandler.GivenThereIsAServiceRunningOn(url, async context =>
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(key))
|
|
||||||
{
|
|
||||||
context.Response.Headers.Add(key, value);
|
|
||||||
}
|
|
||||||
context.Response.StatusCode = statusCode;
|
|
||||||
await context.Response.WriteAsync(responseBody);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
_serviceHandler?.Dispose();
|
|
||||||
_steps.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -17,6 +17,8 @@ using static Ocelot.Infrastructure.Wait;
|
|||||||
|
|
||||||
namespace Ocelot.AcceptanceTests
|
namespace Ocelot.AcceptanceTests
|
||||||
{
|
{
|
||||||
|
using Cache;
|
||||||
|
|
||||||
public class ConfigurationInConsulTests : IDisposable
|
public class ConfigurationInConsulTests : IDisposable
|
||||||
{
|
{
|
||||||
private IWebHost _builder;
|
private IWebHost _builder;
|
||||||
@ -76,51 +78,6 @@ namespace Ocelot.AcceptanceTests
|
|||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void should_return_response_200_with_simple_url_when_using_jsonserialized_cache()
|
|
||||||
{
|
|
||||||
var configuration = new FileConfiguration
|
|
||||||
{
|
|
||||||
ReRoutes = new List<FileReRoute>
|
|
||||||
{
|
|
||||||
new FileReRoute
|
|
||||||
{
|
|
||||||
DownstreamPathTemplate = "/",
|
|
||||||
DownstreamScheme = "http",
|
|
||||||
DownstreamHostAndPorts = new List<FileHostAndPort>
|
|
||||||
{
|
|
||||||
new FileHostAndPort
|
|
||||||
{
|
|
||||||
Host = "localhost",
|
|
||||||
Port = 51779,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
UpstreamPathTemplate = "/",
|
|
||||||
UpstreamHttpMethod = new List<string> { "Get" },
|
|
||||||
}
|
|
||||||
},
|
|
||||||
GlobalConfiguration = new FileGlobalConfiguration()
|
|
||||||
{
|
|
||||||
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider()
|
|
||||||
{
|
|
||||||
Host = "localhost",
|
|
||||||
Port = 9502
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var fakeConsulServiceDiscoveryUrl = "http://localhost:9502";
|
|
||||||
|
|
||||||
this.Given(x => GivenThereIsAFakeConsulServiceDiscoveryProvider(fakeConsulServiceDiscoveryUrl, ""))
|
|
||||||
.And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51779", "", 200, "Hello from Laura"))
|
|
||||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
|
||||||
.And(x => _steps.GivenOcelotIsRunningUsingConsulToStoreConfigAndJsonSerializedCache())
|
|
||||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
|
|
||||||
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
|
|
||||||
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
|
|
||||||
.BDDfy();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_load_configuration_out_of_consul()
|
public void should_load_configuration_out_of_consul()
|
||||||
{
|
{
|
||||||
@ -485,5 +442,28 @@ namespace Ocelot.AcceptanceTests
|
|||||||
_builder?.Dispose();
|
_builder?.Dispose();
|
||||||
_steps.Dispose();
|
_steps.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class FakeCache : IOcelotCache<FileConfiguration>
|
||||||
|
{
|
||||||
|
public void Add(string key, FileConfiguration value, TimeSpan ttl, string region)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddAndDelete(string key, FileConfiguration value, TimeSpan ttl, string region)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileConfiguration Get(string key, string region)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClearRegion(string region)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,6 @@
|
|||||||
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
|
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="CacheManager.Serialization.Json" Version="1.1.2" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.1.1" />
|
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.1.1" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.1.1" />
|
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.1.1" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.2" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.2" />
|
||||||
|
@ -1,40 +1,35 @@
|
|||||||
using System;
|
namespace Ocelot.AcceptanceTests
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Net.Http.Headers;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using CacheManager.Core;
|
|
||||||
using IdentityServer4.AccessTokenValidation;
|
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.AspNetCore.TestHost;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Ocelot.Configuration.File;
|
|
||||||
using Ocelot.DependencyInjection;
|
|
||||||
using Ocelot.Middleware;
|
|
||||||
using Shouldly;
|
|
||||||
using ConfigurationBuilder = Microsoft.Extensions.Configuration.ConfigurationBuilder;
|
|
||||||
using Ocelot.AcceptanceTests.Caching;
|
|
||||||
using System.IO.Compression;
|
|
||||||
using System.Text;
|
|
||||||
using static Ocelot.AcceptanceTests.HttpDelegatingHandlersTests;
|
|
||||||
using Ocelot.Requester;
|
|
||||||
using Ocelot.Middleware.Multiplexer;
|
|
||||||
using static Ocelot.Infrastructure.Wait;
|
|
||||||
|
|
||||||
namespace Ocelot.AcceptanceTests
|
|
||||||
{
|
{
|
||||||
using Butterfly;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using IdentityServer4.AccessTokenValidation;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.AspNetCore.TestHost;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Ocelot.Configuration.File;
|
||||||
|
using Ocelot.DependencyInjection;
|
||||||
|
using Ocelot.Middleware;
|
||||||
|
using Shouldly;
|
||||||
|
using ConfigurationBuilder = Microsoft.Extensions.Configuration.ConfigurationBuilder;
|
||||||
|
using System.IO.Compression;
|
||||||
|
using System.Text;
|
||||||
|
using static Ocelot.AcceptanceTests.HttpDelegatingHandlersTests;
|
||||||
|
using Ocelot.Middleware.Multiplexer;
|
||||||
|
using static Ocelot.Infrastructure.Wait;
|
||||||
using Configuration.Repository;
|
using Configuration.Repository;
|
||||||
using Microsoft.Net.Http.Headers;
|
|
||||||
using Ocelot.Configuration.Creator;
|
using Ocelot.Configuration.Creator;
|
||||||
|
using CookieHeaderValue = System.Net.Http.Headers.CookieHeaderValue;
|
||||||
using MediaTypeHeaderValue = System.Net.Http.Headers.MediaTypeHeaderValue;
|
using MediaTypeHeaderValue = System.Net.Http.Headers.MediaTypeHeaderValue;
|
||||||
|
|
||||||
public class Steps : IDisposable
|
public class Steps : IDisposable
|
||||||
@ -44,7 +39,6 @@ namespace Ocelot.AcceptanceTests
|
|||||||
private HttpResponseMessage _response;
|
private HttpResponseMessage _response;
|
||||||
private HttpContent _postContent;
|
private HttpContent _postContent;
|
||||||
private BearerToken _token;
|
private BearerToken _token;
|
||||||
public HttpClient OcelotClient => _ocelotClient;
|
|
||||||
public string RequestIdKey = "OcRequestId";
|
public string RequestIdKey = "OcRequestId";
|
||||||
private readonly Random _random;
|
private readonly Random _random;
|
||||||
private IWebHostBuilder _webHostBuilder;
|
private IWebHostBuilder _webHostBuilder;
|
||||||
@ -428,55 +422,6 @@ namespace Ocelot.AcceptanceTests
|
|||||||
header.First().ShouldBe(value);
|
header.First().ShouldBe(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ThenTheResponseBodyHeaderIs(string key, string value)
|
|
||||||
{
|
|
||||||
var header = _response.Content.Headers.GetValues(key);
|
|
||||||
header.First().ShouldBe(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ThenTheTraceHeaderIsSet(string key)
|
|
||||||
{
|
|
||||||
var header = _response.Headers.GetValues(key);
|
|
||||||
header.First().ShouldNotBeNullOrEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void GivenOcelotIsRunningUsingJsonSerializedCache()
|
|
||||||
{
|
|
||||||
_webHostBuilder = new WebHostBuilder();
|
|
||||||
|
|
||||||
_webHostBuilder
|
|
||||||
.ConfigureAppConfiguration((hostingContext, config) =>
|
|
||||||
{
|
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
|
||||||
var env = hostingContext.HostingEnvironment;
|
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
|
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
|
|
||||||
config.AddJsonFile("ocelot.json", false, false);
|
|
||||||
config.AddEnvironmentVariables();
|
|
||||||
})
|
|
||||||
.ConfigureServices(s =>
|
|
||||||
{
|
|
||||||
s.AddOcelot()
|
|
||||||
.AddCacheManager((x) =>
|
|
||||||
{
|
|
||||||
x.WithMicrosoftLogging(log =>
|
|
||||||
{
|
|
||||||
log.AddConsole(LogLevel.Debug);
|
|
||||||
})
|
|
||||||
.WithJsonSerializer()
|
|
||||||
.WithHandle(typeof(InMemoryJsonHandle<>));
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.UseOcelot().Wait();
|
|
||||||
});
|
|
||||||
|
|
||||||
_ocelotServer = new TestServer(_webHostBuilder);
|
|
||||||
|
|
||||||
_ocelotClient = _ocelotServer.CreateClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void GivenOcelotIsRunningUsingConsulToStoreConfig()
|
public void GivenOcelotIsRunningUsingConsulToStoreConfig()
|
||||||
{
|
{
|
||||||
_webHostBuilder = new WebHostBuilder();
|
_webHostBuilder = new WebHostBuilder();
|
||||||
@ -505,69 +450,6 @@ namespace Ocelot.AcceptanceTests
|
|||||||
_ocelotClient = _ocelotServer.CreateClient();
|
_ocelotClient = _ocelotServer.CreateClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GivenOcelotIsRunningUsingConsulToStoreConfigAndJsonSerializedCache()
|
|
||||||
{
|
|
||||||
_webHostBuilder = new WebHostBuilder();
|
|
||||||
|
|
||||||
_webHostBuilder
|
|
||||||
.ConfigureAppConfiguration((hostingContext, config) =>
|
|
||||||
{
|
|
||||||
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
|
|
||||||
var env = hostingContext.HostingEnvironment;
|
|
||||||
config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false)
|
|
||||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: false);
|
|
||||||
config.AddJsonFile("ocelot.json", optional: true, reloadOnChange: false);
|
|
||||||
config.AddEnvironmentVariables();
|
|
||||||
})
|
|
||||||
.ConfigureServices(s =>
|
|
||||||
{
|
|
||||||
s.AddOcelot()
|
|
||||||
.AddCacheManager((x) =>
|
|
||||||
{
|
|
||||||
x.WithMicrosoftLogging(log =>
|
|
||||||
{
|
|
||||||
log.AddConsole(LogLevel.Debug);
|
|
||||||
})
|
|
||||||
.WithJsonSerializer()
|
|
||||||
.WithHandle(typeof(InMemoryJsonHandle<>));
|
|
||||||
})
|
|
||||||
.AddStoreOcelotConfigurationInConsul();
|
|
||||||
})
|
|
||||||
.Configure(app =>
|
|
||||||
{
|
|
||||||
app.UseOcelot().Wait();
|
|
||||||
});
|
|
||||||
|
|
||||||
_ocelotServer = new TestServer(_webHostBuilder);
|
|
||||||
|
|
||||||
_ocelotClient = _ocelotServer.CreateClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void ThenTheResponseShouldBe(FileConfiguration expecteds)
|
|
||||||
{
|
|
||||||
var response = JsonConvert.DeserializeObject<FileConfiguration>(_response.Content.ReadAsStringAsync().Result);
|
|
||||||
|
|
||||||
response.GlobalConfiguration.RequestIdKey.ShouldBe(expecteds.GlobalConfiguration.RequestIdKey);
|
|
||||||
response.GlobalConfiguration.ServiceDiscoveryProvider.Host.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Host);
|
|
||||||
response.GlobalConfiguration.ServiceDiscoveryProvider.Port.ShouldBe(expecteds.GlobalConfiguration.ServiceDiscoveryProvider.Port);
|
|
||||||
|
|
||||||
for (var i = 0; i < response.ReRoutes.Count; i++)
|
|
||||||
{
|
|
||||||
for (var j = 0; j < response.ReRoutes[i].DownstreamHostAndPorts.Count; j++)
|
|
||||||
{
|
|
||||||
var result = response.ReRoutes[i].DownstreamHostAndPorts[j];
|
|
||||||
var expected = expecteds.ReRoutes[i].DownstreamHostAndPorts[j];
|
|
||||||
result.Host.ShouldBe(expected.Host);
|
|
||||||
result.Port.ShouldBe(expected.Port);
|
|
||||||
}
|
|
||||||
|
|
||||||
response.ReRoutes[i].DownstreamPathTemplate.ShouldBe(expecteds.ReRoutes[i].DownstreamPathTemplate);
|
|
||||||
response.ReRoutes[i].DownstreamScheme.ShouldBe(expecteds.ReRoutes[i].DownstreamScheme);
|
|
||||||
response.ReRoutes[i].UpstreamPathTemplate.ShouldBe(expecteds.ReRoutes[i].UpstreamPathTemplate);
|
|
||||||
response.ReRoutes[i].UpstreamHttpMethod.ShouldBe(expecteds.ReRoutes[i].UpstreamHttpMethod);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is annoying cos it should be in the constructor but we need to set up the file before calling startup so its a step.
|
/// This is annoying cos it should be in the constructor but we need to set up the file before calling startup so its a step.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -590,15 +472,6 @@ namespace Ocelot.AcceptanceTests
|
|||||||
.UseConfiguration(configuration)
|
.UseConfiguration(configuration)
|
||||||
.ConfigureServices(s =>
|
.ConfigureServices(s =>
|
||||||
{
|
{
|
||||||
Action<ConfigurationBuilderCachePart> settings = (x) =>
|
|
||||||
{
|
|
||||||
x.WithMicrosoftLogging(log =>
|
|
||||||
{
|
|
||||||
log.AddConsole(LogLevel.Debug);
|
|
||||||
})
|
|
||||||
.WithDictionaryHandle();
|
|
||||||
};
|
|
||||||
|
|
||||||
s.AddOcelot(configuration);
|
s.AddOcelot(configuration);
|
||||||
})
|
})
|
||||||
.ConfigureLogging(l =>
|
.ConfigureLogging(l =>
|
||||||
@ -688,26 +561,6 @@ namespace Ocelot.AcceptanceTests
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GivenIHaveAnOcelotToken(string adminPath)
|
|
||||||
{
|
|
||||||
var tokenUrl = $"{adminPath}/connect/token";
|
|
||||||
var formData = new List<KeyValuePair<string, string>>
|
|
||||||
{
|
|
||||||
new KeyValuePair<string, string>("client_id", "admin"),
|
|
||||||
new KeyValuePair<string, string>("client_secret", "secret"),
|
|
||||||
new KeyValuePair<string, string>("scope", "admin"),
|
|
||||||
new KeyValuePair<string, string>("username", "admin"),
|
|
||||||
new KeyValuePair<string, string>("password", "admin"),
|
|
||||||
new KeyValuePair<string, string>("grant_type", "password")
|
|
||||||
};
|
|
||||||
var content = new FormUrlEncodedContent(formData);
|
|
||||||
|
|
||||||
var response = _ocelotClient.PostAsync(tokenUrl, content).Result;
|
|
||||||
var responseContent = response.Content.ReadAsStringAsync().Result;
|
|
||||||
response.EnsureSuccessStatusCode();
|
|
||||||
_token = JsonConvert.DeserializeObject<BearerToken>(responseContent);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void VerifyIdentiryServerStarted(string url)
|
public void VerifyIdentiryServerStarted(string url)
|
||||||
{
|
{
|
||||||
using (var httpClient = new HttpClient())
|
using (var httpClient = new HttpClient())
|
||||||
@ -883,11 +736,6 @@ namespace Ocelot.AcceptanceTests
|
|||||||
_response.Headers.GetValues(RequestIdKey).First().ShouldBe(expected);
|
_response.Headers.GetValues(RequestIdKey).First().ShouldBe(expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ThenTheContentLengthIs(int expected)
|
|
||||||
{
|
|
||||||
_response.Content.Headers.ContentLength.ShouldBe(expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void WhenIMakeLotsOfDifferentRequestsToTheApiGateway()
|
public void WhenIMakeLotsOfDifferentRequestsToTheApiGateway()
|
||||||
{
|
{
|
||||||
int numberOfRequests = 100;
|
int numberOfRequests = 100;
|
||||||
|
@ -5,7 +5,6 @@ using System.Net;
|
|||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using CacheManager.Core;
|
|
||||||
using IdentityServer4.AccessTokenValidation;
|
using IdentityServer4.AccessTokenValidation;
|
||||||
using IdentityServer4.Models;
|
using IdentityServer4.Models;
|
||||||
using IdentityServer4.Test;
|
using IdentityServer4.Test;
|
||||||
@ -557,17 +556,7 @@ namespace Ocelot.IntegrationTests
|
|||||||
})
|
})
|
||||||
.ConfigureServices(x =>
|
.ConfigureServices(x =>
|
||||||
{
|
{
|
||||||
Action<ConfigurationBuilderCachePart> settings = (s) =>
|
|
||||||
{
|
|
||||||
s.WithMicrosoftLogging(log =>
|
|
||||||
{
|
|
||||||
log.AddConsole(LogLevel.Debug);
|
|
||||||
})
|
|
||||||
.WithDictionaryHandle();
|
|
||||||
};
|
|
||||||
|
|
||||||
x.AddOcelot()
|
x.AddOcelot()
|
||||||
.AddCacheManager(settings)
|
|
||||||
.AddAdministration("/administration", "secret");
|
.AddAdministration("/administration", "secret");
|
||||||
})
|
})
|
||||||
.Configure(app =>
|
.Configure(app =>
|
||||||
@ -682,10 +671,6 @@ namespace Ocelot.IntegrationTests
|
|||||||
.ConfigureServices(x => {
|
.ConfigureServices(x => {
|
||||||
x.AddSingleton(_webHostBuilder);
|
x.AddSingleton(_webHostBuilder);
|
||||||
x.AddOcelot()
|
x.AddOcelot()
|
||||||
.AddCacheManager(c =>
|
|
||||||
{
|
|
||||||
c.WithDictionaryHandle();
|
|
||||||
})
|
|
||||||
.AddAdministration("/administration", configOptions);
|
.AddAdministration("/administration", configOptions);
|
||||||
})
|
})
|
||||||
.Configure(app => {
|
.Configure(app => {
|
||||||
@ -714,17 +699,7 @@ namespace Ocelot.IntegrationTests
|
|||||||
})
|
})
|
||||||
.ConfigureServices(x =>
|
.ConfigureServices(x =>
|
||||||
{
|
{
|
||||||
Action<ConfigurationBuilderCachePart> settings = (s) =>
|
|
||||||
{
|
|
||||||
s.WithMicrosoftLogging(log =>
|
|
||||||
{
|
|
||||||
log.AddConsole(LogLevel.Debug);
|
|
||||||
})
|
|
||||||
.WithDictionaryHandle();
|
|
||||||
};
|
|
||||||
|
|
||||||
x.AddOcelot()
|
x.AddOcelot()
|
||||||
.AddCacheManager(settings)
|
|
||||||
.AddAdministration("/administration", "secret");
|
.AddAdministration("/administration", "secret");
|
||||||
})
|
})
|
||||||
.Configure(app =>
|
.Configure(app =>
|
||||||
@ -755,10 +730,6 @@ namespace Ocelot.IntegrationTests
|
|||||||
.ConfigureServices(x => {
|
.ConfigureServices(x => {
|
||||||
x.AddSingleton(_webHostBuilder);
|
x.AddSingleton(_webHostBuilder);
|
||||||
x.AddOcelot()
|
x.AddOcelot()
|
||||||
.AddCacheManager(c =>
|
|
||||||
{
|
|
||||||
c.WithDictionaryHandle();
|
|
||||||
})
|
|
||||||
.AddAdministration("/administration", "secret");
|
.AddAdministration("/administration", "secret");
|
||||||
})
|
})
|
||||||
.Configure(app => {
|
.Configure(app => {
|
||||||
|
@ -4,7 +4,6 @@ using System.IO;
|
|||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using Shouldly;
|
using Shouldly;
|
||||||
@ -13,7 +12,6 @@ using Xunit;
|
|||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using CacheManager.Core;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Ocelot.DependencyInjection;
|
using Ocelot.DependencyInjection;
|
||||||
@ -113,17 +111,7 @@ namespace Ocelot.IntegrationTests
|
|||||||
})
|
})
|
||||||
.ConfigureServices(x =>
|
.ConfigureServices(x =>
|
||||||
{
|
{
|
||||||
Action<ConfigurationBuilderCachePart> settings = (s) =>
|
|
||||||
{
|
|
||||||
s.WithMicrosoftLogging(log =>
|
|
||||||
{
|
|
||||||
log.AddConsole(LogLevel.Debug);
|
|
||||||
})
|
|
||||||
.WithDictionaryHandle();
|
|
||||||
};
|
|
||||||
|
|
||||||
x.AddOcelot()
|
x.AddOcelot()
|
||||||
.AddCacheManager(settings)
|
|
||||||
.AddAdministration("/administration", "secret");
|
.AddAdministration("/administration", "secret");
|
||||||
})
|
})
|
||||||
.Configure(app =>
|
.Configure(app =>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using Ocelot.Configuration;
|
using Xunit;
|
||||||
using Ocelot.Middleware;
|
|
||||||
|
[assembly: CollectionBehavior(DisableTestParallelization = true)]
|
||||||
|
|
||||||
namespace Ocelot.UnitTests.Authentication
|
namespace Ocelot.UnitTests.Authentication
|
||||||
{
|
{
|
||||||
@ -15,14 +16,16 @@ namespace Ocelot.UnitTests.Authentication
|
|||||||
using Shouldly;
|
using Shouldly;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
using Ocelot.Configuration;
|
||||||
|
using Ocelot.Middleware;
|
||||||
|
|
||||||
public class AuthenticationMiddlewareTests
|
public class AuthenticationMiddlewareTests
|
||||||
{
|
{
|
||||||
private AuthenticationMiddleware _middleware;
|
private AuthenticationMiddleware _middleware;
|
||||||
private Mock<IOcelotLoggerFactory> _factory;
|
private readonly Mock<IOcelotLoggerFactory> _factory;
|
||||||
private Mock<IOcelotLogger> _logger;
|
private Mock<IOcelotLogger> _logger;
|
||||||
private OcelotRequestDelegate _next;
|
private OcelotRequestDelegate _next;
|
||||||
private DownstreamContext _downstreamContext;
|
private readonly DownstreamContext _downstreamContext;
|
||||||
|
|
||||||
public AuthenticationMiddlewareTests()
|
public AuthenticationMiddlewareTests()
|
||||||
{
|
{
|
||||||
|
@ -1,103 +0,0 @@
|
|||||||
using System;
|
|
||||||
using CacheManager.Core;
|
|
||||||
using Moq;
|
|
||||||
using Ocelot.Cache;
|
|
||||||
using Shouldly;
|
|
||||||
using TestStack.BDDfy;
|
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
namespace Ocelot.UnitTests.Cache
|
|
||||||
{
|
|
||||||
public class CacheManagerCacheTests
|
|
||||||
{
|
|
||||||
private OcelotCacheManagerCache<string> _ocelotOcelotCacheManager;
|
|
||||||
private Mock<ICacheManager<string>> _mockCacheManager;
|
|
||||||
private string _key;
|
|
||||||
private string _value;
|
|
||||||
private string _resultGet;
|
|
||||||
private TimeSpan _ttlSeconds;
|
|
||||||
private string _region;
|
|
||||||
|
|
||||||
public CacheManagerCacheTests()
|
|
||||||
{
|
|
||||||
_mockCacheManager = new Mock<ICacheManager<string>>();
|
|
||||||
_ocelotOcelotCacheManager = new OcelotCacheManagerCache<string>(_mockCacheManager.Object);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void should_get_from_cache()
|
|
||||||
{
|
|
||||||
this.Given(x => x.GivenTheFollowingIsCached("someKey", "someRegion", "someValue"))
|
|
||||||
.When(x => x.WhenIGetFromTheCache())
|
|
||||||
.Then(x => x.ThenTheResultIs("someValue"))
|
|
||||||
.BDDfy();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void should_add_to_cache()
|
|
||||||
{
|
|
||||||
this.When(x => x.WhenIAddToTheCache("someKey", "someValue", TimeSpan.FromSeconds(1)))
|
|
||||||
.Then(x => x.ThenTheCacheIsCalledCorrectly())
|
|
||||||
.BDDfy();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void should_delete_key_from_cache()
|
|
||||||
{
|
|
||||||
this.Given(_ => GivenTheFollowingRegion("fookey"))
|
|
||||||
.When(_ => WhenIDeleteTheRegion("fookey"))
|
|
||||||
.Then(_ => ThenTheRegionIsDeleted("fookey"))
|
|
||||||
.BDDfy();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WhenIDeleteTheRegion(string region)
|
|
||||||
{
|
|
||||||
_ocelotOcelotCacheManager.ClearRegion(region);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ThenTheRegionIsDeleted(string region)
|
|
||||||
{
|
|
||||||
_mockCacheManager
|
|
||||||
.Verify(x => x.ClearRegion(region), Times.Once);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GivenTheFollowingRegion(string key)
|
|
||||||
{
|
|
||||||
_ocelotOcelotCacheManager.Add(key, "doesnt matter", TimeSpan.FromSeconds(10), "region");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WhenIAddToTheCache(string key, string value, TimeSpan ttlSeconds)
|
|
||||||
{
|
|
||||||
_key = key;
|
|
||||||
_value = value;
|
|
||||||
_ttlSeconds = ttlSeconds;
|
|
||||||
_ocelotOcelotCacheManager.Add(_key, _value, _ttlSeconds, "region");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ThenTheCacheIsCalledCorrectly()
|
|
||||||
{
|
|
||||||
_mockCacheManager
|
|
||||||
.Verify(x => x.Add(It.IsAny<CacheItem<string>>()), Times.Once);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ThenTheResultIs(string expected)
|
|
||||||
{
|
|
||||||
_resultGet.ShouldBe(expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WhenIGetFromTheCache()
|
|
||||||
{
|
|
||||||
_resultGet = _ocelotOcelotCacheManager.Get(_key, _region);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GivenTheFollowingIsCached(string key, string region, string value)
|
|
||||||
{
|
|
||||||
_key = key;
|
|
||||||
_value = value;
|
|
||||||
_region = region;
|
|
||||||
_mockCacheManager
|
|
||||||
.Setup(x => x.Get<string>(It.IsAny<string>(), It.IsAny<string>()))
|
|
||||||
.Returns(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,95 +0,0 @@
|
|||||||
namespace Ocelot.UnitTests.Cache
|
|
||||||
{
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net;
|
|
||||||
using System.Net.Http.Headers;
|
|
||||||
using CacheManager.Core;
|
|
||||||
using Shouldly;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Moq;
|
|
||||||
using Ocelot.Cache;
|
|
||||||
using Ocelot.Cache.Middleware;
|
|
||||||
using Ocelot.Configuration;
|
|
||||||
using Ocelot.Configuration.Builder;
|
|
||||||
using Ocelot.Logging;
|
|
||||||
using Ocelot.Middleware;
|
|
||||||
using TestStack.BDDfy;
|
|
||||||
using Xunit;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Ocelot.Middleware.Multiplexer;
|
|
||||||
|
|
||||||
public class OutputCacheMiddlewareRealCacheTests
|
|
||||||
{
|
|
||||||
private readonly IOcelotCache<CachedResponse> _cacheManager;
|
|
||||||
private readonly OutputCacheMiddleware _middleware;
|
|
||||||
private readonly DownstreamContext _downstreamContext;
|
|
||||||
private OcelotRequestDelegate _next;
|
|
||||||
private Mock<IOcelotLoggerFactory> _loggerFactory;
|
|
||||||
private IRegionCreator _regionCreator;
|
|
||||||
private Mock<IOcelotLogger> _logger;
|
|
||||||
|
|
||||||
public OutputCacheMiddlewareRealCacheTests()
|
|
||||||
{
|
|
||||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
|
||||||
_logger = new Mock<IOcelotLogger>();
|
|
||||||
_loggerFactory.Setup(x => x.CreateLogger<OutputCacheMiddleware>()).Returns(_logger.Object);
|
|
||||||
_regionCreator = new RegionCreator();
|
|
||||||
var cacheManagerOutputCache = CacheFactory.Build<CachedResponse>("OcelotOutputCache", x =>
|
|
||||||
{
|
|
||||||
x.WithDictionaryHandle();
|
|
||||||
});
|
|
||||||
_cacheManager = new OcelotCacheManagerCache<CachedResponse>(cacheManagerOutputCache);
|
|
||||||
_downstreamContext = new DownstreamContext(new DefaultHttpContext());
|
|
||||||
_downstreamContext.DownstreamRequest = new Ocelot.Request.Middleware.DownstreamRequest(new HttpRequestMessage(HttpMethod.Get, "https://some.url/blah?abcd=123"));
|
|
||||||
_next = context => Task.CompletedTask;
|
|
||||||
_middleware = new OutputCacheMiddleware(_next, _loggerFactory.Object, _cacheManager, _regionCreator);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void should_cache_content_headers()
|
|
||||||
{
|
|
||||||
var content = new StringContent("{\"Test\": 1}")
|
|
||||||
{
|
|
||||||
Headers = { ContentType = new MediaTypeHeaderValue("application/json")}
|
|
||||||
};
|
|
||||||
|
|
||||||
var response = new DownstreamResponse(content, HttpStatusCode.OK, new List<KeyValuePair<string, IEnumerable<string>>>());
|
|
||||||
|
|
||||||
this.Given(x => x.GivenResponseIsNotCached(response))
|
|
||||||
.And(x => x.GivenTheDownstreamRouteIs())
|
|
||||||
.When(x => x.WhenICallTheMiddleware())
|
|
||||||
.Then(x => x.ThenTheContentTypeHeaderIsCached())
|
|
||||||
.BDDfy();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WhenICallTheMiddleware()
|
|
||||||
{
|
|
||||||
_middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ThenTheContentTypeHeaderIsCached()
|
|
||||||
{
|
|
||||||
var result = _cacheManager.Get("GET-https://some.url/blah?abcd=123", "kanken");
|
|
||||||
var header = result.ContentHeaders["Content-Type"];
|
|
||||||
header.First().ShouldBe("application/json");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GivenResponseIsNotCached(DownstreamResponse response)
|
|
||||||
{
|
|
||||||
_downstreamContext.DownstreamResponse = response;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GivenTheDownstreamRouteIs()
|
|
||||||
{
|
|
||||||
var reRoute = new DownstreamReRouteBuilder()
|
|
||||||
.WithIsCached(true)
|
|
||||||
.WithCacheOptions(new CacheOptions(100, "kanken"))
|
|
||||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_downstreamContext.DownstreamReRoute = reRoute;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -16,24 +16,22 @@
|
|||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Ocelot.Middleware;
|
using Ocelot.Middleware;
|
||||||
using Ocelot.Middleware.Multiplexer;
|
|
||||||
|
|
||||||
public class OutputCacheMiddlewareTests
|
public class OutputCacheMiddlewareTests
|
||||||
{
|
{
|
||||||
private readonly Mock<IOcelotCache<CachedResponse>> _cacheManager;
|
private readonly Mock<IOcelotCache<CachedResponse>> _cache;
|
||||||
private readonly Mock<IOcelotLoggerFactory> _loggerFactory;
|
private readonly Mock<IOcelotLoggerFactory> _loggerFactory;
|
||||||
private Mock<IOcelotLogger> _logger;
|
private Mock<IOcelotLogger> _logger;
|
||||||
private OutputCacheMiddleware _middleware;
|
private OutputCacheMiddleware _middleware;
|
||||||
private readonly DownstreamContext _downstreamContext;
|
private readonly DownstreamContext _downstreamContext;
|
||||||
private readonly OcelotRequestDelegate _next;
|
private readonly OcelotRequestDelegate _next;
|
||||||
private CachedResponse _response;
|
private CachedResponse _response;
|
||||||
private readonly IRegionCreator _regionCreator;
|
|
||||||
|
|
||||||
public OutputCacheMiddlewareTests()
|
public OutputCacheMiddlewareTests()
|
||||||
{
|
{
|
||||||
_cacheManager = new Mock<IOcelotCache<CachedResponse>>();
|
_cache = new Mock<IOcelotCache<CachedResponse>>();
|
||||||
_regionCreator = new RegionCreator();
|
|
||||||
_downstreamContext = new DownstreamContext(new DefaultHttpContext());
|
_downstreamContext = new DownstreamContext(new DefaultHttpContext());
|
||||||
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
_loggerFactory = new Mock<IOcelotLoggerFactory>();
|
||||||
_logger = new Mock<IOcelotLogger>();
|
_logger = new Mock<IOcelotLogger>();
|
||||||
@ -91,14 +89,14 @@
|
|||||||
|
|
||||||
private void WhenICallTheMiddleware()
|
private void WhenICallTheMiddleware()
|
||||||
{
|
{
|
||||||
_middleware = new OutputCacheMiddleware(_next, _loggerFactory.Object, _cacheManager.Object, _regionCreator);
|
_middleware = new OutputCacheMiddleware(_next, _loggerFactory.Object, _cache.Object);
|
||||||
_middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
|
_middleware.Invoke(_downstreamContext).GetAwaiter().GetResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenThereIsACachedResponse(CachedResponse response)
|
private void GivenThereIsACachedResponse(CachedResponse response)
|
||||||
{
|
{
|
||||||
_response = response;
|
_response = response;
|
||||||
_cacheManager
|
_cache
|
||||||
.Setup(x => x.Get(It.IsAny<string>(), It.IsAny<string>()))
|
.Setup(x => x.Get(It.IsAny<string>(), It.IsAny<string>()))
|
||||||
.Returns(_response);
|
.Returns(_response);
|
||||||
}
|
}
|
||||||
@ -127,13 +125,13 @@
|
|||||||
|
|
||||||
private void ThenTheCacheGetIsCalledCorrectly()
|
private void ThenTheCacheGetIsCalledCorrectly()
|
||||||
{
|
{
|
||||||
_cacheManager
|
_cache
|
||||||
.Verify(x => x.Get(It.IsAny<string>(), It.IsAny<string>()), Times.Once);
|
.Verify(x => x.Get(It.IsAny<string>(), It.IsAny<string>()), Times.Once);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ThenTheCacheAddIsCalledCorrectly()
|
private void ThenTheCacheAddIsCalledCorrectly()
|
||||||
{
|
{
|
||||||
_cacheManager
|
_cache
|
||||||
.Verify(x => x.Add(It.IsAny<string>(), It.IsAny<CachedResponse>(), It.IsAny<TimeSpan>(), It.IsAny<string>()), Times.Once);
|
.Verify(x => x.Add(It.IsAny<string>(), It.IsAny<CachedResponse>(), It.IsAny<TimeSpan>(), It.IsAny<string>()), Times.Once);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using CacheManager.Core;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Hosting.Internal;
|
using Microsoft.AspNetCore.Hosting.Internal;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
@ -81,16 +80,6 @@ namespace Ocelot.UnitTests.DependencyInjection
|
|||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void should_set_up_cache_manager()
|
|
||||||
{
|
|
||||||
this.Given(x => WhenISetUpOcelotServices())
|
|
||||||
.When(x => WhenISetUpCacheManager())
|
|
||||||
.Then(x => ThenAnExceptionIsntThrown())
|
|
||||||
.And(x => OnlyOneVersionOfEachCacheIsRegistered())
|
|
||||||
.BDDfy();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_set_up_consul()
|
public void should_set_up_consul()
|
||||||
{
|
{
|
||||||
@ -282,24 +271,6 @@ namespace Ocelot.UnitTests.DependencyInjection
|
|||||||
first.ShouldBe(second);
|
first.ShouldBe(second);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnlyOneVersionOfEachCacheIsRegistered()
|
|
||||||
{
|
|
||||||
var outputCache = _services.Single(x => x.ServiceType == typeof(IOcelotCache<CachedResponse>));
|
|
||||||
var outputCacheManager = _services.Single(x => x.ServiceType == typeof(ICacheManager<CachedResponse>));
|
|
||||||
var instance = (ICacheManager<CachedResponse>)outputCacheManager.ImplementationInstance;
|
|
||||||
var ocelotConfigCache = _services.Single(x => x.ServiceType == typeof(IOcelotCache<IInternalConfiguration>));
|
|
||||||
var ocelotConfigCacheManager = _services.Single(x => x.ServiceType == typeof(ICacheManager<IInternalConfiguration>));
|
|
||||||
var fileConfigCache = _services.Single(x => x.ServiceType == typeof(IOcelotCache<FileConfiguration>));
|
|
||||||
var fileConfigCacheManager = _services.Single(x => x.ServiceType == typeof(ICacheManager<FileConfiguration>));
|
|
||||||
|
|
||||||
instance.Configuration.MaxRetries.ShouldBe(_maxRetries);
|
|
||||||
outputCache.ShouldNotBeNull();
|
|
||||||
ocelotConfigCache.ShouldNotBeNull();
|
|
||||||
ocelotConfigCacheManager.ShouldNotBeNull();
|
|
||||||
fileConfigCache.ShouldNotBeNull();
|
|
||||||
fileConfigCacheManager.ShouldNotBeNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WhenISetUpConsul()
|
private void WhenISetUpConsul()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -365,21 +336,6 @@ namespace Ocelot.UnitTests.DependencyInjection
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WhenISetUpCacheManager()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_ocelotBuilder.AddCacheManager(x => {
|
|
||||||
x.WithMaxRetries(_maxRetries);
|
|
||||||
x.WithDictionaryHandle();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
_ex = e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WhenIAccessLoggerFactory()
|
private void WhenIAccessLoggerFactory()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
namespace Ocelot.UnitTests.Middleware
|
namespace Ocelot.UnitTests.Middleware
|
||||||
{
|
{
|
||||||
|
using System;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Ocelot.Cache;
|
||||||
using Ocelot.DependencyInjection;
|
using Ocelot.DependencyInjection;
|
||||||
using Ocelot.DownstreamRouteFinder.Middleware;
|
using Ocelot.DownstreamRouteFinder.Middleware;
|
||||||
using Ocelot.DownstreamUrlCreator.Middleware;
|
using Ocelot.DownstreamUrlCreator.Middleware;
|
||||||
@ -40,7 +42,6 @@ namespace Ocelot.UnitTests.Middleware
|
|||||||
.BDDfy();
|
.BDDfy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void ThenThePipelineIsBuilt()
|
private void ThenThePipelineIsBuilt()
|
||||||
{
|
{
|
||||||
_handlers.ShouldNotBeNull();
|
_handlers.ShouldNotBeNull();
|
||||||
@ -67,7 +68,6 @@ namespace Ocelot.UnitTests.Middleware
|
|||||||
_handlers = _builder.BuildOcelotPipeline(new OcelotPipelineConfiguration());
|
_handlers = _builder.BuildOcelotPipeline(new OcelotPipelineConfiguration());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void GivenTheDepedenciesAreSetUp()
|
private void GivenTheDepedenciesAreSetUp()
|
||||||
{
|
{
|
||||||
IConfigurationBuilder test = new ConfigurationBuilder();
|
IConfigurationBuilder test = new ConfigurationBuilder();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user