Reputation: 67
I'm trying to use Axon and Saga design pattern to send data between Micorservices using Java I have two service one for Order and one for Product CQRS Design pattern works perfectly I mean I send data to axon and I see it in my dashboard and then by query data gets and save in read database (MySQL). Today I tried to use Saga design pattern and when create a new order send ReserveProductCommand to axon and gets by Product service but saga doesn't event start and I don't know why
Below Saga class in Order service that should gets OrderCreatedEvent and Log the message but it doesn't
@Saga
public class OrderSaga {
private final transient CommandGateway commandGateway;
private static final Logger LOGGER = LoggerFactory.getLogger(OrderSaga.class);
@Autowired
public OrderSaga(CommandGateway commandGateway) {
this.commandGateway = commandGateway;
}
@StartSaga
@SagaEventHandler(associationProperty = "orderId")
public void handle(OrderCreatedEvent orderCreatedEvent) {
ReserveProductCommand reserveProductCommand = ReserveProductCommand
.builder()
.orderId(orderCreatedEvent.getOrderId())
.productId(orderCreatedEvent.getProductId())
.quantity(orderCreatedEvent.getQuantity())
.userId(orderCreatedEvent.getUserId())
.build();
LOGGER.info("OrderCreatedEvent handled for orderId: " + reserveProductCommand.getOrderId() + " and productId: " + reserveProductCommand.getProductId());
commandGateway.send(reserveProductCommand, new CommandCallback<ReserveProductCommand, Object>() {
@Override
public void onResult(CommandMessage<? extends ReserveProductCommand> commandMessage, CommandResultMessage<?> commandResultMessage) {
if (commandResultMessage.isExceptional()){
}
}
});
}
@SagaEventHandler(associationProperty = "orderId")
public void handle(ProductReservedEvent productReservedEvent){
LOGGER.info("ProductReservedEvent is called for productId: " + productReservedEvent.getProductId() + " and orderId: " + productReservedEvent.getOrderId());
}
}
Below OrderCreatedEvent
@Data
@AllArgsConstructor
@NoArgsConstructor
public class OrderCreatedEvent {
public String orderId;
private String userId;
private String productId;
private int quantity;
private String addressId;
private OrderStatus orderStatus;
}
I've seen axon dashboard OrderCreatedEvent has been published there
Upvotes: 1
Views: 355
Reputation: 231
I think the problem is that Axon requires a no-arg constructor on Saga's. You should use field injection for the resources. This passage in the reference guide explains it:
The SpringResourceInjector uses Spring's dependency injection mechanism to inject resources into a Saga. This means you can use setter injection or direct field injection if you require. The method or field to be injected needs to be annotated in order for Spring to recognize it as a dependency, for example with @Autowired.
The passage can be found here: https://docs.axoniq.io/reference-guide/axon-framework/sagas/implementation. Changing the constructor injection to field injection, like the following sample, should work for you:
@Saga
public class OrderSaga {
@Autowired
private final transient CommandGateway commandGateway;
private static final Logger LOGGER = LoggerFactory.getLogger(OrderSaga.class);
// Abbreviated for clarity
}
Upvotes: 0