Browse Source

isolate built-in jobs from ordinary users

pull/538/head
cKey 4 years ago
parent
commit
6e39cec530
  1. 8
      apps/vue/src/api/task-management/model/backgroundJobInfoModel.ts
  2. 22
      apps/vue/src/views/task-management/background-jobs/datas/ModalData.ts
  3. 8
      apps/vue/src/views/task-management/background-jobs/datas/typing.ts
  4. 6
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobInfo.cs
  5. 19
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobSource.cs
  6. 1
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/BackgroundJobManager.cs
  7. 1
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/BackgroundWorkerAdapter.cs
  8. 2
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/DefaultBackgroundWorker.cs
  9. 4
      aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Application.Contracts/LINGYUN/Abp/TaskManagement/BackgroundJobInfoDto.cs
  10. 4
      aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Application.Contracts/LINGYUN/Abp/TaskManagement/BackgroundJobInfoGetListInput.cs
  11. 3
      aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Application.Contracts/LINGYUN/Abp/TaskManagement/Permissions/TaskManagementPermissionDefinitionProvider.cs
  12. 5
      aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Application.Contracts/LINGYUN/Abp/TaskManagement/Permissions/TaskManagementPermissions.cs
  13. 55
      aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Application/LINGYUN/Abp/TaskManagement/BackgroundJobInfoAppService.cs
  14. 3
      aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain.Shared/LINGYUN/Abp/TaskManagement/Localization/Resources/en.json
  15. 3
      aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain.Shared/LINGYUN/Abp/TaskManagement/Localization/Resources/zh-Hans.json
  16. 6
      aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/LINGYUN/Abp/TaskManagement/BackgroundJobInfo.cs
  17. 4
      aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/LINGYUN/Abp/TaskManagement/BackgroundJobInfoFilter.cs
  18. 1
      aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/LINGYUN/Abp/TaskManagement/BackgroundJobStore.cs
  19. 58
      aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.EntityFrameworkCore/LINGYUN/Abp/TaskManagement/EntityFrameworkCore/EfCoreBackgroundJobInfoRepository.cs
  20. 7
      aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.EntityFrameworkCore/LINGYUN/Abp/TaskManagement/EntityFrameworkCore/TaskManagementDbContextModelCreatingExtensions.cs
  21. 2
      aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/EventBus/Handlers/TenantSynchronizer.cs
  22. 208
      aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Migrations/20220330013146_Add-Field-Source-With-BackgroundJobInfo.Designer.cs
  23. 26
      aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Migrations/20220330013146_Add-Field-Source-With-BackgroundJobInfo.cs
  24. 8
      aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Migrations/TaskManagementMigrationsDbContextModelSnapshot.cs

8
apps/vue/src/api/task-management/model/backgroundJobInfoModel.ts

@ -15,6 +15,12 @@ export enum JobType {
Persistent, Persistent,
} }
export enum JobSource {
None = -1,
User = 0,
System = 10,
}
export enum JobPriority { export enum JobPriority {
Low = 5, Low = 5,
BelowNormal = 10, BelowNormal = 10,
@ -44,6 +50,7 @@ export interface BackgroundJobInfo extends ExtensibleAuditedEntity<string>, IHas
isAbandoned: boolean; isAbandoned: boolean;
interval: number; interval: number;
priority: JobPriority; priority: JobPriority;
source: JobSource;
lockTimeOut: number; lockTimeOut: number;
} }
@ -86,4 +93,5 @@ export interface BackgroundJobInfoGetListInput extends PagedAndSortedResultReque
isAbandoned?: boolean; isAbandoned?: boolean;
jobType?: JobType; jobType?: JobType;
priority?: JobPriority; priority?: JobPriority;
source?: JobSource;
} }

22
apps/vue/src/views/task-management/background-jobs/datas/ModalData.ts

