From 93b44bdb88fe37f2fe409c060ba7c3a2d7f3d58c Mon Sep 17 00:00:00 2001 From: Maxwell Weru Date: Mon, 8 Aug 2022 10:54:55 +0300 Subject: [PATCH 1/3] Make EventBusReadinessOptions independent of EventBusOptions --- .../EventBusConfigureOptions.cs | 26 +++++++++++-------- .../DependencyInjection/EventBusOptions.cs | 5 ---- src/Tingle.EventBus/EventBus.cs | 21 +++++++-------- .../Readiness/DefaultReadinessProvider.cs | 4 +-- 4 files changed, 26 insertions(+), 30 deletions(-) diff --git a/src/Tingle.EventBus/DependencyInjection/EventBusConfigureOptions.cs b/src/Tingle.EventBus/DependencyInjection/EventBusConfigureOptions.cs index 50248d52..08ea7f8c 100644 --- a/src/Tingle.EventBus/DependencyInjection/EventBusConfigureOptions.cs +++ b/src/Tingle.EventBus/DependencyInjection/EventBusConfigureOptions.cs @@ -9,7 +9,7 @@ namespace Microsoft.Extensions.DependencyInjection; /// /// A class to finish configure non-trivial defaults of instances of . /// -internal class EventBusConfigureOptions : IConfigureOptions, IPostConfigureOptions +internal class EventBusConfigureOptions : IConfigureOptions, IPostConfigureOptions, IPostConfigureOptions { private readonly IHostEnvironment environment; private readonly IEnumerable configurators; @@ -45,19 +45,10 @@ public void Configure(EventBusOptions options) /// public void PostConfigure(string name, EventBusOptions options) { - // Check bounds for readiness timeout - var ticks = options.Readiness.Timeout.Ticks; - if (options.Readiness.Enabled) - { - ticks = Math.Max(ticks, TimeSpan.FromSeconds(5).Ticks); // must be more than 5 seconds - ticks = Math.Min(ticks, TimeSpan.FromMinutes(15).Ticks); // must be less than 15 minutes - options.Readiness.Timeout = TimeSpan.FromTicks(ticks); - } - // Check bounds for duplicate detection duration, if duplicate detection is enabled if (options.EnableDeduplication) { - ticks = options.DuplicateDetectionDuration.Ticks; + var ticks = options.DuplicateDetectionDuration.Ticks; ticks = Math.Max(ticks, TimeSpan.FromSeconds(20).Ticks); // must be more than 20 seconds ticks = Math.Min(ticks, TimeSpan.FromDays(7).Ticks); // must be less than 7 days options.DuplicateDetectionDuration = TimeSpan.FromTicks(ticks); @@ -126,4 +117,17 @@ public void PostConfigure(string name, EventBusOptions options) } } } + + /// + public void PostConfigure(string name, EventBusReadinessOptions options) + { + // Check bounds for readiness timeout + var ticks = options.Timeout.Ticks; + if (options.Enabled) + { + ticks = Math.Max(ticks, TimeSpan.FromSeconds(5).Ticks); // must be more than 5 seconds + ticks = Math.Min(ticks, TimeSpan.FromMinutes(15).Ticks); // must be less than 15 minutes + options.Timeout = TimeSpan.FromTicks(ticks); + } + } } diff --git a/src/Tingle.EventBus/DependencyInjection/EventBusOptions.cs b/src/Tingle.EventBus/DependencyInjection/EventBusOptions.cs index f31506ea..46dc29b8 100644 --- a/src/Tingle.EventBus/DependencyInjection/EventBusOptions.cs +++ b/src/Tingle.EventBus/DependencyInjection/EventBusOptions.cs @@ -19,11 +19,6 @@ public class EventBusOptions /// public TimeSpan? StartupDelay { get; set; } - /// - /// Gets the for the Event Bus. - /// - public EventBusReadinessOptions Readiness { get; } = new EventBusReadinessOptions(); - /// /// Gets the for the Event Bus. /// diff --git a/src/Tingle.EventBus/EventBus.cs b/src/Tingle.EventBus/EventBus.cs index 23513293..a297e77e 100644 --- a/src/Tingle.EventBus/EventBus.cs +++ b/src/Tingle.EventBus/EventBus.cs @@ -230,19 +230,16 @@ public async Task StartAsync(CancellationToken cancellationToken) private async Task StartTransportsAsync(CancellationToken cancellationToken) { - if (options.Readiness.Enabled) + try { - try - { - // Perform readiness check before starting bus. - logger.StartupReadinessCheck(); - await readinessProvider.WaitReadyAsync(cancellationToken: cancellationToken); - } - catch (Exception ex) - { - logger.StartupReadinessCheckFailed(ex); - throw; // re-throw to prevent from getting healthy - } + // Perform readiness check before starting bus. + logger.StartupReadinessCheck(); + await readinessProvider.WaitReadyAsync(cancellationToken: cancellationToken); + } + catch (Exception ex) + { + logger.StartupReadinessCheckFailed(ex); + throw; // re-throw to prevent from getting healthy } // Start the bus and its transports diff --git a/src/Tingle.EventBus/Readiness/DefaultReadinessProvider.cs b/src/Tingle.EventBus/Readiness/DefaultReadinessProvider.cs index c7d7148b..7aa44f81 100644 --- a/src/Tingle.EventBus/Readiness/DefaultReadinessProvider.cs +++ b/src/Tingle.EventBus/Readiness/DefaultReadinessProvider.cs @@ -13,10 +13,10 @@ internal class DefaultReadinessProvider : IReadinessProvider, IHealthCheckPublis private HealthReport? healthReport; - public DefaultReadinessProvider(IOptions optionsAccessor, + public DefaultReadinessProvider(IOptions optionsAccessor, ILogger logger) { - options = optionsAccessor?.Value?.Readiness ?? throw new ArgumentNullException(nameof(optionsAccessor)); + options = optionsAccessor?.Value ?? throw new ArgumentNullException(nameof(optionsAccessor)); this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); } From fb434b5b932157f16463d996f92e22f78c6dc09e Mon Sep 17 00:00:00 2001 From: Maxwell Weru Date: Mon, 8 Aug 2022 11:02:17 +0300 Subject: [PATCH 2/3] Make EventBusSerializationOptions independent of EventBusOptions --- .../AzureDevOpsEventSerializer.cs | 2 +- .../NewtonsoftJsonSerializer.cs | 2 +- .../IotHub/IotHubEventSerializer.cs | 2 +- .../EventBusConfigureOptions.cs | 56 +++++++++++-------- .../DependencyInjection/EventBusOptions.cs | 24 -------- .../EventBusSerializationOptions.cs | 32 +++++++++++ .../Serialization/AbstractEventSerializer.cs | 4 +- .../DefaultJsonEventSerializer.cs | 2 +- .../Serialization/Xml/XmlEventSerializer.cs | 2 +- 9 files changed, 73 insertions(+), 53 deletions(-) create mode 100644 src/Tingle.EventBus/DependencyInjection/EventBusSerializationOptions.cs diff --git a/samples/CustomEventSerializer/AzureDevOpsEventSerializer.cs b/samples/CustomEventSerializer/AzureDevOpsEventSerializer.cs index ed413d88..8462eae0 100644 --- a/samples/CustomEventSerializer/AzureDevOpsEventSerializer.cs +++ b/samples/CustomEventSerializer/AzureDevOpsEventSerializer.cs @@ -9,7 +9,7 @@ public class AzureDevOpsEventSerializer : AbstractEventSerializer { private readonly JsonSerializer serializer = JsonSerializer.CreateDefault(); - public AzureDevOpsEventSerializer(IOptionsMonitor optionsAccessor, + public AzureDevOpsEventSerializer(IOptionsMonitor optionsAccessor, ILoggerFactory loggerFactory) : base(optionsAccessor, loggerFactory) { } diff --git a/src/Tingle.EventBus.Serializers.NewtonsoftJson/NewtonsoftJsonSerializer.cs b/src/Tingle.EventBus.Serializers.NewtonsoftJson/NewtonsoftJsonSerializer.cs index b23f222c..7d54eaf9 100644 --- a/src/Tingle.EventBus.Serializers.NewtonsoftJson/NewtonsoftJsonSerializer.cs +++ b/src/Tingle.EventBus.Serializers.NewtonsoftJson/NewtonsoftJsonSerializer.cs @@ -21,7 +21,7 @@ public class NewtonsoftJsonSerializer : AbstractEventSerializer /// /// public NewtonsoftJsonSerializer(IOptions serializerOptionsAccessor, - IOptionsMonitor optionsAccessor, + IOptionsMonitor optionsAccessor, ILoggerFactory loggerFactory) : base(optionsAccessor, loggerFactory) { diff --git a/src/Tingle.EventBus.Transports.Azure.EventHubs/IotHub/IotHubEventSerializer.cs b/src/Tingle.EventBus.Transports.Azure.EventHubs/IotHub/IotHubEventSerializer.cs index 0686ba45..73534d05 100644 --- a/src/Tingle.EventBus.Transports.Azure.EventHubs/IotHub/IotHubEventSerializer.cs +++ b/src/Tingle.EventBus.Transports.Azure.EventHubs/IotHub/IotHubEventSerializer.cs @@ -14,7 +14,7 @@ internal class IotHubEventSerializer : AbstractEventSerializer private static readonly Type BaseType = typeof(IotHubEvent<,,>); private static readonly ConcurrentDictionary typeMaps = new(); - public IotHubEventSerializer(IOptionsMonitor optionsAccessor, + public IotHubEventSerializer(IOptionsMonitor optionsAccessor, ILoggerFactory loggerFactory) : base(optionsAccessor, loggerFactory) { } diff --git a/src/Tingle.EventBus/DependencyInjection/EventBusConfigureOptions.cs b/src/Tingle.EventBus/DependencyInjection/EventBusConfigureOptions.cs index 08ea7f8c..a76a81a3 100644 --- a/src/Tingle.EventBus/DependencyInjection/EventBusConfigureOptions.cs +++ b/src/Tingle.EventBus/DependencyInjection/EventBusConfigureOptions.cs @@ -9,7 +9,11 @@ namespace Microsoft.Extensions.DependencyInjection; /// /// A class to finish configure non-trivial defaults of instances of . /// -internal class EventBusConfigureOptions : IConfigureOptions, IPostConfigureOptions, IPostConfigureOptions +internal class EventBusConfigureOptions : IConfigureOptions, + IPostConfigureOptions, + IPostConfigureOptions, + IConfigureOptions, + IPostConfigureOptions { private readonly IHostEnvironment environment; private readonly IEnumerable configurators; @@ -25,21 +29,6 @@ public void Configure(EventBusOptions options) { // Set the default ConsumerNamePrefix options.Naming.ConsumerNamePrefix ??= environment.ApplicationName; - - // Setup HostInfo - if (options.HostInfo == null) - { - var entry = System.Reflection.Assembly.GetEntryAssembly() ?? System.Reflection.Assembly.GetCallingAssembly(); - options.HostInfo = new HostInfo - { - ApplicationName = environment.ApplicationName, - ApplicationVersion = entry.GetName().Version?.ToString(), - EnvironmentName = environment.EnvironmentName, - LibraryVersion = typeof(EventBus).Assembly.GetName().Version?.ToString(), - MachineName = Environment.MachineName, - OperatingSystem = Environment.OSVersion.ToString(), - }; - } } /// @@ -54,12 +43,6 @@ public void PostConfigure(string name, EventBusOptions options) options.DuplicateDetectionDuration = TimeSpan.FromTicks(ticks); } - // Ensure we have HostInfo set - if (options.HostInfo == null) - { - throw new InvalidOperationException($"'{nameof(options.HostInfo)}' must be set."); - } - // Ensure there is at least one registered transport if (options.RegisteredTransportNames.Count == 0) { @@ -130,4 +113,33 @@ public void PostConfigure(string name, EventBusReadinessOptions options) options.Timeout = TimeSpan.FromTicks(ticks); } } + + /// + public void Configure(EventBusSerializationOptions options) + { + // Setup HostInfo + if (options.HostInfo == null) + { + var entry = System.Reflection.Assembly.GetEntryAssembly() ?? System.Reflection.Assembly.GetCallingAssembly(); + options.HostInfo = new HostInfo + { + ApplicationName = environment.ApplicationName, + ApplicationVersion = entry.GetName().Version?.ToString(), + EnvironmentName = environment.EnvironmentName, + LibraryVersion = typeof(EventBus).Assembly.GetName().Version?.ToString(), + MachineName = Environment.MachineName, + OperatingSystem = Environment.OSVersion.ToString(), + }; + } + } + + /// + public void PostConfigure(string name, EventBusSerializationOptions options) + { + // Ensure we have HostInfo set + if (options.HostInfo == null) + { + throw new InvalidOperationException($"'{nameof(options.HostInfo)}' must be set."); + } + } } diff --git a/src/Tingle.EventBus/DependencyInjection/EventBusOptions.cs b/src/Tingle.EventBus/DependencyInjection/EventBusOptions.cs index 46dc29b8..2e7fa160 100644 --- a/src/Tingle.EventBus/DependencyInjection/EventBusOptions.cs +++ b/src/Tingle.EventBus/DependencyInjection/EventBusOptions.cs @@ -1,9 +1,7 @@ using Polly.Retry; using System.Diagnostics.CodeAnalysis; -using System.Text.Json; using Tingle.EventBus; using Tingle.EventBus.Configuration; -using Tingle.EventBus.Serialization; using Tingle.EventBus.Transports; namespace Microsoft.Extensions.DependencyInjection; @@ -24,28 +22,6 @@ public class EventBusOptions /// public EventBusNamingOptions Naming { get; } = new EventBusNamingOptions(); - /// - /// The options to use for serialization. - /// - public JsonSerializerOptions SerializerOptions { get; set; } = new JsonSerializerOptions - { - NumberHandling = System.Text.Json.Serialization.JsonNumberHandling.AllowNamedFloatingPointLiterals - | System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString, - WriteIndented = false, // less data used - DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingDefault - | System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull, - - PropertyNamingPolicy = JsonNamingPolicy.CamelCase, - PropertyNameCaseInsensitive = true, - AllowTrailingCommas = true, - ReadCommentHandling = JsonCommentHandling.Skip, - }; - - /// - /// The information about the host where the EventBus is running. - /// - public HostInfo? HostInfo { get; set; } - /// /// Indicates if the messages/events produced require guard against duplicate messages. /// If , duplicate messages having the same diff --git a/src/Tingle.EventBus/DependencyInjection/EventBusSerializationOptions.cs b/src/Tingle.EventBus/DependencyInjection/EventBusSerializationOptions.cs new file mode 100644 index 00000000..08d96d43 --- /dev/null +++ b/src/Tingle.EventBus/DependencyInjection/EventBusSerializationOptions.cs @@ -0,0 +1,32 @@ +using System.Text.Json; +using Tingle.EventBus.Serialization; + +namespace Microsoft.Extensions.DependencyInjection; + +/// +/// Specified options for serialization. +/// +public class EventBusSerializationOptions +{ + /// + /// The options to use for serialization. + /// + public JsonSerializerOptions SerializerOptions { get; set; } = new JsonSerializerOptions + { + NumberHandling = System.Text.Json.Serialization.JsonNumberHandling.AllowNamedFloatingPointLiterals + | System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString, + WriteIndented = false, // less data used + DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingDefault + | System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull, + + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + PropertyNameCaseInsensitive = true, + AllowTrailingCommas = true, + ReadCommentHandling = JsonCommentHandling.Skip, + }; + + /// + /// The information about the host where the EventBus is running. + /// + public HostInfo? HostInfo { get; set; } +} diff --git a/src/Tingle.EventBus/Serialization/AbstractEventSerializer.cs b/src/Tingle.EventBus/Serialization/AbstractEventSerializer.cs index 31502ad0..eb3c825d 100644 --- a/src/Tingle.EventBus/Serialization/AbstractEventSerializer.cs +++ b/src/Tingle.EventBus/Serialization/AbstractEventSerializer.cs @@ -22,7 +22,7 @@ public abstract class AbstractEventSerializer : IEventSerializer /// /// /// - protected AbstractEventSerializer(IOptionsMonitor optionsAccessor, ILoggerFactory loggerFactory) + protected AbstractEventSerializer(IOptionsMonitor optionsAccessor, ILoggerFactory loggerFactory) { OptionsAccessor = optionsAccessor ?? throw new ArgumentNullException(nameof(optionsAccessor)); @@ -39,7 +39,7 @@ protected AbstractEventSerializer(IOptionsMonitor optionsAccess protected abstract IList SupportedMediaTypes { get; } /// - protected IOptionsMonitor OptionsAccessor { get; } + protected IOptionsMonitor OptionsAccessor { get; } /// protected ILogger Logger { get; } diff --git a/src/Tingle.EventBus/Serialization/DefaultJsonEventSerializer.cs b/src/Tingle.EventBus/Serialization/DefaultJsonEventSerializer.cs index 11ee3684..4044876a 100644 --- a/src/Tingle.EventBus/Serialization/DefaultJsonEventSerializer.cs +++ b/src/Tingle.EventBus/Serialization/DefaultJsonEventSerializer.cs @@ -15,7 +15,7 @@ public class DefaultJsonEventSerializer : AbstractEventSerializer /// /// The options for configuring the serializer. /// - public DefaultJsonEventSerializer(IOptionsMonitor optionsAccessor, + public DefaultJsonEventSerializer(IOptionsMonitor optionsAccessor, ILoggerFactory loggerFactory) : base(optionsAccessor, loggerFactory) { } diff --git a/src/Tingle.EventBus/Serialization/Xml/XmlEventSerializer.cs b/src/Tingle.EventBus/Serialization/Xml/XmlEventSerializer.cs index a5bfbcdd..4055b4ec 100644 --- a/src/Tingle.EventBus/Serialization/Xml/XmlEventSerializer.cs +++ b/src/Tingle.EventBus/Serialization/Xml/XmlEventSerializer.cs @@ -15,7 +15,7 @@ public class XmlEventSerializer : AbstractEventSerializer /// /// The options for configuring the serializer. /// - public XmlEventSerializer(IOptionsMonitor optionsAccessor, + public XmlEventSerializer(IOptionsMonitor optionsAccessor, ILoggerFactory loggerFactory) : base(optionsAccessor, loggerFactory) { } From 6a3f04147303417e8b66a2573c4bfc7712233b89 Mon Sep 17 00:00:00 2001 From: Maxwell Weru Date: Mon, 8 Aug 2022 11:03:57 +0300 Subject: [PATCH 3/3] Added methods for configuring EventBusReadinessOptions and EventBusSerializationOptions in EventbusBuilder --- .../DependencyInjection/EventBusBuilder.cs | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/Tingle.EventBus/DependencyInjection/EventBusBuilder.cs b/src/Tingle.EventBus/DependencyInjection/EventBusBuilder.cs index a7267e0e..5a8cab61 100644 --- a/src/Tingle.EventBus/DependencyInjection/EventBusBuilder.cs +++ b/src/Tingle.EventBus/DependencyInjection/EventBusBuilder.cs @@ -46,9 +46,7 @@ public EventBusBuilder(IServiceCollection services) /// public IServiceCollection Services { get; } - /// - /// Configure options for EventBus - /// + /// Configure options for the EventBus. /// /// public EventBusBuilder Configure(Action configure) @@ -59,6 +57,28 @@ public EventBusBuilder Configure(Action configure) return this; } + /// Configure readiness options for the EventBus. + /// + /// + public EventBusBuilder ConfigureReadiness(Action configure) + { + if (configure is null) throw new ArgumentNullException(nameof(configure)); + + Services.Configure(configure); + return this; + } + + /// Configure serialization options for the EventBus. + /// + /// + public EventBusBuilder ConfigureSerialization(Action configure) + { + if (configure is null) throw new ArgumentNullException(nameof(configure)); + + Services.Configure(configure); + return this; + } + /// /// Register a transport to be used by the bus. ///