|
|
@ -1,26 +1,30 @@ |
|
|
using Elastic.Clients.Elasticsearch; |
|
|
using Elastic.Clients.Elasticsearch; |
|
|
using Elastic.Clients.Elasticsearch.Mapping; |
|
|
using Elastic.Clients.Elasticsearch.Mapping; |
|
|
|
|
|
using Elastic.Transport.Products.Elasticsearch; |
|
|
using LINGYUN.Abp.Elasticsearch; |
|
|
using LINGYUN.Abp.Elasticsearch; |
|
|
using Microsoft.Extensions.Logging; |
|
|
using Microsoft.Extensions.Logging; |
|
|
using Microsoft.Extensions.Logging.Abstractions; |
|
|
using Microsoft.Extensions.Logging.Abstractions; |
|
|
using Microsoft.Extensions.Options; |
|
|
using Microsoft.Extensions.Options; |
|
|
using System; |
|
|
using System; |
|
|
|
|
|
using System.Text; |
|
|
|
|
|
using System.Threading; |
|
|
using System.Threading.Tasks; |
|
|
using System.Threading.Tasks; |
|
|
|
|
|
using Volo.Abp; |
|
|
using Volo.Abp.DependencyInjection; |
|
|
using Volo.Abp.DependencyInjection; |
|
|
using Volo.Abp.Json; |
|
|
using Volo.Abp.Json; |
|
|
|
|
|
|
|
|
namespace LINGYUN.Abp.AuditLogging.Elasticsearch; |
|
|
namespace LINGYUN.Abp.AuditLogging.Elasticsearch; |
|
|
|
|
|
|
|
|
public class IndexInitializer : IIndexInitializer, ISingletonDependency |
|
|
public class AuditLoggingIndexInitializer : IAuditLoggingIndexInitializer, ISingletonDependency |
|
|
{ |
|
|
{ |
|
|
private readonly AbpJsonOptions _jsonOptions; |
|
|
private readonly AbpJsonOptions _jsonOptions; |
|
|
private readonly AbpAuditLoggingElasticsearchOptions _elasticsearchOptions; |
|
|
private readonly AbpAuditLoggingElasticsearchOptions _elasticsearchOptions; |
|
|
private readonly IIndexNameNormalizer _nameNormalizer; |
|
|
private readonly IIndexNameNormalizer _nameNormalizer; |
|
|
private readonly IElasticsearchClientFactory _clientFactory; |
|
|
private readonly IElasticsearchClientFactory _clientFactory; |
|
|
|
|
|
|
|
|
public ILogger<IndexInitializer> Logger { protected get; set; } |
|
|
public ILogger<AuditLoggingIndexInitializer> Logger { protected get; set; } |
|
|
|
|
|
|
|
|
public IndexInitializer( |
|
|
public AuditLoggingIndexInitializer( |
|
|
IOptions<AbpJsonOptions> jsonOptions, |
|
|
IOptions<AbpJsonOptions> jsonOptions, |
|
|
IOptions<AbpAuditLoggingElasticsearchOptions> elasticsearchOptions, |
|
|
IOptions<AbpAuditLoggingElasticsearchOptions> elasticsearchOptions, |
|
|
IIndexNameNormalizer nameNormalizer, |
|
|
IIndexNameNormalizer nameNormalizer, |
|
|
@ -31,29 +35,40 @@ public class IndexInitializer : IIndexInitializer, ISingletonDependency |
|
|
_nameNormalizer = nameNormalizer; |
|
|
_nameNormalizer = nameNormalizer; |
|
|
_clientFactory = clientFactory; |
|
|
_clientFactory = clientFactory; |
|
|
|
|
|
|
|
|
Logger = NullLogger<IndexInitializer>.Instance; |
|
|
Logger = NullLogger<AuditLoggingIndexInitializer>.Instance; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public async virtual Task InitializeAsync() |
|
|
public async virtual Task InitializeAsync(CancellationToken cancellationToken = default) |
|
|
{ |
|
|
{ |
|
|
var client = _clientFactory.Create(); |
|
|
var client = _clientFactory.Create(); |
|
|
var dateTimeFormat = !_jsonOptions.OutputDateTimeFormat.IsNullOrWhiteSpace() |
|
|
var dateTimeFormat = !_jsonOptions.OutputDateTimeFormat.IsNullOrWhiteSpace() |
|
|
? $"{_jsonOptions.OutputDateTimeFormat}||strict_date_optional_time||epoch_millis" |
|
|
? $"{_jsonOptions.OutputDateTimeFormat}||strict_date_optional_time||epoch_millis" |
|
|
: "strict_date_optional_time||epoch_millis"; |
|
|
: "strict_date_optional_time||epoch_millis"; |
|
|
await InitlizeAuditLogIndex(client, dateTimeFormat); |
|
|
await InitlizeAuditLogIndexTemplate(client, dateTimeFormat, cancellationToken); |
|
|
await InitlizeSecurityLogIndex(client, dateTimeFormat); |
|
|
await InitlizeSecurityLogIndexTemplate(client, dateTimeFormat, cancellationToken); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
protected async virtual Task InitlizeAuditLogIndex(ElasticsearchClient client, string dateTimeFormat) |
|
|
protected async virtual Task InitlizeAuditLogIndexTemplate(ElasticsearchClient client, string dateTimeFormat, CancellationToken cancellationToken = default) |
|
|
{ |
|
|
{ |
|
|
var indexName = _nameNormalizer.NormalizeIndex("audit-log"); |
|
|
var indexName = _nameNormalizer.NormalizeIndex("audit-log"); |
|
|
var indexExists = await client.Indices.ExistsAsync(indexName); |
|
|
var indexPatterns = new[] { indexName + "-*" }; |
|
|
if (!indexExists.Exists) |
|
|
var indexTemplateName = indexName + "-generic"; |
|
|
|
|
|
|
|
|
|
|
|
var indexTemplateExists = await client.Indices.ExistsIndexTemplateAsync(indexTemplateName, cancellationToken); |
|
|
|
|
|
if (indexTemplateExists.Exists) |
|
|
|
|
|
{ |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var putTemplateResponse = await client.Indices.PutIndexTemplateAsync(indexTemplateName, setup => |
|
|
{ |
|
|
{ |
|
|
var indexCreateResponse = await client.Indices.CreateAsync(indexName, c => |
|
|
setup.IndexPatterns(indexPatterns); |
|
|
|
|
|
setup.Priority(100); |
|
|
|
|
|
setup.Version(1); |
|
|
|
|
|
setup.Template(template => |
|
|
{ |
|
|
{ |
|
|
c.Settings(_elasticsearchOptions.AuditLogSettings); |
|
|
template.Settings(_elasticsearchOptions.AuditLogSettings); |
|
|
c.Mappings(mp => mp |
|
|
template.Mappings(mp => mp |
|
|
.Dynamic(DynamicMapping.False) |
|
|
.Dynamic(DynamicMapping.False) |
|
|
.Properties<AuditLog>(pd => |
|
|
.Properties<AuditLog>(pd => |
|
|
{ |
|
|
{ |
|
|
@ -128,30 +143,57 @@ public class IndexInitializer : IIndexInitializer, ISingletonDependency |
|
|
pd.Flattened(f => f.ExtraProperties, f => f.DepthLimit(5).EagerGlobalOrdinals(false)); |
|
|
pd.Flattened(f => f.ExtraProperties, f => f.DepthLimit(5).EagerGlobalOrdinals(false)); |
|
|
})); |
|
|
})); |
|
|
}); |
|
|
}); |
|
|
|
|
|
}, cancellationToken); |
|
|
|
|
|
|
|
|
if (!indexCreateResponse.IsValidResponse) |
|
|
if (!putTemplateResponse.IsValidResponse) |
|
|
{ |
|
|
{ |
|
|
if (indexCreateResponse.TryGetOriginalException(out var ex)) |
|
|
var errorBuilder = new StringBuilder(); |
|
|
|
|
|
if (putTemplateResponse.TryGetOriginalException(out var ex)) |
|
|
{ |
|
|
{ |
|
|
|
|
|
errorBuilder.AppendLine(ex.Message); |
|
|
Logger.LogWarning(ex, "Failed to initialize index and audit log may not be retrieved."); |
|
|
Logger.LogWarning(ex, "Failed to initialize index and audit log may not be retrieved."); |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
Logger.LogWarning("Failed to initialize index and audit log may not be retrieved."); |
|
|
else if (putTemplateResponse.TryGetElasticsearchServerError(out var error)) |
|
|
Logger.LogWarning(indexCreateResponse.DebugInformation); |
|
|
{ |
|
|
|
|
|
errorBuilder.AppendLine(error.ToString()); |
|
|
} |
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
errorBuilder.AppendLine(putTemplateResponse.DebugInformation); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (_elasticsearchOptions.ThrowIfIndexInitFailed) |
|
|
|
|
|
{ |
|
|
|
|
|
throw new AbpInitializationException($"Failed to initialize audit log index template, the error: {errorBuilder.ToString()}"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
protected async virtual Task InitlizeSecurityLogIndex(ElasticsearchClient client, string dateTimeFormat) |
|
|
Logger.LogWarning("Failed to initialize index and audit log may not be retrieved."); |
|
|
|
|
|
Logger.LogWarning("The error: {error}", errorBuilder.ToString()); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected async virtual Task InitlizeSecurityLogIndexTemplate(ElasticsearchClient client, string dateTimeFormat, CancellationToken cancellationToken = default) |
|
|
{ |
|
|
{ |
|
|
var indexName = _nameNormalizer.NormalizeIndex("security-log"); |
|
|
var indexName = _nameNormalizer.NormalizeIndex("security-log"); |
|
|
var indexExists = await client.Indices.ExistsAsync(indexName); |
|
|
var indexPatterns = new[] { indexName + "-*" }; |
|
|
if (!indexExists.Exists) |
|
|
var indexTemplateName = indexName + "-generic"; |
|
|
|
|
|
|
|
|
|
|
|
var indexTemplateExists = await client.Indices.ExistsIndexTemplateAsync(indexTemplateName, cancellationToken); |
|
|
|
|
|
if (indexTemplateExists.Exists) |
|
|
{ |
|
|
{ |
|
|
var indexCreateResponse = await client.Indices.CreateAsync(indexName, c => |
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var putTemplateResponse = await client.Indices.PutIndexTemplateAsync(indexTemplateName, setup => |
|
|
|
|
|
{ |
|
|
|
|
|
setup.IndexPatterns(indexPatterns); |
|
|
|
|
|
setup.Priority(100); |
|
|
|
|
|
setup.Version(1); |
|
|
|
|
|
setup.Template(template => |
|
|
{ |
|
|
{ |
|
|
c.Settings(_elasticsearchOptions.SecurityLogSettings); |
|
|
template.Settings(_elasticsearchOptions.SecurityLogSettings); |
|
|
c.Mappings(mp => |
|
|
template.Mappings(mp => |
|
|
{ |
|
|
{ |
|
|
mp.Dynamic(DynamicMapping.False); |
|
|
mp.Dynamic(DynamicMapping.False); |
|
|
mp.Properties<SecurityLog>(pd => |
|
|
mp.Properties<SecurityLog>(pd => |
|
|
@ -173,16 +215,33 @@ public class IndexInitializer : IIndexInitializer, ISingletonDependency |
|
|
}); |
|
|
}); |
|
|
}); |
|
|
}); |
|
|
}); |
|
|
}); |
|
|
if (!indexCreateResponse.IsValidResponse) |
|
|
}, cancellationToken); |
|
|
|
|
|
|
|
|
|
|
|
if (!putTemplateResponse.IsValidResponse) |
|
|
{ |
|
|
{ |
|
|
if (indexCreateResponse.TryGetOriginalException(out var ex)) |
|
|
var errorBuilder = new StringBuilder(); |
|
|
|
|
|
if (putTemplateResponse.TryGetOriginalException(out var ex)) |
|
|
{ |
|
|
{ |
|
|
Logger.LogWarning(ex, "Failed to initialize index and audit log may not be retrieved."); |
|
|
errorBuilder.AppendLine(ex.Message); |
|
|
|
|
|
Logger.LogWarning(ex, "Failed to initialize index and security log may not be retrieved."); |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
Logger.LogWarning("Failed to initialize index and audit log may not be retrieved."); |
|
|
else if (putTemplateResponse.TryGetElasticsearchServerError(out var error)) |
|
|
Logger.LogWarning(indexCreateResponse.DebugInformation); |
|
|
{ |
|
|
|
|
|
errorBuilder.AppendLine(error.ToString()); |
|
|
|
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
errorBuilder.AppendLine(putTemplateResponse.DebugInformation); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (_elasticsearchOptions.ThrowIfIndexInitFailed) |
|
|
|
|
|
{ |
|
|
|
|
|
throw new AbpInitializationException($"Failed to initialize security log index template, the error: {errorBuilder.ToString()}"); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Logger.LogWarning("Failed to initialize index and security log may not be retrieved."); |
|
|
|
|
|
Logger.LogWarning("The error: {error}", errorBuilder.ToString()); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |