Skip to content

Commit

Permalink
Ping Elasticsearch async (OrchardCMS#14875)
Browse files Browse the repository at this point in the history
  • Loading branch information
MikeAlhayek authored and urbanit committed Mar 18, 2024
1 parent 9ffa9a5 commit 5815690
Showing 1 changed file with 120 additions and 134 deletions.
254 changes: 120 additions & 134 deletions src/OrchardCore.Modules/OrchardCore.Search.Elasticsearch/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
using OrchardCore.Deployment;
using OrchardCore.DisplayManagement.Descriptors;
using OrchardCore.DisplayManagement.Handlers;
using OrchardCore.Environment.Shell.Builders;
using OrchardCore.Environment.Shell.Configuration;
using OrchardCore.Modules;
using OrchardCore.Mvc.Core.Utilities;
Expand Down Expand Up @@ -61,138 +60,96 @@ public override void ConfigureServices(IServiceCollection services)
var configuration = _shellConfiguration.GetSection(ConfigSectionName);
var elasticConfiguration = configuration.Get<ElasticConnectionOptions>();

if (CheckOptions(elasticConfiguration, _logger))
if (!CheckOptions(elasticConfiguration, _logger))
{
services.Configure<ElasticConnectionOptions>(o => o.ConfigurationExists = true);

IConnectionPool pool = null;
var uris = elasticConfiguration.Ports.Select(port => new Uri($"{elasticConfiguration.Url}:{port}")).Distinct();

switch (elasticConfiguration.ConnectionType)
{
case "SingleNodeConnectionPool":
pool = new SingleNodeConnectionPool(uris.First());
break;

case "CloudConnectionPool":
BasicAuthenticationCredentials credentials = null;

if (!string.IsNullOrWhiteSpace(elasticConfiguration.Username) && !string.IsNullOrWhiteSpace(elasticConfiguration.Password) && !string.IsNullOrWhiteSpace(elasticConfiguration.CloudId))
{
credentials = new BasicAuthenticationCredentials(elasticConfiguration.Username, elasticConfiguration.Password);
pool = new CloudConnectionPool(elasticConfiguration.CloudId, credentials);
}
break;

case "StaticConnectionPool":
pool = new StaticConnectionPool(uris);
break;

case "SniffingConnectionPool":
pool = new SniffingConnectionPool(uris);
break;

case "StickyConnectionPool":
pool = new StickyConnectionPool(uris);
break;
return;
}

default:
pool = new SingleNodeConnectionPool(uris.First());
break;
}
services.Configure<ElasticConnectionOptions>(o => o.ConfigurationExists = true);
var settings = GetConnectionSettings(elasticConfiguration);

var settings = new ConnectionSettings(pool).ThrowExceptions();
services.AddSingleton<IElasticClient>(new ElasticClient(settings));

if (elasticConfiguration.ConnectionType != "CloudConnectionPool" && !string.IsNullOrWhiteSpace(elasticConfiguration.Username) && !string.IsNullOrWhiteSpace(elasticConfiguration.Password))
{
settings.BasicAuthentication(elasticConfiguration.Username, elasticConfiguration.Password);
}
services.Configure<ElasticsearchOptions>(o =>
{
o.IndexPrefix = configuration.GetValue<string>(nameof(o.IndexPrefix));
if (!string.IsNullOrWhiteSpace(elasticConfiguration.CertificateFingerprint))
{
settings.CertificateFingerprint(elasticConfiguration.CertificateFingerprint);
}
var jsonNode = configuration.GetSection(nameof(o.Analyzers)).AsJsonNode();
var jsonElement = JsonSerializer.Deserialize<JsonElement>(jsonNode);
if (elasticConfiguration.EnableApiVersioningHeader)
var analyzersObject = JsonObject.Create(jsonElement, new JsonNodeOptions()
{
settings.EnableApiVersioningHeader();
}
PropertyNameCaseInsensitive = true,
});
var client = new ElasticClient(settings);
services.AddSingleton<IElasticClient>(client);
services.Configure<ElasticsearchOptions>(o =>
if (analyzersObject != null)
{
o.IndexPrefix = configuration.GetValue<string>(nameof(o.IndexPrefix));
var jsonNode = configuration.GetSection(nameof(o.Analyzers)).AsJsonNode();
var jsonElement = JsonSerializer.Deserialize<JsonElement>(jsonNode);
var analyzersObject = JsonObject.Create(jsonElement, new JsonNodeOptions()
foreach (var analyzer in analyzersObject)
{
PropertyNameCaseInsensitive = true,
});
if (analyzersObject != null)
{
foreach (var analyzer in analyzersObject)
if (analyzer.Value == null)
{
if (analyzer.Value == null)
{
continue;
}
o.Analyzers.Add(analyzer.Key, analyzer.Value.AsObject());
continue;
}
}
if (o.Analyzers.Count == 0)
{
// When no analyzers are configured, we'll define a default analyzer.
o.Analyzers.Add(ElasticsearchConstants.DefaultAnalyzer, new JsonObject
{
["type"] = "standard",
});
o.Analyzers.Add(analyzer.Key, analyzer.Value.AsObject());
}
});
}
try
if (o.Analyzers.Count == 0)
{
var response = client.Ping();

services.Configure<TemplateOptions>(o =>
// When no analyzers are configured, we'll define a default analyzer.
o.Analyzers.Add(ElasticsearchConstants.DefaultAnalyzer, new JsonObject
{
o.MemberAccessStrategy.Register<SearchIndexViewModel>();
o.MemberAccessStrategy.Register<SearchFormViewModel>();
o.MemberAccessStrategy.Register<SearchResultsViewModel>();
["type"] = "standard",
});

services.AddElasticServices();
services.AddScoped<IPermissionProvider, Permissions>();
services.AddScoped<INavigationProvider, AdminMenu>();
services.AddScoped<IDisplayDriver<ISite>, ElasticSettingsDisplayDriver>();
services.AddScoped<IDisplayDriver<Query>, ElasticQueryDisplayDriver>();
services.AddScoped<IContentTypePartDefinitionDisplayDriver, ContentTypePartIndexSettingsDisplayDriver>();
services.AddScoped<IContentPartFieldDefinitionDisplayDriver, ContentPartFieldIndexSettingsDisplayDriver>();
services.AddScoped<ElasticsearchService>();
services.AddScoped<ISearchService>(sp => sp.GetRequiredService<ElasticsearchService>());
services.AddScoped<IAuthorizationHandler, ElasticsearchAuthorizationHandler>();
}
catch (Exception ex)
{
_logger.LogError(ex, "Elasticsearch is enabled but not active because the connection failed.");
}
}
});

