Skip to content

Commit

Permalink
Merge pull request #109 from TomPallister/feature/clear-cache
Browse files Browse the repository at this point in the history
Feature/clear cache
  • Loading branch information
TomPallister authored Jun 29, 2017
2 parents 26e7621 + 9a4a670 commit 0139452
Show file tree
Hide file tree
Showing 22 changed files with 397 additions and 34 deletions.
8 changes: 5 additions & 3 deletions src/Ocelot/Cache/IOcelotCache.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using System;
using System.Collections.Generic;

namespace Ocelot.Cache
{
public interface IOcelotCache<T>
{
void Add(string key, T value, TimeSpan ttl);
void AddAndDelete(string key, T value, TimeSpan ttl);
T Get(string key);
void Add(string key, T value, TimeSpan ttl, string region);
void AddAndDelete(string key, T value, TimeSpan ttl, string region);
T Get(string key, string region);
void ClearRegion(string region);
}
}
9 changes: 9 additions & 0 deletions src/Ocelot/Cache/IRegionCreator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using Ocelot.Configuration.File;

namespace Ocelot.Cache
{
public interface IRegionCreator
{
string Create(FileReRoute reRoute);
}
}
12 changes: 8 additions & 4 deletions src/Ocelot/Cache/Middleware/OutputCacheMiddleware.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
Expand All @@ -13,16 +14,19 @@ public class OutputCacheMiddleware : OcelotMiddleware
private readonly RequestDelegate _next;
private readonly IOcelotLogger _logger;
private readonly IOcelotCache<HttpResponseMessage> _outputCache;
private readonly IRegionCreator _regionCreator;

public OutputCacheMiddleware(RequestDelegate next,
IOcelotLoggerFactory loggerFactory,
IRequestScopedDataRepository scopedDataRepository,
IOcelotCache<HttpResponseMessage> outputCache)
IOcelotCache<HttpResponseMessage> outputCache,
IRegionCreator regionCreator)
:base(scopedDataRepository)
{
_next = next;
_outputCache = outputCache;
_logger = loggerFactory.CreateLogger<OutputCacheMiddleware>();
_regionCreator = regionCreator;
}

public async Task Invoke(HttpContext context)
Expand All @@ -33,11 +37,11 @@ public async Task Invoke(HttpContext context)
return;
}

var downstreamUrlKey = DownstreamRequest.RequestUri.OriginalString;
var downstreamUrlKey = $"{DownstreamRequest.Method.Method}-{DownstreamRequest.RequestUri.OriginalString}";

_logger.LogDebug("started checking cache for {downstreamUrlKey}", downstreamUrlKey);

var cached = _outputCache.Get(downstreamUrlKey);
var cached = _outputCache.Get(downstreamUrlKey, DownstreamRoute.ReRoute.CacheOptions.Region);

if (cached != null)
{
Expand All @@ -63,7 +67,7 @@ public async Task Invoke(HttpContext context)

var response = HttpResponseMessage;

_outputCache.Add(downstreamUrlKey, response, TimeSpan.FromSeconds(DownstreamRoute.ReRoute.FileCacheOptions.TtlSeconds));
_outputCache.Add(downstreamUrlKey, response, TimeSpan.FromSeconds(DownstreamRoute.ReRoute.CacheOptions.TtlSeconds), DownstreamRoute.ReRoute.CacheOptions.Region);

_logger.LogDebug("finished response added to cache for {downstreamUrlKey}", downstreamUrlKey);
}
Expand Down
19 changes: 13 additions & 6 deletions src/Ocelot/Cache/OcelotCacheManagerCache.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using CacheManager.Core;

namespace Ocelot.Cache
Expand All @@ -12,12 +14,12 @@ public OcelotCacheManagerCache(ICacheManager<T> cacheManager)
_cacheManager = cacheManager;
}

public void Add(string key, T value, TimeSpan ttl)
public void Add(string key, T value, TimeSpan ttl, string region)
{
_cacheManager.Add(new CacheItem<T>(key, value, ExpirationMode.Absolute, ttl));
_cacheManager.Add(new CacheItem<T>(key, region, value, ExpirationMode.Absolute, ttl));
}

