From 20ad639fec0e0e7ee826096c19e189ed1f64e6b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96hlund?= Date: Wed, 26 Feb 2025 12:57:08 +0100 Subject: [PATCH 1/6] Allow RavenDB search engine type to be configured --- .../DatabaseConfiguration.cs | 7 +++- .../DatabaseSetup.cs | 38 ++++++++++++++++--- .../RavenPersistenceConfiguration.cs | 29 ++++++-------- .../PersistenceTestsConfiguration.cs | 18 +++++++-- .../SharedEmbeddedServer.cs | 2 +- .../DatabaseSetup.cs | 8 ++-- .../RavenPersisterSettings.cs | 1 + 7 files changed, 70 insertions(+), 33 deletions(-) diff --git a/src/ServiceControl.Audit.Persistence.RavenDB/DatabaseConfiguration.cs b/src/ServiceControl.Audit.Persistence.RavenDB/DatabaseConfiguration.cs index 05f9258a31..5fb7c290e5 100644 --- a/src/ServiceControl.Audit.Persistence.RavenDB/DatabaseConfiguration.cs +++ b/src/ServiceControl.Audit.Persistence.RavenDB/DatabaseConfiguration.cs @@ -12,7 +12,8 @@ public class DatabaseConfiguration( int dataSpaceRemainingThreshold, int minimumStorageLeftRequiredForIngestion, ServerConfiguration serverConfiguration, - TimeSpan bulkInsertCommitTimeout) + TimeSpan bulkInsertCommitTimeout, + string searchEngineType) { public string Name { get; } = name; @@ -33,5 +34,7 @@ public class DatabaseConfiguration( public int MinimumStorageLeftRequiredForIngestion { get; internal set; } = minimumStorageLeftRequiredForIngestion; //Setting for ATT only public TimeSpan BulkInsertCommitTimeout { get; } = bulkInsertCommitTimeout; + + public string SearchEngineType { get; } = searchEngineType; } -} +} \ No newline at end of file diff --git a/src/ServiceControl.Audit.Persistence.RavenDB/DatabaseSetup.cs b/src/ServiceControl.Audit.Persistence.RavenDB/DatabaseSetup.cs index cb31bf977a..01e7313f1b 100644 --- a/src/ServiceControl.Audit.Persistence.RavenDB/DatabaseSetup.cs +++ b/src/ServiceControl.Audit.Persistence.RavenDB/DatabaseSetup.cs @@ -36,8 +36,8 @@ async Task CreateDatabase(IDocumentStore documentStore, string databaseName, Can try { var databaseRecord = new DatabaseRecord(databaseName); - databaseRecord.Settings.Add("Indexing.Auto.SearchEngineType", "Corax"); - databaseRecord.Settings.Add("Indexing.Static.SearchEngineType", "Corax"); + databaseRecord.Settings.Add("Indexing.Auto.SearchEngineType", configuration.SearchEngineType); + databaseRecord.Settings.Add("Indexing.Static.SearchEngineType", configuration.SearchEngineType); await documentStore.Maintenance.Server.SendAsync(new CreateDatabaseOperation(databaseRecord), cancellationToken); } @@ -59,8 +59,33 @@ async Task UpdateDatabaseSettings(IDocumentStore documentStore, string databaseN var updated = false; - updated |= dbRecord.Settings.TryAdd("Indexing.Auto.SearchEngineType", "Corax"); - updated |= dbRecord.Settings.TryAdd("Indexing.Static.SearchEngineType", "Corax"); + if (dbRecord.Settings.TryGetValue(AutoSearchEngineTypeKey, out var searchEngineTypeAuto)) + { + if (searchEngineTypeAuto != configuration.SearchEngineType) + { + updated = true; + } + } + else + { + updated = true; + } + + dbRecord.Settings[AutoSearchEngineTypeKey] = configuration.SearchEngineType; + + if (dbRecord.Settings.TryGetValue(StaticSearchEngineTypeKey, out var searchEngineTypeStatic)) + { + if (searchEngineTypeStatic != configuration.SearchEngineType) + { + updated = true; + } + } + else + { + updated = true; + } + + dbRecord.Settings[StaticSearchEngineTypeKey] = configuration.SearchEngineType; if (updated) { @@ -116,5 +141,8 @@ async Task ConfigureExpiration(IDocumentStore documentStore, CancellationToken c await documentStore.Maintenance.SendAsync(new ConfigureExpirationOperation(expirationConfig), cancellationToken); } + + const string AutoSearchEngineTypeKey = "Indexing.Auto.SearchEngineType"; + const string StaticSearchEngineTypeKey = "Indexing.Static.SearchEngineType"; } -} +} \ No newline at end of file diff --git a/src/ServiceControl.Audit.Persistence.RavenDB/RavenPersistenceConfiguration.cs b/src/ServiceControl.Audit.Persistence.RavenDB/RavenPersistenceConfiguration.cs index b22003ceae..a6495069b2 100644 --- a/src/ServiceControl.Audit.Persistence.RavenDB/RavenPersistenceConfiguration.cs +++ b/src/ServiceControl.Audit.Persistence.RavenDB/RavenPersistenceConfiguration.cs @@ -22,22 +22,9 @@ public class RavenPersistenceConfiguration : IPersistenceConfiguration public const string MinimumStorageLeftRequiredForIngestionKey = "MinimumStorageLeftRequiredForIngestion"; public const string BulkInsertCommitTimeoutInSecondsKey = "BulkInsertCommitTimeoutInSeconds"; public const string DataSpaceRemainingThresholdKey = "DataSpaceRemainingThreshold"; + public const string SearchEngineTypeKey = "SearchEngineType"; - public IEnumerable ConfigurationKeys => new[]{ - DatabaseNameKey, - DatabasePathKey, - ConnectionStringKey, - ClientCertificatePathKey, - ClientCertificateBase64Key, - ClientCertificatePasswordKey, - DatabaseMaintenancePortKey, - ExpirationProcessTimerInSecondsKey, - LogPathKey, - RavenDbLogLevelKey, - DataSpaceRemainingThresholdKey, - MinimumStorageLeftRequiredForIngestionKey, - BulkInsertCommitTimeoutInSecondsKey - }; + public IEnumerable ConfigurationKeys => new[] { DatabaseNameKey, DatabasePathKey, ConnectionStringKey, ClientCertificatePathKey, ClientCertificateBase64Key, ClientCertificatePasswordKey, DatabaseMaintenancePortKey, ExpirationProcessTimerInSecondsKey, LogPathKey, RavenDbLogLevelKey, DataSpaceRemainingThresholdKey, MinimumStorageLeftRequiredForIngestionKey, BulkInsertCommitTimeoutInSecondsKey, SearchEngineTypeKey }; public string Name => "RavenDB"; @@ -70,10 +57,12 @@ internal static DatabaseConfiguration GetDatabaseConfiguration(PersistenceSettin { serverConfiguration.ClientCertificatePath = clientCertificatePath; } + if (settings.PersisterSpecificSettings.TryGetValue(ClientCertificateBase64Key, out var clientCertificateBase64)) { serverConfiguration.ClientCertificateBase64 = clientCertificateBase64; } + if (settings.PersisterSpecificSettings.TryGetValue(ClientCertificatePasswordKey, out var clientCertificatePassword)) { serverConfiguration.ClientCertificatePassword = clientCertificatePassword; @@ -120,6 +109,11 @@ internal static DatabaseConfiguration GetDatabaseConfiguration(PersistenceSettin var bulkInsertTimeout = TimeSpan.FromSeconds(GetBulkInsertCommitTimeout(settings)); + if (!settings.PersisterSpecificSettings.TryGetValue(SearchEngineTypeKey, out var searchEngineType)) + { + searchEngineType = "Corax"; + } + return new DatabaseConfiguration( databaseName, expirationProcessTimerInSeconds, @@ -129,7 +123,8 @@ internal static DatabaseConfiguration GetDatabaseConfiguration(PersistenceSettin dataSpaceRemainingThreshold, minimumStorageLeftRequiredForIngestion, serverConfiguration, - bulkInsertTimeout); + bulkInsertTimeout, + searchEngineType); } static int GetExpirationProcessTimerInSeconds(PersistenceSettings settings) @@ -198,4 +193,4 @@ static string GetLogPath(PersistenceSettings settings) const int ExpirationProcessTimerInSecondsDefault = 600; const int BulkInsertCommitTimeoutInSecondsDefault = 60; } -} +} \ No newline at end of file diff --git a/src/ServiceControl.Audit.Persistence.Tests.RavenDB/PersistenceTestsConfiguration.cs b/src/ServiceControl.Audit.Persistence.Tests.RavenDB/PersistenceTestsConfiguration.cs index 05a121cd16..a4c3b577df 100644 --- a/src/ServiceControl.Audit.Persistence.Tests.RavenDB/PersistenceTestsConfiguration.cs +++ b/src/ServiceControl.Audit.Persistence.Tests.RavenDB/PersistenceTestsConfiguration.cs @@ -84,7 +84,10 @@ public async Task Configure(Action setSettings) var documentStoreProvider = host.Services.GetRequiredService(); DocumentStore = await documentStoreProvider.GetDocumentStore(); var bulkInsert = DocumentStore.BulkInsert( - options: new BulkInsertOptions { SkipOverwriteIfUnchanged = true, }); + options: new BulkInsertOptions + { + SkipOverwriteIfUnchanged = true, + }); var sessionProvider = host.Services.GetRequiredService(); @@ -103,11 +106,18 @@ public async Task Cleanup() if (DocumentStore != null) { await DocumentStore.Maintenance.Server.SendAsync(new DeleteDatabasesOperation( - new DeleteDatabasesOperation.Parameters { DatabaseNames = [databaseName], HardDelete = true })); + new DeleteDatabasesOperation.Parameters + { + DatabaseNames = [databaseName], + HardDelete = true + })); } - await host.StopAsync(); - host.Dispose(); + if (host != null) + { + await host.StopAsync(); + host.Dispose(); + } } diff --git a/src/ServiceControl.Audit.Persistence.Tests.RavenDB/SharedEmbeddedServer.cs b/src/ServiceControl.Audit.Persistence.Tests.RavenDB/SharedEmbeddedServer.cs index e5a9aa9639..930aaf818e 100644 --- a/src/ServiceControl.Audit.Persistence.Tests.RavenDB/SharedEmbeddedServer.cs +++ b/src/ServiceControl.Audit.Persistence.Tests.RavenDB/SharedEmbeddedServer.cs @@ -36,7 +36,7 @@ public static async Task GetInstance(CancellationToken cancell var logsMode = "Operations"; var serverUrl = $"http://localhost:{PortUtility.FindAvailablePort(33334)}"; - var databaseConfiguration = new DatabaseConfiguration("audit", 60, true, TimeSpan.FromMinutes(5), 120000, 5, 5, new ServerConfiguration(dbPath, serverUrl, logPath, logsMode), TimeSpan.FromSeconds(60)); + var databaseConfiguration = new DatabaseConfiguration("audit", 60, true, TimeSpan.FromMinutes(5), 120000, 5, 5, new ServerConfiguration(dbPath, serverUrl, logPath, logsMode), TimeSpan.FromSeconds(60), "Lucene"); var serverConfig = databaseConfiguration.ServerConfiguration; // TODO: See if more refactoring can be done in configuration classes diff --git a/src/ServiceControl.Persistence.RavenDB/DatabaseSetup.cs b/src/ServiceControl.Persistence.RavenDB/DatabaseSetup.cs index 89ea46ec3a..20dae983a3 100644 --- a/src/ServiceControl.Persistence.RavenDB/DatabaseSetup.cs +++ b/src/ServiceControl.Persistence.RavenDB/DatabaseSetup.cs @@ -35,8 +35,8 @@ async Task CreateDatabase(string databaseName, CancellationToken cancellationTok try { var databaseRecord = new DatabaseRecord(databaseName); - databaseRecord.Settings.Add("Indexing.Auto.SearchEngineType", "Corax"); - databaseRecord.Settings.Add("Indexing.Static.SearchEngineType", "Corax"); + databaseRecord.Settings.Add("Indexing.Auto.SearchEngineType", settings.SearchEngineType); + databaseRecord.Settings.Add("Indexing.Static.SearchEngineType", settings.SearchEngineType); await documentStore.Maintenance.Server.SendAsync(new CreateDatabaseOperation(databaseRecord), cancellationToken); } @@ -58,8 +58,8 @@ async Task UpdateDatabaseSettings(string databaseName, CancellationToken cancell var updated = false; - updated |= dbRecord.Settings.TryAdd("Indexing.Auto.SearchEngineType", "Corax"); - updated |= dbRecord.Settings.TryAdd("Indexing.Static.SearchEngineType", "Corax"); + updated |= dbRecord.Settings.TryAdd("Indexing.Auto.SearchEngineType", settings.SearchEngineType); + updated |= dbRecord.Settings.TryAdd("Indexing.Static.SearchEngineType", settings.SearchEngineType); if (updated) { diff --git a/src/ServiceControl.Persistence.RavenDB/RavenPersisterSettings.cs b/src/ServiceControl.Persistence.RavenDB/RavenPersisterSettings.cs index 13ceb6b874..b921348310 100644 --- a/src/ServiceControl.Persistence.RavenDB/RavenPersisterSettings.cs +++ b/src/ServiceControl.Persistence.RavenDB/RavenPersisterSettings.cs @@ -32,6 +32,7 @@ class RavenPersisterSettings : PersistenceSettings, IRavenClientCertificateInfo public string LogsMode { get; set; } = LogsModeDefault; public string DatabaseName { get; set; } = DatabaseNameDefault; public string ThroughputDatabaseName { get; set; } = ThroughputSettings.DefaultDatabaseName; + public string SearchEngineType { get; set; } = "Corax"; public const string DatabaseNameDefault = "primary"; public const int DatabaseMaintenancePortDefault = 33334; From c05d11ef8de01b298d3730452f2b00e943783c82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96hlund?= Date: Wed, 26 Feb 2025 12:58:24 +0100 Subject: [PATCH 2/6] Switch back to corax default for tests --- .../SharedEmbeddedServer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ServiceControl.Audit.Persistence.Tests.RavenDB/SharedEmbeddedServer.cs b/src/ServiceControl.Audit.Persistence.Tests.RavenDB/SharedEmbeddedServer.cs index 930aaf818e..e719e8c55d 100644 --- a/src/ServiceControl.Audit.Persistence.Tests.RavenDB/SharedEmbeddedServer.cs +++ b/src/ServiceControl.Audit.Persistence.Tests.RavenDB/SharedEmbeddedServer.cs @@ -36,7 +36,7 @@ public static async Task GetInstance(CancellationToken cancell var logsMode = "Operations"; var serverUrl = $"http://localhost:{PortUtility.FindAvailablePort(33334)}"; - var databaseConfiguration = new DatabaseConfiguration("audit", 60, true, TimeSpan.FromMinutes(5), 120000, 5, 5, new ServerConfiguration(dbPath, serverUrl, logPath, logsMode), TimeSpan.FromSeconds(60), "Lucene"); + var databaseConfiguration = new DatabaseConfiguration("audit", 60, true, TimeSpan.FromMinutes(5), 120000, 5, 5, new ServerConfiguration(dbPath, serverUrl, logPath, logsMode), TimeSpan.FromSeconds(60), "Corax"); var serverConfig = databaseConfiguration.ServerConfiguration; // TODO: See if more refactoring can be done in configuration classes From 0785b01e7bfa2aa3f90297a925589c48396ee4b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96hlund?= Date: Wed, 26 Feb 2025 13:49:10 +0100 Subject: [PATCH 3/6] Make main instance read setting --- src/ServiceControl.Persistence.RavenDB/RavenBootstrapper.cs | 1 + .../RavenPersistenceConfiguration.cs | 1 + .../RavenPersisterSettings.cs | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ServiceControl.Persistence.RavenDB/RavenBootstrapper.cs b/src/ServiceControl.Persistence.RavenDB/RavenBootstrapper.cs index bc6e294289..a18258c0d0 100644 --- a/src/ServiceControl.Persistence.RavenDB/RavenBootstrapper.cs +++ b/src/ServiceControl.Persistence.RavenDB/RavenBootstrapper.cs @@ -12,6 +12,7 @@ static class RavenBootstrapper public const string ClientCertificatePasswordKey = "RavenDB/ClientCertificatePassword"; public const string MinimumStorageLeftRequiredForIngestionKey = "MinimumStorageLeftRequiredForIngestion"; public const string DatabaseNameKey = "RavenDB/DatabaseName"; + public const string SearchEngineTypeKey = "RavenDB/SearchEngineType"; public const string LogsPathKey = "LogPath"; public const string RavenDbLogLevelKey = "RavenDBLogLevel"; } diff --git a/src/ServiceControl.Persistence.RavenDB/RavenPersistenceConfiguration.cs b/src/ServiceControl.Persistence.RavenDB/RavenPersistenceConfiguration.cs index f9f66aa6ca..ca5b4f002c 100644 --- a/src/ServiceControl.Persistence.RavenDB/RavenPersistenceConfiguration.cs +++ b/src/ServiceControl.Persistence.RavenDB/RavenPersistenceConfiguration.cs @@ -39,6 +39,7 @@ static T GetRequiredSetting(SettingsRootNamespace settingsRootNamespace, stri ClientCertificatePassword = SettingsReader.Read(settingsRootNamespace, RavenBootstrapper.ClientCertificatePasswordKey), DatabaseName = SettingsReader.Read(settingsRootNamespace, RavenBootstrapper.DatabaseNameKey, RavenPersisterSettings.DatabaseNameDefault), DatabasePath = SettingsReader.Read(settingsRootNamespace, RavenBootstrapper.DatabasePathKey, DefaultDatabaseLocation()), + SearchEngineType = SettingsReader.Read(settingsRootNamespace, RavenBootstrapper.SearchEngineTypeKey, RavenPersisterSettings.SearchEngineTypeDefault), DatabaseMaintenancePort = SettingsReader.Read(settingsRootNamespace, RavenBootstrapper.DatabaseMaintenancePortKey, RavenPersisterSettings.DatabaseMaintenancePortDefault), ExpirationProcessTimerInSeconds = SettingsReader.Read(settingsRootNamespace, RavenBootstrapper.ExpirationProcessTimerInSecondsKey, 600), MinimumStorageLeftRequiredForIngestion = SettingsReader.Read(settingsRootNamespace, RavenBootstrapper.MinimumStorageLeftRequiredForIngestionKey, CheckMinimumStorageRequiredForIngestion.MinimumStorageLeftRequiredForIngestionDefault), diff --git a/src/ServiceControl.Persistence.RavenDB/RavenPersisterSettings.cs b/src/ServiceControl.Persistence.RavenDB/RavenPersisterSettings.cs index b921348310..1fc3807d33 100644 --- a/src/ServiceControl.Persistence.RavenDB/RavenPersisterSettings.cs +++ b/src/ServiceControl.Persistence.RavenDB/RavenPersisterSettings.cs @@ -32,8 +32,9 @@ class RavenPersisterSettings : PersistenceSettings, IRavenClientCertificateInfo public string LogsMode { get; set; } = LogsModeDefault; public string DatabaseName { get; set; } = DatabaseNameDefault; public string ThroughputDatabaseName { get; set; } = ThroughputSettings.DefaultDatabaseName; - public string SearchEngineType { get; set; } = "Corax"; + public string SearchEngineType { get; set; } = SearchEngineTypeDefault; + public const string SearchEngineTypeDefault = "Corax"; public const string DatabaseNameDefault = "primary"; public const int DatabaseMaintenancePortDefault = 33334; public const int ExpirationProcessTimerInSecondsDefault = 600; From 4a27d3229dbb22b6b38cdfb4fbc8f46f468e966e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96hlund?= Date: Wed, 26 Feb 2025 14:03:28 +0100 Subject: [PATCH 4/6] Align keys --- .../DatabaseSetup.cs | 4 ++-- .../RavenPersistenceConfiguration.cs | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/ServiceControl.Audit.Persistence.RavenDB/DatabaseSetup.cs b/src/ServiceControl.Audit.Persistence.RavenDB/DatabaseSetup.cs index 01e7313f1b..7c168bfcf9 100644 --- a/src/ServiceControl.Audit.Persistence.RavenDB/DatabaseSetup.cs +++ b/src/ServiceControl.Audit.Persistence.RavenDB/DatabaseSetup.cs @@ -12,8 +12,8 @@ using Raven.Client.ServerWide; using Raven.Client.ServerWide.Operations; using Raven.Client.ServerWide.Operations.Configuration; - using ServiceControl.Audit.Persistence.RavenDB.Indexes; - using ServiceControl.SagaAudit; + using Indexes; + using SagaAudit; class DatabaseSetup(DatabaseConfiguration configuration) { diff --git a/src/ServiceControl.Audit.Persistence.RavenDB/RavenPersistenceConfiguration.cs b/src/ServiceControl.Audit.Persistence.RavenDB/RavenPersistenceConfiguration.cs index a6495069b2..6fff91c5b2 100644 --- a/src/ServiceControl.Audit.Persistence.RavenDB/RavenPersistenceConfiguration.cs +++ b/src/ServiceControl.Audit.Persistence.RavenDB/RavenPersistenceConfiguration.cs @@ -22,7 +22,7 @@ public class RavenPersistenceConfiguration : IPersistenceConfiguration public const string MinimumStorageLeftRequiredForIngestionKey = "MinimumStorageLeftRequiredForIngestion"; public const string BulkInsertCommitTimeoutInSecondsKey = "BulkInsertCommitTimeoutInSeconds"; public const string DataSpaceRemainingThresholdKey = "DataSpaceRemainingThreshold"; - public const string SearchEngineTypeKey = "SearchEngineType"; + public const string SearchEngineTypeKey = "RavenDB/SearchEngineType"; public IEnumerable ConfigurationKeys => new[] { DatabaseNameKey, DatabasePathKey, ConnectionStringKey, ClientCertificatePathKey, ClientCertificateBase64Key, ClientCertificatePasswordKey, DatabaseMaintenancePortKey, ExpirationProcessTimerInSecondsKey, LogPathKey, RavenDbLogLevelKey, DataSpaceRemainingThresholdKey, MinimumStorageLeftRequiredForIngestionKey, BulkInsertCommitTimeoutInSecondsKey, SearchEngineTypeKey }; @@ -111,7 +111,7 @@ internal static DatabaseConfiguration GetDatabaseConfiguration(PersistenceSettin if (!settings.PersisterSpecificSettings.TryGetValue(SearchEngineTypeKey, out var searchEngineType)) { - searchEngineType = "Corax"; + searchEngineType = SearchEngineTypeDefault; } return new DatabaseConfiguration( @@ -192,5 +192,6 @@ static string GetLogPath(PersistenceSettings settings) const int ExpirationProcessTimerInSecondsDefault = 600; const int BulkInsertCommitTimeoutInSecondsDefault = 60; + const string SearchEngineTypeDefault = "Corax"; } } \ No newline at end of file From 048dceaddec7dc5868bd3cfdaf6cd9779d0c9d6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96hlund?= Date: Thu, 27 Feb 2025 13:28:03 +0100 Subject: [PATCH 5/6] Add test to check that we use corax by default --- .../DatabaseSetup.cs | 17 ++++++----- .../SagaDetailsIndexTests.cs | 29 +++++++++---------- .../SearchEngineTypeTests.cs | 20 +++++++++++++ 3 files changed, 44 insertions(+), 22 deletions(-) create mode 100644 src/ServiceControl.Audit.Persistence.Tests.RavenDB/SearchEngineTypeTests.cs diff --git a/src/ServiceControl.Audit.Persistence.RavenDB/DatabaseSetup.cs b/src/ServiceControl.Audit.Persistence.RavenDB/DatabaseSetup.cs index 7c168bfcf9..16cdd1a444 100644 --- a/src/ServiceControl.Audit.Persistence.RavenDB/DatabaseSetup.cs +++ b/src/ServiceControl.Audit.Persistence.RavenDB/DatabaseSetup.cs @@ -36,8 +36,8 @@ async Task CreateDatabase(IDocumentStore documentStore, string databaseName, Can try { var databaseRecord = new DatabaseRecord(databaseName); - databaseRecord.Settings.Add("Indexing.Auto.SearchEngineType", configuration.SearchEngineType); - databaseRecord.Settings.Add("Indexing.Static.SearchEngineType", configuration.SearchEngineType); + databaseRecord.Settings.Add(AutoSearchEngineTypeKey, configuration.SearchEngineType); + databaseRecord.Settings.Add(StaticSearchEngineTypeKey, configuration.SearchEngineType); await documentStore.Maintenance.Server.SendAsync(new CreateDatabaseOperation(databaseRecord), cancellationToken); } @@ -95,7 +95,7 @@ async Task UpdateDatabaseSettings(IDocumentStore documentStore, string databaseN } } - public static async Task DeleteLegacySagaDetailsIndex(IDocumentStore documentStore, CancellationToken cancellationToken) + internal static async Task DeleteLegacySagaDetailsIndex(IDocumentStore documentStore, CancellationToken cancellationToken) { // If the SagaDetailsIndex exists but does not have a .Take(50000), then we remove the current SagaDetailsIndex and // create a new one. If we do not remove the current one, then RavenDB will attempt to do a side-by-side migration. @@ -103,11 +103,11 @@ public static async Task DeleteLegacySagaDetailsIndex(IDocumentStore documentSto // for the index to not be stale before swapping to the new index. Constant ingestion means the index will never be not-stale. // This needs to stay in place until the next major version as the user could upgrade from an older version of the current // Major (v5.x.x) which might still have the incorrect index. - var sagaDetailsIndexOperation = new GetIndexOperation("SagaDetailsIndex"); + var sagaDetailsIndexOperation = new GetIndexOperation(SagaDetailsIndexName); var sagaDetailsIndexDefinition = await documentStore.Maintenance.SendAsync(sagaDetailsIndexOperation, cancellationToken); if (sagaDetailsIndexDefinition != null && !sagaDetailsIndexDefinition.Reduce.Contains("Take(50000)")) { - await documentStore.Maintenance.SendAsync(new DeleteIndexOperation("SagaDetailsIndex"), cancellationToken); + await documentStore.Maintenance.SendAsync(new DeleteIndexOperation(SagaDetailsIndexName), cancellationToken); } } @@ -120,12 +120,12 @@ async Task CreateIndexes(IDocumentStore documentStore, CancellationToken cancell if (configuration.EnableFullTextSearch) { indexList.Add(new MessagesViewIndexWithFullTextSearch()); - await documentStore.Maintenance.SendAsync(new DeleteIndexOperation("MessagesViewIndex"), cancellationToken); + await documentStore.Maintenance.SendAsync(new DeleteIndexOperation(MessagesViewIndexName), cancellationToken); } else { indexList.Add(new MessagesViewIndex()); - await documentStore.Maintenance.SendAsync(new DeleteIndexOperation("MessagesViewIndexWithFullTextSearch"), cancellationToken); + await documentStore.Maintenance.SendAsync(new DeleteIndexOperation(MessagesViewIndexWithFullTextSearchIndexName), cancellationToken); } await IndexCreation.CreateIndexesAsync(indexList, documentStore, null, null, cancellationToken); @@ -144,5 +144,8 @@ async Task ConfigureExpiration(IDocumentStore documentStore, CancellationToken c const string AutoSearchEngineTypeKey = "Indexing.Auto.SearchEngineType"; const string StaticSearchEngineTypeKey = "Indexing.Static.SearchEngineType"; + internal const string MessagesViewIndexName = "MessagesViewIndex"; + internal const string MessagesViewIndexWithFullTextSearchIndexName = "MessagesViewIndexWithFullTextSearch"; + internal const string SagaDetailsIndexName = "SagaDetailsIndex"; } } \ No newline at end of file diff --git a/src/ServiceControl.Audit.Persistence.Tests.RavenDB/SagaDetailsIndexTests.cs b/src/ServiceControl.Audit.Persistence.Tests.RavenDB/SagaDetailsIndexTests.cs index 4dc9a2d5d8..03e75459b2 100644 --- a/src/ServiceControl.Audit.Persistence.Tests.RavenDB/SagaDetailsIndexTests.cs +++ b/src/ServiceControl.Audit.Persistence.Tests.RavenDB/SagaDetailsIndexTests.cs @@ -4,6 +4,7 @@ using System.Threading; using System.Threading.Tasks; using NUnit.Framework; + using Persistence.RavenDB; using Raven.Client.Documents.Indexes; using Raven.Client.Documents.Operations.Indexes; using ServiceControl.SagaAudit; @@ -14,14 +15,14 @@ class SagaDetailsIndexTests : PersistenceTestFixture [Test] public async Task Deletes_index_that_does_not_have_cap_of_50000() { - await configuration.DocumentStore.Maintenance.SendAsync(new DeleteIndexOperation("SagaDetailsIndex")); + await configuration.DocumentStore.Maintenance.SendAsync(new DeleteIndexOperation(DatabaseSetup.SagaDetailsIndexName)); var indexWithout50000capDefinition = new IndexDefinition { - Name = "SagaDetailsIndex", + Name = DatabaseSetup.SagaDetailsIndexName, Maps = - [ - @"from doc in docs + [ + @"from doc in docs select new { doc.SagaId, @@ -41,7 +42,7 @@ public async Task Deletes_index_that_does_not_have_cap_of_50000() } } }" - ], + ], Reduce = @"from result in results group result by result.SagaId into g @@ -61,12 +62,12 @@ into g await configuration.DocumentStore.Maintenance.SendAsync(putIndexesOp); - var sagaDetailsIndexOperation = new GetIndexOperation("SagaDetailsIndex"); + var sagaDetailsIndexOperation = new GetIndexOperation(DatabaseSetup.SagaDetailsIndexName); var sagaDetailsIndexDefinition = await configuration.DocumentStore.Maintenance.SendAsync(sagaDetailsIndexOperation); Assert.That(sagaDetailsIndexDefinition, Is.Not.Null); - await Persistence.RavenDB.DatabaseSetup.DeleteLegacySagaDetailsIndex(configuration.DocumentStore, CancellationToken.None); + await DatabaseSetup.DeleteLegacySagaDetailsIndex(configuration.DocumentStore, CancellationToken.None); sagaDetailsIndexDefinition = await configuration.DocumentStore.Maintenance.SendAsync(sagaDetailsIndexOperation); @@ -76,9 +77,9 @@ into g [Test] public async Task Does_not_delete_index_that_does_have_cap_of_50000() { - await Persistence.RavenDB.DatabaseSetup.DeleteLegacySagaDetailsIndex(configuration.DocumentStore, CancellationToken.None); + await DatabaseSetup.DeleteLegacySagaDetailsIndex(configuration.DocumentStore, CancellationToken.None); - var sagaDetailsIndexOperation = new GetIndexOperation("SagaDetailsIndex"); + var sagaDetailsIndexOperation = new GetIndexOperation(DatabaseSetup.SagaDetailsIndexName); var sagaDetailsIndexDefinition = await configuration.DocumentStore.Maintenance.SendAsync(sagaDetailsIndexOperation); Assert.That(sagaDetailsIndexDefinition, Is.Not.Null); @@ -100,13 +101,10 @@ await IngestSagaAudits(new SagaSnapshot await configuration.CompleteDBOperation(); - using (var session = configuration.DocumentStore.OpenAsyncSession()) - { - var sagaDetailsIndexOperation = new GetIndexOperation("SagaDetailsIndex"); - var sagaDetailsIndexDefinition = await configuration.DocumentStore.Maintenance.SendAsync(sagaDetailsIndexOperation); + var sagaDetailsIndexOperation = new GetIndexOperation(DatabaseSetup.SagaDetailsIndexName); + var sagaDetailsIndexDefinition = await configuration.DocumentStore.Maintenance.SendAsync(sagaDetailsIndexOperation); - Assert.That(sagaDetailsIndexDefinition.Reduce, Does.Contain("Take(50000)"), "The SagaDetails index definition does not contain a .Take(50000) to limit the number of saga state changes that are reduced by the map/reduce"); - } + Assert.That(sagaDetailsIndexDefinition.Reduce, Does.Contain("Take(50000)"), "The SagaDetails index definition does not contain a .Take(50000) to limit the number of saga state changes that are reduced by the map/reduce"); } async Task IngestSagaAudits(params SagaSnapshot[] snapshots) @@ -116,6 +114,7 @@ async Task IngestSagaAudits(params SagaSnapshot[] snapshots) { await unitOfWork.RecordSagaSnapshot(snapshot); } + await unitOfWork.DisposeAsync(); await configuration.CompleteDBOperation(); } diff --git a/src/ServiceControl.Audit.Persistence.Tests.RavenDB/SearchEngineTypeTests.cs b/src/ServiceControl.Audit.Persistence.Tests.RavenDB/SearchEngineTypeTests.cs new file mode 100644 index 0000000000..ed6d108a93 --- /dev/null +++ b/src/ServiceControl.Audit.Persistence.Tests.RavenDB/SearchEngineTypeTests.cs @@ -0,0 +1,20 @@ +namespace ServiceControl.Audit.Persistence.Tests; + +using System.Threading.Tasks; +using NUnit.Framework; +using Persistence.RavenDB; +using Raven.Client.Documents.Indexes; +using Raven.Client.Documents.Operations.Indexes; + +[TestFixture] +class SearchEngineTypeTests : PersistenceTestFixture +{ + [Test] + public async Task Free_text_search_should_be_on_using_corax_by_default() + { + var index = await configuration.DocumentStore.Maintenance.SendAsync(new GetIndexStatisticsOperation(DatabaseSetup.MessagesViewIndexWithFullTextSearchIndexName)); + + Assert.That(index, Is.Not.Null); + Assert.That(index.SearchEngineType, Is.EqualTo(SearchEngineType.Corax)); + } +} \ No newline at end of file From 4e1dacff0e216bb7e75aa8b1f30427febf6f35b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96hlund?= Date: Thu, 27 Feb 2025 13:51:56 +0100 Subject: [PATCH 6/6] Use enum instead --- .../DatabaseConfiguration.cs | 5 +++-- .../DatabaseSetup.cs | 12 ++++++------ .../RavenPersistenceConfiguration.cs | 14 +++++++++++--- .../SearchEngineTypeTests.cs | 8 +++++--- .../SharedEmbeddedServer.cs | 2 +- .../DatabaseSetup.cs | 8 ++++---- .../RavenPersistenceConfiguration.cs | 3 ++- .../RavenPersisterSettings.cs | 5 +++-- 8 files changed, 35 insertions(+), 22 deletions(-) diff --git a/src/ServiceControl.Audit.Persistence.RavenDB/DatabaseConfiguration.cs b/src/ServiceControl.Audit.Persistence.RavenDB/DatabaseConfiguration.cs index 5fb7c290e5..014e15e926 100644 --- a/src/ServiceControl.Audit.Persistence.RavenDB/DatabaseConfiguration.cs +++ b/src/ServiceControl.Audit.Persistence.RavenDB/DatabaseConfiguration.cs @@ -1,6 +1,7 @@ namespace ServiceControl.Audit.Persistence.RavenDB { using System; + using Raven.Client.Documents.Indexes; using Sparrow.Json; public class DatabaseConfiguration( @@ -13,7 +14,7 @@ public class DatabaseConfiguration( int minimumStorageLeftRequiredForIngestion, ServerConfiguration serverConfiguration, TimeSpan bulkInsertCommitTimeout, - string searchEngineType) + SearchEngineType searchEngineType) { public string Name { get; } = name; @@ -35,6 +36,6 @@ public class DatabaseConfiguration( public TimeSpan BulkInsertCommitTimeout { get; } = bulkInsertCommitTimeout; - public string SearchEngineType { get; } = searchEngineType; + public SearchEngineType SearchEngineType { get; } = searchEngineType; } } \ No newline at end of file diff --git a/src/ServiceControl.Audit.Persistence.RavenDB/DatabaseSetup.cs b/src/ServiceControl.Audit.Persistence.RavenDB/DatabaseSetup.cs index 16cdd1a444..345c6a0b07 100644 --- a/src/ServiceControl.Audit.Persistence.RavenDB/DatabaseSetup.cs +++ b/src/ServiceControl.Audit.Persistence.RavenDB/DatabaseSetup.cs @@ -36,8 +36,8 @@ async Task CreateDatabase(IDocumentStore documentStore, string databaseName, Can try { var databaseRecord = new DatabaseRecord(databaseName); - databaseRecord.Settings.Add(AutoSearchEngineTypeKey, configuration.SearchEngineType); - databaseRecord.Settings.Add(StaticSearchEngineTypeKey, configuration.SearchEngineType); + databaseRecord.Settings.Add(AutoSearchEngineTypeKey, configuration.SearchEngineType.ToString()); + databaseRecord.Settings.Add(StaticSearchEngineTypeKey, configuration.SearchEngineType.ToString()); await documentStore.Maintenance.Server.SendAsync(new CreateDatabaseOperation(databaseRecord), cancellationToken); } @@ -61,7 +61,7 @@ async Task UpdateDatabaseSettings(IDocumentStore documentStore, string databaseN if (dbRecord.Settings.TryGetValue(AutoSearchEngineTypeKey, out var searchEngineTypeAuto)) { - if (searchEngineTypeAuto != configuration.SearchEngineType) + if (searchEngineTypeAuto != configuration.SearchEngineType.ToString()) { updated = true; } @@ -71,11 +71,11 @@ async Task UpdateDatabaseSettings(IDocumentStore documentStore, string databaseN updated = true; } - dbRecord.Settings[AutoSearchEngineTypeKey] = configuration.SearchEngineType; + dbRecord.Settings[AutoSearchEngineTypeKey] = configuration.SearchEngineType.ToString(); if (dbRecord.Settings.TryGetValue(StaticSearchEngineTypeKey, out var searchEngineTypeStatic)) { - if (searchEngineTypeStatic != configuration.SearchEngineType) + if (searchEngineTypeStatic != configuration.SearchEngineType.ToString()) { updated = true; } @@ -85,7 +85,7 @@ async Task UpdateDatabaseSettings(IDocumentStore documentStore, string databaseN updated = true; } - dbRecord.Settings[StaticSearchEngineTypeKey] = configuration.SearchEngineType; + dbRecord.Settings[StaticSearchEngineTypeKey] = configuration.SearchEngineType.ToString(); if (updated) { diff --git a/src/ServiceControl.Audit.Persistence.RavenDB/RavenPersistenceConfiguration.cs b/src/ServiceControl.Audit.Persistence.RavenDB/RavenPersistenceConfiguration.cs index 6fff91c5b2..bac1e2a07a 100644 --- a/src/ServiceControl.Audit.Persistence.RavenDB/RavenPersistenceConfiguration.cs +++ b/src/ServiceControl.Audit.Persistence.RavenDB/RavenPersistenceConfiguration.cs @@ -6,6 +6,7 @@ using System.Reflection; using CustomChecks; using NServiceBus.Logging; + using Raven.Client.Documents.Indexes; public class RavenPersistenceConfiguration : IPersistenceConfiguration { @@ -109,9 +110,16 @@ internal static DatabaseConfiguration GetDatabaseConfiguration(PersistenceSettin var bulkInsertTimeout = TimeSpan.FromSeconds(GetBulkInsertCommitTimeout(settings)); - if (!settings.PersisterSpecificSettings.TryGetValue(SearchEngineTypeKey, out var searchEngineType)) + var searchEngineType = SearchEngineTypeDefault; + + if (settings.PersisterSpecificSettings.TryGetValue(SearchEngineTypeKey, out var searchEngineTypeValue)) { - searchEngineType = SearchEngineTypeDefault; + if (!Enum.TryParse(searchEngineTypeValue, out var explicitSearchEngineType)) + { + throw new InvalidOperationException($"{searchEngineTypeValue} is not supported."); + } + + searchEngineType = explicitSearchEngineType; } return new DatabaseConfiguration( @@ -192,6 +200,6 @@ static string GetLogPath(PersistenceSettings settings) const int ExpirationProcessTimerInSecondsDefault = 600; const int BulkInsertCommitTimeoutInSecondsDefault = 60; - const string SearchEngineTypeDefault = "Corax"; + internal static readonly SearchEngineType SearchEngineTypeDefault = SearchEngineType.Corax; } } \ No newline at end of file diff --git a/src/ServiceControl.Audit.Persistence.Tests.RavenDB/SearchEngineTypeTests.cs b/src/ServiceControl.Audit.Persistence.Tests.RavenDB/SearchEngineTypeTests.cs index ed6d108a93..626e742e9a 100644 --- a/src/ServiceControl.Audit.Persistence.Tests.RavenDB/SearchEngineTypeTests.cs +++ b/src/ServiceControl.Audit.Persistence.Tests.RavenDB/SearchEngineTypeTests.cs @@ -12,9 +12,11 @@ class SearchEngineTypeTests : PersistenceTestFixture [Test] public async Task Free_text_search_should_be_on_using_corax_by_default() { - var index = await configuration.DocumentStore.Maintenance.SendAsync(new GetIndexStatisticsOperation(DatabaseSetup.MessagesViewIndexWithFullTextSearchIndexName)); + var freeTextIndex = await configuration.DocumentStore.Maintenance.SendAsync(new GetIndexStatisticsOperation(DatabaseSetup.MessagesViewIndexWithFullTextSearchIndexName)); + var nonFreeTextIndex = await configuration.DocumentStore.Maintenance.SendAsync(new GetIndexOperation(DatabaseSetup.MessagesViewIndexName)); - Assert.That(index, Is.Not.Null); - Assert.That(index.SearchEngineType, Is.EqualTo(SearchEngineType.Corax)); + Assert.That(nonFreeTextIndex, Is.Null); + Assert.That(freeTextIndex, Is.Not.Null); + Assert.That(freeTextIndex.SearchEngineType, Is.EqualTo(SearchEngineType.Corax)); } } \ No newline at end of file diff --git a/src/ServiceControl.Audit.Persistence.Tests.RavenDB/SharedEmbeddedServer.cs b/src/ServiceControl.Audit.Persistence.Tests.RavenDB/SharedEmbeddedServer.cs index e719e8c55d..88d0b79efa 100644 --- a/src/ServiceControl.Audit.Persistence.Tests.RavenDB/SharedEmbeddedServer.cs +++ b/src/ServiceControl.Audit.Persistence.Tests.RavenDB/SharedEmbeddedServer.cs @@ -36,7 +36,7 @@ public static async Task GetInstance(CancellationToken cancell var logsMode = "Operations"; var serverUrl = $"http://localhost:{PortUtility.FindAvailablePort(33334)}"; - var databaseConfiguration = new DatabaseConfiguration("audit", 60, true, TimeSpan.FromMinutes(5), 120000, 5, 5, new ServerConfiguration(dbPath, serverUrl, logPath, logsMode), TimeSpan.FromSeconds(60), "Corax"); + var databaseConfiguration = new DatabaseConfiguration("audit", 60, true, TimeSpan.FromMinutes(5), 120000, 5, 5, new ServerConfiguration(dbPath, serverUrl, logPath, logsMode), TimeSpan.FromSeconds(60), RavenPersistenceConfiguration.SearchEngineTypeDefault); var serverConfig = databaseConfiguration.ServerConfiguration; // TODO: See if more refactoring can be done in configuration classes diff --git a/src/ServiceControl.Persistence.RavenDB/DatabaseSetup.cs b/src/ServiceControl.Persistence.RavenDB/DatabaseSetup.cs index 20dae983a3..8bdba940c7 100644 --- a/src/ServiceControl.Persistence.RavenDB/DatabaseSetup.cs +++ b/src/ServiceControl.Persistence.RavenDB/DatabaseSetup.cs @@ -35,8 +35,8 @@ async Task CreateDatabase(string databaseName, CancellationToken cancellationTok try { var databaseRecord = new DatabaseRecord(databaseName); - databaseRecord.Settings.Add("Indexing.Auto.SearchEngineType", settings.SearchEngineType); - databaseRecord.Settings.Add("Indexing.Static.SearchEngineType", settings.SearchEngineType); + databaseRecord.Settings.Add("Indexing.Auto.SearchEngineType", settings.SearchEngineType.ToString()); + databaseRecord.Settings.Add("Indexing.Static.SearchEngineType", settings.SearchEngineType.ToString()); await documentStore.Maintenance.Server.SendAsync(new CreateDatabaseOperation(databaseRecord), cancellationToken); } @@ -58,8 +58,8 @@ async Task UpdateDatabaseSettings(string databaseName, CancellationToken cancell var updated = false; - updated |= dbRecord.Settings.TryAdd("Indexing.Auto.SearchEngineType", settings.SearchEngineType); - updated |= dbRecord.Settings.TryAdd("Indexing.Static.SearchEngineType", settings.SearchEngineType); + updated |= dbRecord.Settings.TryAdd("Indexing.Auto.SearchEngineType", settings.SearchEngineType.ToString()); + updated |= dbRecord.Settings.TryAdd("Indexing.Static.SearchEngineType", settings.SearchEngineType.ToString()); if (updated) { diff --git a/src/ServiceControl.Persistence.RavenDB/RavenPersistenceConfiguration.cs b/src/ServiceControl.Persistence.RavenDB/RavenPersistenceConfiguration.cs index ca5b4f002c..f119855aa2 100644 --- a/src/ServiceControl.Persistence.RavenDB/RavenPersistenceConfiguration.cs +++ b/src/ServiceControl.Persistence.RavenDB/RavenPersistenceConfiguration.cs @@ -6,6 +6,7 @@ using Configuration; using CustomChecks; using Particular.LicensingComponent.Contracts; + using Raven.Client.Documents.Indexes; class RavenPersistenceConfiguration : IPersistenceConfiguration { @@ -39,7 +40,7 @@ static T GetRequiredSetting(SettingsRootNamespace settingsRootNamespace, stri ClientCertificatePassword = SettingsReader.Read(settingsRootNamespace, RavenBootstrapper.ClientCertificatePasswordKey), DatabaseName = SettingsReader.Read(settingsRootNamespace, RavenBootstrapper.DatabaseNameKey, RavenPersisterSettings.DatabaseNameDefault), DatabasePath = SettingsReader.Read(settingsRootNamespace, RavenBootstrapper.DatabasePathKey, DefaultDatabaseLocation()), - SearchEngineType = SettingsReader.Read(settingsRootNamespace, RavenBootstrapper.SearchEngineTypeKey, RavenPersisterSettings.SearchEngineTypeDefault), + SearchEngineType = SettingsReader.Read(settingsRootNamespace, RavenBootstrapper.SearchEngineTypeKey, RavenPersisterSettings.SearchEngineTypeDefault), DatabaseMaintenancePort = SettingsReader.Read(settingsRootNamespace, RavenBootstrapper.DatabaseMaintenancePortKey, RavenPersisterSettings.DatabaseMaintenancePortDefault), ExpirationProcessTimerInSeconds = SettingsReader.Read(settingsRootNamespace, RavenBootstrapper.ExpirationProcessTimerInSecondsKey, 600), MinimumStorageLeftRequiredForIngestion = SettingsReader.Read(settingsRootNamespace, RavenBootstrapper.MinimumStorageLeftRequiredForIngestionKey, CheckMinimumStorageRequiredForIngestion.MinimumStorageLeftRequiredForIngestionDefault), diff --git a/src/ServiceControl.Persistence.RavenDB/RavenPersisterSettings.cs b/src/ServiceControl.Persistence.RavenDB/RavenPersisterSettings.cs index 1fc3807d33..7497a13860 100644 --- a/src/ServiceControl.Persistence.RavenDB/RavenPersisterSettings.cs +++ b/src/ServiceControl.Persistence.RavenDB/RavenPersisterSettings.cs @@ -1,5 +1,6 @@ using System; using Particular.LicensingComponent.Contracts; +using Raven.Client.Documents.Linq.Indexing; using ServiceControl.Persistence; using ServiceControl.Persistence.RavenDB.CustomChecks; using ServiceControl.RavenDB; @@ -32,9 +33,9 @@ class RavenPersisterSettings : PersistenceSettings, IRavenClientCertificateInfo public string LogsMode { get; set; } = LogsModeDefault; public string DatabaseName { get; set; } = DatabaseNameDefault; public string ThroughputDatabaseName { get; set; } = ThroughputSettings.DefaultDatabaseName; - public string SearchEngineType { get; set; } = SearchEngineTypeDefault; + public Raven.Client.Documents.Indexes.SearchEngineType SearchEngineType { get; set; } = SearchEngineTypeDefault; - public const string SearchEngineTypeDefault = "Corax"; + public static readonly Raven.Client.Documents.Indexes.SearchEngineType SearchEngineTypeDefault = Raven.Client.Documents.Indexes.SearchEngineType.Corax; public const string DatabaseNameDefault = "primary"; public const int DatabaseMaintenancePortDefault = 33334; public const int ExpirationProcessTimerInSecondsDefault = 600;