Browse Source

feat(tasks): add commonly used jobs

pull/457/head
cKey 4 years ago
parent
commit
58428ab3d8
  1. 7
      aspnet-core/LINGYUN.MicroService.TaskManagement.sln
  2. 11
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/AbpBackgroundTaskConcurrentException.cs
  3. 28
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/AbpBackgroundTasksAbstractionsModule.cs
  4. 15
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/AbpBackgroundTasksOptions.cs
  5. 44
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/AbpJobExecutionException.cs
  6. 0
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/IJobEvent.cs
  7. 0
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobEventBase.cs
  8. 6
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobRunnableContext.cs
  9. 85
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobRunnableContextExtensions.cs
  10. 3
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/FodyWeavers.xml
  11. 30
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/FodyWeavers.xsd
  12. 21
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN.Abp.BackgroundTasks.Jobs.csproj
  13. 25
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/AbpBackgroundTasksJobsModule.cs
  14. 2
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/ConsoleJob.cs
  15. 29
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/DefaultJobNames.cs
  16. 78
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/HttpRequestJob.cs
  17. 26
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/SendEmailJob.cs
  18. 29
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/SendSmsJob.cs
  19. 117
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/ServiceInvocationJob.cs
  20. 2
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/SleepJob.cs
  21. 3
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobExecutorProvider.cs
  22. 2
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobSimpleAdapter.cs
  23. 26
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/AbpBackgroundTasksModule.cs
  24. 14
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Primitives/EmailingJob.cs
  25. 1
      aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/LY.MicroService.TaskManagement.HttpApi.Host.csproj
  26. 2
      aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/TaskManagementHttpApiHostModule.cs

7
aspnet-core/LINGYUN.MicroService.TaskManagement.sln

@ -36,6 +36,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LY.MicroService.TaskManagem
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.BackgroundTasks.Abstractions", "modules\task-management\LINGYUN.Abp.BackgroundTasks.Abstractions\LINGYUN.Abp.BackgroundTasks.Abstractions.csproj", "{4A049C32-55F2-4A5F-954A-C8A977C2D87F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.BackgroundTasks.Jobs", "modules\task-management\LINGYUN.Abp.BackgroundTasks.Jobs\LINGYUN.Abp.BackgroundTasks.Jobs.csproj", "{4C59F590-AA6C-4C46-8060-DA65D8305980}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -82,6 +84,10 @@ Global
{4A049C32-55F2-4A5F-954A-C8A977C2D87F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4A049C32-55F2-4A5F-954A-C8A977C2D87F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4A049C32-55F2-4A5F-954A-C8A977C2D87F}.Release|Any CPU.Build.0 = Release|Any CPU
{4C59F590-AA6C-4C46-8060-DA65D8305980}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4C59F590-AA6C-4C46-8060-DA65D8305980}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4C59F590-AA6C-4C46-8060-DA65D8305980}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4C59F590-AA6C-4C46-8060-DA65D8305980}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -97,6 +103,7 @@ Global
{7051C251-11D0-4971-B13E-F6929AE6DE89} = {385578CC-C0F1-4377-A7A2-682B8F416234}
{E8022994-A19F-4540-B9D1-7EF4AA85D18A} = {8DA8A2EE-0B26-487E-A6C4-518906E92B1B}
{4A049C32-55F2-4A5F-954A-C8A977C2D87F} = {C38EB7EF-BAE9-4129-862A-71C652B81775}
{4C59F590-AA6C-4C46-8060-DA65D8305980} = {C38EB7EF-BAE9-4129-862A-71C652B81775}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E1FD1F4C-D344-408B-97CF-B6F1F6D7D293}

11
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/AbpBackgroundTaskConcurrentException.cs

