Masstransit consumer raw message - c#

Someone put a message in RabbitMq (for example). The message is not in the Masstransit "envelop" format, just json, or maybe something else.
How to get this message in Masstransit consumer as byte[], or string?
I understand that Masstransit has its own message format, but there is a need to receive a raw message. I don’t really like the option when Masstransit and RabbitMq client are used in one service, because these are already two connections, and different message processing logic.

On the receive endpoint where raw JSON messages are to be consumed, you can configure a default deserializer as shown:
endpointConfigurator.UseRawJsonDeserializer(isDefault: true);

Related

NServiceBus sending message to one endpoint and waiting for reply in another

I'm using NServiceBus with RabbitMQ in my project. I have two services that don't know about each other and don't share anything. service1 publishes request messages to endpoint1 (queue1) and service2 listens to endpoint1 and publishes responses to endpoint2 (queue2). There are two questions:
How can service1 handle responses from service2 if service1 doesn't know the response message type but only expects some particular fields in the response message?
I want to create an async API method that sends a request to endpoint1 and waits for the response in endpoint2. Is it somehow possible at all? Also how can I ensure that the reply corresponds with the request?
I expect something like:
public async Task<object> SendRequest(string str) {
var request = new MyRequest(str);
await endPoint1.Publish(request);
var reply = await endPoint2.WaitingReply();
return reply;
}
I will appreciate any help.
Whenever two things communicate, there is always a contract. When functions call each other the contract is the parameters that are required to call that function. With messaging the message is the contract. The coupling is towards the message, not the sender or receiver.
I'm not really sure what you're trying to achieve? You mention an API which is async and endpoint1 and endpoint2.
First of all, there's asynchronous execution and asynchronous communication. The async part in your example code is asynchronous execution of two methods that have the word await in front of them. When we talk about sending messages, that's asynchronous communication. A message is put on the queue and then the code moves on and never looks back at the message. Even when you use the request/reply pattern, no code is actually waiting for a message.
You can wait for a message by blocking the thread, but I highly recommend you avoid that and not use the NServiceBus callback feature. If you think you have to, think again. If you still think so, read the red remarks on that page. If they can't convince you, contact Particular Software to have them explain another time why not. ;-)
It could be that you need a reply message for whatever reason. If you build some website using SignalR (for example) and you want to inform the user on the website when a message returned and some work was completed, you can wait for a reply message. The result is that the website itself becomes an endpoint.
So if the website is EndpointA and it sends a message to EndpointB, it is possible to reply to that message. EndpointA would then also need a message handler for that message. If EndpointB first needs to send a message to EndpointC, which in turn responds to EndpointB and only then it replies back to EndpointA, NServiceBus can't easily help. Not because it's impossible, but because you probably need another solution. EndpointA should probably not be waiting for that many endpoints to reply, so many things could go "wrong" and take too much time.
If you're interested to see how replies work in combination with SignalR and what not, you can check a demo I built for a presentation that has that.

Send outbox message without having type

We are using MassTransit with RabbitMQ and part of our implementation includes an outbox pattern.
Now i'm trying to create a docker container whose only purpose is to dispatch messages from outboxes in several databases.
The container gets a list of connection strings to the various databases and then starts to dispatch messages from their outboxes.
Currently we store the following information in our outbox (with examples):
MessageType: SomeNamespace.SomeType, SomeContract
MessageBody: {"SomeProperty":"MyValue"}
TransmitMethod: Send/Publish
QueueName: SomeQueueName
My question is if it's possible to dispatch these messages without having access to the contract types?
I can add more information to the table if needed to make this happen.
You can look at how the MassTransit message scheduler support for Quartz.NET captures and ultimately sends the message on the transport. In this case, it's saving the serialized message from the transport and reloading the JSON into the message body at serialization time.
You might also find useful details in the relational outbox draft PR.

MassTransit RabbitMq Sending Messages

