Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Eliminate the anti-discovery pattern in Elasticsearch (#15134)
Browse files Browse the repository at this point in the history
MikeAlhayek authored and hishamco committed Feb 1, 2024
1 parent 1bef5b7 commit 9750198
Showing 12 changed files with 302 additions and 136 deletions.
Original file line number Diff line number Diff line change
@@ -50,6 +50,7 @@ public class AdminController : Controller
private readonly INotifier _notifier;
private readonly ILogger _logger;
private readonly IOptions<TemplateOptions> _templateOptions;
private readonly ElasticConnectionOptions _elasticConnectionOptions;
private readonly IShapeFactory _shapeFactory;
private readonly ILocalizationService _localizationService;

@@ -71,6 +72,7 @@ public AdminController(
INotifier notifier,
ILogger<AdminController> logger,
IOptions<TemplateOptions> templateOptions,
IOptions<ElasticConnectionOptions> elasticConnectionOptions,
IShapeFactory shapeFactory,
ILocalizationService localizationService,
IStringLocalizer<AdminController> stringLocalizer,
@@ -90,6 +92,7 @@ public AdminController(
_notifier = notifier;
_logger = logger;
_templateOptions = templateOptions;
_elasticConnectionOptions = elasticConnectionOptions.Value;
_shapeFactory = shapeFactory;
_localizationService = localizationService;
S = stringLocalizer;
@@ -103,6 +106,11 @@ public async Task<IActionResult> Index(ContentOptions options, PagerParameters p
return Forbid();
}

if (!_elasticConnectionOptions.IsFileConfigurationExists())
{
return NotConfigured();
}

var indexes = (await _elasticIndexSettingsService.GetSettingsAsync())
.Select(i => new IndexViewModel { Name = i.IndexName })
.ToList();
@@ -150,13 +158,13 @@ public async Task<IActionResult> Index(ContentOptions options, PagerParameters p

[HttpPost, ActionName(nameof(Index))]
[FormValueRequired("submit.Filter")]
public ActionResult IndexFilterPOST(AdminIndexViewModel model)
public IActionResult IndexFilterPOST(AdminIndexViewModel model)
=> RedirectToAction(nameof(Index), new RouteValueDictionary
{
{ _optionsSearch, model.Options.Search }
});

public async Task<ActionResult> Edit(string indexName = null)
public async Task<IActionResult> Edit(string indexName = null)
{
var IsCreate = string.IsNullOrWhiteSpace(indexName);
var settings = new ElasticIndexSettings();
@@ -166,6 +174,11 @@ public async Task<ActionResult> Edit(string indexName = null)
return Forbid();
}

if (!_elasticConnectionOptions.IsFileConfigurationExists())
{
return NotConfigured();
}

if (!IsCreate)
{
settings = await _elasticIndexSettingsService.GetSettingsAsync(indexName);
@@ -200,6 +213,11 @@ public async Task<ActionResult> EditPost(ElasticIndexSettingsViewModel model, st
return Forbid();
}

if (!_elasticConnectionOptions.IsFileConfigurationExists())
{
return BadRequest();
}

ValidateModel(model);

if (model.IsCreate)
@@ -295,6 +313,11 @@ public async Task<ActionResult> Reset(string id)
return Forbid();
}

if (!_elasticConnectionOptions.IsFileConfigurationExists())
{
return BadRequest();
}

if (!await _elasticIndexManager.ExistsAsync(id))
{
return NotFound();
@@ -316,6 +339,11 @@ public async Task<ActionResult> Rebuild(string id)
return Forbid();
}

if (!_elasticConnectionOptions.IsFileConfigurationExists())
{
return BadRequest();
}

if (!await _elasticIndexManager.ExistsAsync(id))
{
return NotFound();
@@ -349,6 +377,11 @@ public async Task<ActionResult> Delete(ElasticIndexSettingsViewModel model)
return Forbid();
}

if (!_elasticConnectionOptions.IsFileConfigurationExists())
{
return BadRequest();
}

if (!await _elasticIndexManager.ExistsAsync(model.IndexName))
{
await _notifier.SuccessAsync(H["Index not found on Elasticsearch server.", model.IndexName]);
@@ -378,6 +411,11 @@ public async Task<ActionResult> ForceDelete(ElasticIndexSettingsViewModel model)
return Forbid();
}

if (!_elasticConnectionOptions.IsFileConfigurationExists())
{
return BadRequest();
}

try
{
await _elasticIndexingService.DeleteIndexAsync(model.IndexName);
@@ -416,12 +454,19 @@ public async Task<IActionResult> SyncSettings()
return RedirectToAction(nameof(Index));
}

public Task<IActionResult> Query(string indexName, string query)
=> Query(new AdminQueryViewModel
public async Task<IActionResult> Query(string indexName, string query)
{
if (!_elasticConnectionOptions.IsFileConfigurationExists())
{
return NotConfigured();
}

return await Query(new AdminQueryViewModel
{
IndexName = indexName,
DecodedQuery = string.IsNullOrWhiteSpace(query) ? string.Empty : System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(query))
});
}

[HttpPost]
public async Task<IActionResult> Query(AdminQueryViewModel model)
@@ -431,6 +476,11 @@ public async Task<IActionResult> Query(AdminQueryViewModel model)
return Forbid();
}

if (!_elasticConnectionOptions.IsFileConfigurationExists())
{
return BadRequest();
}

model.Indices = (await _elasticIndexSettingsService.GetSettingsAsync()).Select(x => x.IndexName).ToArray();

// Can't query if there are no indices.
@@ -496,6 +546,11 @@ public async Task<ActionResult> IndexPost(ContentOptions options, IEnumerable<st
return Forbid();
}

if (!_elasticConnectionOptions.IsFileConfigurationExists())
{
return BadRequest();
}

if (itemIds?.Count() > 0)
{
var elasticIndexSettings = await _elasticIndexSettingsService.GetSettingsAsync();
@@ -540,7 +595,7 @@ public async Task<ActionResult> IndexPost(ContentOptions options, IEnumerable<st
}
break;
default:
throw new ArgumentOutOfRangeException(nameof(options.BulkAction), "Unknown bulk action");
return BadRequest();
}
}

@@ -577,5 +632,8 @@ private async Task PopulateMenuOptionsAsync(ElasticIndexSettingsViewModel model)
model.Analyzers = _elasticSearchOptions.Analyzers
.Select(x => new SelectListItem { Text = x.Key, Value = x.Key });
}

private IActionResult NotConfigured()
=> View("NotConfigured");
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using OrchardCore.ContentManagement.Metadata.Models;
@@ -22,7 +21,7 @@ public override IDisplayResult Edit(ContentPartFieldDefinition partFieldDefiniti
{
return Initialize<ContentPickerFieldElasticEditorSettings>("ContentPickerFieldElasticEditorSettings_Edit", async model =>
{
partFieldDefinition.PopulateSettings<ContentPickerFieldElasticEditorSettings>(model);
partFieldDefinition.PopulateSettings(model);
model.Indices = (await _elasticIndexSettingsService.GetSettingsAsync()).Select(x => x.IndexName).ToArray();
}).Location("Editor");
}
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Options;
using Nest;
using OrchardCore.DisplayManagement.Entities;
using OrchardCore.DisplayManagement.Handlers;
@@ -30,20 +31,24 @@ public class ElasticSettingsDisplayDriver : SectionDisplayDriver<ISite, ElasticS
private readonly ElasticIndexSettingsService _elasticIndexSettingsService;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IAuthorizationService _authorizationService;
private readonly ElasticConnectionOptions _elasticConnectionOptions;
private readonly IElasticClient _elasticClient;

protected readonly IStringLocalizer S;

public ElasticSettingsDisplayDriver(
ElasticIndexSettingsService elasticIndexSettingsService,
IHttpContextAccessor httpContextAccessor,
IAuthorizationService authorizationService,
IOptions<ElasticConnectionOptions> elasticConnectionOptions,
IElasticClient elasticClient,
IStringLocalizer<ElasticSettingsDisplayDriver> stringLocalizer
)
{
_elasticIndexSettingsService = elasticIndexSettingsService;
_httpContextAccessor = httpContextAccessor;
_authorizationService = authorizationService;
_elasticConnectionOptions = elasticConnectionOptions.Value;
_elasticClient = elasticClient;
S = stringLocalizer;
}
@@ -72,6 +77,11 @@ public override async Task<IDisplayResult> UpdateAsync(ElasticSettings section,
return null;
}

if (!_elasticConnectionOptions.IsFileConfigurationExists())
{
return null;
}

if (!await _authorizationService.AuthorizeAsync(_httpContextAccessor.HttpContext?.User, Permissions.ManageElasticIndexes))
{
return null;
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@
using System.Threading.Tasks;
using Fluid.Values;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Nest;
using OrchardCore.Liquid;
using OrchardCore.Search.Abstractions;
@@ -25,6 +26,7 @@ public class ElasticsearchService : ISearchService
private readonly IElasticSearchQueryService _elasticsearchQueryService;
private readonly IElasticClient _elasticClient;
private readonly JavaScriptEncoder _javaScriptEncoder;
private readonly ElasticConnectionOptions _elasticConnectionOptions;
private readonly ILiquidTemplateManager _liquidTemplateManager;
private readonly ILogger _logger;

@@ -35,6 +37,7 @@ public ElasticsearchService(
IElasticSearchQueryService elasticsearchQueryService,
IElasticClient elasticClient,
JavaScriptEncoder javaScriptEncoder,
IOptions<ElasticConnectionOptions> elasticConnectionOptions,
ILiquidTemplateManager liquidTemplateManager,
ILogger<ElasticsearchService> logger
)
@@ -45,6 +48,7 @@ ILogger<ElasticsearchService> logger
_elasticsearchQueryService = elasticsearchQueryService;
_elasticClient = elasticClient;
_javaScriptEncoder = javaScriptEncoder;
_elasticConnectionOptions = elasticConnectionOptions.Value;
_liquidTemplateManager = liquidTemplateManager;
_logger = logger;
}
@@ -53,13 +57,20 @@ ILogger<ElasticsearchService> logger

public async Task<SearchResult> SearchAsync(string indexName, string term, int start, int pageSize)
{
var result = new SearchResult();

if (!_elasticConnectionOptions.IsFileConfigurationExists())
{
_logger.LogWarning("Elasticsearch: Couldn't execute search. The Elasticsearch has yet been configured.");

return result;
}

var siteSettings = await _siteService.GetSiteSettingsAsync();
var searchSettings = siteSettings.As<ElasticSettings>();

var index = !string.IsNullOrWhiteSpace(indexName) ? indexName.Trim() : searchSettings.SearchIndex;

var result = new SearchResult();

if (index == null || !await _elasticIndexManager.ExistsAsync(index))
{
_logger.LogWarning("Elasticsearch: Couldn't execute search. The search index doesn't exist.");
106 changes: 7 additions & 99 deletions src/OrchardCore.Modules/OrchardCore.Search.Elasticsearch/Startup.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
using System;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Nodes;
using Elasticsearch.Net;
using GraphQL;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
@@ -39,7 +37,6 @@ namespace OrchardCore.Search.Elasticsearch
{
public class Startup : StartupBase
{
private const string ConfigSectionName = "OrchardCore_Elasticsearch";
private readonly AdminOptions _adminOptions;
private readonly IShellConfiguration _shellConfiguration;
private readonly ILogger<Startup> _logger;
@@ -55,21 +52,19 @@ public Startup(IOptions<AdminOptions> adminOptions,

public override void ConfigureServices(IServiceCollection services)
{
var configuration = _shellConfiguration.GetSection(ConfigSectionName);
var elasticConfiguration = configuration.Get<ElasticConnectionOptions>();
services.AddTransient<IConfigureOptions<ElasticConnectionOptions>, ElasticConnectionOptionsConfigurations>();

if (!CheckOptions(elasticConfiguration, _logger))
services.AddSingleton<IElasticClient>((sp) =>
{
return;
}
var options = sp.GetRequiredService<IOptions<ElasticConnectionOptions>>().Value;

services.Configure<ElasticConnectionOptions>(o => o.ConfigurationExists = true);
var settings = GetConnectionSettings(elasticConfiguration);

services.AddSingleton<IElasticClient>(new ElasticClient(settings));
return new ElasticClient(options.GetConnectionSettings() ?? new ConnectionSettings());
});

services.Configure<ElasticsearchOptions>(o =>
{
var configuration = _shellConfiguration.GetSection(ElasticConnectionOptionsConfigurations.ConfigSectionName);

o.IndexPrefix = configuration.GetValue<string>(nameof(o.IndexPrefix));

var jsonNode = configuration.GetSection(nameof(o.Analyzers)).AsJsonNode();
@@ -109,30 +104,6 @@ public override void ConfigureServices(IServiceCollection services)
services.AddScoped<IDisplayDriver<Query>, ElasticQueryDisplayDriver>();
}

private static ConnectionSettings GetConnectionSettings(ElasticConnectionOptions elasticConfiguration)
{
var pool = GetConnectionPool(elasticConfiguration);

var settings = new ConnectionSettings(pool);

if (elasticConfiguration.ConnectionType != "CloudConnectionPool" && !string.IsNullOrWhiteSpace(elasticConfiguration.Username) && !string.IsNullOrWhiteSpace(elasticConfiguration.Password))
{
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();
@@ -179,69 +150,6 @@ public override void Configure(IApplicationBuilder app, IEndpointRouteBuilder ro
defaults: new { controller = adminControllerName, action = nameof(AdminController.SyncSettings) }
);
}

private static bool CheckOptions(ElasticConnectionOptions elasticConnectionOptions, ILogger logger)
{
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.");
optionsAreValid = false;
}

if (elasticConnectionOptions.Ports?.Length == 0)
{
logger.LogError("Elasticsearch is enabled but not active because a port is missing in application configuration.");
optionsAreValid = false;
}

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.Search")]
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div class="alert alert-danger" role="alert">
@T["Elasticsearch has not been configured yet."]
</div>
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
@using Microsoft.Extensions.Options
@using OrchardCore.Contents.Indexing
@using OrchardCore.Search.Elasticsearch.Core.Models

@model ElasticSettingsViewModel
@inject IOptions<ElasticConnectionOptions> ElasticConnectionOptions

@if (!ElasticConnectionOptions.Value.IsFileConfigurationExists())
{
<div class="alert alert-danger" role="alert">
@T["Elasticsearch is not configured. Update the appsettings file with Azure Search AI service information."]
</div>

return;
}

@if (!Model.SearchIndexes.Any())
{
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using Nest;

namespace OrchardCore.Search.Elasticsearch.Core.Models
{
public class ElasticConnectionOptions
@@ -38,13 +40,27 @@ public class ElasticConnectionOptions
public string CertificateFingerprint { get; set; }

/// <summary>
/// Enables compatibility mode for Elasticsearch 8.x
/// Enables compatibility mode for Elasticsearch 8.x.
/// </summary>
public bool EnableApiVersioningHeader { get; set; } = false;

/// <summary>
/// Whether the configuration section exists.
/// </summary>
public bool ConfigurationExists { get; set; }
private bool _fileConfigurationExists { get; set; }

private IConnectionSettingsValues _conntectionSettings;

public void SetFileConfigurationExists(bool fileConfigurationExists)
=> _fileConfigurationExists = fileConfigurationExists;

public bool IsFileConfigurationExists()
=> _fileConfigurationExists;

public void SetConnectionSettings(IConnectionSettingsValues settings)
=> _conntectionSettings = settings;

public IConnectionSettingsValues GetConnectionSettings()
=> _conntectionSettings;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
using Nest;
using OrchardCore.ContentManagement;
using OrchardCore.Environment.Shell;
@@ -13,19 +14,27 @@ public class ElasticContentPickerResultProvider : IContentPickerResultProvider
{
private readonly ElasticIndexManager _elasticIndexManager;
private readonly string _indexPrefix;
private readonly ElasticConnectionOptions _elasticConnectionOptions;

public ElasticContentPickerResultProvider(
ShellSettings shellSettings,
IOptions<ElasticConnectionOptions> elasticConnectionOptions,
ElasticIndexManager elasticIndexManager)
{
_indexPrefix = shellSettings.Name.ToLowerInvariant() + "_";
_elasticConnectionOptions = elasticConnectionOptions.Value;
_elasticIndexManager = elasticIndexManager;
}

public string Name => "Elasticsearch";

public async Task<IEnumerable<ContentPickerResult>> Search(ContentPickerSearchContext searchContext)
{
if (!_elasticConnectionOptions.IsFileConfigurationExists())
{
return Enumerable.Empty<ContentPickerResult>();
}

string indexName = null;

var fieldSettings = searchContext.PartFieldDefinition?.GetSettings<ContentPickerFieldElasticEditorSettings>();
@@ -37,7 +46,7 @@ public async Task<IEnumerable<ContentPickerResult>> Search(ContentPickerSearchCo

if (indexName != null && !await _elasticIndexManager.ExistsAsync(indexName))
{
return new List<ContentPickerResult>();
return Enumerable.Empty<ContentPickerResult>();
}

var results = new List<ContentPickerResult>();
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
using System;
using System.Linq;
using Elasticsearch.Net;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Nest;
using OrchardCore.Environment.Shell.Configuration;
using OrchardCore.Search.Elasticsearch.Core.Models;

namespace OrchardCore.Search.Elasticsearch.Core.Services;

public class ElasticConnectionOptionsConfigurations : IConfigureOptions<ElasticConnectionOptions>
{
public const string ConfigSectionName = "OrchardCore_Elasticsearch";

private readonly IShellConfiguration _shellConfiguration;
private readonly ILogger _logger;

public ElasticConnectionOptionsConfigurations(
IShellConfiguration shellConfiguration,
ILogger<ElasticConnectionOptionsConfigurations> logger)
{
_shellConfiguration = shellConfiguration;
_logger = logger;
}

public void Configure(ElasticConnectionOptions options)
{
var fileOptions = _shellConfiguration.GetSection(ConfigSectionName).Get<ElasticConnectionOptions>()
?? new ElasticConnectionOptions();

options.Url = fileOptions.Url;
options.Ports = fileOptions.Ports;
options.ConnectionType = fileOptions.ConnectionType;
options.CloudId = fileOptions.CloudId;
options.Username = fileOptions.Username;
options.Password = fileOptions.Password;
options.CertificateFingerprint = fileOptions.CertificateFingerprint;
options.EnableApiVersioningHeader = fileOptions.EnableApiVersioningHeader;

if (HasConnectionInfo(options))
{
options.SetFileConfigurationExists(true);
options.SetConnectionSettings(GetConnectionSettings(options));
}
}

private bool HasConnectionInfo(ElasticConnectionOptions elasticConnectionOptions)
{
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.");
optionsAreValid = false;
}

if (elasticConnectionOptions.Ports?.Length == 0)
{
_logger.LogError("Elasticsearch is enabled but not active because a port is missing in application configuration.");
optionsAreValid = false;
}

return optionsAreValid;
}

private static ConnectionSettings GetConnectionSettings(ElasticConnectionOptions elasticConfiguration)
{
var pool = GetConnectionPool(elasticConfiguration);

var settings = new ConnectionSettings(pool);

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

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

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

return settings;
}

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;
}
}
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json.Linq;
using OrchardCore.ContentLocalization;
using OrchardCore.ContentManagement;
@@ -29,6 +30,7 @@ public class ElasticIndexingService
private readonly ElasticIndexSettingsService _elasticIndexSettingsService;
private readonly ElasticIndexManager _indexManager;
private readonly IIndexingTaskManager _indexingTaskManager;
private readonly ElasticConnectionOptions _elasticConnectionOptions;
private readonly ISiteService _siteService;
private readonly IContentDefinitionManager _contentDefinitionManager;
private readonly ILogger _logger;
@@ -39,6 +41,7 @@ public ElasticIndexingService(
ElasticIndexSettingsService elasticIndexSettingsService,
ElasticIndexManager indexManager,
IIndexingTaskManager indexingTaskManager,
IOptions<ElasticConnectionOptions> elasticConnectionOptions,
ISiteService siteService,
IContentDefinitionManager contentDefinitionManager,
ILogger<ElasticIndexingService> logger)
@@ -48,13 +51,19 @@ public ElasticIndexingService(
_elasticIndexSettingsService = elasticIndexSettingsService;
_indexManager = indexManager;
_indexingTaskManager = indexingTaskManager;
_elasticConnectionOptions = elasticConnectionOptions.Value;
_siteService = siteService;
_contentDefinitionManager = contentDefinitionManager;
_logger = logger;
}

public async Task ProcessContentItemsAsync(string indexName = default)
{
if (!_elasticConnectionOptions.IsFileConfigurationExists())
{
return;
}

var allIndices = new Dictionary<string, long>();
var lastTaskId = long.MaxValue;
IEnumerable<ElasticIndexSettings> indexSettingsList = null;
Original file line number Diff line number Diff line change
@@ -4,34 +4,31 @@
using Microsoft.Extensions.DependencyInjection;
using OrchardCore.BackgroundTasks;

namespace OrchardCore.Search.Elasticsearch.Core.Services
namespace OrchardCore.Search.Elasticsearch.Core.Services;

/// <summary>
/// This background task will index content items using Elasticsearch.
/// </summary>
/// <remarks>
/// This services is only registered from OrchardCore.Search.Elasticsearch.Worker feature.
/// </remarks>
[BackgroundTask(
Title = "Elasticsearch Indexes Updater",
Schedule = "* * * * *",
Description = "Updates Elasticsearch indexes.",
LockTimeout = 1000,
LockExpiration = 300000)]
public class IndexingBackgroundTask : IBackgroundTask
{
/// <summary>
/// This background task will index content items using Elasticsearch.
/// </summary>
/// <remarks>
/// This services is only registered from OrchardCore.Search.Elasticsearch.Worker feature.
/// </remarks>
[BackgroundTask(
Title = "Elasticsearch Indexes Updater",
Schedule = "* * * * *",
Description = "Updates Elasticsearch indexes.",
LockTimeout = 1000,
LockExpiration = 300000)]
public class IndexingBackgroundTask : IBackgroundTask
public Task DoWorkAsync(IServiceProvider serviceProvider, CancellationToken cancellationToken)
{
public Task DoWorkAsync(IServiceProvider serviceProvider, CancellationToken cancellationToken)
{
var indexingService = serviceProvider.GetService<ElasticIndexingService>();
var indexingService = serviceProvider.GetService<ElasticIndexingService>();

if (indexingService != null)
{
return indexingService.ProcessContentItemsAsync();
}
else
{
return Task.CompletedTask;
}
if (indexingService != null)
{
return indexingService.ProcessContentItemsAsync();
}

return Task.CompletedTask;
}
}

0 comments on commit 9750198

Please sign in to comment.