@ -1,17 +1,15 @@
using System;
using Volo.Abp;
namespace LINGYUN.Abp.BackgroundTasks;
public class AbpBackgroundTaskConcurrentException : AbpException
public class AbpBackgroundTaskConcurrentException : AbpJobExecutionException
{
public Type JobType { get; }
/// <summary>
/// Creates a new <see cref="AbpBackgroundTaskConcurrentException"/> object.
/// </summary>
/// <param name="innerException">Inner exception</param>
public AbpBackgroundTaskConcurrentException(Type jobType)
: this(
: base(
jobType,
$"This job {jobType.Name} cannot be performed because it has been locked by another performer",
null)
@ -24,7 +22,7 @@ public class AbpBackgroundTaskConcurrentException : AbpException
/// <param name="jobType">Execute job type</param>
/// <param name="innerException">Inner exception</param>
public AbpBackgroundTaskConcurrentException(Type jobType, Exception innerException)
: this(
: base(
jobType,
$"This job {jobType.Name} cannot be performed because it has been locked by another performer",
innerException)
@ -38,8 +36,7 @@ public class AbpBackgroundTaskConcurrentException : AbpException
/// <param name="message">Exception message</param>
/// <param name="innerException">Inner exception</param>
public AbpBackgroundTaskConcurrentException(Type jobType, string message, Exception innerException)
: base(message, innerException)
: base(jobType, message, innerException)
{
JobType = jobType;
}
}

28
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/AbpBackgroundTasksAbstractionsModule.cs

@ -1,7 +1,33 @@
using Volo.Abp.Modularity;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using Volo.Abp.Modularity;
using Volo.Abp.Reflection;
namespace LINGYUN.Abp.BackgroundTasks;
public class AbpBackgroundTasksAbstractionsModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
AutoAddJobMonitors(context.Services);
}
private static void AutoAddJobMonitors(IServiceCollection services)
{
var jobMonitors = new List<Type>();
services.OnRegistred(context =>
{
if (ReflectionHelper.IsAssignableToGenericType(context.ImplementationType, typeof(JobEventBase<>)))
{
jobMonitors.Add(context.ImplementationType);
}
});
services.Configure<AbpBackgroundTasksOptions>(options =>
{
options.JobMonitors.AddIfNotContains(jobMonitors);
});
}
}

15
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/AbpBackgroundTasksOptions.cs → aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/AbpBackgroundTasksOptions.cs

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using Volo.Abp.Collections;
namespace LINGYUN.Abp.BackgroundTasks;
@ -13,6 +14,13 @@ public class AbpBackgroundTasksOptions
/// </remarks>
public ITypeList<IJobEvent> JobMonitors { get; }
/// <summary>
/// 作业提供者列表
/// </summary>
/// <remarks>
/// 用户实现的作业可以添加在集合中
/// </remarks>
public IDictionary<string, Type> JobProviders { get; }
/// <summary>
/// 任务过期时间
/// 默认: 15 days
/// </summary>
@ -65,5 +73,12 @@ public class AbpBackgroundTasksOptions
JobCleanCronExpression = "0 0/10 * * * ? *";
JobMonitors = new TypeList<IJobEvent>();
JobProviders = new Dictionary<string, Type>();
}
public void AddProvider<TJobRunnable>(string name)
where TJobRunnable : IJobRunnable
{
JobProviders[name] = typeof(TJobRunnable);
}
}

44
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/AbpJobExecutionException.cs

@ -0,0 +1,44 @@
using System;
using Volo.Abp;
namespace LINGYUN.Abp.BackgroundTasks;
public class AbpJobExecutionException : AbpException
{
public Type JobType { get; }
/// <summary>
/// Creates a new <see cref="AbpJobExecutionException"/> object.
/// </summary>
/// <param name="innerException">Inner exception</param>
public AbpJobExecutionException(Type jobType)
: this(
jobType,
$"Unable to execute job {jobType.Name}.",
null)
{
}
/// <summary>
/// Creates a new <see cref="AbpJobExecutionException"/> object.
/// </summary>
/// <param name="jobType">Execute job type</param>
/// <param name="innerException">Inner exception</param>
public AbpJobExecutionException(Type jobType, Exception innerException)
: this(
jobType,
$"Unable to execute job {jobType.Name} because it: {innerException.Message}",
innerException)
{
}
/// <summary>
/// Creates a new <see cref="AbpJobExecutionException"/> object.
/// </summary>
/// <param name="jobType">Execute job type</param>
/// <param name="message">Exception message</param>
/// <param name="innerException">Inner exception</param>
public AbpJobExecutionException(Type jobType, string message, Exception innerException)
: base(message, innerException)
{
JobType = jobType;
}
}

