My problem that Composite Event isn't not triggered when I got all the required events (in my case LinkContract
, LinkCustomer
). And there is a strange thing - when I send LinkContract
event, value of ProcessingStatus
became 1
and then when I got the second event LinkCustomer
it changes to 0
, but I thought it must be 3
.
Can someone explain why this happens and my composite event isn't trigger?
I've registered composite event in my MassTransitStateMachine:
using MassTransit;
using Sandbox.WebApi.Models.StateEvents;
using Serilog;
namespace Sandbox.WebApi.StateMachines;
public class BillingStateMachine : MassTransitStateMachine<BillingState>
{
public BillingStateMachine()
{
InstanceState(x => x.CurrentState);
Event(() => LinkCustomer, e => e
.CorrelateById(x => x.Message.CustomerId));
Event(() => LinkContract, e => e
.CorrelateById(x => x.Message.CustomerId));
Initially(
When(LinkCustomer)
.Then(HandleLinkCustomer)
.TransitionTo(Processing),
When(LinkContract)
.Then(HandleLinkContract)
.TransitionTo(Processing));
During(Processing,
When(LinkContract)
.Then(HandleLinkContract),
When(LinkCustomer)
.Then(HandleLinkCustomer));
CompositeEvent(() => PaymentSucceeded,
x => x.ProcessingStatus,
CompositeEventOptions.IncludeInitial,
LinkContract, LinkCustomer);
During(Processing,
When(PaymentSucceeded)
.Then(HandlePaymentSucceeded)
.TransitionTo(Paid));
}
public State Processing { get; }
public State Paid { get; }
public Event PaymentSucceeded { get; }
public Event<ContractCreated> LinkContract { get; }
public Event<CustomerCreated> LinkCustomer { get; }
private static void HandleLinkCustomer(BehaviorContext<BillingState, CustomerCreated> context)
{
context.Saga.CustomerId = context.Message.CustomerId;
Log.Information("Customer was linked: {CustomerId}", context.Saga.CustomerId);
}
private static void HandleLinkContract(BehaviorContext<BillingState, ContractCreated> context)
{
context.Saga.ContractId = context.Message.ContractId;
context.Saga.CustomerId = context.Message.CustomerId;
Log.Information("Contract was linked: {ContractId}", context.Saga.ContractId);
}
private static void HandlePaymentSucceeded(BehaviorContext<BillingState> context)
{
Log.Information("Billing was paid: {ContractId} & {CustomerId}",
context.Saga.ContractId, context.Saga.CustomerId);
}
}
and the following state:
using MassTransit;
namespace Sandbox.WebApi.StateMachines;
public class BillingState : SagaStateMachineInstance, ISagaVersion
{
public Guid CorrelationId { get; set; }
public string CurrentState { get; set; }
public CompositeEventStatus ProcessingStatus { get; set; }
public int Version { get; set; }
public Guid CustomerId { get; set; }
public Guid ContractId { get; set; }
}
There is DI configuration:
services.AddMassTransit(opts =>
{
opts.SetEndpointNameFormatter(KebabCaseEndpointNameFormatter.Instance);
opts.AddConsumers(assembly);
opts.AddSagaStateMachine<BillingStateMachine, BillingState>()
.RedisRepository(x => x
.DatabaseConfiguration("<connection_string>"));
opts.UsingRabbitMq((ctx, cfg) =>
{
cfg.ConfigureEndpoints(ctx);
cfg.AutoStart = true;
cfg.Host("localhost", 5672, "/", r =>
{
r.Username("guest");
r.Password("guest");
});
});
});
Also if this will help, there are logs:
[13:04:29 INF] Bus started: rabbitmq://localhost/
[13:05:16 DBG] Declare exchange: name: Sandbox.WebApi.Models.StateEvents:ContractCreated, type: fanout, durable
[13:05:16 DBG] SEND rabbitmq://localhost/Sandbox.WebApi.Models.StateEvents:ContractCreated eb480000-25c5-9e68-3b62-08da536d8a2f Sandbox.WebApi.Models.StateEvents.ContractCreated
[13:05:16 INF] HTTP POST /api/User/contract responded 204 in 322.4377 ms
[13:05:16 DBG] SAGA:Sandbox.WebApi.StateMachines.BillingState:00000000-507f-1f77-bcf8-6cd799439011 Created Sandbox.WebApi.Models.StateEvents.ContractCreated
[13:05:16 DBG] SAGA:Sandbox.WebApi.StateMachines.BillingState:00000000-507f-1f77-bcf8-6cd799439011 Added Sandbox.WebApi.Models.StateEvents.ContractCreated
[13:05:16 INF] Contract was linked: 00000000-507f-1f77-bcf8-6cd799439011
[13:05:16 DBG] RECEIVE rabbitmq://localhost/billing-state eb480000-25c5-9e68-3b62-08da536d8a2f Sandbox.WebApi.Models.StateEvents.ContractCreated Sandbox.WebApi.StateMachines.BillingState(00:00:00.4622311)
[13:06:29 DBG] Declare exchange: name: Sandbox.WebApi.Models.StateEvents:CustomerCreated, type: fanout, durable
[13:06:29 DBG] SEND rabbitmq://localhost/Sandbox.WebApi.Models.StateEvents:CustomerCreated eb480000-25c5-9e68-751a-08da536db5cb Sandbox.WebApi.Models.StateEvents.CustomerCreated
[13:06:29 INF] HTTP POST /api/User/customer responded 204 in 360.3700 ms
[13:06:29 DBG] SAGA:Sandbox.WebApi.StateMachines.BillingState:00000000-507f-1f77-bcf8-6cd799439011 Used Sandbox.WebApi.Models.StateEvents.CustomerCreated
[13:06:29 INF] Customer was linked: 00000000-507f-1f77-bcf8-6cd799439011
[13:06:29 DBG] RECEIVE rabbitmq://localhost/billing-state eb480000-25c5-9e68-751a-08da536db5cb Sandbox.WebApi.Models.StateEvents.CustomerCreated Sandbox.WebApi.StateMachines.BillingState(00:00:00.3579677)