public void AddAndDelete(string key, T value, TimeSpan ttl)
public void AddAndDelete(string key, T value, TimeSpan ttl, string region)
{
var exists = _cacheManager.Get(key);

Expand All @@ -26,12 +28,17 @@ public void AddAndDelete(string key, T value, TimeSpan ttl)
_cacheManager.Remove(key);
}

_cacheManager.Add(new CacheItem<T>(key, value, ExpirationMode.Absolute, ttl));
Add(key, value, ttl, region);
}

public T Get(string key)
public T Get(string key, string region)
{
return _cacheManager.Get<T>(key);
return _cacheManager.Get<T>(key, region);
}

public void ClearRegion(string region)
{
_cacheManager.ClearRegion(region);
}
}
}
24 changes: 24 additions & 0 deletions src/Ocelot/Cache/RegionCreator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System.Linq;
using Ocelot.Configuration;
using Ocelot.Configuration.File;

namespace Ocelot.Cache
{

public class RegionCreator : IRegionCreator
{
public string Create(FileReRoute reRoute)
{
if(!string.IsNullOrEmpty(reRoute?.FileCacheOptions?.Region))
{
return reRoute?.FileCacheOptions?.Region;
}

var methods = string.Join("", reRoute.UpstreamHttpMethod.Select(m => m));

var region = $"{methods}{reRoute.UpstreamPathTemplate.Replace("/", "")}";

return region;
}
}
}
13 changes: 13 additions & 0 deletions src/Ocelot/Cache/Regions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System.Collections.Generic;

