Search code examples
javac#rabbitmqnservicebus

NServiceBus and Java integration


We have several microservices, most of them written in C#, but one written in Java. We're using NServiceBus and RabbitMQ for communication between the .NET services. We have one case where one of the C# Components needs to talk to the Java component with a Request/Reply over RabbitMQ.

When using NServiceBus the reply Queue is labeled with AnyQueueName-1 where the -1 indicates that this is a Reply Queue.

Debugging the Java service, I can see that I'm able to send Messages from the C# Service to the Java service. Once the Java component is finished processing the Message, it's supposed to send back a Message. Here is where all the problems start.

  1. I can see that it's supposed to send the Message to the correct Queue. The name has been verified within the RabbitMQ Management Tool. But there is no activity in this Queue.

  2. No exceptions are thrown on the Java side, so it appears that it's able to send the message, but where does it go? I do not expect that NServiceBus and Java will work together perfectly, but at least I should see some activity in my expected queue.

The relevant Java code looks like this:

Message responseMessage =
    rabbitTemplate.getMessageConverter().toMessage(
        response, responseProperties);

String replyTo = requestProperties.getReplyTo();
rabbitTemplate.convertAndSend(replyTo, responseMessage, cd);

The variable replyTo is the name of the queue that I expect the message to be pushed to.

Can anyone give me a push in the correct direction? Where should I debug next?

Thanks!


Solution

  • This issue is hard to identify without actual access to the infrastructure.

    It seems to me that, considering your Java client successfully publishes to the RabbitMQ broker but that the C# client doesn't react to the messages, your message serialisation might be missing something.

    Below are a few things that you could check.

    Take a look at the native integration with RabbitMQ sample

    The NServiceBus documentation has a section on how to use native RabbitMQ integration. You can download the sample and see how the particular guys got it to work.

    NServiceBus message headers

    NServiceBus uses specific header attributes within messages. One of these is the NServiceBus.EnclosedMessageTypes header, which allows NServiceBus to identify the message type. More specifically, this header allows NServiceBus to map the message to the corresponding C# class implementing IMessage. Also, the NServiceBus.MessageIntent header would be needed.

    I suggest that you check the NServiceBus Message Headers documentation—especially in your case the Reply Headers section. Make sure that you add the NServiceBus required headers from your Java client as explained in the RabbitMQ API-Guide. I can't tell which headers are mandatory for NServiceBus to work, so trial and error is your friend.

    Track Messages published by NServiceBus in RabbitMQ

    Compare the messages published using NServiceBus with the ones you publish using your Java client. Here is a link for one possible solution on how to trace RabbitMQ messages and their payload. This way you might identify differences between the two message types and their content.

    Use NServiceBus ServiceControl

    One of the advantages of NServiceBus is the tools it brings with it. Set up an instance of ServiceControl and use the ServiceInsights application to check messages and errors per endpoint. This will allow you to determine if your Java messages have been successfully sent or received. Generally, this tooling is great for production environments and I highly recommend using these tools.

    Other things to try

    If nothing gets it to work, another option for you would be to create a slim REST API in C#, as a publisher gateway. This publisher gateway would take the POST requests and publish the content using NServiceBus to your RabbitMQ broker. You would then be able to reference your project containing your messages and use them as your models for the API.

    Here's a possible example:

    POST https://busgateway.corporate.com/api/{endpoint}/send/{messagetype}
    
    body:
    {
       "property": "value",
       "publisher": "java client"
    }
    

    This way, your Java client would send messages using HTTP requests.