0
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/IJobEvent.cs → aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/IJobEvent.cs

0
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/JobEventBase.cs → aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobEventBase.cs

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

@ -8,6 +8,7 @@ public class JobRunnableContext
public Type JobType { get; }
public IServiceProvider ServiceProvider { get; }
public IReadOnlyDictionary<string, object> JobData { get; }
public object Result { get; private set; }
public JobRunnableContext(
Type jobType,
IServiceProvider serviceProvider,
@ -17,4 +18,9 @@ public class JobRunnableContext
ServiceProvider = serviceProvider;
JobData = jobData;
}
public void SetResult(object result)
{
Result = result;
}
}

85
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobRunnableContextExtensions.cs

@ -0,0 +1,85 @@
using Microsoft.Extensions.DependencyInjection;
using System;
namespace LINGYUN.Abp.BackgroundTasks;
public static class JobRunnableContextExtensions
{
public static T GetService<T>(this JobRunnableContext context)
{
return context.ServiceProvider.GetService<T>();
}
public static object GetService(this JobRunnableContext context, Type serviceType)
{
return context.ServiceProvider.GetService(serviceType);
}
public static T GetRequiredService<T>(this JobRunnableContext context)
{
return context.ServiceProvider.GetRequiredService<T>();
}
public static object GetRequiredService(this JobRunnableContext context, Type serviceType)
{
return context.ServiceProvider.GetRequiredService(serviceType);
}
public static string GetString(this JobRunnableContext context, string key)
{
return context.GetJobData(key).ToString();
}
public static bool TryGetString(this JobRunnableContext context, string key, out string value)
{
if (context.TryGetJobData(key, out var data) && data != null)
{
value = data.ToString();
return true;
}
value = default;
return false;
}
public static T GetJobData<T>(this JobRunnableContext context, string key) where T : struct
{
var value = context.GetJobData(key);
return value.To<T>();
}
public static bool TryGetJobData<T>(this JobRunnableContext context, string key, out T value) where T : struct
{
if (context.TryGetJobData(key, out var data) && data != null)
{
try
{
value = data.To<T>();
return true;
}
catch
{
}
}
value = default;
return false;
}
public static object GetJobData(this JobRunnableContext context, string key)
{
if (context.TryGetJobData(key, out var value) && value != null)
{
return value;
}
throw new ArgumentException(key + " not specified.");
}
public static bool TryGetJobData(this JobRunnableContext context, string key, out object value)
{
if (context.JobData.TryGetValue(key, out value))
{
return true;
}
return false;
}
}

3
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait />
</Weavers>

30
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/FodyWeavers.xsd

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

21
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN.Abp.BackgroundTasks.Jobs.csproj

@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Emailing" Version="$(VoloAbpPackageVersion)" />
<PackageReference Include="Volo.Abp.Sms" Version="$(VoloAbpPackageVersion)" />
<PackageReference Include="Volo.Abp.Http.Client" Version="$(VoloAbpPackageVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LINGYUN.Abp.BackgroundTasks.Abstractions\LINGYUN.Abp.BackgroundTasks.Abstractions.csproj" />
</ItemGroup>
</Project>

25
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/AbpBackgroundTasksJobsModule.cs

