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

NEST-326: Maintenance tasks for tenants #54

Merged
merged 31 commits into from
May 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
0974ec6
Adding maintenance task execution capabilities
barthamark Apr 23, 2023
7f2219f
Adding documentation and following open-source guidelines
barthamark Apr 23, 2023
d6dc6ff
Merge remote-tracking branch 'origin/dev' into issue/NEST-326
barthamark Apr 23, 2023
fe285fc
Fixing analyzer violations
barthamark Apr 23, 2023
c8ad7f2
Adding project to solution
barthamark Apr 24, 2023
b2dfc44
Fixing not recognized word
barthamark Apr 24, 2023
f21674b
Fixing markdown linter issues
barthamark Apr 24, 2023
07bcc19
Fixing Readme
barthamark Apr 25, 2023
1273e7a
Fixing analyzer violation
barthamark May 8, 2023
114e6a3
Temporarily disabling maintenance providers
barthamark May 8, 2023
a2ee681
Temporarily commenting out more code
barthamark May 9, 2023
44882f4
Restoring commented code
barthamark May 9, 2023
93b3fe2
Disabling runner temporarily
barthamark May 9, 2023
c9e7766
Readding maintenance runner
barthamark May 9, 2023
16a45fa
Emptying out runner
barthamark May 9, 2023
595edd4
Adding GetScopeAsync line
barthamark May 9, 2023
908bc34
Not using IShellHost
barthamark May 10, 2023
b6a1d56
Separating tenant URL maintenance tasks
barthamark May 13, 2023
69a12ea
Fixing NRE if the config is empty
barthamark May 13, 2023
0c7e71a
Randomly updating a totally irrelevant code line for fun
barthamark May 13, 2023
221ec4b
Disabling analyzer warning
barthamark May 13, 2023
5415694
Disabling analyzer rule
barthamark May 14, 2023
4037d11
Restoring analyzer rules and removing editorconfig
barthamark May 14, 2023
dd01a5d
Minor fixes
barthamark May 15, 2023
4218f3e
Updating main readme
barthamark May 15, 2023
3bc722c
Updating tenant URL updating providers
barthamark May 15, 2023
529b518
Updating SiteUrl logic, adding IsEnabled
barthamark May 16, 2023
920fa73
Adding empty UI test project
barthamark May 16, 2023
fb72004
Adding test
barthamark May 16, 2023
3721107
Fixing test
barthamark May 16, 2023
106f338
Adding the UI test project to the solution
barthamark May 16, 2023
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Lombiq.Tests.UI.Services;
using System.Threading.Tasks;

namespace Lombiq.Hosting.Tenants.Maintenance.Tests.UI.Extensions;

