mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-04-22 06:42:50 +08:00
removed old memory cache and added a few tests for new asp memory cache
This commit is contained in:
parent
b4c29fc727
commit
8b098d2336
@ -1,11 +1,9 @@
|
|||||||
using System;
|
namespace Ocelot.Cache
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
using Microsoft.Extensions.Caching.Distributed;
|
|
||||||
using Microsoft.Extensions.Caching.Memory;
|
|
||||||
|
|
||||||
namespace Ocelot.Cache
|
|
||||||
{
|
{
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
|
|
||||||
public class AspMemoryCache<T> : IOcelotCache<T>
|
public class AspMemoryCache<T> : IOcelotCache<T>
|
||||||
{
|
{
|
||||||
private readonly IMemoryCache _memoryCache;
|
private readonly IMemoryCache _memoryCache;
|
||||||
@ -20,7 +18,9 @@ namespace Ocelot.Cache
|
|||||||
public void Add(string key, T value, TimeSpan ttl, string region)
|
public void Add(string key, T value, TimeSpan ttl, string region)
|
||||||
{
|
{
|
||||||
if (ttl.TotalMilliseconds <= 0)
|
if (ttl.TotalMilliseconds <= 0)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_memoryCache.Set(key, value, ttl);
|
_memoryCache.Set(key, value, ttl);
|
||||||
|
|
||||||
@ -29,9 +29,12 @@ namespace Ocelot.Cache
|
|||||||
|
|
||||||
public T Get(string key, string region)
|
public T Get(string key, string region)
|
||||||
{
|
{
|
||||||
_memoryCache.TryGetValue<T>(key, out T value);
|
if (_memoryCache.TryGetValue(key, out T value))
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
return value;
|
return default(T);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClearRegion(string region)
|
public void ClearRegion(string region)
|
||||||
@ -48,8 +51,10 @@ namespace Ocelot.Cache
|
|||||||
|
|
||||||
public void AddAndDelete(string key, T value, TimeSpan ttl, string region)
|
public void AddAndDelete(string key, T value, TimeSpan ttl, string region)
|
||||||
{
|
{
|
||||||
if (_memoryCache.TryGetValue(key, out object oldValue))
|
if (_memoryCache.TryGetValue(key, out T oldValue))
|
||||||
|
{
|
||||||
_memoryCache.Remove(key);
|
_memoryCache.Remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
Add(key, value, ttl, region);
|
Add(key, value, ttl, region);
|
||||||
}
|
}
|
||||||
|
@ -1,81 +0,0 @@
|
|||||||
namespace Ocelot.Cache
|
|
||||||
{
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
public class InMemoryCache<T> : IOcelotCache<T>
|
|
||||||
{
|
|
||||||
private readonly Dictionary<string, CacheObject<T>> _cache;
|
|
||||||
private readonly Dictionary<string, List<string>> _regions;
|
|
||||||
|
|
||||||
public InMemoryCache()
|
|
||||||
{
|
|
||||||
_cache = new Dictionary<string, CacheObject<T>>();
|
|
||||||
_regions = new Dictionary<string, List<string>>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Add(string key, T value, TimeSpan ttl, string region)
|
|
||||||
{
|
|
||||||
if (ttl.TotalMilliseconds <= 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var expires = DateTime.UtcNow.Add(ttl);
|
|
||||||
|
|
||||||
_cache.Add(key, new CacheObject<T>(value, expires));
|
|
||||||
|
|
||||||
if (_regions.ContainsKey(region))
|
|
||||||
{
|
|
||||||
var current = _regions[region];
|
|
||||||
if (!current.Contains(key))
|
|
||||||
{
|
|
||||||
current.Add(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_regions.Add(region, new List<string> { key });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddAndDelete(string key, T value, TimeSpan ttl, string region)
|
|
||||||
{
|
|
||||||
if (_cache.ContainsKey(key))
|
|
||||||
{
|
|
||||||
_cache.Remove(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
Add(key, value, ttl, region);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ClearRegion(string region)
|
|
||||||
{
|
|
||||||
if (_regions.ContainsKey(region))
|
|
||||||
{
|
|
||||||
var keys = _regions[region];
|
|
||||||
foreach (var key in keys)
|
|
||||||
{
|
|
||||||
_cache.Remove(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public T Get(string key, string region)
|
|
||||||
{
|
|
||||||
if (_cache.ContainsKey(key))
|
|
||||||
{
|
|
||||||
var cached = _cache[key];
|
|
||||||
|
|
||||||
if (cached.Expires > DateTime.UtcNow)
|
|
||||||
{
|
|
||||||
return cached.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
_cache.Remove(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
return default(T);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -77,20 +77,6 @@
|
|||||||
context.DownstreamResponse = response;
|
context.DownstreamResponse = response;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GenerateRequestCacheKey(DownstreamContext context)
|
|
||||||
{
|
|
||||||
string hashedContent = null;
|
|
||||||
StringBuilder downStreamUrlKeyBuilder = new StringBuilder($"{context.DownstreamRequest.Method}-{context.DownstreamRequest.OriginalString}");
|
|
||||||
if (context.DownstreamRequest.Content != null)
|
|
||||||
{
|
|
||||||
string requestContentString = Task.Run(async () => await context.DownstreamRequest.Content?.ReadAsStringAsync()).Result;
|
|
||||||
downStreamUrlKeyBuilder.Append(requestContentString);
|
|
||||||
}
|
|
||||||
|
|
||||||
hashedContent = MD5Helper.GenerateMd5(downStreamUrlKeyBuilder.ToString());
|
|
||||||
return hashedContent;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal DownstreamResponse CreateHttpResponseMessage(CachedResponse cached)
|
internal DownstreamResponse CreateHttpResponseMessage(CachedResponse cached)
|
||||||
{
|
{
|
||||||
if (cached == null)
|
if (cached == null)
|
||||||
|
@ -1,7 +1,3 @@
|
|||||||
using Ocelot.ServiceDiscovery.Providers;
|
|
||||||
|
|
||||||
using Ocelot.Configuration.ChangeTracking;
|
|
||||||
|
|
||||||
namespace Ocelot.DependencyInjection
|
namespace Ocelot.DependencyInjection
|
||||||
{
|
{
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
@ -13,6 +9,8 @@ namespace Ocelot.DependencyInjection
|
|||||||
using Ocelot.Cache;
|
using Ocelot.Cache;
|
||||||
using Ocelot.Claims;
|
using Ocelot.Claims;
|
||||||
using Ocelot.Configuration;
|
using Ocelot.Configuration;
|
||||||
|
using Ocelot.ServiceDiscovery.Providers;
|
||||||
|
using Ocelot.Configuration.ChangeTracking;
|
||||||
using Ocelot.Configuration.Creator;
|
using Ocelot.Configuration.Creator;
|
||||||
using Ocelot.Configuration.File;
|
using Ocelot.Configuration.File;
|
||||||
using Ocelot.Configuration.Parser;
|
using Ocelot.Configuration.Parser;
|
||||||
@ -58,12 +56,8 @@ namespace Ocelot.DependencyInjection
|
|||||||
Services = services;
|
Services = services;
|
||||||
Services.Configure<FileConfiguration>(configurationRoot);
|
Services.Configure<FileConfiguration>(configurationRoot);
|
||||||
|
|
||||||
//Services.TryAddSingleton<IOcelotCache<FileConfiguration>, InMemoryCache<FileConfiguration>>();
|
|
||||||
//Services.TryAddSingleton<IOcelotCache<CachedResponse>, InMemoryCache<CachedResponse>>();
|
|
||||||
Services.TryAddSingleton<IOcelotCache<FileConfiguration>, AspMemoryCache<FileConfiguration>>();
|
Services.TryAddSingleton<IOcelotCache<FileConfiguration>, AspMemoryCache<FileConfiguration>>();
|
||||||
Services.TryAddSingleton<IOcelotCache<CachedResponse>, AspMemoryCache<CachedResponse>>();
|
Services.TryAddSingleton<IOcelotCache<CachedResponse>, AspMemoryCache<CachedResponse>>();
|
||||||
|
|
||||||
|
|
||||||
Services.TryAddSingleton<IHttpResponseHeaderReplacer, HttpResponseHeaderReplacer>();
|
Services.TryAddSingleton<IHttpResponseHeaderReplacer, HttpResponseHeaderReplacer>();
|
||||||
Services.TryAddSingleton<IHttpContextRequestHeaderReplacer, HttpContextRequestHeaderReplacer>();
|
Services.TryAddSingleton<IHttpContextRequestHeaderReplacer, HttpContextRequestHeaderReplacer>();
|
||||||
Services.TryAddSingleton<IHeaderFindAndReplaceCreator, HeaderFindAndReplaceCreator>();
|
Services.TryAddSingleton<IHeaderFindAndReplaceCreator, HeaderFindAndReplaceCreator>();
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
using Microsoft.Extensions.Caching.Memory;
|
namespace Ocelot.UnitTests.Cache
|
||||||
|
|
||||||
namespace Ocelot.UnitTests.Cache
|
|
||||||
{
|
{
|
||||||
using Ocelot.Cache;
|
using Ocelot.Cache;
|
||||||
using Shouldly;
|
using Shouldly;
|
||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
|
|
||||||
public class AspMemoryCacheTests
|
public class AspMemoryCacheTests
|
||||||
{
|
{
|
||||||
@ -27,6 +26,13 @@ namespace Ocelot.UnitTests.Cache
|
|||||||
fake.Value.ShouldBe(1);
|
fake.Value.ShouldBe(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void doesnt_exist()
|
||||||
|
{
|
||||||
|
var result = _cache.Get("1", "region");
|
||||||
|
result.ShouldBeNull();
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void should_add_and_delete()
|
public void should_add_and_delete()
|
||||||
{
|
{
|
||||||
@ -42,11 +48,15 @@ namespace Ocelot.UnitTests.Cache
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void should_clear_region()
|
public void should_clear_region()
|
||||||
{
|
{
|
||||||
var fake = new Fake(1);
|
var fake1 = new Fake(1);
|
||||||
_cache.Add("1", fake, TimeSpan.FromSeconds(100), "region");
|
var fake2 = new Fake(2);
|
||||||
|
_cache.Add("1", fake1, TimeSpan.FromSeconds(100), "region");
|
||||||
|
_cache.Add("2", fake2, TimeSpan.FromSeconds(100), "region");
|
||||||
_cache.ClearRegion("region");
|
_cache.ClearRegion("region");
|
||||||
var result = _cache.Get("1", "region");
|
var result1 = _cache.Get("1", "region");
|
||||||
result.ShouldBeNull();
|
result1.ShouldBeNull();
|
||||||
|
var result2 = _cache.Get("2", "region");
|
||||||
|
result2.ShouldBeNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
@ -1,81 +0,0 @@
|
|||||||
namespace Ocelot.UnitTests.Cache
|
|
||||||
{
|
|
||||||
using Ocelot.Cache;
|
|
||||||
using Shouldly;
|
|
||||||
using System;
|
|
||||||
using System.Threading;
|
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
public class InMemoryCacheTests
|
|
||||||
{
|
|
||||||
private readonly InMemoryCache<Fake> _cache;
|
|
||||||
|
|
||||||
public InMemoryCacheTests()
|
|
||||||
{
|
|
||||||
_cache = new InMemoryCache<Fake>();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void should_cache()
|
|
||||||
{
|
|
||||||
var fake = new Fake(1);
|
|
||||||
_cache.Add("1", fake, TimeSpan.FromSeconds(100), "region");
|
|
||||||
var result = _cache.Get("1", "region");
|
|
||||||
result.ShouldBe(fake);
|
|
||||||
fake.Value.ShouldBe(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void should_add_and_delete()
|
|
||||||
{
|
|
||||||
var fake = new Fake(1);
|
|
||||||
_cache.Add("1", fake, TimeSpan.FromSeconds(100), "region");
|
|
||||||
var newFake = new Fake(1);
|
|
||||||
_cache.AddAndDelete("1", newFake, TimeSpan.FromSeconds(100), "region");
|
|
||||||
var result = _cache.Get("1", "region");
|
|
||||||
result.ShouldBe(newFake);
|
|
||||||
newFake.Value.ShouldBe(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void should_clear_region()
|
|
||||||
{
|
|
||||||
var fake = new Fake(1);
|
|
||||||
_cache.Add("1", fake, TimeSpan.FromSeconds(100), "region");
|
|
||||||
_cache.ClearRegion("region");
|
|
||||||
var result = _cache.Get("1", "region");
|
|
||||||
result.ShouldBeNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void should_clear_key_if_ttl_expired()
|
|
||||||
{
|
|
||||||
var fake = new Fake(1);
|
|
||||||
_cache.Add("1", fake, TimeSpan.FromMilliseconds(50), "region");
|
|
||||||
Thread.Sleep(200);
|
|
||||||
var result = _cache.Get("1", "region");
|
|
||||||
result.ShouldBeNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData(0)]
|
|
||||||
[InlineData(-1)]
|
|
||||||
public void should_not_add_to_cache_if_timespan_empty(int ttl)
|
|
||||||
{
|
|
||||||
var fake = new Fake(1);
|
|
||||||
_cache.Add("1", fake, TimeSpan.FromSeconds(ttl), "region");
|
|
||||||
var result = _cache.Get("1", "region");
|
|
||||||
result.ShouldBeNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
private class Fake
|
|
||||||
{
|
|
||||||
public Fake(int value)
|
|
||||||
{
|
|
||||||
Value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Value { get; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,8 +3,8 @@
|
|||||||
using global::CacheManager.Core;
|
using global::CacheManager.Core;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Ocelot.Cache.CacheManager;
|
using Ocelot.Cache.CacheManager;
|
||||||
using Shouldly;
|
|
||||||
using System;
|
using System;
|
||||||
|
using Shouldly;
|
||||||
using TestStack.BDDfy;
|
using TestStack.BDDfy;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user