From 5dfe172abad609e3d946594ddfd4357d8a9779a3 Mon Sep 17 00:00:00 2001 From: Ramon Smits Date: Mon, 8 Sep 2025 12:47:09 +0200 Subject: [PATCH 1/3] Check that server major/minor is higher than client major/minor --- .../ServiceControl.RavenDB.csproj | 1 + src/ServiceControl.RavenDB/StartupChecks.cs | 15 +++++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/ServiceControl.RavenDB/ServiceControl.RavenDB.csproj b/src/ServiceControl.RavenDB/ServiceControl.RavenDB.csproj index 0479c4ff74..be8a854722 100644 --- a/src/ServiceControl.RavenDB/ServiceControl.RavenDB.csproj +++ b/src/ServiceControl.RavenDB/ServiceControl.RavenDB.csproj @@ -9,6 +9,7 @@ + diff --git a/src/ServiceControl.RavenDB/StartupChecks.cs b/src/ServiceControl.RavenDB/StartupChecks.cs index 46558850e9..9ff59b5c77 100644 --- a/src/ServiceControl.RavenDB/StartupChecks.cs +++ b/src/ServiceControl.RavenDB/StartupChecks.cs @@ -2,6 +2,7 @@ { using System.Reflection; using System.Threading; + using NuGet.Versioning; using Raven.Client.Documents; using Raven.Client.ServerWide.Operations; @@ -11,14 +12,16 @@ public static async Task EnsureServerVersion(IDocumentStore store, CancellationT { var build = await store.Maintenance.Server.SendAsync(new GetBuildNumberOperation(), cancellationToken); - var clientVersion = typeof(Raven.Client.Constants).Assembly.GetCustomAttributes().First().InformationalVersion; - var parts = clientVersion.Split('.'); - var clientProductVersion = $"{parts[0]}.{parts[1]}"; + var clientVersion = SemanticVersion.Parse(typeof(Raven.Client.Constants).Assembly.GetCustomAttributes().First().InformationalVersion); + var serverVersion = NuGetVersion.Parse(build.ProductVersion); - if (clientProductVersion != build.ProductVersion) + var serverHasLowerMajorMinor = serverVersion.Major < clientVersion.Major + || (serverVersion.Major == clientVersion.Major && serverVersion.Minor < clientVersion.Minor); + + if (serverHasLowerMajorMinor) { - throw new Exception($"ServiceControl expects RavenDB Server version {clientProductVersion} but the server is using {build.ProductVersion}."); + throw new Exception($"ServiceControl expects at minimum RavenDB Server version {clientVersion.Major}.{clientVersion.Minor} but the server is using {build.ProductVersion}."); } } } -} +} \ No newline at end of file From ea8e0bbaa5763fd7d79336de7259d1ebb718bfd3 Mon Sep 17 00:00:00 2001 From: Brandon Ording Date: Mon, 8 Sep 2025 12:15:25 -0400 Subject: [PATCH 2/3] Make check work without NuGet.Versioning --- .../ServiceControl.RavenDB.csproj | 1 - src/ServiceControl.RavenDB/StartupChecks.cs | 16 +++++++--------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/ServiceControl.RavenDB/ServiceControl.RavenDB.csproj b/src/ServiceControl.RavenDB/ServiceControl.RavenDB.csproj index be8a854722..0479c4ff74 100644 --- a/src/ServiceControl.RavenDB/ServiceControl.RavenDB.csproj +++ b/src/ServiceControl.RavenDB/ServiceControl.RavenDB.csproj @@ -9,7 +9,6 @@ - diff --git a/src/ServiceControl.RavenDB/StartupChecks.cs b/src/ServiceControl.RavenDB/StartupChecks.cs index 9ff59b5c77..d4182f03bc 100644 --- a/src/ServiceControl.RavenDB/StartupChecks.cs +++ b/src/ServiceControl.RavenDB/StartupChecks.cs @@ -2,7 +2,6 @@ { using System.Reflection; using System.Threading; - using NuGet.Versioning; using Raven.Client.Documents; using Raven.Client.ServerWide.Operations; @@ -11,17 +10,16 @@ public static class StartupChecks public static async Task EnsureServerVersion(IDocumentStore store, CancellationToken cancellationToken = default) { var build = await store.Maintenance.Server.SendAsync(new GetBuildNumberOperation(), cancellationToken); + var serverProductVersion = new Version(build.ProductVersion); - var clientVersion = SemanticVersion.Parse(typeof(Raven.Client.Constants).Assembly.GetCustomAttributes().First().InformationalVersion); - var serverVersion = NuGetVersion.Parse(build.ProductVersion); + var clientVersion = typeof(Raven.Client.Constants).Assembly.GetCustomAttributes().First().InformationalVersion; + var parts = clientVersion.Split('.'); + var clientProductVersion = new Version($"{parts[0]}.{parts[1]}"); - var serverHasLowerMajorMinor = serverVersion.Major < clientVersion.Major - || (serverVersion.Major == clientVersion.Major && serverVersion.Minor < clientVersion.Minor); - - if (serverHasLowerMajorMinor) + if (clientProductVersion > serverProductVersion) { - throw new Exception($"ServiceControl expects at minimum RavenDB Server version {clientVersion.Major}.{clientVersion.Minor} but the server is using {build.ProductVersion}."); + throw new Exception($"ServiceControl expects RavenDB Server version {clientProductVersion} or higher, but the server is using {serverProductVersion}."); } } } -} \ No newline at end of file +} From 1083f4d5af2ada6adbb155e91d3e1bd81c90d8e3 Mon Sep 17 00:00:00 2001 From: Ramon Smits Date: Tue, 9 Sep 2025 11:19:31 +0200 Subject: [PATCH 3/3] Added information regarding RavenDB version compatibility policy --- src/ServiceControl.RavenDB/StartupChecks.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/ServiceControl.RavenDB/StartupChecks.cs b/src/ServiceControl.RavenDB/StartupChecks.cs index d4182f03bc..e5fb5e92fa 100644 --- a/src/ServiceControl.RavenDB/StartupChecks.cs +++ b/src/ServiceControl.RavenDB/StartupChecks.cs @@ -9,6 +9,16 @@ public static class StartupChecks { public static async Task EnsureServerVersion(IDocumentStore store, CancellationToken cancellationToken = default) { + // RavenDB compatibility policy is that the major/minor version of the server must be + // equal or higher than the client and ignores the patch version. + // + // https://docs.ravendb.net/6.2/client-api/faq/backward-compatibility/#compatibility---ravendb-42-and-higher + // + // > Starting with version 4.2, RavenDB clients are compatible with any server of their own version and higher. + // > E.g. - + // > + // > Client 4.2 is compatible with Server 4.2, Server 4.5, Server 5.2, and any other server of a higher version. + var build = await store.Maintenance.Server.SendAsync(new GetBuildNumberOperation(), cancellationToken); var serverProductVersion = new Version(build.ProductVersion);