12 changed files with 297 additions and 1 deletions
@ -0,0 +1,3 @@ |
|||||
|
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
||||
|
<ConfigureAwait ContinueOnCapturedContext="false" /> |
||||
|
</Weavers> |
||||
@ -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> |
||||
@ -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> |
||||
@ -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"); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
@ -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)); |
||||
|
} |
||||
|
} |
||||
@ -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
|
||||
|
} |
||||
|
} |
||||
@ -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); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,8 @@ |
|||||
|
using Volo.Abp.Localization; |
||||
|
|
||||
|
namespace LINGYUN.Abp.Elasticsearch.Jobs.Localization; |
||||
|
|
||||
|
[LocalizationResourceName("ElasticsearchJobs")] |
||||
|
public class ElasticsearchJobsResource |
||||
|
{ |
||||
|
} |
||||
@ -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)" |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
{ |
||||
|
"culture": "zh-Hans", |
||||
|
"texts": { |
||||
|
"IndicesCleanupJob": "过期索引清理作业", |
||||
|
"Indices:IndexPrefix": "索引前缀", |
||||
|
"Indices:TimeZone": "时区", |
||||
|
"Indices:TimeZoneDesc": "计算时差的时区, 默认Utc, 可选(Utc、Local)", |
||||
|
"Indices:ExpirationTime": "过期时间(秒)" |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue