Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Refactor Elasticsearch #364

Merged
merged 5 commits into from
Dec 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ private static void TryAddAutoCompleteRelation(this IServiceCollection services,
throw new ArgumentException($"indexName or alias exists");

if (relation.IsDefault && relationsOptions.Relations.Any(r => r.IsDefault))
throw new ArgumentException("ElasticClient can only have one default", nameof(ElasticsearchRelations.IsDefault));
throw new ArgumentException("ElasticClient can only have one default", nameof(ElasticsearchOptions.IsDefault));

relationsOptions.AddRelation(relation);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,12 @@ private static IServiceCollection AddElasticsearch(IServiceCollection services,
});
}

internal static IElasticClient CreateElasticClient(this IElasticsearchFactory elasticsearchFactory, bool isLog)
internal static IElasticClient CreateElasticClient(this IElasticClientFactory elasticsearchFactory, bool isLog)
{
if (isLog)
return elasticsearchFactory.CreateElasticClient(ElasticConstant.Log.IsIndependent ? ElasticConstant.LOG_CALLER_CLIENT_NAME : ElasticConstant.DEFAULT_CALLER_CLIENT_NAME);
return elasticsearchFactory.Create(ElasticConstant.Log.IsIndependent ? ElasticConstant.LOG_CALLER_CLIENT_NAME : ElasticConstant.DEFAULT_CALLER_CLIENT_NAME);
else
return elasticsearchFactory.CreateElasticClient(ElasticConstant.Trace.IsIndependent ? ElasticConstant.TRACE_CALLER_CLIENT_NAME : ElasticConstant.DEFAULT_CALLER_CLIENT_NAME);
return elasticsearchFactory.Create(ElasticConstant.Trace.IsIndependent ? ElasticConstant.TRACE_CALLER_CLIENT_NAME : ElasticConstant.DEFAULT_CALLER_CLIENT_NAME);
}

internal static ICaller Create(this ICallerFactory callerFactory, bool isLog)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ internal class LogService : ILogService
private readonly IElasticClient _client;
private readonly ICallerFactory _callerFactory;

