Skip to content

Commit

Permalink
Merge pull request #994 from colinin/fix-saas-jobs
Browse files Browse the repository at this point in the history
Fix saas jobs
  • Loading branch information
colinin authored Aug 23, 2024
2 parents f513301 + 0d789b7 commit 47a955b
Show file tree
Hide file tree
Showing 11 changed files with 93 additions and 20 deletions.
7 changes: 7 additions & 0 deletions aspnet-core/LINGYUN.MicroService.SingleProject.sln
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.WeChat.Official
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.WeChat.Work.Handlers", "framework\wechat\LINGYUN.Abp.WeChat.Work.Handlers\LINGYUN.Abp.WeChat.Work.Handlers.csproj", "{DB80C55F-8B70-4840-942A-ED021ED88BD6}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.MultiTenancy.Saas", "modules\saas\LINGYUN.Abp.MultiTenancy.Saas\LINGYUN.Abp.MultiTenancy.Saas.csproj", "{E3C07A77-EAF9-4A3F-8814-7D2F116C8E26}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -1415,6 +1417,10 @@ Global
{DB80C55F-8B70-4840-942A-ED021ED88BD6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DB80C55F-8B70-4840-942A-ED021ED88BD6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DB80C55F-8B70-4840-942A-ED021ED88BD6}.Release|Any CPU.Build.0 = Release|Any CPU
{E3C07A77-EAF9-4A3F-8814-7D2F116C8E26}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E3C07A77-EAF9-4A3F-8814-7D2F116C8E26}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E3C07A77-EAF9-4A3F-8814-7D2F116C8E26}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E3C07A77-EAF9-4A3F-8814-7D2F116C8E26}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -1677,6 +1683,7 @@ Global
{4634B421-36E6-4169-AA1A-11050902495F} = {D94D6AFE-20BD-4F21-8708-03F5E34F49FC}
{BB2DF96A-6ED8-4F47-948C-230EA2065C4C} = {91867618-0D86-4410-91C6-B1166A9ACDF9}
{DB80C55F-8B70-4840-942A-ED021ED88BD6} = {91867618-0D86-4410-91C6-B1166A9ACDF9}
{E3C07A77-EAF9-4A3F-8814-7D2F116C8E26} = {ECE6E6D7-A4F6-4F50-BC21-AE2EB14A3129}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {711A43C0-A2F8-4E5C-9B9F-F2551E4B3FF1}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using LINGYUN.Abp.Saas.Tenants;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
Expand Down Expand Up @@ -43,13 +44,19 @@ public SingleDbMigrationEventHandler(
IGuidGenerator guidGenerator,
IdentityUserManager identityUserManager,
IdentityRoleManager identityRoleManager,
IPermissionDataSeeder permissionDataSeeder)
IPermissionDataSeeder permissionDataSeeder,
IJobStore jobStore,
IJobScheduler jobScheduler,
IOptions<AbpBackgroundTasksOptions> options)
: base("SingleDbMigrator", currentTenant, unitOfWorkManager, tenantStore, abpDistributedLock, distributedEventBus, loggerFactory)
{
GuidGenerator = guidGenerator;
IdentityUserManager = identityUserManager;
IdentityRoleManager = identityRoleManager;
PermissionDataSeeder = permissionDataSeeder;
JobStore = jobStore;
JobScheduler = jobScheduler;
Options = options.Value;
}
public async virtual Task HandleEventAsync(EntityDeletedEto<TenantEto> eventData)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public class AbpNotificationsApplicationAutoMapperProfile : Profile
public AbpNotificationsApplicationAutoMapperProfile()
{
CreateMap<UserNotificationInfo, UserNotificationDto>()
.ForMember(dto => dto.Id, map => map.MapFrom(src => src.Id.ToString()))
.ForMember(dto => dto.Id, map => map.MapFrom(src => src.NotificationId.ToString()))
.ForMember(dto => dto.Lifetime, map => map.Ignore())
.ForMember(dto => dto.Data, map => map.MapFrom((src, nfi) =>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public AbpNotificationsDomainAutoMapperProfile()
}));

