From 4fbe19111d9573a4f9bd2203bfdfe920a362fb42 Mon Sep 17 00:00:00 2001 From: Mauro Servienti Date: Thu, 22 Jan 2026 21:23:08 +0100 Subject: [PATCH] The license status check fails when checking license against a secured RavenDB instance (#5274) * Use the internal RavenDB HTTP client * extract the server URL from the document store * Refactor license status check with cancellation token * Fix whitespace * Make the primary instance LicenseStatusCheck behave like the audit instance one --------- Co-authored-by: Ramon Smits --- .../DatabaseSetup.cs | 2 +- .../LicenseStatusCheck.cs | 48 ++++++++++--------- .../DatabaseSetup.cs | 2 +- .../LicenseStatusCheck.cs | 46 ++++++++++-------- 4 files changed, 53 insertions(+), 45 deletions(-) diff --git a/src/ServiceControl.Audit.Persistence.RavenDB/DatabaseSetup.cs b/src/ServiceControl.Audit.Persistence.RavenDB/DatabaseSetup.cs index e2def6dfc0..b1d42b3d00 100644 --- a/src/ServiceControl.Audit.Persistence.RavenDB/DatabaseSetup.cs +++ b/src/ServiceControl.Audit.Persistence.RavenDB/DatabaseSetup.cs @@ -27,7 +27,7 @@ public async Task Execute(IDocumentStore documentStore, CancellationToken cancel await CreateIndexes(documentStore, configuration.EnableFullTextSearch, cancellationToken); - await LicenseStatusCheck.WaitForLicenseOrThrow(configuration, cancellationToken); + await LicenseStatusCheck.WaitForLicenseOrThrow(documentStore, cancellationToken); await ConfigureExpiration(documentStore, cancellationToken); } diff --git a/src/ServiceControl.Audit.Persistence.RavenDB/LicenseStatusCheck.cs b/src/ServiceControl.Audit.Persistence.RavenDB/LicenseStatusCheck.cs index 9aee22a425..342013df76 100644 --- a/src/ServiceControl.Audit.Persistence.RavenDB/LicenseStatusCheck.cs +++ b/src/ServiceControl.Audit.Persistence.RavenDB/LicenseStatusCheck.cs @@ -1,41 +1,45 @@ namespace ServiceControl.Audit.Persistence.RavenDB; using System; -using System.Net.Http; using System.Net.Http.Json; using System.Threading; using System.Threading.Tasks; +using Raven.Client.Documents; static class LicenseStatusCheck { record LicenseStatusFragment(string Id, string LicensedTo, string Status, bool Expired); - public static async Task WaitForLicenseOrThrow(DatabaseConfiguration configuration, CancellationToken cancellationToken) + public static async Task WaitForLicenseOrThrow(IDocumentStore documentStore, CancellationToken cancellationToken) { - using var client = new HttpClient - { - BaseAddress = new Uri(configuration.ServerConfiguration.ConnectionString ?? configuration.ServerConfiguration.ServerUrl) - }; + var ravenConfiguredHttpClient = documentStore.GetRequestExecutor().HttpClient; + var licenseCheckUrl = documentStore.Urls[0].TrimEnd('/') + "/license/status"; + + using var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); + cts.CancelAfter(30_000); - // Not linking to the incoming cancellationToken to ensure no OperationCancelledException prevents the last InvalidOperationException to be thrown - using var cts = new CancellationTokenSource(30_000); - while (!cts.IsCancellationRequested) + try { - var httpResponse = await client.GetAsync("license/status", cancellationToken); - var licenseStatus = await httpResponse.Content.ReadFromJsonAsync(cancellationToken); - if (licenseStatus.Expired) + while (true) { - throw new InvalidOperationException("The current RavenDB license is expired. Please, contact support"); - } + var httpResponse = await ravenConfiguredHttpClient.GetAsync(licenseCheckUrl, cts.Token); + var licenseStatus = await httpResponse.Content.ReadFromJsonAsync(cts.Token); + if (licenseStatus.Expired) + { + throw new InvalidOperationException("The current RavenDB license is expired. Please, contact support"); + } - if (licenseStatus.LicensedTo != null && licenseStatus.Id != null) - { - return; - } + if (licenseStatus.LicensedTo != null && licenseStatus.Id != null) + { + return; + } - await Task.Delay(200, cancellationToken); + await Task.Delay(200, cts.Token); + } + } + catch (OperationCanceledException) when (!cancellationToken.IsCancellationRequested) + { + throw new InvalidOperationException("Cannot validate the current RavenDB license. Please, contact support"); } - - throw new InvalidOperationException("Cannot validate the current RavenDB license. Please, contact support"); } -} \ No newline at end of file +} diff --git a/src/ServiceControl.Persistence.RavenDB/DatabaseSetup.cs b/src/ServiceControl.Persistence.RavenDB/DatabaseSetup.cs index c77342946b..4b71a0a43b 100644 --- a/src/ServiceControl.Persistence.RavenDB/DatabaseSetup.cs +++ b/src/ServiceControl.Persistence.RavenDB/DatabaseSetup.cs @@ -23,7 +23,7 @@ public async Task Execute(CancellationToken cancellationToken) await IndexCreation.CreateIndexesAsync(typeof(DatabaseSetup).Assembly, documentStore, null, null, cancellationToken); - await LicenseStatusCheck.WaitForLicenseOrThrow(settings, cancellationToken); + await LicenseStatusCheck.WaitForLicenseOrThrow(documentStore, cancellationToken); await ConfigureExpiration(settings, cancellationToken); } diff --git a/src/ServiceControl.Persistence.RavenDB/LicenseStatusCheck.cs b/src/ServiceControl.Persistence.RavenDB/LicenseStatusCheck.cs index deb1956cc6..6b7ff4736e 100644 --- a/src/ServiceControl.Persistence.RavenDB/LicenseStatusCheck.cs +++ b/src/ServiceControl.Persistence.RavenDB/LicenseStatusCheck.cs @@ -1,41 +1,45 @@ namespace ServiceControl.Persistence.RavenDB; using System; -using System.Net.Http; using System.Net.Http.Json; using System.Threading; using System.Threading.Tasks; +using Raven.Client.Documents; static class LicenseStatusCheck { record LicenseStatusFragment(string Id, string LicensedTo, string Status, bool Expired); - public static async Task WaitForLicenseOrThrow(RavenPersisterSettings configuration, CancellationToken cancellationToken) + public static async Task WaitForLicenseOrThrow(IDocumentStore documentStore, CancellationToken cancellationToken) { - using var client = new HttpClient - { - BaseAddress = new Uri(configuration.ConnectionString ?? configuration.ServerUrl) - }; + var ravenConfiguredHttpClient = documentStore.GetRequestExecutor().HttpClient; + var licenseCheckUrl = documentStore.Urls[0].TrimEnd('/') + "/license/status"; + + using var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); + cts.CancelAfter(30_000); - // Not linking to the incoming cancellationToken to ensure no OperationCancelledException prevents the last InvalidOperationException to be thrown - using var cts = new CancellationTokenSource(30_000); - while (!cts.IsCancellationRequested) + try { - var httpResponse = await client.GetAsync("license/status", cancellationToken); - var licenseStatus = await httpResponse.Content.ReadFromJsonAsync(cancellationToken); - if (licenseStatus.Expired) + while (!cts.IsCancellationRequested) { - throw new InvalidOperationException("The current RavenDB license is expired. Please, contact support"); - } + var httpResponse = await ravenConfiguredHttpClient.GetAsync(licenseCheckUrl, cancellationToken); + var licenseStatus = await httpResponse.Content.ReadFromJsonAsync(cancellationToken); + if (licenseStatus.Expired) + { + throw new InvalidOperationException("The current RavenDB license is expired. Please, contact support"); + } - if (licenseStatus.LicensedTo != null && licenseStatus.Id != null) - { - return; - } + if (licenseStatus.LicensedTo != null && licenseStatus.Id != null) + { + return; + } - await Task.Delay(200, cancellationToken); + await Task.Delay(200, cts.Token); + } + } + catch (OperationCanceledException) when (!cancellationToken.IsCancellationRequested) + { + throw new InvalidOperationException("Cannot validate the current RavenDB license. Please, contact support"); } - - throw new InvalidOperationException("Cannot validate the current RavenDB license. Please, contact support"); } } \ No newline at end of file