Skip to content

Commit

Permalink
Merge pull request Jumoo#44 from craigagnew/v10-load-balanced
Browse files Browse the repository at this point in the history
V10 load balanced
  • Loading branch information
KevinJump authored Aug 30, 2024
2 parents ed8a409 + 3c2de81 commit 141b692
Show file tree
Hide file tree
Showing 29 changed files with 514 additions and 104 deletions.
11 changes: 10 additions & 1 deletion Our.Umbraco.MaintenanceMode/Composers/MaintenceModeComposer.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
using Microsoft.Extensions.DependencyInjection;

using Our.Umbraco.MaintenanceMode.Configurations;
using Our.Umbraco.MaintenanceMode.Factories;
using Our.Umbraco.MaintenanceMode.Interfaces;
using Our.Umbraco.MaintenanceMode.NotificationHandlers.Application;
using Our.Umbraco.MaintenanceMode.NotificationHandlers.Content;
using Our.Umbraco.MaintenanceMode.NotificationHandlers.Media;
using Our.Umbraco.MaintenanceMode.NotificationHandlers.ServerVariables;
using Our.Umbraco.MaintenanceMode.Providers;
using Our.Umbraco.MaintenanceMode.Services;
using System.Collections.Generic;
using System.Linq;
Expand Down Expand Up @@ -38,8 +41,12 @@ public static IUmbracoBuilder AddMaintenceManager(this IUmbracoBuilder builder)
builder.Services.Configure<MaintenanceModeSettings>
(builder.Config.GetSection("MaintenanceMode"));


builder.Services.AddTransient<IBackofficeUserAccessor, BackofficeUserAccessor>();
builder.Services.AddSingleton<IStorageProviderFactory, StorageProviderFactory>();
builder.Services.AddSingleton<FileSystemStorageProvider>()
.AddSingleton<IStorageProvider, FileSystemStorageProvider>(s => s.GetService<FileSystemStorageProvider>());
builder.Services.AddSingleton<DatabaseStorageProvider>()
.AddSingleton<IStorageProvider, DatabaseStorageProvider>(s => s.GetService<DatabaseStorageProvider>());
builder.Services.AddUnique<IMaintenanceModeService, MaintenanceModeService>();

builder.AddNotificationHandlers();
Expand All @@ -66,6 +73,8 @@ private static void AddNotificationHandlers(this IUmbracoBuilder builder)
.AddNotificationHandler<MediaMovingNotification, FreezeMediaMovingNotification>()
.AddNotificationHandler<MediaMovingToRecycleBinNotification, FreezeMediaMovingToRecycleBinNotification>()
.AddNotificationHandler<MediaSavingNotification, FreezeMediaSavingNotification>();

