Skip to content
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

Feature/functional dashboard and content app #5

Merged
merged 5 commits into from
Jan 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
❤️ This project is royalty free and open source, so if you using and love it, you can support it by becoming [Github sponsor](https://github.com/sponsors/bielu) ❤️


# Umbraco Cdn Integration provider
This package integrate umbraco publishing pipeline to cdn to refresh content based on publish / save operations.
## Docs
Expand Down
1 change: 1 addition & 0 deletions src/bielu.Umbraco.Cdn.Abstraction/Models/AuditRecord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ namespace bielu.Umbraco.Cdn.Models;

public class AuditRecord
{
public bool IsFromProvider { get; set; }
public string? Name { get; set; }
public DateTime Date { get; set; }
public string? Message { get; set; }
Expand Down
3 changes: 2 additions & 1 deletion src/bielu.Umbraco.Cdn.Core/Composition/CdnComposition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using bielu.Umbraco.Cdn.Core.NotitificationHandlers.Tree;
using bielu.Umbraco.Cdn.Core.Services;
using bielu.Umbraco.Cdn.Services;
using bielu.Umbraco.Cdn.Core.ContentApp;
using Microsoft.Extensions.DependencyInjection;
using Umbraco.Cms.Core.Composing;
using Umbraco.Cms.Core.DependencyInjection;
Expand All @@ -22,7 +23,7 @@ public void Compose(IUmbracoBuilder composition)
{
composition.Services.AddOptions<BieluCdnOptions>().BindConfiguration(BieluCdnOptions.SectionName);
composition.ManifestFilters().Append<BieluCdnUIManifestFilter>();

composition.ContentApps().Append<BieluCdnApp>();
//services
composition.Services.AddTransient(typeof(IUmbracoUrlDeliveryService), typeof(UmbracoUrlDeliveryService));
composition.Services.AddSingleton<ICdnManager, CdnManager>();
Expand Down
1 change: 1 addition & 0 deletions src/bielu.Umbraco.Cdn.Core/Constants/CdnConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
public class CdnConstants
{
public const string CdnConfigSectionName = "Bielu:Cdn";
public const string AuditLogType = "CDN Refresh";
}
34 changes: 34 additions & 0 deletions src/bielu.Umbraco.Cdn.Core/ContentApp/BieluCDNApp.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.ContentEditing;
using Umbraco.Cms.Core.Models.Membership;

namespace bielu.Umbraco.Cdn.Core.ContentApp;

public class BieluCdnApp : IContentAppFactory
{
public global::Umbraco.Cms.Core.Models.ContentEditing.ContentApp? GetContentAppFor(object source, IEnumerable<IReadOnlyUserGroup> userGroups)
{
// Can implement some logic with userGroups if needed
// Allowing us to display the content app with some restrictions for certain groups
if (userGroups.All(x => x.Alias.ToLowerInvariant() != global::Umbraco.Cms.Core.Constants.Security.AdminGroupAlias))
return null;

// Only show app on content items
if (!(source is IContent))
return null;
// Only show app on content with certain content type alias
// if (!content.ContentType.Alias.Equals("aliasName"))
// return null;



return new global::Umbraco.Cms.Core.Models.ContentEditing.ContentApp
{
Alias = "bieluCdnApp",
Name = "CDN",
Icon = "icon-hard-drive",
View = "/App_Plugins/bielu.cdn.ui/contentApp.html",
Weight = 900
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,56 +28,110 @@
private BieluCdnOptions _optionsMonitor;

public BieluCdnManagmentController(ICdnManager manager, IUmbracoContextFactory contextFactory,
Services.ICdnAuditService auditService, IUmbracoUrlDeliveryService urlDeliveryService, IOptionsMonitor<BieluCdnOptions> optionsMonitor)
Services.ICdnAuditService auditService, IUmbracoUrlDeliveryService urlDeliveryService,
IOptionsMonitor<BieluCdnOptions> optionsMonitor)
{
_manager = manager;
_contextFactory = contextFactory;
_auditService = auditService;
_urlDeliveryService = urlDeliveryService;
_optionsMonitor = optionsMonitor.CurrentValue;
optionsMonitor.OnChange((options, name) =>
{
_optionsMonitor = options;
});
optionsMonitor.OnChange((options, name) => { _optionsMonitor = options; });
}

public async Task<IEnumerable<AuditRecord>> GetAuditHistory()
public async Task<IEnumerable<AuditRecord>?> GetAuditHistory()
{
return await _auditService.GetAllRecords();
}

public async Task<IEnumerable<AuditRecord>?> GetAllRecords(int id)
{
return await _auditService.GetAllRecords(id);
}
public async Task<AuditRecord?> GetLastLog(int id)
{
return await _auditService.GetLastRecord(id);
}
public async Task<IEnumerable<Provider>> GetProviders(int id = -1)
{
return await _manager.GetProviders(id);
}

public async Task<Status> RefreshForNode(int id,bool descandants,bool references, string providerId = null, string domain = null)
public async Task<Status> RefreshDomain(string providerId = null, string domain = null)

Check warning on line 59 in src/bielu.Umbraco.Cdn.Core/Controllers/BieluCdnManagmentController.cs

View workflow job for this annotation

GitHub Actions / buildPr / build / build

Cannot convert null literal to non-nullable reference type.

Check warning on line 59 in src/bielu.Umbraco.Cdn.Core/Controllers/BieluCdnManagmentController.cs

View workflow job for this annotation

GitHub Actions / buildPr / build / build

Cannot convert null literal to non-nullable reference type.

Check warning on line 59 in src/bielu.Umbraco.Cdn.Core/Controllers/BieluCdnManagmentController.cs

View workflow job for this annotation

GitHub Actions / buildPr / build / build

Cannot convert null literal to non-nullable reference type.

Check warning on line 59 in src/bielu.Umbraco.Cdn.Core/Controllers/BieluCdnManagmentController.cs

View workflow job for this annotation

GitHub Actions / buildPr / build / build

Cannot convert null literal to non-nullable reference type.
{
List<Status> statuses = new List<Status>();
using (var contextReference = _contextFactory.EnsureUmbracoContext())
{
var hostnames = new List<string> { domain };

if (!string.IsNullOrEmpty(providerId))
{
var service = await _manager.GetService(providerId);
statuses.AddRange(await service.PurgeByAssignedHostnames(hostnames));
return statuses.Merge();
}


foreach (var service in (await _manager.GetServices()).Where(x => x.IsEnabled()))
{
statuses.AddRange(await service.PurgeByAssignedHostnames(hostnames));
}
}

return statuses.Merge();
}

public async Task<Status> RefreshForNode(int id, bool descandants, bool references, string providerId = null,

Check warning on line 83 in src/bielu.Umbraco.Cdn.Core/Controllers/BieluCdnManagmentController.cs

View workflow job for this annotation

GitHub Actions / buildPr / build / build

Cannot convert null literal to non-nullable reference type.

Check warning on line 83 in src/bielu.Umbraco.Cdn.Core/Controllers/BieluCdnManagmentController.cs

View workflow job for this annotation

GitHub Actions / buildPr / build / build

Cannot convert null literal to non-nullable reference type.
string domain = null)

Check warning on line 84 in src/bielu.Umbraco.Cdn.Core/Controllers/BieluCdnManagmentController.cs

View workflow job for this annotation

GitHub Actions / buildPr / build / build

Cannot convert null literal to non-nullable reference type.

Check warning on line 84 in src/bielu.Umbraco.Cdn.Core/Controllers/BieluCdnManagmentController.cs

View workflow job for this annotation

GitHub Actions / buildPr / build / build

Cannot convert null literal to non-nullable reference type.
{
List<Status> statuses = new List<Status>();
using (var contextReference = _contextFactory.EnsureUmbracoContext())
{
var content = contextReference.UmbracoContext.Content.GetById(id);

var urls = _urlDeliveryService.GetUrlsByContent(content, descandants, references);

if (_optionsMonitor.ReferencePurge && references)
{
urls.AddRange(_urlDeliveryService.GetUrlsByReferences(content));
}
if (_optionsMonitor.Auditing)
{
await _auditService.LogRefresh( content.Id,descandants, references);
}
if (!string.IsNullOrEmpty(providerId))
{
var service = await _manager.GetService(providerId);
statuses.AddRange(await service.PurgePages(urls));
statuses.AddRange(await service.PurgePages(urls.Where(x=>x.Contains(domain))));
return statuses.Merge();
}

foreach (var service in (await _manager.GetServices()).Where(x=>x.IsEnabled()))

foreach (var service in (await _manager.GetServices()).Where(x => x.IsEnabled()))
{
statuses.AddRange(await service.PurgePages(urls));
}
}

return statuses.Merge();
}
public async Task<Status> RefreshForProvider(string providerId)
{
List<Status> statuses = new List<Status>();
var service = await _manager.GetService(providerId);

statuses.AddRange(await service.PurgeAll());

return statuses.Merge();
}
public async Task<Status> RefreshAll()
{
List<Status> statuses = new List<Status>();

foreach (var service in (await _manager.GetServices()).Where(x => x.IsEnabled()))
{
statuses.AddRange(await service.PurgeAll());
}

return statuses.Merge();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public void Filter(List<PackageManifest> manifests)
{
$"/App_Plugins/bielu.cdn.ui/{(_options.DevMode ? "dev-bootstrapper" : "bootstrapper")}.js",
"/App_Plugins/bielu.cdn.ui/bielu.cdn.ui.angularController.js",
"/App_Plugins/bielu.cdn.ui/bielu.cdn.ui.angularController.contentApp.js",

},
Version = assembly.GetName()?.Version?.ToString(3) ?? "0.1.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,30 +29,28 @@ public class ContentEventsNotificationNotificationHandler : INotificationAsyncHa
private readonly IUmbracoUrlDeliveryService _umbracoUrlDeliveryService;
private readonly IEnumerable<ICdnService> _cdnServices;
private readonly ILogger<ContentEventsNotificationNotificationHandler> _logger;
private readonly IAuditService _auditService;
private readonly IBackOfficeSecurityAccessor _accessor;
private readonly BieluCdnOptions _configuration;
private readonly ICdnAuditService _auditService;
private BieluCdnOptions _configuration;

public ContentEventsNotificationNotificationHandler(IUmbracoUrlDeliveryService umbracoUrlDeliveryService,
IEnumerable<ICdnService> cdnServices, ILogger<ContentEventsNotificationNotificationHandler> logger,
IAuditService auditService, IBackOfficeSecurityAccessor accessor, IOptionsMonitor<BieluCdnOptions> configuration)
ICdnAuditService auditService, IOptionsMonitor<BieluCdnOptions> configuration)
{
_umbracoUrlDeliveryService = umbracoUrlDeliveryService;
_cdnServices = cdnServices;
_logger = logger;
_auditService = auditService;
_accessor = accessor;
_configuration = configuration.CurrentValue;
configuration.OnChange((options, name) => { _configuration = options; });

}

public async Task HandleAsync(ContentMovingNotification notification, CancellationToken cancellationToken)
{
var pages = new List<string>();
var currentUser = _accessor.BackOfficeSecurity.CurrentUser;
foreach (var content in notification.MoveInfoCollection)
{
pages.AddRange(GetPages(content.Entity));
pages.AddRange(await GetPages(content.Entity));
}

//todo: optimize as now we dont valide which domains is valid for either of cdns
Expand Down Expand Up @@ -86,14 +84,12 @@ public async Task HandleAsync(ContentMovingNotification notification, Cancellati
}
}

private List<string> GetPages(IContent content)
private async Task<List<string>> GetPages(IContent content)
{
var currentUser = _accessor.BackOfficeSecurity.CurrentUser;
var pages = new List<string>();
if (_configuration.Auditing)
{
_auditService.Add(AuditType.Custom, currentUser.Id, content.Id, "CDN Refresh",
$"CDN cache was purged", $"CDN cache purged");
await _auditService.LogRefresh( content.Id);
}

pages.AddRange(_umbracoUrlDeliveryService.GetUrlsByContent(content));
Expand All @@ -110,7 +106,7 @@ public async Task HandleAsync(ContentDeletingNotification notification, Cancella

foreach (var content in notification.DeletedEntities)
{
pages.AddRange(GetPages(content));
pages.AddRange(await GetPages(content));
}

//todo: optimize as now we dont valide which domains is valid for either of cdns
Expand Down Expand Up @@ -157,7 +153,6 @@ public async Task HandleAsync(ContentDeletingNotification notification, Cancella

public async Task HandleAsync(ContentUnpublishedNotification notification, CancellationToken cancellationToken)
{
var currentUser = _accessor.BackOfficeSecurity.CurrentUser;
if (!notification.State.ContainsKey("purgedUrls"))
{
return;
Expand Down Expand Up @@ -208,12 +203,10 @@ public async Task HandleAsync(ContentUnpublishedNotification notification, Cance

public async Task HandleAsync(ContentPublishedNotification notification, CancellationToken cancellationToken)
{
var currentUser = _accessor.BackOfficeSecurity.CurrentUser;

var pages = new List<string>();
foreach (var content in notification.PublishedEntities)
{
pages.AddRange(GetPages(content));
pages.AddRange(await GetPages(content));
}

try
Expand Down Expand Up @@ -261,7 +254,7 @@ public async Task HandleAsync(ContentUnpublishingNotification notification, Canc
var pages = new List<string>();
foreach (var content in notification.UnpublishedEntities)
{
pages.AddRange(GetPages(content));
pages.AddRange(await GetPages(content));
}

notification.State["purgedUrls"] = pages;
Expand All @@ -271,15 +264,14 @@ public async Task HandleAsync(ContentPublishingNotification notification, Cancel
{
try
{
var currentUser = _accessor.BackOfficeSecurity.CurrentUser;
var pages = new List<string>();
var pages = new List<string>();


foreach (var content in notification.PublishedEntities)
{
if (content.Published)
{
pages.AddRange(GetPages(content));
pages.AddRange(await GetPages(content));
}
}

Expand All @@ -299,15 +291,12 @@ public async Task HandleAsync(ContentSavedNotification notification, Cancellatio

try
{
var currentUser = _accessor.BackOfficeSecurity.CurrentUser;
var pages = new List<string>();


foreach (var content in notification.SavedEntities)
foreach (var content in notification.SavedEntities)
{
if (content.Published)
{
pages.AddRange(GetPages(content));
pages.AddRange(await GetPages(content));
}
}

Expand Down
Loading
Loading