namespace Ocelot.Cache
{
public class Regions
{
public Regions(List<string> value)
{
Value = value;
}
public List<string> Value {get;private set;}
}
}
4 changes: 3 additions & 1 deletion src/Ocelot/Configuration/CacheOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
{
public class CacheOptions
{
public CacheOptions(int ttlSeconds)
public CacheOptions(int ttlSeconds, string region)
{
TtlSeconds = ttlSeconds;
Region = region;
}

public int TtlSeconds { get; private set; }
public string Region {get;private set;}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Ocelot.Cache;
using Ocelot.Configuration.Builder;
using Ocelot.Configuration.File;
using Ocelot.Configuration.Parser;
Expand Down Expand Up @@ -36,6 +37,7 @@ public class FileOcelotConfigurationCreator : IOcelotConfigurationCreator
private IQoSOptionsCreator _qosOptionsCreator;
private IReRouteOptionsCreator _fileReRouteOptionsCreator;
private IRateLimitOptionsCreator _rateLimitOptionsCreator;
private IRegionCreator _regionCreator;

public FileOcelotConfigurationCreator(
IOptions<FileConfiguration> options,
Expand All @@ -52,9 +54,11 @@ public FileOcelotConfigurationCreator(
IServiceProviderConfigurationCreator serviceProviderConfigCreator,
IQoSOptionsCreator qosOptionsCreator,
IReRouteOptionsCreator fileReRouteOptionsCreator,
IRateLimitOptionsCreator rateLimitOptionsCreator
IRateLimitOptionsCreator rateLimitOptionsCreator,
IRegionCreator regionCreator
)
{
_regionCreator = regionCreator;
_rateLimitOptionsCreator = rateLimitOptionsCreator;
_requestIdKeyCreator = requestIdKeyCreator;
_upstreamTemplatePatternCreator = upstreamTemplatePatternCreator;
Expand Down Expand Up @@ -137,6 +141,8 @@ private async Task<ReRoute> SetUpReRoute(FileReRoute fileReRoute, FileGlobalConf

var rateLimitOption = _rateLimitOptionsCreator.Create(fileReRoute, globalConfiguration, fileReRouteOptions.EnableRateLimiting);

var region = _regionCreator.Create(fileReRoute);

var reRoute = new ReRouteBuilder()
.WithDownstreamPathTemplate(fileReRoute.DownstreamPathTemplate)
.WithUpstreamPathTemplate(fileReRoute.UpstreamPathTemplate)
Expand All @@ -151,7 +157,7 @@ private async Task<ReRoute> SetUpReRoute(FileReRoute fileReRoute, FileGlobalConf
.WithClaimsToQueries(claimsToQueries)
.WithRequestIdKey(requestIdKey)
.WithIsCached(fileReRouteOptions.IsCached)
.WithCacheOptions(new CacheOptions(fileReRoute.FileCacheOptions.TtlSeconds))
.WithCacheOptions(new CacheOptions(fileReRoute.FileCacheOptions.TtlSeconds, region))
.WithDownstreamScheme(fileReRoute.DownstreamScheme)
.WithLoadBalancer(fileReRoute.LoadBalancer)
.WithDownstreamHost(fileReRoute.DownstreamHost)
Expand Down
1 change: 1 addition & 0 deletions src/Ocelot/Configuration/File/FileCacheOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
public class FileCacheOptions
{
public int TtlSeconds { get; set; }
public string Region {get; set;}
}
}
4 changes: 2 additions & 2 deletions src/Ocelot/Configuration/ReRoute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public ReRoute(PathTemplate downstreamPathTemplate,
IsAuthorised = isAuthorised;
RequestIdKey = requestIdKey;
IsCached = isCached;
FileCacheOptions = fileCacheOptions;
CacheOptions = fileCacheOptions;
ClaimsToQueries = claimsToQueries
?? new List<ClaimToThing>();
ClaimsToClaims = claimsToClaims
Expand Down Expand Up @@ -74,7 +74,7 @@ public ReRoute(PathTemplate downstreamPathTemplate,
public Dictionary<string, string> RouteClaimsRequirement { get; private set; }
public string RequestIdKey { get; private set; }
public bool IsCached { get; private set; }
public CacheOptions FileCacheOptions { get; private set; }
public CacheOptions CacheOptions { get; private set; }
public string DownstreamScheme {get;private set;}
public bool IsQos { get; private set; }
public QoSOptions QosOptionsOptions { get; private set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public ConsulOcelotConfigurationRepository(ConsulRegistryConfiguration consulReg

public async Task<Response<IOcelotConfiguration>> Get()
{
var config = _cache.Get(_ocelotConfiguration);
var config = _cache.Get(_ocelotConfiguration, _ocelotConfiguration);

if (config != null)
{
Expand Down Expand Up @@ -68,7 +68,7 @@ public async Task<Response> AddOrReplace(IOcelotConfiguration ocelotConfiguratio

if (result.Response)
{
_cache.AddAndDelete(_ocelotConfiguration, ocelotConfiguration, TimeSpan.FromSeconds(3));
_cache.AddAndDelete(_ocelotConfiguration, ocelotConfiguration, TimeSpan.FromSeconds(3), _ocelotConfiguration);

return new OkResponse();
}
Expand Down
29 changes: 29 additions & 0 deletions src/Ocelot/Controllers/OutputCacheController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Ocelot.Cache;
using Ocelot.Configuration.Provider;

namespace Ocelot.Controllers
{
[Authorize]
[Route("outputcache")]
public class OutputCacheController : Controller
{
private IOcelotCache<HttpResponseMessage> _cache;

public OutputCacheController(IOcelotCache<HttpResponseMessage> cache)
{
_cache = cache;
}

[HttpDelete]
[Route("{region}")]
public IActionResult Delete(string region)
{
_cache.ClearRegion(region);
return new NoContentResult();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ public static IServiceCollection AddOcelot(this IServiceCollection services, ICo
.AddJsonFormatters();

services.AddLogging();
services.TryAddSingleton<IRegionCreator, RegionCreator>();
services.TryAddSingleton<IFileConfigurationRepository, FileConfigurationRepository>();
services.TryAddSingleton<IFileConfigurationSetter, FileConfigurationSetter>();
services.TryAddSingleton<IFileConfigurationProvider, FileConfigurationProvider>();
Expand Down
1 change: 1 addition & 0 deletions test/Ocelot.AcceptanceTests/Ocelot.AcceptanceTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.MiddlewareAnalysis" Version="1.1.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0-preview-20170106-08" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.0-beta2-build1317" />
<PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="1.1.1" />
Expand Down
Loading

0 comments on commit 0139452

Please sign in to comment.