@ -1,7 +1,7 @@
import { useLocalization } from '/@/hooks/abp/useLocalization'; import { useLocalization } from '/@/hooks/abp/useLocalization';
import { FormProps } from '/@/components/Form'; import { FormProps } from '/@/components/Form';
import { JobStatus, JobType, JobPriority } from '/@/api/task-management/model/backgroundJobInfoModel'; import { JobStatus, JobType, JobPriority, JobSource } from '/@/api/task-management/model/backgroundJobInfoModel';
import { JobStatusMap, JobTypeMap, JobPriorityMap } from './typing'; import { JobStatusMap, JobTypeMap, JobPriorityMap, JobSourceMap } from './typing';
const { L } = useLocalization('TaskManagement', 'AbpUi'); const { L } = useLocalization('TaskManagement', 'AbpUi');
@ -56,11 +56,25 @@ export function getSearchFormSchemas(): Partial<FormProps> {
], ],
}, },
}, },
{
field: 'source',
component: 'Select',
label: L('DisplayName:Source'),
colProps: { span: 6 },
defaultValue: JobSource.User,
componentProps: {
options: [
{ label: JobSourceMap[JobSource.None], value: JobSource.None },
{ label: JobSourceMap[JobSource.User], value: JobSource.User },
{ label: JobSourceMap[JobSource.System], value: JobSource.System },
],
},
},
{ {
field: 'beginTime', field: 'beginTime',
component: 'DatePicker', component: 'DatePicker',
label: L('DisplayName:BeginTime'), label: L('DisplayName:BeginTime'),
colProps: { span: 9 }, colProps: { span: 6 },
componentProps: { componentProps: {
style: { style: {
width: '100%', width: '100%',
@ -71,7 +85,7 @@ export function getSearchFormSchemas(): Partial<FormProps> {
field: 'endTime', field: 'endTime',
component: 'DatePicker', component: 'DatePicker',
label: L('DisplayName:EndTime'), label: L('DisplayName:EndTime'),
colProps: { span: 9 }, colProps: { span: 6 },
componentProps: { componentProps: {
style: { style: {
width: '100%', width: '100%',

8
apps/vue/src/views/task-management/background-jobs/datas/typing.ts

@ -1,4 +1,4 @@
import { JobStatus, JobType, JobPriority } from '/@/api/task-management/model/backgroundJobInfoModel'; import { JobStatus, JobType, JobPriority, JobSource } from '/@/api/task-management/model/backgroundJobInfoModel';
import { useLocalization } from '/@/hooks/abp/useLocalization'; import { useLocalization } from '/@/hooks/abp/useLocalization';
const { L } = useLocalization('TaskManagement'); const { L } = useLocalization('TaskManagement');
@ -41,3 +41,9 @@ export const JobPriorityColor = {
[JobPriority.AboveNormal]: 'orange', [JobPriority.AboveNormal]: 'orange',
[JobPriority.High]: 'red', [JobPriority.High]: 'red',
} }
export const JobSourceMap = {
[JobSource.None]: L('DisplayName:None'),
[JobSource.User]: L('DisplayName:User'),
[JobSource.System]: L('DisplayName:System'),
}

6
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobInfo.cs

@ -30,9 +30,13 @@ public class JobInfo
/// </summary> /// </summary>
public string Result { get; set; } public string Result { get; set; }
/// <summary> /// <summary>
/// 作业来源
/// </summary>
public JobSource Source { get; set; } = JobSource.None;
/// <summary>
/// 任务参数 /// 任务参数
/// </summary> /// </summary>
public IDictionary<string, object> Args { get; set; } public IDictionary<string, object> Args { get; set; } = new Dictionary<string, object>();
/// <summary> /// <summary>
/// 任务状态 /// 任务状态
/// </summary> /// </summary>

19
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobSource.cs

@ -0,0 +1,19 @@
namespace LINGYUN.Abp.BackgroundTasks;
/// <summary>
/// 作业来源
/// </summary>
public enum JobSource
{
/// <summary>
/// 未定义
/// </summary>
None = -1,
/// <summary>
/// 用户
/// </summary>
User = 0,
/// <summary>
/// 系统内置
/// </summary>
System = 10,
}

1
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/BackgroundJobManager.cs

@ -65,6 +65,7 @@ public class BackgroundJobManager : IBackgroundJobManager, ITransientDependency
Name = jobId.ToString(), Name = jobId.ToString(),
Group = "BackgroundJobs", Group = "BackgroundJobs",
Priority = ConverForm(priority), Priority = ConverForm(priority),
Source = JobSource.System,
BeginTime = DateTime.Now, BeginTime = DateTime.Now,
Args = jobArgs, Args = jobArgs,
Description = "From the framework background jobs", Description = "From the framework background jobs",

1
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/BackgroundWorkerAdapter.cs

@ -74,6 +74,7 @@ public class BackgroundWorkerAdapter<TWorker> : BackgroundWorkerBase, IBackgroun
Name = workerType.FullName, Name = workerType.FullName,
Group = "BackgroundWorkers", Group = "BackgroundWorkers",
Priority = JobPriority.Normal, Priority = JobPriority.Normal,
Source = JobSource.System,
BeginTime = Clock.Now, BeginTime = Clock.Now,
Args = jobArgs, Args = jobArgs,
Description = "From the framework background workers", Description = "From the framework background workers",

2
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/DefaultBackgroundWorker.cs

@ -62,6 +62,7 @@ internal class DefaultBackgroundWorker : BackgroundService
Cron = _options.JobFetchCronExpression, Cron = _options.JobFetchCronExpression,
JobType = JobType.Period, JobType = JobType.Period,
Priority = JobPriority.High, Priority = JobPriority.High,
Source = JobSource.System,
LockTimeOut = _options.JobFetchLockTimeOut, LockTimeOut = _options.JobFetchLockTimeOut,
Type = typeof(BackgroundPollingJob).AssemblyQualifiedName, Type = typeof(BackgroundPollingJob).AssemblyQualifiedName,
}; };
@ -82,6 +83,7 @@ internal class DefaultBackgroundWorker : BackgroundService
Cron = _options.JobCleanCronExpression, Cron = _options.JobCleanCronExpression,
JobType = JobType.Period, JobType = JobType.Period,
Priority = JobPriority.High, Priority = JobPriority.High,
Source = JobSource.System,
Type = typeof(BackgroundCleaningJob).AssemblyQualifiedName, Type = typeof(BackgroundCleaningJob).AssemblyQualifiedName,
}; };
} }

4
aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Application.Contracts/LINGYUN/Abp/TaskManagement/BackgroundJobInfoDto.cs

@ -97,6 +97,10 @@ public class BackgroundJobInfoDto : ExtensibleAuditedEntityDto<string>, IHasConc
/// </summary> /// </summary>
public JobPriority Priority { get; set; } public JobPriority Priority { get; set; }
/// <summary> /// <summary>
/// 作业来源
/// </summary>
public JobSource Source { get; set; }
/// <summary>
/// 任务独占超时时长(秒) /// 任务独占超时时长(秒)
/// 0或更小不生效 /// 0或更小不生效
/// </summary> /// </summary>

4
aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Application.Contracts/LINGYUN/Abp/TaskManagement/BackgroundJobInfoGetListInput.cs

@ -62,4 +62,8 @@ public class BackgroundJobInfoGetListInput: PagedAndSortedResultRequestDto
/// 优先级 /// 优先级
/// </summary> /// </summary>
public JobPriority? Priority { get; set; } public JobPriority? Priority { get; set; }
/// <summary>
/// 作业来源
/// </summary>
public JobSource? Source { get; set; }
} }

3
aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Application.Contracts/LINGYUN/Abp/TaskManagement/Permissions/TaskManagementPermissionDefinitionProvider.cs

@ -39,6 +39,9 @@ public class TaskManagementPermissionDefinitionProvider : PermissionDefinitionPr
backgroundJobs.AddChild( backgroundJobs.AddChild(
TaskManagementPermissions.BackgroundJobs.Stop, TaskManagementPermissions.BackgroundJobs.Stop,
L("Permissions:StopJob")); L("Permissions:StopJob"));
backgroundJobs.AddChild(
TaskManagementPermissions.BackgroundJobs.ManageSystemJobs,
L("Permissions:ManageSystemJobs"));
var backgroundJobLogs = group.AddPermission( var backgroundJobLogs = group.AddPermission(
TaskManagementPermissions.BackgroundJobLogs.Default, TaskManagementPermissions.BackgroundJobLogs.Default,

5
aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Application.Contracts/LINGYUN/Abp/TaskManagement/Permissions/TaskManagementPermissions.cs

@ -15,6 +15,11 @@ public static class TaskManagementPermissions
public const string Resume = Default + ".Resume"; public const string Resume = Default + ".Resume";
public const string Start = Default + ".Start"; public const string Start = Default + ".Start";
public const string Stop = Default + ".Stop"; public const string Stop = Default + ".Stop";
/// <summary>
/// 是否允许管理系统内置作业
/// 通常内置作业是由程序运行中产生,需要控制用户行为
/// </summary>
public const string ManageSystemJobs = Default + ".ManageSystemJobs";
} }
public static class BackgroundJobLogs public static class BackgroundJobLogs

55
aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Application/LINGYUN/Abp/TaskManagement/BackgroundJobInfoAppService.cs

@ -1,7 +1,6 @@
using LINGYUN.Abp.BackgroundTasks; using LINGYUN.Abp.BackgroundTasks;
using LINGYUN.Abp.TaskManagement.Permissions; using LINGYUN.Abp.TaskManagement.Permissions;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -45,6 +44,7 @@ public class BackgroundJobInfoAppService : TaskManagementApplicationService, IBa
input.BeginTime, input.BeginTime,
input.EndTime, input.EndTime,
input.Priority, input.Priority,
JobSource.User,
input.MaxCount, input.MaxCount,
input.MaxTryCount, input.MaxTryCount,
CurrentTenant.Id); CurrentTenant.Id);
@ -66,6 +66,8 @@ public class BackgroundJobInfoAppService : TaskManagementApplicationService, IBa
{ {
var backgroundJobInfo = await BackgroundJobInfoRepository.GetAsync(id); var backgroundJobInfo = await BackgroundJobInfoRepository.GetAsync(id);
await CheckIfChangeSystemJob(backgroundJobInfo);
await BackgroundJobManager.DeleteAsync(backgroundJobInfo); await BackgroundJobManager.DeleteAsync(backgroundJobInfo);
} }
@ -92,6 +94,7 @@ public class BackgroundJobInfoAppService : TaskManagementApplicationService, IBa
Group = input.Group, Group = input.Group,
Name = input.Name, Name = input.Name,
Priority = input.Priority, Priority = input.Priority,
Source = input.Source,
Status = input.Status, Status = input.Status,
Type = input.Type Type = input.Type
}; };
@ -108,6 +111,8 @@ public class BackgroundJobInfoAppService : TaskManagementApplicationService, IBa
{ {
var backgroundJobInfo = await BackgroundJobInfoRepository.GetAsync(id); var backgroundJobInfo = await BackgroundJobInfoRepository.GetAsync(id);
await CheckIfChangeSystemJob(backgroundJobInfo);
await BackgroundJobManager.PauseAsync(backgroundJobInfo); await BackgroundJobManager.PauseAsync(backgroundJobInfo);
} }
@ -116,6 +121,8 @@ public class BackgroundJobInfoAppService : TaskManagementApplicationService, IBa
{ {
var backgroundJobInfo = await BackgroundJobInfoRepository.GetAsync(id); var backgroundJobInfo = await BackgroundJobInfoRepository.GetAsync(id);
await CheckIfChangeSystemJob(backgroundJobInfo);
await BackgroundJobManager.ResumeAsync(backgroundJobInfo); await BackgroundJobManager.ResumeAsync(backgroundJobInfo);
} }
@ -124,6 +131,8 @@ public class BackgroundJobInfoAppService : TaskManagementApplicationService, IBa
{ {
var backgroundJobInfo = await BackgroundJobInfoRepository.GetAsync(id); var backgroundJobInfo = await BackgroundJobInfoRepository.GetAsync(id);
await CheckIfChangeSystemJob(backgroundJobInfo);
await BackgroundJobManager.TriggerAsync(backgroundJobInfo); await BackgroundJobManager.TriggerAsync(backgroundJobInfo);
} }
@ -132,6 +141,8 @@ public class BackgroundJobInfoAppService : TaskManagementApplicationService, IBa
{ {
var backgroundJobInfo = await BackgroundJobInfoRepository.GetAsync(id); var backgroundJobInfo = await BackgroundJobInfoRepository.GetAsync(id);
await CheckIfChangeSystemJob(backgroundJobInfo);
await BackgroundJobManager.StopAsync(backgroundJobInfo); await BackgroundJobManager.StopAsync(backgroundJobInfo);
} }
@ -140,6 +151,8 @@ public class BackgroundJobInfoAppService : TaskManagementApplicationService, IBa
{ {
var backgroundJobInfo = await BackgroundJobInfoRepository.GetAsync(id); var backgroundJobInfo = await BackgroundJobInfoRepository.GetAsync(id);
await CheckIfChangeSystemJob(backgroundJobInfo);
await BackgroundJobManager.QueueAsync(backgroundJobInfo); await BackgroundJobManager.QueueAsync(backgroundJobInfo);
} }
@ -148,6 +161,8 @@ public class BackgroundJobInfoAppService : TaskManagementApplicationService, IBa
{ {
var backgroundJobInfo = await BackgroundJobInfoRepository.GetAsync(id); var backgroundJobInfo = await BackgroundJobInfoRepository.GetAsync(id);
await CheckIfChangeSystemJob(backgroundJobInfo);
var resetJob = backgroundJobInfo.JobType == input.JobType; var resetJob = backgroundJobInfo.JobType == input.JobType;
UpdateByInput(backgroundJobInfo, input); UpdateByInput(backgroundJobInfo, input);
@ -168,6 +183,11 @@ public class BackgroundJobInfoAppService : TaskManagementApplicationService, IBa
} }
var jobs = await GetListAsync(input); var jobs = await GetListAsync(input);
if (jobs.Any(job => job.Source == JobSource.System))
{
await AuthorizationService.CheckAsync(TaskManagementPermissions.BackgroundJobs.ManageSystemJobs);
}
await BackgroundJobManager.BulkDeleteAsync(jobs); await BackgroundJobManager.BulkDeleteAsync(jobs);
} }
@ -180,6 +200,11 @@ public class BackgroundJobInfoAppService : TaskManagementApplicationService, IBa
} }
var jobs = await GetListAsync(input); var jobs = await GetListAsync(input);
if (jobs.Any(job => job.Source == JobSource.System))
{
await AuthorizationService.CheckAsync(TaskManagementPermissions.BackgroundJobs.ManageSystemJobs);
}
await BackgroundJobManager.BulkStopAsync(jobs); await BackgroundJobManager.BulkStopAsync(jobs);
} }
@ -192,6 +217,11 @@ public class BackgroundJobInfoAppService : TaskManagementApplicationService, IBa
} }
var jobs = await GetListAsync(input); var jobs = await GetListAsync(input);
if (jobs.Any(job => job.Source == JobSource.System))
{
await AuthorizationService.CheckAsync(TaskManagementPermissions.BackgroundJobs.ManageSystemJobs);
}
await BackgroundJobManager.BulkQueueAsync(jobs); await BackgroundJobManager.BulkQueueAsync(jobs);
} }
@ -204,6 +234,11 @@ public class BackgroundJobInfoAppService : TaskManagementApplicationService, IBa
} }
var jobs = await GetListAsync(input); var jobs = await GetListAsync(input);
if (jobs.Any(job => job.Source == JobSource.System))
{
await AuthorizationService.CheckAsync(TaskManagementPermissions.BackgroundJobs.ManageSystemJobs);
}
await BackgroundJobManager.BulkTriggerAsync(jobs); await BackgroundJobManager.BulkTriggerAsync(jobs);
} }
@ -216,6 +251,11 @@ public class BackgroundJobInfoAppService : TaskManagementApplicationService, IBa
} }
var jobs = await GetListAsync(input); var jobs = await GetListAsync(input);
if (jobs.Any(job => job.Source == JobSource.System))
{
await AuthorizationService.CheckAsync(TaskManagementPermissions.BackgroundJobs.ManageSystemJobs);
}
await BackgroundJobManager.BulkResumeAsync(jobs); await BackgroundJobManager.BulkResumeAsync(jobs);
} }
@ -228,6 +268,11 @@ public class BackgroundJobInfoAppService : TaskManagementApplicationService, IBa
} }
var jobs = await GetListAsync(input); var jobs = await GetListAsync(input);
if (jobs.Any(job => job.Source == JobSource.System))
{
await AuthorizationService.CheckAsync(TaskManagementPermissions.BackgroundJobs.ManageSystemJobs);
}
await BackgroundJobManager.BulkPauseAsync(jobs); await BackgroundJobManager.BulkPauseAsync(jobs);
} }
@ -262,4 +307,12 @@ public class BackgroundJobInfoAppService : TaskManagementApplicationService, IBa
break; break;
} }
} }
protected async virtual Task CheckIfChangeSystemJob(BackgroundJobInfo backgroundJobInfo)
{
if (backgroundJobInfo.Source == JobSource.System)
{
await AuthorizationService.CheckAsync(TaskManagementPermissions.BackgroundJobs.ManageSystemJobs);
}
}
} }