services.Configure<TemplateOptions>(o =>
{
o.MemberAccessStrategy.Register<SearchIndexViewModel>();
o.MemberAccessStrategy.Register<SearchFormViewModel>();
o.MemberAccessStrategy.Register<SearchResultsViewModel>();
});

services.AddElasticServices();
services.AddScoped<IPermissionProvider, Permissions>();
services.AddScoped<INavigationProvider, AdminMenu>();
services.AddScoped<IDisplayDriver<ISite>, ElasticSettingsDisplayDriver>();
services.AddScoped<IDisplayDriver<Query>, ElasticQueryDisplayDriver>();
services.AddScoped<IContentTypePartDefinitionDisplayDriver, ContentTypePartIndexSettingsDisplayDriver>();
services.AddScoped<IContentPartFieldDefinitionDisplayDriver, ContentPartFieldIndexSettingsDisplayDriver>();
services.AddScoped<ElasticsearchService>();
services.AddScoped<ISearchService>(sp => sp.GetRequiredService<ElasticsearchService>());
services.AddScoped<IAuthorizationHandler, ElasticsearchAuthorizationHandler>();
}

public override void Configure(IApplicationBuilder app, IEndpointRouteBuilder routes, IServiceProvider serviceProvider)
private static ConnectionSettings GetConnectionSettings(ElasticConnectionOptions elasticConfiguration)
{
var options = serviceProvider.GetRequiredService<IOptions<ElasticConnectionOptions>>().Value;
var pool = GetConnectionPool(elasticConfiguration);

var settings = new ConnectionSettings(pool);

if (!options.ConfigurationExists)
if (elasticConfiguration.ConnectionType != "CloudConnectionPool" && !string.IsNullOrWhiteSpace(elasticConfiguration.Username) && !string.IsNullOrWhiteSpace(elasticConfiguration.Password))
{
return;
settings.BasicAuthentication(elasticConfiguration.Username, elasticConfiguration.Password);
}

if (!string.IsNullOrWhiteSpace(elasticConfiguration.CertificateFingerprint))
{
settings.CertificateFingerprint(elasticConfiguration.CertificateFingerprint);
}

if (elasticConfiguration.EnableApiVersioningHeader)
{
settings.EnableApiVersioningHeader();
}

return settings;
}

