Merge pull request #5132 from mdmontesinos/sitemap-cache
resolves #4899: output cache for sitemap
This commit is contained in:
commit
a34ed756db
|
@ -53,6 +53,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
services.AddScoped<ISyncService, SyncService>();
|
||||
services.AddScoped<ILocalizationCookieService, LocalizationCookieService>();
|
||||
services.AddScoped<ICookieConsentService, CookieConsentService>();
|
||||
services.AddScoped<ICacheService, CacheService>();
|
||||
|
||||
// providers
|
||||
services.AddScoped<ITextEditor, Oqtane.Modules.Controls.QuillJSTextEditor>();
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
@inject IStringLocalizer<Index> Localizer
|
||||
@inject INotificationService NotificationService
|
||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||
@inject ICacheService CacheService
|
||||
|
||||
@if (_initialized)
|
||||
{
|
||||
|
@ -50,11 +51,12 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="sitemap" HelpText="The site map url for this site which can be submitted to search engines for indexing" ResourceKey="SiteMap">Site Map: </Label>
|
||||
<Label Class="col-sm-3" For="sitemap" HelpText="The site map url for this site which can be submitted to search engines for indexing. The sitemap is cached for 5 minutes and the cache can be manually cleared." ResourceKey="SiteMap">Site Map: </Label>
|
||||
<div class="col-sm-9">
|
||||
<div class="input-group">
|
||||
<input id="sitemap" class="form-control" @bind="@_sitemap" disabled />
|
||||
<a href="@_sitemap" class="btn btn-secondary" target="_new">@Localizer["Browse"]</a>
|
||||
<button type="button" class="btn btn-danger" @onclick="EvictSitemapOutputCache">@Localizer["SiteMap.EvictCache"]</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -732,7 +734,7 @@
|
|||
settings = SettingService.SetSetting(settings, "SMTPEnabled", _smtpenabled, true);
|
||||
settings = SettingService.SetSetting(settings, "SiteGuid", _siteguid, true);
|
||||
settings = SettingService.SetSetting(settings, "NotificationRetention", _retention.ToString(), true);
|
||||
|
||||
|
||||
//cookie consent
|
||||
settings = SettingService.SetSetting(settings, "CookieConsent", _cookieconsent);
|
||||
|
||||
|
@ -932,4 +934,9 @@
|
|||
_aliasname = "";
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private async Task EvictSitemapOutputCache() {
|
||||
await CacheService.EvictOutputCacheByTag(Constants.SitemapOutputCacheTag);
|
||||
AddModuleMessage(Localizer["Success.SiteMap.CacheEvicted"], MessageType.Success);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -349,7 +349,7 @@
|
|||
<value>Relay Configured?</value>
|
||||
</data>
|
||||
<data name="SiteMap.HelpText" xml:space="preserve">
|
||||
<value>The site map url for this site which can be submitted to search engines for indexing</value>
|
||||
<value>The site map url for this site which can be submitted to search engines for indexing. The sitemap is cached for 5 minutes and the cache can be manually cleared.</value>
|
||||
</data>
|
||||
<data name="SiteMap.Text" xml:space="preserve">
|
||||
<value>Site Map:</value>
|
||||
|
@ -441,4 +441,10 @@
|
|||
<data name="Theme.Heading" xml:space="preserve">
|
||||
<value>Theme</value>
|
||||
</data>
|
||||
<data name="SiteMap.EvictCache" xml:space="preserve">
|
||||
<value>Clear Cache</value>
|
||||
</data>
|
||||
<data name="Success.SiteMap.CacheEvicted" xml:space="preserve">
|
||||
<value>SiteMap Output Cache Evicted</value>
|
||||
</data>
|
||||
</root>
|
23
Oqtane.Client/Services/CacheService.cs
Normal file
23
Oqtane.Client/Services/CacheService.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Oqtane.Documentation;
|
||||
using Oqtane.Shared;
|
||||
|
||||
namespace Oqtane.Services
|
||||
{
|
||||
/// <inheritdoc cref="ICacheService" />
|
||||
[PrivateApi("Don't show in the documentation, as everything should use the Interface")]
|
||||
public class CacheService : ServiceBase, ICacheService
|
||||
{
|
||||
public CacheService(HttpClient http, SiteState siteState) : base(http, siteState) { }
|
||||
|
||||
private string ApiUrl => CreateApiUrl("Cache");
|
||||
|
||||
public async Task EvictOutputCacheByTag(string tag, CancellationToken cancellationToken = default)
|
||||
{
|
||||
await DeleteAsync($"{ApiUrl}/outputCache/evictByTag/{tag}");
|
||||
}
|
||||
}
|
||||
}
|
18
Oqtane.Client/Services/Interfaces/ICacheService.cs
Normal file
18
Oqtane.Client/Services/Interfaces/ICacheService.cs
Normal file
|
@ -0,0 +1,18 @@
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Oqtane.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// Service to manage cache
|
||||
/// </summary>
|
||||
public interface ICacheService
|
||||
{
|
||||
/// <summary>
|
||||
/// Evicts the output cache for a specific tag
|
||||
/// </summary>
|
||||
/// <param name="tag"></param>
|
||||
/// <returns></returns>
|
||||
Task EvictOutputCacheByTag(string tag, CancellationToken cancellationToken = default);
|
||||
}
|
||||
}
|
31
Oqtane.Server/Controllers/CacheController.cs
Normal file
31
Oqtane.Server/Controllers/CacheController.cs
Normal file
|
@ -0,0 +1,31 @@
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
using Oqtane.Models;
|
||||
using Oqtane.Services;
|
||||
using Oqtane.Shared;
|
||||
|
||||
namespace Oqtane.Controllers
|
||||
{
|
||||
[Route(ControllerRoutes.ApiRoute)]
|
||||
public class CacheController : Controller
|
||||
{
|
||||
private readonly ICacheService _cacheService;
|
||||
|
||||
public CacheController(ICacheService cacheService)
|
||||
{
|
||||
_cacheService = cacheService;
|
||||
}
|
||||
|
||||
// DELETE api/<controller>/outputCache/evictByTag/{tag}
|
||||
[HttpDelete("outputCache/evictByTag/{tag}")]
|
||||
[Authorize(Roles = RoleNames.Admin)]
|
||||
public async Task EvictOutputCacheByTag(string tag, CancellationToken cancellationToken = default)
|
||||
{
|
||||
await _cacheService.EvictOutputCacheByTag(tag, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -117,6 +117,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
// services
|
||||
services.AddTransient<ISiteService, ServerSiteService>();
|
||||
services.AddTransient<ILocalizationCookieService, ServerLocalizationCookieService>();
|
||||
services.AddTransient<ICacheService, ServerCacheService>();
|
||||
|
||||
// repositories
|
||||
services.AddTransient<IModuleDefinitionRepository, ModuleDefinitionRepository>();
|
||||
|
|
|
@ -7,6 +7,7 @@ using System.Xml;
|
|||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using Microsoft.AspNetCore.OutputCaching;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Oqtane.Enums;
|
||||
using Oqtane.Infrastructure;
|
||||
|
@ -19,6 +20,7 @@ using Oqtane.Shared;
|
|||
namespace Oqtane.Pages
|
||||
{
|
||||
[AllowAnonymous]
|
||||
[OutputCache(Duration = 300, Tags = [Constants.SitemapOutputCacheTag])]
|
||||
public class SitemapModel : PageModel
|
||||
{
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
|
|
41
Oqtane.Server/Services/CacheService.cs
Normal file
41
Oqtane.Server/Services/CacheService.cs
Normal file
|
@ -0,0 +1,41 @@
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.OutputCaching;
|
||||
|
||||
using Oqtane.Documentation;
|
||||
using Oqtane.Enums;
|
||||
using Oqtane.Infrastructure;
|
||||
using Oqtane.Shared;
|
||||
|
||||
namespace Oqtane.Services
|
||||
{
|
||||
[PrivateApi("Don't show in the documentation, as everything should use the Interface")]
|
||||
public class ServerCacheService : ICacheService
|
||||
{
|
||||
private readonly IOutputCacheStore _outputCacheStore;
|
||||
private readonly ILogManager _logger;
|
||||
private readonly IHttpContextAccessor _accessor;
|
||||
|
||||
public ServerCacheService(IOutputCacheStore outputCacheStore, ILogManager logger, IHttpContextAccessor accessor)
|
||||
{
|
||||
_outputCacheStore = outputCacheStore;
|
||||
_logger = logger;
|
||||
_accessor = accessor;
|
||||
}
|
||||
|
||||
public async Task EvictOutputCacheByTag(string tag, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (_accessor.HttpContext.User.IsInRole(RoleNames.Admin))
|
||||
{
|
||||
await _outputCacheStore.EvictByTagAsync(tag, cancellationToken);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Other, "Evicted Output Cache for Tag {Tag}", tag);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Output Cache Eviction for {Tag}", tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -142,6 +142,8 @@ namespace Oqtane
|
|||
});
|
||||
});
|
||||
|
||||
services.AddOutputCache();
|
||||
|
||||
services.AddMvc(options =>
|
||||
{
|
||||
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
|
||||
|
@ -222,6 +224,7 @@ namespace Oqtane
|
|||
app.UseJwtAuthorization();
|
||||
app.UseRouting();
|
||||
app.UseCors();
|
||||
app.UseOutputCache();
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
app.UseAntiforgery();
|
||||
|
|
|
@ -94,6 +94,8 @@ namespace Oqtane.Shared
|
|||
public const string CookieConsentCookieName = "Oqtane.CookieConsent";
|
||||
public const string CookieConsentCookieValue = "yes";
|
||||
public const string CookieConsentActionCookieValue = "yes";
|
||||
|
||||
public const string SitemapOutputCacheTag = "Sitemap";
|
||||
// Obsolete constants
|
||||
|
||||
const string RoleObsoleteMessage = "Use the corresponding member from Oqtane.Shared.RoleNames";
|
||||
|
|
Loading…
Reference in New Issue
Block a user