diff --git a/Directory.Build.props b/Directory.Build.props index 613e23f..a6ba50d 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -4,5 +4,6 @@ 2.0.593 6.0.* 1.9.7 + 7.15.1 \ No newline at end of file diff --git a/Sanhe.Abp.Framework.sln b/Sanhe.Abp.Framework.sln index d2a91c2..ad240d5 100644 --- a/Sanhe.Abp.Framework.sln +++ b/Sanhe.Abp.Framework.sln @@ -85,7 +85,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sanhe.Abp.Identity.HttpApi" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sanhe.Abp.Identity.HttpApi.Client", "modules\identity\Sanhe.Abp.Identity.HttpApi.Client\Sanhe.Abp.Identity.HttpApi.Client.csproj", "{6E5D3C18-45B4-478B-B064-140C5CDDD327}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sanhe.Abp.EntityFrameworkCore", "modules\common\Sanhe.Abp.EntityFrameworkCore\Sanhe.Abp.EntityFrameworkCore.csproj", "{464E3A2C-BBEB-4CD9-BAB8-A51D6283940A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sanhe.Abp.EntityFrameworkCore", "modules\common\Sanhe.Abp.EntityFrameworkCore\Sanhe.Abp.EntityFrameworkCore.csproj", "{464E3A2C-BBEB-4CD9-BAB8-A51D6283940A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "elasticsearch", "elasticsearch", "{449F764E-D3D5-4DFD-8707-2A378CF44C64}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sanhe.Abp.Elasticsearch", "modules\elasticsearch\Sanhe.Abp.Elasticsearch\Sanhe.Abp.Elasticsearch.csproj", "{3E1DA541-4D48-47A1-93FA-3D75BCB078F3}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -213,6 +217,10 @@ Global {464E3A2C-BBEB-4CD9-BAB8-A51D6283940A}.Debug|Any CPU.Build.0 = Debug|Any CPU {464E3A2C-BBEB-4CD9-BAB8-A51D6283940A}.Release|Any CPU.ActiveCfg = Release|Any CPU {464E3A2C-BBEB-4CD9-BAB8-A51D6283940A}.Release|Any CPU.Build.0 = Release|Any CPU + {3E1DA541-4D48-47A1-93FA-3D75BCB078F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3E1DA541-4D48-47A1-93FA-3D75BCB078F3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3E1DA541-4D48-47A1-93FA-3D75BCB078F3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3E1DA541-4D48-47A1-93FA-3D75BCB078F3}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -254,6 +262,8 @@ Global {F53FC671-99FD-4CD8-915E-5B77619A6C6B} = {BAA5EE9D-A5C6-45F3-A89B-B3CC30FF3DFE} {6E5D3C18-45B4-478B-B064-140C5CDDD327} = {BAA5EE9D-A5C6-45F3-A89B-B3CC30FF3DFE} {464E3A2C-BBEB-4CD9-BAB8-A51D6283940A} = {2A768109-31B7-4C52-928C-3023DAB9F254} + {449F764E-D3D5-4DFD-8707-2A378CF44C64} = {F5F5D604-531B-4B57-A88E-C9C5CEEC55D7} + {3E1DA541-4D48-47A1-93FA-3D75BCB078F3} = {449F764E-D3D5-4DFD-8707-2A378CF44C64} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {AB69BFDE-9DDB-4D16-8CB8-72472C0319CD} diff --git a/modules/elasticsearch/Sanhe.Abp.Elasticsearch/FodyWeavers.xml b/modules/elasticsearch/Sanhe.Abp.Elasticsearch/FodyWeavers.xml new file mode 100644 index 0000000..1715698 --- /dev/null +++ b/modules/elasticsearch/Sanhe.Abp.Elasticsearch/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/modules/elasticsearch/Sanhe.Abp.Elasticsearch/README.md b/modules/elasticsearch/Sanhe.Abp.Elasticsearch/README.md new file mode 100644 index 0000000..2948a63 --- /dev/null +++ b/modules/elasticsearch/Sanhe.Abp.Elasticsearch/README.md @@ -0,0 +1,37 @@ +# Sanhe.Abp.Elasticsearch + +Abp Elasticsearch集成,提供全局唯一IElasticClient访问接口 + +## 模块引用 + + +```csharp +[DependsOn(typeof(AbpElasticsearchModule))] +public class YouProjectModule : AbpModule +{ + // other +} +``` + +## 配置项 + +* AbpElasticsearchOptions.FieldCamelCase 字段是否采用 camelCase 格式, 默认false +* AbpElasticsearchOptions.NodeUris ES端点,多个端点以,或;分隔 +* AbpElasticsearchOptions.TypeName 文档名称,默认_doc +* AbpElasticsearchOptions.ConnectionLimit 最大连接数,详情见 NEST 文档 +* AbpElasticsearchOptions.UserName 连接用户,详情见 NEST 文档 +* AbpElasticsearchOptions.Password 用户密码,详情见 NEST 文档 +* AbpElasticsearchOptions.ConnectionTimeout 连接超时时间,详情见 NEST 文档 + +## appsettings.json + +```json +{ + "Elasticsearch": { + "NodeUris": "http://localhost:9200" + } +} + +``` + +[作者colinin,Github](https://github.com/colinin/abp-next-admin) \ No newline at end of file diff --git a/modules/elasticsearch/Sanhe.Abp.Elasticsearch/Sanhe.Abp.Elasticsearch.csproj b/modules/elasticsearch/Sanhe.Abp.Elasticsearch/Sanhe.Abp.Elasticsearch.csproj new file mode 100644 index 0000000..af433b5 --- /dev/null +++ b/modules/elasticsearch/Sanhe.Abp.Elasticsearch/Sanhe.Abp.Elasticsearch.csproj @@ -0,0 +1,15 @@ + + + + + + + netstandard2.0 + + + + + + + + diff --git a/modules/elasticsearch/Sanhe.Abp.Elasticsearch/Sanhe/Abp/Elasticsearch/AbpElasticsearchModule.cs b/modules/elasticsearch/Sanhe.Abp.Elasticsearch/Sanhe/Abp/Elasticsearch/AbpElasticsearchModule.cs new file mode 100644 index 0000000..507af5f --- /dev/null +++ b/modules/elasticsearch/Sanhe.Abp.Elasticsearch/Sanhe/Abp/Elasticsearch/AbpElasticsearchModule.cs @@ -0,0 +1,14 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Modularity; + +namespace Sanhe.Abp.Elasticsearch +{ + public class AbpElasticsearchModule : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + var configuration = context.Services.GetConfiguration(); + Configure(configuration.GetSection("Elasticsearch")); + } + } +} diff --git a/modules/elasticsearch/Sanhe.Abp.Elasticsearch/Sanhe/Abp/Elasticsearch/AbpElasticsearchOptions.cs b/modules/elasticsearch/Sanhe.Abp.Elasticsearch/Sanhe/Abp/Elasticsearch/AbpElasticsearchOptions.cs new file mode 100644 index 0000000..0bd3cbd --- /dev/null +++ b/modules/elasticsearch/Sanhe.Abp.Elasticsearch/Sanhe/Abp/Elasticsearch/AbpElasticsearchOptions.cs @@ -0,0 +1,94 @@ +using Elasticsearch.Net; +using Nest; +using System; +using System.Linq; + +namespace Sanhe.Abp.Elasticsearch +{ + public class AbpElasticsearchOptions + { + /// + /// 字段名称 是否为 camelCase 格式。 + /// 如果为true, 在ES中为 camelCase。 + /// 如果为false,在ES中为 CamelCase。 + /// 默认:false。 + /// + public bool FieldCamelCase { get; set; } + /// + /// Ensures the response bytes are always available on the + /// + public bool DisableDirectStreaming { get; set; } + /// + /// ES端点,多个端点以,或;分隔 + /// + public string NodeUris { get; set; } + /// + /// 最大连接数 + /// + public int ConnectionLimit { get; set; } + /// + /// 连接用户名 + /// + public string UserName { get; set; } + /// + /// 用户密码 + /// + public string Password { get; set; } + /// + /// 连接超时时间 + /// + public TimeSpan ConnectionTimeout { get; set; } + /// + /// + /// + public IConnection Connection { get; set; } + /// + /// + /// + public ConnectionSettings.SourceSerializerFactory SerializerFactory { get; set; } + + public AbpElasticsearchOptions() + { + ConnectionLimit = ConnectionConfiguration.DefaultConnectionLimit; + ConnectionTimeout = ConnectionConfiguration.DefaultTimeout; + } + + internal IConnectionSettingsValues CreateConfiguration() + { + IConnectionPool connectionPool; + var nodes = NodeUris + .Split(new[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries) + .Select(uriString => new Uri(uriString)); + + if (nodes.Count() == 1) + { + connectionPool = new SingleNodeConnectionPool(nodes.First()); + } + else + { + connectionPool = new StaticConnectionPool(nodes); + } + + var configuration = new ConnectionSettings( + connectionPool, + Connection, + SerializerFactory) + .ConnectionLimit(ConnectionLimit) + .RequestTimeout(ConnectionTimeout); + + if (!FieldCamelCase) + { + configuration.DefaultFieldNameInferrer((name) => name); + } + + if (UserName.IsNullOrWhiteSpace()) + { + configuration.BasicAuthentication(UserName, Password); + } + + configuration.DisableDirectStreaming(DisableDirectStreaming); + + return configuration; + } + } +} diff --git a/modules/elasticsearch/Sanhe.Abp.Elasticsearch/Sanhe/Abp/Elasticsearch/ElasticsearchClientFactory.cs b/modules/elasticsearch/Sanhe.Abp.Elasticsearch/Sanhe/Abp/Elasticsearch/ElasticsearchClientFactory.cs new file mode 100644 index 0000000..1e2ee2d --- /dev/null +++ b/modules/elasticsearch/Sanhe.Abp.Elasticsearch/Sanhe/Abp/Elasticsearch/ElasticsearchClientFactory.cs @@ -0,0 +1,32 @@ +using Microsoft.Extensions.Options; +using Nest; +using System; +using Volo.Abp.DependencyInjection; + +namespace Sanhe.Abp.Elasticsearch +{ + public class ElasticsearchClientFactory : IElasticsearchClientFactory, ISingletonDependency + { + private readonly AbpElasticsearchOptions _options; + private readonly Lazy _lazyClient; + + public ElasticsearchClientFactory( + IOptions options) + { + _options = options.Value; + + _lazyClient = new Lazy(CreateClient); + } + + public IElasticClient Create() => _lazyClient.Value; + + protected virtual IElasticClient CreateClient() + { + var configuration = _options.CreateConfiguration(); + + var client = new ElasticClient(configuration); + + return client; + } + } +} diff --git a/modules/elasticsearch/Sanhe.Abp.Elasticsearch/Sanhe/Abp/Elasticsearch/IElasticsearchClientFactory.cs b/modules/elasticsearch/Sanhe.Abp.Elasticsearch/Sanhe/Abp/Elasticsearch/IElasticsearchClientFactory.cs new file mode 100644 index 0000000..3c61712 --- /dev/null +++ b/modules/elasticsearch/Sanhe.Abp.Elasticsearch/Sanhe/Abp/Elasticsearch/IElasticsearchClientFactory.cs @@ -0,0 +1,9 @@ +using Nest; + +namespace Sanhe.Abp.Elasticsearch +{ + public interface IElasticsearchClientFactory + { + IElasticClient Create(); + } +}