3
aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain.Shared/LINGYUN/Abp/TaskManagement/Localization/Resources/en.json

@ -11,6 +11,7 @@
"Permissions:ResumeJob": "Resume Job", "Permissions:ResumeJob": "Resume Job",
"Permissions:StartJob": "Start Job", "Permissions:StartJob": "Start Job",
"Permissions:StopJob": "Stop Job", "Permissions:StopJob": "Stop Job",
"Permissions:ManageSystemJobs": "Manage System Jobs",
"Permissions:BackgroundJobLogs": "BackgroundJobs Logs", "Permissions:BackgroundJobLogs": "BackgroundJobs Logs",
"Permissions:DeleteJobLogs": "Delete Job Logs", "Permissions:DeleteJobLogs": "Delete Job Logs",
"TaskManagement:01000": "A job named {Name} already exists in the Group {Group}!", "TaskManagement:01000": "A job named {Name} already exists in the Group {Group}!",
@ -66,6 +67,8 @@
"DisplayName:Normal": "Normal", "DisplayName:Normal": "Normal",
"DisplayName:AboveNormal": "Above Normal", "DisplayName:AboveNormal": "Above Normal",
"DisplayName:High": "High", "DisplayName:High": "High",
"DisplayName:User": "User",
"DisplayName:System": "System",
"BackgroundJobs": "Jobs", "BackgroundJobs": "Jobs",
"BackgroundJobDetail": "Job Detail", "BackgroundJobDetail": "Job Detail",
"BackgroundJobLogs": "Job Logs", "BackgroundJobLogs": "Job Logs",

