Hi Everyone,
If I have a Saga with 2 services attached to Axon Server, but one of the services is down. When the Saga starts and sends the next CreateInvoiceCommand to commandGateway, it will throw NoHandlerForCommandException. I am wondering what is the proper way to compensate for previously executed command?
How can I let the caller OrderCommandServiceImpl.createOrderAndWait() method knows that the saga transaction is failed and is compensated?
@Service
public class OrderCommandServiceImpl implements OrderCommandService {
private final CommandGateway commandGateway;
@Autowired
private MyOrderService myOrderService;
public OrderCommandServiceImpl(CommandGateway commandGateway) {
this.commandGateway = commandGateway;
}
@Override
public String createOrderAndWait(OrderCreateDTO orderCreateDTO) {
myOrderService.incrementOrder();
return commandGateway.sendAndWait(new CreateOrderCommand(UUID.randomUUID().toString(), orderCreateDTO.getItemType(),
orderCreateDTO.getPrice(), orderCreateDTO.getCurrency(), String.valueOf(OrderStatus.CREATED)));
}
}
@Aggregate
public class OrderAggregate {
private MyOrderService myOrderService;
@AggregateIdentifier
private String orderId;
private ItemType itemType;
private BigDecimal price;
private String currency;
private OrderStatus orderStatus;
public OrderAggregate() {
}
@CommandHandler
public OrderAggregate(CreateOrderCommand createOrderCommand, MyOrderService myOrderService){
this.myOrderService = myOrderService;
AggregateLifecycle.apply(new OrderCreatedEvent(createOrderCommand.orderId, createOrderCommand.itemType,
createOrderCommand.price, createOrderCommand.currency, createOrderCommand.orderStatus));
}
@EventSourcingHandler
protected void on(OrderCreatedEvent orderCreatedEvent){
this.orderId = orderCreatedEvent.orderId;
this.itemType = ItemType.valueOf(orderCreatedEvent.itemType);
this.price = orderCreatedEvent.price;
this.currency = orderCreatedEvent.currency;
this.orderStatus = OrderStatus.valueOf(orderCreatedEvent.orderStatus);
}
@Saga
public class OrderManagementSaga {
@Inject
private transient CommandGateway commandGateway;
@StartSaga
@SagaEventHandler(associationProperty = "orderId")
public void handle(OrderCreatedEvent orderCreatedEvent){
String paymentId = UUID.randomUUID().toString();
System.out.println("Saga OrderCreatedEvent Received");
//associate Saga
SagaLifecycle.associateWith("paymentId", paymentId);
System.out.println("order id" + orderCreatedEvent.orderId);
//send the commands
try {
commandGateway.sendAndWait(new CreateInvoiceCommand(paymentId, orderCreatedEvent.orderId));
} catch (AxonException ae) {
System.out.println("Caught Exception " + ae);
commandGateway.sendAndWait(new UpdateOrderStatusCommand(orderCreatedEvent.orderId, String.valueOf(OrderStatus.REJECTED)));
}
}
...