Azure MQ - Messaging Entity could not be found

After trying a very basic example, the azure mq server doesn’t seem to create the queues. App is .net core 2.0 and the newly published nuget package ServiceStack.Azure.

I have this in the apphost:

container.Register<IMessageService>(c => new ServiceBusMqServer("Endpoint=sb://myservicebusexample.servicebus.windows.net/;SharedAccessKeyName=default;SharedAccessKey=mykey=") );
var  mq = container.Resolve<IMessageService>();
mq.RegisterHandler<QueueMessage>(ExecuteMessage);
mq.RegisterHandler<SendMessage>(ExecuteMessage);
mq.Start();

When I publish the first message via a service:

this.MessageProducer.Publish<QueueMessage>(new QueueMessage() { Id = 1, BodyHtml = "test" });

I get the error below. Prior to the Azure MQ test this worked with the inmemorymq provider. Here is the azure error:

System.AggregateException occurred
  HResult=0x80131500
  Message=One or more errors occurred. (Put token failed. status-code: 404, status-description: The messaging entity 'sb://myservicebus.servicebus.windows.net/QueueMessage.inq' could not be found..)
  Source=<Cannot evaluate the exception source>
  StackTrace:
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at ServiceStack.Azure.Messaging.ServiceBusMqMessageProducer.Publish(String queueName, IMessage message)
   at SipSales.Infrastructure.ServiceInterface.SendService.Any(SendCampaign campaign) in c:\projects\sipsales\SipSales\SipSales\Infrastructure\ServiceInterface\SendService.cs:line 18
   at ServiceStack.Host.ServiceExec`1.<>c__DisplayClass3_0.<CreateExecFn>b__0(Object service, Object request)
   at ServiceStack.Host.ServiceRunner`1.Execute(IRequest req, Object instance, TRequest requestDto)
  
Inner Exception 1:
MessagingEntityNotFoundException: Put token failed. status-code: 404, status-description: The messaging entity 'sb://myservicebus.servicebus.windows.net/QueueMessage.inq' could not be found..

This is limitation of Azure.ServiceBus library for .NET Core. Azure team dropped away NamespaceManager class from .NET Core. This class in .NET framework implementation provides features for management Azure Queues (create/delete/get counts). For usng .NET Core you have to create queues first using Azure portal or Azure CLI. .NET framework version creates these queues automatically. There is an issue about it, you can vote in comments for Azure team to implement it.

Thanks… That’s kind of a breaking change for the service bus azure library considering all of their sample code creates queues/etc. Moving targets…

You probably should implement this though even if there is an alternate Start that needs to be called.

yes, it’s another way to create queues in .NET Core version but it requires to supply subscription Id, resource group name and bunch of other settings additionally to Azure Service Bus connection string but in this case there will be incompatibility when registering Azure Service Bus in .NET and .NET Core. But if incompatibility is not an issue it can be implemented as workaround alternative before Azure team returns back NamespaceManager.

I posted a comment to that thread. I’ll do my testing on .net instead of core for the time being.

For anyone interested in getting this to work.

  1. Create a service principal in your Azure AD section. It is under App Registrations. I’m not sure if it requires this permission or note but I added it to mine: Windows Azure Service Management API
  2. Note the following: tenantId (on the properties of the ad blade), appid (clientid), client secret(create a key), subscription id (on the subscription blade),
  3. Go to the Service Bus and give that user permissions there
  4. Lastly, you have to manually create your queues if you are using the core package. All the code is below.
var tenantId = "YOUR TENANT ID";
var context = new AuthenticationContext($"https://login.microsoftonline.com/{tenantId}");

var clientId = "YOUR APP ID";
var clientSecret = "YOUR APP SECRET";

var result = context.AcquireTokenAsync(
    "https://management.core.windows.net/",
    new ClientCredential(clientId, clientSecret)
).Result;

var creds = new TokenCredentials(result.AccessToken);
var sbClient = new ServiceBusManagementClient(creds)
{
    SubscriptionId = "YOUR SUBSCRIPTION ID"
};

var queueParams = new Microsoft.Azure.Management.ServiceBus.Models.SBQueue()
{
    EnablePartitioning = true
};

mq.RegisterHandler<SendMessage>(ServiceController.ExecuteMessage);

foreach(var q in QueueNames<QueueMessage>.AllQueueNames)
{
    var rr = sbClient.Queues.CreateOrUpdateAsync("resource group name", "name of your service bus", q.Replace("mq:", ""), queueParams).Result;
}
3 Likes

thanks for posting your solution! :relaxed:
Quick question - did you need to change anything in your publishing process or general configuration to accommodate the fact that you changed the queue names by removed the illegal characters?

No, they seemed to work fine, I assume the mq: is something internal. I ended up writing a wrapper:

 public void RegisterHandler<T>(IMessageService mq, ServiceBusManagementClient sbClient, Func<IMessage<T>, object> processMessageFn, int noOfThreads)
        {
            mq.RegisterHandler<T>(processMessageFn, noOfThreads);
            var queueParams = new Microsoft.Azure.Management.ServiceBus.Models.SBQueue()
            {
                EnablePartitioning = true
            };
            
            foreach (var q in QueueNames<T>.AllQueueNames)
            {
                var rr = sbClient.Queues.CreateOrUpdateAsync(AppSettings.Get<string>("serviceBusResourceGroup"), AppSettings.Get<string>("serviceBusName"), q.Replace("mq:", ""), queueParams).Result;
            }

        }

great stuff - thanks for the speedy reply! :smile:

@RyanMBritton No problem. Can you let me know if you find the Azure MQ process’s throughput slow, fast or otherwise? I tried to process 10,000 messages and it took hours in my test and am just curious to your experience.