Monitor RabbitMQ direct routing topology with ServiceControl adapter

Component: ServiceControl Transport Adapter
NuGet Package ServiceControl.TransportAdapter (1.x)
Target NServiceBus Version: 6.x

This sample shows how to configure ServiceControl to monitor endpoints and retry messages when using the RabbitMQ direct routing topology. ServiceControl by default supports only the default RabbitMQ routing topology, therefore a kind of "transport adapter" is required to monitor systems using other routing topologies.

Prerequisistes

  1. Install ServiceControl.
  2. Install RabbitMQ broker on localhost.
  3. Using ServiceControl Management tool, set up ServiceControl to monitor endpoints using RabbitMQ transport:
  • Add a new ServiceControl instance.
  • Use default Particular.ServiceControl as the instance name (ensure there is no other instance of SC running with the same name).
  • Specify host=localhost as a connection string. ServiceControl Management Utility will automatically create queues and exchanges on the broker.
If other ServiceControl instances have been running on this machine, it's necessary to specify a non-default port number for API. Adjust ServicePulse settings accordingly to point to this location.
  1. Ensure the ServiceControl process is running before running the sample.
  2. Install ServicePulse
In order to connect to a different RabbitMQ broker, ensure all connection strings in the sample are updated.

Running the project

  1. Start the Adapter, Sales and Shipping projects.
  2. Open ServicePulse (by default it's available at http://localhost:9090/#/dashboard) and select the Endpoints Overview. Samples.ServiceControl.RabbitMQAdapter.Shipping endpoint should be visible in the Active Endpoints tab as it has the Heartbeats plugin installed.
  3. Go to the Sales console and press o to send a message.
  4. Notice the Sales endpoint receives its own message and successfully processes it.
  5. Press f to simulate message processing failure.
  6. Go to the Shipping console and also press f to simulate message processing failure.
  7. Press o in Sales to create more messages.
  8. Notice both messages failed processing in their respective endpoints.
  9. Open ServicePulse and select the Failed Messages view.
  10. Notice the existence of one failed message group with two messages. Open the group.
  11. Press the "Retry all" button.
  12. Go to the Shipping console and verify that the message has been successfully processed.
  13. Go to the Sales console and verify that the message has been successfully processed.
  14. Shut down the Shipping endpoint.
  15. Open ServicePulse and notice a red label next to the heart icon. Click on the that icon to open the Endpoints Overview. Notice that Samples.ServiceControl.RabbitMQAdapter.Shipping is now displayed in the Inactive Endpoints tab.

Code walk-through

The code base consists of three projects.

Sales Endpoint

The Sales project contains an endpoint that simulates the execution of a business process by exchanging messages with the Sales endpoint. It includes a message processing failure simulation mode (toggled by pressing f) which can be used to generate failed messages that demonstrate message retry functionality. The Sales endpoint uses the RabbitMQ direct routing topology and requires an adapter in order to communicate with ServiceControl.

The following code configures the Sales endpoint to communicate with the adapter:

var endpointConfiguration = new EndpointConfiguration("Samples.ServiceControl.RabbitMQAdapter.Sales");

var transport = endpointConfiguration.UseTransport<RabbitMQTransport>();
transport.ConnectionString("host=localhost");
transport.DelayedDelivery().DisableTimeoutManager();

transport.UseDirectRoutingTopology();

endpointConfiguration.SendFailedMessagesTo("adapter_error");
endpointConfiguration.AuditProcessedMessagesTo("adapter_audit");

Shipping Endpoint

The Shipping project also contains an endpoint that simulates the execution of a business process by exchanging messages with the Shipping endpoint. It includes message processing failure simulation mode (toggled by pressing f) which can be used to generate failed messages that demonstrate message retry functionality.

The Shipping endpoint uses the RabbitMQ direct routing topology and requires an adapter in order to communicate with ServiceControl.

The Shipping endpoint has the Heartbeats plugin installed to enable uptime monitoring via ServicePulse.

The following code configures the Shipping endpoint to communicate with the adapter:

var endpointConfiguration = new EndpointConfiguration("Samples.ServiceControl.RabbitMQAdapter.Shipping");

var transport = endpointConfiguration.UseTransport<RabbitMQTransport>();
transport.ConnectionString("host=localhost");
transport.DelayedDelivery().DisableTimeoutManager();

transport.UseDirectRoutingTopology();

endpointConfiguration.SendFailedMessagesTo("adapter_error");
endpointConfiguration.AuditProcessedMessagesTo("adapter_audit");
endpointConfiguration.HeartbeatPlugin("adapter_Particular.ServiceControl");

Adapter

The Adapter project hosts the ServiceControl.TransportAdapter. The adapter has two sides: endpoint-facing and ServiceControl-facing. In this sample the ServiceControl-facing side uses the RabbitMQ transport with the default conventional routing topology:

var transportAdapter =
    new TransportAdapterConfig<RabbitMQTransport, RabbitMQTransport>("ServiceControl.RabbitMQ.Adapter");

transportAdapter.CustomizeServiceControlTransport(
    customization: transport =>
    {
        transport.ConnectionString("host=localhost");
        var delayedDelivery = transport.DelayedDelivery();
        delayedDelivery.DisableTimeoutManager();
    });

The following code configures the adapter to use the RabbitMQ direct routing topology when communicating with the business endpoints:

transportAdapter.CustomizeEndpointTransport(
    customization: transport =>
    {
        transport.ConnectionString("host=localhost");
        var delayedDelivery = transport.DelayedDelivery();
        delayedDelivery.DisableTimeoutManager();

        transport.UseDirectRoutingTopology();
    });

The following code configures names of the queues used by the adapter and ServiceControl:

transportAdapter.EndpointSideErrorQueue = "adapter_error";
transportAdapter.EndpointSideAuditQueue = "adapter_audit";
transportAdapter.EndpointSideControlQueue = "adapter_Particular.ServiceControl";

transportAdapter.ServiceControlSideErrorQueue = "error";
transportAdapter.ServiceControlSideAuditQueue = "audit";
transportAdapter.ServiceControlSideControlQueue = "Particular.ServiceControl";

Related Articles


Last modified