Footsteps in the sand, the seashore mind…

NServiceBus-ServiceMatrix Saga To Saga Request/Response Pattern

Summary

This document explains how to setup a SAGA to SAGA request Response pattern. Bus.Reply is used, as ReplyToOriginator is not supported. We will simulate a service receiving an order, then sending it to an Order Service, which then has a request/response pattern to process payment.

TimeOuts and responding to the original calling (originator) saga

Never use Bus.Reply within a TimeOut handle in the Saga, as it will try to reply to the timeout queue, as Bus.Reply will always respond to the source of the LAST incoming message.

To get ReplyToOriginator working between Saga’s, you need to:

Ensure the called Saga (ProcessOrder) lives LONGER than the called (Payment), by using timeouts in both sagas

You need to add a correlation

This is the message pattern with timeouts and a polling pattern, which you can run indefinitely if ever needed.

Create three endpoints

Click New endpoint

Create an OrderReceiver, as an NServiceBus Host. Do the same for OrderSaga and PaymentSaga

Your canvas will look like this

Send a message from OrderReceiver to OrderSaga

So now we will simulate a service (OrderReceiver) that receives orders on a backend system and then sends them to our OrderSaga for long running transaction processing

Click the OrderReceiver and click “Send Command”

Set the Service name to Orders (Domain) and the command ProcessOrder

Your canvas should look like this

Click the undeployed component and select Deploy

Select OrderSaga as the destination and click Done

Your canvas should look like this, with a bit of interior design J

Edit the ProcessOrder message and add the following propertiesOrderIdAmount

Open the ProcessOrderSender.cs file under the Orders folder, we will configure it to send 3 orders. We will implement IWantToRunWhenBusStartsAndStops

Note that I am not in the infrastructure folder, as this is generated code.

Build the solution

Configure the OrderSaga as a Saga and Message Correlation

Great, so now we have the minimum need to set the OrderSaga endpoint to a real Saga, as a SAGA MUST have a message to handle. In this case ProcessOrder.

Click the ProcessOrderHandler and click “Convert To Saga”

This will open the ProcessOrderHandlerConfigureHowToFindSaga.cs file. Build the solution, so that partial classes are generated.

We want to correlate order messages based on the orderId to the correct Saga instance. So here we will set the properties on how to find it. Add the following code:

Open the file ProcessOrderHandlerSagaData.cs and add the OrderId, set the property to Unique, as this is how the Saga will correlate messages to the correct instance.

Excellent, so now we have correlation established between the OrderReceiver and the OrderSaga. So if ever the Saga receives order updates for the same order, the infrastructure will no which instance to send the processorder command to.

Configure Saga To Saga Command

Here we will configure the OrderSaga to send a message to the PaymentSaga, then we will update the PaymentSaga to become a Saga.

Click the ProcessOrderHandler and click SendCommand

Name the command ProcessOrderPayment

Click Copy to Clipboard. This will then open the ProcessOrderHandler.cs file. Paste the code.

Open the Canvas, it should look like this

Click the ProcessOrderPaymentHandler, and Click Deploy.

Select the Payment Saga, as this will handle the ProcessOrderPayment Request.

Your canvas will look like this. BUILD SOLUTION

Let’s CONVERT PaymentSaga endpoint to a Saga, as we have the minimum needed to do this!WARNING: NEVER convert an endpoint to a saga unless it has at least one message handler, else it cannot implement IAmStartedByMessages interface. You would have to wire it up manually, since the Infrastructure code generator will not know how.

Click ProcessOrderPaymentHandler and click Convert to Saga…

This will open the ProcessOrderPaymentHandlerConfigureHowToFindSaga

Build the solution, to auto generate the Saga partial classes and infrastructure

We want the payment instance to correlate to the correct order Id, so add this:

Build the solution! We added properties so ConfigureHowToFindSaga will compile J

Configure Saga To Saga Response and Bus.Reply

Open the ServiceMAtrix Canvas, confirm your canvas looks like thisnotice the icon for saga’s has a circle in it with a square.

Click the ProcessOrderPaymentHandler in the payment Saga and click Reply with Message…

Click Ok

Copy the code to Clipboard

Click the Copy To Clipboard, note the mouse pointer will show as busy, however you can still click copy to clipboard.

This will open the ProcessOrderPaymentHandler.cs, paste the code here. Put in a Thread.Sleep to simulate a credit card payment.

Your canvas will look like this now

Add the following code to ProcessOrderHandler.cs file

Build the solution

Testing the solution

Following the following in Order, so the msmq’s are created in the correct order, to avoid race conditions on the first time is starts.