@ -0,0 +1,25 @@
using Volo.Abp.Emailing;
using Volo.Abp.Http.Client;
using Volo.Abp.Modularity;
using Volo.Abp.Sms;
namespace LINGYUN.Abp.BackgroundTasks.Jobs;
[DependsOn(typeof(AbpEmailingModule))]
[DependsOn(typeof(AbpSmsModule))]
[DependsOn(typeof(AbpHttpClientModule))]
public class AbpBackgroundTasksJobsModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpBackgroundTasksOptions>(options =>
{
options.AddProvider<ConsoleJob>(DefaultJobNames.ConsoleJob);
options.AddProvider<SendEmailJob>(DefaultJobNames.SendEmailJob);
options.AddProvider<SendSmsJob>(DefaultJobNames.SendSmsJob);
options.AddProvider<SleepJob>(DefaultJobNames.SleepJob);
options.AddProvider<ServiceInvocationJob>(DefaultJobNames.ServiceInvocationJob);
options.AddProvider<HttpRequestJob>(DefaultJobNames.HttpRequestJob);
});
}
}

2
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Primitives/ConsoleJob.cs → aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/ConsoleJob.cs

@ -1,7 +1,7 @@
using System;
using System.Threading.Tasks;
namespace LINGYUN.Abp.BackgroundTasks.Primitives;
namespace LINGYUN.Abp.BackgroundTasks.Jobs;
public class ConsoleJob : IJobRunnable
{

29
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/DefaultJobNames.cs

@ -0,0 +1,29 @@
namespace LINGYUN.Abp.BackgroundTasks.Jobs;
public static class DefaultJobNames
{
/// <summary>
/// 发送邮件
/// </summary>
public const string SendEmailJob = "SendEmail";
/// <summary>
/// 发送短信
/// </summary>
public const string SendSmsJob = "SendSms";
/// <summary>
/// 控制台输出
/// </summary>
public const string ConsoleJob = "Console";
/// <summary>
/// 休眠
/// </summary>
public const string SleepJob = "Sleep";
/// <summary>
/// 服务间调用
/// </summary>
public const string ServiceInvocationJob = "ServiceInvocation";
/// <summary>
/// Http请求
/// </summary>
public const string HttpRequestJob = "HttpRequest";
}

78
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/HttpRequestJob.cs

@ -0,0 +1,78 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Http;
using Volo.Abp.Json;
namespace LINGYUN.Abp.BackgroundTasks.Jobs;
public class HttpRequestJob : IJobRunnable
{
public const string PropertyUrl = "url";
public const string PropertyMethod = "method";
public const string PropertyData = "data";
public const string PropertyContentType = "contentType";
public const string PropertyHeaders = "headers";
public const string PropertyToken = "token";
public virtual async Task ExecuteAsync(JobRunnableContext context)
{
var clientFactory = context.GetRequiredService<IHttpClientFactory>();
var client = clientFactory.CreateClient();
var requestMessage = BuildRequestMessage(context);
var response = await client.SendAsync(
requestMessage,
HttpCompletionOption.ResponseHeadersRead);
var stringContent = await response.Content.ReadAsStringAsync();
if (!response.IsSuccessStatusCode && stringContent.IsNullOrWhiteSpace())
{
context.SetResult($"HttpStatusCode: {(int)response.StatusCode}, Reason: {response.ReasonPhrase}");
return;
}
context.SetResult(stringContent);
}
protected virtual HttpRequestMessage BuildRequestMessage(JobRunnableContext context)
{
var url = context.GetString(PropertyUrl);
var method = context.GetString(PropertyMethod);
context.TryGetJobData(PropertyData, out var data);
context.TryGetJobData(PropertyContentType, out var contentType);
var jsonSerializer = context.GetRequiredService<IJsonSerializer>();
var httpRequestMesasge = new HttpRequestMessage(new HttpMethod(method), url);
if (data != null)
{
// TODO: 需要支持表单类型
// application/json 支持
httpRequestMesasge.Content = new StringContent(
jsonSerializer.Serialize(data),
Encoding.UTF8,
contentType?.ToString() ?? MimeTypes.Application.Json);
}
if (context.TryGetJobData(PropertyHeaders, out var headers) &&
headers is IDictionary<string, string> headersDic)
{
foreach (var header in headersDic)
{
httpRequestMesasge.Headers.Add(header.Key, header.Value);
}
}
// TODO: 和 headers 一起?
if (context.TryGetString(PropertyToken, out var accessToken))
{
httpRequestMesasge.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
}
return httpRequestMesasge;
}
}

26
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/SendEmailJob.cs

@ -0,0 +1,26 @@
using System.Threading.Tasks;
using Volo.Abp.Emailing;
namespace LINGYUN.Abp.BackgroundTasks.Jobs;
public class SendEmailJob : IJobRunnable
{
public const string PropertyFrom = "from";
public const string PropertyTo = "to";
public const string PropertySubject = "subject";
public const string PropertyBody = "body";
public const string PropertyIsBodyHtml = "isBodyHtml";
public virtual async Task ExecuteAsync(JobRunnableContext context)
{
context.TryGetString(PropertyFrom, out var from);
var to = context.GetString(PropertyTo);
var subject = context.GetString(PropertySubject);
var body = context.GetString(PropertyBody);
context.TryGetJobData<bool>(PropertyIsBodyHtml, out var isBodyHtml);
var emailSender = context.GetRequiredService<IEmailSender>();
await emailSender.QueueAsync(from, to, subject, body, isBodyHtml);
}
}

29
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/SendSmsJob.cs

@ -0,0 +1,29 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Sms;
namespace LINGYUN.Abp.BackgroundTasks.Jobs;
public class SendSmsJob : IJobRunnable
{
public const string PropertyPhoneNumber = "phoneNumber";
public const string PropertyMessage = "message";
public const string PropertyProperties = "properties";
public virtual async Task ExecuteAsync(JobRunnableContext context)
{
var phoneNumber = context.GetString(PropertyPhoneNumber);
var message = context.GetString(PropertyMessage);
var smsMessage = new SmsMessage(phoneNumber, message);
if (context.TryGetJobData(PropertyProperties, out var data) &&
data is IDictionary<string, object> properties)
{
smsMessage.Properties.AddIfNotContains(properties);
}
var smsSender = context.GetRequiredService<ISmsSender>();
await smsSender.SendAsync(smsMessage);
}
}

117
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/ServiceInvocationJob.cs

@ -0,0 +1,117 @@
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Http.Client;
using Volo.Abp.Http.Client.ClientProxying;
using Volo.Abp.Http.Client.DynamicProxying;
using Volo.Abp.Http.Client.Proxying;
using Volo.Abp.Http.Modeling;
using Volo.Abp.Localization;
namespace LINGYUN.Abp.BackgroundTasks.Jobs;
public class ServiceInvocationJob : IJobRunnable
{
public const string PropertyService = "service";
public const string PropertyMethod = "method";
public const string PropertyCulture = "culture";
public virtual async Task ExecuteAsync(JobRunnableContext context)
{
// 获取参数列表
var type = context.GetString(PropertyService);
var method = context.GetString(PropertyMethod);
var serviceType = Type.GetType(type, true);
var serviceMethod = serviceType.GetMethod(method);
context.TryGetString(PropertyCulture, out var culture);
using (CultureHelper.Use(culture ?? CultureInfo.CurrentCulture.Name))
{
// 反射所必须的参数
var callRequestMethod = nameof(DynamicHttpProxyInterceptorClientProxy<object>.CallRequestAsync);
var clientProxyType = typeof(DynamicHttpProxyInterceptorClientProxy<>).MakeGenericType(serviceType);
var clientProxy = context.GetRequiredService(clientProxyType);
var clientProxyMethod = typeof(DynamicHttpProxyInterceptorClientProxy<>).GetMethod(callRequestMethod);
// 调用远程服务发现端点
var actionApiDescription = await GetActionApiDescriptionModel(context, serviceType, serviceMethod);
// 拼接调用参数
var invokeParameters = new Dictionary<string, object>();
var methodParameters = serviceMethod.GetParameters();
foreach (var parameter in methodParameters)
{
if (context.TryGetJobData(parameter.Name, out var value))
{
invokeParameters.Add(parameter.Name, value);
}
}
// 构造服务代理上下文
var clientProxyRequestContext = new ClientProxyRequestContext(
actionApiDescription,
invokeParameters,
serviceType);
if (serviceMethod.ReturnType.GenericTypeArguments.IsNullOrEmpty())
{
// 直接调用
var taskProxy = (Task)clientProxyMethod.Invoke(clientProxy, new object[] { clientProxyRequestContext });
await taskProxy;
}
else
{
// 有返回值的调用
var callRequestAsyncMethod = typeof(DynamicHttpProxyInterceptor<object>)
.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance)
.First(m => m.Name == callRequestMethod && m.IsGenericMethodDefinition);
var returnType = serviceMethod.ReturnType.GenericTypeArguments[0];
var result = (Task)callRequestAsyncMethod
.MakeGenericMethod(returnType)
.Invoke(this, new object[] { context });
context.SetResult(await GetResultAsync(result, returnType));
}
}
}
protected virtual async Task<ActionApiDescriptionModel> GetActionApiDescriptionModel(
JobRunnableContext context,
Type serviceType,
MethodInfo method)
{
var clientOptions = context.GetRequiredService<IOptions<AbpHttpClientOptions>>().Value;
var remoteServiceConfigurationProvider = context.GetRequiredService<IRemoteServiceConfigurationProvider>();
var proxyHttpClientFactory = context.GetRequiredService<IProxyHttpClientFactory>();
var apiDescriptionFinder = context.GetRequiredService<IApiDescriptionFinder>();
var clientConfig = clientOptions.HttpClientProxies.GetOrDefault(serviceType) ??
throw new AbpException($"Could not get DynamicHttpClientProxyConfig for {serviceType.FullName}.");
var remoteServiceConfig = await remoteServiceConfigurationProvider.GetConfigurationOrDefaultAsync(clientConfig.RemoteServiceName);
var client = proxyHttpClientFactory.Create(clientConfig.RemoteServiceName);
return await apiDescriptionFinder.FindActionAsync(
client,
remoteServiceConfig.BaseUrl,
serviceType,
method
);
}
protected virtual async Task<object> GetResultAsync(Task task, Type resultType)
{
await task;
var resultProperty = typeof(Task<>)
.MakeGenericType(resultType)
.GetProperty(nameof(Task<object>.Result), BindingFlags.Instance | BindingFlags.Public);
Check.NotNull(resultProperty, nameof(resultProperty));
return resultProperty.GetValue(task);
}
}

