diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7e9b1418..efcea7e0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,7 +32,6 @@ jobs: uses: actions/setup-dotnet@v4.0.0 with: dotnet-version: 8.0.x - dotnet-quality: 'preview' - name: Build run: dotnet build src --configuration Release - name: Upload packages @@ -43,7 +42,7 @@ jobs: path: nugets/ retention-days: 7 - name: Setup MongoDB Server - uses: Particular/setup-mongodb-action@v1.3.1 + uses: Particular/setup-mongodb-action@v1.4.0 with: connection-string-name: NServiceBusStorageMongoDB_ConnectionString mongodb-port: 27018 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index dc5cc0e3..6ed92d3d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,7 +21,6 @@ jobs: uses: actions/setup-dotnet@v4.0.0 with: dotnet-version: 8.0.x - dotnet-quality: 'preview' - name: Build run: dotnet build src --configuration Release - name: Sign NuGet packages diff --git a/src/NServiceBus.Storage.MongoDB.AcceptanceTests/NServiceBus.Storage.MongoDB.AcceptanceTests.csproj b/src/NServiceBus.Storage.MongoDB.AcceptanceTests/NServiceBus.Storage.MongoDB.AcceptanceTests.csproj index 01088a28..adf9e957 100644 --- a/src/NServiceBus.Storage.MongoDB.AcceptanceTests/NServiceBus.Storage.MongoDB.AcceptanceTests.csproj +++ b/src/NServiceBus.Storage.MongoDB.AcceptanceTests/NServiceBus.Storage.MongoDB.AcceptanceTests.csproj @@ -11,8 +11,8 @@ - - + + diff --git a/src/NServiceBus.Storage.MongoDB.NoTx.AcceptanceTests/NServiceBus.Storage.MongoDB.NoTx.AcceptanceTests.csproj b/src/NServiceBus.Storage.MongoDB.NoTx.AcceptanceTests/NServiceBus.Storage.MongoDB.NoTx.AcceptanceTests.csproj index 01088a28..adf9e957 100644 --- a/src/NServiceBus.Storage.MongoDB.NoTx.AcceptanceTests/NServiceBus.Storage.MongoDB.NoTx.AcceptanceTests.csproj +++ b/src/NServiceBus.Storage.MongoDB.NoTx.AcceptanceTests/NServiceBus.Storage.MongoDB.NoTx.AcceptanceTests.csproj @@ -11,8 +11,8 @@ - - + + diff --git a/src/NServiceBus.Storage.MongoDB.PersistenceTests/NServiceBus.Storage.MongoDB.PersistenceTests.csproj b/src/NServiceBus.Storage.MongoDB.PersistenceTests/NServiceBus.Storage.MongoDB.PersistenceTests.csproj index d8987433..5ac9f96f 100644 --- a/src/NServiceBus.Storage.MongoDB.PersistenceTests/NServiceBus.Storage.MongoDB.PersistenceTests.csproj +++ b/src/NServiceBus.Storage.MongoDB.PersistenceTests/NServiceBus.Storage.MongoDB.PersistenceTests.csproj @@ -11,8 +11,8 @@ - - + + diff --git a/src/NServiceBus.Storage.MongoDB.Tests/NServiceBus.Storage.MongoDB.Tests.csproj b/src/NServiceBus.Storage.MongoDB.Tests/NServiceBus.Storage.MongoDB.Tests.csproj index 348b5d28..924a2439 100644 --- a/src/NServiceBus.Storage.MongoDB.Tests/NServiceBus.Storage.MongoDB.Tests.csproj +++ b/src/NServiceBus.Storage.MongoDB.Tests/NServiceBus.Storage.MongoDB.Tests.csproj @@ -11,12 +11,12 @@ - - + + - \ No newline at end of file + diff --git a/src/NServiceBus.Storage.MongoDB.TransactionalSession.AcceptanceTests/Infrastructure/TransactionSessionDefaultServer.cs b/src/NServiceBus.Storage.MongoDB.TransactionalSession.AcceptanceTests/Infrastructure/TransactionSessionDefaultServer.cs index 37fe0ecc..1885e803 100644 --- a/src/NServiceBus.Storage.MongoDB.TransactionalSession.AcceptanceTests/Infrastructure/TransactionSessionDefaultServer.cs +++ b/src/NServiceBus.Storage.MongoDB.TransactionalSession.AcceptanceTests/Infrastructure/TransactionSessionDefaultServer.cs @@ -10,38 +10,39 @@ public class TransactionSessionDefaultServer : IEndpointSetupTemplate { - public virtual async Task GetConfiguration(RunDescriptor runDescriptor, EndpointCustomizationConfiguration endpointConfiguration, + public virtual async Task GetConfiguration(RunDescriptor runDescriptor, EndpointCustomizationConfiguration endpointCustomizations, Func configurationBuilderCustomization) { - var builder = new EndpointConfiguration(endpointConfiguration.EndpointName); - builder.EnableInstallers(); + var endpointConfiguration = new EndpointConfiguration(endpointCustomizations.EndpointName); - builder.Recoverability() + endpointConfiguration.EnableInstallers(); + endpointConfiguration.UseSerialization(); + endpointConfiguration.Recoverability() .Delayed(delayed => delayed.NumberOfRetries(0)) .Immediate(immediate => immediate.NumberOfRetries(0)); - builder.SendFailedMessagesTo("error"); + endpointConfiguration.SendFailedMessagesTo("error"); var storageDir = Path.Combine(Path.GetTempPath(), "learn", TestContext.CurrentContext.Test.ID); - builder.UseTransport(new AcceptanceTestingTransport + endpointConfiguration.UseTransport(new AcceptanceTestingTransport { StorageLocation = storageDir }); - var mongoSettings = builder.UsePersistence(); + var mongoSettings = endpointConfiguration.UsePersistence(); mongoSettings.EnableTransactionalSession(); mongoSettings.MongoClient(SetupFixture.MongoClient); mongoSettings.DatabaseName(SetupFixture.DatabaseName); mongoSettings.UseTransactions(true); - builder.RegisterStartupTask(sp => new CaptureServiceProviderStartupTask(sp, runDescriptor.ScenarioContext)); + endpointConfiguration.RegisterStartupTask(sp => new CaptureServiceProviderStartupTask(sp, runDescriptor.ScenarioContext)); - await configurationBuilderCustomization(builder).ConfigureAwait(false); + await configurationBuilderCustomization(endpointConfiguration).ConfigureAwait(false); // scan types at the end so that all types used by the configuration have been loaded into the AppDomain - builder.TypesToIncludeInScan(endpointConfiguration.GetTypesScopedByTestClass()); + endpointConfiguration.TypesToIncludeInScan(endpointCustomizations.GetTypesScopedByTestClass()); - return builder; + return endpointConfiguration; } } } \ No newline at end of file diff --git a/src/NServiceBus.Storage.MongoDB.TransactionalSession.AcceptanceTests/NServiceBus.Storage.MongoDB.TransactionalSession.AcceptanceTests.csproj b/src/NServiceBus.Storage.MongoDB.TransactionalSession.AcceptanceTests/NServiceBus.Storage.MongoDB.TransactionalSession.AcceptanceTests.csproj index 4cd15f04..7414c147 100644 --- a/src/NServiceBus.Storage.MongoDB.TransactionalSession.AcceptanceTests/NServiceBus.Storage.MongoDB.TransactionalSession.AcceptanceTests.csproj +++ b/src/NServiceBus.Storage.MongoDB.TransactionalSession.AcceptanceTests/NServiceBus.Storage.MongoDB.TransactionalSession.AcceptanceTests.csproj @@ -13,9 +13,9 @@ - - - + + + diff --git a/src/NServiceBus.Storage.MongoDB.TransactionalSession.Tests/NServiceBus.Storage.MongoDB.TransactionalSession.Tests.csproj b/src/NServiceBus.Storage.MongoDB.TransactionalSession.Tests/NServiceBus.Storage.MongoDB.TransactionalSession.Tests.csproj index c36e4cfd..91d45c96 100644 --- a/src/NServiceBus.Storage.MongoDB.TransactionalSession.Tests/NServiceBus.Storage.MongoDB.TransactionalSession.Tests.csproj +++ b/src/NServiceBus.Storage.MongoDB.TransactionalSession.Tests/NServiceBus.Storage.MongoDB.TransactionalSession.Tests.csproj @@ -16,11 +16,11 @@ - - - + + + - \ No newline at end of file + diff --git a/src/NServiceBus.Storage.MongoDB.TransactionalSession/NServiceBus.Storage.MongoDB.TransactionalSession.csproj b/src/NServiceBus.Storage.MongoDB.TransactionalSession/NServiceBus.Storage.MongoDB.TransactionalSession.csproj index 23308247..7f2680d5 100644 --- a/src/NServiceBus.Storage.MongoDB.TransactionalSession/NServiceBus.Storage.MongoDB.TransactionalSession.csproj +++ b/src/NServiceBus.Storage.MongoDB.TransactionalSession/NServiceBus.Storage.MongoDB.TransactionalSession.csproj @@ -12,8 +12,8 @@ - + - \ No newline at end of file + diff --git a/src/NServiceBus.Storage.MongoDB.sln b/src/NServiceBus.Storage.MongoDB.sln index a22fcb35..94bc21ad 100644 --- a/src/NServiceBus.Storage.MongoDB.sln +++ b/src/NServiceBus.Storage.MongoDB.sln @@ -9,7 +9,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NServiceBus.Storage.MongoDB EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{204B96DD-7CDD-498E-B527-2CA09B17AD6D}" ProjectSection(SolutionItems) = preProject + ..\.github\workflows\ci.yml = ..\.github\workflows\ci.yml Custom.Build.props = Custom.Build.props + ..\.github\workflows\release.yml = ..\.github\workflows\release.yml EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NServiceBus.Storage.MongoDB.AcceptanceTests", "NServiceBus.Storage.MongoDB.AcceptanceTests\NServiceBus.Storage.MongoDB.AcceptanceTests.csproj", "{6BCA8AC9-E4BC-4920-BA3F-C218708B8A6B}" @@ -22,7 +24,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NServiceBus.Storage.MongoDB EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NServiceBus.Storage.MongoDB.TransactionalSession.AcceptanceTests", "NServiceBus.Storage.MongoDB.TransactionalSession.AcceptanceTests\NServiceBus.Storage.MongoDB.TransactionalSession.AcceptanceTests.csproj", "{704337C7-74B5-435A-88C7-AC0E10EA7795}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NServiceBus.Storage.MongoDB.TransactionalSession.Tests", "NServiceBus.Storage.MongoDB.TransactionalSession.Tests\NServiceBus.Storage.MongoDB.TransactionalSession.Tests.csproj", "{C9FA6374-432B-4E58-AC5C-7C86FEAA9256}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NServiceBus.Storage.MongoDB.TransactionalSession.Tests", "NServiceBus.Storage.MongoDB.TransactionalSession.Tests\NServiceBus.Storage.MongoDB.TransactionalSession.Tests.csproj", "{C9FA6374-432B-4E58-AC5C-7C86FEAA9256}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/src/NServiceBus.Storage.MongoDB/Configuration/CompatibilitySettings.cs b/src/NServiceBus.Storage.MongoDB/Configuration/CompatibilitySettings.cs index 001ef11e..b1b7a162 100644 --- a/src/NServiceBus.Storage.MongoDB/Configuration/CompatibilitySettings.cs +++ b/src/NServiceBus.Storage.MongoDB/Configuration/CompatibilitySettings.cs @@ -19,7 +19,7 @@ internal CompatibilitySettings(SettingsHolder settingsHolder) : base(settingsHol /// public CompatibilitySettings VersionElementName(string versionElementName) { - Guard.AgainstNullAndEmpty(nameof(versionElementName), versionElementName); + ArgumentException.ThrowIfNullOrWhiteSpace(versionElementName); this.GetSettings().Set(SettingsKeys.VersionElementName, versionElementName); return this; @@ -30,7 +30,7 @@ public CompatibilitySettings VersionElementName(string versionElementName) /// public CompatibilitySettings CollectionNamingConvention(Func collectionNamingConvention) { - Guard.AgainstNull(nameof(collectionNamingConvention), collectionNamingConvention); + ArgumentNullException.ThrowIfNull(collectionNamingConvention); this.GetSettings().Set(SettingsKeys.CollectionNamingConvention, collectionNamingConvention); return this; diff --git a/src/NServiceBus.Storage.MongoDB/Configuration/MongoSettingsExtensions.cs b/src/NServiceBus.Storage.MongoDB/Configuration/MongoSettingsExtensions.cs index b594002d..df4a93fc 100644 --- a/src/NServiceBus.Storage.MongoDB/Configuration/MongoSettingsExtensions.cs +++ b/src/NServiceBus.Storage.MongoDB/Configuration/MongoSettingsExtensions.cs @@ -15,8 +15,8 @@ public static class MongoSettingsExtensions /// public static PersistenceExtensions MongoClient(this PersistenceExtensions persistenceExtensions, IMongoClient mongoClient) { - Guard.AgainstNull(nameof(persistenceExtensions), persistenceExtensions); - Guard.AgainstNull(nameof(mongoClient), mongoClient); + ArgumentNullException.ThrowIfNull(persistenceExtensions); + ArgumentNullException.ThrowIfNull(mongoClient); persistenceExtensions.GetSettings().Set(SettingsKeys.MongoClient, () => mongoClient); return persistenceExtensions; @@ -27,8 +27,8 @@ public static PersistenceExtensions MongoClient(this Persisten /// public static PersistenceExtensions DatabaseName(this PersistenceExtensions persistenceExtensions, string databaseName) { - Guard.AgainstNull(nameof(persistenceExtensions), persistenceExtensions); - Guard.AgainstNullAndEmpty(nameof(databaseName), databaseName); + ArgumentNullException.ThrowIfNull(persistenceExtensions); + ArgumentException.ThrowIfNullOrWhiteSpace(databaseName); persistenceExtensions.GetSettings().Set(SettingsKeys.DatabaseName, databaseName); return persistenceExtensions; @@ -39,7 +39,7 @@ public static PersistenceExtensions DatabaseName(this Persiste /// public static PersistenceExtensions UseTransactions(this PersistenceExtensions persistenceExtensions, bool useTransactions) { - Guard.AgainstNull(nameof(persistenceExtensions), persistenceExtensions); + ArgumentNullException.ThrowIfNull(persistenceExtensions); persistenceExtensions.GetSettings().Set(SettingsKeys.UseTransactions, useTransactions); return persistenceExtensions; @@ -50,8 +50,8 @@ public static PersistenceExtensions UseTransactions(this Persi /// public static PersistenceExtensions TimeToKeepOutboxDeduplicationData(this PersistenceExtensions persistenceExtensions, TimeSpan timeToKeepOutboxDeduplicationData) { - Guard.AgainstNull(nameof(persistenceExtensions), persistenceExtensions); - Guard.AgainstNegativeAndZero(nameof(timeToKeepOutboxDeduplicationData), timeToKeepOutboxDeduplicationData); + ArgumentNullException.ThrowIfNull(persistenceExtensions); + ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(timeToKeepOutboxDeduplicationData, TimeSpan.Zero); var seconds = Math.Ceiling(timeToKeepOutboxDeduplicationData.TotalSeconds); diff --git a/src/NServiceBus.Storage.MongoDB/NServiceBus.Storage.MongoDB.csproj b/src/NServiceBus.Storage.MongoDB/NServiceBus.Storage.MongoDB.csproj index 9cb2b2de..1c5124d1 100644 --- a/src/NServiceBus.Storage.MongoDB/NServiceBus.Storage.MongoDB.csproj +++ b/src/NServiceBus.Storage.MongoDB/NServiceBus.Storage.MongoDB.csproj @@ -1,12 +1,12 @@ - + net8.0 - - + + @@ -15,4 +15,4 @@ - \ No newline at end of file + diff --git a/src/NServiceBus.Storage.MongoDB/SynchronizedStorage/SynchronizedStorage.cs b/src/NServiceBus.Storage.MongoDB/SynchronizedStorage/SynchronizedStorage.cs index aae05d5d..5a8e26c9 100644 --- a/src/NServiceBus.Storage.MongoDB/SynchronizedStorage/SynchronizedStorage.cs +++ b/src/NServiceBus.Storage.MongoDB/SynchronizedStorage/SynchronizedStorage.cs @@ -26,41 +26,40 @@ protected override void Setup(FeatureConfigurationContext context) try { - client.GetDatabase(databaseName); - } - catch (ArgumentException ex) - { - throw new Exception($"The persistence database name '{databaseName}' is invalid. Configure a valid database name by calling 'EndpointConfiguration.UsePersistence<{nameof(MongoPersistence)}>().DatabaseName(databaseName)'.", ex); - } + var database = client.GetDatabase(databaseName); - try - { - using (var session = client.StartSession()) + // perform a query to the server to make sure cluster details are loaded + database.ListCollectionNames(); + + using var session = client.StartSession(); + + if (useTransactions) { - if (useTransactions) - { - var clusterType = client.Cluster.Description.Type; + var clusterType = client.Cluster.Description.Type; - //HINT: cluster configuration check is needed as the built-in checks, executed during "StartTransaction() call, - // do not detect if the cluster configuration is a supported one. Only the version ranges are validated. - // Without this check, exceptions will be thrown during message processing. - if (clusterType is not ClusterType.ReplicaSet and not ClusterType.Sharded) - { - throw new Exception($"Transactions are only supported on replica sets or sharded clusters. Disable support for transactions by calling 'EndpointConfiguration.UsePersistence<{nameof(MongoPersistence)}>().UseTransactions(false)'."); - } + //HINT: cluster configuration check is needed as the built-in checks, executed during "StartTransaction() call, + // do not detect if the cluster configuration is a supported one. Only the version ranges are validated. + // Without this check, exceptions will be thrown during message processing. + if (clusterType is not ClusterType.ReplicaSet and not ClusterType.Sharded) + { + throw new Exception($"The cluster type in use is {clusterType}, but transactions are only supported on replica sets or sharded clusters. Disable support for transactions by calling 'EndpointConfiguration.UsePersistence<{nameof(MongoPersistence)}>().UseTransactions(false)'."); + } - try - { - session.StartTransaction(); - session.AbortTransaction(); - } - catch (NotSupportedException ex) - { - throw new Exception($"Transactions are not supported by the MongoDB server. Disable support for transactions by calling 'EndpointConfiguration.UsePersistence<{nameof(MongoPersistence)}>().UseTransactions(false)'.", ex); - } + try + { + session.StartTransaction(); + session.AbortTransaction(); + } + catch (NotSupportedException ex) + { + throw new Exception($"Transactions are not supported by the MongoDB server. Disable support for transactions by calling 'EndpointConfiguration.UsePersistence<{nameof(MongoPersistence)}>().UseTransactions(false)'.", ex); } } } + catch (ArgumentException ex) + { + throw new Exception($"The persistence database name '{databaseName}' is invalid. Configure a valid database name by calling 'EndpointConfiguration.UsePersistence<{nameof(MongoPersistence)}>().DatabaseName(databaseName)'.", ex); + } catch (NotSupportedException ex) { throw new Exception("Sessions are not supported by the MongoDB server. The NServiceBus.Storage.MongoDB persistence requires MongoDB server version 3.6 or greater.", ex); diff --git a/src/NServiceBus.Storage.MongoDB/SynchronizedStorage/SynchronizedStorageSessionExtensions.cs b/src/NServiceBus.Storage.MongoDB/SynchronizedStorage/SynchronizedStorageSessionExtensions.cs index 61de1df1..4cd9f6dc 100644 --- a/src/NServiceBus.Storage.MongoDB/SynchronizedStorage/SynchronizedStorageSessionExtensions.cs +++ b/src/NServiceBus.Storage.MongoDB/SynchronizedStorage/SynchronizedStorageSessionExtensions.cs @@ -21,7 +21,7 @@ public static IClientSessionHandle GetClientSession(this ISynchronizedStorageSes /// public static IMongoSynchronizedStorageSession MongoPersistenceSession(this ISynchronizedStorageSession session) { - Guard.AgainstNull(nameof(session), session); + ArgumentNullException.ThrowIfNull(session); if (session is IMongoSynchronizedStorageSession mongoSession) { diff --git a/src/NServiceBus.Storage.MongoDB/Utils/Guard.cs b/src/NServiceBus.Storage.MongoDB/Utils/Guard.cs deleted file mode 100644 index 25d1461a..00000000 --- a/src/NServiceBus.Storage.MongoDB/Utils/Guard.cs +++ /dev/null @@ -1,81 +0,0 @@ -namespace NServiceBus.Storage.MongoDB -{ - using System; - using System.Collections; - using System.Linq; - using System.Reflection; - - static class Guard - { - public static void TypeHasDefaultConstructor(Type type, string argumentName) - { - if (type.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) - .All(ctor => ctor.GetParameters().Length != 0)) - { - var error = $"Type '{type.FullName}' must have a default constructor."; - throw new ArgumentException(error, argumentName); - } - } - - public static void AgainstNull(string argumentName, object value) - { - if (value == null) - { - throw new ArgumentNullException(argumentName); - } - } - - public static void AgainstNullAndEmpty(string argumentName, string value) - { - if (string.IsNullOrWhiteSpace(value)) - { - throw new ArgumentNullException(argumentName); - } - } - - public static void AgainstNullAndEmpty(string argumentName, ICollection value) - { - if (value == null) - { - throw new ArgumentNullException(argumentName); - } - - if (value.Count == 0) - { - throw new ArgumentOutOfRangeException(argumentName); - } - } - - public static void AgainstNegativeAndZero(string argumentName, int value) - { - if (value <= 0) - { - throw new ArgumentOutOfRangeException(argumentName); - } - } - - public static void AgainstNegative(string argumentName, int value) - { - if (value < 0) - { - throw new ArgumentOutOfRangeException(argumentName); - } - } - - public static void AgainstNegativeAndZero(string argumentName, TimeSpan value) - { - if (value <= TimeSpan.Zero) - { - throw new ArgumentOutOfRangeException(argumentName); - } - } - - public static void AgainstNegative(string argumentName, TimeSpan value) - { - if (value < TimeSpan.Zero) - { - throw new ArgumentOutOfRangeException(argumentName); - } - } - } -} \ No newline at end of file