I am not able to figure out on how to specify the Exchange and Queue in my GetSendEndpoint()) task when sending / publishing messages?
As per MassTransit documentation https://masstransit-project.com/usage/producers.html#send you can specify the exchange and queue like
GetSendEndpoint(new Uri("queue:input-queue"))
However, I can only do one or the other?
Is there an alternative way of sending with exchange and queue specified?
I am doing this in Asp.Net Core so here are my configuration:
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddMassTransit();
services.AddSingleton(p => Bus.Factory.CreateUsingRabbitMq(cfg =>
{
cfg.Host("rabbitmq://localhost", h =>
{
h.Username("admin");
h.Password("admin");
});
}));
services.AddSingleton<IBus>(p => p.GetRequiredService<IBusControl>());
services.AddSingleton<IHostedService, BusService>();
}
And this is how send the message
var endpoint = await _bus.GetSendEndpoint(new Uri(queue:Test.Queue));
await endpoint.Send(new Message()
{
Text = "This is a test message"
});
As you can see I can only specify the queue name.
If you specify an exchange, only the exchange is declared on the broker. The message will be sent directly to the exchange.
"exchange:your-exchange-name"
If you specify a queue, the queue along with an exchange of the same name will be declared and the exchange will be bound to the queue. Messages will be delivered to the exchange of the same name, which will deliver them to the queue.
"queue:your-queue-name"
If you want a different exchange and queue name, you can specify both using:
"exchange:your-exchange-name?bind=true&queue=your-queue-name"
Or you could simplify, but it's a little confusing with two queues:
"queue:your-exchange-name&queue=your-queue-name"
Reading Chris's response in here Mass Transit : No consumer
It seems like Exchanges are created by MassTransit when publishing messages, based on the message types. Publishing does not create any queues. Queues are where messages are stored for delivery to consumers.
and Queues are created when receive endpoints are added to a bus. For the consumers, handlers, and sagas added to a receive endpoint, the exchanges are created and bound so that messages published to the exchanges are received by the receive endpoint (via the queue).
So if my publisher doesn't have a receive endpoint defined then any messages I send will be lost as there will be no queues or binding?
Further reading on here https://groups.google.com/forum/#!topic/masstransit-discuss/oVzZkg1os9o seems to further confirm this.
So based on the above link in order to achieve what I want i.e. to create the exchange and bind it to a queue I will need to specify it in the Uri as such
var sendEndpoint = bus.GetSendEndpoint(new Uri("rabbitmq://localhost/vhost1/exchange1?bind=true&queue=queue1"));
where exchange1 is the Exchange, queue1 is the Queue and bind=true would bind the queue to the exchange.
If sticking to the original MT design a Consumers needs to be running before to setup the exchanges and queues before a Producer can start publishing? This seems to give less flexibility to the Publisher?

Track Service Bus Message Topic Subscription

I have a service bus topic subscription model . I am in control of designing the sender component to a topic. however receiver is a remote server whose code i cannot control. Now the tricky part, is i need to somehow possibly know some stats from service bus without really having to ask the remote server to do additional work.
For eg.
1)Last message processed (it's content)
2)Last message completed succesfully - Time and content.
This is for basic troubleshooting on my word to know, that message has atleast been recieved by the receiver.
Is it possible to do this?
What does it mean "Last message processed" and "Last message completed succesfully". If you have a constant stream of messages, at what point you would determine what's a last message.
What you're asking is somewhat in violation of the pub/sub concept. The whole point of topics and subscriptions is to decouple publishers and subscribers.
This is for basic troubleshooting on my word to know, that message has atleast been recieved by the receiver.
When messages are sent to the subscription queue, they are either consumed or eventually end up in the dead-letter queue. If they are in the dead-letter queue, you'll know the reason. In case they are consumed, you will have to trust the consumer it knows what it's doing. Any time of "reply" or "acknowledgement" goes against the concept of events, where you broadcast of something that has happened and should not carry if it was received or not.

Read message body (raw xml) from MSMQ using Nservice bus before Handle() is called

Is There any way I can read raw xml message from MSMQ using NService bus before it parses it to corresponding class object.
I am getting message in Handle(Class obj). This is working fine but I want to log the xml from raw message body which NService parses to class object .
Have a look at transport message mutators. You'll be able to inspect both the Body and Headers of the message
#Chris-Bednarski's answer is correct, but I wanted to add that NServiceBus has auditing built-in which takes the complete messages and passes it on to another queue, so you don't have to do that yourself.
As of version 4, there is another process which feeds off of that queue and persists those messages into RavenDB as well as a UI (called ServiceInsight) that enables you to see everything that flowed through your system. You can find it here:
http://particular.net/ServiceInsight

Categories

Resources