2
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Primitives/SleepJob.cs → aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/SleepJob.cs

@ -1,7 +1,7 @@
using System;
using System.Threading.Tasks;
namespace LINGYUN.Abp.BackgroundTasks.Primitives;
namespace LINGYUN.Abp.BackgroundTasks.Jobs;
public class SleepJob : IJobRunnable
{

3
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobExecutorProvider.cs

@ -3,6 +3,7 @@ using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using Quartz;
using System;
using System.Collections.Generic;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Timing;
@ -27,7 +28,7 @@ public class QuartzJobExecutorProvider : IQuartzJobExecutorProvider, ISingletonD
public IJobDetail CreateJob(JobInfo job)
{
var jobType = Type.GetType(job.Type);
var jobType = Type.GetType(job.Type) ?? Options.JobProviders.GetOrDefault(job.Type);
if (jobType == null)
{
Logger.LogWarning($"The task: {job.Group} - {job.Name}: {job.Type} is not registered and cannot create an instance of the performer type.");

2
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobSimpleAdapter.cs

@ -29,5 +29,7 @@ public class QuartzJobSimpleAdapter<TJobRunnable> : IJob
context.MergedJobDataMap.ToImmutableDictionary());
await jobExecuter.ExecuteAsync(jobContext);
context.Result = jobContext.Result;
}
}

