3

In scenarios where you want to share a Azure Service Bus namespace (to save cost etc), it's helpful to be able to explicitly set queue and topic names rather than rely on MassTransit conventions. Whilst this is straightforward with queues, we've run into difficulty with topics.

The MassTransit documentation is sparse in this area.

It's currently recommending to use a ReceiveEndpoint which appears to forward messages from a topic subscription onto a queue and then subscribe to that queue. We have got this setup working but it seems wasteful when we could just subscribe to the topic directly?

cfg.ReceiveEndpoint(
    host, 
    "my-queue-1",
    e =>
    {
        e.Subscribe("my-topic-1", "sub-1");
        e.ConfigureConsumer<MyConsumer>(provider);
        e.MaxConcurrentCalls = 24;
    });

I've discovered SubscriptionEndpoint which appears to do just this. We'd like to subscribe to a specifically named topic 'my-topic-1' with a named subscription 'sub-1'. We can replace the ReceiveEndpoint with a SubscriptionEndpoint as follows:

cfg.SubscriptionEndpoint(
    host,
    "sub-1",
    "my-topic-1",
    e =>
    {
        e.ConfigureConsumer<MyConsumer>(provider);
        e.MaxConcurrentCalls = 24;
    });

We'd like the publisher to be in a separate application, what should its bus config and publish code look like? The docs hint that the Publish Topology can be used to supply an explicit Service Bus topic name. We've tried setting the TopicDescription.Path as follows:

Bus.Factory.CreateUsingAzureServiceBus(..., cfg =>
{
    cfg.Publish<IMyMessage>(x =>
    {
        x.TopicDescription.Path = "my-topic-1";
    });
});
await bus.Publish<IMyMessage>(message);

But the message is not getting through to the consumer.

It seems this is a issue with publishing. Although the publisher creates the topic 'my-topic-1' it still publishes the message to the topic 'my.namespace/imymessage'. Looking at the source of ServiceBusMessagePublishTopology I can see why this is the case (_topicDescription vs _topicConfigurator) but it doesn't seem obvious how to override the topic's Path with the topic path hardcoded to the messageTopology's EntityName (#L42) and the then only a setter on BasePath available.

Simon Ness
  • 2,272
  • 22
  • 28
  • I'm not sure if there is something different with using a topic name, versus the message type topic name, I know these unit tests pass for me: https://github.com/MassTransit/MassTransit/blob/develop/src/MassTransit.Azure.ServiceBus.Core.Tests/Subscription_Specs.cs#L48 – Chris Patterson Aug 21 '19 at 20:38
  • Thanks Chris. The error didn't occur when running our service for a 2nd time so think it might have been related to switching between `ReceiveEndpoint` and `SubscriptionEndpoint` in the first instance. However the consumer does not fire upon publishing a message to the topic. Will keep digging. – Simon Ness Aug 22 '19 at 11:13
  • 1
    Did you change the entity name for the message type so that publish sends it to your topic, or is another system publishing the message? – Chris Patterson Aug 22 '19 at 12:42
  • Thanks again Chris. Sorry for the too-ing and fro-ing. We're now down to an error in the publisher. Your thoughts would be much appreciated! – Simon Ness Aug 23 '19 at 05:50
  • 3
    cfg.Message(x => x.EntityName = "my-topic-1"); – Chris Patterson Aug 23 '19 at 15:40
  • 2
    A ha, makes sense. Easy when you know how! Thanks again @ChrisPatterson. For those wondering this should be `cfg.Message(x => x.SetEntityName("my-topic-1"));` – Simon Ness Aug 26 '19 at 06:03

0 Answers0