I'm new to Masstransit and I have taken up a small test case to create pub /Sub with AWS SQS and in case of any exception consume the fault and perform the recoverable action .
Registration and Receive End point configuration
public void ConfigureServices(IServiceCollection services) { services.AddControllers();
services.AddMassTransit(config => {
config.AddConsumer<OrderConsumer>();
config.AddConsumer<OrderFaultConsumer>();
//config.AddConsumer<OrderAccepted>();
config.UsingAmazonSqs((ctx, cfg) => {
cfg.Host("ap-southeast-2",
h =>
{
h.AccessKey("AccessKey");
h.SecretKey("SecretKey");
});
cfg.ReceiveEndpoint("order-queue", c => {
//Don't create a new topic
c.ConfigureConsumeTopology = false;
c.Subscribe("Order", s =>
{
});
c.UseMessageRetry(r=>r.Immediate(3));
c.ConfigureConsumer<OrderConsumer>(ctx);
c.ConfigureConsumer<OrderFaultConsumer>(ctx);
});
services.AddMassTransitHostedService();
Sample Publishing code :
public async Task<IActionResult> Post([FromBody] OrderDto order)
{
await publishEndpoint.Publish<IOrder>(new Order()
{
Message="Fault",
order=order
});
return Ok();
}
OrderConsumer
public class OrderConsumer : IConsumer<IOrder>
{
private readonly ILogger<OrderConsumer> logger;
public OrderConsumer(ILogger<OrderConsumer> logger)
{
this.logger = logger;
}
/*
MassTransit delivers messages to consumers by calling the Consume method */
public async Task Consume(ConsumeContext<IOrder> context)
{
if(context.Message.Message=="Fault")
throw new Exception("Very bad things happened");
await Console.Out.WriteLineAsync(context.Message.Message);
}
}
OrderFaultConsumer
public class OrderFaultConsumer : IConsumer<Fault<IOrder>>
{
private readonly ILogger<OrderFaultConsumer> _logger;
public OrderFaultConsumer(ILogger<OrderFaultConsumer> logger)
{
_logger = logger;
}
public async Task Consume(ConsumeContext<Fault<IOrder>> context)
{
var originalMessage = context.Message.Message.order;
var exceptions = context.Message.Exceptions;
//Do something interesting
await Console.Out.WriteLineAsync($"discarding message:{JsonConvert.SerializeObject(originalMessage)}");
}
}
Expectation is :
- "Order" topic should be created
- "Order_Queue" should be created which is subscribed to Order topic.
- If publish is successful and the message(input) !=Fault then "OrderConsumer" shouldbe invoked.
- If Message(input)=="Fault" then "OrderConsumer" is invoked , exception should be thrown after the immediate 3 times retry , OrderFaultConsumer should be invoked for handling fault
Actual :
- Topic Created
- Queue Created and Subscribed
- Successful scenario Passed.
- Failed Scenario , new FaultTopic got created (not expected) and OrderFaultConsumer is never invoked or consumed . 5.Order_Queue_error got created and the fault message is pushed ( not expected).
Please advise.