All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Added
- Introduced SendDispatch methods on DispatchSender. Those methods allow to send single message bigger than 1MB
- Changed
- skip transaction renaming when ServiceBus instrumentation is missing
- Changed
- Fix diagnostic id null reference
- Changed
- Fix logging scope formatting
- Add span with span link to the process transaction to have link with the producer
- Open telemetry
- Fix Transaction to follow Open telemetry standard with Span links
- Open telemetry
- Fix a problem where the nuget Ev.ServiceBus.Apm was not produced
- Added
- MessageReceptionBuilder
- Exposed
HandlerType
inMessageReceptionBuilder
. - Exposed
PayloadType
inMessageReceptionBuilder
.
- Exposed
- new categorized Logging
- Ev.ServiceBus.LoggingExtensions.MessageProcessing : For logs related to message processing
- Ev.ServiceBus.LoggingExtensions.ServiceBusClientManagement : For logs related to creation of client / disposition of clients
- Ev.ServiceBus.LoggingExtensions.ServiceBusEngine : For logs related to the initialization of the Host
- Ev.ServiceBus.HealthChecks.LoggingExtensionsHealthChecks : For logs related to service bus health checks registration
- New telemetryOptions
- ActivitySource (Ev.ServiceBus) for message processing
- Ev.ServiceBus.Apm : Elastic Apm integration
- MessageReceptionBuilder
- Modified
- Reduce number of log entries and duplicate exception logging
- Use of high performance logging mechanism
[Breaking]
The exception catched during IMessageHandler was changed to FailedToProcessMessageException
Original exception is stored in the inner exception if you are using IExceptionHandler use this to get original message
public class CustomExceptionHandler : IExceptionHandler
{
public Task HandleExceptionAsync(ProcessErrorEventArgs args)
{
var original = exceptionEvent.Exception is FailedToProcessMessageException wrapperException
? wrapperException.InnerException!
: exceptionEvent.Exception!;
return Task.CompletedTask;
}
}
- Removed obsolete methods and related code :
services.RegisterServiceBusQueue("queueName");
services.RegisterServiceBusTopic("topicName");
services.RegisterServiceBusSubscription("topicName", "subscriptionName");
- Ev.ServiceBus doesn't require you to define a payload serializer anymore. By default, System.Text.Json will be used as a serializer.
- Added
services.AddServiceBus().WithPayloadSerializer<TMessagePayloadSerializer>();
that allows you to specify a serializer.
- Added .NET 8 support
- Changed - Azure.ServiceBus nuget updated to v 7.17.0
- Fixed a bug about .AddEvServiceBusChecks(), if didn't you call that before any other code that registers IConfigureOptions, it would not be registered.
- Improved
IMessagePublisher.Publish<TMessagePayload>(TMessagePayload messageDto, Action<IDispatchContext> messageContextConfiguration)
method to be able to set custom application properties to a dispatch
- IMessageDispatcher.ExecuteDispatches method has now CancellationToken support.
- Added IDispatchExtender interface that allows you to access and update outgoing message just before they are sent.
- Refactored internals of Ev.ServiceBus to put MessageReceptionRegistration in the MessageContext.
- MessageReceptionRegistration is now accessible in the IServiceBusEventListener interface.
- Changed - Azure.ServiceBus nuget updated to v 7.12.0
- Added DiagnosticID (traceparent) support for publisher / dispatcher in case of end to end tracing (according: Distributed tracing and correlation through Service Bus messaging)
- Added the MessageId property to the MessageContext class to allow MessageId customization on publish
- Made some internal methods public in IServiceBusRegistry class
- Changed the dispatch Sender to use ServiceBusMessageBatch and optimize message sending.
- Added methods to Schedule dispatches
- Removed usages of netcore3.1 and net5 frameworks.
- made the registration of resources case insensitive.
- Update the
IMessageMetadata
interface to expose all metadata properties of the receiving message as well as the methods to complete/abandon/deadletter/defer said message.
- Resolved a bug where putting a '/' in PayloadTypeIds of message contracts will make the AsyncUi json not valid.
- Removed EventTypeId related code.
- Healthchecks are now disabled when Ev.ServiceBus is disabled.
- Connections won't be created anymore when Ev.ServiceBus is disabled.
- Added method overloads for
RegisterDispatch
andRegisterReception
Which are not templated. - Made old registration method obsolete.
- merged v3.7.0 with v4.1.0
- CorrelationId is now created automatically and is being passed to newly published events.
- Added method overload enabling you to publish a message with a specific correlationId.
- refactored the entire project to use Azure.Messaging.ServiceBus
- Made the matching of payloadTypeIds less strict by making it case-insensitive.
- Added method overloads enabling you to publish a message with a specific sessionId.
- Clients can now receive message in session mode.
- Added net6.0 as target framework.
- Added IMessageMetadataAccessor service that allows you to access data like correlationId or user properties of the underlying message.
- Added
Ev.ServiceBus.AsyncApi
package. It helps you generate an AsyncApi schema with Ev.ServiceBus registrations.
- Added log messages that tells if Ev.ServiceBus is deactivated or if only reception is deactivated.
- Ev.ServiceBus.HealthChecks is now compatible with netcore3.1
- Refactored internal registration of dispatches and receptions.
- Added
IServiceBusEventListener
interface that lets you hook up to the internal eventsstart
,succeeded
andfailed
.
- Add custom tags for health check
- Fixed an issue where messages were not sent anymore on the dead letter queue
-
The main Api has been redesigned to reduce the number of lines of code necessary to configure it.
Example of old API :
services.ConfigureServiceBus(options =>
{
options.RegisterSubscription("mytopic", "mysubscription")
.WithConnectionString(serviceBusConnectionString)
.ToIntegrationEventHandling();
});
services.RegisterIntegrationEventSubscription<MyEvent1, MyEvent1Handler>(builder =>
{
builder.EventTypeId = "MyEvent1";
builder.ReceiveFromSubscription("mytopic", "mysubscription");
});
services.RegisterIntegrationEventSubscription<MyEvent2, MyEvent2Handler>(builder =>
{
builder.EventTypeId = "MyEvent2";
builder.ReceiveFromSubscription("mytopic", "mysubscription");
});
services.RegisterIntegrationEventSubscription<MyEvent3, MyEvent3Handler>(builder =>
{
builder.EventTypeId = "MyEvent3";
builder.ReceiveFromSubscription("mytopic", "mysubscription");
});
Example of new API :
services.RegisterServiceBusReception().FromSubscription("mytopic", "mysubscription", builder => {
builder.RegisterReception<MyEvent1, MyEvent1Handler>();
builder.RegisterReception<MyEvent2, MyEvent2Handler>();
builder.RegisterReception<MyEvent3, MyEvent3Handler>();
});
- Added the ability to automatically serialize objects into messages and send them to a topic or queue depending on configuration.
- Added the ability to automatically deserialize messages into objects that are received and process them into specific handlers depending on configuration.
- The PayloadTypeId is now automatically generated and uses the type's simple name.
- Queue are now fully supported for message reception.
- Registration of underlying senders/receivers is now automatic.
- The NuGet packages now properly target multiple frameworks including net5
- The protocol now uses the user property named 'PayloadTypeId' instead of 'EventTypeId' to resolve routing (The old user property is still provided for retro-compatibility purposes).
- Added logging messages when a message is sent.
- Upon reception of a message, a log scope is now created to pass useful information (such as the name of the resource the received message is coming from)
- Added Ev.ServiceBus.HealthChecks NuGet package : it's goal is to automatically register Ev.ServiceBus registrations as healthCheck registrations.
- Added Ev.ServiceBus.Mvc NuGet package : it's goal is to better integrate Ev.ServiceBus with MVC components of Asp.Net Core
- The method
services.ConfigureServiceBus()
has been replaced:// this method has been removed public static IServiceCollection ConfigureServiceBus(this IServiceCollection services, Action<ServiceBusOptions> config); // and replaced by these public static QueueOptions RegisterServiceBusQueue(this IServiceCollection services, string queueName); public static TopicOptions RegisterServiceBusTopic(this IServiceCollection services, string topicName); public static SubscriptionOptions RegisterServiceBusSubscription(this IServiceCollection services, string topicName, string subscriptionName);
- The methods used to set connection settings on a registration have also been replaced :
// these methods have been remmoved public static TOptions WithConnectionString<TOptions>(this TOptions options, string connectionString) where TOptions : ClientOptions; public static TOptions WithConnection<TOptions>(this TOptions options, ServiceBusConnection connection); public static TOptions WithConnectionStringBuilder<TOptions>(this TOptions options, ServiceBusConnectionStringBuilder connectionStringBuilder) where TOptions : ClientOptions; public static TOptions WithReceiveMode<TOptions>(this TOptions options, ReceiveMode receiveMode); public static TOptions WithRetryPolicy<TOptions>(this TOptions options, RetryPolicy retryPolicy); // and replaces by these public static TOptions WithConnection<TOptions>(this TOptions options, string connectionString, ReceiveMode receiveMode = ReceiveMode.PeekLock, RetryPolicy? retryPolicy = null) where TOptions : ClientOptions; public static TOptions WithConnection<TOptions>(this TOptions options, ServiceBusConnection connection, ReceiveMode receiveMode = ReceiveMode.PeekLock, RetryPolicy? retryPolicy = null) where TOptions : ClientOptions; public static TOptions WithConnection<TOptions>(this TOptions options, ServiceBusConnectionStringBuilder connectionStringBuilder, ReceiveMode receiveMode = ReceiveMode.PeekLock, RetryPolicy? retryPolicy = null) where TOptions : ClientOptions;
- Refactored the
services.AddServiceBus()
to be more extensible :// old method public static IServiceCollection AddServiceBus(this IServiceCollection services, bool enabled = true, bool receiveMessages = true); // new method public static IServiceCollection AddServiceBus(this IServiceCollection services, Action<ServiceBusSettings> config);
- Added the ability to set default connection settings :
services.AddServiceBus(settings => { settings.WithConnection(connectionString); });
- All log messages are now prefixed with "[Ev.ServiceBus]"
- Microsoft.Azure.ServiceBus NuGet package has been updated to v5.1.0
- The method
.WithCustomMessageHandler()
now registers the handler into the IOC container (before you needed to register it yourself)
- Added
.ConfigureAwait(false)
to async calls.
- added log for message processing time
- removed closing behavior when an exception occurs.
- Documentation
- Moving around a bit of code. No functionality changed.
- Added a boolean
Enabled
that controls whether Ev.ServiceBus is activated or not in the server. - Added a boolean
ReceiveMessages
that controls Ev.ServiceBus will listen or not to messages.
- The exception handling during reception of a message has drastically changed. Now it will close the client at the first exception received by the exception handler.
- A control parameter at exception handler execution allows for disabling this feature.
- This change has been done to prevent the client from flooding the logs with repetitive errors.
- A critical log is produced whenever a client is closed that way.
- The application will need to be restarted to resolve the issue.
- Now the nuget is built with several target platforms instead of just netstandard2.0:
- netstandard2.0
- net48
- netcoreapp2.2
- netcoreapp3
services.AddServiceBus();
method can now be called several times without harm- updated nuget
Microsoft.Azure.ServiceBus
to version 4.1.1.
- Added
WithConnection
method that allows you to provide aServiceBusConnection
object instead of a connection string. - Added
WithConnectionStringBuilder
method that allows you to provideServiceBusConnectionStringBuilder
object instead of a connection string. - Added
WithReceiveMode
method that allows you to set the ReceiveMode for the registered clients. - Added
WithRetryPolicy
method that allows you to set the retry policy for the registered clients.
Examples:
services.ConfigureServiceBus(options =>
{
options.RegisterServiceBusQueue("MyQueue")
.WithConnection(new ServiceBusConnection(""))
.WithReceiveMode(ReceiveMode.PeekLock)
.WithRetryPolicy(RetryPolicy.NoRetry);
options.RegisterServiceBusTopic("MyTopic")
.WithConnectionStringBuilder(new ServiceBusConnectionStringBuilder())
.WithRetryPolicy(RetryPolicy.NoRetry);
options.RegisterServiceBusSubscription("MyTopic", "MySubscription")
.WithConnectionString("")
.WithReceiveMode(ReceiveMode.ReceiveAndDelete)
.WithRetryPolicy(RetryPolicy.NoRetry);
});
- Added
ClientType
information in theIMessageReceiver
interface. - Added
ClientType
information in theIMessageSender
interface. - Added
GetQueueSender
in theIServiceBusRegistry
interface. - Added
GetTopicSender
in theIServiceBusRegistry
interface. - Added a mechanism that throttles the log of the
MessagingEntityNotFoundException
exception.
QueueSenderNotFoundException
exception will now be thrown when you try to get a sender that is not in the registry.TopicSenderNotFoundException
exception will now be thrown when you try to get a sender that is not in the registry.DuplicateQueueRegistrationException
exception will now be thrown when you try to register the same resource twice.DuplicateSubscriptionRegistrationException
exception will now be thrown when you try to register the same resource twice.DuplicateTopicRegistrationException
exception will now be thrown when you try to register the same resource twice.
- Removed
RegisterMessageHandler
methods fromIMessageReceiver
interface. - Removed
GetMessageReceiver
method from theIServiceBusRegistry
interface. - Removed
GetMessageSender
method from theIServiceBusRegistry
interface.