From e81e25c6ff752bbaef3e06a1d56d9fe8bf3a164c Mon Sep 17 00:00:00 2001 From: Mauro Servienti Date: Thu, 14 Dec 2023 14:25:35 +0100 Subject: [PATCH] Rename to Maddox.NServiceBus and introduce the separation between configuration manager and endpoint (#31) * Some ideas * Introduce configuration managers and endpoints as different classes with different responsibilities * Rename to Maddox.NServiceBus * Rename NuGet package --- README.md | 16 +- docs/README.md | 2 +- .../LearningEndpointTests.cs | 9 +- .../Maddox.NServiceBus.Tests.csproj} | 2 +- .../Usings.cs | 0 .../endpoint.settings.json | 0 ...s.Endpoints.sln => Maddox.NServiceBus.sln} | 4 +- .../EndpointConfigurationManager.cs | 165 ++++++++++++++++++ src/Maddox.NServiceBus/LearningEndpoint.cs | 14 ++ .../LearningEndpointConfigurationManager.cs | 25 +++ .../Maddox.NServiceBus.csproj} | 4 +- src/Maddox.NServiceBus/NServiceBusEndpoint.cs | 72 ++++++++ .../LearningEndpoint.cs | 22 --- .../NServiceBusEndpoint.cs | 159 ----------------- 14 files changed, 295 insertions(+), 199 deletions(-) rename src/{NServiceBoXes.Endpoints.Tests => Maddox.NServiceBus.Tests}/LearningEndpointTests.cs (93%) rename src/{NServiceBoXes.Endpoints.Tests/NServiceBoXes.Endpoints.Tests.csproj => Maddox.NServiceBus.Tests/Maddox.NServiceBus.Tests.csproj} (93%) rename src/{NServiceBoXes.Endpoints.Tests => Maddox.NServiceBus.Tests}/Usings.cs (100%) rename src/{NServiceBoXes.Endpoints.Tests => Maddox.NServiceBus.Tests}/endpoint.settings.json (100%) rename src/{NServiceBoXes.Endpoints.sln => Maddox.NServiceBus.sln} (72%) create mode 100644 src/Maddox.NServiceBus/EndpointConfigurationManager.cs create mode 100644 src/Maddox.NServiceBus/LearningEndpoint.cs create mode 100644 src/Maddox.NServiceBus/LearningEndpointConfigurationManager.cs rename src/{NServiceBoXes.Endpoints/NServiceBoXes.Endpoints.csproj => Maddox.NServiceBus/Maddox.NServiceBus.csproj} (92%) create mode 100644 src/Maddox.NServiceBus/NServiceBusEndpoint.cs delete mode 100644 src/NServiceBoXes.Endpoints.Tests/LearningEndpoint.cs delete mode 100644 src/NServiceBoXes.Endpoints/NServiceBusEndpoint.cs diff --git a/README.md b/README.md index b8763be..c15e05b 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -# NServiceBoXes.Endpoints +# Maddox.NServiceBus -NServiceBoXes Endpoints simplify [NServiceBus endpoints](https://docs.particular.net/nservicebus/) configuration by providing for supported transports a corresponding NServiceBoXes endpoint with sensible defaults. For example, creating and starting a RabbitMQ endpoint could be as easy as: +Maddox simplifies [NServiceBus endpoints](https://docs.particular.net/nservicebus/) configuration by providing for supported transports a corresponding Maddox endpoint with sensible defaults. For example, creating and starting a RabbitMQ endpoint could be as easy as: ```csharp var endpoint = new RabbitMqEndpoint("my-endpoint", connectionString: "host=localhost"); @@ -11,7 +11,7 @@ var endpointInstance = await endpoint.Start(); ## Microsoft configuration extension support -NServiceBoXes endpoints can be configured through the [`Microsoft.Extensions.Configuration`](https://www.nuget.org/packages/Microsoft.Extensions.Configuration). The above-presented RabbitMQ endpoint can be configured as follows: +Maddox.NServiceBus can be configured through the [`Microsoft.Extensions.Configuration`](https://www.nuget.org/packages/Microsoft.Extensions.Configuration). The above-presented RabbitMQ endpoint can be configured as follows: ```csharp Host.CreateDefaultBuilder() @@ -19,21 +19,21 @@ Host.CreateDefaultBuilder() .Build(); ``` -The endpoint will retrieve values from the `IConfiguration` object instance. For more information, refer to the [NServiceBoXes.Endpoints configuration options docmentation](/docs). +The endpoint will retrieve values from the `IConfiguration` object instance. For more information, refer to the [Maddox.NServiceBus configuration options docmentation](/docs). ## Supported endpoints -- [NServiceBoXes.Endpoints.AmazonSQS](https://github.com/mauroservienti/NServiceBoXes.Endpoints.AmazonSQS) -- [NServiceBoXes.Endpoints.RabbitMQ](https://github.com/mauroservienti/NServiceBoXes.Endpoints.RabbitMQ) +- [Maddox.NServiceBus.AmazonSQS](https://github.com/mauroservienti/Maddox.NServiceBus.AmazonSQS) +- [Maddox.NServiceBus.RabbitMQ](https://github.com/mauroservienti/Maddox.NServiceBus.RabbitMQ) ## How to get it - Pre-releases are available on [Feedz.io](https://feedz.io/) ([public feed](https://f.feedz.io/mauroservienti/pre-releases/nuget/index.json)) -- Releases on [NuGet.org](https://www.nuget.org/packages?q=NServiceBoXes) +- Releases on [NuGet.org](https://www.nuget.org/packages?q=Maddox) ## NOTE -> This package is not meant to be used directly. It serves as a base package for other NServiceBoXes Endpoints, such as [NServiceBoXes.Endpoints.AmazonSQS](https://github.com/mauroservienti/NServiceBoXes.Endpoints.AmazonSQS), [NServiceBoXes.Endpoints.RabbitMQ](https://github.com/mauroservienti/NServiceBoXes.Endpoints.RabbitMQ), and many more. +> This package is not meant to be used directly. It serves as a base package for other Maddox.NServiceBus Endpoints, such as [Maddox.NServiceBus.AmazonSQS](https://github.com/mauroservienti/Maddox.NServiceBus.AmazonSQS) or [Maddox.NServiceBus.Endpoints.RabbitMQ](https://github.com/mauroservienti/Maddox.NServiceBus.RabbitMQ). --- diff --git a/docs/README.md b/docs/README.md index b5d5e98..9bd8e93 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,6 +1,6 @@ # Configuration -NServiceBoXes endpoints can be configured through the [`Microsoft.Extensions.Configuration`](https://www.nuget.org/packages/Microsoft.Extensions.Configuration). All settings are defined in the `NServiceBus:EndpointConfiguration` section. Different endpoints supporting different transport may define additional settings. Refer to the endpoint-specific documentation for more details. +Maddox.NServiceBus endpoints can be configured through the [`Microsoft.Extensions.Configuration`](https://www.nuget.org/packages/Microsoft.Extensions.Configuration). All settings are defined in the `NServiceBus:EndpointConfiguration` section. Different endpoints supporting different transport may define additional settings. Refer to the endpoint-specific documentation for more details. ## Endpoint name diff --git a/src/NServiceBoXes.Endpoints.Tests/LearningEndpointTests.cs b/src/Maddox.NServiceBus.Tests/LearningEndpointTests.cs similarity index 93% rename from src/NServiceBoXes.Endpoints.Tests/LearningEndpointTests.cs rename to src/Maddox.NServiceBus.Tests/LearningEndpointTests.cs index ee8b7cb..cf6b581 100644 --- a/src/NServiceBoXes.Endpoints.Tests/LearningEndpointTests.cs +++ b/src/Maddox.NServiceBus.Tests/LearningEndpointTests.cs @@ -1,14 +1,15 @@ using Microsoft.Extensions.Configuration; +using NServiceBus; using NServiceBus.Configuration.AdvancedExtensibility; -namespace NServiceBoXes.Endpoints.Tests; +namespace Maddox.NServiceBus.Tests; public class LearningEndpointTests { [Fact] public void Basic_endpoint_respect_name_and_default_values() { - var expectedEndpointName = "my-endpoint"; + const string expectedEndpointName = "my-endpoint"; var endpoint = new LearningEndpoint(expectedEndpointName); EndpointConfiguration endpointConfiguration = endpoint; @@ -20,7 +21,7 @@ public void Basic_endpoint_respect_name_and_default_values() [Fact] public void Using_json_configuration_respect_settings() { - var expectedEndpointName = "my-endpoint"; + const string expectedEndpointName = "my-endpoint"; var config = new ConfigurationBuilder() .AddJsonFile("endpoint.settings.json") @@ -44,7 +45,7 @@ public void Using_json_configuration_respect_settings() [Fact] public void Using_env_var_configuration_respect_endpoint_name() { - var expectedEndpointName = "my-endpoint"; + const string expectedEndpointName = "my-endpoint"; Environment.SetEnvironmentVariable("NServiceBus:EndpointConfiguration:EndpointName", expectedEndpointName); var config = new ConfigurationBuilder() diff --git a/src/NServiceBoXes.Endpoints.Tests/NServiceBoXes.Endpoints.Tests.csproj b/src/Maddox.NServiceBus.Tests/Maddox.NServiceBus.Tests.csproj similarity index 93% rename from src/NServiceBoXes.Endpoints.Tests/NServiceBoXes.Endpoints.Tests.csproj rename to src/Maddox.NServiceBus.Tests/Maddox.NServiceBus.Tests.csproj index 5086312..440fbc9 100644 --- a/src/NServiceBoXes.Endpoints.Tests/NServiceBoXes.Endpoints.Tests.csproj +++ b/src/Maddox.NServiceBus.Tests/Maddox.NServiceBus.Tests.csproj @@ -27,7 +27,7 @@ - + diff --git a/src/NServiceBoXes.Endpoints.Tests/Usings.cs b/src/Maddox.NServiceBus.Tests/Usings.cs similarity index 100% rename from src/NServiceBoXes.Endpoints.Tests/Usings.cs rename to src/Maddox.NServiceBus.Tests/Usings.cs diff --git a/src/NServiceBoXes.Endpoints.Tests/endpoint.settings.json b/src/Maddox.NServiceBus.Tests/endpoint.settings.json similarity index 100% rename from src/NServiceBoXes.Endpoints.Tests/endpoint.settings.json rename to src/Maddox.NServiceBus.Tests/endpoint.settings.json diff --git a/src/NServiceBoXes.Endpoints.sln b/src/Maddox.NServiceBus.sln similarity index 72% rename from src/NServiceBoXes.Endpoints.sln rename to src/Maddox.NServiceBus.sln index 6164238..3cc3e33 100644 --- a/src/NServiceBoXes.Endpoints.sln +++ b/src/Maddox.NServiceBus.sln @@ -1,8 +1,8 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NServiceBoXes.Endpoints", "NServiceBoXes.Endpoints\NServiceBoXes.Endpoints.csproj", "{96B64204-3CA7-4DCD-B2B1-472C68C8548E}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Maddox.NServiceBus", "Maddox.NServiceBus\Maddox.NServiceBus.csproj", "{96B64204-3CA7-4DCD-B2B1-472C68C8548E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NServiceBoXes.Endpoints.Tests", "NServiceBoXes.Endpoints.Tests\NServiceBoXes.Endpoints.Tests.csproj", "{4A3D3957-A397-48E5-88A5-800DC7CE1705}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Maddox.NServiceBus.Tests", "Maddox.NServiceBus.Tests\Maddox.NServiceBus.Tests.csproj", "{4A3D3957-A397-48E5-88A5-800DC7CE1705}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/src/Maddox.NServiceBus/EndpointConfigurationManager.cs b/src/Maddox.NServiceBus/EndpointConfigurationManager.cs new file mode 100644 index 0000000..bcf0bce --- /dev/null +++ b/src/Maddox.NServiceBus/EndpointConfigurationManager.cs @@ -0,0 +1,165 @@ +using Microsoft.Extensions.Configuration; +using NServiceBus.Serialization; +using NServiceBus.Transport; + +namespace Maddox.NServiceBus; + +public abstract class EndpointConfigurationManager + where TTransport : TransportDefinition +{ + const string NServiceBusEndpointConfigurationSectionName = "NServiceBus:EndpointConfiguration"; + Action? transportCustomization; + Func? transportFactory; + bool _useDefaultSerializer = true; + Action>? _serializerCustomization; + EndpointConfiguration _endpointConfiguration = null!; + + static void ConfigureAuditing(EndpointConfiguration endpointConfiguration, IConfigurationSection? endpointConfigurationSection) + { + var auditSection = endpointConfigurationSection?.GetSection("Auditing"); + var enableAuditing = bool.Parse(auditSection?["Enabled"] ?? true.ToString()); + if (!enableAuditing) + { + return; + } + + var auditQueue = auditSection?["AuditQueue"] ?? "audit"; + endpointConfiguration.AuditProcessedMessagesTo(auditQueue); + } + + static void ConfigureRecoverability(EndpointConfiguration endpointConfiguration, IConfigurationSection? endpointConfigurationSection) + { + var recoverabilitySection = endpointConfigurationSection?.GetSection("Recoverability"); + + var errorQueue = recoverabilitySection?["ErrorQueue"] ?? "error"; + endpointConfiguration.SendFailedMessagesTo(errorQueue); + + var recoverabilityConfiguration = endpointConfiguration.Recoverability(); + + if (recoverabilitySection?.GetSection("Immediate") is { } immediateSection) + { + recoverabilityConfiguration.Immediate( + immediate => + { + if(immediateSection["NumberOfRetries"] is {} numberOfRetries) + { + immediate.NumberOfRetries(int.Parse(numberOfRetries)); + } + }); + } + + if(recoverabilitySection?.GetSection("Delayed") is { } delayedSection) + { + recoverabilityConfiguration.Delayed( + delayed => + { + if(delayedSection["NumberOfRetries"] is { } numberOfRetries) + { + delayed.NumberOfRetries(int.Parse(numberOfRetries)); + } + + if (delayedSection["TimeIncrease"] is {} timeIncrease) + {; + delayed.TimeIncrease(TimeSpan.Parse(timeIncrease)); + } + }); + } + } + + protected abstract TTransport CreateTransport(IConfigurationSection? transportConfigurationSection); + + protected static void ApplyCommonTransportSettings(IConfigurationSection? transportConfigurationSection, + TransportDefinition transport) + { + if (transportConfigurationSection?["TransportTransactionMode"] is { } transportTransactionMode) + { + Enum.TryParse(transportTransactionMode, ignoreCase: false, out TransportTransactionMode ttm); + transport.TransportTransactionMode = ttm; + } + } + + public void CustomizeTransport(Action transport) + { + this.transportCustomization = transport; + } + + public void OverrideTransport(Func factory) + { + this.transportFactory = factory; + } + + public SerializationExtensions ReplaceDefaultSerializer() where T : SerializationDefinition, new() + { + _useDefaultSerializer = false; + return _endpointConfiguration.UseSerialization(); + } + + public void CustomizeDefaultSerializer(Action>? serializerCustomization) + { + _serializerCustomization = serializerCustomization; + } + + void Customize(EndpointConfiguration endpointConfiguration, + IConfigurationSection? endpointConfigurationSection) + { + ConfigureAuditing(endpointConfiguration, endpointConfigurationSection); + ConfigureRecoverability(endpointConfiguration, endpointConfigurationSection); + + // create and configure the transport + var transport = transportFactory != null ? transportFactory(endpointConfigurationSection) : CreateTransport(endpointConfigurationSection?.GetSection("Transport")); + transportCustomization?.Invoke(transport); + endpointConfiguration.UseTransport(transport); + + // TODO create and configure the persistence + + if (_useDefaultSerializer) + { + var serializerConfiguration = endpointConfiguration.UseSerialization(); + _serializerCustomization?.Invoke(serializerConfiguration); + } + } + + static IConfigurationSection GetMandatoryEndpointConfigurationSection(IConfiguration configuration) + { + var endpointConfigurationSection = configuration.GetSection(NServiceBusEndpointConfigurationSectionName); + if (endpointConfigurationSection == null) + throw new Exception($"Cannot find the required '{NServiceBusEndpointConfigurationSectionName}' configuration section"); + + return endpointConfigurationSection; + } + + static string GetMandatoryEndpointName(IConfigurationSection endpointConfigurationSection) + { + return endpointConfigurationSection["EndpointName"] + ?? throw new ArgumentException( + "EndpointName cannot be null. Make sure the " + + $"{NServiceBusEndpointConfigurationSectionName}:EndpointName configuration value is set."); + } + + public EndpointConfiguration CreateEndpointConfiguration(string endpointName, IConfiguration? configuration) + { + if (string.IsNullOrWhiteSpace(endpointName)) + throw new ArgumentException("Endpoint name is required and cannot be empty", nameof(endpointName)); + + _endpointConfiguration = new EndpointConfiguration(endpointName); + + var endpointConfigurationSection = configuration?.GetSection(NServiceBusEndpointConfigurationSectionName); + Customize(_endpointConfiguration, endpointConfigurationSection); + + return _endpointConfiguration; + } + + public EndpointConfiguration CreateEndpointConfiguration(IConfiguration configuration) + { + if (configuration == null) throw new ArgumentNullException(nameof(configuration)); + + var endpointConfigurationSection = GetMandatoryEndpointConfigurationSection(configuration); + var endpointName = GetMandatoryEndpointName(endpointConfigurationSection); + + _endpointConfiguration = new EndpointConfiguration(endpointName); + + Customize(_endpointConfiguration, endpointConfigurationSection); + + return _endpointConfiguration; + } +} \ No newline at end of file diff --git a/src/Maddox.NServiceBus/LearningEndpoint.cs b/src/Maddox.NServiceBus/LearningEndpoint.cs new file mode 100644 index 0000000..90121cc --- /dev/null +++ b/src/Maddox.NServiceBus/LearningEndpoint.cs @@ -0,0 +1,14 @@ +using Microsoft.Extensions.Configuration; + +namespace Maddox.NServiceBus; + +public class LearningEndpoint : NServiceBusEndpoint +{ + public LearningEndpoint(IConfiguration configuration) : base(configuration) + { + } + + public LearningEndpoint(string endpointName, IConfiguration? configuration = null) : base(endpointName, configuration) + { + } +} \ No newline at end of file diff --git a/src/Maddox.NServiceBus/LearningEndpointConfigurationManager.cs b/src/Maddox.NServiceBus/LearningEndpointConfigurationManager.cs new file mode 100644 index 0000000..914d7bf --- /dev/null +++ b/src/Maddox.NServiceBus/LearningEndpointConfigurationManager.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Configuration; + +namespace Maddox.NServiceBus; + +public class LearningEndpointConfigurationManager : EndpointConfigurationManager +{ + protected override LearningTransport CreateTransport(IConfigurationSection? transportConfigurationSection) + { + LearningTransport transport = new (); + + ApplyCommonTransportSettings(transportConfigurationSection, transport); + + if (transportConfigurationSection?["StorageDirectory"] is { } storageDirectory) + { + transport.StorageDirectory = storageDirectory; + } + + if (transportConfigurationSection?["RestrictPayloadSize"] is { } restrictPayloadSize) + { + transport.RestrictPayloadSize = bool.Parse(restrictPayloadSize); + } + + return transport; + } +} \ No newline at end of file diff --git a/src/NServiceBoXes.Endpoints/NServiceBoXes.Endpoints.csproj b/src/Maddox.NServiceBus/Maddox.NServiceBus.csproj similarity index 92% rename from src/NServiceBoXes.Endpoints/NServiceBoXes.Endpoints.csproj rename to src/Maddox.NServiceBus/Maddox.NServiceBus.csproj index 963b647..ba670c0 100644 --- a/src/NServiceBoXes.Endpoints/NServiceBoXes.Endpoints.csproj +++ b/src/Maddox.NServiceBus/Maddox.NServiceBus.csproj @@ -8,10 +8,10 @@ Mauro Servienti - NServiceBoXes Endpoints + Maddox.NServiceBus Apache-2.0 icon.png - NServiceBus NServiceBoXes Endpoints + Maddox NServiceBus Endpoints true $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb true diff --git a/src/Maddox.NServiceBus/NServiceBusEndpoint.cs b/src/Maddox.NServiceBus/NServiceBusEndpoint.cs new file mode 100644 index 0000000..c725243 --- /dev/null +++ b/src/Maddox.NServiceBus/NServiceBusEndpoint.cs @@ -0,0 +1,72 @@ +using Microsoft.Extensions.Configuration; +using NServiceBus.Persistence; +using NServiceBus.Serialization; +using NServiceBus.Transport; + +namespace Maddox.NServiceBus; + +public abstract class NServiceBusEndpoint + where TTransport : TransportDefinition + where TEndpointConfigurationManager : EndpointConfigurationManager, new() +{ + readonly EndpointConfiguration _endpointConfiguration; + readonly TEndpointConfigurationManager _configurationManager; + + protected NServiceBusEndpoint(IConfiguration configuration) + { + _configurationManager = new TEndpointConfigurationManager(); + _endpointConfiguration = _configurationManager.CreateEndpointConfiguration(configuration); + } + + protected NServiceBusEndpoint(string endpointName, IConfiguration? configuration = null) + { + if (endpointName == null) throw new ArgumentNullException(nameof(endpointName)); + + _configurationManager = new TEndpointConfigurationManager(); + _endpointConfiguration = _configurationManager.CreateEndpointConfiguration(endpointName, configuration); + } + + public static implicit operator EndpointConfiguration(NServiceBusEndpoint endpoint) + { + return endpoint._endpointConfiguration; + } + + public PersistenceExtensions UsePersistence() + where T : PersistenceDefinition + { + return _endpointConfiguration.UsePersistence(); + } + + public PersistenceExtensions UsePersistence() + where T : PersistenceDefinition + where S : StorageType + { + return _endpointConfiguration.UsePersistence(); + } + + public SerializationExtensions ReplaceDefaultSerializer() where T : SerializationDefinition, new() + { + return _configurationManager.ReplaceDefaultSerializer(); + } + + public void CustomizeDefaultSerializer(Action>? serializerCustomization) + { + _configurationManager.CustomizeDefaultSerializer(serializerCustomization); + } + + public void CustomizeTransport(Action transportCustomization) + { + _configurationManager.CustomizeTransport(transportCustomization); + } + + public void OverrideTransport(Func transportFactory) + { + _configurationManager.OverrideTransport(transportFactory); + } + + public async Task Start() + { + var endpointInstance = await Endpoint.Start(_endpointConfiguration).ConfigureAwait(false); + return endpointInstance; + } +} \ No newline at end of file diff --git a/src/NServiceBoXes.Endpoints.Tests/LearningEndpoint.cs b/src/NServiceBoXes.Endpoints.Tests/LearningEndpoint.cs deleted file mode 100644 index 040a512..0000000 --- a/src/NServiceBoXes.Endpoints.Tests/LearningEndpoint.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Microsoft.Extensions.Configuration; -using NServiceBus; - -namespace NServiceBoXes.Endpoints.Tests; - -public class LearningEndpoint : NServiceBusEndpoint -{ - public LearningEndpoint(IConfiguration configuration) - : base(GetEndpointNameFromConfigurationOrThrow(configuration), configuration) - { - } - - public LearningEndpoint(string endpointName, IConfiguration? configuration = null) - : base(endpointName, configuration) - { - } - - protected override LearningTransport CreateTransport(IConfigurationSection? endpointConfigurationSection) - { - return new LearningTransport(); - } -} \ No newline at end of file diff --git a/src/NServiceBoXes.Endpoints/NServiceBusEndpoint.cs b/src/NServiceBoXes.Endpoints/NServiceBusEndpoint.cs deleted file mode 100644 index 77dff40..0000000 --- a/src/NServiceBoXes.Endpoints/NServiceBusEndpoint.cs +++ /dev/null @@ -1,159 +0,0 @@ -using Microsoft.Extensions.Configuration; -using NServiceBus.Persistence; -using NServiceBus.Serialization; -using NServiceBus.Transport; - -namespace NServiceBoXes.Endpoints; - -public abstract class NServiceBusEndpoint where TTransport : TransportDefinition -{ - readonly IConfiguration? _configuration; - protected EndpointConfiguration EndpointConfiguration{ get; } - protected IConfigurationSection? EndpointConfigurationSection { get; } - - Action>? _serializerCustomization; - bool _useDefaultSerializer = true; - - protected TTransport Transport { get; private set; } = null!; - Action? _transportCustomization; - Func? _transportFactory; - - protected NServiceBusEndpoint(string endpointName, IConfiguration? configuration = null) - { - if (endpointName == null) throw new ArgumentNullException(nameof(endpointName)); - - _configuration = configuration; - EndpointConfiguration = new EndpointConfiguration(endpointName); - EndpointConfigurationSection = configuration?.GetSection("NServiceBus:EndpointConfiguration"); - } - - protected abstract TTransport CreateTransport(IConfigurationSection? endpointConfigurationSection); - - void ConfigureAuditing() - { - var auditSection = EndpointConfigurationSection?.GetSection("Auditing"); - var enableAuditing = bool.Parse(auditSection?["Enabled"] ?? true.ToString()); - if (!enableAuditing) - { - return; - } - - var auditQueue = auditSection?["AuditQueue"] ?? "audit"; - EndpointConfiguration.AuditProcessedMessagesTo(auditQueue); - } - - void ConfigureRecoverability() - { - var recoverabilitySection = EndpointConfigurationSection?.GetSection("Recoverability"); - - var errorQueue = recoverabilitySection?["ErrorQueue"] ?? "error"; - EndpointConfiguration.SendFailedMessagesTo(errorQueue); - - var recoverabilityConfiguration = EndpointConfiguration.Recoverability(); - - if (recoverabilitySection?.GetSection("Immediate") is { } immediateSection) - { - recoverabilityConfiguration.Immediate( - immediate => - { - if(immediateSection["NumberOfRetries"] is {} numberOfRetries) - { - immediate.NumberOfRetries(int.Parse(numberOfRetries)); - } - }); - } - - if(recoverabilitySection?.GetSection("Delayed") is { } delayedSection) - { - recoverabilityConfiguration.Delayed( - delayed => - { - if(delayedSection["NumberOfRetries"] is { } numberOfRetries) - { - delayed.NumberOfRetries(int.Parse(numberOfRetries)); - } - - if (delayedSection["TimeIncrease"] is {} timeIncrease) - {; - delayed.TimeIncrease(TimeSpan.Parse(timeIncrease)); - } - }); - } - } - - - protected static string GetEndpointNameFromConfigurationOrThrow(IConfiguration? configuration) - { - if (configuration == null) throw new ArgumentNullException(nameof(configuration)); - - return configuration.GetSection("NServiceBus:EndpointConfiguration")["EndpointName"] - ?? throw new ArgumentException( - "EndpointName cannot be null. Make sure the " + - "NServiceBus:EndpointConfiguration:EndpointName configuration section is set."); - } - - protected virtual void FinalizeConfiguration() - { - ConfigureAuditing(); - ConfigureRecoverability(); - - if (_useDefaultSerializer) - { - var serializerConfiguration = EndpointConfiguration.UseSerialization(); - _serializerCustomization?.Invoke(serializerConfiguration); - } - - Transport = _transportFactory != null ? _transportFactory(_configuration) : CreateTransport(EndpointConfigurationSection); - - _transportCustomization?.Invoke(Transport); - EndpointConfiguration.UseTransport(Transport); - } - - public static implicit operator EndpointConfiguration(NServiceBusEndpoint endpoint) - { - endpoint.FinalizeConfiguration(); - return endpoint.EndpointConfiguration; - } - - public PersistenceExtensions UsePersistence() - where T : PersistenceDefinition - { - return EndpointConfiguration.UsePersistence(); - } - - public PersistenceExtensions UsePersistence() - where T : PersistenceDefinition - where S : StorageType - { - return EndpointConfiguration.UsePersistence(); - } - - public SerializationExtensions ReplaceDefaultSerializer() where T : SerializationDefinition, new() - { - _useDefaultSerializer = false; - return EndpointConfiguration.UseSerialization(); - } - - public void CustomizeDefaultSerializer(Action> serializerCustomization) - { - _serializerCustomization = serializerCustomization; - } - - public void CustomizeTransport(Action transportCustomization) - { - _transportCustomization = transportCustomization; - } - - public void OverrideTransport(Func transportFactory) - { - _transportFactory = transportFactory; - } - - public async Task Start() - { - FinalizeConfiguration(); - - var endpointInstance = await Endpoint.Start(EndpointConfiguration).ConfigureAwait(false); - return endpointInstance; - } -} \ No newline at end of file