3
aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain.Shared/LINGYUN/Abp/TaskManagement/Localization/Resources/zh-Hans.json

@ -11,6 +11,7 @@
"Permissions:ResumeJob": "恢复作业", "Permissions:ResumeJob": "恢复作业",
"Permissions:StartJob": "启动作业", "Permissions:StartJob": "启动作业",
"Permissions:StopJob": "停止作业", "Permissions:StopJob": "停止作业",
"Permissions:ManageSystemJobs": "管理系统作业",
"Permissions:BackgroundJobLogs": "日志管理", "Permissions:BackgroundJobLogs": "日志管理",
"Permissions:DeleteJobLogs": "删除作业日志", "Permissions:DeleteJobLogs": "删除作业日志",
"TaskManagement:01000": "分组 {Group} 中已经存在一个名称为 {Name} 的作业!", "TaskManagement:01000": "分组 {Group} 中已经存在一个名称为 {Name} 的作业!",
@ -66,6 +67,8 @@
"DisplayName:Normal": "正常", "DisplayName:Normal": "正常",
"DisplayName:AboveNormal": "高于正常", "DisplayName:AboveNormal": "高于正常",
"DisplayName:High": "高", "DisplayName:High": "高",
"DisplayName:User": "用户",
"DisplayName:System": "系统内置",
"BackgroundJobs": "作业列表", "BackgroundJobs": "作业列表",
"BackgroundJobDetail": "作业详情", "BackgroundJobDetail": "作业详情",
"BackgroundJobLogs": "作业日志", "BackgroundJobLogs": "作业日志",