builder.AddNotificationHandler<UmbracoApplicationStartingNotification, UmbracoApplicationStartingHandler>();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,7 @@ public class MaintenanceModeSettings
{
public bool IsInMaintenanceMode { get; set; }
public bool IsContentFrozen { get; set; }
public StorageMode StorageMode { get; set; }
public int WaitTimeBetweenDatabaseCalls { get; set; } = 30;
}
}
14 changes: 14 additions & 0 deletions Our.Umbraco.MaintenanceMode/Configurations/StorageMode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Our.Umbraco.MaintenanceMode.Configurations
{
public enum StorageMode
{
FileSystem = 0,
Database = 1
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public IActionResult Index()
{

Response.StatusCode = 503;
return View($"/views/{_maintenanceModeService.Settings.TemplateName}.cshtml", _maintenanceModeService.Settings.ViewModel);
return View($"/views/{_maintenanceModeService.Status.Settings.TemplateName}.cshtml", _maintenanceModeService.Status.Settings.ViewModel);
}

public MaintenanceModeController(IUmbracoContextAccessor umbracoContextAccessor, IUmbracoDatabaseFactory databaseFactory, ServiceContext services, AppCaches appCaches, IProfilingLogger profilingLogger, IPublishedUrlProvider publishedUrlProvider, IMaintenanceModeService maintenanceModeService)
Expand Down
16 changes: 16 additions & 0 deletions Our.Umbraco.MaintenanceMode/Factories/IStorageProviderFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Our.Umbraco.MaintenanceMode.Configurations;
using Our.Umbraco.MaintenanceMode.Providers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Our.Umbraco.MaintenanceMode.Factories
{
public interface IStorageProviderFactory
{
StorageMode StorageMode { get; }
IStorageProvider GetProvider();
}
}
45 changes: 45 additions & 0 deletions Our.Umbraco.MaintenanceMode/Factories/StorageProviderFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using System;
using Microsoft.Extensions.Options;
using Our.Umbraco.MaintenanceMode.Configurations;
using Our.Umbraco.MaintenanceMode.Providers;
using Umbraco.Cms.Core.Sync;

namespace Our.Umbraco.MaintenanceMode.Factories
{
public class StorageProviderFactory : IStorageProviderFactory
{
private readonly Configurations.MaintenanceModeSettings _maintenanceModeSettings;
private readonly IServiceProvider _serviceProvider;
private readonly IServerRoleAccessor _serverRoleAccessor;

public StorageProviderFactory(
IOptions<Configurations.MaintenanceModeSettings> maintenanceModeSettings,
IServiceProvider serviceProvider,
IServerRoleAccessor serverRoleAccessor)
{
_maintenanceModeSettings = maintenanceModeSettings.Value;
_serviceProvider = serviceProvider;
_serverRoleAccessor = serverRoleAccessor;
}

//public StorageMode StorageMode => this._maintenanceModeSettings?.StorageMode ?? StorageMode.FileSystem;
public StorageMode StorageMode
{
get
{
return _maintenanceModeSettings?.StorageMode ?? _serverRoleAccessor.CurrentServerRole switch
{
// check server role to see if umbraco thinks it's load balanced
ServerRole.Subscriber or ServerRole.SchedulingPublisher => StorageMode.Database,
_ => StorageMode.FileSystem,
};
}
}

public IStorageProvider GetProvider() => StorageMode switch
{
StorageMode.Database => (IStorageProvider)_serviceProvider.GetService(typeof(DatabaseStorageProvider)),
_ => (IStorageProvider)_serviceProvider.GetService(typeof(FileSystemStorageProvider))
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ public interface IMaintenanceModeService
{
Task ToggleMaintenanceMode(bool maintenanceMode);
Task ToggleContentFreeze(bool isContentFrozen);
bool IsInMaintenanceMode { get; }
bool IsContentFrozen { get; }
MaintenanceModeSettings Settings { get; }
MaintenanceModeStatus Status { get; }
Task SaveSettings(MaintenanceModeSettings settings);
}
Expand Down
7 changes: 7 additions & 0 deletions Our.Umbraco.MaintenanceMode/MaintenanceMode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,12 @@ internal static class MaintenanceMode
/// route use for maintenance requests (random name so as not to clash)
/// </summary>
public const string MaintenanceRoot = "e7f7581c6bcd4113954e163ff18cbaba";

public const string PackageAlias = "Our.Umbraco.MaintenanceMode";

/// <summary>
/// Identifier for accessing record in the DB, currently only setting this at global level (-1) is supported
/// </summary>
public const int MaintenanceConfigRootId = -1;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ public async Task InvokeAsync(HttpContext context, IBackofficeUserAccessor backo
if (backofficeUserAccessor != null)
{
if (_runtimeState.Level == RuntimeLevel.Run &&
_maintenanceModeService.IsInMaintenanceMode)
_maintenanceModeService.Status.IsInMaintenanceMode)
{
// todo figure out how to do this check here
if (!_maintenanceModeService.Settings.AllowBackOfficeUsersThrough
if (!_maintenanceModeService.Status.Settings.AllowBackOfficeUsersThrough
&& IsAuthenticated)
{
context = HandleRequest(context);
Expand All @@ -54,8 +54,6 @@ public async Task InvokeAsync(HttpContext context, IBackofficeUserAccessor backo
}

await _next(context);


}

private bool IsBackOfficeAuthenticated(IBackofficeUserAccessor backofficeUserAccessor) {
Expand Down
29 changes: 29 additions & 0 deletions Our.Umbraco.MaintenanceMode/Migrations/InitialMigration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using Microsoft.Extensions.Options;
using Our.Umbraco.MaintenanceMode.Configurations;
using Our.Umbraco.MaintenanceMode.Models.Schema;
using Umbraco.Cms.Infrastructure.Migrations;

namespace Our.Umbraco.MaintenanceMode.Migrations
{
public sealed class InitialMigration : MigrationBase
{
public const string Key = "maintenance-mode-init";

private readonly MaintenanceModeSettings _maintenanceModeSettings;

public InitialMigration(
IMigrationContext context,
IOptions<MaintenanceModeSettings> maintenanceModeSettings
) : base(context)
{
}

protected override void Migrate()
{
if (!TableExists(nameof(MaintenanceModeSchema)))
{
Create.Table<MaintenanceModeSchema>().Do();
}
}
}
}
23 changes: 23 additions & 0 deletions Our.Umbraco.MaintenanceMode/Models/Schema/MaintenanceModeSchema.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
using System.ComponentModel.DataAnnotations;
using NPoco;
using Umbraco.Cms.Infrastructure.Persistence.DatabaseAnnotations;

namespace Our.Umbraco.MaintenanceMode.Models.Schema
{
[TableName(TableName)]
[PrimaryKey(nameof(Id), AutoIncrement = false)]
[ExplicitColumns]
public class MaintenanceModeSchema
{
public const string TableName = "MaintenanceModeConfig";

[Column(nameof(Id))]
[PrimaryKeyColumn(AutoIncrement = false)]
public int Id { get; set; }

[Column(nameof(Value))]
[SpecialDbType(SpecialDbTypes.NTEXT)]
public string Value { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Migrations;
using Umbraco.Cms.Core.Notifications;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core;
using Umbraco.Cms.Infrastructure.Migrations.Upgrade;
using Umbraco.Cms.Infrastructure.Migrations;
using Our.Umbraco.MaintenanceMode.Migrations;
using Umbraco.Cms.Infrastructure.Scoping;

namespace Our.Umbraco.MaintenanceMode.NotificationHandlers.Application
{
public class UmbracoApplicationStartingHandler : INotificationHandler<UmbracoApplicationStartingNotification>
{
private readonly IScopeProvider _scopeProvider;
private readonly IMigrationPlanExecutor _migrationPlanExecutor;
private readonly IKeyValueService _keyValueService;
private readonly IRuntimeState _runtimeState;

public UmbracoApplicationStartingHandler(IScopeProvider scopeProvider,
IMigrationPlanExecutor migrationPlanExecutor,
IKeyValueService keyValueService,
IRuntimeState runtimeState)
{
_scopeProvider = scopeProvider;
_migrationPlanExecutor = migrationPlanExecutor;
_keyValueService = keyValueService;
_runtimeState = runtimeState;
}

public void Handle(UmbracoApplicationStartingNotification notification)
{
if (_runtimeState.Level < RuntimeLevel.Run) return;

var plan = new MigrationPlan(MaintenanceMode.PackageAlias);

plan.From(string.Empty)
.To<InitialMigration>(InitialMigration.Key);

var upgrader = new Upgrader(plan);

upgrader.Execute(_migrationPlanExecutor, _scopeProvider, _keyValueService);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ public FreezeContentCopyingNotification(IMaintenanceModeService maintenanceModeS

public void Handle(ContentCopyingNotification notification)
{
if (_maintenanceModeService.IsContentFrozen)
if (_maintenanceModeService.Status.IsContentFrozen)
{
if (_backofficeUserAccessor.BackofficeUser == null) return;

if (_maintenanceModeService.Settings.UnfrozenUsers.Contains(_backofficeUserAccessor.BackofficeUser.GetId().ToString())) return;
if (_maintenanceModeService.Status.Settings.UnfrozenUsers.Contains(_backofficeUserAccessor.BackofficeUser.GetId().ToString())) return;


notification.CancelOperation(new EventMessage("Warning", "This site is currently frozen during updates", EventMessageType.Error));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ public FreezeContentDeletingNotification(IMaintenanceModeService maintenanceMode

public void Handle(ContentDeletingNotification notification)
{
if (_maintenanceModeService.IsContentFrozen)
if (_maintenanceModeService.Status.IsContentFrozen)
{
if (_backofficeUserAccessor.BackofficeUser == null) return;

if (_maintenanceModeService.Settings.UnfrozenUsers.Contains(_backofficeUserAccessor.BackofficeUser.GetId().ToString())) return;
if (_maintenanceModeService.Status.Settings.UnfrozenUsers.Contains(_backofficeUserAccessor.BackofficeUser.GetId().ToString())) return;


notification.CancelOperation(new EventMessage("Warning", "This site is currently frozen during updates", EventMessageType.Error));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ public FreezeContentMovingNotification(IMaintenanceModeService maintenanceModeSe

public void Handle(ContentMovingNotification notification)
{
if (_maintenanceModeService.IsContentFrozen)
if (_maintenanceModeService.Status.IsContentFrozen)
{
if (_backofficeUserAccessor.BackofficeUser == null) return;

if (_maintenanceModeService.Settings.UnfrozenUsers.Contains(_backofficeUserAccessor.BackofficeUser.GetId().ToString())) return;
if (_maintenanceModeService.Status.Settings.UnfrozenUsers.Contains(_backofficeUserAccessor.BackofficeUser.GetId().ToString())) return;


notification.CancelOperation(new EventMessage("Warning", "This site is currently frozen during updates", EventMessageType.Error));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ public FreezeContentMovingToRecycleBinNotification(IMaintenanceModeService maint

public void Handle(ContentMovingToRecycleBinNotification notification)
{
if (_maintenanceModeService.IsContentFrozen)
if (_maintenanceModeService.Status.IsContentFrozen)
{
if (_backofficeUserAccessor.BackofficeUser == null) return;

if (_maintenanceModeService.Settings.UnfrozenUsers.Contains(_backofficeUserAccessor.BackofficeUser.GetId().ToString())) return;
if (_maintenanceModeService.Status.Settings.UnfrozenUsers.Contains(_backofficeUserAccessor.BackofficeUser.GetId().ToString())) return;


notification.CancelOperation(new EventMessage("Warning", "This site is currently frozen during updates", EventMessageType.Error));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ public FreezeContentPublishingNotification(IMaintenanceModeService maintenanceMo

public void Handle(ContentPublishingNotification notification)
{
if (_maintenanceModeService.IsContentFrozen)
if (_maintenanceModeService.Status.IsContentFrozen)
{
if (_backofficeUserAccessor.BackofficeUser == null) return;

if (_maintenanceModeService.Settings.UnfrozenUsers.Contains(_backofficeUserAccessor.BackofficeUser.GetId().ToString())) return;
if (_maintenanceModeService.Status.Settings.UnfrozenUsers.Contains(_backofficeUserAccessor.BackofficeUser.GetId().ToString())) return;


notification.CancelOperation(new EventMessage("Warning", "This site is currently frozen during updates", EventMessageType.Error));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ public FreezeContentSavingNotification(IMaintenanceModeService maintenanceModeSe

public void Handle(ContentSavingNotification notification)
{
if (_maintenanceModeService.IsContentFrozen)
if (_maintenanceModeService.Status.IsContentFrozen)
{
if (_backofficeUserAccessor.BackofficeUser == null) return;

if (_maintenanceModeService.Settings.UnfrozenUsers.Contains(_backofficeUserAccessor.BackofficeUser.GetId().ToString())) return;
if (_maintenanceModeService.Status.Settings.UnfrozenUsers.Contains(_backofficeUserAccessor.BackofficeUser.GetId().ToString())) return;


notification.CancelOperation(new EventMessage("Warning", "This site is currently frozen during updates", EventMessageType.Error));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ public FreezeContentUnpublishingNotification(IMaintenanceModeService maintenance

public void Handle(ContentUnpublishingNotification notification)
{
if (_maintenanceModeService.IsContentFrozen)
if (_maintenanceModeService.Status.IsContentFrozen)
{
if (_backofficeUserAccessor.BackofficeUser == null) return;

if (_maintenanceModeService.Settings.UnfrozenUsers.Contains(_backofficeUserAccessor.BackofficeUser.GetId().ToString())) return;
if (_maintenanceModeService.Status.Settings.UnfrozenUsers.Contains(_backofficeUserAccessor.BackofficeUser.GetId().ToString())) return;


notification.CancelOperation(new EventMessage("Warning", "This site is currently frozen during updates", EventMessageType.Error));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ public FreezeMediaDeletingNotification(IMaintenanceModeService maintenanceModeSe

public void Handle(MediaDeletingNotification notification)
{
if (_maintenanceModeService.IsContentFrozen)
if (_maintenanceModeService.Status.IsContentFrozen)
{
if (_backofficeUserAccessor.BackofficeUser == null) return;

if (_maintenanceModeService.Settings.UnfrozenUsers.Contains(_backofficeUserAccessor.BackofficeUser.GetId().ToString())) return;
if (_maintenanceModeService.Status.Settings.UnfrozenUsers.Contains(_backofficeUserAccessor.BackofficeUser.GetId().ToString())) return;


notification.CancelOperation(new EventMessage("Warning", "This site is currently frozen during updates", EventMessageType.Error));
Expand Down
Loading

0 comments on commit 141b692

Please sign in to comment.