1
This commit is contained in:
parent
d40e83ba9c
commit
87f096e0e6
@ -42,5 +42,11 @@
|
|||||||
"UserName": "dev",
|
"UserName": "dev",
|
||||||
"Password": "itd!@#123"
|
"Password": "itd!@#123"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"ElasticSearch": {
|
||||||
|
"NodeUrls": [ "http://elasticsearch-dev.default.svc.cluster.local:9200" ],
|
||||||
|
"LoginName": "elastic",
|
||||||
|
"Password": "afyTgmVb8jq6",
|
||||||
|
"Base64PassPassword": "Basic ZWxhc3RpYzphZnlUZ21WYjhqcTY="
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
using Fake.Modularity;
|
using System.Configuration;
|
||||||
|
using Fake.Modularity;
|
||||||
using Fake.SqlSugarCore;
|
using Fake.SqlSugarCore;
|
||||||
using Fake.UnitOfWork;
|
using Fake.UnitOfWork;
|
||||||
|
using InterfaceForward.Repositories.Log.ES;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
@ -20,5 +22,13 @@ public class InterfaceForwardRepositoriesModule : FakeModule
|
|||||||
});
|
});
|
||||||
|
|
||||||
context.Services.AddScoped(typeof(IBasicRepository<>), typeof(BasicRepository<>));
|
context.Services.AddScoped(typeof(IBasicRepository<>), typeof(BasicRepository<>));
|
||||||
|
|
||||||
|
context.Services.Configure<ElasticSearchOptions>(options =>
|
||||||
|
{
|
||||||
|
configuration.GetSection("ElasticSearch").Bind(options);
|
||||||
|
#if !DEBUG
|
||||||
|
options.ShowLogInfo = false;
|
||||||
|
#endif
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,29 +1,25 @@
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Elasticsearch.Net;
|
using Elasticsearch.Net;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Nest;
|
using Nest;
|
||||||
|
|
||||||
namespace InterfaceForward.Repositories.Log.ES;
|
namespace InterfaceForward.Repositories.Log.ES;
|
||||||
|
|
||||||
public class ConnectionFactory
|
public class ConnectionFactory : ISingletonDependency
|
||||||
{
|
{
|
||||||
internal static ElasticSearchOptions _options;
|
private readonly ILogger<ConnectionFactory> _logger;
|
||||||
internal static ConnectionSettings _connectionSettings;
|
private readonly ElasticSearchOptions _options;
|
||||||
private static ConcurrentDictionary<Type, IElasticClient> _clientDic = new();
|
private readonly ConnectionSettings _connectionSettings;
|
||||||
|
private readonly ConcurrentDictionary<Type, IElasticClient> _clientDic = new();
|
||||||
|
|
||||||
#region 构造函数
|
|
||||||
/// <summary>
|
public ConnectionFactory(IOptions<ElasticSearchOptions> options, ILogger<ConnectionFactory> logger)
|
||||||
/// 构造函数
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="options"></param>
|
|
||||||
public ConnectionFactory(IOptions<ElasticSearchOptions> options)
|
|
||||||
{
|
{
|
||||||
if (_options == null)
|
_logger = logger;
|
||||||
_options = options.Value;
|
_options = options.Value;
|
||||||
|
|
||||||
if (_connectionSettings == null)
|
|
||||||
{
|
|
||||||
var uris = new List<Uri>();
|
var uris = new List<Uri>();
|
||||||
foreach (var item in _options.NodeUrls)
|
foreach (var item in _options.NodeUrls)
|
||||||
{
|
{
|
||||||
@ -33,35 +29,29 @@ public class ConnectionFactory
|
|||||||
//using var connectionPool = new SniffingConnectionPool(uris);//集群连接池,支持嗅探,ping
|
//using var connectionPool = new SniffingConnectionPool(uris);//集群连接池,支持嗅探,ping
|
||||||
|
|
||||||
using var connectionPool = new SingleNodeConnectionPool(uris[0]); //单点连接池
|
using var connectionPool = new SingleNodeConnectionPool(uris[0]); //单点连接池
|
||||||
_connectionSettings = new ConnectionSettings(connectionPool).BasicAuthentication(_options.LoginName, _options.Password);
|
_connectionSettings =
|
||||||
|
new ConnectionSettings(connectionPool).BasicAuthentication(_options.LoginName, _options.Password);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 上下文
|
|
||||||
public IElasticClient GetContext(Type type)
|
public IElasticClient GetContext(Type type)
|
||||||
{
|
{
|
||||||
IElasticClient client = null;
|
|
||||||
|
|
||||||
//如果有缓存,直接从缓存返回
|
//如果有缓存,直接从缓存返回
|
||||||
if (_clientDic.ContainsKey(type))
|
if (_clientDic.TryGetValue(type, out var value))
|
||||||
{
|
{
|
||||||
client = _clientDic[type];
|
return value;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
IElasticClient client;
|
||||||
var defaultIndex = "";
|
var defaultIndex = "";
|
||||||
|
|
||||||
var attr = type.GetCustomAttribute<ElasticsearchTypeAttribute>(false);
|
var attr = type.GetCustomAttribute<ElasticsearchTypeAttribute>(false);
|
||||||
if (attr == null)
|
if (attr == null)
|
||||||
throw new Exception("未找到指定对象的index名称");
|
throw new Exception("未找到指定对象的index名称");
|
||||||
|
|
||||||
//如果启用了index前缀
|
defaultIndex = !_options.IndexPrefix.IsNullOrWhiteSpace()
|
||||||
var useIndexNamePrefix = type.GetCustomAttributes(typeof(UseIndexPrefixAttribute), true).Any();
|
? $"{_options.IndexPrefix}{attr.RelationName}"
|
||||||
if (useIndexNamePrefix && string.IsNullOrEmpty(_options.IndexPrefix))
|
: attr.RelationName;
|
||||||
throw new Exception($"{type}启用了index前缀,却没在配置文件中找到相关配置,请检查配置项[ElasticSearch:IndexPrefix]是否指定!");
|
|
||||||
|
|
||||||
defaultIndex = useIndexNamePrefix ? $"{_options.IndexPrefix}{attr.RelationName}" : attr.RelationName;
|
|
||||||
_connectionSettings.DefaultIndex(defaultIndex);
|
_connectionSettings.DefaultIndex(defaultIndex);
|
||||||
|
|
||||||
//是否输出日志
|
//是否输出日志
|
||||||
@ -85,13 +75,10 @@ public class ConnectionFactory
|
|||||||
|
|
||||||
_clientDic.TryAdd(type, client);
|
_clientDic.TryAdd(type, client);
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#region 输出执行结果
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 输出执行结果
|
/// 输出执行结果
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -100,11 +87,8 @@ public class ConnectionFactory
|
|||||||
private string GetInfosFromApiCallDetails(IApiCallDetails details)
|
private string GetInfosFromApiCallDetails(IApiCallDetails details)
|
||||||
{
|
{
|
||||||
var infos = $@"
|
var infos = $@"
|
||||||
|-执行时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ffff")}
|
|-执行时间:{DateTime.Now:yyyy-MM-dd HH:mm:ss ffff}
|
||||||
|-请求响应:{details.DebugInformation} ";
|
|-请求响应:{details.DebugInformation} ";
|
||||||
return infos;
|
return infos;
|
||||||
}
|
}
|
||||||
#endregion
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
@ -4,35 +4,15 @@ namespace InterfaceForward.Repositories.Log.ES;
|
|||||||
|
|
||||||
public abstract class ElasticSearchContextAbstract<T> : IElasticsearchClientService<T> where T : IdBaseIndex, new()
|
public abstract class ElasticSearchContextAbstract<T> : IElasticsearchClientService<T> where T : IdBaseIndex, new()
|
||||||
{
|
{
|
||||||
|
private readonly string _indexName;
|
||||||
|
protected IElasticClient Context { get; }
|
||||||
|
|
||||||
#region 构造函数
|
protected ElasticSearchContextAbstract(ConnectionFactory connectionFactory)
|
||||||
private readonly IElasticClient _client;
|
|
||||||
private string _indexName;
|
|
||||||
public ElasticSearchContextAbstract(ConnectionFactory connectionFactory)
|
|
||||||
{
|
{
|
||||||
_client = connectionFactory.GetContext(typeof(T));
|
Context = connectionFactory.GetContext(typeof(T));
|
||||||
_indexName = _client.ConnectionSettings.DefaultIndex;
|
_indexName = Context.ConnectionSettings.DefaultIndex;
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 上下文
|
|
||||||
public IElasticClient Context
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _client;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 新增文档
|
|
||||||
/// <summary>
|
|
||||||
/// 新增文档
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="data">索引数据</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
/// <exception cref="Exception"></exception>
|
|
||||||
public virtual async Task<string> IndexDocumentAsync(T data)
|
public virtual async Task<string> IndexDocumentAsync(T data)
|
||||||
{
|
{
|
||||||
var response = await Context.IndexAsync(data, request => request.Index(_indexName));
|
var response = await Context.IndexAsync(data, request => request.Index(_indexName));
|
||||||
@ -42,13 +22,6 @@ public abstract class ElasticSearchContextAbstract<T> : IElasticsearchClientServ
|
|||||||
return response.Id;
|
return response.Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 批量新增文档
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T"></typeparam>
|
|
||||||
/// <param name="list"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
/// <exception cref="Exception"></exception>
|
|
||||||
public virtual async Task<BulkResponse> IndexManyDocumentAsync(List<T> list, bool refresh = false)
|
public virtual async Task<BulkResponse> IndexManyDocumentAsync(List<T> list, bool refresh = false)
|
||||||
{
|
{
|
||||||
var response = await Context.IndexManyAsync<T>(list, _indexName);
|
var response = await Context.IndexManyAsync<T>(list, _indexName);
|
||||||
@ -60,47 +33,22 @@ public abstract class ElasticSearchContextAbstract<T> : IElasticsearchClientServ
|
|||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 根据Id删除文档
|
|
||||||
/// <summary>
|
|
||||||
/// 根据Id删除文档
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
/// <exception cref="Exception"></exception>
|
|
||||||
public virtual async Task DeleteByIdAsync(string id)
|
public virtual async Task DeleteByIdAsync(string id)
|
||||||
{
|
{
|
||||||
var response = await Context.DeleteAsync<T>(id, i => i.Index(_indexName));
|
var response = await Context.DeleteAsync<T>(id, i => i.Index(_indexName));
|
||||||
if (!response.IsValid)
|
if (!response.IsValid)
|
||||||
throw new Exception($"数据删除失败,原因:{response.DebugInformation}");
|
throw new Exception($"数据删除失败,原因:{response.DebugInformation}");
|
||||||
}
|
}
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 修改指定的文档
|
|
||||||
/// <summary>
|
|
||||||
/// 修改指定的文档
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T"></typeparam>
|
|
||||||
/// <param name="data"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
/// <exception cref="Exception"></exception>
|
|
||||||
public virtual async Task UpdateAsync(string id, T data)
|
public virtual async Task UpdateAsync(string id, T data)
|
||||||
{
|
{
|
||||||
var response = await Context.UpdateAsync<T>(id, u => u.Doc(data).Index(_indexName));
|
var response = await Context.UpdateAsync<T>(id, u => u.Doc(data).Index(_indexName));
|
||||||
if (!response.IsValid)
|
if (!response.IsValid)
|
||||||
throw new Exception($"数据修改失败,原因:{response.DebugInformation}");
|
throw new Exception($"数据修改失败,原因:{response.DebugInformation}");
|
||||||
}
|
}
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 根据ID获取单条
|
public virtual async Task<T?> GetByIdAsync(string id)
|
||||||
/// <summary>
|
|
||||||
/// 根据ID获取单条文档
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
/// <exception cref="Exception"></exception>
|
|
||||||
public virtual async Task<T> GetByIdAsync(string id)
|
|
||||||
{
|
{
|
||||||
var response = await Context.GetAsync<T>(id, i => i.Index(_indexName));
|
var response = await Context.GetAsync<T>(id, i => i.Index(_indexName));
|
||||||
if (response.Source != null)
|
if (response.Source != null)
|
||||||
@ -108,11 +56,10 @@ public abstract class ElasticSearchContextAbstract<T> : IElasticsearchClientServ
|
|||||||
|
|
||||||
switch (response.ApiCall.HttpStatusCode)
|
switch (response.ApiCall.HttpStatusCode)
|
||||||
{
|
{
|
||||||
case 200: return response?.Source;
|
case 200: return response.Source;
|
||||||
case 404: return null;
|
case 404: return null;
|
||||||
default: throw new Exception($"数据查询失败,原因:{response.DebugInformation}");
|
default: throw new Exception($"数据查询失败,原因:{response.DebugInformation}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -5,31 +5,25 @@ public class ElasticSearchOptions
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 是否显示日志
|
/// 是否显示日志
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool ShowLogInfo { get; set; } = false;
|
public bool ShowLogInfo { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 服务节点
|
/// 服务节点
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<string> NodeUrls { get; set; }
|
public List<string> NodeUrls { get; set; } = [];
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 索引前缀
|
/// 索引前缀
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string IndexPrefix { get; set; }
|
public string? IndexPrefix { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 登录账号
|
/// 登录账号
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string LoginName { get; set; }
|
public string LoginName { get; set; } = null!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 登录密码(明文)
|
/// 登录密码(明文)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Password { get; set; }
|
public string Password { get; set; } = null!;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 登录密码(加密)
|
|
||||||
/// </summary>
|
|
||||||
public string Base64PassPassword { get; set; }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -4,10 +4,47 @@ namespace InterfaceForward.Repositories.Log.ES;
|
|||||||
|
|
||||||
public interface IElasticsearchClientService<T> where T : class
|
public interface IElasticsearchClientService<T> where T : class
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 新增文档
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data">索引数据</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <exception cref="Exception"></exception>
|
||||||
Task<string> IndexDocumentAsync(T data);
|
Task<string> IndexDocumentAsync(T data);
|
||||||
Task<T> GetByIdAsync(string Id);
|
|
||||||
Task UpdateAsync(string id, T input);
|
/// <summary>
|
||||||
Task DeleteByIdAsync(string id);
|
/// 批量新增文档
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <param name="list"></param>
|
||||||
|
/// <param name="refresh"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <exception cref="Exception"></exception>
|
||||||
Task<BulkResponse> IndexManyDocumentAsync(List<T> list, bool refresh);
|
Task<BulkResponse> IndexManyDocumentAsync(List<T> list, bool refresh);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据ID获取单条文档
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <exception cref="Exception"></exception>
|
||||||
|
Task<T?> GetByIdAsync(string id);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 修改指定的文档
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <param name="id"></param>
|
||||||
|
/// <param name="data"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <exception cref="Exception"></exception>
|
||||||
|
Task UpdateAsync(string id, T data);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据Id删除文档
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <exception cref="Exception"></exception>
|
||||||
|
Task DeleteByIdAsync(string id);
|
||||||
}
|
}
|
||||||
@ -1,16 +0,0 @@
|
|||||||
namespace InterfaceForward.Repositories.Log.ES;
|
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Class)]
|
|
||||||
public class UseIndexPrefixAttribute : Attribute
|
|
||||||
{
|
|
||||||
public UseIndexPrefixAttribute()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
public UseIndexPrefixAttribute(string indexPrefix)
|
|
||||||
{
|
|
||||||
IndexPrefix = indexPrefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string IndexPrefix { get; }
|
|
||||||
}
|
|
||||||
@ -1,5 +1,6 @@
|
|||||||
using InterfaceForward.Domain.Shared.Dtos;
|
using InterfaceForward.Domain.Shared.Dtos;
|
||||||
using InterfaceForward.Repositories.Log.Entitys;
|
using InterfaceForward.Repositories.Log.Entitys;
|
||||||
|
using InterfaceForward.Repositories.Log.ES;
|
||||||
using InterfaceForward.Repositories.Log.ValueObjects;
|
using InterfaceForward.Repositories.Log.ValueObjects;
|
||||||
using Nest;
|
using Nest;
|
||||||
|
|
||||||
@ -8,7 +9,7 @@ namespace InterfaceForward.Repositories.Log.Services
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 日志仓储
|
/// 日志仓储
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface ILogRepository
|
public interface ILogRepository : IElasticsearchClientService<LogIndex>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 应用id
|
/// 应用id
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user