jazzyuk
jazzyuk

Reputation: 23

Rebus Azure ServiceBus - Missing MessageID for message originated from external service

I'm creating a Proof of Concept using the Rebus in relation to Azure Service Bus, however I'm having a bit of an issue parsing a message that is put on the queue from an external source.

I'm getting the error message:

Received message with empty or absent 'rbs2-msg-id' header!

I've looked through GitHub and noticed this listing about how someone had a similar issue for RabbitMQ, and it was recommended to use a decorator:

https://github.com/rebus-org/Rebus/issues/508

However I'm not sure on how to do this just for the Message ID.

One option I'd gone down was actually modifying the Rebus.AzureTransport code to do this:

var messageId = headers.GetValueOrNull(Headers.MessageId);

if (string.IsNullOrEmpty(messageId))
{
    messageId = Guid.NewGuid().ToString();
    headers[Headers.MessageId] = messageId;
}

But would prefer an alternative!

Another thing I've noticed, is that a BrokeredMessage is put on the ASB like this:

var message = new BrokeredMessage("<xml>This is a test message: " + DateTime.Now+ "</xml>");

It's not being serialised correctly when being received by Rebus. I get the following error:

Unhandled exception 1 while handling message with ID db13880d-124c-4ed5-993e-96faeca0f140: System.Collections.Generic.KeyNotFoundException: Could not find the key 'rbs2-content-type'

By overriding the Serialiser, the underdying message is coming across as:

@strin3http://schemas.microsoft.com/2003/10/Serialization/?6This is a test message: 06/12/2016 07:44:21

so I'm not sure what I'm doing wrong.

Thanks in advance.

Upvotes: 1

Views: 769

Answers (1)

mookid8000
mookid8000

Reputation: 18628

Well... as the error messages say, the incoming message does not contain sufficient information in order for Rebus to process it.

Moreover, Rebus' Azure Service Bus transport requires that the message contents be sent as a Stream in order to avoid the cost of enclosing the contained bytes in an XML structure (which is what the Azure Service Bus driver does by default).

If I were you, I would probably not use Rebus to receive messages from a queue that does not contain messages sent by Rebus. Or, I might do it – but only if the incoming messages were very easy to adapt to adhere to the Rebus format.

It can be a little bit cumbersome though to make that happen, because – as you have correctly observed – it requires that certain headers are present, which function as hints to Rebus on how to track it between processing attempts, how to deserialize it, where to reply to if bus.Reply is called, etc. So I still might end up not doing it anyway :)

I suggest you do something like this:

while(true)
{
    var message = GetNextMessageOrNullFromQueue();

    if (message == null) continue;

    UnwrapMessageAndSendWithRebusToRebusQueue(message);
}

this way coding your own receive loop to receive your custom-formatted Azure Service Bus messages, delegating the actual handling of it (possibly also deserialization from an XML text into objects?) to a Rebus endpoint.

This is generally the preferred way of integrating with external things because it keeps the logic of bridging back and forth between the outside and the inside of your application at the perimeter, instead of bleeding into your application.

Upvotes: 1

Related Questions