-
Notifications
You must be signed in to change notification settings - Fork 2
integration rabbitmq setup
The NetFusion.Integration.RabbitMq plugin provides sending commands to queue and publishing domain-events to exchanges.
dotnet add package NetFusion.Integration.RabbitMQ
The same IMessagingService methods used to dispatch in-process commands and domain-events are used for dispatching to RabbitMQ. This allows changing an application's behavior without having to change the calling code and provides a consistent API for all messaging implementations (RabbitMQ, Azure ServiceBus, Redis...). The responsibility of how a message is published is moved from the code dispatching the message to a routing based on the message's type.
- Sending Commands to work queues for asynchronous processing
- Sending Commands to work queues for processing having an asynchronous response returned on a reply queue
- Publishing of Domain-Events to Direct, Topic, and Fanout exchanges
- Sending RPC Commands between microservices
- Optional automatic creation of all Exchanges, Queues, Bindings, and Subscriptions
The following assumes the Microservice template, provided by NetFusion, was used to create the initial microservice based solution. Execute the following to create a solution using the template. First, install the template by executing the following:
dotnet new install NetFusion.Templates
Create a directory for the example:
mkdir Examples.RabbitMQ
Execute the following to generate the solution within the directory:
cd Examples.RabbitMQ
dotnet new netfusion-microservice -p 5003
cd src/
dotnet build
The solution containing the completed RabbitMQ examples can be found here:
NetFusion-Examples/Examples/Source/Examples.RabbitMQ
Since the use of RabbitMQ is an infrastructure concern, add a reference to the NetFusion.Infrastructure.RabbitMQ Nuget containing the plugin to the infrastructure project as follows:
dotnet add ./src/Components/Examples.RabbitMQ.Infra/Examples.RabbitMQ.Infra.csproj package NetFusion.Integration.RabbitMQ
Edit the Program.cs file for the Microservice's WebApi project to add the plugin to the composite-application. Add the following lines as shown below in the complete code listing:
.AddRabbitMq()
.InitPluginConfig<RabbitMqConfig>(c => c.IsAutoCreateEnabled = true)
When routing messages to RabbitMQ queues and exchanges, they will be automatically created based on the properties specified by the route if the IsAutoCreateEnabled property is set to true.
The RabbitMQ plugin requires an implementation of ISerializationManager to be registered for serializing and deserializing sent and received messages based on content-type.
dotnet add ./src/Components/Examples.RabbitMQ.Infra/Examples.RabbitMQ.Infra.csproj package NetFusion.Services.Serialization
The registration can be done in the Compose method which is the last place services can be registered as shown below in the complete code listing. With the above changes, the Program.cs file should now have the following code:
// Add Plugins to the Composite-Container:
builder.Services.CompositeContainer(builder.Configuration, new SerilogExtendedLogger())
.AddSettings()
.AddRabbitMq()
.InitPluginConfig<RabbitMqConfig>(c => c.IsAutoCreateEnabled = true)
.AddPlugin<InfraPlugin>()
.AddPlugin<AppPlugin>()
.AddPlugin<DomainPlugin>()
.AddPlugin<WebApiPlugin>()
.Compose(s =>
{
s.AddSingleton<ISerializationManager, SerializationManager>();
});
When a message is published, an enricher can be added to set message attributes consistently on every published message. The NetFusion.Services.Messaging Nuget contains the following predefined enrichers:
- CorrelationEnricher - Adds MessageId and CorrelationId Guid values to every published message.
- DateOccurredEnricher - Adds the date the message was published.
- HostEnricher - Adds information about the host microservice.
Add the following Nuget packages to the Examples.RabbitMQ.Infa project:
dotnet add ./src/Components/Examples.RabbitMQ.Infra/Examples.RabbitMQ.Infra.csproj package NetFusion.Services.Messaging
Add the following code to the Program.cs file of the host microservice:
.AddRabbitMq()
.InitPluginConfig<RabbitMqConfig>(c => c.IsAutoCreateEnabled = true)
.InitPluginConfig<MessageDispatchConfig>(c =>
{
c.AddEnricher<CorrelationEnricher>();
c.AddEnricher<DateOccurredEnricher>();
c.AddEnricher<HostEnricher>();
})
// Add Plugins to the Composite-Container:
builder.Services.CompositeContainer(builder.Configuration, new SerilogExtendedLogger())
.AddSettings()
.AddRabbitMq()
.InitPluginConfig<RabbitMqConfig>(c => c.IsAutoCreateEnabled = true)
.InitPluginConfig<MessageDispatchConfig>(c =>
{
c.AddEnricher<CorrelationEnricher>();
c.AddEnricher<DateOccurredEnricher>();
c.AddEnricher<HostEnricher>();
})
.AddPlugin<InfraPlugin>()
.AddPlugin<AppPlugin>()
.AddPlugin<DomainPlugin>()
.AddPlugin<WebApiPlugin>()
.Compose(s =>
{
s.AddSingleton<ISerializationManager, SerializationManager>();
});
Define the configuration section within app settings.json used by the plugin:
{
"logging": {
"seqUrl": "http://localhost:5341"
},
"netfusion": {
"rabbitMq": {
"connections": {
"testBus" : {
"username": "demo",
"password": "papillion",
"vHostName": "/netfusion",
"hosts": [
{
"hostname": "localhost",
"port": "5682"
}
]
}
}
}
}
}
When a command is sent or domain-event published, a class derived from RabbitMqRouter providing a fluent api, is used to determine how the message is routed to RabbitMQ. The microservice sending the message specifies the queue or exchanged to which the message will be delivered. The subscribing microservice uses the same fluent api to specify how a received message is dispatched to an associated message handler.
Add the following class named RabbitMqBusRouter to the Examples.RabbitMq.Infra project within the Routers directory:
using NetFusion.Integration.RabbitMQ;
namespace Examples.RabbitMq.Infra;
public class RabbitMqBusRouter : RabbitMqRouter
{
public RabbitMqBusRouter() : base("testBus")
{
}
protected override void OnDefineEntities()
{
}
}
The value passed to the base constructor (testBus in this case) is the name of the connection specified within the application settings to which the routing applies.
Each example will add message routes to the above class.
While the publisher and subscriber are usually two different microservices, these examples will only use a single microservice solution acting as both the publisher and consumer. This allows the examples to focus on a single solution and only one process must be executed. However, in a production environment, the publisher and consumer would be separate microservices. The documentation and example code are separated into Publishing and Subscribing sections indicating which microservice the code would be placed.
The above configuration file specifies connections based on instances of SEQ and RabbitMQ running within Docker. To run the examples locally, the following script can be executed to deploy both services to docker:
cd NetFusion-Examples/Examples/Source/Examples.RabbitMQ/docker
docker-compose up -d
When completed, the following can be executed to remove the services running in Docker:
cd NetFusion-Examples/Examples/Source/Examples.RabbitMQ/docker
docker-compose down
docker volume rm dev-seq_data
docker volume rm dev-rabbit_data
docker volume rm dev-rabbit_logs
The SEQ log Web interface can be found here: http://localhost:8051/
The RabbitMQ Admin interface can be found here: http://localhost:15682 User: admin, Password: admin
The example microservice used within the examples can be executed as follows:
cd Examples.RabbitMQ/src/Examples.RabbitMQ.WebApi/
dotnet run
-
Templates
-
Resources
-
Bootstrapping
-
Modules Details
-
Settings
-
Validation
-
Monitoring
- Setup
- Commands
- Queries
- Domain Events
- Message Logs
- Message Publishers
- Message Enrichers
- Message Filters
-
Azure Service Bus
-
RabbitMQ
-
Redis
-
MongoDB