26
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/AbpBackgroundTasksModule.cs

@ -1,13 +1,10 @@
using LINGYUN.Abp.BackgroundTasks.Internal;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using Volo.Abp.Auditing;
using Volo.Abp.BackgroundJobs;
using Volo.Abp.DistributedLocking;
using Volo.Abp.Guids;
using Volo.Abp.Modularity;
using Volo.Abp.Reflection;
namespace LINGYUN.Abp.BackgroundTasks;
@ -18,32 +15,9 @@ namespace LINGYUN.Abp.BackgroundTasks;
[DependsOn(typeof(AbpGuidsModule))]
public class AbpBackgroundTasksModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
AutoAddJobMonitors(context.Services);
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddTransient(typeof(BackgroundJobAdapter<>));
context.Services.AddHostedService<DefaultBackgroundWorker>();
}
private static void AutoAddJobMonitors(IServiceCollection services)
{
var jobMonitors = new List<Type>();
services.OnRegistred(context =>
{
if (ReflectionHelper.IsAssignableToGenericType(context.ImplementationType, typeof(JobEventBase<>)))
{
jobMonitors.Add(context.ImplementationType);
}
});
services.Configure<AbpBackgroundTasksOptions>(options =>
{
options.JobMonitors.AddIfNotContains(jobMonitors);
});
}
}

