diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs index 4254b5479f..474b13be14 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs @@ -289,7 +289,7 @@ public class AbpApplicationConfigurationAppService : ApplicationService, IAbpApp Values = new Dictionary() }; - var settingDefinitions = _settingDefinitionManager.GetAll().Where(x => x.IsVisibleToClients); + var settingDefinitions = (await _settingDefinitionManager.GetAllAsync()).Where(x => x.IsVisibleToClients); var settingValues = await _settingProvider.GetAllAsync(settingDefinitions.Select(x => x.Name).ToArray()); diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/AbpSettingOptions.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/AbpSettingOptions.cs index 127ab7b970..c8a06736b6 100644 --- a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/AbpSettingOptions.cs +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/AbpSettingOptions.cs @@ -1,4 +1,5 @@ -using Volo.Abp.Collections; +using System.Collections.Generic; +using Volo.Abp.Collections; namespace Volo.Abp.Settings; @@ -8,9 +9,12 @@ public class AbpSettingOptions public ITypeList ValueProviders { get; } + public HashSet DeletedSettings { get; } + public AbpSettingOptions() { DefinitionProviders = new TypeList(); ValueProviders = new TypeList(); + DeletedSettings = new HashSet(); } } diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/IDynamicSettingDefinitionStore.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/IDynamicSettingDefinitionStore.cs new file mode 100644 index 0000000000..17f5029cd1 --- /dev/null +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/IDynamicSettingDefinitionStore.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using JetBrains.Annotations; + +namespace Volo.Abp.Settings; + +public interface IDynamicSettingDefinitionStore +{ + Task GetAsync([NotNull] string name); + + Task> GetAllAsync(); + + Task GetOrNullAsync([NotNull] string name); +} diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingDefinitionManager.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingDefinitionManager.cs index 865fe5557a..d21a2f8b4c 100644 --- a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingDefinitionManager.cs +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingDefinitionManager.cs @@ -1,14 +1,17 @@ using System.Collections.Generic; +using System.Threading.Tasks; using JetBrains.Annotations; namespace Volo.Abp.Settings; public interface ISettingDefinitionManager { - [NotNull] - SettingDefinition Get([NotNull] string name); + [ItemNotNull] + Task GetAsync([NotNull] string name); - IReadOnlyList GetAll(); + [ItemNotNull] + Task> GetAllAsync(); - SettingDefinition GetOrNull(string name); + [ItemCanBeNull] + Task GetOrNullAsync([NotNull] string name); } diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/IStaticSettingDefinitionStore.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/IStaticSettingDefinitionStore.cs new file mode 100644 index 0000000000..a5aae07533 --- /dev/null +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/IStaticSettingDefinitionStore.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using JetBrains.Annotations; + +namespace Volo.Abp.Settings; + +public interface IStaticSettingDefinitionStore +{ + Task GetAsync([NotNull] string name); + + Task> GetAllAsync(); + + Task GetOrNullAsync([NotNull] string name); +} diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/NullDynamicSettingDefinitionStore.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/NullDynamicSettingDefinitionStore.cs new file mode 100644 index 0000000000..f814f071af --- /dev/null +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/NullDynamicSettingDefinitionStore.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Settings; + +public class NullDynamicSettingDefinitionStore : IDynamicSettingDefinitionStore, ISingletonDependency +{ + private readonly static Task CachedSettingResult = Task.FromResult((SettingDefinition)null); + + private readonly static Task> CachedSettingsResult = Task.FromResult((IReadOnlyList)Array.Empty().ToImmutableList()); + + public Task GetAsync(string name) + { + return CachedSettingResult; + } + + public Task> GetAllAsync() + { + return CachedSettingsResult; + } + + public Task GetOrNullAsync(string name) + { + return CachedSettingResult; + } +} diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingDefinitionManager.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingDefinitionManager.cs index ed285422b3..25dd30912d 100644 --- a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingDefinitionManager.cs +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingDefinitionManager.cs @@ -1,72 +1,50 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; +using System.Threading.Tasks; using Volo.Abp.DependencyInjection; namespace Volo.Abp.Settings; public class SettingDefinitionManager : ISettingDefinitionManager, ISingletonDependency { - protected Lazy> SettingDefinitions { get; } + protected readonly IStaticSettingDefinitionStore StaticStore; + protected readonly IDynamicSettingDefinitionStore DynamicStore; - protected AbpSettingOptions Options { get; } - - protected IServiceProvider ServiceProvider { get; } - - public SettingDefinitionManager( - IOptions options, - IServiceProvider serviceProvider) + public SettingDefinitionManager(IStaticSettingDefinitionStore staticStore, IDynamicSettingDefinitionStore dynamicStore) { - ServiceProvider = serviceProvider; - Options = options.Value; - - SettingDefinitions = new Lazy>(CreateSettingDefinitions, true); + StaticStore = staticStore; + DynamicStore = dynamicStore; } - public virtual SettingDefinition Get(string name) + public virtual async Task GetAsync(string name) { - Check.NotNull(name, nameof(name)); - - var setting = GetOrNull(name); - - if (setting == null) + var permission = await GetOrNullAsync(name); + if (permission == null) { - throw new AbpException("Undefined setting: " + name); + throw new AbpException("Undefined Template: " + name); } - return setting; + return permission; } - public virtual IReadOnlyList GetAll() + public virtual async Task GetOrNullAsync(string name) { - return SettingDefinitions.Value.Values.ToImmutableList(); - } + Check.NotNull(name, nameof(name)); - public virtual SettingDefinition GetOrNull(string name) - { - return SettingDefinitions.Value.GetOrDefault(name); + return await StaticStore.GetOrNullAsync(name) ?? await DynamicStore.GetOrNullAsync(name); } - protected virtual IDictionary CreateSettingDefinitions() + public virtual async Task> GetAllAsync() { - var settings = new Dictionary(); + var staticTemplates = await StaticStore.GetAllAsync(); + var staticTemplateNames = staticTemplates + .Select(p => p.Name) + .ToImmutableHashSet(); - using (var scope = ServiceProvider.CreateScope()) - { - var providers = Options - .DefinitionProviders - .Select(p => scope.ServiceProvider.GetRequiredService(p) as ISettingDefinitionProvider) - .ToList(); - - foreach (var provider in providers) - { - provider.Define(new SettingDefinitionContext(settings)); - } - } + var dynamicTemplates = await DynamicStore.GetAllAsync(); - return settings; + /* We prefer static Templates over dynamics */ + return staticTemplates.Concat(dynamicTemplates.Where(d => !staticTemplateNames.Contains(d.Name))).ToImmutableList(); } } diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingProvider.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingProvider.cs index 01791bef00..6adf4b4ca6 100644 --- a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingProvider.cs +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingProvider.cs @@ -23,7 +23,7 @@ public class SettingProvider : ISettingProvider, ITransientDependency public virtual async Task GetOrNullAsync(string name) { - var setting = SettingDefinitionManager.Get(name); + var setting = await SettingDefinitionManager.GetAsync(name); var providers = Enumerable .Reverse(SettingValueProviderManager.Providers); @@ -46,7 +46,7 @@ public class SettingProvider : ISettingProvider, ITransientDependency public virtual async Task> GetAllAsync(string[] names) { var result = new Dictionary(); - var settingDefinitions = SettingDefinitionManager.GetAll().Where(x => names.Contains(x.Name)).ToList(); + var settingDefinitions = (await SettingDefinitionManager.GetAllAsync()).Where(x => names.Contains(x.Name)).ToList(); foreach (var definition in settingDefinitions) { @@ -85,7 +85,7 @@ public class SettingProvider : ISettingProvider, ITransientDependency public virtual async Task> GetAllAsync() { var settingValues = new List(); - var settingDefinitions = SettingDefinitionManager.GetAll(); + var settingDefinitions = await SettingDefinitionManager.GetAllAsync(); foreach (var setting in settingDefinitions) { @@ -110,4 +110,4 @@ public class SettingProvider : ISettingProvider, ITransientDependency return null; } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/StaticSettingDefinitionStore.cs b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/StaticSettingDefinitionStore.cs new file mode 100644 index 0000000000..2421e4f877 --- /dev/null +++ b/framework/src/Volo.Abp.Settings/Volo/Abp/Settings/StaticSettingDefinitionStore.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Settings; + +public class StaticSettingDefinitionStore : IStaticSettingDefinitionStore, ISingletonDependency +{ + protected Lazy> SettingDefinitions { get; } + + protected AbpSettingOptions Options { get; } + + protected IServiceProvider ServiceProvider { get; } + + public StaticSettingDefinitionStore(IOptions options, IServiceProvider serviceProvider) + { + ServiceProvider = serviceProvider; + Options = options.Value; + + SettingDefinitions = new Lazy>(CreateSettingDefinitions, true); + } + + public virtual async Task GetAsync(string name) + { + Check.NotNull(name, nameof(name)); + + var setting = await GetOrNullAsync(name); + + if (setting == null) + { + throw new AbpException("Undefined setting: " + name); + } + + return setting; + } + + public virtual Task> GetAllAsync() + { + return Task.FromResult>(SettingDefinitions.Value.Values.ToImmutableList()); + } + + public virtual Task GetOrNullAsync(string name) + { + return Task.FromResult(SettingDefinitions.Value.GetOrDefault(name)); + } + + protected virtual IDictionary CreateSettingDefinitions() + { + var settings = new Dictionary(); + + using (var scope = ServiceProvider.CreateScope()) + { + var providers = Options + .DefinitionProviders + .Select(p => scope.ServiceProvider.GetRequiredService(p) as ISettingDefinitionProvider) + .ToList(); + + foreach (var provider in providers) + { + provider.Define(new SettingDefinitionContext(settings)); + } + } + + return settings; + } +} diff --git a/framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/NullIDynamicTemplateDefinitionStore.cs b/framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/NullIDynamicTemplateDefinitionStore.cs index 326b525c0e..115f46b2ac 100644 --- a/framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/NullIDynamicTemplateDefinitionStore.cs +++ b/framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/NullIDynamicTemplateDefinitionStore.cs @@ -10,7 +10,7 @@ public class NullIDynamicTemplateDefinitionStore : IDynamicTemplateDefinitionSto { private readonly static Task CachedTemplateResult = Task.FromResult((TemplateDefinition)null); - private readonly static Task> CachedFeaturesResult = Task.FromResult((IReadOnlyList)Array.Empty().ToImmutableList()); + private readonly static Task> CachedTemplatesResult = Task.FromResult((IReadOnlyList)Array.Empty().ToImmutableList()); public Task GetAsync(string name) { @@ -19,7 +19,7 @@ public class NullIDynamicTemplateDefinitionStore : IDynamicTemplateDefinitionSto public Task> GetAllAsync() { - return CachedFeaturesResult; + return CachedTemplatesResult; } public Task GetOrNullAsync(string name) diff --git a/modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/Migrations/20210209024820_init.cs b/modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/Migrations/20210209024820_init.cs deleted file mode 100644 index 12af73bf16..0000000000 --- a/modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/Migrations/20210209024820_init.cs +++ /dev/null @@ -1,484 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -namespace Volo.Abp.SettingManagement.DemoApp.Migrations; - -public partial class init : Migration -{ - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "AbpClaimTypes", - columns: table => new { - Id = table.Column(type: "uniqueidentifier", nullable: false), - Name = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), - Required = table.Column(type: "bit", nullable: false), - IsStatic = table.Column(type: "bit", nullable: false), - Regex = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true), - RegexDescription = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: true), - Description = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), - ValueType = table.Column(type: "int", nullable: false), - ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true), - ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AbpClaimTypes", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "AbpLinkUsers", - columns: table => new { - Id = table.Column(type: "uniqueidentifier", nullable: false), - SourceUserId = table.Column(type: "uniqueidentifier", nullable: false), - SourceTenantId = table.Column(type: "uniqueidentifier", nullable: true), - TargetUserId = table.Column(type: "uniqueidentifier", nullable: false), - TargetTenantId = table.Column(type: "uniqueidentifier", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AbpLinkUsers", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "AbpOrganizationUnits", - columns: table => new { - Id = table.Column(type: "uniqueidentifier", nullable: false), - TenantId = table.Column(type: "uniqueidentifier", nullable: true), - ParentId = table.Column(type: "uniqueidentifier", nullable: true), - Code = table.Column(type: "nvarchar(95)", maxLength: 95, nullable: false), - DisplayName = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), - ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true), - ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: true), - CreationTime = table.Column(type: "datetime2", nullable: false), - CreatorId = table.Column(type: "uniqueidentifier", nullable: true), - LastModificationTime = table.Column(type: "datetime2", nullable: true), - LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), - IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), - DeleterId = table.Column(type: "uniqueidentifier", nullable: true), - DeletionTime = table.Column(type: "datetime2", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AbpOrganizationUnits", x => x.Id); - table.ForeignKey( - name: "FK_AbpOrganizationUnits_AbpOrganizationUnits_ParentId", - column: x => x.ParentId, - principalTable: "AbpOrganizationUnits", - principalColumn: "Id", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "AbpPermissionGrants", - columns: table => new { - Id = table.Column(type: "uniqueidentifier", nullable: false), - TenantId = table.Column(type: "uniqueidentifier", nullable: true), - Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), - ProviderName = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - ProviderKey = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_AbpPermissionGrants", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "AbpRoles", - columns: table => new { - Id = table.Column(type: "uniqueidentifier", nullable: false), - TenantId = table.Column(type: "uniqueidentifier", nullable: true), - Name = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), - NormalizedName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), - IsDefault = table.Column(type: "bit", nullable: false), - IsStatic = table.Column(type: "bit", nullable: false), - IsPublic = table.Column(type: "bit", nullable: false), - ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true), - ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AbpRoles", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "AbpSecurityLogs", - columns: table => new { - Id = table.Column(type: "uniqueidentifier", nullable: false), - TenantId = table.Column(type: "uniqueidentifier", nullable: true), - ApplicationName = table.Column(type: "nvarchar(96)", maxLength: 96, nullable: true), - Identity = table.Column(type: "nvarchar(96)", maxLength: 96, nullable: true), - Action = table.Column(type: "nvarchar(96)", maxLength: 96, nullable: true), - UserId = table.Column(type: "uniqueidentifier", nullable: true), - UserName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), - TenantName = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), - ClientId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), - CorrelationId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), - ClientIpAddress = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), - BrowserInfo = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true), - CreationTime = table.Column(type: "datetime2", nullable: false), - ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true), - ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AbpSecurityLogs", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "AbpSettings", - columns: table => new { - Id = table.Column(type: "uniqueidentifier", nullable: false), - Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), - Value = table.Column(type: "nvarchar(2048)", maxLength: 2048, nullable: false), - ProviderName = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), - ProviderKey = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AbpSettings", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "AbpUsers", - columns: table => new { - Id = table.Column(type: "uniqueidentifier", nullable: false), - TenantId = table.Column(type: "uniqueidentifier", nullable: true), - UserName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), - NormalizedUserName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), - Name = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), - Surname = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), - Email = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), - NormalizedEmail = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), - EmailConfirmed = table.Column(type: "bit", nullable: false, defaultValue: false), - PasswordHash = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), - SecurityStamp = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), - IsExternal = table.Column(type: "bit", nullable: false, defaultValue: false), - PhoneNumber = table.Column(type: "nvarchar(16)", maxLength: 16, nullable: true), - PhoneNumberConfirmed = table.Column(type: "bit", nullable: false, defaultValue: false), - TwoFactorEnabled = table.Column(type: "bit", nullable: false, defaultValue: false), - LockoutEnd = table.Column(type: "datetimeoffset", nullable: true), - LockoutEnabled = table.Column(type: "bit", nullable: false, defaultValue: false), - AccessFailedCount = table.Column(type: "int", nullable: false, defaultValue: 0), - ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true), - ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: true), - CreationTime = table.Column(type: "datetime2", nullable: false), - CreatorId = table.Column(type: "uniqueidentifier", nullable: true), - LastModificationTime = table.Column(type: "datetime2", nullable: true), - LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), - IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), - DeleterId = table.Column(type: "uniqueidentifier", nullable: true), - DeletionTime = table.Column(type: "datetime2", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AbpUsers", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "AbpOrganizationUnitRoles", - columns: table => new { - RoleId = table.Column(type: "uniqueidentifier", nullable: false), - OrganizationUnitId = table.Column(type: "uniqueidentifier", nullable: false), - TenantId = table.Column(type: "uniqueidentifier", nullable: true), - CreationTime = table.Column(type: "datetime2", nullable: false), - CreatorId = table.Column(type: "uniqueidentifier", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AbpOrganizationUnitRoles", x => new { x.OrganizationUnitId, x.RoleId }); - table.ForeignKey( - name: "FK_AbpOrganizationUnitRoles_AbpOrganizationUnits_OrganizationUnitId", - column: x => x.OrganizationUnitId, - principalTable: "AbpOrganizationUnits", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_AbpOrganizationUnitRoles_AbpRoles_RoleId", - column: x => x.RoleId, - principalTable: "AbpRoles", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "AbpRoleClaims", - columns: table => new { - Id = table.Column(type: "uniqueidentifier", nullable: false), - RoleId = table.Column(type: "uniqueidentifier", nullable: false), - TenantId = table.Column(type: "uniqueidentifier", nullable: true), - ClaimType = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), - ClaimValue = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AbpRoleClaims", x => x.Id); - table.ForeignKey( - name: "FK_AbpRoleClaims_AbpRoles_RoleId", - column: x => x.RoleId, - principalTable: "AbpRoles", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "AbpUserClaims", - columns: table => new { - Id = table.Column(type: "uniqueidentifier", nullable: false), - UserId = table.Column(type: "uniqueidentifier", nullable: false), - TenantId = table.Column(type: "uniqueidentifier", nullable: true), - ClaimType = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), - ClaimValue = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AbpUserClaims", x => x.Id); - table.ForeignKey( - name: "FK_AbpUserClaims_AbpUsers_UserId", - column: x => x.UserId, - principalTable: "AbpUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "AbpUserLogins", - columns: table => new { - UserId = table.Column(type: "uniqueidentifier", nullable: false), - LoginProvider = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - TenantId = table.Column(type: "uniqueidentifier", nullable: true), - ProviderKey = table.Column(type: "nvarchar(196)", maxLength: 196, nullable: false), - ProviderDisplayName = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AbpUserLogins", x => new { x.UserId, x.LoginProvider }); - table.ForeignKey( - name: "FK_AbpUserLogins_AbpUsers_UserId", - column: x => x.UserId, - principalTable: "AbpUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "AbpUserOrganizationUnits", - columns: table => new { - UserId = table.Column(type: "uniqueidentifier", nullable: false), - OrganizationUnitId = table.Column(type: "uniqueidentifier", nullable: false), - TenantId = table.Column(type: "uniqueidentifier", nullable: true), - CreationTime = table.Column(type: "datetime2", nullable: false), - CreatorId = table.Column(type: "uniqueidentifier", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AbpUserOrganizationUnits", x => new { x.OrganizationUnitId, x.UserId }); - table.ForeignKey( - name: "FK_AbpUserOrganizationUnits_AbpOrganizationUnits_OrganizationUnitId", - column: x => x.OrganizationUnitId, - principalTable: "AbpOrganizationUnits", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_AbpUserOrganizationUnits_AbpUsers_UserId", - column: x => x.UserId, - principalTable: "AbpUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "AbpUserRoles", - columns: table => new { - UserId = table.Column(type: "uniqueidentifier", nullable: false), - RoleId = table.Column(type: "uniqueidentifier", nullable: false), - TenantId = table.Column(type: "uniqueidentifier", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AbpUserRoles", x => new { x.UserId, x.RoleId }); - table.ForeignKey( - name: "FK_AbpUserRoles_AbpRoles_RoleId", - column: x => x.RoleId, - principalTable: "AbpRoles", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_AbpUserRoles_AbpUsers_UserId", - column: x => x.UserId, - principalTable: "AbpUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "AbpUserTokens", - columns: table => new { - UserId = table.Column(type: "uniqueidentifier", nullable: false), - LoginProvider = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), - TenantId = table.Column(type: "uniqueidentifier", nullable: true), - Value = table.Column(type: "nvarchar(max)", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AbpUserTokens", x => new { x.UserId, x.LoginProvider, x.Name }); - table.ForeignKey( - name: "FK_AbpUserTokens_AbpUsers_UserId", - column: x => x.UserId, - principalTable: "AbpUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateIndex( - name: "IX_AbpLinkUsers_SourceUserId_SourceTenantId_TargetUserId_TargetTenantId", - table: "AbpLinkUsers", - columns: new[] { "SourceUserId", "SourceTenantId", "TargetUserId", "TargetTenantId" }, - unique: true, - filter: "[SourceTenantId] IS NOT NULL AND [TargetTenantId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_AbpOrganizationUnitRoles_RoleId_OrganizationUnitId", - table: "AbpOrganizationUnitRoles", - columns: new[] { "RoleId", "OrganizationUnitId" }); - - migrationBuilder.CreateIndex( - name: "IX_AbpOrganizationUnits_Code", - table: "AbpOrganizationUnits", - column: "Code"); - - migrationBuilder.CreateIndex( - name: "IX_AbpOrganizationUnits_ParentId", - table: "AbpOrganizationUnits", - column: "ParentId"); - - migrationBuilder.CreateIndex( - name: "IX_AbpPermissionGrants_Name_ProviderName_ProviderKey", - table: "AbpPermissionGrants", - columns: new[] { "Name", "ProviderName", "ProviderKey" }); - - migrationBuilder.CreateIndex( - name: "IX_AbpRoleClaims_RoleId", - table: "AbpRoleClaims", - column: "RoleId"); - - migrationBuilder.CreateIndex( - name: "IX_AbpRoles_NormalizedName", - table: "AbpRoles", - column: "NormalizedName"); - - migrationBuilder.CreateIndex( - name: "IX_AbpSecurityLogs_TenantId_Action", - table: "AbpSecurityLogs", - columns: new[] { "TenantId", "Action" }); - - migrationBuilder.CreateIndex( - name: "IX_AbpSecurityLogs_TenantId_ApplicationName", - table: "AbpSecurityLogs", - columns: new[] { "TenantId", "ApplicationName" }); - - migrationBuilder.CreateIndex( - name: "IX_AbpSecurityLogs_TenantId_Identity", - table: "AbpSecurityLogs", - columns: new[] { "TenantId", "Identity" }); - - migrationBuilder.CreateIndex( - name: "IX_AbpSecurityLogs_TenantId_UserId", - table: "AbpSecurityLogs", - columns: new[] { "TenantId", "UserId" }); - - migrationBuilder.CreateIndex( - name: "IX_AbpSettings_Name_ProviderName_ProviderKey", - table: "AbpSettings", - columns: new[] { "Name", "ProviderName", "ProviderKey" }); - - migrationBuilder.CreateIndex( - name: "IX_AbpUserClaims_UserId", - table: "AbpUserClaims", - column: "UserId"); - - migrationBuilder.CreateIndex( - name: "IX_AbpUserLogins_LoginProvider_ProviderKey", - table: "AbpUserLogins", - columns: new[] { "LoginProvider", "ProviderKey" }); - - migrationBuilder.CreateIndex( - name: "IX_AbpUserOrganizationUnits_UserId_OrganizationUnitId", - table: "AbpUserOrganizationUnits", - columns: new[] { "UserId", "OrganizationUnitId" }); - - migrationBuilder.CreateIndex( - name: "IX_AbpUserRoles_RoleId_UserId", - table: "AbpUserRoles", - columns: new[] { "RoleId", "UserId" }); - - migrationBuilder.CreateIndex( - name: "IX_AbpUsers_Email", - table: "AbpUsers", - column: "Email"); - - migrationBuilder.CreateIndex( - name: "IX_AbpUsers_NormalizedEmail", - table: "AbpUsers", - column: "NormalizedEmail"); - - migrationBuilder.CreateIndex( - name: "IX_AbpUsers_NormalizedUserName", - table: "AbpUsers", - column: "NormalizedUserName"); - - migrationBuilder.CreateIndex( - name: "IX_AbpUsers_UserName", - table: "AbpUsers", - column: "UserName"); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "AbpClaimTypes"); - - migrationBuilder.DropTable( - name: "AbpLinkUsers"); - - migrationBuilder.DropTable( - name: "AbpOrganizationUnitRoles"); - - migrationBuilder.DropTable( - name: "AbpPermissionGrants"); - - migrationBuilder.DropTable( - name: "AbpRoleClaims"); - - migrationBuilder.DropTable( - name: "AbpSecurityLogs"); - - migrationBuilder.DropTable( - name: "AbpSettings"); - - migrationBuilder.DropTable( - name: "AbpUserClaims"); - - migrationBuilder.DropTable( - name: "AbpUserLogins"); - - migrationBuilder.DropTable( - name: "AbpUserOrganizationUnits"); - - migrationBuilder.DropTable( - name: "AbpUserRoles"); - - migrationBuilder.DropTable( - name: "AbpUserTokens"); - - migrationBuilder.DropTable( - name: "AbpOrganizationUnits"); - - migrationBuilder.DropTable( - name: "AbpRoles"); - - migrationBuilder.DropTable( - name: "AbpUsers"); - } -} diff --git a/modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/Migrations/20210209024820_init.Designer.cs b/modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/Migrations/20230626120017_Initial.Designer.cs similarity index 78% rename from modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/Migrations/20210209024820_init.Designer.cs rename to modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/Migrations/20230626120017_Initial.Designer.cs index 913e150570..be9eac74b7 100644 --- a/modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/Migrations/20210209024820_init.Designer.cs +++ b/modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/Migrations/20230626120017_Initial.Designer.cs @@ -8,20 +8,24 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Volo.Abp.EntityFrameworkCore; using Volo.Abp.SettingManagement.DemoApp; +#nullable disable + namespace Volo.Abp.SettingManagement.DemoApp.Migrations { [DbContext(typeof(DemoAppDbContext))] - [Migration("20210209024820_init")] - partial class init + [Migration("20230626120017_Initial")] + partial class Initial { + /// protected override void BuildTargetModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder - .UseIdentityColumns() .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer) - .HasAnnotation("Relational:MaxIdentifierLength", 128) - .HasAnnotation("ProductVersion", "5.0.2"); + .HasAnnotation("ProductVersion", "7.0.1") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b => { @@ -67,7 +71,7 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations b.HasKey("Id"); - b.ToTable("AbpClaimTypes"); + b.ToTable("AbpClaimTypes", (string)null); }); modelBuilder.Entity("Volo.Abp.Identity.IdentityLinkUser", b => @@ -94,7 +98,7 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations .IsUnique() .HasFilter("[SourceTenantId] IS NOT NULL AND [TargetTenantId] IS NOT NULL"); - b.ToTable("AbpLinkUsers"); + b.ToTable("AbpLinkUsers", (string)null); }); modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b => @@ -109,6 +113,9 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations .HasColumnType("nvarchar(40)") .HasColumnName("ConcurrencyStamp"); + b.Property("EntityVersion") + .HasColumnType("int"); + b.Property("ExtraProperties") .HasColumnType("nvarchar(max)") .HasColumnName("ExtraProperties"); @@ -143,7 +150,7 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations b.HasIndex("NormalizedName"); - b.ToTable("AbpRoles"); + b.ToTable("AbpRoles", (string)null); }); modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => @@ -171,7 +178,7 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations b.HasIndex("RoleId"); - b.ToTable("AbpRoleClaims"); + b.ToTable("AbpRoleClaims", (string)null); }); modelBuilder.Entity("Volo.Abp.Identity.IdentitySecurityLog", b => @@ -246,7 +253,7 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations b.HasIndex("TenantId", "UserId"); - b.ToTable("AbpSecurityLogs"); + b.ToTable("AbpSecurityLogs", (string)null); }); modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => @@ -295,10 +302,17 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations .HasDefaultValue(false) .HasColumnName("EmailConfirmed"); + b.Property("EntityVersion") + .HasColumnType("int"); + b.Property("ExtraProperties") .HasColumnType("nvarchar(max)") .HasColumnName("ExtraProperties"); + b.Property("IsActive") + .HasColumnType("bit") + .HasColumnName("IsActive"); + b.Property("IsDeleted") .ValueGeneratedOnAdd() .HasColumnType("bit") @@ -319,6 +333,9 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations .HasColumnType("uniqueidentifier") .HasColumnName("LastModifierId"); + b.Property("LastPasswordChangeTime") + .HasColumnType("datetimeoffset"); + b.Property("LockoutEnabled") .ValueGeneratedOnAdd() .HasColumnType("bit") @@ -367,6 +384,9 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations .HasColumnType("nvarchar(256)") .HasColumnName("SecurityStamp"); + b.Property("ShouldChangePasswordOnNextLogin") + .HasColumnType("bit"); + b.Property("Surname") .HasMaxLength(64) .HasColumnType("nvarchar(64)") @@ -398,7 +418,7 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations b.HasIndex("UserName"); - b.ToTable("AbpUsers"); + b.ToTable("AbpUsers", (string)null); }); modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => @@ -426,7 +446,34 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations b.HasIndex("UserId"); - b.ToTable("AbpUserClaims"); + b.ToTable("AbpUserClaims", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserDelegation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("EndTime") + .HasColumnType("datetime2"); + + b.Property("SourceUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartTime") + .HasColumnType("datetime2"); + + b.Property("TargetUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("AbpUserDelegations", (string)null); }); modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => @@ -455,7 +502,7 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations b.HasIndex("LoginProvider", "ProviderKey"); - b.ToTable("AbpUserLogins"); + b.ToTable("AbpUserLogins", (string)null); }); modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b => @@ -482,7 +529,7 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations b.HasIndex("UserId", "OrganizationUnitId"); - b.ToTable("AbpUserOrganizationUnits"); + b.ToTable("AbpUserOrganizationUnits", (string)null); }); modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => @@ -501,7 +548,7 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations b.HasIndex("RoleId", "UserId"); - b.ToTable("AbpUserRoles"); + b.ToTable("AbpUserRoles", (string)null); }); modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => @@ -526,7 +573,7 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations b.HasKey("UserId", "LoginProvider", "Name"); - b.ToTable("AbpUserTokens"); + b.ToTable("AbpUserTokens", (string)null); }); modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => @@ -569,6 +616,9 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations .HasColumnType("nvarchar(128)") .HasColumnName("DisplayName"); + b.Property("EntityVersion") + .HasColumnType("int"); + b.Property("ExtraProperties") .HasColumnType("nvarchar(max)") .HasColumnName("ExtraProperties"); @@ -600,7 +650,7 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations b.HasIndex("ParentId"); - b.ToTable("AbpOrganizationUnits"); + b.ToTable("AbpOrganizationUnits", (string)null); }); modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b => @@ -627,7 +677,60 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations b.HasIndex("RoleId", "OrganizationUnitId"); - b.ToTable("AbpOrganizationUnitRoles"); + b.ToTable("AbpOrganizationUnitRoles", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionDefinitionRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("GroupName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("IsEnabled") + .HasColumnType("bit"); + + b.Property("MultiTenancySide") + .HasColumnType("tinyint"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ParentName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Providers") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("StateCheckers") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("GroupName"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("AbpPermissions", (string)null); }); modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGrant", b => @@ -657,9 +760,39 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations b.HasKey("Id"); - b.HasIndex("Name", "ProviderName", "ProviderKey"); + b.HasIndex("TenantId", "Name", "ProviderName", "ProviderKey") + .IsUnique() + .HasFilter("[TenantId] IS NOT NULL"); + + b.ToTable("AbpPermissionGrants", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGroupDefinitionRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); - b.ToTable("AbpPermissionGrants"); + b.ToTable("AbpPermissionGroups", (string)null); }); modelBuilder.Entity("Volo.Abp.SettingManagement.Setting", b => @@ -688,9 +821,58 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations b.HasKey("Id"); - b.HasIndex("Name", "ProviderName", "ProviderKey"); + b.HasIndex("Name", "ProviderName", "ProviderKey") + .IsUnique() + .HasFilter("[ProviderName] IS NOT NULL AND [ProviderKey] IS NOT NULL"); + + b.ToTable("AbpSettings", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.SettingManagement.SettingDefinitionRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("DefaultValue") + .HasColumnType("nvarchar(max)"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsEncrypted") + .HasColumnType("bit"); + + b.Property("IsInherited") + .HasColumnType("bit"); + + b.Property("IsVisibleToClients") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Providers") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); - b.ToTable("AbpSettings"); + b.ToTable("AbpSettingDefinitionRecords", (string)null); }); modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => diff --git a/modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/Migrations/20230626120017_Initial.cs b/modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/Migrations/20230626120017_Initial.cs new file mode 100644 index 0000000000..c12b52422d --- /dev/null +++ b/modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/Migrations/20230626120017_Initial.cs @@ -0,0 +1,619 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Volo.Abp.SettingManagement.DemoApp.Migrations +{ + /// + public partial class Initial : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "AbpClaimTypes", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + Name = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + Required = table.Column(type: "bit", nullable: false), + IsStatic = table.Column(type: "bit", nullable: false), + Regex = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true), + RegexDescription = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: true), + Description = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + ValueType = table.Column(type: "int", nullable: false), + ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true), + ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AbpClaimTypes", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AbpLinkUsers", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + SourceUserId = table.Column(type: "uniqueidentifier", nullable: false), + SourceTenantId = table.Column(type: "uniqueidentifier", nullable: true), + TargetUserId = table.Column(type: "uniqueidentifier", nullable: false), + TargetTenantId = table.Column(type: "uniqueidentifier", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AbpLinkUsers", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AbpOrganizationUnits", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + ParentId = table.Column(type: "uniqueidentifier", nullable: true), + Code = table.Column(type: "nvarchar(95)", maxLength: 95, nullable: false), + DisplayName = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + EntityVersion = table.Column(type: "int", nullable: false), + ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true), + ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: true), + CreationTime = table.Column(type: "datetime2", nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: true), + LastModificationTime = table.Column(type: "datetime2", nullable: true), + LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), + IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), + DeleterId = table.Column(type: "uniqueidentifier", nullable: true), + DeletionTime = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AbpOrganizationUnits", x => x.Id); + table.ForeignKey( + name: "FK_AbpOrganizationUnits_AbpOrganizationUnits_ParentId", + column: x => x.ParentId, + principalTable: "AbpOrganizationUnits", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "AbpPermissionGrants", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + ProviderName = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + ProviderKey = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AbpPermissionGrants", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AbpPermissionGroups", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + DisplayName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AbpPermissionGroups", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AbpPermissions", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + GroupName = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + ParentName = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: true), + DisplayName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + IsEnabled = table.Column(type: "bit", nullable: false), + MultiTenancySide = table.Column(type: "tinyint", nullable: false), + Providers = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: true), + StateCheckers = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AbpPermissions", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AbpRoles", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + Name = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + NormalizedName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + IsDefault = table.Column(type: "bit", nullable: false), + IsStatic = table.Column(type: "bit", nullable: false), + IsPublic = table.Column(type: "bit", nullable: false), + EntityVersion = table.Column(type: "int", nullable: false), + ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true), + ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AbpRoles", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AbpSecurityLogs", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + ApplicationName = table.Column(type: "nvarchar(96)", maxLength: 96, nullable: true), + Identity = table.Column(type: "nvarchar(96)", maxLength: 96, nullable: true), + Action = table.Column(type: "nvarchar(96)", maxLength: 96, nullable: true), + UserId = table.Column(type: "uniqueidentifier", nullable: true), + UserName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + TenantName = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + ClientId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + CorrelationId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + ClientIpAddress = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + BrowserInfo = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true), + CreationTime = table.Column(type: "datetime2", nullable: false), + ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true), + ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AbpSecurityLogs", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AbpSettingDefinitionRecords", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + DisplayName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + Description = table.Column(type: "nvarchar(max)", nullable: true), + DefaultValue = table.Column(type: "nvarchar(max)", nullable: true), + IsVisibleToClients = table.Column(type: "bit", nullable: false), + Providers = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: true), + IsInherited = table.Column(type: "bit", nullable: false), + IsEncrypted = table.Column(type: "bit", nullable: false), + ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AbpSettingDefinitionRecords", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AbpSettings", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + Value = table.Column(type: "nvarchar(2048)", maxLength: 2048, nullable: false), + ProviderName = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + ProviderKey = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AbpSettings", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AbpUserDelegations", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + SourceUserId = table.Column(type: "uniqueidentifier", nullable: false), + TargetUserId = table.Column(type: "uniqueidentifier", nullable: false), + StartTime = table.Column(type: "datetime2", nullable: false), + EndTime = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AbpUserDelegations", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AbpUsers", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + UserName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + NormalizedUserName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + Name = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + Surname = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + Email = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + NormalizedEmail = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + EmailConfirmed = table.Column(type: "bit", nullable: false, defaultValue: false), + PasswordHash = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + SecurityStamp = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + IsExternal = table.Column(type: "bit", nullable: false, defaultValue: false), + PhoneNumber = table.Column(type: "nvarchar(16)", maxLength: 16, nullable: true), + PhoneNumberConfirmed = table.Column(type: "bit", nullable: false, defaultValue: false), + IsActive = table.Column(type: "bit", nullable: false), + TwoFactorEnabled = table.Column(type: "bit", nullable: false, defaultValue: false), + LockoutEnd = table.Column(type: "datetimeoffset", nullable: true), + LockoutEnabled = table.Column(type: "bit", nullable: false, defaultValue: false), + AccessFailedCount = table.Column(type: "int", nullable: false, defaultValue: 0), + ShouldChangePasswordOnNextLogin = table.Column(type: "bit", nullable: false), + EntityVersion = table.Column(type: "int", nullable: false), + LastPasswordChangeTime = table.Column(type: "datetimeoffset", nullable: true), + ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true), + ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: true), + CreationTime = table.Column(type: "datetime2", nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: true), + LastModificationTime = table.Column(type: "datetime2", nullable: true), + LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), + IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), + DeleterId = table.Column(type: "uniqueidentifier", nullable: true), + DeletionTime = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AbpUsers", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AbpOrganizationUnitRoles", + columns: table => new + { + RoleId = table.Column(type: "uniqueidentifier", nullable: false), + OrganizationUnitId = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + CreationTime = table.Column(type: "datetime2", nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AbpOrganizationUnitRoles", x => new { x.OrganizationUnitId, x.RoleId }); + table.ForeignKey( + name: "FK_AbpOrganizationUnitRoles_AbpOrganizationUnits_OrganizationUnitId", + column: x => x.OrganizationUnitId, + principalTable: "AbpOrganizationUnits", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_AbpOrganizationUnitRoles_AbpRoles_RoleId", + column: x => x.RoleId, + principalTable: "AbpRoles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AbpRoleClaims", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + RoleId = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + ClaimType = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + ClaimValue = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AbpRoleClaims", x => x.Id); + table.ForeignKey( + name: "FK_AbpRoleClaims_AbpRoles_RoleId", + column: x => x.RoleId, + principalTable: "AbpRoles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AbpUserClaims", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + UserId = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + ClaimType = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + ClaimValue = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AbpUserClaims", x => x.Id); + table.ForeignKey( + name: "FK_AbpUserClaims_AbpUsers_UserId", + column: x => x.UserId, + principalTable: "AbpUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AbpUserLogins", + columns: table => new + { + UserId = table.Column(type: "uniqueidentifier", nullable: false), + LoginProvider = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + ProviderKey = table.Column(type: "nvarchar(196)", maxLength: 196, nullable: false), + ProviderDisplayName = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AbpUserLogins", x => new { x.UserId, x.LoginProvider }); + table.ForeignKey( + name: "FK_AbpUserLogins_AbpUsers_UserId", + column: x => x.UserId, + principalTable: "AbpUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AbpUserOrganizationUnits", + columns: table => new + { + UserId = table.Column(type: "uniqueidentifier", nullable: false), + OrganizationUnitId = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + CreationTime = table.Column(type: "datetime2", nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AbpUserOrganizationUnits", x => new { x.OrganizationUnitId, x.UserId }); + table.ForeignKey( + name: "FK_AbpUserOrganizationUnits_AbpOrganizationUnits_OrganizationUnitId", + column: x => x.OrganizationUnitId, + principalTable: "AbpOrganizationUnits", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_AbpUserOrganizationUnits_AbpUsers_UserId", + column: x => x.UserId, + principalTable: "AbpUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AbpUserRoles", + columns: table => new + { + UserId = table.Column(type: "uniqueidentifier", nullable: false), + RoleId = table.Column(type: "uniqueidentifier", nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AbpUserRoles", x => new { x.UserId, x.RoleId }); + table.ForeignKey( + name: "FK_AbpUserRoles_AbpRoles_RoleId", + column: x => x.RoleId, + principalTable: "AbpRoles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_AbpUserRoles_AbpUsers_UserId", + column: x => x.UserId, + principalTable: "AbpUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AbpUserTokens", + columns: table => new + { + UserId = table.Column(type: "uniqueidentifier", nullable: false), + LoginProvider = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + Value = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AbpUserTokens", x => new { x.UserId, x.LoginProvider, x.Name }); + table.ForeignKey( + name: "FK_AbpUserTokens_AbpUsers_UserId", + column: x => x.UserId, + principalTable: "AbpUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_AbpLinkUsers_SourceUserId_SourceTenantId_TargetUserId_TargetTenantId", + table: "AbpLinkUsers", + columns: new[] { "SourceUserId", "SourceTenantId", "TargetUserId", "TargetTenantId" }, + unique: true, + filter: "[SourceTenantId] IS NOT NULL AND [TargetTenantId] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_AbpOrganizationUnitRoles_RoleId_OrganizationUnitId", + table: "AbpOrganizationUnitRoles", + columns: new[] { "RoleId", "OrganizationUnitId" }); + + migrationBuilder.CreateIndex( + name: "IX_AbpOrganizationUnits_Code", + table: "AbpOrganizationUnits", + column: "Code"); + + migrationBuilder.CreateIndex( + name: "IX_AbpOrganizationUnits_ParentId", + table: "AbpOrganizationUnits", + column: "ParentId"); + + migrationBuilder.CreateIndex( + name: "IX_AbpPermissionGrants_TenantId_Name_ProviderName_ProviderKey", + table: "AbpPermissionGrants", + columns: new[] { "TenantId", "Name", "ProviderName", "ProviderKey" }, + unique: true, + filter: "[TenantId] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_AbpPermissionGroups_Name", + table: "AbpPermissionGroups", + column: "Name", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_AbpPermissions_GroupName", + table: "AbpPermissions", + column: "GroupName"); + + migrationBuilder.CreateIndex( + name: "IX_AbpPermissions_Name", + table: "AbpPermissions", + column: "Name", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_AbpRoleClaims_RoleId", + table: "AbpRoleClaims", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "IX_AbpRoles_NormalizedName", + table: "AbpRoles", + column: "NormalizedName"); + + migrationBuilder.CreateIndex( + name: "IX_AbpSecurityLogs_TenantId_Action", + table: "AbpSecurityLogs", + columns: new[] { "TenantId", "Action" }); + + migrationBuilder.CreateIndex( + name: "IX_AbpSecurityLogs_TenantId_ApplicationName", + table: "AbpSecurityLogs", + columns: new[] { "TenantId", "ApplicationName" }); + + migrationBuilder.CreateIndex( + name: "IX_AbpSecurityLogs_TenantId_Identity", + table: "AbpSecurityLogs", + columns: new[] { "TenantId", "Identity" }); + + migrationBuilder.CreateIndex( + name: "IX_AbpSecurityLogs_TenantId_UserId", + table: "AbpSecurityLogs", + columns: new[] { "TenantId", "UserId" }); + + migrationBuilder.CreateIndex( + name: "IX_AbpSettingDefinitionRecords_Name", + table: "AbpSettingDefinitionRecords", + column: "Name", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_AbpSettings_Name_ProviderName_ProviderKey", + table: "AbpSettings", + columns: new[] { "Name", "ProviderName", "ProviderKey" }, + unique: true, + filter: "[ProviderName] IS NOT NULL AND [ProviderKey] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_AbpUserClaims_UserId", + table: "AbpUserClaims", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_AbpUserLogins_LoginProvider_ProviderKey", + table: "AbpUserLogins", + columns: new[] { "LoginProvider", "ProviderKey" }); + + migrationBuilder.CreateIndex( + name: "IX_AbpUserOrganizationUnits_UserId_OrganizationUnitId", + table: "AbpUserOrganizationUnits", + columns: new[] { "UserId", "OrganizationUnitId" }); + + migrationBuilder.CreateIndex( + name: "IX_AbpUserRoles_RoleId_UserId", + table: "AbpUserRoles", + columns: new[] { "RoleId", "UserId" }); + + migrationBuilder.CreateIndex( + name: "IX_AbpUsers_Email", + table: "AbpUsers", + column: "Email"); + + migrationBuilder.CreateIndex( + name: "IX_AbpUsers_NormalizedEmail", + table: "AbpUsers", + column: "NormalizedEmail"); + + migrationBuilder.CreateIndex( + name: "IX_AbpUsers_NormalizedUserName", + table: "AbpUsers", + column: "NormalizedUserName"); + + migrationBuilder.CreateIndex( + name: "IX_AbpUsers_UserName", + table: "AbpUsers", + column: "UserName"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "AbpClaimTypes"); + + migrationBuilder.DropTable( + name: "AbpLinkUsers"); + + migrationBuilder.DropTable( + name: "AbpOrganizationUnitRoles"); + + migrationBuilder.DropTable( + name: "AbpPermissionGrants"); + + migrationBuilder.DropTable( + name: "AbpPermissionGroups"); + + migrationBuilder.DropTable( + name: "AbpPermissions"); + + migrationBuilder.DropTable( + name: "AbpRoleClaims"); + + migrationBuilder.DropTable( + name: "AbpSecurityLogs"); + + migrationBuilder.DropTable( + name: "AbpSettingDefinitionRecords"); + + migrationBuilder.DropTable( + name: "AbpSettings"); + + migrationBuilder.DropTable( + name: "AbpUserClaims"); + + migrationBuilder.DropTable( + name: "AbpUserDelegations"); + + migrationBuilder.DropTable( + name: "AbpUserLogins"); + + migrationBuilder.DropTable( + name: "AbpUserOrganizationUnits"); + + migrationBuilder.DropTable( + name: "AbpUserRoles"); + + migrationBuilder.DropTable( + name: "AbpUserTokens"); + + migrationBuilder.DropTable( + name: "AbpOrganizationUnits"); + + migrationBuilder.DropTable( + name: "AbpRoles"); + + migrationBuilder.DropTable( + name: "AbpUsers"); + } + } +} diff --git a/modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/Migrations/DemoAppDbContextModelSnapshot.cs b/modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/Migrations/DemoAppDbContextModelSnapshot.cs index 72995d69a7..98c6fb2dcf 100644 --- a/modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/Migrations/DemoAppDbContextModelSnapshot.cs +++ b/modules/setting-management/app/Volo.Abp.SettingManagement.DemoApp/Migrations/DemoAppDbContextModelSnapshot.cs @@ -7,6 +7,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Volo.Abp.EntityFrameworkCore; using Volo.Abp.SettingManagement.DemoApp; +#nullable disable + namespace Volo.Abp.SettingManagement.DemoApp.Migrations { [DbContext(typeof(DemoAppDbContext))] @@ -16,10 +18,11 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations { #pragma warning disable 612, 618 modelBuilder - .UseIdentityColumns() .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer) - .HasAnnotation("Relational:MaxIdentifierLength", 128) - .HasAnnotation("ProductVersion", "5.0.2"); + .HasAnnotation("ProductVersion", "7.0.1") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b => { @@ -65,7 +68,7 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations b.HasKey("Id"); - b.ToTable("AbpClaimTypes"); + b.ToTable("AbpClaimTypes", (string)null); }); modelBuilder.Entity("Volo.Abp.Identity.IdentityLinkUser", b => @@ -92,7 +95,7 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations .IsUnique() .HasFilter("[SourceTenantId] IS NOT NULL AND [TargetTenantId] IS NOT NULL"); - b.ToTable("AbpLinkUsers"); + b.ToTable("AbpLinkUsers", (string)null); }); modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b => @@ -107,6 +110,9 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations .HasColumnType("nvarchar(40)") .HasColumnName("ConcurrencyStamp"); + b.Property("EntityVersion") + .HasColumnType("int"); + b.Property("ExtraProperties") .HasColumnType("nvarchar(max)") .HasColumnName("ExtraProperties"); @@ -141,7 +147,7 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations b.HasIndex("NormalizedName"); - b.ToTable("AbpRoles"); + b.ToTable("AbpRoles", (string)null); }); modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => @@ -169,7 +175,7 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations b.HasIndex("RoleId"); - b.ToTable("AbpRoleClaims"); + b.ToTable("AbpRoleClaims", (string)null); }); modelBuilder.Entity("Volo.Abp.Identity.IdentitySecurityLog", b => @@ -244,7 +250,7 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations b.HasIndex("TenantId", "UserId"); - b.ToTable("AbpSecurityLogs"); + b.ToTable("AbpSecurityLogs", (string)null); }); modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => @@ -293,10 +299,17 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations .HasDefaultValue(false) .HasColumnName("EmailConfirmed"); + b.Property("EntityVersion") + .HasColumnType("int"); + b.Property("ExtraProperties") .HasColumnType("nvarchar(max)") .HasColumnName("ExtraProperties"); + b.Property("IsActive") + .HasColumnType("bit") + .HasColumnName("IsActive"); + b.Property("IsDeleted") .ValueGeneratedOnAdd() .HasColumnType("bit") @@ -317,6 +330,9 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations .HasColumnType("uniqueidentifier") .HasColumnName("LastModifierId"); + b.Property("LastPasswordChangeTime") + .HasColumnType("datetimeoffset"); + b.Property("LockoutEnabled") .ValueGeneratedOnAdd() .HasColumnType("bit") @@ -365,6 +381,9 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations .HasColumnType("nvarchar(256)") .HasColumnName("SecurityStamp"); + b.Property("ShouldChangePasswordOnNextLogin") + .HasColumnType("bit"); + b.Property("Surname") .HasMaxLength(64) .HasColumnType("nvarchar(64)") @@ -396,7 +415,7 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations b.HasIndex("UserName"); - b.ToTable("AbpUsers"); + b.ToTable("AbpUsers", (string)null); }); modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => @@ -424,7 +443,34 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations b.HasIndex("UserId"); - b.ToTable("AbpUserClaims"); + b.ToTable("AbpUserClaims", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserDelegation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("EndTime") + .HasColumnType("datetime2"); + + b.Property("SourceUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartTime") + .HasColumnType("datetime2"); + + b.Property("TargetUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("AbpUserDelegations", (string)null); }); modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => @@ -453,7 +499,7 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations b.HasIndex("LoginProvider", "ProviderKey"); - b.ToTable("AbpUserLogins"); + b.ToTable("AbpUserLogins", (string)null); }); modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b => @@ -480,7 +526,7 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations b.HasIndex("UserId", "OrganizationUnitId"); - b.ToTable("AbpUserOrganizationUnits"); + b.ToTable("AbpUserOrganizationUnits", (string)null); }); modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => @@ -499,7 +545,7 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations b.HasIndex("RoleId", "UserId"); - b.ToTable("AbpUserRoles"); + b.ToTable("AbpUserRoles", (string)null); }); modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => @@ -524,7 +570,7 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations b.HasKey("UserId", "LoginProvider", "Name"); - b.ToTable("AbpUserTokens"); + b.ToTable("AbpUserTokens", (string)null); }); modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => @@ -567,6 +613,9 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations .HasColumnType("nvarchar(128)") .HasColumnName("DisplayName"); + b.Property("EntityVersion") + .HasColumnType("int"); + b.Property("ExtraProperties") .HasColumnType("nvarchar(max)") .HasColumnName("ExtraProperties"); @@ -598,7 +647,7 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations b.HasIndex("ParentId"); - b.ToTable("AbpOrganizationUnits"); + b.ToTable("AbpOrganizationUnits", (string)null); }); modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b => @@ -625,7 +674,60 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations b.HasIndex("RoleId", "OrganizationUnitId"); - b.ToTable("AbpOrganizationUnitRoles"); + b.ToTable("AbpOrganizationUnitRoles", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionDefinitionRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("GroupName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("IsEnabled") + .HasColumnType("bit"); + + b.Property("MultiTenancySide") + .HasColumnType("tinyint"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ParentName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Providers") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("StateCheckers") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("GroupName"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("AbpPermissions", (string)null); }); modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGrant", b => @@ -655,9 +757,39 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations b.HasKey("Id"); - b.HasIndex("Name", "ProviderName", "ProviderKey"); + b.HasIndex("TenantId", "Name", "ProviderName", "ProviderKey") + .IsUnique() + .HasFilter("[TenantId] IS NOT NULL"); + + b.ToTable("AbpPermissionGrants", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGroupDefinitionRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); - b.ToTable("AbpPermissionGrants"); + b.ToTable("AbpPermissionGroups", (string)null); }); modelBuilder.Entity("Volo.Abp.SettingManagement.Setting", b => @@ -686,9 +818,58 @@ namespace Volo.Abp.SettingManagement.DemoApp.Migrations b.HasKey("Id"); - b.HasIndex("Name", "ProviderName", "ProviderKey"); + b.HasIndex("Name", "ProviderName", "ProviderKey") + .IsUnique() + .HasFilter("[ProviderName] IS NOT NULL AND [ProviderKey] IS NOT NULL"); + + b.ToTable("AbpSettings", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.SettingManagement.SettingDefinitionRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("DefaultValue") + .HasColumnType("nvarchar(max)"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsEncrypted") + .HasColumnType("bit"); + + b.Property("IsInherited") + .HasColumnType("bit"); + + b.Property("IsVisibleToClients") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Providers") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); - b.ToTable("AbpSettings"); + b.ToTable("AbpSettingDefinitionRecords", (string)null); }); modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/SettingDefinitionRecordConsts.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/SettingDefinitionRecordConsts.cs new file mode 100644 index 0000000000..96ce8c082f --- /dev/null +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/SettingDefinitionRecordConsts.cs @@ -0,0 +1,12 @@ +namespace Volo.Abp.SettingManagement; + +public class SettingDefinitionRecordConsts +{ + public static int MaxNameLength { get; set; } = 128; + + public static int MaxDisplayNameLength { get; set; } = 256; + + public static int MaxDescriptionLength { get; set; } = 512; + + public static int MaxProvidersLength { get; set; } = 128; +} diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo.Abp.SettingManagement.Domain.csproj b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo.Abp.SettingManagement.Domain.csproj index cdccd41dfe..5e84103de3 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo.Abp.SettingManagement.Domain.csproj +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo.Abp.SettingManagement.Domain.csproj @@ -22,4 +22,8 @@ + + + + diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/AbpSettingManagementDomainModule.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/AbpSettingManagementDomainModule.cs index c429fa0bba..38979ab8ae 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/AbpSettingManagementDomainModule.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/AbpSettingManagementDomainModule.cs @@ -1,7 +1,17 @@ -using Volo.Abp.Caching; +using System; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Polly; +using Volo.Abp.Caching; +using Volo.Abp.DependencyInjection; using Volo.Abp.Domain; using Volo.Abp.Modularity; using Volo.Abp.Settings; +using Volo.Abp.Threading; namespace Volo.Abp.SettingManagement; @@ -13,6 +23,8 @@ namespace Volo.Abp.SettingManagement; )] public class AbpSettingManagementDomainModule : AbpModule { + private readonly CancellationTokenSource _cancellationTokenSource = new(); + public override void ConfigureServices(ServiceConfigurationContext context) { Configure(options => @@ -24,4 +36,128 @@ public class AbpSettingManagementDomainModule : AbpModule options.Providers.Add(); }); } + + public override void OnApplicationInitialization(ApplicationInitializationContext context) + { + AsyncHelper.RunSync(() => OnApplicationInitializationAsync(context)); + } + + public override Task OnApplicationInitializationAsync(ApplicationInitializationContext context) + { + InitializeDynamicSettings(context); + return Task.CompletedTask; + } + + public override Task OnApplicationShutdownAsync(ApplicationShutdownContext context) + { + _cancellationTokenSource.Cancel(); + return Task.CompletedTask; + } + + private void InitializeDynamicSettings(ApplicationInitializationContext context) + { + var options = context + .ServiceProvider + .GetRequiredService>() + .Value; + + if (!options.SaveStaticSettingsToDatabase && !options.IsDynamicSettingStoreEnabled) + { + return; + } + + var rootServiceProvider = context.ServiceProvider.GetRequiredService(); + + Task.Run(async () => + { + using var scope = rootServiceProvider.CreateScope(); + var applicationLifetime = scope.ServiceProvider.GetService(); + var cancellationTokenProvider = scope.ServiceProvider.GetRequiredService(); + var cancellationToken = applicationLifetime?.ApplicationStopping ?? _cancellationTokenSource.Token; + + try + { + using (cancellationTokenProvider.Use(cancellationToken)) + { + if (cancellationTokenProvider.Token.IsCancellationRequested) + { + return; + } + + await SaveStaticSettingsToDatabaseAsync(options, scope, cancellationTokenProvider); + + if (cancellationTokenProvider.Token.IsCancellationRequested) + { + return; + } + + await PreCacheDynamicSettingsAsync(options, scope); + } + } + // ReSharper disable once EmptyGeneralCatchClause (No need to log since it is logged above) + catch { } + }); + } + + private async static Task SaveStaticSettingsToDatabaseAsync( + SettingManagementOptions options, + IServiceScope scope, + ICancellationTokenProvider cancellationTokenProvider) + { + if (!options.SaveStaticSettingsToDatabase) + { + return; + } + + await Policy + .Handle() + .WaitAndRetryAsync(8, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt) * 10)) + .ExecuteAsync(async _ => + { + try + { + // ReSharper disable once AccessToDisposedClosure + await scope + .ServiceProvider + .GetRequiredService() + .SaveAsync(); + } + catch (Exception ex) + { + // ReSharper disable once AccessToDisposedClosure + scope.ServiceProvider + .GetService>()? + .LogException(ex); + + throw; // Polly will catch it + } + }, cancellationTokenProvider.Token); + } + + private async static Task PreCacheDynamicSettingsAsync(SettingManagementOptions options, IServiceScope scope) + { + if (!options.IsDynamicSettingStoreEnabled) + { + return; + } + + try + { + // Pre-cache settings, so first request doesn't wait + await scope + .ServiceProvider + .GetRequiredService() + .GetAllAsync(); + } + catch (Exception ex) + { + // ReSharper disable once AccessToDisposedClosure + scope + .ServiceProvider + .GetService>()? + .LogException(ex); + + throw; // It will be cached in InitializeDynamicSettings + } + } } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/DynamicSettingDefinitionStore.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/DynamicSettingDefinitionStore.cs new file mode 100644 index 0000000000..bcdf23dd99 --- /dev/null +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/DynamicSettingDefinitionStore.cs @@ -0,0 +1,162 @@ +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Threading.Tasks; +using Microsoft.Extensions.Caching.Distributed; +using Microsoft.Extensions.Options; +using Volo.Abp.Caching; +using Volo.Abp.DependencyInjection; +using Volo.Abp.DistributedLocking; +using Volo.Abp.Settings; +using Volo.Abp.Threading; + +namespace Volo.Abp.SettingManagement; + +[Dependency(ReplaceServices = true)] +public class DynamicSettingDefinitionStore : IDynamicSettingDefinitionStore, ITransientDependency +{ + protected ISettingDefinitionRecordRepository SettingRepository { get; } + protected ISettingDefinitionSerializer SettingDefinitionSerializer { get; } + protected IDynamicSettingDefinitionStoreInMemoryCache StoreCache { get; } + protected IDistributedCache DistributedCache { get; } + protected IAbpDistributedLock DistributedLock { get; } + public SettingManagementOptions SettingManagementOptions { get; } + protected AbpDistributedCacheOptions CacheOptions { get; } + + public DynamicSettingDefinitionStore( + ISettingDefinitionRecordRepository textSettingRepository, + ISettingDefinitionSerializer textSettingDefinitionSerializer, + IDynamicSettingDefinitionStoreInMemoryCache storeCache, + IDistributedCache distributedCache, + IOptions cacheOptions, + IOptions settingManagementOptions, + IAbpDistributedLock distributedLock) + { + SettingRepository = textSettingRepository; + SettingDefinitionSerializer = textSettingDefinitionSerializer; + StoreCache = storeCache; + DistributedCache = distributedCache; + DistributedLock = distributedLock; + SettingManagementOptions = settingManagementOptions.Value; + CacheOptions = cacheOptions.Value; + } + + public virtual async Task GetAsync(string name) + { + var setting = await GetOrNullAsync(name); + if (setting == null) + { + throw new AbpException("Undefined setting: " + name); + } + + return setting; + } + + public virtual async Task GetOrNullAsync(string name) + { + if (!SettingManagementOptions.IsDynamicSettingStoreEnabled) + { + return null; + } + + using (await StoreCache.SyncSemaphore.LockAsync()) + { + await EnsureCacheIsUptoDateAsync(); + return StoreCache.GetSettingOrNull(name); + } + } + + public virtual async Task> GetAllAsync() + { + if (!SettingManagementOptions.IsDynamicSettingStoreEnabled) + { + return Array.Empty(); + } + + using (await StoreCache.SyncSemaphore.LockAsync()) + { + await EnsureCacheIsUptoDateAsync(); + return StoreCache.GetSettings().ToImmutableList(); + } + } + + protected virtual async Task EnsureCacheIsUptoDateAsync() + { + if (StoreCache.LastCheckTime.HasValue && + DateTime.Now.Subtract(StoreCache.LastCheckTime.Value).TotalSeconds < 30) + { + /* We get the latest setting with a small delay for optimization */ + return; + } + + var stampInDistributedCache = await GetOrSetStampInDistributedCache(); + + if (stampInDistributedCache == StoreCache.CacheStamp) + { + StoreCache.LastCheckTime = DateTime.Now; + return; + } + + await UpdateInMemoryStoreCache(); + + StoreCache.CacheStamp = stampInDistributedCache; + StoreCache.LastCheckTime = DateTime.Now; + } + + protected virtual async Task UpdateInMemoryStoreCache() + { + var settingRecords = await SettingRepository.GetListAsync(); + await StoreCache.FillAsync(settingRecords); + } + + protected virtual async Task GetOrSetStampInDistributedCache() + { + var cacheKey = GetCommonStampCacheKey(); + + var stampInDistributedCache = await DistributedCache.GetStringAsync(cacheKey); + if (stampInDistributedCache != null) + { + return stampInDistributedCache; + } + + await using (var commonLockHandle = await DistributedLock.TryAcquireAsync(GetCommonDistributedLockKey(), TimeSpan.FromMinutes(2))) + { + if (commonLockHandle == null) + { + /* This request will fail */ + throw new AbpException( + "Could not acquire distributed lock for setting definition common stamp check!" + ); + } + + stampInDistributedCache = await DistributedCache.GetStringAsync(cacheKey); + if (stampInDistributedCache != null) + { + return stampInDistributedCache; + } + + stampInDistributedCache = Guid.NewGuid().ToString(); + + await DistributedCache.SetStringAsync( + cacheKey, + stampInDistributedCache, + new DistributedCacheEntryOptions + { + SlidingExpiration = TimeSpan.FromDays(30) //TODO: Make it configurable? + } + ); + } + + return stampInDistributedCache; + } + + protected virtual string GetCommonStampCacheKey() + { + return $"{CacheOptions.KeyPrefix}_AbpInMemorySettingCacheStamp"; + } + + protected virtual string GetCommonDistributedLockKey() + { + return $"{CacheOptions.KeyPrefix}_Common_AbpSettingUpdateLock"; + } +} diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/DynamicSettingDefinitionStoreInMemoryCache.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/DynamicSettingDefinitionStoreInMemoryCache.cs new file mode 100644 index 0000000000..e682e7a085 --- /dev/null +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/DynamicSettingDefinitionStoreInMemoryCache.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Localization; +using Volo.Abp.Settings; + +namespace Volo.Abp.SettingManagement; + +public class DynamicSettingDefinitionStoreInMemoryCache : IDynamicSettingDefinitionStoreInMemoryCache, ISingletonDependency +{ + public string CacheStamp { get; set; } + + protected IDictionary SettingDefinitions { get; } + protected ILocalizableStringSerializer LocalizableStringSerializer { get; } + + public SemaphoreSlim SyncSemaphore { get; } = new(1, 1); + + public DateTime? LastCheckTime { get; set; } + + public DynamicSettingDefinitionStoreInMemoryCache(ILocalizableStringSerializer localizableStringSerializer) + { + LocalizableStringSerializer = localizableStringSerializer; + SettingDefinitions = new Dictionary(); + } + + public Task FillAsync(List settingRecords) + { + SettingDefinitions.Clear(); + + foreach (var record in settingRecords) + { + var settingDefinition = new SettingDefinition( + record.Name, + record.DefaultValue, + LocalizableStringSerializer.Deserialize(record.DisplayName), + record.Description != null ? LocalizableStringSerializer.Deserialize(record.Description) : null, + record.IsVisibleToClients, + record.IsInherited, + record.IsEncrypted); + + foreach (var property in record.ExtraProperties) + { + settingDefinition.WithProperty(property.Key, property.Value); + } + + SettingDefinitions[record.Name] = settingDefinition; + } + + return Task.CompletedTask; + } + + public SettingDefinition GetSettingOrNull(string name) + { + return SettingDefinitions.GetOrDefault(name); + } + + public IReadOnlyList GetSettings() + { + return SettingDefinitions.Values.ToList(); + } +} diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/IDynamicSettingDefinitionStoreInMemoryCache.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/IDynamicSettingDefinitionStoreInMemoryCache.cs new file mode 100644 index 0000000000..5c2c208e49 --- /dev/null +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/IDynamicSettingDefinitionStoreInMemoryCache.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.Settings; + +namespace Volo.Abp.SettingManagement; + +public interface IDynamicSettingDefinitionStoreInMemoryCache +{ + string CacheStamp { get; set; } + + SemaphoreSlim SyncSemaphore { get; } + + DateTime? LastCheckTime { get; set; } + + Task FillAsync(List settingRecords); + + SettingDefinition GetSettingOrNull(string name); + + IReadOnlyList GetSettings(); +} diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/ISettingDefinitionRecordRepository.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/ISettingDefinitionRecordRepository.cs new file mode 100644 index 0000000000..81beb2583c --- /dev/null +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/ISettingDefinitionRecordRepository.cs @@ -0,0 +1,11 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.Domain.Repositories; + +namespace Volo.Abp.SettingManagement; + +public interface ISettingDefinitionRecordRepository : IBasicRepository +{ + Task FindByNameAsync(string name, CancellationToken cancellationToken = default); +} diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/ISettingDefinitionSerializer.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/ISettingDefinitionSerializer.cs new file mode 100644 index 0000000000..f6942b7b01 --- /dev/null +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/ISettingDefinitionSerializer.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.Settings; + +namespace Volo.Abp.SettingManagement; + +public interface ISettingDefinitionSerializer +{ + Task SerializeAsync(SettingDefinition setting); + + Task> SerializeAsync(IEnumerable settings); +} diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/IStaticSettingSaver.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/IStaticSettingSaver.cs new file mode 100644 index 0000000000..07a959d7d8 --- /dev/null +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/IStaticSettingSaver.cs @@ -0,0 +1,8 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.SettingManagement; + +public interface IStaticSettingSaver +{ + Task SaveAsync(); +} diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingDefinitionRecord.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingDefinitionRecord.cs new file mode 100644 index 0000000000..ab65964aab --- /dev/null +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingDefinitionRecord.cs @@ -0,0 +1,188 @@ +using System; +using System.Collections.Generic; +using JetBrains.Annotations; +using Volo.Abp.Data; +using Volo.Abp.Domain.Entities; +using Volo.Abp.Localization; + +namespace Volo.Abp.SettingManagement; + +public class SettingDefinitionRecord : BasicAggregateRoot, IHasExtraProperties +{ + /// + /// Unique name of the setting. + /// + [NotNull] + public string Name { get; set; } + + [NotNull] + public string DisplayName { get; set; } + + [CanBeNull] + public string Description { get; set; } + + /// + /// Default value of the setting. + /// + [CanBeNull] + public string DefaultValue { get; set; } + + /// + /// Can clients see this setting and it's value. + /// It maybe dangerous for some settings to be visible to clients (such as an email server password). + /// Default: false. + /// + public bool IsVisibleToClients { get; set; } + + /// + /// Comma separated list of provider names. + /// + public string Providers { get; set; } + + /// + /// Is this setting inherited from parent scopes. + /// Default: True. + /// + public bool IsInherited { get; set; } + + /// + /// Is this setting stored as encrypted in the data source. + /// Default: False. + /// + public bool IsEncrypted { get; set; } + + public ExtraPropertyDictionary ExtraProperties { get; protected set; } + + public SettingDefinitionRecord() + { + ExtraProperties = new ExtraPropertyDictionary(); + this.SetDefaultsForExtraProperties(); + } + + public SettingDefinitionRecord( + Guid id, + string name, + string displayName, + string description, + string defaultValue, + bool isVisibleToClients, + string providers, + bool isInherited, + bool isEncrypted) + : base(id) + { + Name = Check.NotNullOrWhiteSpace(name, nameof(name), SettingDefinitionRecordConsts.MaxNameLength); + DisplayName = Check.NotNullOrWhiteSpace(displayName, nameof(displayName), SettingDefinitionRecordConsts.MaxDisplayNameLength); + Description = Check.Length(description, nameof(description), SettingDefinitionRecordConsts.MaxDescriptionLength); + DefaultValue = defaultValue; + IsVisibleToClients = isVisibleToClients; + Providers = Check.Length(providers, nameof(providers), SettingDefinitionRecordConsts.MaxProvidersLength); + IsInherited = isInherited; + IsEncrypted = isEncrypted; + ExtraProperties = new ExtraPropertyDictionary(); + this.SetDefaultsForExtraProperties(); + } + + public bool HasSameData(SettingDefinitionRecord otherRecord) + { + if (Name != otherRecord.Name) + { + return false; + } + + if (DisplayName != otherRecord.DisplayName) + { + return false; + } + + if (Description != otherRecord.Description) + { + return false; + } + + if (DefaultValue != otherRecord.DefaultValue) + { + return false; + } + + if (IsVisibleToClients != otherRecord.IsVisibleToClients) + { + return false; + } + + if (Providers != otherRecord.Providers) + { + return false; + } + + if (IsInherited != otherRecord.IsInherited) + { + return false; + } + + if (IsEncrypted != otherRecord.IsEncrypted) + { + return false; + } + + if (!this.HasSameExtraProperties(otherRecord)) + { + return false; + } + + return true; + } + + public void Patch(SettingDefinitionRecord otherRecord) + { + if (Name != otherRecord.Name) + { + Name = otherRecord.Name; + } + + if (DisplayName != otherRecord.DisplayName) + { + DisplayName = otherRecord.DisplayName; + } + + if (Description != otherRecord.Description) + { + Description = otherRecord.Description; + } + + if (DefaultValue != otherRecord.DefaultValue) + { + DefaultValue = otherRecord.DefaultValue; + } + + if (IsVisibleToClients != otherRecord.IsVisibleToClients) + { + IsVisibleToClients = otherRecord.IsVisibleToClients; + } + + if (Providers != otherRecord.Providers) + { + Providers = otherRecord.Providers; + } + + if (IsInherited != otherRecord.IsInherited) + { + IsInherited = otherRecord.IsInherited; + } + + if (IsEncrypted != otherRecord.IsEncrypted) + { + IsEncrypted = otherRecord.IsEncrypted; + } + + if (!this.HasSameExtraProperties(otherRecord)) + { + this.ExtraProperties.Clear(); + + foreach (var property in otherRecord.ExtraProperties) + { + this.ExtraProperties.Add(property.Key, property.Value); + } + } + } +} diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingDefinitionSerializer.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingDefinitionSerializer.cs new file mode 100644 index 0000000000..ae63797bba --- /dev/null +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingDefinitionSerializer.cs @@ -0,0 +1,59 @@ +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Guids; +using Volo.Abp.Localization; +using Volo.Abp.Settings; + +namespace Volo.Abp.SettingManagement; + +public class SettingDefinitionSerializer : ISettingDefinitionSerializer, ITransientDependency +{ + protected IGuidGenerator GuidGenerator { get; } + protected ILocalizableStringSerializer LocalizableStringSerializer { get; } + + public SettingDefinitionSerializer(IGuidGenerator guidGenerator, ILocalizableStringSerializer localizableStringSerializer) + { + GuidGenerator = guidGenerator; + LocalizableStringSerializer = localizableStringSerializer; + } + + public virtual Task SerializeAsync(SettingDefinition setting) + { + using (CultureHelper.Use(CultureInfo.InvariantCulture)) + { + var record = new SettingDefinitionRecord( + GuidGenerator.Create(), + setting.Name, + LocalizableStringSerializer.Serialize(setting.DisplayName), + LocalizableStringSerializer.Serialize(setting.Description), + setting.DefaultValue, + setting.IsVisibleToClients, + SerializeProviders(setting.Providers), + setting.IsInherited, + setting.IsEncrypted); + + foreach (var property in setting.Properties) + { + record.SetProperty(property.Key, property.Value); + } + + return Task.FromResult(record); + } + } + + public virtual Task> SerializeAsync(IEnumerable settings) + { + return Task.FromResult(settings.Select(SerializeAsync).Select(t => t.Result).ToList()); + } + + protected virtual string SerializeProviders(ICollection providers) + { + return providers.Any() + ? providers.JoinAsString(",") + : null; + } +} diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingManagementOptions.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingManagementOptions.cs index 6a1a66d3cb..bf5a1018ba 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingManagementOptions.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingManagementOptions.cs @@ -6,6 +6,16 @@ public class SettingManagementOptions { public ITypeList Providers { get; } + /// + /// Default: true. + /// + public bool SaveStaticSettingsToDatabase { get; set; } = true; + + /// + /// Default: false. + /// + public bool IsDynamicSettingStoreEnabled { get; set; } + public SettingManagementOptions() { Providers = new TypeList(); diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingManagementStore.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingManagementStore.cs index 90cfdd9122..4e892abded 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingManagementStore.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingManagementStore.cs @@ -92,7 +92,7 @@ public class SettingManagementStore : ISettingManagementStore, ITransientDepende string currentName, SettingCacheItem currentCacheItem) { - var settingDefinitions = SettingDefinitionManager.GetAll(); + var settingDefinitions = await SettingDefinitionManager.GetAllAsync(); var settingsDictionary = (await SettingRepository.GetListAsync(providerName, providerKey)) .ToDictionary(s => s.Name, s => s.Value); @@ -176,7 +176,7 @@ public class SettingManagementStore : ISettingManagementStore, ITransientDepende string providerKey, List notCacheKeys) { - var settingDefinitions = SettingDefinitionManager.GetAll().Where(x => notCacheKeys.Any(k => GetSettingNameFormCacheKeyOrNull(k) == x.Name)); + var settingDefinitions = (await SettingDefinitionManager.GetAllAsync()).Where(x => notCacheKeys.Any(k => GetSettingNameFormCacheKeyOrNull(k) == x.Name)); var settingsDictionary = (await SettingRepository.GetListAsync(notCacheKeys.Select(GetSettingNameFormCacheKeyOrNull).ToArray(), providerName, providerKey)) .ToDictionary(s => s.Name, s => s.Value); diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingManager.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingManager.cs index 570c99925b..800f2140f5 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingManager.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/SettingManager.cs @@ -50,7 +50,7 @@ public class SettingManager : ISettingManager, ISingletonDependency { Check.NotNull(providerName, nameof(providerName)); - var settingDefinitions = SettingDefinitionManager.GetAll(); + var settingDefinitions = await SettingDefinitionManager.GetAllAsync(); var providers = Enumerable.Reverse(Providers) .SkipWhile(c => c.Name != providerName); @@ -113,7 +113,7 @@ public class SettingManager : ISettingManager, ISingletonDependency Check.NotNull(name, nameof(name)); Check.NotNull(providerName, nameof(providerName)); - var setting = SettingDefinitionManager.Get(name); + var setting = await SettingDefinitionManager.GetAsync(name); var providers = Enumerable .Reverse(Providers) @@ -162,7 +162,7 @@ public class SettingManager : ISettingManager, ISingletonDependency protected virtual async Task GetOrNullInternalAsync(string name, string providerName, string providerKey, bool fallback = true) { - var setting = SettingDefinitionManager.Get(name); + var setting = await SettingDefinitionManager.GetAsync(name); var providers = Enumerable .Reverse(Providers); diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/StaticSettingSaver.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/StaticSettingSaver.cs new file mode 100644 index 0000000000..78ddf400e2 --- /dev/null +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain/Volo/Abp/SettingManagement/StaticSettingSaver.cs @@ -0,0 +1,240 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json; +using System.Text.Json.Serialization.Metadata; +using System.Threading.Tasks; +using Microsoft.Extensions.Caching.Distributed; +using Microsoft.Extensions.Options; +using Volo.Abp.Caching; +using Volo.Abp.DependencyInjection; +using Volo.Abp.DistributedLocking; +using Volo.Abp.Guids; +using Volo.Abp.Json.SystemTextJson.Modifiers; +using Volo.Abp.Settings; +using Volo.Abp.Threading; +using Volo.Abp.Uow; + +namespace Volo.Abp.SettingManagement; + +public class StaticSettingSaver : IStaticSettingSaver, ITransientDependency +{ + protected IStaticSettingDefinitionStore StaticStore { get; } + protected ISettingDefinitionRecordRepository SettingRepository { get; } + protected ISettingDefinitionSerializer SettingSerializer { get; } + protected IDistributedCache Cache { get; } + protected IApplicationInfoAccessor ApplicationInfoAccessor { get; } + protected IAbpDistributedLock DistributedLock { get; } + protected AbpSettingOptions SettingOptions { get; } + protected ICancellationTokenProvider CancellationTokenProvider { get; } + protected AbpDistributedCacheOptions CacheOptions { get; } + protected IUnitOfWorkManager UnitOfWorkManager { get; } + protected IGuidGenerator GuidGenerator { get; } + + public StaticSettingSaver( + IStaticSettingDefinitionStore staticStore, + ISettingDefinitionRecordRepository settingRepository, + ISettingDefinitionSerializer settingSerializer, + IDistributedCache cache, + IOptions cacheOptions, + IApplicationInfoAccessor applicationInfoAccessor, + IAbpDistributedLock distributedLock, + IOptions settingOptions, + ICancellationTokenProvider cancellationTokenProvider, + IUnitOfWorkManager unitOfWorkManager, + IGuidGenerator guidGenerator) + { + StaticStore = staticStore; + SettingRepository = settingRepository; + SettingSerializer = settingSerializer; + Cache = cache; + ApplicationInfoAccessor = applicationInfoAccessor; + DistributedLock = distributedLock; + CancellationTokenProvider = cancellationTokenProvider; + SettingOptions = settingOptions.Value; + CacheOptions = cacheOptions.Value; + UnitOfWorkManager = unitOfWorkManager; + GuidGenerator = guidGenerator; + } + + [UnitOfWork] + public async Task SaveAsync() + { + await using var applicationLockHandle = await DistributedLock.TryAcquireAsync( + GetApplicationDistributedLockKey() + ); + + if (applicationLockHandle == null) + { + /* Another application instance is already doing it */ + return; + } + + var cacheKey = GetApplicationHashCacheKey(); + var cachedHash = await Cache.GetStringAsync(cacheKey, CancellationTokenProvider.Token); + + var settingRecords = await SettingSerializer.SerializeAsync(await StaticStore.GetAllAsync()); + var currentHash = CalculateHash(settingRecords, SettingOptions.DeletedSettings); + + if (cachedHash == currentHash) + { + return; + } + + await using (var commonLockHandle = await DistributedLock.TryAcquireAsync( + GetCommonDistributedLockKey(), + TimeSpan.FromMinutes(5))) + { + if (commonLockHandle == null) + { + /* It will re-try */ + throw new AbpException("Could not acquire distributed lock for saving static Settings!"); + } + + using (var unitOfWork = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: true)) + { + try + { + var hasChangesInSettings = await UpdateChangedSettingsAsync(settingRecords); + + if (hasChangesInSettings) + { + await Cache.SetStringAsync( + GetCommonStampCacheKey(), + Guid.NewGuid().ToString(), + new DistributedCacheEntryOptions { + SlidingExpiration = TimeSpan.FromDays(30) //TODO: Make it configurable? + }, + CancellationTokenProvider.Token + ); + } + } + catch + { + try + { + await unitOfWork.RollbackAsync(); + } + catch + { + /* ignored */ + } + + throw; + } + + await unitOfWork.CompleteAsync(); + } + } + + await Cache.SetStringAsync( + cacheKey, + currentHash, + new DistributedCacheEntryOptions { + SlidingExpiration = TimeSpan.FromDays(30) //TODO: Make it configurable? + }, + CancellationTokenProvider.Token + ); + } + + private async Task UpdateChangedSettingsAsync(List SettingRecords) + { + var newRecords = new List(); + var changedRecords = new List(); + + var settingRecordsInDatabase = (await SettingRepository.GetListAsync()).ToDictionary(x => x.Name); + + foreach (var record in SettingRecords) + { + var settingRecordInDatabase = settingRecordsInDatabase.GetOrDefault(record.Name); + if (settingRecordInDatabase == null) + { + /* New group */ + newRecords.Add(record); + continue; + } + + if (record.HasSameData(settingRecordInDatabase)) + { + /* Not changed */ + continue; + } + + /* Changed */ + settingRecordInDatabase.Patch(record); + changedRecords.Add(settingRecordInDatabase); + } + + /* Deleted */ + var deletedRecords = new List(); + + if (SettingOptions.DeletedSettings.Any()) + { + deletedRecords.AddRange(settingRecordsInDatabase.Values.Where(x => SettingOptions.DeletedSettings.Contains(x.Name))); + } + + if (newRecords.Any()) + { + await SettingRepository.InsertManyAsync(newRecords); + } + + if (changedRecords.Any()) + { + await SettingRepository.UpdateManyAsync(changedRecords); + } + + if (deletedRecords.Any()) + { + await SettingRepository.DeleteManyAsync(deletedRecords); + } + + return newRecords.Any() || changedRecords.Any() || deletedRecords.Any(); + } + + private string GetApplicationDistributedLockKey() + { + return $"{CacheOptions.KeyPrefix}_{ApplicationInfoAccessor.ApplicationName}_AbpSettingUpdateLock"; + } + + private string GetCommonDistributedLockKey() + { + return $"{CacheOptions.KeyPrefix}_Common_AbpSettingUpdateLock"; + } + + private string GetApplicationHashCacheKey() + { + return $"{CacheOptions.KeyPrefix}_{ApplicationInfoAccessor.ApplicationName}_AbpSettingsHash"; + } + + private string GetCommonStampCacheKey() + { + return $"{CacheOptions.KeyPrefix}_AbpInMemorySettingCacheStamp"; + } + + private string CalculateHash(List settingRecords, IEnumerable deletedSettings) + { + var jsonSerializerOptions = new JsonSerializerOptions + { + TypeInfoResolver = new DefaultJsonTypeInfoResolver + { + Modifiers = + { + new AbpIgnorePropertiesModifiers().CreateModifyAction(x => x.Id), + } + } + }; + + var stringBuilder = new StringBuilder(); + + stringBuilder.Append("SettingRecords:"); + stringBuilder.AppendLine(JsonSerializer.Serialize(settingRecords, jsonSerializerOptions)); + + stringBuilder.Append("DeletedSetting:"); + stringBuilder.Append(deletedSettings.JoinAsString(",")); + + return stringBuilder + .ToString() + .ToMd5(); + } +} diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.EntityFrameworkCore/Volo/Abp/SettingManagement/EntityFrameworkCore/AbpSettingManagementEntityFrameworkCoreModule.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.EntityFrameworkCore/Volo/Abp/SettingManagement/EntityFrameworkCore/AbpSettingManagementEntityFrameworkCoreModule.cs index 1a17278e13..8811f3e3ef 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.EntityFrameworkCore/Volo/Abp/SettingManagement/EntityFrameworkCore/AbpSettingManagementEntityFrameworkCoreModule.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.EntityFrameworkCore/Volo/Abp/SettingManagement/EntityFrameworkCore/AbpSettingManagementEntityFrameworkCoreModule.cs @@ -17,6 +17,7 @@ public class AbpSettingManagementEntityFrameworkCoreModule : AbpModule options.AddDefaultRepositories(); options.AddRepository(); + options.AddRepository(); }); } } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.EntityFrameworkCore/Volo/Abp/SettingManagement/EntityFrameworkCore/EfCoreSettingDefinitionRecordRepository.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.EntityFrameworkCore/Volo/Abp/SettingManagement/EntityFrameworkCore/EfCoreSettingDefinitionRecordRepository.cs new file mode 100644 index 0000000000..bd39aff00f --- /dev/null +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.EntityFrameworkCore/Volo/Abp/SettingManagement/EntityFrameworkCore/EfCoreSettingDefinitionRecordRepository.cs @@ -0,0 +1,24 @@ +using System; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Volo.Abp.Domain.Repositories.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore; + +namespace Volo.Abp.SettingManagement.EntityFrameworkCore; + +public class EfCoreSettingDefinitionRecordRepository : EfCoreRepository, ISettingDefinitionRecordRepository +{ + public EfCoreSettingDefinitionRecordRepository(IDbContextProvider dbContextProvider) + : base(dbContextProvider) + { + } + + public virtual async Task FindByNameAsync(string name, CancellationToken cancellationToken = default) + { + return await (await GetDbSetAsync()) + .OrderBy(x => x.Id) + .FirstOrDefaultAsync(x => x.Name == name, cancellationToken); + } +} diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.EntityFrameworkCore/Volo/Abp/SettingManagement/EntityFrameworkCore/ISettingManagementDbContext.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.EntityFrameworkCore/Volo/Abp/SettingManagement/EntityFrameworkCore/ISettingManagementDbContext.cs index 6c6e29a78b..049ab71113 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.EntityFrameworkCore/Volo/Abp/SettingManagement/EntityFrameworkCore/ISettingManagementDbContext.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.EntityFrameworkCore/Volo/Abp/SettingManagement/EntityFrameworkCore/ISettingManagementDbContext.cs @@ -10,4 +10,6 @@ namespace Volo.Abp.SettingManagement.EntityFrameworkCore; public interface ISettingManagementDbContext : IEfCoreDbContext { DbSet Settings { get; } + + DbSet SettingDefinitionRecords { get; } } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.EntityFrameworkCore/Volo/Abp/SettingManagement/EntityFrameworkCore/SettingManagementDbContext.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.EntityFrameworkCore/Volo/Abp/SettingManagement/EntityFrameworkCore/SettingManagementDbContext.cs index bd1f3abf10..6d9482e428 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.EntityFrameworkCore/Volo/Abp/SettingManagement/EntityFrameworkCore/SettingManagementDbContext.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.EntityFrameworkCore/Volo/Abp/SettingManagement/EntityFrameworkCore/SettingManagementDbContext.cs @@ -10,6 +10,7 @@ namespace Volo.Abp.SettingManagement.EntityFrameworkCore; public class SettingManagementDbContext : AbpDbContext, ISettingManagementDbContext { public DbSet Settings { get; set; } + public DbSet SettingDefinitionRecords { get; set; } public SettingManagementDbContext(DbContextOptions options) : base(options) diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.EntityFrameworkCore/Volo/Abp/SettingManagement/EntityFrameworkCore/SettingManagementDbContextModelBuilderExtensions.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.EntityFrameworkCore/Volo/Abp/SettingManagement/EntityFrameworkCore/SettingManagementDbContextModelBuilderExtensions.cs index 45937d0027..75fd9a1e78 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.EntityFrameworkCore/Volo/Abp/SettingManagement/EntityFrameworkCore/SettingManagementDbContextModelBuilderExtensions.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.EntityFrameworkCore/Volo/Abp/SettingManagement/EntityFrameworkCore/SettingManagementDbContextModelBuilderExtensions.cs @@ -36,6 +36,21 @@ public static class SettingManagementDbContextModelBuilderExtensions b.ApplyObjectExtensionMappings(); }); + builder.Entity(b => + { + b.ToTable(AbpSettingManagementDbProperties.DbTablePrefix + "SettingDefinitionRecords", AbpSettingManagementDbProperties.DbSchema); + + b.ConfigureByConvention(); + + b.Property(x => x.Name).HasMaxLength(SettingDefinitionRecordConsts.MaxNameLength).IsRequired(); + b.Property(x => x.DisplayName).HasMaxLength(SettingDefinitionRecordConsts.MaxDisplayNameLength).IsRequired(); + b.Property(x => x.Providers).HasMaxLength(SettingDefinitionRecordConsts.MaxProvidersLength); + + b.HasIndex(x => new { x.Name }).IsUnique(); + + b.ApplyObjectExtensionMappings(); + }); + builder.TryConfigureObjectExtensions(); } } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.MongoDB/Volo/Abp/SettingManagement/MongoDB/AbpSettingManagementMongoDbModule.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.MongoDB/Volo/Abp/SettingManagement/MongoDB/AbpSettingManagementMongoDbModule.cs index e06f5bd86a..d77de425e2 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.MongoDB/Volo/Abp/SettingManagement/MongoDB/AbpSettingManagementMongoDbModule.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.MongoDB/Volo/Abp/SettingManagement/MongoDB/AbpSettingManagementMongoDbModule.cs @@ -17,6 +17,7 @@ public class AbpSettingManagementMongoDbModule : AbpModule options.AddDefaultRepositories(); options.AddRepository(); + options.AddRepository(); }); } } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.MongoDB/Volo/Abp/SettingManagement/MongoDB/ISettingManagementMongoDbContext.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.MongoDB/Volo/Abp/SettingManagement/MongoDB/ISettingManagementMongoDbContext.cs index 099c886e2d..1078e0a2f4 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.MongoDB/Volo/Abp/SettingManagement/MongoDB/ISettingManagementMongoDbContext.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.MongoDB/Volo/Abp/SettingManagement/MongoDB/ISettingManagementMongoDbContext.cs @@ -10,4 +10,5 @@ namespace Volo.Abp.SettingManagement.MongoDB; public interface ISettingManagementMongoDbContext : IAbpMongoDbContext { IMongoCollection Settings { get; } + IMongoCollection SettingDefinitionRecords { get; } } diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.MongoDB/Volo/Abp/SettingManagement/MongoDB/MongoSettingDefinitionRecordRepository.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.MongoDB/Volo/Abp/SettingManagement/MongoDB/MongoSettingDefinitionRecordRepository.cs new file mode 100644 index 0000000000..d2500cccd2 --- /dev/null +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.MongoDB/Volo/Abp/SettingManagement/MongoDB/MongoSettingDefinitionRecordRepository.cs @@ -0,0 +1,23 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using MongoDB.Driver.Linq; +using Volo.Abp.Domain.Repositories.MongoDB; +using Volo.Abp.MongoDB; + +namespace Volo.Abp.SettingManagement.MongoDB; + +public class MongoSettingDefinitionRecordRepository : MongoDbRepository, ISettingDefinitionRecordRepository +{ + public MongoSettingDefinitionRecordRepository(IMongoDbContextProvider dbContextProvider) + : base(dbContextProvider) + { + } + + public virtual async Task FindByNameAsync(string name, CancellationToken cancellationToken = default) + { + return await (await GetMongoQueryableAsync(cancellationToken)) + .OrderBy(x => x.Id) + .FirstOrDefaultAsync(s => s.Name == name, GetCancellationToken(cancellationToken)); + } +} diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.MongoDB/Volo/Abp/SettingManagement/MongoDB/SettingManagementMongoDbContext.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.MongoDB/Volo/Abp/SettingManagement/MongoDB/SettingManagementMongoDbContext.cs index b31e1c314d..159d792b27 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.MongoDB/Volo/Abp/SettingManagement/MongoDB/SettingManagementMongoDbContext.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.MongoDB/Volo/Abp/SettingManagement/MongoDB/SettingManagementMongoDbContext.cs @@ -10,6 +10,7 @@ namespace Volo.Abp.SettingManagement.MongoDB; public class SettingManagementMongoDbContext : AbpMongoDbContext, ISettingManagementMongoDbContext { public IMongoCollection Settings => Collection(); + public IMongoCollection SettingDefinitionRecords => Collection(); protected override void CreateModel(IMongoModelBuilder modelBuilder) { diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.MongoDB/Volo/Abp/SettingManagement/MongoDB/SettingManagementMongoDbContextExtensions.cs b/modules/setting-management/src/Volo.Abp.SettingManagement.MongoDB/Volo/Abp/SettingManagement/MongoDB/SettingManagementMongoDbContextExtensions.cs index 4b171c8181..5aa7f70391 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.MongoDB/Volo/Abp/SettingManagement/MongoDB/SettingManagementMongoDbContextExtensions.cs +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.MongoDB/Volo/Abp/SettingManagement/MongoDB/SettingManagementMongoDbContextExtensions.cs @@ -13,5 +13,10 @@ public static class SettingManagementMongoDbContextExtensions { b.CollectionName = AbpSettingManagementDbProperties.DbTablePrefix + "Settings"; }); + + builder.Entity(b => + { + b.CollectionName = AbpSettingManagementDbProperties.DbTablePrefix + "SettingDefinitionRecords"; + }); } } diff --git a/modules/setting-management/test/Volo.Abp.SettingManagement.Tests/Volo/Abp/SettingManagement/DefaultValueSettingManagementProvider_Tests.cs b/modules/setting-management/test/Volo.Abp.SettingManagement.Tests/Volo/Abp/SettingManagement/DefaultValueSettingManagementProvider_Tests.cs index f13019ab16..026d07aedb 100644 --- a/modules/setting-management/test/Volo.Abp.SettingManagement.Tests/Volo/Abp/SettingManagement/DefaultValueSettingManagementProvider_Tests.cs +++ b/modules/setting-management/test/Volo.Abp.SettingManagement.Tests/Volo/Abp/SettingManagement/DefaultValueSettingManagementProvider_Tests.cs @@ -17,7 +17,7 @@ public class DefaultValueSettingManagementProvider_Tests : SettingsTestBase [Fact] public async Task GetOrNullAsync() { - var mySetting3 = _settingDefinitionManager.Get("MySetting3"); + var mySetting3 = await _settingDefinitionManager.GetAsync("MySetting3"); var defaultValueSettingManagementProvider = new DefaultValueSettingManagementProvider(); (await defaultValueSettingManagementProvider @@ -27,7 +27,7 @@ public class DefaultValueSettingManagementProvider_Tests : SettingsTestBase [Fact] public async Task SetAsync() { - var mySetting3 = _settingDefinitionManager.Get("MySetting3"); + var mySetting3 = await _settingDefinitionManager.GetAsync("MySetting3"); await Assert.ThrowsAsync(async () => await new DefaultValueSettingManagementProvider().SetAsync(mySetting3, "123", DefaultValueSettingValueProvider.ProviderName)); @@ -36,7 +36,7 @@ public class DefaultValueSettingManagementProvider_Tests : SettingsTestBase [Fact] public async Task ClearAsync() { - var mySetting3 = _settingDefinitionManager.Get("MySetting3"); + var mySetting3 = await _settingDefinitionManager.GetAsync("MySetting3"); await Assert.ThrowsAsync(async () => await new DefaultValueSettingManagementProvider().ClearAsync(mySetting3,