From 4324e1e8f1d39e40157483c0970fcba398915cf5 Mon Sep 17 00:00:00 2001 From: Mohsen Rajabi Date: Sat, 30 May 2020 21:34:12 +0430 Subject: [PATCH 01/10] add cache --- .../Middleware/AuthenticationMiddleware.cs | 31 +++++++++++++------ .../AuthenticationMiddlewareTests.cs | 5 +-- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/Ocelot/Authentication/Middleware/AuthenticationMiddleware.cs b/src/Ocelot/Authentication/Middleware/AuthenticationMiddleware.cs index 22fa1dca0..b059944fb 100644 --- a/src/Ocelot/Authentication/Middleware/AuthenticationMiddleware.cs +++ b/src/Ocelot/Authentication/Middleware/AuthenticationMiddleware.cs @@ -3,17 +3,22 @@ using Ocelot.Configuration; using Ocelot.Logging; using Ocelot.Middleware; +using System; namespace Ocelot.Authentication.Middleware { public sealed class AuthenticationMiddleware : OcelotMiddleware { private readonly RequestDelegate _next; + private readonly IMemoryCache _memoryCache; - public AuthenticationMiddleware(RequestDelegate next, IOcelotLoggerFactory loggerFactory) + public AuthenticationMiddleware(RequestDelegate next, + IOcelotLoggerFactory loggerFactory, + IMemoryCache memoryCache) : base(loggerFactory.CreateLogger()) { _next = next; + _memoryCache = memoryCache; } public async Task Invoke(HttpContext httpContext) @@ -25,22 +30,30 @@ public async Task Invoke(HttpContext httpContext) // reducing nesting, returning early when no authentication is needed. if (request.Method.Equals("OPTIONS", StringComparison.OrdinalIgnoreCase) || !downstreamRoute.IsAuthenticated) { - Logger.LogInformation($"No authentication needed for path '{path}'."); + Logger.LogInformation(() => $"No authentication needed for path '{path}'."); await _next(httpContext); return; } Logger.LogInformation(() => $"The path '{path}' is an authenticated route! {MiddlewareName} checking if client is authenticated..."); + var token = httpContext.Request.Headers.FirstOrDefault(r => r.Key.Equals("Authorization", StringComparison.OrdinalIgnoreCase)); + var cacheKey = "identityToken." + token; + if (!_memoryCache.TryGetValue(cacheKey, out ClaimsPrincipal userClaim)) + { + var result = await AuthenticateAsync(httpContext, downstreamRoute); - var result = await AuthenticateAsync(httpContext, downstreamRoute); + userClaim = result.Principal; - if (result.Principal?.Identity == null) - { - SetUnauthenticatedError(httpContext, path, null); - return; + _memoryCache.Set(cacheKey, userClaim, TimeSpan.FromMinutes(5)); } - - httpContext.User = result.Principal; + httpContext.User = userClaim; + //var result = await AuthenticateAsync(httpContext, downstreamRoute); + //if (result.Principal?.Identity == null) + //{ + // SetUnauthenticatedError(httpContext, path, null); + // return; + //} + //httpContext.User = result.Principal; if (httpContext.User.Identity.IsAuthenticated) { diff --git a/test/Ocelot.UnitTests/Authentication/AuthenticationMiddlewareTests.cs b/test/Ocelot.UnitTests/Authentication/AuthenticationMiddlewareTests.cs index 0bd9eb603..418af5b6e 100644 --- a/test/Ocelot.UnitTests/Authentication/AuthenticationMiddlewareTests.cs +++ b/test/Ocelot.UnitTests/Authentication/AuthenticationMiddlewareTests.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Caching.Memory; using Ocelot.Configuration; using Ocelot.Configuration.Builder; using Ocelot.Logging; @@ -49,7 +50,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())); var expected = _middleware.GetType().Name; // Act @@ -259,7 +260,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); } } From b09bb55a34bb94e580811ff38b7d418ed33a2f09 Mon Sep 17 00:00:00 2001 From: Mohsen Rajabi Date: Sat, 30 May 2020 22:25:39 +0430 Subject: [PATCH 02/10] add cache file repository --- .../ConsulFileConfigurationRepository.cs | 8 ++--- .../DiskFileConfigurationRepository.cs | 16 +++++++++- .../DiskFileConfigurationRepositoryTests.cs | 29 +++++++++++-------- 3 files changed, 36 insertions(+), 17 deletions(-) diff --git a/src/Ocelot.Provider.Consul/ConsulFileConfigurationRepository.cs b/src/Ocelot.Provider.Consul/ConsulFileConfigurationRepository.cs index c95146f46..46aacbdee 100644 --- a/src/Ocelot.Provider.Consul/ConsulFileConfigurationRepository.cs +++ b/src/Ocelot.Provider.Consul/ConsulFileConfigurationRepository.cs @@ -67,10 +67,10 @@ public async Task Set(FileConfiguration ocelotConfiguration) Value = bytes, }; - var result = await _consul.KV.Put(kvPair); - if (result.Response) - { - _cache.AddAndDelete(_configurationKey, ocelotConfiguration, TimeSpan.FromSeconds(3), _configurationKey); + var result = await _consul.KV.Put(kvPair); + if (result.Response) + { + _cache.AddAndDelete(_configurationKey, ocelotConfiguration, TimeSpan.FromSeconds(5), _configurationKey); return new OkResponse(); } diff --git a/src/Ocelot/Configuration/Repository/DiskFileConfigurationRepository.cs b/src/Ocelot/Configuration/Repository/DiskFileConfigurationRepository.cs index 023fbfafc..861539705 100644 --- a/src/Ocelot/Configuration/Repository/DiskFileConfigurationRepository.cs +++ b/src/Ocelot/Configuration/Repository/DiskFileConfigurationRepository.cs @@ -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,15 +13,20 @@ public class DiskFileConfigurationRepository : IFileConfigurationRepository { private readonly IWebHostEnvironment _hostingEnvironment; private readonly IOcelotConfigurationChangeTokenSource _changeTokenSource; + private readonly IOcelotCache _cache; + private readonly string _cacheKey; private FileInfo _ocelotFile; private FileInfo _environmentFile; private readonly object _lock = new(); - public DiskFileConfigurationRepository(IWebHostEnvironment hostingEnvironment, IOcelotConfigurationChangeTokenSource changeTokenSource) + public DiskFileConfigurationRepository(IWebHostEnvironment hostingEnvironment, + IOcelotConfigurationChangeTokenSource changeTokenSource, Cache.IOcelotCache cache) { _hostingEnvironment = hostingEnvironment; _changeTokenSource = changeTokenSource; Initialize(AppContext.BaseDirectory); + _cache = cache; + _cacheKey = "InternalDiskFileConfigurationRepository"; } public DiskFileConfigurationRepository(IWebHostEnvironment hostingEnvironment, IOcelotConfigurationChangeTokenSource changeTokenSource, string folder) @@ -42,6 +48,11 @@ private void Initialize(string folder) public Task> Get() { + var configuration = _cache.Get(_cacheKey, _cacheKey); + + if (configuration != null) + return Task.FromResult>(new OkResponse(configuration)); + string jsonConfiguration; lock (_lock) @@ -76,6 +87,9 @@ public Task Set(FileConfiguration fileConfiguration) } _changeTokenSource.Activate(); + + _cache.AddAndDelete(_cacheKey, fileConfiguration, TimeSpan.FromMinutes(5), _cacheKey); + return Task.FromResult(new OkResponse()); } } diff --git a/test/Ocelot.UnitTests/Configuration/DiskFileConfigurationRepositoryTests.cs b/test/Ocelot.UnitTests/Configuration/DiskFileConfigurationRepositoryTests.cs index 4ca5a70b0..2de2cf52a 100644 --- a/test/Ocelot.UnitTests/Configuration/DiskFileConfigurationRepositoryTests.cs +++ b/test/Ocelot.UnitTests/Configuration/DiskFileConfigurationRepositoryTests.cs @@ -20,8 +20,10 @@ public DiskFileConfigurationRepositoryTests() _hostingEnvironment = new Mock(); _changeTokenSource = new Mock(MockBehavior.Strict); _changeTokenSource.Setup(m => m.Activate()); - } - + var aspMemoryCache = new AspMemoryCache(new MemoryCache(new MemoryCacheOptions())); + _repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object, _changeTokenSource.Object, aspMemoryCache); + } + private void Arrange([CallerMemberName] string testName = null) { _hostingEnvironment.Setup(he => he.EnvironmentName).Returns(testName); @@ -30,11 +32,11 @@ private void Arrange([CallerMemberName] string testName = null) [Fact] public async Task Should_return_file_configuration() - { + { Arrange(); var config = FakeFileConfigurationForGet(); GivenTheConfigurationIs(config); - + // Act await WhenIGetTheRoutes(); @@ -49,7 +51,7 @@ public async Task Should_return_file_configuration_if_environment_name_is_unavai var config = FakeFileConfigurationForGet(); GivenTheEnvironmentNameIsUnavailable(); GivenTheConfigurationIs(config); - + // Act await WhenIGetTheRoutes(); @@ -62,7 +64,7 @@ public async Task Should_set_file_configuration() { Arrange(); var config = FakeFileConfigurationForSet(); - + // Act await WhenISetTheConfiguration(config); @@ -81,7 +83,7 @@ public async Task Should_set_file_configuration_if_environment_name_is_unavailab // Act await WhenISetTheConfiguration(config); - + // Assert ThenTheConfigurationIsStoredAs(config); ThenTheConfigurationJsonIsIndented(config); @@ -97,7 +99,7 @@ public async Task Should_set_environment_file_configuration_and_ocelot_file_conf // Act await WhenISetTheConfiguration(config); - + // Assert ThenTheConfigurationIsStoredAs(config); ThenTheConfigurationJsonIsIndented(config); @@ -105,7 +107,7 @@ public async Task Should_set_environment_file_configuration_and_ocelot_file_conf } private FileInfo GivenTheUserAddedOcelotJson() - { + { var primaryFile = Path.Combine(TestID, ConfigurationBuilderExtensions.PrimaryConfigFile); var ocelotJson = new FileInfo(primaryFile); if (ocelotJson.Exists) @@ -120,7 +122,10 @@ private FileInfo GivenTheUserAddedOcelotJson() private void GivenTheEnvironmentNameIsUnavailable() { - _hostingEnvironment.Setup(he => he.EnvironmentName).Returns((string)null); + _environmentName = null; + _hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName); + var aspMemoryCache = new AspMemoryCache(new MemoryCache(new MemoryCacheOptions())); + _repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object, _changeTokenSource.Object, aspMemoryCache); } private async Task WhenISetTheConfiguration(FileConfiguration fileConfiguration) @@ -227,8 +232,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) }, From efc955bd44bc53c6bb07342d319799953b6fb713 Mon Sep 17 00:00:00 2001 From: raman-m Date: Tue, 1 Aug 2023 16:20:55 +0300 Subject: [PATCH 03/10] SA1503 Braces should not be omitted. Wrap with braces --- .../Configuration/Repository/DiskFileConfigurationRepository.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Ocelot/Configuration/Repository/DiskFileConfigurationRepository.cs b/src/Ocelot/Configuration/Repository/DiskFileConfigurationRepository.cs index 861539705..ecb7a7629 100644 --- a/src/Ocelot/Configuration/Repository/DiskFileConfigurationRepository.cs +++ b/src/Ocelot/Configuration/Repository/DiskFileConfigurationRepository.cs @@ -51,7 +51,9 @@ public Task> Get() var configuration = _cache.Get(_cacheKey, _cacheKey); if (configuration != null) + { return Task.FromResult>(new OkResponse(configuration)); + } string jsonConfiguration; From d0fca0fdaf33b063a148f9c36252e7d2ffe022b4 Mon Sep 17 00:00:00 2001 From: raman-m Date: Fri, 13 Oct 2023 15:50:26 +0300 Subject: [PATCH 04/10] Add required namespaces --- .../Authentication/Middleware/AuthenticationMiddleware.cs | 2 ++ .../Configuration/Repository/DiskFileConfigurationRepository.cs | 2 +- .../Authentication/AuthenticationMiddlewareTests.cs | 1 + .../Configuration/DiskFileConfigurationRepositoryTests.cs | 2 ++ 4 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Ocelot/Authentication/Middleware/AuthenticationMiddleware.cs b/src/Ocelot/Authentication/Middleware/AuthenticationMiddleware.cs index b059944fb..86d0ad2de 100644 --- a/src/Ocelot/Authentication/Middleware/AuthenticationMiddleware.cs +++ b/src/Ocelot/Authentication/Middleware/AuthenticationMiddleware.cs @@ -1,9 +1,11 @@ using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Caching.Memory; using Ocelot.Configuration; using Ocelot.Logging; using Ocelot.Middleware; using System; +using System.Security.Claims; namespace Ocelot.Authentication.Middleware { diff --git a/src/Ocelot/Configuration/Repository/DiskFileConfigurationRepository.cs b/src/Ocelot/Configuration/Repository/DiskFileConfigurationRepository.cs index ecb7a7629..faba0ef67 100644 --- a/src/Ocelot/Configuration/Repository/DiskFileConfigurationRepository.cs +++ b/src/Ocelot/Configuration/Repository/DiskFileConfigurationRepository.cs @@ -20,7 +20,7 @@ public class DiskFileConfigurationRepository : IFileConfigurationRepository private readonly object _lock = new(); public DiskFileConfigurationRepository(IWebHostEnvironment hostingEnvironment, - IOcelotConfigurationChangeTokenSource changeTokenSource, Cache.IOcelotCache cache) + IOcelotConfigurationChangeTokenSource changeTokenSource, IOcelotCache cache) { _hostingEnvironment = hostingEnvironment; _changeTokenSource = changeTokenSource; diff --git a/test/Ocelot.UnitTests/Authentication/AuthenticationMiddlewareTests.cs b/test/Ocelot.UnitTests/Authentication/AuthenticationMiddlewareTests.cs index 418af5b6e..8e8d7b038 100644 --- a/test/Ocelot.UnitTests/Authentication/AuthenticationMiddlewareTests.cs +++ b/test/Ocelot.UnitTests/Authentication/AuthenticationMiddlewareTests.cs @@ -1,6 +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; diff --git a/test/Ocelot.UnitTests/Configuration/DiskFileConfigurationRepositoryTests.cs b/test/Ocelot.UnitTests/Configuration/DiskFileConfigurationRepositoryTests.cs index 2de2cf52a..68658c7aa 100644 --- a/test/Ocelot.UnitTests/Configuration/DiskFileConfigurationRepositoryTests.cs +++ b/test/Ocelot.UnitTests/Configuration/DiskFileConfigurationRepositoryTests.cs @@ -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; From a4e33f449a67ac38611ccf7c17720fa55f2fdd2c Mon Sep 17 00:00:00 2001 From: Raman Maksimchuk Date: Sun, 10 Nov 2024 15:20:33 +0300 Subject: [PATCH 05/10] Fix build after rebasing --- .../Middleware/AuthenticationMiddleware.cs | 24 ++++++++----------- .../DiskFileConfigurationRepositoryTests.cs | 7 +++--- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/src/Ocelot/Authentication/Middleware/AuthenticationMiddleware.cs b/src/Ocelot/Authentication/Middleware/AuthenticationMiddleware.cs index 86d0ad2de..043ba6a21 100644 --- a/src/Ocelot/Authentication/Middleware/AuthenticationMiddleware.cs +++ b/src/Ocelot/Authentication/Middleware/AuthenticationMiddleware.cs @@ -4,7 +4,6 @@ using Ocelot.Configuration; using Ocelot.Logging; using Ocelot.Middleware; -using System; using System.Security.Claims; namespace Ocelot.Authentication.Middleware @@ -40,23 +39,20 @@ public async Task Invoke(HttpContext httpContext) Logger.LogInformation(() => $"The path '{path}' is an authenticated route! {MiddlewareName} checking if client is authenticated..."); var token = httpContext.Request.Headers.FirstOrDefault(r => r.Key.Equals("Authorization", StringComparison.OrdinalIgnoreCase)); var cacheKey = "identityToken." + token; - if (!_memoryCache.TryGetValue(cacheKey, out ClaimsPrincipal userClaim)) + if (!_memoryCache.TryGetValue(cacheKey, out ClaimsPrincipal principal)) { - var result = await AuthenticateAsync(httpContext, downstreamRoute); - - userClaim = result.Principal; + var auth = await AuthenticateAsync(httpContext, downstreamRoute); + principal = auth.Principal; + _memoryCache.Set(cacheKey, principal, TimeSpan.FromMinutes(5)); + } - _memoryCache.Set(cacheKey, userClaim, TimeSpan.FromMinutes(5)); + if (principal?.Identity == null) + { + SetUnauthenticatedError(httpContext, path, null); + return; } - httpContext.User = userClaim; - //var result = await AuthenticateAsync(httpContext, downstreamRoute); - //if (result.Principal?.Identity == null) - //{ - // SetUnauthenticatedError(httpContext, path, null); - // return; - //} - //httpContext.User = result.Principal; + httpContext.User = principal; if (httpContext.User.Identity.IsAuthenticated) { Logger.LogInformation(() => $"Client has been authenticated for path '{path}' by '{httpContext.User.Identity.AuthenticationType}' scheme."); diff --git a/test/Ocelot.UnitTests/Configuration/DiskFileConfigurationRepositoryTests.cs b/test/Ocelot.UnitTests/Configuration/DiskFileConfigurationRepositoryTests.cs index 68658c7aa..930dfb239 100644 --- a/test/Ocelot.UnitTests/Configuration/DiskFileConfigurationRepositoryTests.cs +++ b/test/Ocelot.UnitTests/Configuration/DiskFileConfigurationRepositoryTests.cs @@ -22,7 +22,7 @@ public DiskFileConfigurationRepositoryTests() _hostingEnvironment = new Mock(); _changeTokenSource = new Mock(MockBehavior.Strict); _changeTokenSource.Setup(m => m.Activate()); - var aspMemoryCache = new AspMemoryCache(new MemoryCache(new MemoryCacheOptions())); + var aspMemoryCache = new DefaultMemoryCache(new MemoryCache(new MemoryCacheOptions())); _repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object, _changeTokenSource.Object, aspMemoryCache); } @@ -124,9 +124,8 @@ private FileInfo GivenTheUserAddedOcelotJson() private void GivenTheEnvironmentNameIsUnavailable() { - _environmentName = null; - _hostingEnvironment.Setup(he => he.EnvironmentName).Returns(_environmentName); - var aspMemoryCache = new AspMemoryCache(new MemoryCache(new MemoryCacheOptions())); + _hostingEnvironment.Setup(he => he.EnvironmentName).Returns(string.Empty); + var aspMemoryCache = new DefaultMemoryCache(new MemoryCache(new MemoryCacheOptions())); _repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object, _changeTokenSource.Object, aspMemoryCache); } From 6504dccde67e0103fd48332e7904a362c6990aae Mon Sep 17 00:00:00 2001 From: Raman Maksimchuk Date: Sun, 10 Nov 2024 15:32:00 +0300 Subject: [PATCH 06/10] EOL: src/Ocelot.Provider.Consul/ConsulFileConfigurationRepository.cs --- .../ConsulFileConfigurationRepository.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/Ocelot.Provider.Consul/ConsulFileConfigurationRepository.cs b/src/Ocelot.Provider.Consul/ConsulFileConfigurationRepository.cs index 46aacbdee..f70855aa4 100644 --- a/src/Ocelot.Provider.Consul/ConsulFileConfigurationRepository.cs +++ b/src/Ocelot.Provider.Consul/ConsulFileConfigurationRepository.cs @@ -54,7 +54,6 @@ public async Task> Get() var bytes = queryResult.Response.Value; var json = Encoding.UTF8.GetString(bytes); var consulConfig = JsonConvert.DeserializeObject(json); - return new OkResponse(consulConfig); } @@ -67,11 +66,10 @@ public async Task Set(FileConfiguration ocelotConfiguration) Value = bytes, }; - var result = await _consul.KV.Put(kvPair); - if (result.Response) - { - _cache.AddAndDelete(_configurationKey, ocelotConfiguration, TimeSpan.FromSeconds(5), _configurationKey); - + var result = await _consul.KV.Put(kvPair); + if (result.Response) + { + _cache.AddAndDelete(_configurationKey, ocelotConfiguration, TimeSpan.FromSeconds(5), _configurationKey); return new OkResponse(); } From d052f478d3586db3ec8c93351b7a73a96e78bffe Mon Sep 17 00:00:00 2001 From: Raman Maksimchuk Date: Sun, 10 Nov 2024 16:05:52 +0300 Subject: [PATCH 07/10] Quick code review by @raman-m --- .../Middleware/AuthenticationMiddleware.cs | 4 ++-- .../DiskFileConfigurationRepository.cs | 23 ++++++++----------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/Ocelot/Authentication/Middleware/AuthenticationMiddleware.cs b/src/Ocelot/Authentication/Middleware/AuthenticationMiddleware.cs index 043ba6a21..9a1ee4b1a 100644 --- a/src/Ocelot/Authentication/Middleware/AuthenticationMiddleware.cs +++ b/src/Ocelot/Authentication/Middleware/AuthenticationMiddleware.cs @@ -37,8 +37,8 @@ public async Task Invoke(HttpContext httpContext) } Logger.LogInformation(() => $"The path '{path}' is an authenticated route! {MiddlewareName} checking if client is authenticated..."); - var token = httpContext.Request.Headers.FirstOrDefault(r => r.Key.Equals("Authorization", StringComparison.OrdinalIgnoreCase)); - var cacheKey = "identityToken." + token; + var token = httpContext.Request.Headers.Authorization; + var cacheKey = $"{nameof(AuthenticationMiddleware)}.{nameof(IHeaderDictionary.Authorization)}:{token}"; if (!_memoryCache.TryGetValue(cacheKey, out ClaimsPrincipal principal)) { var auth = await AuthenticateAsync(httpContext, downstreamRoute); diff --git a/src/Ocelot/Configuration/Repository/DiskFileConfigurationRepository.cs b/src/Ocelot/Configuration/Repository/DiskFileConfigurationRepository.cs index faba0ef67..b70c41de1 100644 --- a/src/Ocelot/Configuration/Repository/DiskFileConfigurationRepository.cs +++ b/src/Ocelot/Configuration/Repository/DiskFileConfigurationRepository.cs @@ -14,22 +14,25 @@ public class DiskFileConfigurationRepository : IFileConfigurationRepository private readonly IWebHostEnvironment _hostingEnvironment; private readonly IOcelotConfigurationChangeTokenSource _changeTokenSource; private readonly IOcelotCache _cache; - private readonly string _cacheKey; + private FileInfo _ocelotFile; private FileInfo _environmentFile; private readonly object _lock = new(); + public const string CacheKey = nameof(DiskFileConfigurationRepository); public DiskFileConfigurationRepository(IWebHostEnvironment hostingEnvironment, - IOcelotConfigurationChangeTokenSource changeTokenSource, IOcelotCache cache) + IOcelotConfigurationChangeTokenSource changeTokenSource, + IOcelotCache cache) { _hostingEnvironment = hostingEnvironment; _changeTokenSource = changeTokenSource; - Initialize(AppContext.BaseDirectory); _cache = cache; - _cacheKey = "InternalDiskFileConfigurationRepository"; + Initialize(AppContext.BaseDirectory); } - public DiskFileConfigurationRepository(IWebHostEnvironment hostingEnvironment, IOcelotConfigurationChangeTokenSource changeTokenSource, string folder) + public DiskFileConfigurationRepository(IWebHostEnvironment hostingEnvironment, + IOcelotConfigurationChangeTokenSource changeTokenSource, + string folder) { _hostingEnvironment = hostingEnvironment; _changeTokenSource = changeTokenSource; @@ -48,29 +51,25 @@ private void Initialize(string folder) public Task> Get() { - var configuration = _cache.Get(_cacheKey, _cacheKey); - + var configuration = _cache.Get(CacheKey, region: CacheKey); if (configuration != null) { return Task.FromResult>(new OkResponse(configuration)); } string jsonConfiguration; - lock (_lock) { jsonConfiguration = FileSys.ReadAllText(_environmentFile.FullName); } var fileConfiguration = JsonConvert.DeserializeObject(jsonConfiguration); - return Task.FromResult>(new OkResponse(fileConfiguration)); } public Task Set(FileConfiguration fileConfiguration) { var jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration, Formatting.Indented); - lock (_lock) { if (_environmentFile.Exists) @@ -89,9 +88,7 @@ public Task Set(FileConfiguration fileConfiguration) } _changeTokenSource.Activate(); - - _cache.AddAndDelete(_cacheKey, fileConfiguration, TimeSpan.FromMinutes(5), _cacheKey); - + _cache.AddAndDelete(CacheKey, fileConfiguration, TimeSpan.FromMinutes(5), region: CacheKey); return Task.FromResult(new OkResponse()); } } From ff3f5ab68e64de3a1ac64051527b7c5982a6fb4b Mon Sep 17 00:00:00 2001 From: Raman Maksimchuk Date: Sun, 10 Nov 2024 16:23:22 +0300 Subject: [PATCH 08/10] CacheTtlSeconds static value --- .../ConsulFileConfigurationRepository.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Ocelot.Provider.Consul/ConsulFileConfigurationRepository.cs b/src/Ocelot.Provider.Consul/ConsulFileConfigurationRepository.cs index f70855aa4..09023d311 100644 --- a/src/Ocelot.Provider.Consul/ConsulFileConfigurationRepository.cs +++ b/src/Ocelot.Provider.Consul/ConsulFileConfigurationRepository.cs @@ -57,6 +57,10 @@ public async Task> Get() return new OkResponse(consulConfig); } + /// Default TTL in seconds for caching . + /// An value. + public static int CacheTtlSeconds { get; set; } = 5; + public async Task Set(FileConfiguration ocelotConfiguration) { var json = JsonConvert.SerializeObject(ocelotConfiguration, Formatting.Indented); @@ -69,7 +73,7 @@ public async Task Set(FileConfiguration ocelotConfiguration) var result = await _consul.KV.Put(kvPair); if (result.Response) { - _cache.AddAndDelete(_configurationKey, ocelotConfiguration, TimeSpan.FromSeconds(5), _configurationKey); + _cache.AddAndDelete(_configurationKey, ocelotConfiguration, TimeSpan.FromSeconds(CacheTtlSeconds), _configurationKey); return new OkResponse(); } From 36909d98d599e552deff73922e576ccfc39f7f6c Mon Sep 17 00:00:00 2001 From: Raman Maksimchuk Date: Sun, 10 Nov 2024 16:44:54 +0300 Subject: [PATCH 09/10] Global static CacheTtlSeconds settings --- .../ConsulFileConfigurationRepository.cs | 4 ++-- .../Authentication/Middleware/AuthenticationMiddleware.cs | 6 +++++- .../Repository/DiskFileConfigurationRepository.cs | 6 +++++- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/Ocelot.Provider.Consul/ConsulFileConfigurationRepository.cs b/src/Ocelot.Provider.Consul/ConsulFileConfigurationRepository.cs index 09023d311..00982500a 100644 --- a/src/Ocelot.Provider.Consul/ConsulFileConfigurationRepository.cs +++ b/src/Ocelot.Provider.Consul/ConsulFileConfigurationRepository.cs @@ -57,8 +57,8 @@ public async Task> Get() return new OkResponse(consulConfig); } - /// Default TTL in seconds for caching . - /// An value. + /// Default TTL in seconds for caching in the method. + /// An value, 5 by default. public static int CacheTtlSeconds { get; set; } = 5; public async Task Set(FileConfiguration ocelotConfiguration) diff --git a/src/Ocelot/Authentication/Middleware/AuthenticationMiddleware.cs b/src/Ocelot/Authentication/Middleware/AuthenticationMiddleware.cs index 9a1ee4b1a..2845803c9 100644 --- a/src/Ocelot/Authentication/Middleware/AuthenticationMiddleware.cs +++ b/src/Ocelot/Authentication/Middleware/AuthenticationMiddleware.cs @@ -22,6 +22,10 @@ public AuthenticationMiddleware(RequestDelegate next, _memoryCache = memoryCache; } + /// Default TTL in seconds for caching of the current object. + /// An value, 300 seconds (5 minutes) by default. + public static int CacheTtlSeconds { get; set; } = 300; + public async Task Invoke(HttpContext httpContext) { var request = httpContext.Request; @@ -43,7 +47,7 @@ public async Task Invoke(HttpContext httpContext) { var auth = await AuthenticateAsync(httpContext, downstreamRoute); principal = auth.Principal; - _memoryCache.Set(cacheKey, principal, TimeSpan.FromMinutes(5)); + _memoryCache.Set(cacheKey, principal, TimeSpan.FromSeconds(CacheTtlSeconds)); } if (principal?.Identity == null) diff --git a/src/Ocelot/Configuration/Repository/DiskFileConfigurationRepository.cs b/src/Ocelot/Configuration/Repository/DiskFileConfigurationRepository.cs index b70c41de1..2929eeaf2 100644 --- a/src/Ocelot/Configuration/Repository/DiskFileConfigurationRepository.cs +++ b/src/Ocelot/Configuration/Repository/DiskFileConfigurationRepository.cs @@ -67,6 +67,10 @@ public Task> Get() return Task.FromResult>(new OkResponse(fileConfiguration)); } + /// Default TTL in seconds for caching in the method. + /// An value, 300 seconds (5 minutes) by default. + public static int CacheTtlSeconds { get; set; } = 300; + public Task Set(FileConfiguration fileConfiguration) { var jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration, Formatting.Indented); @@ -88,7 +92,7 @@ public Task Set(FileConfiguration fileConfiguration) } _changeTokenSource.Activate(); - _cache.AddAndDelete(CacheKey, fileConfiguration, TimeSpan.FromMinutes(5), region: CacheKey); + _cache.AddAndDelete(CacheKey, fileConfiguration, TimeSpan.FromSeconds(CacheTtlSeconds), region: CacheKey); return Task.FromResult(new OkResponse()); } } From 615a7c72fbae78c20c6513dc0c5dfd5841bb407b Mon Sep 17 00:00:00 2001 From: Raman Maksimchuk Date: Sun, 10 Nov 2024 17:17:10 +0300 Subject: [PATCH 10/10] Fix unit tests --- .../DiskFileConfigurationRepository.cs | 2 ++ .../DiskFileConfigurationRepositoryTests.cs | 17 ++++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/Ocelot/Configuration/Repository/DiskFileConfigurationRepository.cs b/src/Ocelot/Configuration/Repository/DiskFileConfigurationRepository.cs index 2929eeaf2..6daab22e3 100644 --- a/src/Ocelot/Configuration/Repository/DiskFileConfigurationRepository.cs +++ b/src/Ocelot/Configuration/Repository/DiskFileConfigurationRepository.cs @@ -32,10 +32,12 @@ public DiskFileConfigurationRepository(IWebHostEnvironment hostingEnvironment, public DiskFileConfigurationRepository(IWebHostEnvironment hostingEnvironment, IOcelotConfigurationChangeTokenSource changeTokenSource, + IOcelotCache cache, string folder) { _hostingEnvironment = hostingEnvironment; _changeTokenSource = changeTokenSource; + _cache = cache; Initialize(folder); } diff --git a/test/Ocelot.UnitTests/Configuration/DiskFileConfigurationRepositoryTests.cs b/test/Ocelot.UnitTests/Configuration/DiskFileConfigurationRepositoryTests.cs index 930dfb239..ff51a6c83 100644 --- a/test/Ocelot.UnitTests/Configuration/DiskFileConfigurationRepositoryTests.cs +++ b/test/Ocelot.UnitTests/Configuration/DiskFileConfigurationRepositoryTests.cs @@ -14,22 +14,25 @@ public sealed class DiskFileConfigurationRepositoryTests : FileUnitTest { private readonly Mock _hostingEnvironment; private readonly Mock _changeTokenSource; + private readonly Mock> _cache; private IFileConfigurationRepository _repo; private FileConfiguration _result; public DiskFileConfigurationRepositoryTests() { - _hostingEnvironment = new Mock(); - _changeTokenSource = new Mock(MockBehavior.Strict); + _hostingEnvironment = new(); + _changeTokenSource = new(); + _cache = new(); _changeTokenSource.Setup(m => m.Activate()); - var aspMemoryCache = new DefaultMemoryCache(new MemoryCache(new MemoryCacheOptions())); - _repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object, _changeTokenSource.Object, aspMemoryCache); + + // TODO Add integration tests: var aspMemoryCache = new DefaultMemoryCache(new MemoryCache(new MemoryCacheOptions())); + _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] @@ -125,8 +128,8 @@ private FileInfo GivenTheUserAddedOcelotJson() private void GivenTheEnvironmentNameIsUnavailable() { _hostingEnvironment.Setup(he => he.EnvironmentName).Returns(string.Empty); - var aspMemoryCache = new DefaultMemoryCache(new MemoryCache(new MemoryCacheOptions())); - _repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object, _changeTokenSource.Object, aspMemoryCache); + // TODO Add integration tests: var aspMemoryCache = new DefaultMemoryCache(new MemoryCache(new MemoryCacheOptions())); + //_repo = new DiskFileConfigurationRepository(_hostingEnvironment.Object, _changeTokenSource.Object, aspMemoryCache); } private async Task WhenISetTheConfiguration(FileConfiguration fileConfiguration)