Azure Service Bus interoperability between Apache Camel based producer and .NET consumer

we're trying to build an event-based integration between an Apache Camel based system with produces messages in an Azure Service Bus topic and an .NET based consumer of these messages.

The producer used the AMQP interface of the Service Bus, while the .NET based consumer uses the current API from Microsoft in namespace Azure.Messaging.ServiceBus.

When we try to access the body in a received message as follows:

private async Task ProcessMessagesAsync(ProcessMessageEventArgs args)
{
    try { 
        message = Encoding.UTF8.GetString(args.Message.Body);
    }
    catch( Exception e)
    {
        _logger.LogError(e, "Body not decoded: Message: {@message}", e.Message);
    }

    _logger.LogInformation("Body Type: {@bodytype}, Content-Type: {@contenttype}, Message: {@message}, Properties: {@properties}", raw.Body.BodyType, args.Message.ContentType, message, args.Message.ApplicationProperties);

    await args.CompleteMessageAsync(args.Message);
}

the following exception is raised:

Value cannot be retrieved using the Body property.Use GetRawAmqpMessage to access the underlying Amqp Message object.
System.NotSupportedException: Value cannot be retrieved using the Body property.Use GetRawAmqpMessage to access the underlying Amqp Message object.
   at Azure.Messaging.ServiceBus.Amqp.AmqpMessageExtensions.GetBody(AmqpAnnotatedMessage message)
   at Azure.Messaging.ServiceBus.ServiceBusReceivedMessage.get_Body()

When peeking the topic with service bus explorer the message looks strange:

@string3http://schemas.microsoft.com/2003/10/Serialization/�_{"metadata":{"version":"1.0.0","message_id":"AGHcNehoD-hK0pPJCSga9v9sXFwC","message_timestamp":"2022-01-10T13:34:32.778Z"},"data":{"source_timestamp":"2022-01-05T17:20:31.000","material":"101052"}}

When messages are sent to another topic with a .NET producer there's a plaintext JSON body in the topic, as expected.

Did anybody successfully build a solution with Azure Service Bus with components based on the two mentioned frameworks, and what did the trick so that interoperability did work? Who can a Camel AMQP producer create messages with a BodyType of Data so that the body can be decoded by the .NET Service Bus client libraries without need to use GetRawAmqpMessage?


Solution 1:

I can't speak to what format Camel is using, but that error message indicates that the Body that you're trying to decode is not an AMQP data body, which is what the Service Bus client library uses and expects.

In order to read a body that is encoded as an AMQP value or sequence, you'll need to work with the data in AMQP format rather than by using the ServiceBusReceivedMessage convenience layer. To do so, you'll want to call GetRawAmqpMessage on the ServiceBusReceivedMessage, which will give you back an AmqpAnnotatedMessage.

The annotated message Body property will return an AmqpMessageBody instance which will allow you to query the BodyType and retrieve the data in its native format using one of the TryGetmethods on the AmqpMessageBody.