public static class MaintenanceExtensions
{
public static void SetUpdateSiteUrlMaintenanceConfiguration(
this OrchardCoreUITestExecutorConfiguration configuration) => configuration.OrchardCoreConfiguration.BeforeAppStart +=
(_, argumentsBuilder) =>
{
argumentsBuilder
.AddWithValue(
"OrchardCore:Lombiq_Hosting_Tenants_Maintenance:UpdateSiteUrl:IsEnabled",
value: true)
.AddWithValue(
"OrchardCore:Lombiq_Hosting_Tenants_Maintenance:UpdateSiteUrl:DefaultTenantSiteUrl",
value: "https://test.com");

return Task.CompletedTask;
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Atata;
using Lombiq.Tests.UI.Extensions;
using Lombiq.Tests.UI.Services;
using OpenQA.Selenium;
using Shouldly;
using System.Threading.Tasks;

namespace Lombiq.Hosting.Tenants.Maintenance.Tests.UI.Extensions;

public static class TestCaseUITestContextExtensions
{
public static async Task TestSiteUrlMaintenanceExecution(this UITestContext context)
{
await context.SignInDirectlyAsync();
await context.GoToAdminRelativeUrlAsync("/Settings/general");
context.Get(By.Name("ISite.BaseUrl")).GetValue().ShouldBe("https://test.com");
}
}
13 changes: 13 additions & 0 deletions Lombiq.Hosting.Tenants.Maintenance.Tests.UI/License.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Copyright © 2021, [Lombiq Technologies Ltd.](https://lombiq.com)

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

- Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>

<PropertyGroup>
<Title>Lombiq Hosting - Tenants Maintenance for Orchard Core - UI Test Extensions</Title>
<Authors>Lombiq Technologies</Authors>
<Copyright>Copyright © 2021, Lombiq Technologies Ltd.</Copyright>
<Description>Lombiq Hosting - Tenants Maintenance for Orchard Core - UI Test Extensions: Extension methods that test tenants maintenance for Orchard Core.</Description>
<PackageIcon>NuGetIcon.png</PackageIcon>
<PackageTags>OrchardCore;Lombiq;AspNetCore;Multitenancy;SaaS</PackageTags>
<RepositoryUrl>https://github.com/Lombiq/Hosting-Tenants</RepositoryUrl>
<PackageProjectUrl>https://github.com/Lombiq/Hosting-Tenants/blob/dev/Lombiq.Hosting.Tenants.Maintenance.Tests.UI/Readme.md</PackageProjectUrl>
<PackageLicenseFile>License.md</PackageLicenseFile>
</PropertyGroup>

<ItemGroup Condition="'$(NuGetBuild)' != 'true'">
<ProjectReference Include="..\..\..\..\test\Lombiq.UITestingToolbox\Lombiq.Tests.UI\Lombiq.Tests.UI.csproj" />
</ItemGroup>

<ItemGroup Condition="'$(NuGetBuild)' == 'true'">
<PackageReference Include="Lombiq.Tests.UI" Version="6.0.0" />
</ItemGroup>

<ItemGroup>
<None Include="License.md" Pack="true" PackagePath="" />
<None Include="NuGetIcon.png" Pack="true" PackagePath="" />
<None Include="Readme.md" />
</ItemGroup>

</Project>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions Lombiq.Hosting.Tenants.Maintenance.Tests.UI/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Lombiq Hosting - Tenants Maintenance for Orchard Core - UI Test Extensions

## About

Extension methods that test tenants maintenance for Orchard Core, with the help of [Lombiq UI Testing Toolbox for Orchard Core](https://github.com/Lombiq/UI-Testing-Toolbox).

Call these from a UI test project to verify the module's basic features; as seen in [Open-Source Orchard Core Extensions](https://github.com/Lombiq/Open-Source-Orchard-Core-Extensions).
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Lombiq.Hosting.Tenants.Maintenance.Constants;

public static class DocumentCollections
{
public const string Maintenance = nameof(Maintenance);
}
9 changes: 9 additions & 0 deletions Lombiq.Hosting.Tenants.Maintenance/Constants/FeatureNames.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Lombiq.Hosting.Tenants.Maintenance.Constants;

public static class FeatureNames
{
public const string Module = "Lombiq.Hosting.Tenants.Maintenance";
public const string Maintenance = Module;
public const string UpdateSiteUrl = Maintenance + "." + nameof(UpdateSiteUrl);
public const string UpdateShellRequestUrls = Maintenance + "." + nameof(UpdateShellRequestUrls);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using Lombiq.Hosting.Tenants.Maintenance.Models;

namespace Lombiq.Hosting.Tenants.Maintenance.Extensions;

public static class MaintenanceTaskExecutionContextExtensions
{
public static bool WasLatestExecutionSuccessful(this MaintenanceTaskExecutionContext execution) =>
execution.LatestExecution?.IsSuccess == true;
}
25 changes: 25 additions & 0 deletions Lombiq.Hosting.Tenants.Maintenance/Helpers/TenantUrlHelpers.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using OrchardCore.Environment.Shell;

namespace Lombiq.Hosting.Tenants.Maintenance.Helpers;

internal static class TenantUrlHelpers
{
public static string ReplaceTenantName(string url, string tenantName) =>
// Evaluate the tenant name in lowercase as it will be used in the URL or request URL prefixes.
#pragma warning disable CA1308 // Normalize strings to uppercase
url?.Replace("{TenantName}", tenantName.ToLowerInvariant());
#pragma warning restore CA1308 // Normalize strings to uppercase

public static string GetTenantUrl(string urlForDefaultTenant, string urlForAnyTenant, ShellSettings shellSettings)
{
var evaluatedRequestUrl = !string.IsNullOrEmpty(urlForAnyTenant)
? ReplaceTenantName(urlForAnyTenant, shellSettings.Name)
: string.Empty;
var defaultShellRequestUrl =
string.IsNullOrEmpty(urlForDefaultTenant)
? evaluatedRequestUrl
: urlForDefaultTenant;

return shellSettings.IsDefaultShell() ? defaultShellRequestUrl : evaluatedRequestUrl;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using Lombiq.Hosting.Tenants.Maintenance.Constants;
using Lombiq.Hosting.Tenants.Maintenance.Models;
using System;
using YesSql.Indexes;

namespace Lombiq.Hosting.Tenants.Maintenance.Indexes;

public class MaintenanceTaskExecutionIndex : MapIndex
{
public string MaintenanceId { get; set; }
public DateTime ExecutionTimeUtc { get; set; }
public bool IsSuccess { get; set; }
}

public class MaintenanceTaskExecutionIndexProvider : IndexProvider<MaintenanceTaskExecutionData>
{
public MaintenanceTaskExecutionIndexProvider() =>
CollectionName = DocumentCollections.Maintenance;

public override void Describe(DescribeContext<MaintenanceTaskExecutionData> context) =>
context.For<MaintenanceTaskExecutionIndex>()
.Map(execution => new MaintenanceTaskExecutionIndex
{
MaintenanceId = execution.MaintenanceId,
ExecutionTimeUtc = execution.ExecutionTimeUtc,
IsSuccess = execution.IsSuccess,
});
}
13 changes: 13 additions & 0 deletions Lombiq.Hosting.Tenants.Maintenance/License.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Copyright © 2021, [Lombiq Technologies Ltd.](https://lombiq.com)

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

- Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<AddRazorSupportForMvc>true</AddRazorSupportForMvc>
<DefaultItemExcludes>$(DefaultItemExcludes);.git*;node_modules\**;Tests\**</DefaultItemExcludes>
</PropertyGroup>

<PropertyGroup>
<Title>Lombiq Hosting - Tenants Maintenance for Orchard Core</Title>
<Authors>Lombiq Technologies</Authors>
<Copyright>Copyright © 2021, Lombiq Technologies Ltd.</Copyright>
<Description>Lombiq Hosting - Tenants Maintenance for Orchard Core: With the help of this module you can execute maintenance tasks on tenants.</Description>
<PackageIcon>NuGetIcon.png</PackageIcon>
<PackageTags>OrchardCore;Lombiq;AspNetCore;Multitenancy;SaaS;Maintenance</PackageTags>
<RepositoryUrl>https://github.com/Lombiq/Hosting-Tenants</RepositoryUrl>
<PackageProjectUrl>https://github.com/Lombiq/Hosting-Tenants/blob/dev/Lombiq.Hosting.Tenants.Maintenance/Readme.md</PackageProjectUrl>
<PackageLicenseFile>License.md</PackageLicenseFile>
</PropertyGroup>

<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="OrchardCore.Module.Targets" Version="1.5.0" />
<PackageReference Include="OrchardCore.ContentManagement" Version="1.5.0" />
<PackageReference Include="OrchardCore.ContentTypes.Abstractions" Version="1.5.0" />
<PackageReference Include="OrchardCore.DisplayManagement" Version="1.5.0" />
<PackageReference Include="OrchardCore.Settings" Version="1.5.0" />
</ItemGroup>

<ItemGroup>
<None Include="License.md" Pack="true" PackagePath="" />
<None Include="Readme.md" />
<None Include="NuGetIcon.png" Pack="true" PackagePath="" />
</ItemGroup>

<ItemGroup>
<None Remove="node_modules\**" />
<None Remove="Tests\**" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using Lombiq.Hosting.Tenants.Maintenance.Constants;
using Lombiq.Hosting.Tenants.Maintenance.Services;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using OrchardCore.Environment.Shell.Configuration;
using OrchardCore.Modules;

namespace Lombiq.Hosting.Tenants.Maintenance.Maintenance.UpdateShellRequestUrl;

[Feature(FeatureNames.UpdateShellRequestUrls)]
public class Startup : StartupBase
{
private readonly IShellConfiguration _shellConfiguration;

public Startup(IShellConfiguration shellConfiguration) =>
_shellConfiguration = shellConfiguration;

public override void ConfigureServices(IServiceCollection services)
{
var options = new UpdateShellRequestUrlMaintenanceOptions();
var configSection = _shellConfiguration.GetSection("Lombiq_Hosting_Tenants_Maintenance:UpdateShellRequestUrl");
configSection.Bind(options);
services.Configure<UpdateShellRequestUrlMaintenanceOptions>(configSection);

services.AddScoped<IMaintenanceProvider, UpdateShellRequestUrlsMaintenanceProvider>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Lombiq.Hosting.Tenants.Maintenance.Maintenance.UpdateShellRequestUrl;

public class UpdateShellRequestUrlMaintenanceOptions
{
public bool IsEnabled { get; set; }
public string DefaultShellRequestUrl { get; set; }
public string RequestUrl { get; set; }
public string RequestUrlPrefix { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using Lombiq.Hosting.Tenants.Maintenance.Extensions;
using Lombiq.Hosting.Tenants.Maintenance.Helpers;
using Lombiq.Hosting.Tenants.Maintenance.Models;
using Lombiq.Hosting.Tenants.Maintenance.Services;
using Microsoft.Extensions.Options;
using OrchardCore.Environment.Shell;
using System.Threading.Tasks;

namespace Lombiq.Hosting.Tenants.Maintenance.Maintenance.UpdateShellRequestUrl;

public class UpdateShellRequestUrlsMaintenanceProvider : MaintenanceProviderBase
{
private readonly ShellSettings _shellSettings;
private readonly IOptions<UpdateShellRequestUrlMaintenanceOptions> _options;
private readonly IShellSettingsManager _shellSettingsManager;

public UpdateShellRequestUrlsMaintenanceProvider(
ShellSettings shellSettings,
IOptions<UpdateShellRequestUrlMaintenanceOptions> options,
IShellSettingsManager shellSettingsManager)
{
_shellSettings = shellSettings;
_options = options;
_shellSettingsManager = shellSettingsManager;
}

public override Task<bool> ShouldExecuteAsync(MaintenanceTaskExecutionContext context) =>
Task.FromResult(_options.Value.IsEnabled &&
_shellSettings.IsDefaultShell() &&
!context.WasLatestExecutionSuccessful());

public override async Task ExecuteAsync(MaintenanceTaskExecutionContext context)
{
var allShellSettings = await _shellSettingsManager.LoadSettingsAsync();
foreach (var shellSettings in allShellSettings)
{
shellSettings.RequestUrlHost = TenantUrlHelpers.GetTenantUrl(
_options.Value.DefaultShellRequestUrl,
_options.Value.RequestUrl,
shellSettings);
shellSettings.RequestUrlPrefix = TenantUrlHelpers.ReplaceTenantName(
_options.Value.RequestUrlPrefix,
shellSettings.Name);

await _shellSettingsManager.SaveSettingsAsync(shellSettings);
}

context.ReloadShellAfterMaintenanceCompletion = true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using Lombiq.Hosting.Tenants.Maintenance.Constants;
using Lombiq.Hosting.Tenants.Maintenance.Services;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using OrchardCore.Environment.Shell.Configuration;
using OrchardCore.Modules;

namespace Lombiq.Hosting.Tenants.Maintenance.Maintenance.UpdateSiteUrl;

[Feature(FeatureNames.UpdateSiteUrl)]
public class Startup : StartupBase
{
private readonly IShellConfiguration _shellConfiguration;

public Startup(IShellConfiguration shellConfiguration) =>
_shellConfiguration = shellConfiguration;

public override void ConfigureServices(IServiceCollection services)
{
var options = new UpdateSiteUrlMaintenanceOptions();
var configSection = _shellConfiguration.GetSection("Lombiq_Hosting_Tenants_Maintenance:UpdateSiteUrl");
configSection.Bind(options);
services.Configure<UpdateSiteUrlMaintenanceOptions>(configSection);

services.AddScoped<IMaintenanceProvider, UpdateSiteUrlMaintenanceProvider>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Lombiq.Hosting.Tenants.Maintenance.Maintenance.UpdateSiteUrl;

public class UpdateSiteUrlMaintenanceOptions
{
public bool IsEnabled { get; set; }
public string DefaultTenantSiteUrl { get; set; }
public string SiteUrl { get; set; }
}
Loading