Skip to content

Commit

Permalink
Merge pull request #427 from sbwalker/master
Browse files Browse the repository at this point in the history
Added ability to execute version specific code during framework upgrade (removed ApplicationVersion table and replaced with Version field on Tenant table), updated version number to 0.9.0 and renamed install scripts to match - this will be a baseline release which will be upgradeable
  • Loading branch information
sbwalker authored May 1, 2020
2 parents 03592da + 7c6dc6d commit e7a2eaa
Show file tree
Hide file tree
Showing 23 changed files with 229 additions and 144 deletions.
2 changes: 1 addition & 1 deletion Oqtane.Client/Oqtane.Client.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<LangVersion>7.3</LangVersion>
<RazorLangVersion>3.0</RazorLangVersion>
<Configurations>Debug;Release</Configurations>
<Version>0.0.9</Version>
<Version>0.9.0</Version>
<Product>Oqtane</Product>
<Authors>Shaun Walker</Authors>
<Company>.NET Foundation</Company>
Expand Down
4 changes: 2 additions & 2 deletions Oqtane.Client/Services/Interfaces/ISettingService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ namespace Oqtane.Services
{
public interface ISettingService
{
Task<Dictionary<string, string>> GetHostSettingsAsync();
Task<Dictionary<string, string>> GetTenantSettingsAsync();

Task UpdateHostSettingsAsync(Dictionary<string, string> hostSettings);
Task UpdateTenantSettingsAsync(Dictionary<string, string> tenantSettings);

Task<Dictionary<string, string>> GetSiteSettingsAsync(int siteId);

Expand Down
8 changes: 4 additions & 4 deletions Oqtane.Client/Services/SettingService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ private string Apiurl
get { return CreateApiUrl(_siteState.Alias, _navigationManager.Uri, "Setting"); }
}

public async Task<Dictionary<string, string>> GetHostSettingsAsync()
public async Task<Dictionary<string, string>> GetTenantSettingsAsync()
{
return await GetSettingsAsync(EntityNames.Host, -1);
return await GetSettingsAsync(EntityNames.Tenant, -1);
}

public async Task UpdateHostSettingsAsync(Dictionary<string, string> hostSettings)
public async Task UpdateTenantSettingsAsync(Dictionary<string, string> tenantSettings)
{
await UpdateSettingsAsync(hostSettings, EntityNames.Host, -1);
await UpdateSettingsAsync(tenantSettings, EntityNames.Tenant, -1);
}

public async Task<Dictionary<string, string>> GetSiteSettingsAsync(int siteId)
Expand Down
2 changes: 1 addition & 1 deletion Oqtane.Package/Oqtane.Framework.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>Oqtane.Framework</id>
<version>0.0.9</version>
<version>0.9.0</version>
<authors>Shaun Walker</authors>
<owners>.NET Foundation</owners>
<title>Oqtane Framework</title>
Expand Down
2 changes: 1 addition & 1 deletion Oqtane.Server/Controllers/SettingController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ private bool IsAuthorized(string entityName, int entityId, string permissionName
}
switch (entityName)
{
case EntityNames.Host:
case EntityNames.Tenant:
authorized = User.IsInRole(Constants.HostRole);
break;
case EntityNames.Site:
Expand Down
63 changes: 36 additions & 27 deletions Oqtane.Server/Infrastructure/DatabaseManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ public class DatabaseManager : IDatabaseManager
private readonly IServiceScopeFactory _serviceScopeFactory;
private readonly IMemoryCache _cache;


public DatabaseManager(IConfigurationRoot config, IServiceScopeFactory serviceScopeFactory, IMemoryCache cache)
{
_config = config;
Expand Down Expand Up @@ -217,7 +216,6 @@ private Installation MigrateMaster(InstallConfig install)

if (result.Success)
{
CreateApplicationVersion(install.ConnectionString);
UpdateConnectionString(install.ConnectionString);
}
}
Expand Down Expand Up @@ -277,21 +275,43 @@ private Installation MigrateTenants(InstallConfig install)
{
var result = new Installation { Success = false, Message = string.Empty };

using (var db = new InstallationContext(NormalizeConnectionString(_config.GetConnectionString(SettingKeys.ConnectionStringKey))))
string[] versions = Constants.ReleaseVersions.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

using (var scope = _serviceScopeFactory.CreateScope())
{
foreach (var tenant in db.Tenant.ToList())
var upgrades = scope.ServiceProvider.GetRequiredService<IUpgradeManager>();

using (var db = new InstallationContext(NormalizeConnectionString(_config.GetConnectionString(SettingKeys.ConnectionStringKey))))
{
var upgradeConfig = DeployChanges.To.SqlDatabase(NormalizeConnectionString(tenant.DBConnectionString))
.WithScriptsEmbeddedInAssembly(Assembly.GetExecutingAssembly(), s => s.Contains("Tenant") && s.EndsWith(".sql",StringComparison.OrdinalIgnoreCase));

var upgrade = upgradeConfig.Build();
if (upgrade.IsUpgradeRequired())
foreach (var tenant in db.Tenant.ToList())
{
var upgradeResult = upgrade.PerformUpgrade();
result.Success = upgradeResult.Successful;
if (!result.Success)
var upgradeConfig = DeployChanges.To.SqlDatabase(NormalizeConnectionString(tenant.DBConnectionString))
.WithScriptsEmbeddedInAssembly(Assembly.GetExecutingAssembly(), s => s.Contains("Tenant.") && s.EndsWith(".sql", StringComparison.OrdinalIgnoreCase));

var upgrade = upgradeConfig.Build();
if (upgrade.IsUpgradeRequired())
{
var upgradeResult = upgrade.PerformUpgrade();
result.Success = upgradeResult.Successful;
if (!result.Success)
{
result.Message = upgradeResult.Error.Message;
}
}

// execute any version specific upgrade logic
string version = tenant.Version;
int index = Array.FindIndex(versions, item => item == version);
if (index != (versions.Length - 1))
{
result.Message = upgradeResult.Error.Message;
if (index == -1) index = 0;
for (int i = index; i < versions.Length; i++)
{
upgrades.Upgrade(tenant, versions[i]);
}
tenant.Version = versions[versions.Length - 1];
db.Entry(tenant).State = EntityState.Modified;
db.SaveChanges();
}
}
}
Expand Down Expand Up @@ -460,6 +480,9 @@ private Installation CreateSite(InstallConfig install)
aliases.UpdateAlias(alias);
}

tenant.Version = Constants.Version;
tenants.UpdateTenant(tenant);

log.Log(site.SiteId, LogLevel.Trace, this, LogFunction.Create, "Site Created {Site}", site);
}
}
Expand All @@ -469,20 +492,6 @@ private Installation CreateSite(InstallConfig install)

return result;
}

