-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Caching ClaimsPrincipal
during authentication and re-caching FileConfiguration
objects in Consul and Disk File configuration repos
#1249
base: develop
Are you sure you want to change the base?
Changes from all commits
4324e1e
b09bb55
efc955b
d0fca0f
a4e33f4
6504dcc
d052f47
ff3f5ab
36909d9
615a7c7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
using Microsoft.AspNetCore.Hosting; | ||
using Newtonsoft.Json; | ||
using Ocelot.Cache; | ||
using Ocelot.Configuration.ChangeTracking; | ||
using Ocelot.Configuration.File; | ||
using Ocelot.DependencyInjection; | ||
|
@@ -12,21 +13,31 @@ public class DiskFileConfigurationRepository : IFileConfigurationRepository | |
{ | ||
private readonly IWebHostEnvironment _hostingEnvironment; | ||
private readonly IOcelotConfigurationChangeTokenSource _changeTokenSource; | ||
private readonly IOcelotCache<FileConfiguration> _cache; | ||
|
||
private FileInfo _ocelotFile; | ||
private FileInfo _environmentFile; | ||
private readonly object _lock = new(); | ||
public const string CacheKey = nameof(DiskFileConfigurationRepository); | ||
|
||
public DiskFileConfigurationRepository(IWebHostEnvironment hostingEnvironment, IOcelotConfigurationChangeTokenSource changeTokenSource) | ||
public DiskFileConfigurationRepository(IWebHostEnvironment hostingEnvironment, | ||
IOcelotConfigurationChangeTokenSource changeTokenSource, | ||
IOcelotCache<FileConfiguration> cache) | ||
{ | ||
_hostingEnvironment = hostingEnvironment; | ||
_changeTokenSource = changeTokenSource; | ||
_cache = cache; | ||
Initialize(AppContext.BaseDirectory); | ||
} | ||
|
||
public DiskFileConfigurationRepository(IWebHostEnvironment hostingEnvironment, IOcelotConfigurationChangeTokenSource changeTokenSource, string folder) | ||
public DiskFileConfigurationRepository(IWebHostEnvironment hostingEnvironment, | ||
IOcelotConfigurationChangeTokenSource changeTokenSource, | ||
IOcelotCache<FileConfiguration> cache, | ||
string folder) | ||
{ | ||
_hostingEnvironment = hostingEnvironment; | ||
_changeTokenSource = changeTokenSource; | ||
_cache = cache; | ||
Initialize(folder); | ||
} | ||
|
||
|
@@ -42,22 +53,29 @@ private void Initialize(string folder) | |
|
||
public Task<Response<FileConfiguration>> Get() | ||
{ | ||
string jsonConfiguration; | ||
var configuration = _cache.Get(CacheKey, region: CacheKey); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Enforced use of the cache❗ |
||
if (configuration != null) | ||
{ | ||
return Task.FromResult<Response<FileConfiguration>>(new OkResponse<FileConfiguration>(configuration)); | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
string jsonConfiguration; | ||
lock (_lock) | ||
RaynaldM marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
jsonConfiguration = FileSys.ReadAllText(_environmentFile.FullName); | ||
} | ||
|
||
var fileConfiguration = JsonConvert.DeserializeObject<FileConfiguration>(jsonConfiguration); | ||
|
||
return Task.FromResult<Response<FileConfiguration>>(new OkResponse<FileConfiguration>(fileConfiguration)); | ||
} | ||
|
||
/// <summary>Default TTL in seconds for caching <see cref="FileConfiguration"/> in the <see cref="Set(FileConfiguration)"/> method.</summary> | ||
/// <value>An <see cref="int"/> value, 300 seconds (5 minutes) by default.</value> | ||
public static int CacheTtlSeconds { get; set; } = 300; | ||
|
||
public Task<Response> Set(FileConfiguration fileConfiguration) | ||
{ | ||
var jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration, Formatting.Indented); | ||
|
||
lock (_lock) | ||
{ | ||
if (_environmentFile.Exists) | ||
|
@@ -76,6 +94,7 @@ public Task<Response> Set(FileConfiguration fileConfiguration) | |
} | ||
|
||
_changeTokenSource.Activate(); | ||
_cache.AddAndDelete(CacheKey, fileConfiguration, TimeSpan.FromSeconds(CacheTtlSeconds), region: CacheKey); | ||
return Task.FromResult<Response>(new OkResponse()); | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,7 @@ | ||
using Microsoft.AspNetCore.Authentication; | ||
using Microsoft.AspNetCore.Http; | ||
using Microsoft.Extensions.Caching.Memory; | ||
using Ocelot.Authentication.Middleware; | ||
using Ocelot.Configuration; | ||
using Ocelot.Configuration.Builder; | ||
using Ocelot.Logging; | ||
|
@@ -49,7 +51,7 @@ public void MiddlewareName_Cstor_ReturnsTypeName() | |
isNextCalled = true; | ||
return Task.CompletedTask; | ||
}; | ||
_middleware = new AuthenticationMiddleware(_next, _factory.Object); | ||
_middleware = new AuthenticationMiddleware(_next, _factory.Object, new MemoryCache(new MemoryCacheOptions())); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Enforcing the use of |
||
var expected = _middleware.GetType().Name; | ||
|
||
// Act | ||
|
@@ -259,7 +261,7 @@ private async void WhenICallTheMiddleware() | |
_httpContext.Response.Body = stream; | ||
return Task.CompletedTask; | ||
}; | ||
_middleware = new AuthenticationMiddleware(_next, _factory.Object); | ||
_middleware = new AuthenticationMiddleware(_next, _factory.Object, new MemoryCache(new MemoryCacheOptions())); | ||
await _middleware.Invoke(_httpContext); | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,7 @@ | ||
using Microsoft.AspNetCore.Hosting; | ||
using Microsoft.Extensions.Caching.Memory; | ||
using Newtonsoft.Json; | ||
using Ocelot.Cache; | ||
using Ocelot.Configuration.ChangeTracking; | ||
using Ocelot.Configuration.File; | ||
using Ocelot.Configuration.Repository; | ||
|
@@ -12,29 +14,34 @@ public sealed class DiskFileConfigurationRepositoryTests : FileUnitTest | |
{ | ||
private readonly Mock<IWebHostEnvironment> _hostingEnvironment; | ||
private readonly Mock<IOcelotConfigurationChangeTokenSource> _changeTokenSource; | ||
private readonly Mock<IOcelotCache<FileConfiguration>> _cache; | ||
private IFileConfigurationRepository _repo; | ||
private FileConfiguration _result; | ||
|
||
public DiskFileConfigurationRepositoryTests() | ||
{ | ||
_hostingEnvironment = new Mock<IWebHostEnvironment>(); | ||
_changeTokenSource = new Mock<IOcelotConfigurationChangeTokenSource>(MockBehavior.Strict); | ||
_hostingEnvironment = new(); | ||
_changeTokenSource = new(); | ||
_cache = new(); | ||
_changeTokenSource.Setup(m => m.Activate()); | ||
} | ||
|
||
|
||
// TODO Add integration tests: var aspMemoryCache = new DefaultMemoryCache<FileConfiguration>(new MemoryCache(new MemoryCacheOptions())); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add integration tests! |
||
_repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object, _changeTokenSource.Object, /*aspMemoryCache*/_cache.Object); | ||
} | ||
|
||
private void Arrange([CallerMemberName] string testName = null) | ||
{ | ||
_hostingEnvironment.Setup(he => he.EnvironmentName).Returns(testName); | ||
_repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object, _changeTokenSource.Object, TestID); | ||
_repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object, _changeTokenSource.Object, _cache.Object, TestID); | ||
} | ||
|
||
[Fact] | ||
public async Task Should_return_file_configuration() | ||
{ | ||
{ | ||
Arrange(); | ||
var config = FakeFileConfigurationForGet(); | ||
GivenTheConfigurationIs(config); | ||
|
||
// Act | ||
await WhenIGetTheRoutes(); | ||
|
||
|
@@ -49,7 +56,7 @@ public async Task Should_return_file_configuration_if_environment_name_is_unavai | |
var config = FakeFileConfigurationForGet(); | ||
GivenTheEnvironmentNameIsUnavailable(); | ||
GivenTheConfigurationIs(config); | ||
|
||
// Act | ||
await WhenIGetTheRoutes(); | ||
|
||
|
@@ -62,7 +69,7 @@ public async Task Should_set_file_configuration() | |
{ | ||
Arrange(); | ||
var config = FakeFileConfigurationForSet(); | ||
|
||
// Act | ||
await WhenISetTheConfiguration(config); | ||
|
||
|
@@ -81,7 +88,7 @@ public async Task Should_set_file_configuration_if_environment_name_is_unavailab | |
|
||
// Act | ||
await WhenISetTheConfiguration(config); | ||
|
||
// Assert | ||
ThenTheConfigurationIsStoredAs(config); | ||
ThenTheConfigurationJsonIsIndented(config); | ||
|
@@ -97,15 +104,15 @@ public async Task Should_set_environment_file_configuration_and_ocelot_file_conf | |
|
||
// Act | ||
await WhenISetTheConfiguration(config); | ||
|
||
// Assert | ||
ThenTheConfigurationIsStoredAs(config); | ||
ThenTheConfigurationJsonIsIndented(config); | ||
ThenTheOcelotJsonIsStoredAs(ocelotJson, config); | ||
} | ||
|
||
private FileInfo GivenTheUserAddedOcelotJson() | ||
{ | ||
{ | ||
var primaryFile = Path.Combine(TestID, ConfigurationBuilderExtensions.PrimaryConfigFile); | ||
var ocelotJson = new FileInfo(primaryFile); | ||
if (ocelotJson.Exists) | ||
|
@@ -120,7 +127,9 @@ private FileInfo GivenTheUserAddedOcelotJson() | |
|
||
private void GivenTheEnvironmentNameIsUnavailable() | ||
{ | ||
_hostingEnvironment.Setup(he => he.EnvironmentName).Returns((string)null); | ||
_hostingEnvironment.Setup(he => he.EnvironmentName).Returns(string.Empty); | ||
// TODO Add integration tests: var aspMemoryCache = new DefaultMemoryCache<FileConfiguration>(new MemoryCache(new MemoryCacheOptions())); | ||
//_repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object, _changeTokenSource.Object, aspMemoryCache); | ||
} | ||
|
||
private async Task WhenISetTheConfiguration(FileConfiguration fileConfiguration) | ||
|
@@ -227,8 +236,8 @@ private static FileConfiguration FakeFileConfigurationForGet() | |
{ | ||
var route = GivenRoute("localhost", "/test/test/{test}"); | ||
return GivenConfiguration(route); | ||
} | ||
|
||
} | ||
private static FileRoute GivenRoute(string host, string downstream) => new() | ||
{ | ||
DownstreamHostAndPorts = new() { new(host, 80) }, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are upgrading with enforced use of the cache❗