14
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Primitives/EmailingJob.cs

@ -1,14 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace LINGYUN.Abp.BackgroundTasks.Primitives;
public class EmailingJob : IJobRunnable
{
public virtual async Task ExecuteAsync(JobRunnableContext context)
{
}
}

1
aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/LY.MicroService.TaskManagement.HttpApi.Host.csproj

@ -50,6 +50,7 @@
<ItemGroup>
<ProjectReference Include="..\..\modules\common\LINGYUN.Abp.Data.DbMigrator\LINGYUN.Abp.Data.DbMigrator.csproj" />
<ProjectReference Include="..\..\modules\common\LINGYUN.Abp.ExceptionHandling.Emailing\LINGYUN.Abp.ExceptionHandling.Emailing.csproj" />
<ProjectReference Include="..\..\modules\task-management\LINGYUN.Abp.BackgroundTasks.Jobs\LINGYUN.Abp.BackgroundTasks.Jobs.csproj" />
<ProjectReference Include="..\..\modules\task-management\LINGYUN.Abp.BackgroundTasks.Quartz\LINGYUN.Abp.BackgroundTasks.Quartz.csproj" />
<ProjectReference Include="..\..\modules\task-management\LINGYUN.Abp.TaskManagement.Application\LINGYUN.Abp.TaskManagement.Application.csproj" />
<ProjectReference Include="..\..\modules\task-management\LINGYUN.Abp.TaskManagement.EntityFrameworkCore\LINGYUN.Abp.TaskManagement.EntityFrameworkCore.csproj" />

2
aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/TaskManagementHttpApiHostModule.cs

@ -1,4 +1,5 @@
using LINGYUN.Abp.AuditLogging.Elasticsearch;
using LINGYUN.Abp.BackgroundTasks.Jobs;
using LINGYUN.Abp.BackgroundTasks.Quartz;
using LINGYUN.Abp.Data.DbMigrator;
using LINGYUN.Abp.ExceptionHandling.Emailing;
@ -42,6 +43,7 @@ namespace LY.MicroService.TaskManagement;
typeof(AbpHttpClientIdentityModelWebModule),
typeof(AbpAspNetCoreMultiTenancyModule),
typeof(AbpDbFinderMultiTenancyModule),
typeof(AbpBackgroundTasksJobsModule),
typeof(AbpBackgroundTasksQuartzModule),
typeof(TaskManagementApplicationModule),
typeof(TaskManagementHttpApiModule),

Loading…
Cancel
Save