public override void Configure(IApplicationBuilder app, IEndpointRouteBuilder routes, IServiceProvider serviceProvider)
{
var adminControllerName = typeof(AdminController).ControllerName();

routes.MapAreaControllerRoute(
Expand Down Expand Up @@ -240,14 +197,14 @@ public override void Configure(IApplicationBuilder app, IEndpointRouteBuilder ro

private static bool CheckOptions(ElasticConnectionOptions elasticConnectionOptions, ILogger logger)
{
var optionsAreValid = true;

if (elasticConnectionOptions == null)
{
logger.LogError("Elasticsearch is enabled but not active because the configuration is missing.");
return false;
}

var optionsAreValid = true;

if (string.IsNullOrWhiteSpace(elasticConnectionOptions.Url))
{
logger.LogError("Elasticsearch is enabled but not active because the 'Url' is missing or empty in application configuration.");
Expand All @@ -262,31 +219,66 @@ private static bool CheckOptions(ElasticConnectionOptions elasticConnectionOptio

return optionsAreValid;
}

private static IConnectionPool GetConnectionPool(ElasticConnectionOptions elasticConfiguration)
{
var uris = elasticConfiguration.Ports.Select(port => new Uri($"{elasticConfiguration.Url}:{port}")).Distinct();
IConnectionPool pool = null;
switch (elasticConfiguration.ConnectionType)
{
case "SingleNodeConnectionPool":
pool = new SingleNodeConnectionPool(uris.First());
break;

case "CloudConnectionPool":
if (!string.IsNullOrWhiteSpace(elasticConfiguration.Username) && !string.IsNullOrWhiteSpace(elasticConfiguration.Password) && !string.IsNullOrWhiteSpace(elasticConfiguration.CloudId))
{
var credentials = new BasicAuthenticationCredentials(elasticConfiguration.Username, elasticConfiguration.Password);
pool = new CloudConnectionPool(elasticConfiguration.CloudId, credentials);
}
break;

case "StaticConnectionPool":
pool = new StaticConnectionPool(uris);
break;

case "SniffingConnectionPool":
pool = new SniffingConnectionPool(uris);
break;

case "StickyConnectionPool":
pool = new StickyConnectionPool(uris);
break;

default:
pool = new SingleNodeConnectionPool(uris.First());
break;
}

return pool;
}
}

[RequireFeatures("OrchardCore.Deployment")]
public class DeploymentStartup : StartupBase
{
public override void ConfigureServices(IServiceCollection services)
{
if (services.Any(d => d.GetImplementationType() == typeof(ElasticsearchService)))
{
services.AddTransient<IDeploymentSource, ElasticIndexDeploymentSource>();
services.AddSingleton<IDeploymentStepFactory>(new DeploymentStepFactory<ElasticIndexDeploymentStep>());
services.AddScoped<IDisplayDriver<DeploymentStep>, ElasticIndexDeploymentStepDriver>();
services.AddTransient<IDeploymentSource, ElasticIndexDeploymentSource>();
services.AddSingleton<IDeploymentStepFactory>(new DeploymentStepFactory<ElasticIndexDeploymentStep>());
services.AddScoped<IDisplayDriver<DeploymentStep>, ElasticIndexDeploymentStepDriver>();

services.AddTransient<IDeploymentSource, ElasticSettingsDeploymentSource>();
services.AddSingleton<IDeploymentStepFactory>(new DeploymentStepFactory<ElasticSettingsDeploymentStep>());
services.AddScoped<IDisplayDriver<DeploymentStep>, ElasticSettingsDeploymentStepDriver>();
services.AddTransient<IDeploymentSource, ElasticSettingsDeploymentSource>();
services.AddSingleton<IDeploymentStepFactory>(new DeploymentStepFactory<ElasticSettingsDeploymentStep>());
services.AddScoped<IDisplayDriver<DeploymentStep>, ElasticSettingsDeploymentStepDriver>();

services.AddTransient<IDeploymentSource, ElasticIndexRebuildDeploymentSource>();
services.AddSingleton<IDeploymentStepFactory>(new DeploymentStepFactory<ElasticIndexRebuildDeploymentStep>());
services.AddScoped<IDisplayDriver<DeploymentStep>, ElasticIndexRebuildDeploymentStepDriver>();
services.AddTransient<IDeploymentSource, ElasticIndexRebuildDeploymentSource>();
services.AddSingleton<IDeploymentStepFactory>(new DeploymentStepFactory<ElasticIndexRebuildDeploymentStep>());
services.AddScoped<IDisplayDriver<DeploymentStep>, ElasticIndexRebuildDeploymentStepDriver>();

services.AddTransient<IDeploymentSource, ElasticIndexResetDeploymentSource>();
services.AddSingleton<IDeploymentStepFactory>(new DeploymentStepFactory<ElasticIndexResetDeploymentStep>());
services.AddScoped<IDisplayDriver<DeploymentStep>, ElasticIndexResetDeploymentStepDriver>();
}
services.AddTransient<IDeploymentSource, ElasticIndexResetDeploymentSource>();
services.AddSingleton<IDeploymentStepFactory>(new DeploymentStepFactory<ElasticIndexResetDeploymentStep>());
services.AddScoped<IDisplayDriver<DeploymentStep>, ElasticIndexResetDeploymentStepDriver>();
}
}

Expand All @@ -295,10 +287,7 @@ public class ElasticWorkerStartup : StartupBase
{
public override void ConfigureServices(IServiceCollection services)
{
if (services.Any(d => d.GetImplementationType() == typeof(ElasticsearchService)))
{
services.AddSingleton<IBackgroundTask, IndexingBackgroundTask>();
}
services.AddSingleton<IBackgroundTask, IndexingBackgroundTask>();
}
}

Expand All @@ -307,12 +296,9 @@ public class ElasticContentPickerStartup : StartupBase
{
public override void ConfigureServices(IServiceCollection services)
{
if (services.Any(d => d.GetImplementationType() == typeof(ElasticsearchService)))
{
services.AddScoped<IContentPickerResultProvider, ElasticContentPickerResultProvider>();
services.AddScoped<IContentPartFieldDefinitionDisplayDriver, ContentPickerFieldElasticEditorSettingsDriver>();
services.AddShapeAttributes<ElasticContentPickerShapeProvider>();
}
services.AddScoped<IContentPickerResultProvider, ElasticContentPickerResultProvider>();
services.AddScoped<IContentPartFieldDefinitionDisplayDriver, ContentPickerFieldElasticEditorSettingsDriver>();
services.AddShapeAttributes<ElasticContentPickerShapeProvider>();
}
}
}

0 comments on commit 5815690

Please sign in to comment.