From 268e0e72a30faf4c480247d3388740b068d9d324 Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Sat, 2 Apr 2022 09:19:30 -0400 Subject: [PATCH] refactored IUpgradeable to use the migration attribute approach --- .../Infrastructure/DatabaseManager.cs | 82 +++++++++++-------- .../Infrastructure/Interfaces/ISiteUpgrade.cs | 9 ++ .../Infrastructure/Interfaces/IUpgradeable.cs | 11 --- .../Interfaces/SiteUpgradeAttribute.cs | 27 ++++++ .../SiteUpgrade/ExampleUpgrade.cs | 37 ++------- 5 files changed, 87 insertions(+), 79 deletions(-) create mode 100644 Oqtane.Server/Infrastructure/Interfaces/ISiteUpgrade.cs delete mode 100644 Oqtane.Server/Infrastructure/Interfaces/IUpgradeable.cs create mode 100644 Oqtane.Server/Infrastructure/Interfaces/SiteUpgradeAttribute.cs diff --git a/Oqtane.Server/Infrastructure/DatabaseManager.cs b/Oqtane.Server/Infrastructure/DatabaseManager.cs index 8a200e12..063fa353 100644 --- a/Oqtane.Server/Infrastructure/DatabaseManager.cs +++ b/Oqtane.Server/Infrastructure/DatabaseManager.cs @@ -673,43 +673,61 @@ namespace Oqtane.Infrastructure { var result = new Installation { Success = false, Message = string.Empty }; - using (var scope = _serviceScopeFactory.CreateScope()) + // get site upgrades + Dictionary siteupgrades = new Dictionary(); + var assemblies = AppDomain.CurrentDomain.GetOqtaneAssemblies(); + foreach (Assembly assembly in assemblies) { - var aliases = scope.ServiceProvider.GetRequiredService(); - var tenantManager = scope.ServiceProvider.GetRequiredService(); - var sites = scope.ServiceProvider.GetRequiredService(); - - var assemblies = AppDomain.CurrentDomain.GetOqtaneAssemblies(); - foreach (Assembly assembly in assemblies) + foreach (var type in assembly.GetTypes(typeof(ISiteUpgrade))) { - foreach (var type in assembly.GetTypes().Where(item => item.GetInterfaces().Contains(typeof(IUpgradeable)))) + if (Attribute.IsDefined(type, typeof(SiteUpgradeAttribute))) { - var obj = Activator.CreateInstance(type) as IUpgradeable; - if (obj != null) + var attribute = (SiteUpgradeAttribute)Attribute.GetCustomAttribute(type, typeof(SiteUpgradeAttribute)); + siteupgrades.Add(attribute.AliasName + " " + attribute.Version, type); + } + } + } + + // execute site upgrades + if (siteupgrades.Count > 0) + { + using (var scope = _serviceScopeFactory.CreateScope()) + { + var aliases = scope.ServiceProvider.GetRequiredService(); + var tenantManager = scope.ServiceProvider.GetRequiredService(); + var sites = scope.ServiceProvider.GetRequiredService(); + var logger = scope.ServiceProvider.GetRequiredService(); + + foreach (var alias in aliases.GetAliases().ToList().Where(item => item.IsDefault)) + { + foreach (var upgrade in siteupgrades) { - foreach (var alias in aliases.GetAliases().ToList().Where(item => item.IsDefault)) + if (upgrade.Key.StartsWith(alias.Name, StringComparison.OrdinalIgnoreCase)) { - var versions = obj.GetVersions(alias); - if (!string.IsNullOrEmpty(versions)) + tenantManager.SetTenant(alias.TenantId); + var site = sites.GetSites().FirstOrDefault(item => item.SiteId == alias.SiteId); + if (site != null) { - tenantManager.SetTenant(alias.TenantId); - var site = sites.GetSites().FirstOrDefault(item => item.SiteId == alias.SiteId); - if (site != null) + var version = upgrade.Key.Split(' ').Last(); + if (string.IsNullOrEmpty(site.Version) || Version.Parse(version) > Version.Parse(site.Version)) { - foreach (var version in versions.Split(',', StringSplitOptions.RemoveEmptyEntries)) + try { - if (string.IsNullOrEmpty(site.Version) || Version.Parse(version) > Version.Parse(site.Version)) + var obj = Activator.CreateInstance(upgrade.Value) as ISiteUpgrade; + if (obj.Upgrade(site, alias)) { - if (obj.Upgrade(alias, version)) - { - site.Version = version; - sites.UpdateSite(site); - } - else - { - result.Message = "An Error Occurred Executing IUpgradeable Interface For " + alias.Name + " For Version " + version; - } + site.Version = version; + sites.UpdateSite(site); + logger.Log(alias.SiteId, Shared.LogLevel.Information, "Site Upgrade", LogFunction.Other, "Site Upgraded Successfully To Version {version} For {Alias}", version, alias.Name); } + else + { + logger.Log(alias.SiteId, Shared.LogLevel.Error, "Site Upgrade", LogFunction.Other, "Site Could Not Be Upgraded Using IUpgradeable Interface {Type} For {Alias} And Version {Version}", upgrade.Value, alias.Name, version); + } + } + catch (Exception ex) + { + logger.Log(alias.SiteId, Shared.LogLevel.Error, "Site Upgrade", LogFunction.Other, "An Error Occurred Executing IUpgradeable Interface {Type} For {Alias} And Version {Version} {Error}", upgrade.Value, alias.Name, version, ex.Message); } } } @@ -719,15 +737,7 @@ namespace Oqtane.Infrastructure } } - if (string.IsNullOrEmpty(result.Message)) - { - result.Success = true; - } - else - { - _filelogger.LogError(Utilities.LogMessage(this, result.Message)); - } - + result.Success = true; return result; } diff --git a/Oqtane.Server/Infrastructure/Interfaces/ISiteUpgrade.cs b/Oqtane.Server/Infrastructure/Interfaces/ISiteUpgrade.cs new file mode 100644 index 00000000..262d5147 --- /dev/null +++ b/Oqtane.Server/Infrastructure/Interfaces/ISiteUpgrade.cs @@ -0,0 +1,9 @@ +using Oqtane.Models; + +namespace Oqtane.Infrastructure +{ + public interface ISiteUpgrade + { + bool Upgrade(Site site, Alias alias); + } +} diff --git a/Oqtane.Server/Infrastructure/Interfaces/IUpgradeable.cs b/Oqtane.Server/Infrastructure/Interfaces/IUpgradeable.cs deleted file mode 100644 index 607fed92..00000000 --- a/Oqtane.Server/Infrastructure/Interfaces/IUpgradeable.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Oqtane.Models; - -namespace Oqtane.Infrastructure -{ - public interface IUpgradeable - { - string GetVersions(Alias alias); - - bool Upgrade(Alias alias, string version); - } -} diff --git a/Oqtane.Server/Infrastructure/Interfaces/SiteUpgradeAttribute.cs b/Oqtane.Server/Infrastructure/Interfaces/SiteUpgradeAttribute.cs new file mode 100644 index 00000000..30441e47 --- /dev/null +++ b/Oqtane.Server/Infrastructure/Interfaces/SiteUpgradeAttribute.cs @@ -0,0 +1,27 @@ +using System; + +namespace Oqtane.Infrastructure +{ + [AttributeUsage(AttributeTargets.Class)] + public class SiteUpgradeAttribute : Attribute + { + private string aliasname; + private string version; + + public SiteUpgradeAttribute(string AliasName, string Version) + { + aliasname = AliasName; + version = Version; + } + + public virtual string AliasName + { + get { return aliasname; } + } + + public virtual string Version + { + get { return version; } + } + } +} diff --git a/Oqtane.Server/Infrastructure/SiteUpgrade/ExampleUpgrade.cs b/Oqtane.Server/Infrastructure/SiteUpgrade/ExampleUpgrade.cs index 02d072db..dde44221 100644 --- a/Oqtane.Server/Infrastructure/SiteUpgrade/ExampleUpgrade.cs +++ b/Oqtane.Server/Infrastructure/SiteUpgrade/ExampleUpgrade.cs @@ -1,41 +1,14 @@ using Oqtane.Models; -using Oqtane.Documentation; namespace Oqtane.Infrastructure { - [PrivateApi("Mark Site-Template classes as private, since it's not very useful in the public docs")] - public class ExampleUpgrade : IUpgradeable + [SiteUpgrade("localhost:44357", "01.00.00")] + public class ExampleUpgrade : ISiteUpgrade { - string IUpgradeable.GetVersions(Alias alias) + bool ISiteUpgrade.Upgrade(Site site, Alias alias) { - var versions = ""; - switch (alias.Name) - { - case "localhost:44357": - // return the comma delimited list of official release versions for the specific site - versions = "1.0.0"; - break; - } - return versions; - } - - bool IUpgradeable.Upgrade(Alias alias, string version) - { - bool success = true; - switch (alias.Name) - { - case "localhost:44357": - // the version cases should match the list of versions returned above - switch (version) - { - case "1.0.0": - // execute some version-specific upgrade logic for the site here such as adding pages, modules, content, etc... - success = true; - break; - } - break; - } - return success; + // execute some version-specific upgrade logic for the site here such as adding pages, modules, content, etc... + return true; } } }