integration servicebus setup - grecosoft/NetFusion GitHub Wiki

IMAGEAzure Service Bus: Plugin Setup

The NetFusion.Integration.RabbitMq plugin provides sending commands to queue and publishing domain-events to exchanges.

dotnet add package NetFusion.Integration.ServiceBus

IMAGE The same IMessagingService methods used to dispatch in-process commands and domain-events are used for dispatching to Azure Service Bus. 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.


Supported Features

  • Sending Commands to queues for asynchronous processing
  • Sending Commands to queues for processing having an asynchronous response returned on a reply queue
  • Publishing of Domain-Events to Topics for delivery to defined subscriptions
  • Sending RPC Commands between microservices
  • Optional automatic creation of all Queues, Topics, and Subscriptions

Adding Service Bus Plugin to Microservice

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.ServiceBus

Execute the following to generate the solution within the directory:

cd Examples.ServiceBus
dotnet new netfusion-microservice -p 5003
cd src/
dotnet build

The solution containing the completed Service Bus examples can be found here:

NetFusion-Examples/Examples/Source/Examples.ServiceBus

Add Service Bus Nuget Package

Since the use of Azure Service Bus is an infrastructure concern, add a reference to the NetFusion.Infrastructure.ServiceBus Nuget containing the plugin to the infrastructure project as follows:

dotnet add ./src/Components/Examples.ServiceBus.Infra/Examples.ServiceBus.Infra.csproj package NetFusion.Integration.ServiceBus

Register Plugin

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:

.AddAzureServiceBus()
.InitPluginConfig((ServiceBusConfig c) => c.IsAutoCreateEnabled = true)

When routing messages to Azure Service Bus queues and topics, they will be automatically created based on the properties specified by the route if the IsAutoCreateEnabled property is set to true.

Add Serialization Nuget Package

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.ServiceBus.Infra/Examples.ServiceBus.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>();
    });

Add Enrichers to Message Pipeline

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.ServiceBus.Infa project:

dotnet add ./src/Components/Examples.ServiceBus.Infra/Examples.ServiceBus.Infra.csproj  package NetFusion.Services.Messaging

Add the following code to the Program.cs file of the host microservice:

.AddAzureServiceBus()
.InitPluginConfig((ServiceBusConfig c) => c.IsAutoCreateEnabled = true)
.InitPluginConfig<MessageDispatchConfig>(c =>
{
    c.AddEnricher<CorrelationEnricher>();
    c.AddEnricher<DateOccurredEnricher>();
    c.AddEnricher<HostEnricher>();
})

Completed Bootstrap Code

// Add Plugins to the Composite-Container:
builder.Services.CompositeContainer(builder.Configuration, new SerilogExtendedLogger())
    .AddSettings()

    .AddAzureServiceBus()
    .InitPluginConfig((ServiceBusConfig 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>();
    });

Running SEQ within Docker

By default, NetFusion uses Serilog for writing logs. These logs can be viewed within SEQ by running it within Docker. Complete the following to deploy SEQ to Docker:

docker-compose up -d

SEQ Web Interface: http://http://localhost:8051

When completed when the examples, the following can be used to remove SEQ from docker:

docker-compose down
docker volume rm dev-seq_data 

Create Azure Service Bus Resource

Complete the following steps to create an Azure Service Bus resource.

  • Create a new resource and search for "service bus"

IMAGE

  • On the Create namespace screen, select your resource group and enter a unique name for your namespace. For these examples, the Standard or Premium pricing tier must be selected.

IMAGE

  • Navigate through the remaining screens and select all the default values. At the last screen, select the create button.

IMAGE

IMAGE

  • After a New York minute, the Service Bus resource will be created:

IMAGE

  • Select the Go to resource button to navigate to the main screen of the Service Bus portal:

    IMAGE

Configuration Settings

Next, a configuration used by the Service Bus plugin will be added to the microservice's appsettings.json file. Locate the namespace's connection string by completing the following from the Service Bus portal:

  • Selected the Shared access policies link on the left of the screen.
  • Select the RootManageSharedAccessKey link:

IMAGE

  • Select the RootManageSharedAccessKey link:

IMAGE

  • Copy the value of the Primary Connection String and updated the configuration settings using your associated namespace values as follows:
{
  "logging": {
    "seqUrl": "http://localhost:5341"
  },
  "netfusion": {
    "azure": {
      "serviceBus": {
        "namespaces": {
          "netfusionBus": {
            "ConnString": "[Enter your connection string]"
          }
        }
      }
    },
    "plugins": {
    
    },
    "viewerUrl": ""
  }
}

Service Bus Router

When a command is sent or domain-event published, a class derived from NamespaceRouter providing a fluent api, is used to determine how messages are routed to Azure Service Bus. The microservice sending the message specifies the queue or topic 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.

Create the following class named ServiceBusRouter within the Examples.ServiceBus.Infra project within the Routers directory:

using NetFusion.Integration.ServiceBus;

namespace Examples.ServiceBus.Infra.Routers;

public class ServiceBusRouter : NamespaceRouter
{
    public ServiceBusRouter() : base("netfusionBus")
    {
    }

    protected override void OnDefineEntities()
    {

    }
}

The value passed to the base constructor (netfusionBus 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.

IMAGEWhile 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 example code is separated into Publishing and Subscribing sections indicating which microservice the code would be placed.

Running Example Microservice

Run the following to execution the example microservice:

cd Examples.ServiceBus/src/Examples.ServiceBus.WebApi
dotnet run
⚠️ **GitHub.com Fallback** ⚠️