6
aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/LINGYUN/Abp/TaskManagement/BackgroundJobInfo.cs

@ -73,6 +73,10 @@ public class BackgroundJobInfo : AuditedAggregateRoot<string>, IMultiTenant
/// </summary> /// </summary>
public virtual string Cron { get; protected set; } public virtual string Cron { get; protected set; }
/// <summary> /// <summary>
/// 作业来源
/// </summary>
public virtual JobSource Source { get; protected set; }
/// <summary>
/// 任务优先级 /// 任务优先级
/// </summary> /// </summary>
public virtual JobPriority Priority { get; protected set; } public virtual JobPriority Priority { get; protected set; }
@ -115,6 +119,7 @@ public class BackgroundJobInfo : AuditedAggregateRoot<string>, IMultiTenant
DateTime beginTime, DateTime beginTime,
DateTime? endTime = null, DateTime? endTime = null,
JobPriority priority = JobPriority.Normal, JobPriority priority = JobPriority.Normal,
JobSource source = JobSource.None,
int maxCount = 0, int maxCount = 0,
int maxTryCount = 50, int maxTryCount = 50,
Guid? tenantId = null) : base(id) Guid? tenantId = null) : base(id)
@ -123,6 +128,7 @@ public class BackgroundJobInfo : AuditedAggregateRoot<string>, IMultiTenant
Group = Check.NotNullOrWhiteSpace(group, nameof(group), BackgroundJobInfoConsts.MaxGroupLength); Group = Check.NotNullOrWhiteSpace(group, nameof(group), BackgroundJobInfoConsts.MaxGroupLength);
Type = Check.NotNullOrWhiteSpace(type, nameof(type), BackgroundJobInfoConsts.MaxTypeLength); Type = Check.NotNullOrWhiteSpace(type, nameof(type), BackgroundJobInfoConsts.MaxTypeLength);
Priority = priority; Priority = priority;
Source = source;
BeginTime = beginTime; BeginTime = beginTime;
EndTime = endTime; EndTime = endTime;

4
aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/LINGYUN/Abp/TaskManagement/BackgroundJobInfoFilter.cs

@ -64,4 +64,8 @@ public class BackgroundJobInfoFilter
/// 优先级 /// 优先级
/// </summary> /// </summary>
public JobPriority? Priority { get; set; } public JobPriority? Priority { get; set; }
/// <summary>
/// 作业来源
/// </summary>
public JobSource? Source { get; set; }
} }

1
aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/LINGYUN/Abp/TaskManagement/BackgroundJobStore.cs

