2023-12-14: The latest ASB SDK doesn't support plugins and requires inheritance. See details in #201.
2021-07-14: Consider using native Azure Service Bus service large messages feature for attachments up-to 100 MB.
This is a plugin for Microsoft.Azure.ServiceBus client
Allows sending messages that exceed maximum size by implementing Claim Check pattern with Azure Storage.
Available here http://nuget.org/packages/ServiceBus.AttachmentPlugin
To Install from the Nuget Package Manager Console
PM> Install-Package ServiceBus.AttachmentPlugin
- Examples
- Convert body into attachment, no matter how big it is
- Sending a message without exposing the storage account to receivers
- Configure blob container name
- Configure message property to identify attachment blob
- Configure custom blob name override
- Configure message property for SAS uri to attachment blob
- Configure criteria for message max size identification
- Configuring connection string provider
- Configuring plugin using StorageCredentials (Service or Container SAS)
- Using attachments with Azure Functions
- Cleanup
- Who's trusting this plugin in production
- Icon
Configuration and registration
var sender = new MessageSender(connectionString, queueName);
var config = new AzureStorageAttachmentConfiguration(storageConnectionString);
sender.RegisterAzureStorageAttachmentPlugin(config);
Sending
var payload = new MyMessage
{
MyProperty = "The Value"
};
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.RegisterAzureStorageAttachmentPlugin(config);
var message = await receiver.ReceiveAsync().ConfigureAwait(false);
// message will contain the original payload
Configuration and registration with blob SAS URI
var sender = new MessageSender(connectionString, queueName);
var config = new AzureStorageAttachmentConfiguration(storageConnectionString)
.WithBlobSasUri(
sasTokenValidationTime: TimeSpan.FromHours(4),
messagePropertyToIdentifySasUri: "mySasUriProperty");
sender.RegisterAzureStorageAttachmentPlugin(config);
Sending
var payload = new MyMessage
{
MyProperty = "The Value"
};
var serialized = JsonConvert.SerializeObject(payload);
var payloadAsBytes = Encoding.UTF8.GetBytes(serialized);
var message = new Message(payloadAsBytes);
Receiving only mode (w/o Storage account credentials)
// Override message property used to identify SAS URI
// .RegisterAzureStorageAttachmentPluginForReceivingOnly() is using "$attachment.sas.uri" by default
messageReceiver.RegisterAzureStorageAttachmentPluginForReceivingOnly("mySasUriProperty");
var message = await messageReceiver.ReceiveAsync().ConfigureAwait(false);
Default container name is "attachments". The value is available via AzureStorageAttachmentConfigurationConstants.DefaultContainerName
constant.
new AzureStorageAttachmentConfiguration(storageConnectionString, containerName:"blobs");
Default blob identifier property name is "$attachment.blob". The value is available via AzureStorageAttachmentConfigurationConstants.DefaultMessagePropertyToIdentifyAttachmentBlob
constant.
new AzureStorageAttachmentConfiguration(storageConnectionString, messagePropertyToIdentifyAttachmentBlob: "myblob");
Default blob name is a GUID.
var sender = new MessageSender(connectionString, queueName);
var config = new AzureStorageAttachmentConfiguration(storageConnectionString)
.OverrideBlobName(message =>
{
var tenantId = message.UserProperties["tenantId"].ToString();
var blobName = $"{tenantId}/{message.MessageId}";
return blobName;
});
sender.RegisterAzureStorageAttachmentPlugin(config);
Default SAS uri property name is "$attachment.sas.uri". The value is available via AzureStorageAttachmentConfigurationConstants.DefaultMessagePropertyToIdentitySasUri
constant.
Default SAS token validation time is 7 days.
new AzureStorageAttachmentConfiguration(storageConnectionString)
.WithBlobSasUri(
messagePropertyToIdentifySasUri: "mySasUriProperty",
sasTokenValidationTime: TimeSpan.FromHours(12));
Default is to convert any body to attachment.
// messages with body > 200KB should be converted to use attachments
new AzureStorageAttachmentConfiguration(storageConnectionString,
messageMaxSizeReachedCriteria: message => message.Body.Length > 200 * 1024);
When Storage connection string needs to be retrieved rather than passed in as a plain text, AzureStorageAttachmentConfiguration
accepts implementation of IProvideStorageConnectionString
.
The plugin comes with a PlainTextConnectionStringProvider
and can be used in the following way.
var provider = new PlainTextConnectionStringProvider(connectionString);
var config = new AzureStorageAttachmentConfiguration(provider);
var credentials = new StorageCredentials( /*Shared key OR Service SAS OR Container SAS*/);
var config = new AzureStorageAttachmentConfiguration(credentials, blobEndpoint);
See StorageCredentials
for more details.
Azure Functions currently has no way to register plugins, these extension methods are a workaround until this feature is added.
To use the extensions, your Function must return (send) or take as parameter (receive) an instance of Message
.
Upload attachment to Azure Storage blob
//To make it possible to use SAS URI when downloading, use WithBlobSasUri() when creating configuration object
await message.UploadAzureStorageAttachment(config);
Download attachment from Azure Storage blob
//Using SAS URI with default message property ($attachment.sas.uri)
await message.DownloadAzureStorageAttachment();
//Using SAS URI with custom message property
await message.DownloadAzureStorageAttachment("$custom-attachment.sas.uri");
//Using configuration object
await message.DownloadAzureStorageAttachment(config);
The plugin does NOT implement cleanup for the reasons stated here. When cleanup is required, there are a few options available depending on the use case.
Proudly list your company here if use this plugin in production
Created by Dinosoft Labs from the Noun Project.