private void CreateApplicationVersion(string connectionString)
{
using (var db = new InstallationContext(NormalizeConnectionString(connectionString)))
{
var version = db.ApplicationVersion.FirstOrDefault(item => item.Version == Constants.Version);
if (version == null)
{
version = new ApplicationVersion { Version = Constants.Version, CreatedOn = DateTime.UtcNow };
db.ApplicationVersion.Add(version);
db.SaveChanges();
}
}
}

private string NormalizeConnectionString(string connectionString)
{
Expand Down
9 changes: 9 additions & 0 deletions Oqtane.Server/Infrastructure/Interfaces/IUpgradeManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using Oqtane.Models;

namespace Oqtane.Infrastructure
{
public interface IUpgradeManager
{
void Upgrade(Tenant tenant, string version);
}
}
93 changes: 93 additions & 0 deletions Oqtane.Server/Infrastructure/UpgradeManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
using Microsoft.Extensions.DependencyInjection;
using Oqtane.Extensions;
using Oqtane.Models;
using Oqtane.Repository;
using Oqtane.Shared;
using System.Collections.Generic;
using System.Linq;

namespace Oqtane.Infrastructure
{
public class UpgradeManager : IUpgradeManager
{
private readonly IAliasRepository _aliases;
private readonly IServiceScopeFactory _serviceScopeFactory;

public UpgradeManager(IAliasRepository aliases, IServiceScopeFactory serviceScopeFactory)
{
_aliases = aliases;
_serviceScopeFactory = serviceScopeFactory;
}

public void Upgrade(Tenant tenant, string version)
{
// core framework upgrade logic - note that you can check if current tenant is Master if you only want to execute logic once
var pageTemplates = new List<PageTemplate>();

switch (version)
{
case "0.9.0":
// add a page to all existing sites on upgrade

//pageTemplates.Add(new PageTemplate
//{
// Name = "Test",
// Parent = "",
// Path = "test",
// Icon = Icons.Badge,
// IsNavigation = true,
// IsPersonalizable = false,
// EditMode = false,
// PagePermissions = new List<Permission>
// {
// new Permission(PermissionNames.View, Constants.AdminRole, true),
// new Permission(PermissionNames.View, Constants.AllUsersRole, true),
// new Permission(PermissionNames.Edit, Constants.AdminRole, true)
// }.EncodePermissions(),
// PageTemplateModules = new List<PageTemplateModule>
// {
// new PageTemplateModule
// {
// ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Login.Index).ToModuleDefinitionName(), Title = "Test", Pane = "Content",
// ModulePermissions = new List<Permission>
// {
// new Permission(PermissionNames.View, Constants.AdminRole, true),
// new Permission(PermissionNames.View, Constants.AllUsersRole, true),
// new Permission(PermissionNames.Edit, Constants.AdminRole, true)
// }.EncodePermissions(),
// Content = ""
// }
// }
//});
CreateSitePages(tenant, pageTemplates);
break;
}
}

private void CreateSitePages(Tenant tenant, List<PageTemplate> pageTemplates)
{
if (pageTemplates.Count != 0)
{
var processed = new List<Site>();
foreach (Alias alias in _aliases.GetAliases().Where(item => item.TenantId == tenant.TenantId))
{
if (!processed.Exists(item => item.SiteId == alias.SiteId))
{
using (var scope = _serviceScopeFactory.CreateScope())
{
var siteState = scope.ServiceProvider.GetRequiredService<SiteState>();
siteState.Alias = alias;
var sites = scope.ServiceProvider.GetRequiredService<ISiteRepository>();
var site = sites.GetSite(alias.SiteId);
if (site != null)
{
sites.CreatePages(site, pageTemplates);
}
processed.Add(site);
}
}
}
}
}
}
}
8 changes: 3 additions & 5 deletions Oqtane.Server/Oqtane.Server.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<TargetFramework>netcoreapp3.1</TargetFramework>
<LangVersion>7.3</LangVersion>
<Configurations>Debug;Release</Configurations>
<Version>0.0.9</Version>
<Version>0.9.0</Version>
<Product>Oqtane</Product>
<Authors>Shaun Walker</Authors>
<Company>.NET Foundation</Company>
Expand All @@ -20,10 +20,8 @@
<ItemGroup>
<EmbeddedResource Include="Modules\HtmlText\Scripts\HtmlText.1.0.0.sql" />
<EmbeddedResource Include="Modules\HtmlText\Scripts\HtmlText.Uninstall.sql" />
<EmbeddedResource Include="Scripts\Master.00.00.00.sql" />
<EmbeddedResource Include="Scripts\Master.00.00.01.sql" />
<EmbeddedResource Include="Scripts\Tenant.00.00.00.sql" />
<EmbeddedResource Include="Scripts\Tenant.00.00.01.sql" />
<EmbeddedResource Include="Scripts\Master.0.9.0.sql" />
<EmbeddedResource Include="Scripts\Tenant.0.9.0.sql" />
</ItemGroup>

<ItemGroup>
Expand Down
2 changes: 0 additions & 2 deletions Oqtane.Server/Repository/Context/InstallationContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,5 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
public virtual DbSet<Tenant> Tenant { get; set; }
public virtual DbSet<ModuleDefinition> ModuleDefinition { get; set; }
public virtual DbSet<Job> Job { get; set; }

public virtual DbSet<ApplicationVersion> ApplicationVersion { get; set; }
}
}
1 change: 1 addition & 0 deletions Oqtane.Server/Repository/Interfaces/ISiteRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ public interface ISiteRepository
Site UpdateSite(Site site);
Site GetSite(int siteId);
void DeleteSite(int siteId);
void CreatePages(Site site, List<PageTemplate> pageTemplates);
}
}
2 changes: 1 addition & 1 deletion Oqtane.Server/Repository/SiteRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -731,7 +731,7 @@ private void CreateSite(Site site)
CreatePages(site, CreateAdminPages());
}