@ -79,6 +79,7 @@ public class BackgroundJobStore : IJobStore, ITransientDependency
jobInfo.BeginTime, jobInfo.BeginTime,
jobInfo.EndTime, jobInfo.EndTime,
jobInfo.Priority, jobInfo.Priority,
jobInfo.Source,
jobInfo.MaxCount, jobInfo.MaxCount,
jobInfo.MaxTryCount) jobInfo.MaxTryCount)
{ {

58
aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.EntityFrameworkCore/LINGYUN/Abp/TaskManagement/EntityFrameworkCore/EfCoreBackgroundJobInfoRepository.cs

@ -63,6 +63,7 @@ public class EfCoreBackgroundJobInfoRepository :
JobType = x.JobType, JobType = x.JobType,
Status = x.Status, Status = x.Status,
Priority = x.Priority, Priority = x.Priority,
Source = x.Source,
LastRunTime = x.LastRunTime, LastRunTime = x.LastRunTime,
LockTimeOut = x.LockTimeOut, LockTimeOut = x.LockTimeOut,
Result = x.Result, Result = x.Result,
@ -103,43 +104,13 @@ public class EfCoreBackgroundJobInfoRepository :
public virtual async Task<int> GetCountAsync(BackgroundJobInfoFilter filter, CancellationToken cancellationToken = default) public virtual async Task<int> GetCountAsync(BackgroundJobInfoFilter filter, CancellationToken cancellationToken = default)
{ {
return await (await GetDbSetAsync()) return await ApplyFilter(await GetDbSetAsync(), filter)
.WhereIf(!filter.Type.IsNullOrWhiteSpace(), x => x.Type.Contains(filter.Type))
.WhereIf(!filter.Group.IsNullOrWhiteSpace(), x => x.Group.Equals(filter.Group))
.WhereIf(!filter.Name.IsNullOrWhiteSpace(), x => x.Name.Equals(filter.Name))
.WhereIf(!filter.Filter.IsNullOrWhiteSpace(), x => x.Name.Contains(filter.Filter) ||
x.Group.Contains(filter.Filter) || x.Type.Contains(filter.Filter) || x.Description.Contains(filter.Filter))
.WhereIf(filter.JobType.HasValue, x => x.JobType == filter.JobType)
.WhereIf(filter.Priority.HasValue, x => x.Priority == filter.Priority.Value)
.WhereIf(filter.Status.HasValue, x => x.Status == filter.Status.Value)
.WhereIf(filter.IsAbandoned.HasValue, x => x.IsAbandoned == filter.IsAbandoned.Value)
.WhereIf(filter.BeginLastRunTime.HasValue, x => filter.BeginLastRunTime.Value.CompareTo(x.LastRunTime) <= 0)
.WhereIf(filter.EndLastRunTime.HasValue, x => filter.EndLastRunTime.Value.CompareTo(x.LastRunTime) >= 0)
.WhereIf(filter.BeginTime.HasValue, x => x.BeginTime.CompareTo(x.BeginTime) >= 0)
.WhereIf(filter.EndTime.HasValue, x => filter.EndTime.Value.CompareTo(x.EndTime) >= 0)
.WhereIf(filter.BeginCreationTime.HasValue, x => x.CreationTime.CompareTo(filter.BeginCreationTime.Value) >= 0)
.WhereIf(filter.EndCreationTime.HasValue, x => x.CreationTime.CompareTo(filter.EndCreationTime.Value) <= 0)
.CountAsync(GetCancellationToken(cancellationToken)); .CountAsync(GetCancellationToken(cancellationToken));
} }
public virtual async Task<List<BackgroundJobInfo>> GetListAsync(BackgroundJobInfoFilter filter, string sorting = "Name", int maxResultCount = 10, int skipCount = 0, CancellationToken cancellationToken = default) public virtual async Task<List<BackgroundJobInfo>> GetListAsync(BackgroundJobInfoFilter filter, string sorting = "Name", int maxResultCount = 10, int skipCount = 0, CancellationToken cancellationToken = default)
{ {
return await (await GetDbSetAsync()) return await ApplyFilter(await GetDbSetAsync(), filter)
.WhereIf(!filter.Type.IsNullOrWhiteSpace(), x => x.Type.Contains(filter.Type))
.WhereIf(!filter.Group.IsNullOrWhiteSpace(), x => x.Group.Equals(filter.Group))
.WhereIf(!filter.Name.IsNullOrWhiteSpace(), x => x.Name.Equals(filter.Name))
.WhereIf(!filter.Filter.IsNullOrWhiteSpace(), x => x.Name.Contains(filter.Filter) ||
x.Group.Contains(filter.Filter) || x.Type.Contains(filter.Filter) || x.Description.Contains(filter.Filter))
.WhereIf(filter.JobType.HasValue, x => x.JobType == filter.JobType)
.WhereIf(filter.Status.HasValue, x => x.Status == filter.Status.Value)
.WhereIf(filter.Priority.HasValue, x => x.Priority == filter.Priority.Value)
.WhereIf(filter.IsAbandoned.HasValue, x => x.IsAbandoned == filter.IsAbandoned.Value)
.WhereIf(filter.BeginLastRunTime.HasValue, x => filter.BeginLastRunTime.Value.CompareTo(x.LastRunTime) <= 0)
.WhereIf(filter.EndLastRunTime.HasValue, x => filter.EndLastRunTime.Value.CompareTo(x.LastRunTime) >= 0)
.WhereIf(filter.BeginTime.HasValue, x => x.BeginTime.CompareTo(x.BeginTime) >= 0)
.WhereIf(filter.EndTime.HasValue, x => filter.EndTime.Value.CompareTo(x.EndTime) >= 0)
.WhereIf(filter.BeginCreationTime.HasValue, x => x.CreationTime.CompareTo(filter.BeginCreationTime.Value) >= 0)
.WhereIf(filter.EndCreationTime.HasValue, x => x.CreationTime.CompareTo(filter.EndCreationTime.Value) <= 0)
.OrderBy(sorting ?? $"{nameof(BackgroundJobInfo.CreationTime)} DESC") .OrderBy(sorting ?? $"{nameof(BackgroundJobInfo.CreationTime)} DESC")
.PageBy(skipCount, maxResultCount) .PageBy(skipCount, maxResultCount)
.ToListAsync(GetCancellationToken(cancellationToken)); .ToListAsync(GetCancellationToken(cancellationToken));
@ -161,4 +132,27 @@ public class EfCoreBackgroundJobInfoRepository :
.AsNoTracking() .AsNoTracking()
.ToListAsync(GetCancellationToken(cancellationToken)); .ToListAsync(GetCancellationToken(cancellationToken));
} }
protected virtual IQueryable<BackgroundJobInfo> ApplyFilter(
IQueryable<BackgroundJobInfo> queryable,
BackgroundJobInfoFilter filter)
{
return queryable
.WhereIf(!filter.Type.IsNullOrWhiteSpace(), x => x.Type.Contains(filter.Type))
.WhereIf(!filter.Group.IsNullOrWhiteSpace(), x => x.Group.Equals(filter.Group))
.WhereIf(!filter.Name.IsNullOrWhiteSpace(), x => x.Name.Equals(filter.Name))
.WhereIf(!filter.Filter.IsNullOrWhiteSpace(), x => x.Name.Contains(filter.Filter) ||
x.Group.Contains(filter.Filter) || x.Type.Contains(filter.Filter) || x.Description.Contains(filter.Filter))
.WhereIf(filter.JobType.HasValue, x => x.JobType == filter.JobType)
.WhereIf(filter.Status.HasValue, x => x.Status == filter.Status.Value)
.WhereIf(filter.Priority.HasValue, x => x.Priority == filter.Priority.Value)
.WhereIf(filter.Source.HasValue, x => x.Source == filter.Source.Value)
.WhereIf(filter.IsAbandoned.HasValue, x => x.IsAbandoned == filter.IsAbandoned.Value)
.WhereIf(filter.BeginLastRunTime.HasValue, x => filter.BeginLastRunTime.Value.CompareTo(x.LastRunTime) <= 0)
.WhereIf(filter.EndLastRunTime.HasValue, x => filter.EndLastRunTime.Value.CompareTo(x.LastRunTime) >= 0)
.WhereIf(filter.BeginTime.HasValue, x => x.BeginTime.CompareTo(x.BeginTime) >= 0)
.WhereIf(filter.EndTime.HasValue, x => filter.EndTime.Value.CompareTo(x.EndTime) >= 0)
.WhereIf(filter.BeginCreationTime.HasValue, x => x.CreationTime.CompareTo(filter.BeginCreationTime.Value) >= 0)
.WhereIf(filter.EndCreationTime.HasValue, x => x.CreationTime.CompareTo(filter.EndCreationTime.Value) <= 0);
}
} }

