Native Integration with Azure Service Bus Transport

Component: Azure Service Bus Transport | Nuget: NServiceBus.Azure.Transports.WindowsAzureServiceBus (Version: 7.x)
Target NServiceBus Version: 6.x

Prerequisites

An environment variable named AzureServiceBus.ConnectionString with the connection string for the Azure Service Bus namespace.

Azure Service Bus Transport

This sample utilizes the Azure Service Bus Transport.

Code walk-through

This sample shows how to send a message from non-NServiceBus code using the Azure Service Bus API and process it with an NServiceBus endpoint using the Azure Service Bus transport.

The sample contains two executable projects:

  • NativeSender - sends a native BrokeredMessage messages to a queue.
  • Receiver - NServiceBus endpoint that processes messages sent by NativeSender.

Sending messages with native Azure Service Bus API

Configuring the native sender to send messages to the queue used by the receiving endpoint is required when integrating the Azure Service Bus sender with NServiceBus endpoints. By default, the input queue for an NServiceBus endpoint is its endpoint name.

Edit
var endpointConfiguration = new EndpointConfiguration("Samples.ASB.NativeIntegration");

The native sender is using queue client to send a BrokeredMessage.

Message serialization

The Azure Service Bus transport is using the JSON serializer by default. Therefore, the message sent by a native sender needs to be valid JSON.

Edit
var nativeMessage = @"{""Content"":""Hello from native sender"",""SendOnUtc"":""2015-10-27T20:47:27.4682716Z""}";

To generate a serialized message, the MessageGenerator project can be used with the unit test named Generate under the SerializedMessageGenerator test fixture.

BrokeredMessage body format

The Azure Service Bus API allows the construction of a BrokeredMessage body from a stream or an object that will get serialized by the internals of BrokeredMessage.

Both the sender (native or NServiceBus) and the receiver must agree on the convention used for sending the message body.

Required headers

For a native message to be processed, NServiceBus endpoints using the Azure Service Bus transport require two headers:

  1. Message type
  2. BrokeredMessage body type

These headers need to be stored as BrokeredMessage properties.

Edit
message.Properties["NServiceBus.EnclosedMessageTypes"] = "NativeMessage";
message.Properties["Transport-Encoding"] = "application/octect-stream";
The NServiceBus.EnclosedMessageTypes property must contain the message type expected by the NServiceBus endpoint. Message type should include namespace it's contained in.

The message itself is defined as an IMessage in the Shared project.

To specify a message ID different from the underlying transport message ID (BrokeredMessage.MessageId), set the NServiceBus.MessageId header on the native message with the desired message ID.
Edit
public class NativeMessage :
    IMessage
{
    public string Content { get; set; }
    public DateTime SendOnUtc { get; set; }
}

NServiceBus receiving endpoint

The receiver is defining how to get the Azure Service Bus transport message body by specifying a strategy using BrokeredMessageBodyConversion.

Edit
var transport = endpointConfiguration.UseTransport<AzureServiceBusTransport>();
var topologySettings = transport.UseEndpointOrientedTopology();
topologySettings.BrokeredMessageBodyType(SupportedBrokeredMessageBodyTypes.Stream);
Both the sender (native or NServiceBus) and the receiver have to agree on the convention used for sending the message body.

Handling messages from native sender in an NServiceBus endpoint

Once the message is received by the NServiceBus endpoint, its contents will be presented.

Edit
public class NativeMessageHandler :
    IHandleMessages<NativeMessage>
{
    static ILog log = LogManager.GetLogger<NativeMessageHandler>();

    public Task Handle(NativeMessage message, IMessageHandlerContext context)
    {
        log.Info($"Message content: {message.Content}");
        log.Info($"Received native message sent on {message.SendOnUtc} UTC");
        return Task.CompletedTask;
    }
}

Things to note

  • The use of the AzureServiceBus.ConnectionString environment variable mentioned above.
  • The use of UseSingleBrokerQueue prevents the Azure Service Bus transport individualizing queue names by appending the machine name.
  • Execute Receiver first to create destination queue NativeSender will need to send native messages.

Related Articles


Last modified