I want to use Azure Service Bus from inside an .NET Core 2.1 application. I'm familiar with the SDK coming with the Nuget package Microsoft.Azure.ServiceBus and using this I'm currently writing to a topic and receiving messages from there.
What I want now is to create subscriptions on this topic for every client. The point is that I want to create a filtered subscription using the SqlFilter. This means, I have to create the subscription by code.
BTW: As far as I've seen it the only other way then doing it in code is using ARM template for the deployment because the portal will not allow me to create a filtered subscription.
I understood, that Microsoft.Azure.ServiceBus is not able to create ressources and so I went to the Nuget package Microsoft.Azure.Management.ServiceBus. So I now can create a new subscription from code now like this:
private static async Task CreateSubscriptionAsync()
{
var context = new AuthenticationContext($"https://login.microsoftonline.com/{Configuration["AppSettings:AzureManagement:TenantId"]}");
var token = await context.AcquireTokenAsync(
"https://management.core.windows.net/",
new ClientCredential(Configuration["AppSettings:AzureManagement:ClientId"], Configuration["AppSettings:AzureManagement:ClientSecret"]));
var creds = new TokenCredentials(token.AccessToken);
using (var sbClient = new ServiceBusManagementClient(creds)
{
SubscriptionId = VariableHelper.Configuration["AppSettings:AzureManagement:AzureSubscriptionId"]
})
{
var queueParams = new SBSubscription
{
LockDuration = TimeSpan.FromSeconds(10)
};
await sbClient.Subscriptions.CreateOrUpdateAsync(
Configuration["AppSettings:ServiceBus:ResourceGroup"],
Configuration["AppSettings:ServiceBus:Namespace"],
Configuration["AppSettings:ServiceBus:TopicName"],
"mysub",
queueParams);
}
}
This works so I have a new subscription which I'm also able to delete. But now where can I define the filter? The SBSubscription-type contains no option to define a filter and there is no method-overload in sbClient.Subscriptions.CreateOrUpdateAsync.
The only way I found to do this in code is based on the old Nuget WindowsAzure.ServiceBus which is not available for .NET Core. So there I would use a NamespaceManager like this:
var manager = NamespaceManager.CreateFromConnectionString("MyConnectionString");
var rule = new RuleDescription("property > 4");
var sub = manager.CreateSubscriptionAsync(new SubscriptionDescription("mytopic", "mysub"), rule);
Without this feature the complete topic-thing seems to be very useless to me and I can't believe that this means that Azure Service Bus is simply not ready for .NET Core.
Edit: Solution as suggested by Arunprabhu
I just wanted to present the solution in complete.
- Add reference to NuGet
Microsoft.Azure.Management.ServiceBus. - Add reference to NuGet
Microsoft.Azure.ServiceBus. - Create the sub as follows:
private static async Task CreateSubscriptionAsync()
{
// this is to show that it works with any subscription-name
var subName = Guid.NewGuid().ToString("N");
// create the subscription using Azure Management API
var context = new AuthenticationContext($"https://login.microsoftonline.com/{Configuration["AppSettings:AzureManagement:TenantId"]}");
var token = await context.AcquireTokenAsync(
"https://management.core.windows.net/",
new ClientCredential(Configuration["AppSettings:AzureManagement:ClientId"], Configuration["AppSettings:AzureManagement:ClientSecret"]));
var creds = new TokenCredentials(token.AccessToken);
using (var sbClient = new ServiceBusManagementClient(creds)
{
SubscriptionId = VariableHelper.Configuration["AppSettings:AzureManagement:AzureSubscriptionId"]
})
{
var queueParams = new SBSubscription
{
LockDuration = TimeSpan.FromSeconds(10)
};
await sbClient.Subscriptions.CreateOrUpdateAsync(
Configuration["AppSettings:ServiceBus:ResourceGroup"],
Configuration["AppSettings:ServiceBus:Namespace"],
Configuration["AppSettings:ServiceBus:TopicName"],
subName,
queueParams);
}
// add filter-rule using Azure ServiceBus API
var client = new SubscriptionClient(ServiceBusConnectionString, Configuration["AppSettings:ServiceBus:TopicName"], subName);
await client.AddRuleAsync("default", new SqlFilter("1=1"));
// That's it
}