CreateMap<UserNotificationInfo, NotificationInfo>()
.ForMember(dto => dto.Id, map => map.MapFrom(src => src.Id.ToString()))
.ForMember(dto => dto.Id, map => map.MapFrom(src => src.NotificationId.ToString()))
.ForMember(dto => dto.Name, map => map.MapFrom(src => src.Name))
.ForMember(dto => dto.Lifetime, map => map.Ignore())
.ForMember(dto => dto.Type, map => map.MapFrom(src => src.Type))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public class UserNotificationInfo
public Guid? TenantId { get; set; }
public string Name { get; set; }
public long Id { get; set; }
public long NotificationId { get; set; }
public ExtraPropertyDictionary ExtraProperties { get; set; }
public string NotificationTypeName { get; set; }
public DateTime CreationTime { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ on un.NotificationId equals n.NotificationId
where n.NotificationId.Equals(notificationId)
select new UserNotificationInfo
{
Id = n.NotificationId,
Id = un.Id,
NotificationId = n.NotificationId,
TenantId = n.TenantId,
Name = n.NotificationName,
ExtraProperties = n.ExtraProperties,
Expand Down Expand Up @@ -89,7 +90,7 @@ join n in dbContext.Set<Notification>()
on un.NotificationId equals n.NotificationId
select new UserNotificationInfo
{
Id = n.NotificationId,
NotificationId = n.NotificationId,
TenantId = n.TenantId,
Name = n.NotificationName,
ExtraProperties = n.ExtraProperties,
Expand Down Expand Up @@ -121,7 +122,7 @@ on un.NotificationId equals n.NotificationId
where un.UserId == userId
select new UserNotificationInfo
{
Id = n.NotificationId,
NotificationId = n.NotificationId,
TenantId = n.TenantId,
Name = n.NotificationName,
ExtraProperties = n.ExtraProperties,
Expand Down Expand Up @@ -170,7 +171,7 @@ on un.NotificationId equals n.NotificationId
where un.UserId == userId
select new UserNotificationInfo
{
Id = n.NotificationId,
NotificationId = n.NotificationId,
TenantId = n.TenantId,
Name = n.NotificationName,
ExtraProperties = n.ExtraProperties,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using LINGYUN.Abp.Saas.Features;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
Expand All @@ -8,7 +9,6 @@
using Volo.Abp.Application.Dtos;
using Volo.Abp.Data;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.Features;
using Volo.Abp.MultiTenancy;
using Volo.Abp.ObjectExtending;

Expand All @@ -20,15 +20,18 @@ public class TenantAppService : AbpSaasAppServiceBase, ITenantAppService
protected IDistributedEventBus EventBus { get; }
protected ITenantRepository TenantRepository { get; }
protected ITenantManager TenantManager { get; }
protected IConnectionStringChecker ConnectionStringChecker { get; }

public TenantAppService(
ITenantRepository tenantRepository,
ITenantManager tenantManager,
IDistributedEventBus eventBus)
IDistributedEventBus eventBus,
IConnectionStringChecker connectionStringChecker)
{
EventBus = eventBus;
TenantRepository = tenantRepository;
TenantManager = tenantManager;
ConnectionStringChecker = connectionStringChecker;
}

public async virtual Task<TenantDto> GetAsync(Guid id)
Expand Down Expand Up @@ -80,13 +83,15 @@ public async virtual Task<TenantDto> CreateAsync(TenantCreateDto input)

if (!input.UseSharedDatabase && !input.DefaultConnectionString.IsNullOrWhiteSpace())
{
await CheckConnectionString(input.DefaultConnectionString);
tenant.SetDefaultConnectionString(input.DefaultConnectionString);
}

if (input.ConnectionStrings.Any())
{
foreach (var connectionString in input.ConnectionStrings)
{
await CheckConnectionString(connectionString.Value, connectionString.Key);
tenant.SetConnectionString(connectionString.Key, connectionString.Value);
}
}
Expand Down Expand Up @@ -119,6 +124,7 @@ public async virtual Task<TenantDto> CreateAsync(TenantCreateDto input)
await EventBus.PublishAsync(eto);
});


await CurrentUnitOfWork.SaveChangesAsync();

return ObjectMapper.Map<Tenant, TenantDto>(tenant);
Expand Down Expand Up @@ -157,12 +163,17 @@ public async virtual Task DeleteAsync(Guid id)
}

// 租户删除时查询会失效, 在删除前确认
var strategy = await FeatureChecker.GetAsync(SaasFeatureNames.Tenant.RecycleStrategy, RecycleStrategy.Recycle);
var recycleStrategy = RecycleStrategy.Recycle;
var strategySet = await FeatureChecker.GetOrNullAsync(SaasFeatureNames.Tenant.RecycleStrategy);
if (!strategySet.IsNullOrWhiteSpace() && Enum.TryParse<RecycleStrategy>(strategySet, out var strategy))
{
recycleStrategy = strategy;
}
var eto = new TenantDeletedEto
{
Id = tenant.Id,
Name = tenant.Name,
Strategy = strategy,
Strategy = recycleStrategy,
EntityVersion = tenant.EntityVersion,
DefaultConnectionString = tenant.FindDefaultConnectionString(),
};
Expand Down Expand Up @@ -259,4 +270,34 @@ public async virtual Task DeleteConnectionStringAsync(Guid id, string name)

await CurrentUnitOfWork.SaveChangesAsync();
}