public LogService(IElasticsearchFactory elasticsearchFactory, ICallerFactory callerFactory)
public LogService(IElasticClientFactory elasticClientFactory, ICallerFactory callerFactory)
{
_client = elasticsearchFactory.CreateElasticClient(true);
_client = elasticClientFactory.CreateElasticClient(true);
_callerFactory = callerFactory;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ internal class TraceService : ITraceService
{
private readonly IElasticClient _client;

public TraceService(IElasticsearchFactory elasticsearchFactory)
public TraceService(IElasticClientFactory elasticClientFactory)
{
_client = elasticsearchFactory.CreateElasticClient(false);
_client = elasticClientFactory.CreateElasticClient(false);
}

public async Task<object> AggregateAsync(SimpleAggregateRequestDto query)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

namespace Masa.Contrib.StackSdks.Tsc.Elasticsearch.Tests.Extensions;

#pragma warning disable CS0618
[TestClass]
public class ServiceExtenistionTests
{
Expand All @@ -16,6 +17,7 @@ public void AddLogNodesTest()

var factory = services.BuildServiceProvider().GetRequiredService<IElasticsearchFactory>();
Assert.IsNotNull(factory);

Assert.IsNotNull(factory.CreateElasticClient(ElasticConstant.LOG_CALLER_CLIENT_NAME));
Assert.ThrowsException<NotSupportedException>(() => factory.CreateElasticClient(ElasticConstant.TRACE_CALLER_CLIENT_NAME));
Assert.ThrowsException<NotSupportedException>(() => factory.CreateElasticClient(ElasticConstant.DEFAULT_CALLER_CLIENT_NAME));
Expand Down Expand Up @@ -132,3 +134,4 @@ public void AddLogTraceOptionsTest()
services.Clear();
}
}
#pragma warning restore CS0618
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Copyright (c) MASA Stack All rights reserved.
// Licensed under the MIT License. See LICENSE.txt in the project root for license information.

namespace Masa.Utils.Data.Elasticsearch;

public class DefaultElasticClientFactory : IElasticClientFactory
{
private readonly List<string> _names;
private readonly IOptionsMonitor<ElasticsearchOptions> _elasticsearchOptions;

public DefaultElasticClientFactory(IOptionsMonitor<ElasticsearchOptions> elasticsearchOptions,
IEnumerable<IConfigureOptions<ElasticsearchOptions>> options)
{
_elasticsearchOptions = elasticsearchOptions;
_names = options.Select(opt => ((ConfigureNamedOptions<ElasticsearchOptions>)opt).Name).ToList();
}

public IElasticClient Create()
{
var elasticsearchOptions = _elasticsearchOptions.Get(Microsoft.Extensions.Options.Options.DefaultName);

if (elasticsearchOptions.Nodes is null) elasticsearchOptions = _elasticsearchOptions.Get(_names.FirstOrDefault());

if (elasticsearchOptions.Nodes is null) throw new ArgumentException("The default ElasticClient is not found, please check if Elasticsearch is added");

return Create(elasticsearchOptions);
}

public IElasticClient Create(string name)
{
var elasticsearchOptions = _elasticsearchOptions.Get(name);
if (elasticsearchOptions.Nodes is null) throw new NotSupportedException($"The ElasticClient whose name is {name} is not found");

return Create(elasticsearchOptions);
}

private static IElasticClient Create(ElasticsearchOptions elasticsearchOptions)
{
var settings = elasticsearchOptions.UseConnectionPool
? GetConnectionSettingsConnectionPool(elasticsearchOptions)
: GetConnectionSettingsBySingleNode(elasticsearchOptions);

return new ElasticClient(settings);
}

private static ConnectionSettings GetConnectionSettingsBySingleNode(ElasticsearchOptions relation)
{
var connectionSetting = new ConnectionSettings(new Uri(relation.Nodes[0]))
.EnableApiVersioningHeader();
relation.Action?.Invoke(connectionSetting);
return connectionSetting;
}

private static ConnectionSettings GetConnectionSettingsConnectionPool(ElasticsearchOptions relation)
{
var pool = new StaticConnectionPool(
relation.Nodes.Select(node => new Uri(node)),
relation.StaticConnectionPoolOptions?.Randomize ?? true,
relation.StaticConnectionPoolOptions?.DateTimeProvider);

var settings = new ConnectionSettings(
pool,
relation.ConnectionSettingsOptions?.Connection,
relation.ConnectionSettingsOptions?.SourceSerializerFactory,
relation.ConnectionSettingsOptions?.PropertyMappingProvider)
.EnableApiVersioningHeader();

relation.Action?.Invoke(settings);
return settings;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,80 +5,16 @@ namespace Masa.Utils.Data.Elasticsearch;

public class DefaultElasticsearchFactory : IElasticsearchFactory
{
private readonly Dictionary<string, ElasticsearchRelations> _relations;
private readonly ConcurrentDictionary<string, IElasticClient> _elasticClients;
private readonly IElasticClientFactory _factory;

public DefaultElasticsearchFactory(ElasticsearchRelationsOptions options)
{
_relations = options.Relations;
_elasticClients = new();
}
public DefaultElasticsearchFactory(IElasticClientFactory factory)
=> _factory = factory;

public IMasaElasticClient CreateClient()
{
return new DefaultMasaElasticClient(CreateElasticClient());
}
public IMasaElasticClient CreateClient() => new DefaultMasaElasticClient(CreateElasticClient());

public IMasaElasticClient CreateClient(string name)
{
return new DefaultMasaElasticClient(CreateElasticClient(name));
}
public IMasaElasticClient CreateClient(string name) => new DefaultMasaElasticClient(CreateElasticClient(name));

public IElasticClient CreateElasticClient()
{
var elasticsearchRelation = _relations.Values.SingleOrDefault(r => r.IsDefault) ?? _relations.Values.FirstOrDefault();
public IElasticClient CreateElasticClient() => _factory.Create();

if (elasticsearchRelation == null)
throw new Exception("The default ElasticClient is not found, please check if Elasticsearch is added");

return GetOrAddElasticClient(elasticsearchRelation.Name);
}

public IElasticClient CreateElasticClient(string name)
{
if (!_relations.ContainsKey(name))
throw new NotSupportedException($"The ElasticClient whose name is {name} is not found");

return GetOrAddElasticClient(name);
}

private IElasticClient GetOrAddElasticClient(string name)
=> _elasticClients.GetOrAdd(name, name => Create(name));

private IElasticClient Create(string name)
{
var relation = _relations[name];

var settings = relation.UseConnectionPool
? GetConnectionSettingsConnectionPool(relation)
: GetConnectionSettingsBySingleNode(relation);

return new ElasticClient(settings);
}

private ConnectionSettings GetConnectionSettingsBySingleNode(ElasticsearchRelations relation)
{
var connectionSetting = new ConnectionSettings(relation.Nodes[0])
.EnableApiVersioningHeader();
relation.Action?.Invoke(connectionSetting);
return connectionSetting;
}

private ConnectionSettings GetConnectionSettingsConnectionPool(ElasticsearchRelations relation)
{
var pool = new StaticConnectionPool(
relation.Nodes,
relation.StaticConnectionPoolOptions?.Randomize ?? true,
relation.StaticConnectionPoolOptions?.DateTimeProvider);

var settings = new ConnectionSettings(
pool,
relation.ConnectionSettingsOptions?.Connection,
relation.ConnectionSettingsOptions?.SourceSerializerFactory,
relation.ConnectionSettingsOptions?.PropertyMappingProvider)
.EnableApiVersioningHeader();

relation.Action?.Invoke(settings);
return settings;
}
public IElasticClient CreateElasticClient(string name) => _factory.Create(name);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) MASA Stack All rights reserved.
// Licensed under the MIT License. See LICENSE.txt in the project root for license information.

namespace Masa.Utils.Data.Elasticsearch;

public class DefaultMasaElasticClientFactory : IMasaElasticClientFactory
{
private readonly IElasticClientFactory _clientFactory;

public DefaultMasaElasticClientFactory(IElasticClientFactory clientFactory)
{
_clientFactory = clientFactory;
}

public IMasaElasticClient Create()
{
var elasticClient = _clientFactory.Create();
return new DefaultMasaElasticClient(elasticClient);
}

public IMasaElasticClient Create(string name)
{
var elasticClient = _clientFactory.Create(name);
return new DefaultMasaElasticClient(elasticClient);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
// Copyright (c) MASA Stack All rights reserved.
// Licensed under the MIT License. See LICENSE.txt in the project root for license information.

// ReSharper disable once CheckNamespace

namespace Microsoft.Extensions.DependencyInjection;

public static partial class ServiceCollectionExtensions
{
private static MasaElasticsearchBuilder CreateElasticsearchClient(this IServiceCollection services, string name)
{
var elasticClient = services.BuildServiceProvider().GetRequiredService<IElasticsearchFactory>().CreateElasticClient(name);
var elasticClient = services.BuildServiceProvider().GetRequiredService<IElasticClientFactory>().Create(name);
return new MasaElasticsearchBuilder(services, elasticClient);
}

Expand All @@ -16,15 +18,17 @@ public static MasaElasticsearchBuilder AddElasticsearchClient(this IServiceColle

public static MasaElasticsearchBuilder AddElasticsearchClient(this IServiceCollection services, string[]? nodes)
=> services
.AddElasticsearch(Const.DEFAULT_CLIENT_NAME, nodes == null || nodes.Length == 0 ? new[] {"http://localhost:9200"} : nodes)
.AddElasticsearch(Const.DEFAULT_CLIENT_NAME, nodes == null || nodes.Length == 0 ? new[] { "http://localhost:9200" } : nodes)
.CreateElasticsearchClient(Const.DEFAULT_CLIENT_NAME);

public static MasaElasticsearchBuilder AddElasticsearchClient(this IServiceCollection services, string name, params string[] nodes)
=> services.AddElasticsearch(name, nodes).CreateElasticsearchClient(name);

public static MasaElasticsearchBuilder AddElasticsearchClient(this IServiceCollection services, string name, Action<ElasticsearchOptions> action)
public static MasaElasticsearchBuilder AddElasticsearchClient(this IServiceCollection services, string name,
Action<ElasticsearchOptions> action)
=> services.AddElasticsearch(name, action).CreateElasticsearchClient(name);

public static MasaElasticsearchBuilder AddElasticsearchClient(this IServiceCollection services, string name, Func<ElasticsearchOptions> func)
public static MasaElasticsearchBuilder AddElasticsearchClient(this IServiceCollection services, string name,
Func<ElasticsearchOptions> func)
=> services.AddElasticsearch(name, func).CreateElasticsearchClient(name);
}
Loading