7
aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.EntityFrameworkCore/LINGYUN/Abp/TaskManagement/EntityFrameworkCore/TaskManagementDbContextModelCreatingExtensions.cs

@ -1,4 +1,5 @@
using Microsoft.EntityFrameworkCore; using LINGYUN.Abp.BackgroundTasks;
using Microsoft.EntityFrameworkCore;
using System; using System;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.EntityFrameworkCore.Modeling; using Volo.Abp.EntityFrameworkCore.Modeling;
@ -51,6 +52,10 @@ public static class TaskManagementDbContextModelCreatingExtensions
.HasConversion(new ExtraPropertiesValueConverter(b.Metadata.ClrType)) .HasConversion(new ExtraPropertiesValueConverter(b.Metadata.ClrType))
.Metadata.SetValueComparer(new ExtraPropertyDictionaryValueComparer()); .Metadata.SetValueComparer(new ExtraPropertyDictionaryValueComparer());
b.Property(p => p.Source)
.HasColumnName(nameof(BackgroundJobInfo.Source))
.HasDefaultValue(JobSource.None);
b.ConfigureByConvention(); b.ConfigureByConvention();
b.HasIndex(p => new { p.Name, p.Group }); b.HasIndex(p => new { p.Name, p.Group });

2
aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/EventBus/Handlers/TenantSynchronizer.cs

@ -116,6 +116,7 @@ namespace LY.MicroService.TaskManagement.EventBus.Handlers
Cron = Options.JobFetchCronExpression, Cron = Options.JobFetchCronExpression,
JobType = JobType.Period, JobType = JobType.Period,
Priority = JobPriority.High, Priority = JobPriority.High,
Source = JobSource.System,
LockTimeOut = Options.JobFetchLockTimeOut, LockTimeOut = Options.JobFetchLockTimeOut,
TenantId = tenantId, TenantId = tenantId,
Type = typeof(BackgroundPollingJob).AssemblyQualifiedName, Type = typeof(BackgroundPollingJob).AssemblyQualifiedName,
@ -137,6 +138,7 @@ namespace LY.MicroService.TaskManagement.EventBus.Handlers
Cron = Options.JobCleanCronExpression, Cron = Options.JobCleanCronExpression,
JobType = JobType.Period, JobType = JobType.Period,
Priority = JobPriority.High, Priority = JobPriority.High,
Source = JobSource.System,
TenantId = tenantId, TenantId = tenantId,
Type = typeof(BackgroundCleaningJob).AssemblyQualifiedName, Type = typeof(BackgroundCleaningJob).AssemblyQualifiedName,
}; };

