How do you access the dead letter sub-queue on an Azure subscription?

假装没事ソ 提交于 2019-11-27 03:54:18

问题


When I use the following:

var deadLetterPath = SubscriptionClient.FormatDeadLetterPath(topicPath,subName);
var client = SubscriptionClient.CreateFromConnectionString(connectionString, deadLetterPath, subName);

I get an InvalidOperationException

Cannot directly create a client on a sub-queue. Create a client on the main queue and use that to create receivers on the appropriate sub-queue

Some parts of the azure documentation say to use SubscriptionClient.CreateReceiver to access a sub-queue but that method doesn't exist.


回答1:


Does this approach work for you ?

MessagingFactory factory = MessagingFactory.CreateFromConnectionString(cnxString);
var deadLetterPath = SubscriptionClient.FormatDeadLetterPath(topicPath,subName);
var dlqReceiver = factory.CreateMessageReceiver(deadLetterPath, ReceiveMode.ReceiveAndDelete);

I haven't test it out here (in a meeting), but give it a try

cheers




回答2:


There is a convention naming for Dead letter queue using Azure Service Bus:

  • For Service Bus Queue: queuePath/$DeadLetterQueue
  • For Service Bus Subscription: topicPath/subscriptionName/$DeadLetterQueue

So you can access your dead letter queues the same way you access your queues.

From @SamVanhoutte answer, you can see that the ServiceBus framework provides methods to format the dead letter queue name:

  • For Service Bus Queue: QueueClient.FormatDeadLetterPath(queuePath)

  • For Service Bus Subscription: SubscriptionClient.FormatDeadLetterPath(topicPath, subscriptionName)

I wrote two small methods to create a message receiver for queue and subscription where you can set if you want the deal letter queue or not:

/// <summary>
/// Create a new <see cref="MessageReceiver"/> object using the specified Service Bus Queue path.
/// </summary>
/// <param name="connectionString">The connection string to access the desired service namespace.</param>
/// <param name="queuePath">The Service Bus Queue path.</param>
/// <param name="isDeadLetter">True if the desired path is the deadletter queue.</param>
public static MessageReceiver CreateMessageReceiver(string connectionString, string queuePath,
    bool isDeadLetter = false)
{
    return MessagingFactory.CreateFromConnectionString(connectionString)
        .CreateMessageReceiver(isDeadLetter
            ? QueueClient.FormatDeadLetterPath(queuePath)
            : queuePath);
}

/// <summary>
/// Create a new <see cref="MessageReceiver"/> object using the specified Service Bus Topic Subscription path.
/// </summary>
/// <param name="connectionString">The connection string to access the desired service namespace.</param>
/// <param name="topicPath">The Service Bus Topic path.</param>
/// <param name="subscriptionName">The Service Bus Topic Subscription name.</param>
/// <param name="isDeadLetter">True if the desired path is the deadletter subqueue.</param>
public static MessageReceiver CreateMessageReceiver(string connectionString, string topicPath,
    string subscriptionName, bool isDeadLetter = false)
{
    return MessagingFactory.CreateFromConnectionString(connectionString)
        .CreateMessageReceiver(isDeadLetter
            ? SubscriptionClient.FormatDeadLetterPath(topicPath, subscriptionName)
            : SubscriptionClient.FormatSubscriptionPath(topicPath, subscriptionName));
}



回答3:


If you are using Microsoft.Azure.ServiceBus instead of Microsoft.ServiceBus, it is slightly different.

var deadQueuePath = EntityNameHelper.FormatDeadLetterPath(your_queue_name);
var deadQueueReceiver = new MessageReceiver(connectionString, deadQueuePath);

As per EntityNameHelper class in Microsoft.Azure.ServiceBus namespace, for topics, use the subscription path instead of your_queue_name.

The name of the queue, or path of the subscription.

/// <summary>
/// Formats the dead letter path for either a queue, or a subscription.
/// </summary>
/// <param name="entityPath">The name of the queue, or path of the subscription.</param>
/// <returns>The path as a string of the dead letter entity.</returns>
public static string FormatDeadLetterPath(string entityPath)
{
    return EntityNameHelper.FormatSubQueuePath(entityPath, EntityNameHelper.DeadLetterQueueName);
}



回答4:


Those who want to do it in python.

Receive the messages from the dead letter queue:

from azure.servicebus import ServiceBusClient
import json
connectionString = "Your Connection String to Service Bus"
serviceBusClient = ServiceBusClient.from_connection_string(connectionString)
queueName = "Your Queue Name created in the Service Bus"
queueClient = serviceBusClient.get_queue(queueName)
with queueClient.get_deadletter_receiver(prefetch=5) as queueReceiver:
    messages = queueReceiver.fetch_next(timeout=100)
    for message in messages:
        # message.body is a generator object. Use next() to get the body.
        body = next(message.body)
        message.complete()

Hope it helps to someone.



来源:https://stackoverflow.com/questions/22681954/how-do-you-access-the-dead-letter-sub-queue-on-an-azure-subscription

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!