protected async virtual Task CheckConnectionString(string connectionString, string name = null)
{
try
{
var checkResult = await ConnectionStringChecker.CheckAsync(connectionString);
// 检查连接是否可用
if (!checkResult.Connected)
{
throw name.IsNullOrWhiteSpace()
? new BusinessException(AbpSaasErrorCodes.InvalidDefaultConnectionString)
: new BusinessException(AbpSaasErrorCodes.InvalidConnectionString)
.WithData("Name", name);
}
// 默认连接字符串改变不能影响到现有数据库
if (checkResult.DatabaseExists && name.IsNullOrWhiteSpace())
{
throw new BusinessException(AbpSaasErrorCodes.DefaultConnectionStringDatabaseExists);
}
}
catch (Exception e)
{
Logger.LogWarning("An error occurred while checking the validity of the connection string");
Logger.LogWarning(e.Message);
throw name.IsNullOrWhiteSpace()
? new BusinessException(AbpSaasErrorCodes.InvalidDefaultConnectionString)
: new BusinessException(AbpSaasErrorCodes.InvalidConnectionString)
.WithData("Name", name);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,16 @@ public static class AbpSaasErrorCodes
public const string DuplicateEditionDisplayName = Namespace + ":010001";
public const string DeleteUsedEdition = Namespace + ":010002";
public const string DuplicateTenantName = Namespace + ":020001";
/// <summary>
/// 无效的默认连接字符串
/// </summary>
public const string InvalidDefaultConnectionString = Namespace + ":020101";
/// <summary>
/// 默认连接字符串指向的数据库已经存在
/// </summary>
public const string DefaultConnectionStringDatabaseExists = Namespace + ":020102";
/// <summary>
/// {Name} 的连接字符串无效
/// </summary>
public const string InvalidConnectionString = Namespace + ":020103";
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
"Saas:010001": "Unable to create duplicate editions {DisplayName}!",
"Saas:010002": "Tried to delete the edition in use: {DisplayName}!",
"Saas:020001": "Unable to create duplicate tenants {Name}!",
"Saas:020002": "The database string that cannot be connected!",
"Saas:020101": "The default connection string cannot open a connection to the database!",
"Saas:020102": "The database pointed to by the default connection string already exists!",
"Saas:020103": "Unable to open the database connection pointed to by {Name}!",
"Volo.AbpIo.MultiTenancy:010001": "The tenant is unavailable or restricted!",
"Volo.AbpIo.MultiTenancy:010002": "Tenant unavailable!",
"Menu:Saas": "Saas",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
"Saas:010001": "已经存在名为 {DisplayName} 的版本!",
"Saas:010002": "试图删除正在使用的版本: {DisplayName}!",
"Saas:020001": "已经存在名为 {Name} 的租户!",
"Saas:020002": "无法连接的数据库字符串!",
"Saas:020101": "无法打开默认连接字符串指向的数据库连接!",
"Saas:020102": "默认连接字符串指向的数据库已经存在!",
"Saas:020103": "无法打开 {Name} 指向的数据库连接!",
"Volo.AbpIo.MultiTenancy:010001": "租户不可用或受限制!",
"Volo.AbpIo.MultiTenancy:010002": "租户不可用!",
"Menu:Saas": "Saas",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,22 @@ public override void Define(IFeatureDefinitionContext context)
ItemSource = new StaticSelectionStringValueItemSource(
new LocalizableSelectionStringValueItem
{
Value = RecycleStrategy.Reserve.ToString(),
Value = "0",
DisplayText = new LocalizableStringInfo(
LocalizationResourceNameAttribute.GetName(typeof(AbpSaasResource)),
"RecycleStrategy:Reserve")
LocalizationResourceNameAttribute.GetName(typeof(AbpSaasResource)),
"RecycleStrategy:Reserve")
},
new LocalizableSelectionStringValueItem
{
Value = RecycleStrategy.Recycle.ToString(),
Value = "1",
DisplayText = new LocalizableStringInfo(
LocalizationResourceNameAttribute.GetName(typeof(AbpSaasResource)),
"RecycleStrategy:Recycle")
LocalizationResourceNameAttribute.GetName(typeof(AbpSaasResource)),
"RecycleStrategy:Recycle")
})
};
saas.AddFeature(
name: SaasFeatureNames.Tenant.RecycleStrategy,
defaultValue: RecycleStrategy.Recycle.ToString(),
defaultValue: "1",
displayName: L("Features:RecycleStrategy"),
description: L("Features:RecycleStrategyDesc"),
valueType: selectionValueType,
Expand Down

0 comments on commit 47a955b

Please sign in to comment.