208
aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Migrations/20220330013146_Add-Field-Source-With-BackgroundJobInfo.Designer.cs

@ -0,0 +1,208 @@
// <auto-generated />
using System;
using LY.MicroService.TaskManagement.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Volo.Abp.EntityFrameworkCore;
#nullable disable
namespace LY.MicroService.TaskManagement.Migrations
{
[DbContext(typeof(TaskManagementMigrationsDbContext))]
[Migration("20220330013146_Add-Field-Source-With-BackgroundJobInfo")]
partial class AddFieldSourceWithBackgroundJobInfo
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.MySql)
.HasAnnotation("ProductVersion", "6.0.3")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("LINGYUN.Abp.TaskManagement.BackgroundJobInfo", b =>
{
b.Property<string>("Id")
.HasColumnType("varchar(255)");
b.Property<string>("Args")
.HasColumnType("longtext")
.HasColumnName("Args");
b.Property<DateTime>("BeginTime")
.HasColumnType("datetime(6)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("Cron")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("Cron");
b.Property<string>("Description")
.HasMaxLength(255)
.HasColumnType("varchar(255)")
.HasColumnName("Description");
b.Property<DateTime?>("EndTime")
.HasColumnType("datetime(6)");
b.Property<string>("ExtraProperties")
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<string>("Group")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("Group");
b.Property<int>("Interval")
.HasColumnType("int");
b.Property<bool>("IsAbandoned")
.HasColumnType("tinyint(1)");
b.Property<bool>("IsEnabled")
.HasColumnType("tinyint(1)");
b.Property<int>("JobType")
.HasColumnType("int");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)")
.HasColumnName("LastModifierId");
b.Property<DateTime?>("LastRunTime")
.HasColumnType("datetime(6)");
b.Property<int>("LockTimeOut")
.HasColumnType("int");
b.Property<int>("MaxCount")
.HasColumnType("int");
b.Property<int>("MaxTryCount")
.HasColumnType("int");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("varchar(100)")
.HasColumnName("Name");
b.Property<DateTime?>("NextRunTime")
.HasColumnType("datetime(6)");
b.Property<int>("Priority")
.HasColumnType("int");
b.Property<string>("Result")
.HasMaxLength(1000)
.HasColumnType("varchar(1000)")
.HasColumnName("Result");
b.Property<int>("Source")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasDefaultValue(-1)
.HasColumnName("Source");
b.Property<int>("Status")
.HasColumnType("int");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.Property<int>("TriggerCount")
.HasColumnType("int");
b.Property<int>("TryCount")
.HasColumnType("int");
b.Property<string>("Type")
.IsRequired()
.HasMaxLength(1000)
.HasColumnType("varchar(1000)")
.HasColumnName("Type");
b.HasKey("Id");
b.HasIndex("Name", "Group");
b.ToTable("TK_BackgroundJobs", (string)null);
});
modelBuilder.Entity("LINGYUN.Abp.TaskManagement.BackgroundJobLog", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
b.Property<string>("Exception")
.HasMaxLength(2000)
.HasColumnType("varchar(2000)")
.HasColumnName("Exception");
b.Property<string>("JobGroup")
.HasMaxLength(50)
.HasColumnType("varchar(50)")
.HasColumnName("JobGroup");
b.Property<string>("JobId")
.HasMaxLength(255)
.HasColumnType("varchar(255)")
.HasColumnName("JobId");
b.Property<string>("JobName")
.HasMaxLength(100)
.HasColumnType("varchar(100)")
.HasColumnName("JobName");
b.Property<string>("JobType")
.HasMaxLength(1000)
.HasColumnType("varchar(1000)")
.HasColumnName("JobType");
b.Property<string>("Message")
.HasMaxLength(1000)
.HasColumnType("varchar(1000)")
.HasColumnName("Message");
b.Property<DateTime>("RunTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("JobGroup", "JobName");
b.ToTable("TK_BackgroundJobLogs", (string)null);
});
#pragma warning restore 612, 618
}
}
}

26
aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Migrations/20220330013146_Add-Field-Source-With-BackgroundJobInfo.cs

@ -0,0 +1,26 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace LY.MicroService.TaskManagement.Migrations
{
public partial class AddFieldSourceWithBackgroundJobInfo : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "Source",
table: "TK_BackgroundJobs",
type: "int",
nullable: false,
defaultValue: -1);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "Source",
table: "TK_BackgroundJobs");
}
}
}

8
aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Migrations/TaskManagementMigrationsDbContextModelSnapshot.cs

@ -18,7 +18,7 @@ namespace LY.MicroService.TaskManagement.Migrations
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder
.HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.MySql) .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.MySql)
.HasAnnotation("ProductVersion", "6.0.1") .HasAnnotation("ProductVersion", "6.0.3")
.HasAnnotation("Relational:MaxIdentifierLength", 64); .HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("LINGYUN.Abp.TaskManagement.BackgroundJobInfo", b => modelBuilder.Entity("LINGYUN.Abp.TaskManagement.BackgroundJobInfo", b =>
@ -119,6 +119,12 @@ namespace LY.MicroService.TaskManagement.Migrations
.HasColumnType("varchar(1000)") .HasColumnType("varchar(1000)")
.HasColumnName("Result"); .HasColumnName("Result");
b.Property<int>("Source")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasDefaultValue(-1)
.HasColumnName("Source");
b.Property<int>("Status") b.Property<int>("Status")
.HasColumnType("int"); .HasColumnType("int");

Loading…
Cancel
Save