Skip to content

Commit

Permalink
Merge pull request #841 from colinin/add-elasticsearch-jobs
Browse files Browse the repository at this point in the history
feat(jobs): add elasticsearch jobs.
  • Loading branch information
colinin authored Jun 25, 2023
2 parents 563b15a + 1aa7643 commit f5323af
Show file tree
Hide file tree
Showing 12 changed files with 297 additions and 1 deletion.
18 changes: 17 additions & 1 deletion aspnet-core/LINGYUN.MicroService.TaskManagement.sln
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "migrations", "migrations",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LY.MicroService.TaskManagement.DbMigrator", "migrations\LY.MicroService.TaskManagement.DbMigrator\LY.MicroService.TaskManagement.DbMigrator.csproj", "{52FD8F39-0AB6-4C51-A584-187C219AC8B5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LY.MicroService.TaskManagement.EntityFrameworkCore", "migrations\LY.MicroService.TaskManagement.EntityFrameworkCore\LY.MicroService.TaskManagement.EntityFrameworkCore.csproj", "{58F51875-6D2C-4A65-9DD3-8BC004B39B72}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LY.MicroService.TaskManagement.EntityFrameworkCore", "migrations\LY.MicroService.TaskManagement.EntityFrameworkCore\LY.MicroService.TaskManagement.EntityFrameworkCore.csproj", "{58F51875-6D2C-4A65-9DD3-8BC004B39B72}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "elasticsearch", "elasticsearch", "{DC7ACD8B-044B-435D-94C5-06C75A8BD026}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Elasticsearch", "modules\elasticsearch\LINGYUN.Abp.Elasticsearch\LINGYUN.Abp.Elasticsearch.csproj", "{167CE485-72D3-4E95-80B1-00430CBB8888}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Elasticsearch.Jobs", "modules\elasticsearch\LINGYUN.Abp.Elasticsearch.Jobs\LINGYUN.Abp.Elasticsearch.Jobs.csproj", "{798FEFB4-B65F-4B6C-A36D-611DD71A48AB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -212,6 +218,14 @@ Global
{58F51875-6D2C-4A65-9DD3-8BC004B39B72}.Debug|Any CPU.Build.0 = Debug|Any CPU
{58F51875-6D2C-4A65-9DD3-8BC004B39B72}.Release|Any CPU.ActiveCfg = Release|Any CPU
{58F51875-6D2C-4A65-9DD3-8BC004B39B72}.Release|Any CPU.Build.0 = Release|Any CPU
{167CE485-72D3-4E95-80B1-00430CBB8888}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{167CE485-72D3-4E95-80B1-00430CBB8888}.Debug|Any CPU.Build.0 = Debug|Any CPU
{167CE485-72D3-4E95-80B1-00430CBB8888}.Release|Any CPU.ActiveCfg = Release|Any CPU
{167CE485-72D3-4E95-80B1-00430CBB8888}.Release|Any CPU.Build.0 = Release|Any CPU
{798FEFB4-B65F-4B6C-A36D-611DD71A48AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{798FEFB4-B65F-4B6C-A36D-611DD71A48AB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{798FEFB4-B65F-4B6C-A36D-611DD71A48AB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{798FEFB4-B65F-4B6C-A36D-611DD71A48AB}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -247,6 +261,8 @@ Global
{DF963ABB-E713-49E9-A03C-DEB431E369DF} = {B38D2141-AC0F-4F4A-9315-4292E3856C15}
{52FD8F39-0AB6-4C51-A584-187C219AC8B5} = {820A8FA4-17C4-44DF-8C31-9F211D00F790}
{58F51875-6D2C-4A65-9DD3-8BC004B39B72} = {820A8FA4-17C4-44DF-8C31-9F211D00F790}
{167CE485-72D3-4E95-80B1-00430CBB8888} = {DC7ACD8B-044B-435D-94C5-06C75A8BD026}
{798FEFB4-B65F-4B6C-A36D-611DD71A48AB} = {A9536BD2-2573-44CA-B033-DC16B7E345E5}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E1FD1F4C-D344-408B-97CF-B6F1F6D7D293}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>
Original file line number Diff line number Diff line change
@@ -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>
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">

<Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" />

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
</PropertyGroup>

<ItemGroup>
<None Remove="LINGYUN\Abp\Elasticsearch\Jobs\Localization\Resources\*.json" />
</ItemGroup>

<ItemGroup>
<EmbeddedResource Include="LINGYUN\Abp\Elasticsearch\Jobs\Localization\Resources\*.json" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Volo.Abp.Timing" Version="$(VoloAbpPackageVersion)" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\task-management\LINGYUN.Abp.BackgroundTasks.Abstractions\LINGYUN.Abp.BackgroundTasks.Abstractions.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.Elasticsearch\LINGYUN.Abp.Elasticsearch.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using LINGYUN.Abp.BackgroundTasks;
using LINGYUN.Abp.Elasticsearch.Jobs.Localization;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.Timing;
using Volo.Abp.VirtualFileSystem;

namespace LINGYUN.Abp.Elasticsearch.Jobs;

[DependsOn(typeof(AbpTimingModule))]
[DependsOn(typeof(AbpElasticsearchModule))]
[DependsOn(typeof(AbpBackgroundTasksAbstractionsModule))]
public class AbpElasticsearchJobsModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpElasticsearchJobsModule>();
});

Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Add<ElasticsearchJobsResource>()
.AddVirtualJson("/LINGYUN/Abp/Elasticsearch/Jobs/Localization/Resources");
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using LINGYUN.Abp.BackgroundTasks;

namespace LINGYUN.Abp.Elasticsearch.Jobs;

public class NotificationJobDefinitionProvider : JobDefinitionProvider
{
public override void Define(IJobDefinitionContext context)
{
context.Add(
new JobDefinition(
ExpiredIndicesCleanupJob.Name,
typeof(ExpiredIndicesCleanupJob),
LocalizableStatic.Create("IndicesCleanupJob"),
ExpiredIndicesCleanupJob.Paramters));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
using LINGYUN.Abp.BackgroundTasks;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Timing;

namespace LINGYUN.Abp.Elasticsearch.Jobs;

/// <summary>
/// Elasticsearch 过期索引清理作业
/// </summary>
public class ExpiredIndicesCleanupJob : IJobRunnable
{
#region Definition Paramters

public readonly static IReadOnlyList<JobDefinitionParamter> Paramters =
new List<JobDefinitionParamter>
{
new JobDefinitionParamter(
PropertyIndexPrefix,
LocalizableStatic.Create("Indices:IndexPrefix"),
required: true),
new JobDefinitionParamter(
PropertyTimeZone,
LocalizableStatic.Create("Indices:TimeZone"),
LocalizableStatic.Create("Indices:TimeZoneDesc")),
new JobDefinitionParamter(
PropertyExpirationTime,
LocalizableStatic.Create("Indices:ExpirationTime")),
};

public const string Name = "ExpiredIndicesCleanupJob";
/// <summary>
/// 每次清除记录大小
/// </summary>
private const string PropertyIndexPrefix = "IndexPrefix";
/// <summary>
/// 计算时差的时区, 默认Utc
/// </summary>
private const string PropertyTimeZone = "TimeZone";
/// <summary>
/// 过期时间, 单位秒, 默认 5184000 (60天)
/// </summary>
private const string PropertyExpirationTime = "ExpirationTime";

#endregion

public async virtual Task ExecuteAsync(JobRunnableContext context)
{
#region Initializes Job Parameters

var timeZone = TimeZoneInfo.Utc;
var indexPrefix = context.GetString(PropertyIndexPrefix);
var timeZoneString = context.GetOrDefaultString(PropertyTimeZone, "utc");
var expirationSecond = context.GetOrDefaultJobData(PropertyExpirationTime, 5184000L);

if (!timeZoneString.IsNullOrWhiteSpace())
{
timeZone = timeZoneString.ToLowerInvariant() switch
{
"local" => TimeZoneInfo.Local,
_ => TimeZoneInfo.Utc,
};
}

var elasticClientFactory = context.GetRequiredService<IElasticsearchClientFactory>();
var elasticClient = elasticClientFactory.Create();

var clock = context.GetRequiredService<IClock>();
var expirationTime = clock.Now.AddSeconds(-expirationSecond);
var startTime = TimeZoneInfo.ConvertTime(new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), timeZone);
var removeIndices = new List<string>();

#endregion

#region ES indices.get_settings API

// GET demo*/_settings
var settingResponse = await elasticClient.Indices.GetSettingsAsync(indexPrefix);
if (!settingResponse.IsValid)
{
throw new AbpJobExecutionException(GetType(), settingResponse.ServerError.ToString(), settingResponse.OriginalException);
}

foreach (var indexSet in settingResponse.Indices)
{
// 索引创建日期
if (indexSet.Value.Settings.TryGetValue("index.creation_date", out var indexSetV) &&
long.TryParse(indexSetV.ToString(), out var timestamp))
{
var indexCreationDate = startTime.AddMilliseconds(timestamp);
if (indexCreationDate <= expirationTime)
{
removeIndices.Add(indexSet.Key.Name);
}
}
}

#endregion

#region ES indices.delete API

foreach (var index in removeIndices)
{
var delResponse = await elasticClient.Indices.DeleteAsync(index);
if (!delResponse.IsValid)
{
throw new AbpJobExecutionException(GetType(), delResponse.ServerError.ToString(), delResponse.OriginalException);
}
}

#endregion
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using LINGYUN.Abp.Elasticsearch.Jobs.Localization;
using Volo.Abp.Localization;

namespace LINGYUN.Abp.Elasticsearch.Jobs;

internal static class LocalizableStatic
{
public static ILocalizableString Create(string name)
{
return LocalizableString.Create<ElasticsearchJobsResource>(name);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Volo.Abp.Localization;

namespace LINGYUN.Abp.Elasticsearch.Jobs.Localization;

[LocalizationResourceName("ElasticsearchJobs")]
public class ElasticsearchJobsResource
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"culture": "en",
"texts": {
"IndicesCleanupJob": "Expired index cleanup job",
"Indices:IndexPrefix": "Index prefix",
"Indices:TimeZone": "Timezone",
"Indices:TimeZoneDesc": "Time zone for calculating the time difference, default Utc, optional (Utc, Local).",
"Indices:ExpirationTime": "Expiration time(seconds)"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"culture": "zh-Hans",
"texts": {
"IndicesCleanupJob": "过期索引清理作业",
"Indices:IndexPrefix": "索引前缀",
"Indices:TimeZone": "时区",
"Indices:TimeZoneDesc": "计算时差的时区, 默认Utc, 可选(Utc、Local)",
"Indices:ExpirationTime": "过期时间(秒)"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ public static string GetString(this JobRunnableContext context, string key)
return context.GetJobData(key).ToString();
}

public static string GetOrDefaultString(this JobRunnableContext context, string key, string defaultValue = "")
{
if (context.TryGetString(key, out var value))
{
return value;
}

return defaultValue;
}

public static bool TryGetString(this JobRunnableContext context, string key, out string value)
{
if (context.TryGetJobData(key, out var data) && data != null)
Expand Down Expand Up @@ -65,6 +75,16 @@ public static T GetJobData<T>(this JobRunnableContext context, string key) where
return value.To<T>();
}

public static T GetOrDefaultJobData<T>(this JobRunnableContext context, string key, T defaultValue) where T : struct
{
if (context.TryGetJobData<T>(key, out var value))
{
return value;
}

return defaultValue;
}

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)
Expand Down

0 comments on commit f5323af

Please sign in to comment.