Azure Service Bus Plugins

Plugins

For a very long time Azure Service Bus client WindowsAzure.ServiceBus/ was a black box. When it came to the customization of the message payload, it would allow choosing on serialization, and that's pretty much it. Message IDs were always generated as random Guids and were required to be overwritten to comply with project requirements. Needed to secure the payload? You'd need to have that code to operate on the data before it would become BrokeredMessage payload.

These are the hardships of the old client though. With the new client, Microsoft.Azure.ServiceBus things are different. With support for extensibility, the new client offers a simple incoming and outgoing pipelines. These pipelines take plugins that have a relatively simple API but can help immensely with message customization when it's sent or received. This is what a plugin skeleton looks like (at the time of writing, this is still in preview):

public abstract class ServiceBusPlugin
{
  public abstract string Name { get; }
  public virtual bool ShouldContinueOnException => false;
  public virtual Task<Message> BeforeMessageSend(Message message)
  {
      return Task.FromResult(message);
  }
  public virtual Task<Message> AfterMessageReceive(Message message)
  {
      return Task.FromResult(message);
  }
}

In the previous post, I've already talked about MessageIdPlugin and KeyVaultPlugin. In this post, I'd like to extend the topic by demonstrating another power that plugins bring to the game.

Sending large messages

How large message can be?

Today it's 256KB/1MB including headers.

Isn't that a solved problem already? That's what Claim Check pattern is for.

While claim check pattern is indeed the way to go, it is distracting from the actual code you most likely trying to get out - sending messages. Remember, another level of indirection can solve a problem. For sending and receiving large messages that could be a claim check plugin. A message exceeding maximum size would be saved to a blob, reference attached to the message, and upon receive payload would be read back and associated with the message. More than that, a plugin could determine based on some custom logic at what point a message should be "offloaded" to a blob or not. Criteria could be payload size or message type for example.

Meet ServiceBus.AttachmentPlugin

And that's exactly what ServiceBus.AttachmentPlugin is. Harvesting the power of OSS extensibility and NuGet packaging it implements Claim Check pattern plugin for the new ASB client.

To use the plugin, a connection string to Storage account is required. With Storage connection string, the plugin can be configured and used

Configuration and registration

var sender = new MessageSender(connectionString, queueName);
var config = new AzureStorageAttachmentConfiguration(storageConnectionString);
var plugin = new AzureStorageAttachment(config);
sender.RegisterPlugin(plugin);

Sending

var payload = new MyMessage { ... }; 
var serialized = JsonConvert.SerializeObject(payload);
var payloadAsBytes = Encoding.UTF8.GetBytes(serialized);
var message = new Message(payloadAsBytes);

Receiving

var receiver = new MessageReceiver(connectionString, entityPath, ReceiveMode.ReceiveAndDelete);
receiver.RegisterPlugin(plugin);
var msg = await receiver.ReceiveAsync();
// msg will contain the original payload

Configuration applies the defaults, which can be overriden.

Visual of a sample message sent with the plugin.

Seeing is believing

Install-Package ServiceBus.AttachmentPlugin -Pre

Found issues or have suggestions? Raise those here.

No Comments