private void CreatePages(Site site, List<PageTemplate> pageTemplates)
public void CreatePages(Site site, List<PageTemplate> pageTemplates)
{
List<ModuleDefinition> moduledefinitions = _moduleDefinitionRepository.GetModuleDefinitions(site.SiteId).ToList();
foreach (PageTemplate pagetemplate in pageTemplates)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ CREATE TABLE [dbo].[Tenant](
[TenantId] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](100) NOT NULL,
[DBConnectionString] [nvarchar](1024) NOT NULL,
[Version] [nvarchar](50) NULL,
[CreatedBy] [nvarchar](256) NOT NULL,
[CreatedOn] [datetime] NOT NULL,
[ModifiedBy] [nvarchar](256) NOT NULL,
Expand Down Expand Up @@ -91,17 +92,6 @@ CREATE TABLE [dbo].[JobLog] (
)
GO

CREATE TABLE [dbo].[ApplicationVersion](
[ApplicationVersionId] [int] IDENTITY(1,1) NOT NULL,
[Version] [nvarchar](50) NOT NULL,
[CreatedOn] [datetime] NOT NULL
CONSTRAINT [PK_ApplicationVersion] PRIMARY KEY CLUSTERED
(
[ApplicationVersionId] ASC
)
)
GO

/*
Create foreign key relationships
Expand Down
5 changes: 0 additions & 5 deletions Oqtane.Server/Scripts/Master.00.00.01.sql

This file was deleted.

Loading

0 comments on commit e7a2eaa

Please sign in to comment.