0

For logging purposes, I want to get the message count of an Azure Service Bus subscription, given a subscription client. The only examples I found use the NamespaceManager, but that seems a bit redundant to me since I already have a SubscriptionClient. Is there a way to go directly from the client to the SubscriptionDescription?

Fwiw, I tried using the detour via the name space manager, but I get a it throws a 401 Unauthorized error:

int GetMessageCount(SubscriptionClient client) {
    NameSpaceManager nsm = new NamespaceManager(client.MessagingFactory.NamespaceEndpoints.First());
    SubscriptionDescription desc = nsm.GetSubscription(client.TopicPath, client.Name); // <-- throws error
    long numMsg = desc.MessageCount;
    return numMsg;
}
Thomas Schreiter
  • 770
  • 2
  • 10
  • 25

3 Answers3

1

Is there a way to go directly from the client to the SubscriptionDescription?

According to SubscriptionClient Class, it does not provide a direct way to get message count from a given SubscriptionClient object.

it throws a 401 Unauthorized error

The code client.MessagingFactory.NamespaceEndpoints.First() returns namespace endpoint, you initialize a new instance of the Microsoft.ServiceBus.NamespaceManager class with that service namespace URI base address, but you do not specify a credential that authorizes you to perform actions, so it returns 401 error when you do GetSubscription action. The following code works fine on my side, you can try it.

NamespaceManager nsm = new NamespaceManager(client.MessagingFactory.NamespaceEndpoints.First(), TokenProvider.CreateSharedAccessSignatureTokenProvider("{keyName}", "{SharedAccessKey}"));

var subscriptionDesc = nsm.GetSubscription(topicName, subscriptionName);

long messageCount = subscriptionDesc.MessageCount;
Fei Han
  • 26,415
  • 1
  • 30
  • 41
1

You're constructing your NamespaceManager with incorrect data.

client.MessagingFactory.NamespaceEndpoints.First()

returns Azure Service Bus namespace URI, not a connection string that is needed.

Is there a way to go directly from the client to the SubscriptionDescription?

Not really. To get message count on an entity is a management operation that has to go through NamespaceManager. Client is run-time operations on messages, not management of entities. Also, you shouldn't be creating namespace manager every time. Once you have it, cache it and re-use.

Sean Feldman
  • 23,443
  • 7
  • 55
  • 80
  • Too bad. I ended up creating the NamespaceManager once and then call `GetSubscription()` every time I want to know the number of messages. The code is a bit messy, because I have to pass around the NamespaceManager. – Thomas Schreiter Sep 06 '17 at 22:32
  • 1
    You're not supposed to mix management operations with the messaging operations according to the library design. That is even more enforced with the new microsoft.azure.servicebus client. – Sean Feldman Sep 06 '17 at 23:10
  • Yeah, I'm not too happy with my implementation, but it gets the job done. Now I understand that things can get convoluted quickly. If I'm going deeper that route, I will clean it up and separate the two concerns. – Thomas Schreiter Sep 13 '17 at 16:57
0

As of now (November 2019) there is still no way to do this via SubscriptionClient.

Yet people offer workarounds in this topic so here is another one via ManagementClient:

public async static Task<long> GetSubscriptionMessageCountAsync(
    ManagementClient client,
    SubscriptionDescription subscription)
{
    var runtimeInfo = await client.GetSubscriptionRuntimeInfoAsync(
        subscription.TopicPath,
        subscription.SubscriptionName);

    return runtimeInfo.MessageCount;
}
psfinaki
  • 1,814
  • 15
  • 29