DEV Community

Jonas Samuelsson
Jonas Samuelsson

Posted on • Updated on

Resend Azure Service Bus topic message

In this post I'm going to take a look at one of the implications of resubmitting azure service bus subscription dead letter messages and how it can be solved.

Azure service bus has two kind of messaging entities, queues and topics. We wont go deep into the difference of the two here but basically a queue has a single logical consumer while a a topic can have multiple logical consumers (subscriptions). Microsoft docs available here.

A message sent to a topic is distributed to all configured subscriptions. And each subscription has its own dead letter queue where messages are placed if the can't be consumed within the specified retry count.

It would be nice to resend a dead letter message back to its subscription but that can't be done. No messages (new or dead letters) can be sent directly to a subscription, they have to be sent to the topic.

But this means that the message will be distributed to both subscriptions. If you have written your message handlers to be idempotent, meaning that they can handle the same message twice, there is no problem and you can stop reading now but if that isn't something you can guarantee you're in a bit of a problem. As we were.

Filters to the rescue.

Filters can be applied to a subscription to make sure that only messages that fulfills a given criteria is handled by the subscription (messages that don't fulfill the criteria are dropped).

We applied filters to all our subscriptions so that it only process messages where a header called TargetSubscription either doesn't exist or contains the name of the subscription.

Since we use bicep to deploy our azure infrastructure it was fairly easy to create a module for this.

resource r 'Microsoft.ServiceBus/namespaces/topics/subscriptions/rules@2021-11-01' = [for subscription in subscriptions: {
  name: '${namespace}/${subscription.topicName}/${subscription.name}/default'
  dependsOn: [
    s
  ]
  properties: {
    filterType: 'SqlFilter'
    sqlFilter: {
      sqlExpression: 'TargetSubscription is null or TargetSubscription = \'\' or TargetSubscription = \'${subscription.name}\''
    }
  }
}]
Enter fullscreen mode Exit fullscreen mode

With this in place it now becomes fairly trivial to send messages to a specific subscription.

Top comments (0)