diff --git a/src/HealthChecks.AzureServiceBus/AzureServiceBusQueueMessageCountThresholdHealthCheck.cs b/src/HealthChecks.AzureServiceBus/AzureServiceBusQueueMessageCountThresholdHealthCheck.cs new file mode 100644 index 0000000000..21a12dbeac --- /dev/null +++ b/src/HealthChecks.AzureServiceBus/AzureServiceBusQueueMessageCountThresholdHealthCheck.cs @@ -0,0 +1,81 @@ +using HealthChecks.AzureServiceBus.Configuration; +using Microsoft.Extensions.Diagnostics.HealthChecks; + +namespace HealthChecks.AzureServiceBus; + +public class AzureServiceBusQueueMessageCountThresholdHealthCheck : AzureServiceBusHealthCheck, IHealthCheck +{ + private readonly string _queueName; + private readonly AzureServiceBusQueueMessagesCountThreshold? _activeMessagesThreshold; + private readonly AzureServiceBusQueueMessagesCountThreshold? _deadLetterMessagesThreshold; + + public AzureServiceBusQueueMessageCountThresholdHealthCheck(AzureServiceBusQueueMessagesCountThresholdHealthCheckOptions options) + : base(options) + { + _queueName = Guard.ThrowIfNull(options.QueueName); + _activeMessagesThreshold = options.ActiveMessages; + _deadLetterMessagesThreshold = options.DeadLetterMessages; + } + + protected override string ConnectionKey => $"{Prefix}_{_queueName}"; + + /// + public async Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) + { + try + { + var managementClient = ManagementClientConnections.GetOrAdd(ConnectionKey, CreateManagementClient()); + + var properties = await managementClient.GetQueueRuntimePropertiesAsync(_queueName, cancellationToken).ConfigureAwait(false); + + var activeQueueHealthStatus = CheckHealthStatus( + properties.Value.ActiveMessageCount, + _activeMessagesThreshold, + "queue"); + + if (activeQueueHealthStatus.Status != HealthStatus.Healthy) + { + return activeQueueHealthStatus; + } + + var deadLetterQueueHealthStatus = CheckHealthStatus( + properties.Value.DeadLetterMessageCount, + _deadLetterMessagesThreshold, + "dead letter queue"); + + if (deadLetterQueueHealthStatus.Status != HealthStatus.Healthy) + { + return deadLetterQueueHealthStatus; + } + + return HealthCheckResult.Healthy(); + } + catch (Exception ex) + { + return new HealthCheckResult(context.Registration.FailureStatus, exception: ex); + } + } + + private HealthCheckResult CheckHealthStatus( + long messagesCount, + AzureServiceBusQueueMessagesCountThreshold? threshold, + string queueType) + { + if (threshold is null) + { + return HealthCheckResult.Healthy(); + } + + if (messagesCount >= threshold.Value.UnhealthyThreshold) + { + return HealthCheckResult.Unhealthy($"Message in {queueType} {_queueName} exceeded the amount of messages allowed for the unhealthy threshold {threshold.Value.UnhealthyThreshold}/{messagesCount}"); + } + + if (messagesCount >= threshold.Value.DegradedThreshold) + { + return HealthCheckResult.Degraded($"Message in {queueType} {_queueName} exceeded the amount of messages allowed for the degraded threshold {threshold.Value.DegradedThreshold}/{messagesCount}"); + } + + return HealthCheckResult.Healthy(); + } +} diff --git a/src/HealthChecks.AzureServiceBus/Configuration/AzureServiceBusQueueMessagesCountThreshold.cs b/src/HealthChecks.AzureServiceBus/Configuration/AzureServiceBusQueueMessagesCountThreshold.cs new file mode 100644 index 0000000000..7943bfbf11 --- /dev/null +++ b/src/HealthChecks.AzureServiceBus/Configuration/AzureServiceBusQueueMessagesCountThreshold.cs @@ -0,0 +1,23 @@ +using Microsoft.Extensions.Diagnostics.HealthChecks; + +namespace HealthChecks.AzureServiceBus.Configuration; + +/// +/// Threshold configuration options for . +/// +public struct AzureServiceBusQueueMessagesCountThreshold +{ + /// + /// Number of active/dead letter Service Bus messages in the queue before message health check returned . + /// + public int DegradedThreshold { get; set; } = 5; + + /// + /// Number of active/dead letter Service Bus messages in the queue before message health check returned . + /// + public int UnhealthyThreshold { get; set; } = 10; + + public AzureServiceBusQueueMessagesCountThreshold() + { + } +} diff --git a/src/HealthChecks.AzureServiceBus/Configuration/AzureServiceBusQueueMessagesCountThresholdHealthCheckOptions.cs b/src/HealthChecks.AzureServiceBus/Configuration/AzureServiceBusQueueMessagesCountThresholdHealthCheckOptions.cs new file mode 100644 index 0000000000..f31432f2cb --- /dev/null +++ b/src/HealthChecks.AzureServiceBus/Configuration/AzureServiceBusQueueMessagesCountThresholdHealthCheckOptions.cs @@ -0,0 +1,22 @@ +namespace HealthChecks.AzureServiceBus.Configuration; + +/// +/// Configuration options for . +/// +public class AzureServiceBusQueueMessagesCountThresholdHealthCheckOptions : AzureServiceBusQueueHealthCheckOptions +{ + /// + /// Threshold configuration for active messages queue. + /// + public AzureServiceBusQueueMessagesCountThreshold? ActiveMessages { get; set; } + + /// + /// Threshold configuration for dead letter messages queue. + /// + public AzureServiceBusQueueMessagesCountThreshold? DeadLetterMessages { get; set; } + + public AzureServiceBusQueueMessagesCountThresholdHealthCheckOptions(string queueName) + : base(queueName) + { + } +} diff --git a/src/HealthChecks.AzureServiceBus/DependencyInjection/AzureServiceBusHealthCheckBuilderExtensions.cs b/src/HealthChecks.AzureServiceBus/DependencyInjection/AzureServiceBusHealthCheckBuilderExtensions.cs index 887428c804..6a05ce25bc 100644 --- a/src/HealthChecks.AzureServiceBus/DependencyInjection/AzureServiceBusHealthCheckBuilderExtensions.cs +++ b/src/HealthChecks.AzureServiceBus/DependencyInjection/AzureServiceBusHealthCheckBuilderExtensions.cs @@ -1,722 +1,814 @@ -using Azure.Core; -using Azure.Messaging.EventHubs; -using HealthChecks.AzureServiceBus; -using HealthChecks.AzureServiceBus.Configuration; -using Microsoft.Extensions.Diagnostics.HealthChecks; - -namespace Microsoft.Extensions.DependencyInjection; - -/// -/// Extension methods to configure , -/// , , -/// , . -/// -public static class AzureServiceBusHealthCheckBuilderExtensions -{ - private const string AZUREEVENTHUB_NAME = "azureeventhub"; - private const string AZUREQUEUE_NAME = "azurequeue"; - private const string AZURETOPIC_NAME = "azuretopic"; - private const string AZURESUBSCRIPTION_NAME = "azuresubscription"; - - /// - /// Add a health check for specified Azure Event Hub. - /// - /// The . - /// The azure event hub connection string. - /// The azure event hub name. - /// An optional action to allow additional Azure Event Hub configuration. - /// The health check name. Optional. If null the type name 'azureeventhub' will be used for the name. - /// - /// The that should be reported when the health check fails. Optional. If null then - /// the default status of will be reported. - /// - /// A list of tags that can be used to filter sets of health checks. Optional. - /// An optional representing the timeout of the check. - /// The specified . - public static IHealthChecksBuilder AddAzureEventHub( - this IHealthChecksBuilder builder, - string connectionString, - string eventHubName, - Action? configure = default, - string? name = default, - HealthStatus? failureStatus = default, - IEnumerable? tags = default, - TimeSpan? timeout = default) => - builder.AddAzureEventHub( - _ => connectionString, - _ => eventHubName, - configure, - name, - failureStatus, - tags, - timeout); - - /// - /// Add a health check for specified Azure Event Hub. - /// - /// The . - /// A factory to build the azure event hub connection string. - /// A factory to build the azure event hub name. - /// An optional action to allow additional Azure Event Hub configuration. - /// The health check name. Optional. If null the type name 'azureeventhub' will be used for the name. - /// - /// The that should be reported when the health check fails. Optional. If null then - /// the default status of will be reported. - /// - /// A list of tags that can be used to filter sets of health checks. Optional. - /// An optional representing the timeout of the check. - /// The specified . - public static IHealthChecksBuilder AddAzureEventHub( - this IHealthChecksBuilder builder, - Func connectionStringFactory, - Func eventHubNameFactory, - Action? configure = default, - string? name = default, - HealthStatus? failureStatus = default, - IEnumerable? tags = default, - TimeSpan? timeout = default) - { - Guard.ThrowIfNull(connectionStringFactory); - Guard.ThrowIfNull(eventHubNameFactory); - - return builder.Add(new HealthCheckRegistration( - name ?? AZUREEVENTHUB_NAME, - sp => - { - var options = new AzureEventHubHealthCheckOptions - { - ConnectionString = connectionStringFactory(sp), - EventHubName = eventHubNameFactory(sp) - }; - - configure?.Invoke(options); - return new AzureEventHubHealthCheck(options); - }, - failureStatus, - tags, - timeout)); - } - - /// - /// Add a health check for specified Azure Event Hub. - /// - /// The . - /// The azure event hub fully qualified namespace. - /// The azure event hub name. - /// The token credential for authentication. - /// An optional action to allow additional Azure Event Hub configuration. - /// The health check name. Optional. If null the type name 'azureeventhub' will be used for the name. - /// - /// The that should be reported when the health check fails. Optional. If null then - /// the default status of will be reported. - /// - /// A list of tags that can be used to filter sets of health checks. Optional. - /// An optional representing the timeout of the check. - /// The specified . - public static IHealthChecksBuilder AddAzureEventHub( - this IHealthChecksBuilder builder, - string fullyQualifiedNamespace, - string eventHubName, - TokenCredential tokenCredential, - Action? configure = default, - string? name = default, - HealthStatus? failureStatus = default, - IEnumerable? tags = default, - TimeSpan? timeout = default) => - builder.AddAzureEventHub( - _ => fullyQualifiedNamespace, - _ => eventHubName, - _ => tokenCredential, - configure, - name, - failureStatus, - tags, - timeout); - - /// - /// Add a health check for specified Azure Event Hub. - /// - /// The . - /// A factory to build the azure event hub fully qualified namespace. - /// A factory to build the azure event hub name. - /// A factory to build the token credential for authentication. - /// An optional action to allow additional Azure Event Hub configuration. - /// The health check name. Optional. If null the type name 'azureeventhub' will be used for the name. - /// - /// The that should be reported when the health check fails. Optional. If null then - /// the default status of will be reported. - /// - /// A list of tags that can be used to filter sets of health checks. Optional. - /// An optional representing the timeout of the check. - /// The specified . - public static IHealthChecksBuilder AddAzureEventHub( - this IHealthChecksBuilder builder, - Func fullyQualifiedNamespaceFactory, - Func eventHubNameFactory, - Func tokenCredentialFactory, - Action? configure = default, - string? name = default, - HealthStatus? failureStatus = default, - IEnumerable? tags = default, - TimeSpan? timeout = default) - { - Guard.ThrowIfNull(fullyQualifiedNamespaceFactory); - Guard.ThrowIfNull(eventHubNameFactory); - Guard.ThrowIfNull(tokenCredentialFactory); - - return builder.Add(new HealthCheckRegistration( - name ?? AZUREEVENTHUB_NAME, - sp => - { - var options = new AzureEventHubHealthCheckOptions - { - FullyQualifiedNamespace = fullyQualifiedNamespaceFactory(sp), - EventHubName = eventHubNameFactory(sp), - Credential = tokenCredentialFactory(sp) - }; - - configure?.Invoke(options); - return new AzureEventHubHealthCheck(options); - }, - failureStatus, - tags, - timeout)); - } - - /// - /// Add a health check for specified Azure Event Hub. - /// - /// The . - /// The event hub connection factory used to create a event hub connection for this health check. - /// An optional action to allow additional Azure Event Hub configuration. - /// The health check name. Optional. If null the type name 'azureeventhub' will be used for the name. - /// - /// The that should be reported when the health check fails. Optional. If null then - /// the default status of will be reported. - /// - /// A list of tags that can be used to filter sets of health checks. Optional. - /// An optional representing the timeout of the check. - /// The specified . - public static IHealthChecksBuilder AddAzureEventHub( - this IHealthChecksBuilder builder, - Func eventHubConnectionFactory, - Action? configure = default, - string? name = default, - HealthStatus? failureStatus = default, - IEnumerable? tags = default, - TimeSpan? timeout = default) - { - Guard.ThrowIfNull(eventHubConnectionFactory); - - return builder.Add(new HealthCheckRegistration( - name ?? AZUREEVENTHUB_NAME, - sp => - { - var options = new AzureEventHubHealthCheckOptions { Connection = eventHubConnectionFactory(sp) }; - configure?.Invoke(options); - return new AzureEventHubHealthCheck(options); - }, - failureStatus, - tags, - timeout)); - } - - /// - /// Add a health check for specified Azure Service Bus Queue. - /// - /// The . - /// The azure service bus connection string to be used. - /// The name of the queue to check. - /// An optional action to allow additional Azure Service Bus configuration. - /// The health check name. Optional. If null the type name 'azurequeue' will be used for the name. - /// - /// The that should be reported when the health check fails. Optional. If null then - /// the default status of will be reported. - /// - /// A list of tags that can be used to filter sets of health checks. Optional. - /// An optional representing the timeout of the check. - /// The specified . - public static IHealthChecksBuilder AddAzureServiceBusQueue( - this IHealthChecksBuilder builder, - string connectionString, - string queueName, - Action? configure = default, - string? name = default, - HealthStatus? failureStatus = default, - IEnumerable? tags = default, - TimeSpan? timeout = default) => - builder.AddAzureServiceBusQueue( - _ => connectionString, - _ => queueName, - configure, - name, - failureStatus, - tags, - timeout); - - /// - /// Add a health check for specified Azure Service Bus Queue. - /// - /// The . - /// A factory to build the azure service bus connection string to be used. - /// A factory to build the queue name to check. - /// An optional action to allow additional Azure Service Bus configuration. - /// The health check name. Optional. If null the type name 'azurequeue' will be used for the name. - /// - /// The that should be reported when the health check fails. Optional. If null then - /// the default status of will be reported. - /// - /// A list of tags that can be used to filter sets of health checks. Optional. - /// An optional representing the timeout of the check. - /// The specified . - public static IHealthChecksBuilder AddAzureServiceBusQueue( - this IHealthChecksBuilder builder, - Func connectionStringFactory, - Func queueNameFactory, - Action? configure = default, - string? name = default, - HealthStatus? failureStatus = default, - IEnumerable? tags = default, - TimeSpan? timeout = default) - { - Guard.ThrowIfNull(connectionStringFactory); - Guard.ThrowIfNull(queueNameFactory); - - return builder.Add(new HealthCheckRegistration( - name ?? AZUREQUEUE_NAME, - sp => - { - var options = new AzureServiceBusQueueHealthCheckOptions(queueNameFactory(sp)) - { - ConnectionString = connectionStringFactory(sp) - }; - - configure?.Invoke(options); - return new AzureServiceBusQueueHealthCheck(options); - }, - failureStatus, - tags, - timeout)); - } - - /// - /// Add a health check for specified Azure Service Bus Queue. - /// - /// The . - /// The azure service bus fully qualified namespace to be used, format sb://myservicebus.servicebus.windows.net/. - /// The name of the queue to check. - /// The token credential for authentication. - /// An optional action to allow additional Azure Service Bus configuration. - /// The health check name. Optional. If null the type name 'azurequeue' will be used for the name. - /// - /// The that should be reported when the health check fails. Optional. If null then - /// the default status of will be reported. - /// - /// A list of tags that can be used to filter sets of health checks. Optional. - /// An optional representing the timeout of the check. - /// The specified . - public static IHealthChecksBuilder AddAzureServiceBusQueue( - this IHealthChecksBuilder builder, - string fullyQualifiedNamespace, - string queueName, - TokenCredential tokenCredential, - Action? configure = default, - string? name = default, - HealthStatus? failureStatus = default, - IEnumerable? tags = default, - TimeSpan? timeout = default) => - builder.AddAzureServiceBusQueue( - _ => fullyQualifiedNamespace, - _ => queueName, - _ => tokenCredential, - configure, - name, - failureStatus, - tags, - timeout); - - /// - /// Add a health check for specified Azure Service Bus Queue. - /// - /// The . - /// A factory to build the azure service bus fully qualified namespace to be used, format sb://myservicebus.servicebus.windows.net/. - /// A factory to build the name of the queue to check. - /// A factory to build the token credential for authentication. - /// An optional action to allow additional Azure Service Bus configuration. - /// The health check name. Optional. If null the type name 'azurequeue' will be used for the name. - /// - /// The that should be reported when the health check fails. Optional. If null then - /// the default status of will be reported. - /// - /// A list of tags that can be used to filter sets of health checks. Optional. - /// An optional representing the timeout of the check. - /// The specified . - public static IHealthChecksBuilder AddAzureServiceBusQueue( - this IHealthChecksBuilder builder, - Func fullyQualifiedNamespaceFactory, - Func queueNameFactory, - Func tokenCredentialFactory, - Action? configure = default, - string? name = default, - HealthStatus? failureStatus = default, - IEnumerable? tags = default, - TimeSpan? timeout = default) - { - Guard.ThrowIfNull(fullyQualifiedNamespaceFactory); - Guard.ThrowIfNull(queueNameFactory); - Guard.ThrowIfNull(tokenCredentialFactory); - - return builder.Add(new HealthCheckRegistration( - name ?? AZUREQUEUE_NAME, - sp => - { - var options = new AzureServiceBusQueueHealthCheckOptions(queueNameFactory(sp)) - { - FullyQualifiedNamespace = fullyQualifiedNamespaceFactory(sp), - Credential = tokenCredentialFactory(sp) - }; - - configure?.Invoke(options); - return new AzureServiceBusQueueHealthCheck(options); - }, - failureStatus, - tags, - timeout)); - } - - /// - /// Add a health check for Azure Service Bus Topic. - /// - /// The . - /// The Azure ServiceBus connection string to be used. - /// The name of the topic to check. - /// An optional action to allow additional Azure Service Bus configuration. - /// The health check name. Optional. If null the type name 'azuretopic' will be used for the name. - /// - /// The that should be reported when the health check fails. Optional. If null then - /// the default status of will be reported. - /// - /// A list of tags that can be used to filter sets of health checks. Optional. - /// An optional representing the timeout of the check. - /// The specified . - public static IHealthChecksBuilder AddAzureServiceBusTopic( - this IHealthChecksBuilder builder, - string connectionString, - string topicName, - Action? configure = default, - string? name = default, - HealthStatus? failureStatus = default, - IEnumerable? tags = default, - TimeSpan? timeout = default) => - builder.AddAzureServiceBusTopic( - _ => connectionString, - _ => topicName, - configure, - name, - failureStatus, - tags, - timeout); - - /// - /// Add a health check for Azure Service Bus Topic. - /// - /// The . - /// A factory to build the Azure ServiceBus connection string to be used. - /// A factory to build the name of the topic to check. - /// An optional action to allow additional Azure Service Bus configuration. - /// The health check name. Optional. If null the type name 'azuretopic' will be used for the name. - /// - /// The that should be reported when the health check fails. Optional. If null then - /// the default status of will be reported. - /// - /// A list of tags that can be used to filter sets of health checks. Optional. - /// An optional representing the timeout of the check. - /// The specified . - public static IHealthChecksBuilder AddAzureServiceBusTopic( - this IHealthChecksBuilder builder, - Func connectionStringFactory, - Func topicNameFactory, - Action? configure = default, - string? name = default, - HealthStatus? failureStatus = default, - IEnumerable? tags = default, - TimeSpan? timeout = default) - { - Guard.ThrowIfNull(connectionStringFactory); - Guard.ThrowIfNull(topicNameFactory); - - return builder.Add(new HealthCheckRegistration( - name ?? AZURETOPIC_NAME, - sp => - { - var options = new AzureServiceBusTopicHealthCheckOptions(topicNameFactory(sp)) - { - ConnectionString = connectionStringFactory(sp) - }; - - configure?.Invoke(options); - return new AzureServiceBusTopicHealthCheck(options); - }, - failureStatus, - tags, - timeout)); - } - - /// - /// Add a health check for Azure Service Bus Topic. - /// - /// The . - /// The azure service bus fully qualified namespace to be used, format sb://myservicebus.servicebus.windows.net/. - /// The name of the topic to check. - /// The token credential for authentication. - /// The health check name. Optional. If null the type name 'azuretopic' will be used for the name. - /// - /// The that should be reported when the health check fails. Optional. If null then - /// the default status of will be reported. - /// - /// A list of tags that can be used to filter sets of health checks. Optional. - /// An optional representing the timeout of the check. - /// The specified . - public static IHealthChecksBuilder AddAzureServiceBusTopic( - this IHealthChecksBuilder builder, - string fullyQualifiedNamespace, - string topicName, - TokenCredential tokenCredential, - string? name = default, - HealthStatus? failureStatus = default, - IEnumerable? tags = default, - TimeSpan? timeout = default) => - builder.AddAzureServiceBusTopic( - _ => fullyQualifiedNamespace, - _ => topicName, - _ => tokenCredential, - configure: null, - name, - failureStatus, - tags, - timeout); - - /// - /// Add a health check for Azure Service Bus Topic. - /// - /// The . - /// A factory to build the azure service bus fully qualified namespace to be used, format sb://myservicebus.servicebus.windows.net/. - /// A factory to build the name of the topic to check. - /// A factory to build the token credential for authentication. - /// An optional action to allow additional Azure Service Bus configuration. - /// The health check name. Optional. If null the type name 'azuretopic' will be used for the name. - /// - /// The that should be reported when the health check fails. Optional. If null then - /// the default status of will be reported. - /// - /// A list of tags that can be used to filter sets of health checks. Optional. - /// An optional representing the timeout of the check. - /// The specified . - public static IHealthChecksBuilder AddAzureServiceBusTopic( - this IHealthChecksBuilder builder, - Func fullyQualifiedNamespaceFactory, - Func topicNameFactory, - Func tokenCredentialFactory, - Action? configure = default, - string? name = default, - HealthStatus? failureStatus = default, - IEnumerable? tags = default, - TimeSpan? timeout = default) - { - Guard.ThrowIfNull(fullyQualifiedNamespaceFactory); - Guard.ThrowIfNull(topicNameFactory); - Guard.ThrowIfNull(tokenCredentialFactory); - - return builder.Add(new HealthCheckRegistration( - name ?? AZURETOPIC_NAME, - sp => - { - var options = new AzureServiceBusTopicHealthCheckOptions(topicNameFactory(sp)) - { - FullyQualifiedNamespace = fullyQualifiedNamespaceFactory(sp), - Credential = tokenCredentialFactory(sp) - }; - - configure?.Invoke(options); - return new AzureServiceBusTopicHealthCheck(options); - }, - failureStatus, - tags, - timeout)); - } - - /// - /// Add a health check for Azure Service Bus Subscription. - /// - /// The . - /// The Azure ServiceBus connection string to be used. - /// The name of the topic to check. - /// The subscription name of the topic subscription to check. - /// An optional action to allow additional Azure Service Bus configuration. - /// The health check name. Optional. If null the type name 'azuretopic' will be used for the name. - /// - /// The that should be reported when the health check fails. Optional. If null then - /// the default status of will be reported. - /// - /// A list of tags that can be used to filter sets of health checks. Optional. - /// An optional representing the timeout of the check. - /// The specified . - public static IHealthChecksBuilder AddAzureServiceBusSubscription( - this IHealthChecksBuilder builder, - string connectionString, - string topicName, - string subscriptionName, - Action? configure = default, - string? name = default, - HealthStatus? failureStatus = default, - IEnumerable? tags = default, - TimeSpan? timeout = default) => - builder.AddAzureServiceBusSubscription( - _ => connectionString, - _ => topicName, - _ => subscriptionName, - configure, - name, - failureStatus, - tags, - timeout); - - /// - /// Add a health check for Azure Service Bus Subscription. - /// - /// The . - /// A factory to build the Azure ServiceBus connection string to be used. - /// A factory to build the name of the topic to check. - /// A factory to build the subscription name of the topic subscription to check. - /// An optional action to allow additional Azure Service Bus configuration. - /// The health check name. Optional. If null the type name 'azuretopic' will be used for the name. - /// - /// The that should be reported when the health check fails. Optional. If null then - /// the default status of will be reported. - /// - /// A list of tags that can be used to filter sets of health checks. Optional. - /// An optional representing the timeout of the check. - /// The specified . - public static IHealthChecksBuilder AddAzureServiceBusSubscription( - this IHealthChecksBuilder builder, - Func connectionStringFactory, - Func topicNameFactory, - Func subscriptionNameFactory, - Action? configure = default, - string? name = default, - HealthStatus? failureStatus = default, - IEnumerable? tags = default, - TimeSpan? timeout = default) - { - Guard.ThrowIfNull(connectionStringFactory); - Guard.ThrowIfNull(topicNameFactory); - Guard.ThrowIfNull(subscriptionNameFactory); - - return builder.Add(new HealthCheckRegistration( - name ?? AZURESUBSCRIPTION_NAME, - sp => - { - var options = new AzureServiceBusSubscriptionHealthCheckHealthCheckOptions(topicNameFactory(sp), subscriptionNameFactory(sp)) - { - ConnectionString = connectionStringFactory(sp) - }; - - configure?.Invoke(options); - return new AzureServiceBusSubscriptionHealthCheck(options); - }, - failureStatus, - tags, - timeout)); - } - - /// - /// Add a health check for Azure Service Bus Subscription. - /// - /// The . - /// The azure service bus fully qualified namespace to be used, format sb://myservicebus.servicebus.windows.net/. - /// The name of the topic to check. - /// The subscription name of the topic subscription to check. - /// The token credential for authentication. - /// An optional action to allow additional Azure Service Bus configuration. - /// The health check name. Optional. If null the type name 'azuretopic' will be used for the name. - /// - /// The that should be reported when the health check fails. Optional. If null then - /// the default status of will be reported. - /// - /// A list of tags that can be used to filter sets of health checks. Optional. - /// An optional representing the timeout of the check. - /// The specified . - public static IHealthChecksBuilder AddAzureServiceBusSubscription( - this IHealthChecksBuilder builder, - string fullyQualifiedNamespace, - string topicName, - string subscriptionName, - TokenCredential tokenCredential, - Action? configure = default, - string? name = default, - HealthStatus? failureStatus = default, - IEnumerable? tags = default, - TimeSpan? timeout = default) => - builder.AddAzureServiceBusSubscription( - _ => fullyQualifiedNamespace, - _ => topicName, - _ => subscriptionName, - _ => tokenCredential, - configure, - name, - failureStatus, - tags, - timeout); - - /// - /// Add a health check for Azure Service Bus Subscription. - /// - /// The . - /// A factory to build the azure service bus fully qualified namespace to be used, format sb://myservicebus.servicebus.windows.net/. - /// A factory to build the name of the topic to check. - /// A factory to build the subscription name of the topic subscription to check. - /// A factory to build the token credential for authentication. - /// An optional action to allow additional Azure Service Bus configuration. - /// The health check name. Optional. If null the type name 'azuretopic' will be used for the name. - /// - /// The that should be reported when the health check fails. Optional. If null then - /// the default status of will be reported. - /// - /// A list of tags that can be used to filter sets of health checks. Optional. - /// An optional representing the timeout of the check. - /// The specified . - public static IHealthChecksBuilder AddAzureServiceBusSubscription( - this IHealthChecksBuilder builder, - Func fullyQualifiedNamespaceFactory, - Func topicNameFactory, - Func subscriptionNameFactory, - Func tokenCredentialFactory, - Action? configure = default, - string? name = default, - HealthStatus? failureStatus = default, - IEnumerable? tags = default, - TimeSpan? timeout = default) - { - Guard.ThrowIfNull(fullyQualifiedNamespaceFactory); - Guard.ThrowIfNull(topicNameFactory); - Guard.ThrowIfNull(subscriptionNameFactory); - Guard.ThrowIfNull(tokenCredentialFactory); - - return builder.Add(new HealthCheckRegistration( - name ?? AZURESUBSCRIPTION_NAME, - sp => - { - var options = new AzureServiceBusSubscriptionHealthCheckHealthCheckOptions(topicNameFactory(sp), subscriptionNameFactory(sp)) - { - FullyQualifiedNamespace = fullyQualifiedNamespaceFactory(sp), - Credential = tokenCredentialFactory(sp) - }; - - configure?.Invoke(options); - return new AzureServiceBusSubscriptionHealthCheck(options); - }, - failureStatus, - tags, - timeout)); - } -} +using Azure.Core; +using Azure.Messaging.EventHubs; +using HealthChecks.AzureServiceBus; +using HealthChecks.AzureServiceBus.Configuration; +using Microsoft.Extensions.Diagnostics.HealthChecks; + +namespace Microsoft.Extensions.DependencyInjection; + +/// +/// Extension methods to configure , +/// , , +/// , , +/// . +/// +public static class AzureServiceBusHealthCheckBuilderExtensions +{ + private const string AZUREEVENTHUB_NAME = "azureeventhub"; + private const string AZUREQUEUE_NAME = "azurequeue"; + private const string AZURETOPIC_NAME = "azuretopic"; + private const string AZURESUBSCRIPTION_NAME = "azuresubscription"; + private const string AZUREQUEUETHRESHOLD_NAME = "azurequeuethreshold"; + + /// + /// Add a health check for specified Azure Event Hub. + /// + /// The . + /// The azure event hub connection string. + /// The azure event hub name. + /// An optional action to allow additional Azure Event Hub configuration. + /// The health check name. Optional. If null the type name 'azureeventhub' will be used for the name. + /// + /// The that should be reported when the health check fails. Optional. If null then + /// the default status of will be reported. + /// + /// A list of tags that can be used to filter sets of health checks. Optional. + /// An optional representing the timeout of the check. + /// The specified . + public static IHealthChecksBuilder AddAzureEventHub( + this IHealthChecksBuilder builder, + string connectionString, + string eventHubName, + Action? configure = default, + string? name = default, + HealthStatus? failureStatus = default, + IEnumerable? tags = default, + TimeSpan? timeout = default) => + builder.AddAzureEventHub( + _ => connectionString, + _ => eventHubName, + configure, + name, + failureStatus, + tags, + timeout); + + /// + /// Add a health check for specified Azure Event Hub. + /// + /// The . + /// A factory to build the azure event hub connection string. + /// A factory to build the azure event hub name. + /// An optional action to allow additional Azure Event Hub configuration. + /// The health check name. Optional. If null the type name 'azureeventhub' will be used for the name. + /// + /// The that should be reported when the health check fails. Optional. If null then + /// the default status of will be reported. + /// + /// A list of tags that can be used to filter sets of health checks. Optional. + /// An optional representing the timeout of the check. + /// The specified . + public static IHealthChecksBuilder AddAzureEventHub( + this IHealthChecksBuilder builder, + Func connectionStringFactory, + Func eventHubNameFactory, + Action? configure = default, + string? name = default, + HealthStatus? failureStatus = default, + IEnumerable? tags = default, + TimeSpan? timeout = default) + { + Guard.ThrowIfNull(connectionStringFactory); + Guard.ThrowIfNull(eventHubNameFactory); + + return builder.Add(new HealthCheckRegistration( + name ?? AZUREEVENTHUB_NAME, + sp => + { + var options = new AzureEventHubHealthCheckOptions + { + ConnectionString = connectionStringFactory(sp), + EventHubName = eventHubNameFactory(sp) + }; + + configure?.Invoke(options); + return new AzureEventHubHealthCheck(options); + }, + failureStatus, + tags, + timeout)); + } + + /// + /// Add a health check for specified Azure Event Hub. + /// + /// The . + /// The azure event hub fully qualified namespace. + /// The azure event hub name. + /// The token credential for authentication. + /// An optional action to allow additional Azure Event Hub configuration. + /// The health check name. Optional. If null the type name 'azureeventhub' will be used for the name. + /// + /// The that should be reported when the health check fails. Optional. If null then + /// the default status of will be reported. + /// + /// A list of tags that can be used to filter sets of health checks. Optional. + /// An optional representing the timeout of the check. + /// The specified . + public static IHealthChecksBuilder AddAzureEventHub( + this IHealthChecksBuilder builder, + string fullyQualifiedNamespace, + string eventHubName, + TokenCredential tokenCredential, + Action? configure = default, + string? name = default, + HealthStatus? failureStatus = default, + IEnumerable? tags = default, + TimeSpan? timeout = default) => + builder.AddAzureEventHub( + _ => fullyQualifiedNamespace, + _ => eventHubName, + _ => tokenCredential, + configure, + name, + failureStatus, + tags, + timeout); + + /// + /// Add a health check for specified Azure Event Hub. + /// + /// The . + /// A factory to build the azure event hub fully qualified namespace. + /// A factory to build the azure event hub name. + /// A factory to build the token credential for authentication. + /// An optional action to allow additional Azure Event Hub configuration. + /// The health check name. Optional. If null the type name 'azureeventhub' will be used for the name. + /// + /// The that should be reported when the health check fails. Optional. If null then + /// the default status of will be reported. + /// + /// A list of tags that can be used to filter sets of health checks. Optional. + /// An optional representing the timeout of the check. + /// The specified . + public static IHealthChecksBuilder AddAzureEventHub( + this IHealthChecksBuilder builder, + Func fullyQualifiedNamespaceFactory, + Func eventHubNameFactory, + Func tokenCredentialFactory, + Action? configure = default, + string? name = default, + HealthStatus? failureStatus = default, + IEnumerable? tags = default, + TimeSpan? timeout = default) + { + Guard.ThrowIfNull(fullyQualifiedNamespaceFactory); + Guard.ThrowIfNull(eventHubNameFactory); + Guard.ThrowIfNull(tokenCredentialFactory); + + return builder.Add(new HealthCheckRegistration( + name ?? AZUREEVENTHUB_NAME, + sp => + { + var options = new AzureEventHubHealthCheckOptions + { + FullyQualifiedNamespace = fullyQualifiedNamespaceFactory(sp), + EventHubName = eventHubNameFactory(sp), + Credential = tokenCredentialFactory(sp) + }; + + configure?.Invoke(options); + return new AzureEventHubHealthCheck(options); + }, + failureStatus, + tags, + timeout)); + } + + /// + /// Add a health check for specified Azure Event Hub. + /// + /// The . + /// The event hub connection factory used to create a event hub connection for this health check. + /// An optional action to allow additional Azure Event Hub configuration. + /// The health check name. Optional. If null the type name 'azureeventhub' will be used for the name. + /// + /// The that should be reported when the health check fails. Optional. If null then + /// the default status of will be reported. + /// + /// A list of tags that can be used to filter sets of health checks. Optional. + /// An optional representing the timeout of the check. + /// The specified . + public static IHealthChecksBuilder AddAzureEventHub( + this IHealthChecksBuilder builder, + Func eventHubConnectionFactory, + Action? configure = default, + string? name = default, + HealthStatus? failureStatus = default, + IEnumerable? tags = default, + TimeSpan? timeout = default) + { + Guard.ThrowIfNull(eventHubConnectionFactory); + + return builder.Add(new HealthCheckRegistration( + name ?? AZUREEVENTHUB_NAME, + sp => + { + var options = new AzureEventHubHealthCheckOptions { Connection = eventHubConnectionFactory(sp) }; + configure?.Invoke(options); + return new AzureEventHubHealthCheck(options); + }, + failureStatus, + tags, + timeout)); + } + + /// + /// Add a health check for specified Azure Service Bus Queue. + /// + /// The . + /// The azure service bus connection string to be used. + /// The name of the queue to check. + /// An optional action to allow additional Azure Service Bus configuration. + /// The health check name. Optional. If null the type name 'azurequeue' will be used for the name. + /// + /// The that should be reported when the health check fails. Optional. If null then + /// the default status of will be reported. + /// + /// A list of tags that can be used to filter sets of health checks. Optional. + /// An optional representing the timeout of the check. + /// The specified . + public static IHealthChecksBuilder AddAzureServiceBusQueue( + this IHealthChecksBuilder builder, + string connectionString, + string queueName, + Action? configure = default, + string? name = default, + HealthStatus? failureStatus = default, + IEnumerable? tags = default, + TimeSpan? timeout = default) => + builder.AddAzureServiceBusQueue( + _ => connectionString, + _ => queueName, + configure, + name, + failureStatus, + tags, + timeout); + + /// + /// Add a health check for specified Azure Service Bus Queue. + /// + /// The . + /// A factory to build the azure service bus connection string to be used. + /// A factory to build the queue name to check. + /// An optional action to allow additional Azure Service Bus configuration. + /// The health check name. Optional. If null the type name 'azurequeue' will be used for the name. + /// + /// The that should be reported when the health check fails. Optional. If null then + /// the default status of will be reported. + /// + /// A list of tags that can be used to filter sets of health checks. Optional. + /// An optional representing the timeout of the check. + /// The specified . + public static IHealthChecksBuilder AddAzureServiceBusQueue( + this IHealthChecksBuilder builder, + Func connectionStringFactory, + Func queueNameFactory, + Action? configure = default, + string? name = default, + HealthStatus? failureStatus = default, + IEnumerable? tags = default, + TimeSpan? timeout = default) + { + Guard.ThrowIfNull(connectionStringFactory); + Guard.ThrowIfNull(queueNameFactory); + + return builder.Add(new HealthCheckRegistration( + name ?? AZUREQUEUE_NAME, + sp => + { + var options = new AzureServiceBusQueueHealthCheckOptions(queueNameFactory(sp)) + { + ConnectionString = connectionStringFactory(sp) + }; + + configure?.Invoke(options); + return new AzureServiceBusQueueHealthCheck(options); + }, + failureStatus, + tags, + timeout)); + } + + /// + /// Add a health check for specified Azure Service Bus Queue. + /// + /// The . + /// The azure service bus fully qualified namespace to be used, format sb://myservicebus.servicebus.windows.net/. + /// The name of the queue to check. + /// The token credential for authentication. + /// An optional action to allow additional Azure Service Bus configuration. + /// The health check name. Optional. If null the type name 'azurequeue' will be used for the name. + /// + /// The that should be reported when the health check fails. Optional. If null then + /// the default status of will be reported. + /// + /// A list of tags that can be used to filter sets of health checks. Optional. + /// An optional representing the timeout of the check. + /// The specified . + public static IHealthChecksBuilder AddAzureServiceBusQueue( + this IHealthChecksBuilder builder, + string fullyQualifiedNamespace, + string queueName, + TokenCredential tokenCredential, + Action? configure = default, + string? name = default, + HealthStatus? failureStatus = default, + IEnumerable? tags = default, + TimeSpan? timeout = default) => + builder.AddAzureServiceBusQueue( + _ => fullyQualifiedNamespace, + _ => queueName, + _ => tokenCredential, + configure, + name, + failureStatus, + tags, + timeout); + + /// + /// Add a health check for specified Azure Service Bus Queue. + /// + /// The . + /// A factory to build the azure service bus fully qualified namespace to be used, format sb://myservicebus.servicebus.windows.net/. + /// A factory to build the name of the queue to check. + /// A factory to build the token credential for authentication. + /// An optional action to allow additional Azure Service Bus configuration. + /// The health check name. Optional. If null the type name 'azurequeue' will be used for the name. + /// + /// The that should be reported when the health check fails. Optional. If null then + /// the default status of will be reported. + /// + /// A list of tags that can be used to filter sets of health checks. Optional. + /// An optional representing the timeout of the check. + /// The specified . + public static IHealthChecksBuilder AddAzureServiceBusQueue( + this IHealthChecksBuilder builder, + Func fullyQualifiedNamespaceFactory, + Func queueNameFactory, + Func tokenCredentialFactory, + Action? configure = default, + string? name = default, + HealthStatus? failureStatus = default, + IEnumerable? tags = default, + TimeSpan? timeout = default) + { + Guard.ThrowIfNull(fullyQualifiedNamespaceFactory); + Guard.ThrowIfNull(queueNameFactory); + Guard.ThrowIfNull(tokenCredentialFactory); + + return builder.Add(new HealthCheckRegistration( + name ?? AZUREQUEUE_NAME, + sp => + { + var options = new AzureServiceBusQueueHealthCheckOptions(queueNameFactory(sp)) + { + FullyQualifiedNamespace = fullyQualifiedNamespaceFactory(sp), + Credential = tokenCredentialFactory(sp) + }; + + configure?.Invoke(options); + return new AzureServiceBusQueueHealthCheck(options); + }, + failureStatus, + tags, + timeout)); + } + + /// + /// Add a health check for specified Azure Service Bus Queue active or dead letter messages threshold. + /// + /// The . + /// The azure service bus connection string to be used. + /// The name of the queue to check. + /// The health check name. Optional. If null the type name 'azurequeuethreshold' will be used for the name. + /// An optional action to allow additional Azure Service Bus configuration. + /// + /// The that should be reported when the health check fails. Optional. If null then + /// the default status of will be reported. + /// + /// A list of tags that can be used to filter sets of health checks. Optional. + /// An optional representing the timeout of the check. + /// The . + public static IHealthChecksBuilder AddAzureServiceBusQueueMessageCountThreshold( + this IHealthChecksBuilder builder, + string connectionString, + string queueName, + string? name = default, + Action? configure = null, + HealthStatus? failureStatus = default, + IEnumerable? tags = default, + TimeSpan? timeout = default) + { + Guard.ThrowIfNull(connectionString); + Guard.ThrowIfNull(queueName); + + var options = new AzureServiceBusQueueMessagesCountThresholdHealthCheckOptions(queueName) + { + ConnectionString = connectionString, + }; + + configure?.Invoke(options); + + return builder.Add(new HealthCheckRegistration( + name ?? AZUREQUEUETHRESHOLD_NAME, + sp => new AzureServiceBusQueueMessageCountThresholdHealthCheck(options), + failureStatus, + tags, + timeout)); + } + + /// + /// Add a health check for specified Azure Service Bus Queue active or dead letter messages threshold. + /// + /// The . + /// The azure service bus endpoint to be used, format sb://myservicebus.servicebus.windows.net/. + /// The name of the queue to check. + /// The token credential for authentication. + /// An optional action to allow additional Azure Service Bus configuration. + /// The health check name. Optional. If null the type name 'azurequeuethreshold' will be used for the name. + /// + /// The that should be reported when the health check fails. Optional. If null then + /// the default status of will be reported. + /// + /// A list of tags that can be used to filter sets of health checks. Optional. + /// An optional representing the timeout of the check. + /// The . + public static IHealthChecksBuilder AddAzureServiceBusQueueMessageCountThreshold( + this IHealthChecksBuilder builder, + string endpoint, + string queueName, + TokenCredential tokenCredential, + Action? configure = null, + string? name = default, + HealthStatus? failureStatus = default, + IEnumerable? tags = default, + TimeSpan? timeout = default) + { + Guard.ThrowIfNull(endpoint); + Guard.ThrowIfNull(queueName); + Guard.ThrowIfNull(tokenCredential); + + var options = new AzureServiceBusQueueMessagesCountThresholdHealthCheckOptions(queueName) + { + FullyQualifiedNamespace = endpoint, + Credential = tokenCredential, + }; + + configure?.Invoke(options); + + return builder.Add(new HealthCheckRegistration( + name ?? AZUREQUEUETHRESHOLD_NAME, + sp => new AzureServiceBusQueueMessageCountThresholdHealthCheck(options), + failureStatus, + tags, + timeout)); + } + + /// + /// Add a health check for Azure Service Bus Topic. + /// + /// The . + /// The Azure ServiceBus connection string to be used. + /// The name of the topic to check. + /// An optional action to allow additional Azure Service Bus configuration. + /// The health check name. Optional. If null the type name 'azuretopic' will be used for the name. + /// + /// The that should be reported when the health check fails. Optional. If null then + /// the default status of will be reported. + /// + /// A list of tags that can be used to filter sets of health checks. Optional. + /// An optional representing the timeout of the check. + /// The specified . + public static IHealthChecksBuilder AddAzureServiceBusTopic( + this IHealthChecksBuilder builder, + string connectionString, + string topicName, + Action? configure = default, + string? name = default, + HealthStatus? failureStatus = default, + IEnumerable? tags = default, + TimeSpan? timeout = default) => + builder.AddAzureServiceBusTopic( + _ => connectionString, + _ => topicName, + configure, + name, + failureStatus, + tags, + timeout); + + /// + /// Add a health check for Azure Service Bus Topic. + /// + /// The . + /// A factory to build the Azure ServiceBus connection string to be used. + /// A factory to build the name of the topic to check. + /// An optional action to allow additional Azure Service Bus configuration. + /// The health check name. Optional. If null the type name 'azuretopic' will be used for the name. + /// + /// The that should be reported when the health check fails. Optional. If null then + /// the default status of will be reported. + /// + /// A list of tags that can be used to filter sets of health checks. Optional. + /// An optional representing the timeout of the check. + /// The specified . + public static IHealthChecksBuilder AddAzureServiceBusTopic( + this IHealthChecksBuilder builder, + Func connectionStringFactory, + Func topicNameFactory, + Action? configure = default, + string? name = default, + HealthStatus? failureStatus = default, + IEnumerable? tags = default, + TimeSpan? timeout = default) + { + Guard.ThrowIfNull(connectionStringFactory); + Guard.ThrowIfNull(topicNameFactory); + + return builder.Add(new HealthCheckRegistration( + name ?? AZURETOPIC_NAME, + sp => + { + var options = new AzureServiceBusTopicHealthCheckOptions(topicNameFactory(sp)) + { + ConnectionString = connectionStringFactory(sp) + }; + + configure?.Invoke(options); + return new AzureServiceBusTopicHealthCheck(options); + }, + failureStatus, + tags, + timeout)); + } + + /// + /// Add a health check for Azure Service Bus Topic. + /// + /// The . + /// The azure service bus fully qualified namespace to be used, format sb://myservicebus.servicebus.windows.net/. + /// The name of the topic to check. + /// The token credential for authentication. + /// The health check name. Optional. If null the type name 'azuretopic' will be used for the name. + /// + /// The that should be reported when the health check fails. Optional. If null then + /// the default status of will be reported. + /// + /// A list of tags that can be used to filter sets of health checks. Optional. + /// An optional representing the timeout of the check. + /// The specified . + public static IHealthChecksBuilder AddAzureServiceBusTopic( + this IHealthChecksBuilder builder, + string fullyQualifiedNamespace, + string topicName, + TokenCredential tokenCredential, + string? name = default, + HealthStatus? failureStatus = default, + IEnumerable? tags = default, + TimeSpan? timeout = default) => + builder.AddAzureServiceBusTopic( + _ => fullyQualifiedNamespace, + _ => topicName, + _ => tokenCredential, + configure: null, + name, + failureStatus, + tags, + timeout); + + /// + /// Add a health check for Azure Service Bus Topic. + /// + /// The . + /// A factory to build the azure service bus fully qualified namespace to be used, format sb://myservicebus.servicebus.windows.net/. + /// A factory to build the name of the topic to check. + /// A factory to build the token credential for authentication. + /// An optional action to allow additional Azure Service Bus configuration. + /// The health check name. Optional. If null the type name 'azuretopic' will be used for the name. + /// + /// The that should be reported when the health check fails. Optional. If null then + /// the default status of will be reported. + /// + /// A list of tags that can be used to filter sets of health checks. Optional. + /// An optional representing the timeout of the check. + /// The specified . + public static IHealthChecksBuilder AddAzureServiceBusTopic( + this IHealthChecksBuilder builder, + Func fullyQualifiedNamespaceFactory, + Func topicNameFactory, + Func tokenCredentialFactory, + Action? configure = default, + string? name = default, + HealthStatus? failureStatus = default, + IEnumerable? tags = default, + TimeSpan? timeout = default) + { + Guard.ThrowIfNull(fullyQualifiedNamespaceFactory); + Guard.ThrowIfNull(topicNameFactory); + Guard.ThrowIfNull(tokenCredentialFactory); + + return builder.Add(new HealthCheckRegistration( + name ?? AZURETOPIC_NAME, + sp => + { + var options = new AzureServiceBusTopicHealthCheckOptions(topicNameFactory(sp)) + { + FullyQualifiedNamespace = fullyQualifiedNamespaceFactory(sp), + Credential = tokenCredentialFactory(sp) + }; + + configure?.Invoke(options); + return new AzureServiceBusTopicHealthCheck(options); + }, + failureStatus, + tags, + timeout)); + } + + /// + /// Add a health check for Azure Service Bus Subscription. + /// + /// The . + /// The Azure ServiceBus connection string to be used. + /// The name of the topic to check. + /// The subscription name of the topic subscription to check. + /// An optional action to allow additional Azure Service Bus configuration. + /// The health check name. Optional. If null the type name 'azuretopic' will be used for the name. + /// + /// The that should be reported when the health check fails. Optional. If null then + /// the default status of will be reported. + /// + /// A list of tags that can be used to filter sets of health checks. Optional. + /// An optional representing the timeout of the check. + /// The specified . + public static IHealthChecksBuilder AddAzureServiceBusSubscription( + this IHealthChecksBuilder builder, + string connectionString, + string topicName, + string subscriptionName, + Action? configure = default, + string? name = default, + HealthStatus? failureStatus = default, + IEnumerable? tags = default, + TimeSpan? timeout = default) => + builder.AddAzureServiceBusSubscription( + _ => connectionString, + _ => topicName, + _ => subscriptionName, + configure, + name, + failureStatus, + tags, + timeout); + + /// + /// Add a health check for Azure Service Bus Subscription. + /// + /// The . + /// A factory to build the Azure ServiceBus connection string to be used. + /// A factory to build the name of the topic to check. + /// A factory to build the subscription name of the topic subscription to check. + /// An optional action to allow additional Azure Service Bus configuration. + /// The health check name. Optional. If null the type name 'azuretopic' will be used for the name. + /// + /// The that should be reported when the health check fails. Optional. If null then + /// the default status of will be reported. + /// + /// A list of tags that can be used to filter sets of health checks. Optional. + /// An optional representing the timeout of the check. + /// The specified . + public static IHealthChecksBuilder AddAzureServiceBusSubscription( + this IHealthChecksBuilder builder, + Func connectionStringFactory, + Func topicNameFactory, + Func subscriptionNameFactory, + Action? configure = default, + string? name = default, + HealthStatus? failureStatus = default, + IEnumerable? tags = default, + TimeSpan? timeout = default) + { + Guard.ThrowIfNull(connectionStringFactory); + Guard.ThrowIfNull(topicNameFactory); + Guard.ThrowIfNull(subscriptionNameFactory); + + return builder.Add(new HealthCheckRegistration( + name ?? AZURESUBSCRIPTION_NAME, + sp => + { + var options = new AzureServiceBusSubscriptionHealthCheckHealthCheckOptions(topicNameFactory(sp), subscriptionNameFactory(sp)) + { + ConnectionString = connectionStringFactory(sp) + }; + + configure?.Invoke(options); + return new AzureServiceBusSubscriptionHealthCheck(options); + }, + failureStatus, + tags, + timeout)); + } + + /// + /// Add a health check for Azure Service Bus Subscription. + /// + /// The . + /// The azure service bus fully qualified namespace to be used, format sb://myservicebus.servicebus.windows.net/. + /// The name of the topic to check. + /// The subscription name of the topic subscription to check. + /// The token credential for authentication. + /// An optional action to allow additional Azure Service Bus configuration. + /// The health check name. Optional. If null the type name 'azuretopic' will be used for the name. + /// + /// The that should be reported when the health check fails. Optional. If null then + /// the default status of will be reported. + /// + /// A list of tags that can be used to filter sets of health checks. Optional. + /// An optional representing the timeout of the check. + /// The specified . + public static IHealthChecksBuilder AddAzureServiceBusSubscription( + this IHealthChecksBuilder builder, + string fullyQualifiedNamespace, + string topicName, + string subscriptionName, + TokenCredential tokenCredential, + Action? configure = default, + string? name = default, + HealthStatus? failureStatus = default, + IEnumerable? tags = default, + TimeSpan? timeout = default) => + builder.AddAzureServiceBusSubscription( + _ => fullyQualifiedNamespace, + _ => topicName, + _ => subscriptionName, + _ => tokenCredential, + configure, + name, + failureStatus, + tags, + timeout); + + /// + /// Add a health check for Azure Service Bus Subscription. + /// + /// The . + /// A factory to build the azure service bus fully qualified namespace to be used, format sb://myservicebus.servicebus.windows.net/. + /// A factory to build the name of the topic to check. + /// A factory to build the subscription name of the topic subscription to check. + /// A factory to build the token credential for authentication. + /// An optional action to allow additional Azure Service Bus configuration. + /// The health check name. Optional. If null the type name 'azuretopic' will be used for the name. + /// + /// The that should be reported when the health check fails. Optional. If null then + /// the default status of will be reported. + /// + /// A list of tags that can be used to filter sets of health checks. Optional. + /// An optional representing the timeout of the check. + /// The specified . + public static IHealthChecksBuilder AddAzureServiceBusSubscription( + this IHealthChecksBuilder builder, + Func fullyQualifiedNamespaceFactory, + Func topicNameFactory, + Func subscriptionNameFactory, + Func tokenCredentialFactory, + Action? configure = default, + string? name = default, + HealthStatus? failureStatus = default, + IEnumerable? tags = default, + TimeSpan? timeout = default) + { + Guard.ThrowIfNull(fullyQualifiedNamespaceFactory); + Guard.ThrowIfNull(topicNameFactory); + Guard.ThrowIfNull(subscriptionNameFactory); + Guard.ThrowIfNull(tokenCredentialFactory); + + return builder.Add(new HealthCheckRegistration( + name ?? AZURESUBSCRIPTION_NAME, + sp => + { + var options = new AzureServiceBusSubscriptionHealthCheckHealthCheckOptions(topicNameFactory(sp), subscriptionNameFactory(sp)) + { + FullyQualifiedNamespace = fullyQualifiedNamespaceFactory(sp), + Credential = tokenCredentialFactory(sp) + }; + + configure?.Invoke(options); + return new AzureServiceBusSubscriptionHealthCheck(options); + }, + failureStatus, + tags, + timeout)); + } +} diff --git a/test/HealthChecks.AzureServiceBus.Tests/DependencyInjection/AzureServiceBusQueueMessageThresholdCountUnitTests.cs b/test/HealthChecks.AzureServiceBus.Tests/DependencyInjection/AzureServiceBusQueueMessageThresholdCountUnitTests.cs new file mode 100644 index 0000000000..36ec4bad0a --- /dev/null +++ b/test/HealthChecks.AzureServiceBus.Tests/DependencyInjection/AzureServiceBusQueueMessageThresholdCountUnitTests.cs @@ -0,0 +1,55 @@ +namespace HealthChecks.AzureServiceBus.Tests.DependencyInjection; + +public class azure_service_bus_queue_message_threshold_registration_should +{ + [Fact] + public void add_health_check_when_properly_configured() + { + var services = new ServiceCollection(); + services.AddHealthChecks() + .AddAzureServiceBusQueueMessageCountThreshold("cnn", "queueName"); + + using var serviceProvider = services.BuildServiceProvider(); + var options = serviceProvider.GetRequiredService>(); + + var registration = options.Value.Registrations.First(); + var check = registration.Factory(serviceProvider); + + registration.Name.ShouldBe("azurequeuethreshold"); + check.ShouldBeOfType(); + } + + [Fact] + public void add_named_health_check_when_properly_configured() + { + var services = new ServiceCollection(); + services.AddHealthChecks() + .AddAzureServiceBusQueueMessageCountThreshold("cnn", "queueName", + name: "azureservicebusqueuemessagethresholdcheck"); + + using var serviceProvider = services.BuildServiceProvider(); + var options = serviceProvider.GetRequiredService>(); + + var registration = options.Value.Registrations.First(); + var check = registration.Factory(serviceProvider); + + registration.Name.ShouldBe("azureservicebusqueuemessagethresholdcheck"); + check.ShouldBeOfType(); + } + + [Fact] + public void fail_when_no_health_check_configuration_provided() + { + var services = new ServiceCollection(); + services.AddHealthChecks() + .AddAzureServiceBusQueue(string.Empty, string.Empty); + + using var serviceProvider = services.BuildServiceProvider(); + var options = serviceProvider.GetRequiredService>(); + + var registration = options.Value.Registrations.First(); + var factory = () => registration.Factory(serviceProvider); + + factory.ShouldThrow(); + } +} diff --git a/test/HealthChecks.AzureServiceBus.Tests/DependencyInjection/AzureServiceBusQueueMessageThresholdCountUnitWithTokenUnitTests.cs b/test/HealthChecks.AzureServiceBus.Tests/DependencyInjection/AzureServiceBusQueueMessageThresholdCountUnitWithTokenUnitTests.cs new file mode 100644 index 0000000000..f15e4af2c3 --- /dev/null +++ b/test/HealthChecks.AzureServiceBus.Tests/DependencyInjection/AzureServiceBusQueueMessageThresholdCountUnitWithTokenUnitTests.cs @@ -0,0 +1,63 @@ +using Azure.Core; + +namespace HealthChecks.AzureServiceBus.Tests.DependencyInjection; + +public class azure_service_bus_queue_message_threshold_registration_with_token_should +{ + [Fact] + public void add_health_check_when_properly_configured() + { + var services = new ServiceCollection(); + services.AddHealthChecks() + .AddAzureServiceBusQueueMessageCountThreshold("cnn", "queueName", new MockTokenCredentials()); + + using var serviceProvider = services.BuildServiceProvider(); + var options = serviceProvider.GetRequiredService>(); + + var registration = options.Value.Registrations.First(); + var check = registration.Factory(serviceProvider); + + registration.Name.ShouldBe("azurequeuethreshold"); + check.ShouldBeOfType(); + } + + [Fact] + public void add_named_health_check_when_properly_configured() + { + var services = new ServiceCollection(); + services.AddHealthChecks() + .AddAzureServiceBusQueueMessageCountThreshold("cnn", "queueName", new MockTokenCredentials(), + name: "azureservicebusqueuemessagethresholdcheck"); + + using var serviceProvider = services.BuildServiceProvider(); + var options = serviceProvider.GetRequiredService>(); + + var registration = options.Value.Registrations.First(); + var check = registration.Factory(serviceProvider); + + registration.Name.ShouldBe("azureservicebusqueuemessagethresholdcheck"); + check.ShouldBeOfType(); + } + + [Fact] + public void fail_when_no_health_check_configuration_provided() + { + var services = new ServiceCollection(); + services.AddHealthChecks() + .AddAzureServiceBusQueueMessageCountThreshold(string.Empty, string.Empty, new MockTokenCredentials()); + + using var serviceProvider = services.BuildServiceProvider(); + var options = serviceProvider.GetRequiredService>(); + + var registration = options.Value.Registrations.First(); + var factory = () => registration.Factory(serviceProvider); + + factory.ShouldThrow(); + } +} + +public class MockTokenCredentials : TokenCredential +{ + public override AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken) => throw new NotImplementedException(); + public override ValueTask GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken) => throw new NotImplementedException(); +} diff --git a/test/HealthChecks.AzureServiceBus.Tests/HealthChecks.AzureServiceBus.approved.txt b/test/HealthChecks.AzureServiceBus.Tests/HealthChecks.AzureServiceBus.approved.txt index d51361b275..b260fea34d 100644 --- a/test/HealthChecks.AzureServiceBus.Tests/HealthChecks.AzureServiceBus.approved.txt +++ b/test/HealthChecks.AzureServiceBus.Tests/HealthChecks.AzureServiceBus.approved.txt @@ -24,6 +24,12 @@ namespace HealthChecks.AzureServiceBus protected override string ConnectionKey { get; } public System.Threading.Tasks.Task CheckHealthAsync(Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckContext context, System.Threading.CancellationToken cancellationToken = default) { } } + public class AzureServiceBusQueueMessageCountThresholdHealthCheck : HealthChecks.AzureServiceBus.AzureServiceBusHealthCheck, Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheck + { + public AzureServiceBusQueueMessageCountThresholdHealthCheck(HealthChecks.AzureServiceBus.Configuration.AzureServiceBusQueueMessagesCountThresholdHealthCheckOptions options) { } + protected override string ConnectionKey { get; } + public System.Threading.Tasks.Task CheckHealthAsync(Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckContext context, System.Threading.CancellationToken cancellationToken = default) { } + } public class AzureServiceBusSubscriptionHealthCheck : HealthChecks.AzureServiceBus.AzureServiceBusHealthCheck, Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheck { public AzureServiceBusSubscriptionHealthCheck(HealthChecks.AzureServiceBus.Configuration.AzureServiceBusSubscriptionHealthCheckHealthCheckOptions options) { } @@ -61,6 +67,18 @@ namespace HealthChecks.AzureServiceBus.Configuration public string QueueName { get; set; } public bool UsePeekMode { get; set; } } + public struct AzureServiceBusQueueMessagesCountThreshold + { + public AzureServiceBusQueueMessagesCountThreshold() { } + public int DegradedThreshold { get; set; } + public int UnhealthyThreshold { get; set; } + } + public class AzureServiceBusQueueMessagesCountThresholdHealthCheckOptions : HealthChecks.AzureServiceBus.Configuration.AzureServiceBusQueueHealthCheckOptions + { + public AzureServiceBusQueueMessagesCountThresholdHealthCheckOptions(string queueName) { } + public HealthChecks.AzureServiceBus.Configuration.AzureServiceBusQueueMessagesCountThreshold? ActiveMessages { get; set; } + public HealthChecks.AzureServiceBus.Configuration.AzureServiceBusQueueMessagesCountThreshold? DeadLetterMessages { get; set; } + } public class AzureServiceBusSubscriptionHealthCheckHealthCheckOptions : HealthChecks.AzureServiceBus.Configuration.AzureServiceBusTopicHealthCheckOptions { public AzureServiceBusSubscriptionHealthCheckHealthCheckOptions(string topicName, string subscriptionName) { } @@ -86,6 +104,8 @@ namespace Microsoft.Extensions.DependencyInjection public static Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder AddAzureServiceBusQueue(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder builder, string connectionString, string queueName, System.Action? configure = null, string? name = null, Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus? failureStatus = default, System.Collections.Generic.IEnumerable? tags = null, System.TimeSpan? timeout = default) { } public static Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder AddAzureServiceBusQueue(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder builder, System.Func fullyQualifiedNamespaceFactory, System.Func queueNameFactory, System.Func tokenCredentialFactory, System.Action? configure = null, string? name = null, Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus? failureStatus = default, System.Collections.Generic.IEnumerable? tags = null, System.TimeSpan? timeout = default) { } public static Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder AddAzureServiceBusQueue(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder builder, string fullyQualifiedNamespace, string queueName, Azure.Core.TokenCredential tokenCredential, System.Action? configure = null, string? name = null, Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus? failureStatus = default, System.Collections.Generic.IEnumerable? tags = null, System.TimeSpan? timeout = default) { } + public static Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder AddAzureServiceBusQueueMessageCountThreshold(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder builder, string connectionString, string queueName, string? name = null, System.Action? configure = null, Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus? failureStatus = default, System.Collections.Generic.IEnumerable? tags = null, System.TimeSpan? timeout = default) { } + public static Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder AddAzureServiceBusQueueMessageCountThreshold(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder builder, string endpoint, string queueName, Azure.Core.TokenCredential tokenCredential, System.Action? configure = null, string? name = null, Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus? failureStatus = default, System.Collections.Generic.IEnumerable? tags = null, System.TimeSpan? timeout = default) { } public static Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder AddAzureServiceBusSubscription(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder builder, System.Func connectionStringFactory, System.Func topicNameFactory, System.Func subscriptionNameFactory, System.Action? configure = null, string? name = null, Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus? failureStatus = default, System.Collections.Generic.IEnumerable? tags = null, System.TimeSpan? timeout = default) { } public static Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder AddAzureServiceBusSubscription(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder builder, string connectionString, string topicName, string subscriptionName, System.Action? configure = null, string? name = null, Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus? failureStatus = default, System.Collections.Generic.IEnumerable? tags = null, System.TimeSpan? timeout = default) { } public static Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder AddAzureServiceBusSubscription(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder builder, System.Func fullyQualifiedNamespaceFactory, System.Func topicNameFactory, System.Func subscriptionNameFactory, System.Func tokenCredentialFactory, System.Action? configure = null, string? name = null, Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus? failureStatus = default, System.Collections.Generic.IEnumerable? tags = null, System.TimeSpan? timeout = default) { }