Our team introduced the first distributed architecture in our organization. We opted to take the path of least resistance (free options) and built it on MassTransit and RabbitMq. Now that the organization has bought into a distributed architecture, I would like to evaluate other technologies (including paid options) to see what they have to offer. I am currently working on a POC to integrate NServiceBus into our existing architecture. Our current architecture is built on a MassTransit saga that sends commands to various consumers based on incoming events. I would like to start by shutting down one of those consumers and plugging in a NServiceBus Handler to handle the message instead.
Here’s my endpoint config:
var endPointName = "mapplandetailsfromplandocument";
var endpointConfiguration = new EndpointConfiguration(endPointName);
endpointConfiguration
.EnableInstallers(); // Installers ensure that endpoint-specific artifacts (e.g. database tables, queues, directories, etc.) are created and configured
endpointConfiguration
.UseTransport<RabbitMQTransport>()
.ConnectionString("amqp://guest:guest@localhost:5675")
.UseConventionalRoutingTopology();
endpointConfiguration.UseSerialization<NewtonsoftSerializer>();
// nServiceBus needs to know the type of message (command, event, etc.). Can either
// implement an nServiceBus interface (eg. ICommand) or define a convention.
// https://docs.particular.net/nservicebus/messaging/conventions
var conventions = endpointConfiguration.Conventions();
conventions.DefiningCommandsAs(type => type.Namespace == "RADAR.Messaging.Commands");
conventions.DefiningEventsAs(type => type.Namespace == "RADAR.Messaging.Events");
return endpointConfiguration;
Here's my handler:
public class MapPlanDetailsFromPlanDocumentConsumer : IHandleMessages<MapPlanDetailsFromPlanDocument>
{
public Task Handle(MapPlanDetailsFromPlanDocument message, IMessageHandlerContext context)
{
Console.WriteLine("Handling message...");
return Task.CompletedTask;
}
}
Here’s my message (defined in a separate assembly):
public class MapPlanDetailsFromPlanDocument : IMapPlanDetailsFromPlanDocument
{
/// <inheritdoc cref="IPlanMessage.PlanId"/>
public string PlanId { get; set; }
}
Here’s the message serialized by MassTransit:
{
"messageId": "7a000000-9a3c-0005-38b5-08d931cb3555",
"correlationId": "208d7f02-7e4b-4d76-acb7-82d36bc86791",
"conversationId": "208d7f02-7e4b-4d76-acb7-82d36bc86791",
"initiatorId": "208d7f02-7e4b-4d76-acb7-82d36bc86791",
"sourceAddress": "rabbitmq://localhost/plancomparesaga",
"destinationAddress": "amqp://localhost:5675/mapplandetailsfromplandocument",
"messageType": [
"urn:message:RADAR.Messaging.Commands:MapPlanDetailsFromPlanDocument",
"urn:message:RADAR.Messaging.Commands:IMapPlanDetailsFromPlanDocument",
"urn:message:RADAR.Messaging:IPlanMessage"
],
"message": {
"planId": "000159"
},
"sentTime": "2021-06-17T20:05:09.2535477Z",
"headers": {},
"host": {
"machineName": "LT001351",
"processName": "RADAR.PlanCompare.Saga",
"processId": 36364,
"assembly": "RADAR.PlanCompare.Saga",
"assemblyVersion": "1.0.0.0",
"frameworkVersion": "3.1.15",
"massTransitVersion": "7.1.8.0",
"operatingSystemVersion": "Microsoft Windows NT 6.2.9200.0"
}
}
This is the error message when the handler tries to handle the message:
NServiceBus.MessageDeserializationException: An error occurred while attempting to extract logical messages from incoming physical message 7a000000-9a3c-0005-a6fe-08d931d763b5
---> System.Exception: Could not find metadata for 'Newtonsoft.Json.Linq.JObject'.
Ensure the following:
1. 'Newtonsoft.Json.Linq.JObject' is included in initial scanning.
2. 'Newtonsoft.Json.Linq.JObject' implements either 'IMessage', 'IEvent' or 'ICommand' or alternatively, if you don't want to implement an interface, you can use 'Unobtrusive Mode'.
How can I handle this message without the sender modifying the message in any way?