0

I'm trying to get a pair of NSB endpoint (an event publisher and an event subscriber) running on top of Azure Service Bus.

I have created the service bus and the topic through the Azure portal, and my publisher is able to publish events to the topic just fine. Here's the code for that:

    public static async Task Main()
    {
        var endpointConfiguration = new EndpointConfiguration(EndpointName);
        endpointConfiguration.SendOnly();

        var transport = endpointConfiguration.UseTransport<AzureServiceBusTransport>();
        transport.ConnectionString(ServiceBusConnectionString);
        transport.TopicName(TopicName);

        var startableEndpoint = await Endpoint.Create(endpointConfiguration)
            .ConfigureAwait(false);

        var endpointInstance = await startableEndpoint.Start().ConfigureAwait(false);

        var message = new MyMessage {Data = Guid.NewGuid().ToString()};

        Console.WriteLine($"");
        Console.WriteLine($"----------------");
        Console.WriteLine($"Sending message ({message.Data})");
        Console.WriteLine($"----------------");
        Console.WriteLine($"");

        await endpointInstance.Publish(message);

        await endpointInstance.Stop().ConfigureAwait(false);
    }

The message class lives in a shared assembly:

namespace NsbAsbPoc.Messages
{
    public class MyMessage : IEvent
    {
        public string Data { get; set; }
    }
}

I'm unable to get a subscriber set up for this message though. I've tried the following:

    public static async Task Main()
    {
        var endpointConfiguration = new EndpointConfiguration(EndpointName);

        endpointConfiguration
            .UseTransport<AzureServiceBusTransport>()
            .ConnectionString(ServiceBusConnectionString)
            .TopicName(TopicName);

        endpointConfiguration.UsePersistence<InMemoryPersistence>();

        var startableEndpoint =
            await Endpoint.Create(endpointConfiguration).ConfigureAwait(false);

        var endpointInstance = await startableEndpoint.Start().ConfigureAwait(false);

        Console.ReadLine();

        await endpointInstance.Stop().ConfigureAwait(false);
    }

    public class Handler : IHandleMessages<MyMessage>
    {
        public Task Handle(MyMessage message, IMessageHandlerContext context)
        {
            Console.WriteLine($"");
            Console.WriteLine($"----------------");
            Console.WriteLine($"Received message ({message.Data})");
            Console.WriteLine($"----------------");
            Console.WriteLine($"");

            return Task.CompletedTask;
        }
    }

But I'm getting the following error on startup:

ERROR NServiceBus.Features.AutoSubscribe AutoSubscribe was unable 
to subscribe to event 'NsbAsbPoc.Messages.MyMessage': The messaging entity 
'xxxx:Topic:rich-test-topic|rich-test-vs-receiver-nsb|NsbAsbPoc.Messages.MyMessage' 
could not be found. TrackingId:150fa682-205a-4dc1-a2fb-af6ddf8c1b4f_B2, SystemTracker:NoSystemTracker, Timestamp:2019-07-23T14:25:16

Note that in the above message I've redacted the name of the bus instance. Note also that rich-test-topic is the name of my topic and rich-test-vs-receiver-nsb is the name of my receiving endpoint.

I'm completely stuck as to how to continue since this new version of the NServiceBus.Transport.AzureServiceBus library appears to have almost no documentation and almost no samples. I don't know what it's doing; am I supposed to manually configure the subscription? Should I be letting NSB create the topic itself? Is the endpoint name significant in any way?

Richiban
  • 5,569
  • 3
  • 30
  • 42

1 Answers1

1

The exception that you got states that the subscription with the rule for the event is not found. If you create the topic manually and configure the publisher to use it, the publisher will send the event to the topic. For the subscriber to work, it needs to find the topic (which you've created and configured on both sides) but the subscription along with the rule needs to be created as well. The missing subscription should match the subscribing / receiving endpoint name, rich-test-vs-receiver-nsb, and the rule should match the message full name, NsbAsbPoc.Messages.MyMessage. You can find visualization here.

What I recommend is to enable installers in your development environment to see what NServiceBus creates first so that you could disable those later and script the creation of the entities. To enable installers, see this document.

Sean Feldman
  • 23,443
  • 7
  • 55
  • 80
  • Thanks very much Sean, I have got it working by simply deleting everything in the bus and then enabling installers. At first I couldn't tell what was different between what I had created manually and what NSB created for me, but then I realised that rules don't seem to show up in the Azure portal so I was completely unaware of what they were. Thanks for clearing this up. – Richiban Jul 24 '19 at 08:49
  • 1
    No worries. ASB is not a trivial service and there are multiple caveats. If you use a 3rd party tool, you'll be able to see those rules. – Sean Feldman Jul 24 '19 at 09:04
  • Your comment seems to imply that Installers are considered a 'development' scenario; is there a reason that I wouldn't keep these enabled when this eventually becomes a production app? Why create these resources manually if I know that NSB can create exactly what it needs with the correct properties automatically? – Richiban Jul 24 '19 at 09:27
  • 1
    Didn't mean to imply that. Reading your original comment I _assumed_ you cannot or do not want let endpoints create the infrastructure for you. Both options are valid scenarios. – Sean Feldman Jul 24 '19 at 09:29