Getting Started
Architecture
NServiceBus
Transports
Persistence
ServiceInsight
ServicePulse
ServiceControl
Monitoring
Samples

MongoDB Persistence

NuGet Package: NServiceBus.Storage.MongoDB (3.x)
Target Version: NServiceBus 8.x

Prerequisites

Ensure an instance of MongoDB is running on localhost:27017. See Install MongoDB on Windows.

MongoDB management UI

To visualize the data in MongoDB, it is useful to install a MongoDB administration tool. The screen shots shown in this sample use Robomongo.

Code walk-through

This sample shows a simple client/server scenario:

  • Client sends a StartOrder message to Server
  • Server starts an OrderSaga.
  • OrderSaga requests a timeout with a CompleteOrder data.
  • When the CompleteOrder timeout fires the OrderSaga publishes an OrderCompleted event.
  • Server then publishes a message that the client subscribes to.
  • Client handles the OrderCompleted event.

MongoDB configuration

The Server endpoint is configured to use the MongoDB persistence.

var endpointConfiguration = new EndpointConfiguration("Samples.MongoDB.Server");
var persistence = endpointConfiguration.UsePersistence<MongoPersistence>();
persistence.DatabaseName("Samples_MongoDB_Server");

Unless the mongo url is configured, the persistence will use the default connection string of mongodb://localhost:27017.

Similarly, unless the database name setting is configured, the persistence will use the endpoint name as the database name. In this sample the database name will be Samples_MongoDB_Server.

Order saga

public class OrderSaga :
    Saga<OrderSagaData>,
    IAmStartedByMessages<StartOrder>,
    IHandleTimeouts<CompleteOrder>
{
    static ILog log = LogManager.GetLogger<OrderSaga>();

    protected override void ConfigureHowToFindSaga(SagaPropertyMapper<OrderSagaData> mapper)
    {
        mapper.MapSaga(sagaData => sagaData.OrderId)
            .ToMessage<StartOrder>(message => message.OrderId);
    }

    public Task Handle(StartOrder message, IMessageHandlerContext context)
    {
        Data.OrderId = message.OrderId;
        var orderDescription = $"The saga for order {message.OrderId}";
        Data.OrderDescription = orderDescription;

        log.Info($"Received StartOrder message {Data.OrderId}. Starting Saga");
        log.Info("Order will complete in 5 seconds");

        var timeoutData = new CompleteOrder
        {
            OrderDescription = orderDescription
        };

        return RequestTimeout(context, TimeSpan.FromSeconds(5), timeoutData);
    }

    public Task Timeout(CompleteOrder state, IMessageHandlerContext context)
    {
        log.Info($"Saga with OrderId {Data.OrderId} completed");

        var orderCompleted = new OrderCompleted
        {
            OrderId = Data.OrderId
        };

        MarkAsComplete();

        return context.Publish(orderCompleted);
    }
}

Saga data

The saga data is stored in the ordersagadata collection.

public class OrderSagaData : ContainSagaData
{
    public Guid OrderId { get; set; }

    public string OrderDescription { get; set; }
}
  • IContainSagaData.Id maps to the native MongoDB document _id
  • IContainSagaData.Originator and IContainSagaData.OriginalMessageId both map to simple property pairs.
  • Custom properties on the SagaData, in this case OrderDescription and OrderId, are also mapped to simple properties.
  • _t is type serialization metadata used by the underlying MongoDB Driver.
  • _version is added and managed by NServiceBus.Storage.MongoDB to prevent concurrency issues.

Related Articles

  • Sagas
    NServiceBus uses event-driven architecture to include fault-tolerance and scalability in long-term business processes.

Last modified