24

My scenario: Website hosted on the cloud, where each instance creates a subscription to a Service Bus Topic for itself to listen for messages.

My question: How do I programmatically create subscriptions?

Liam
  • 27,717
  • 28
  • 128
  • 190
Josh
  • 2,958
  • 3
  • 16
  • 27
  • 1
    I hear you. Have been asking for management operations since day one. Good news is that the team is listening. Perhaps to make it more realistic, it will take time. Suggest to voice your opinion in the GitHub issue I've linked in my answer. – Sean Feldman Mar 22 '18 at 14:13
  • 1
    Josh, you could consider marking Gustavo's answer as the accepted answer, as it will help others that land on this question. – Raj Rao Jun 18 '19 at 17:26

3 Answers3

47

Microsoft.Azure.ServiceBus.3.1.0 allows to create a ManagementClient using the ConnectionString.

private async Task CreateTopicSubscriptions()
{
    var client = new ManagementClient(ServiceBusConnectionString);
    for (int i = 0; i < Subscriptions.Length; i++)
    {
        if (!await client.SubscriptionExistsAsync(TopicName, Subscriptions[i]))
        {
            await client.CreateSubscriptionAsync(new SubscriptionDescription(TopicName, Subscriptions[i]));
        }
    }
}
Gustavo Armenta
  • 1,525
  • 12
  • 14
  • 2
    @josh, I am glad to find this question and not be the one going through this frustration. Definitely he experience is way better now, like actually usable. – Gustavo Armenta Aug 16 '18 at 23:18
  • This was very difficult to find. SO FTW! – Jeremy Holovacs Dec 07 '18 at 15:57
  • What about SqlFilter? Can you also add it in the code? – Dave Mar 15 '19 at 07:42
  • Any word on how the equivalent would be done for EventHubs? – cdmdotnet Nov 20 '19 at 22:36
  • As SubscriptionExistsAsync and CreateSubscriptionAsync both perform REST calls in the background, there is a race -- if the subscription is created between the two calls, the second calls fails with an exception. Don't know how to solve it, though, as I cannot find anything with the "create if not exists" semantics. – Palec Mar 24 '20 at 14:44
  • @Palec I think since Create is enclosed in a conditional, the await must return for Exists prior to code continuing. – Still.Tony May 06 '20 at 00:24
  • Yes, @Still.Tony. But there still is the race I described. Consider two instances of the same code executing the same instructions at the same time. Both check if the subscription exists, both try to create the subscription -- only one may succeed, the other fails with an exception. – Palec May 11 '20 at 19:46
  • @GustavoArmenta this is no longer valid as https://www.nuget.org/packages/Microsoft.Azure.ServiceBus has been deprecated. As the accepted answer could you please edit to reflect that this is no longer the preferred solution? – Simon Opelt Nov 10 '22 at 09:12
6

Original plan for the new Azure Service Bus client was not to include management plane at all and use Azure Active Directory route instead. This has proven to be too problematic, just like you've pointed out. Microsoft messaging team has put together a sample to demonstrate the basic operations.

Note that there's a pending PR to get it working with .NET Core 2.0

Moving forward, it was recognized that developers prefer to access Service Bass using a connection string like they used to over Azure Active Directory option. Management Operations issue is raised to track requests. Current plan is to provide a light weight management library for the .NET Standard client.

For now, the options are either to leverage the old client to create entities or use Microsoft.Azure.Management.ServiceBus (or Fluent) until the management package is available.

Update

Management operations were released as part of 3.1.0 version of the client.

Sean Feldman
  • 23,443
  • 7
  • 55
  • 80
  • 2
    Accepting this answer because while it didn't solve the technical problem, it addresses the underlying WTF-itude of the state of the libraries right now. – Josh Mar 22 '18 at 17:44
  • @josh you're hilarious :) Completely agree about the frustration level. Please chime in on the issue. You'll find ASB team listening and taking action. – Sean Feldman Mar 22 '18 at 18:16
  • @SeanFeldman, I think Gustavo's answer should now become the excepted answer. – Raj Rao Jun 17 '19 at 22:13
  • @RajRao I'm not sure what do you expect me to do. This is the issue with SO - the answer was provided in the context of the question. When the question was asked, there was no `ManagementClient` yet. So the answer was correct **at that point in time**. I can only ammend my answer to indicate that the plan has been implemented. – Sean Feldman Jun 17 '19 at 22:32
  • Also, the issue I've linked to was closed in 3.1.0, which is when the `ManagementClient` was released. Cheers. – Sean Feldman Jun 17 '19 at 22:33
  • @SeanFeldman, you are correct. Sorry, somehow, I thought, you had asked the question! – Raj Rao Jun 18 '19 at 17:25
4

Microsoft.Azure.ServiceBus has been deprecated. The new option is Azure.Messaging.ServiceBus and ManagementClient has been replaced by ServiceBusAdministrationClient.

string connectionString = "<connection_string>";
ServiceBusAdministrationClient client = new ServiceBusAdministrationClient(connectionString);

This new package also supports ManagedIdentity:

string fullyQualifiedNamespace = "yournamespace.servicebus.windows.net";
ServiceBusAdministrationClient client = new ServiceBusAdministrationClient(fullyQualifiedNamespace, new DefaultAzureCredential());

A little example:

var queueExists = await _administrationClient.QueueExistsAsync(queueName);
        if(!queueExists)
            await _administrationClient.CreateQueueAsync(queueName);

More info here.

Augusto Sanchez
  • 999
  • 1
  • 6
  • 14