Hi Dears,
i am a new to axon and want to apply CQRS using AXON in our project and just created a poc to get full understand.
at first i tried axon-server as event store and i faced an issue for replying all events whenver i restart any microservice after searching i found @Steven_van_Beelen pointed to using persistence unit so i tried monogo-extension as event store but after that my OrderSagaManager
which has this annotation [@SagaEventHandler] not get notified although the event firing happen please need ur help and clarification thanks i will share my code and configuration below:
@Saga(sagaStore = "sagaStore")
public class OrderSagaManager {
private static final Logger log = LoggerFactory.getLogger(OrderSagaManager.class);
@Autowired
OrderSummaryEntityRepository entityRepository;
@Autowired
private CommandGateway commandGateway;
@StartSaga
@SagaEventHandler(associationProperty = "orderId")
public void handleCreate(OrderCreatedEvent orderCreatedEvent) {
try {
log.info("handleCreate >>>> orderId: {} , productId: {}",orderCreatedEvent.getOrderId(),
orderCreatedEvent.getProductId());
OrderSummaryEntity orderSummaryEntity = OrderSummaryEntity.builder().orderId(orderCreatedEvent.getOrderId())
.productId(orderCreatedEvent.getProductId()).productName(orderCreatedEvent.getProductName())
.price(orderCreatedEvent.getPrice()).orderStatus(orderCreatedEvent.getOrderStatus())
.creationDate(orderCreatedEvent.getCreationDate()).quantity(orderCreatedEvent.getQuantity())
.build();
entityRepository.save(orderSummaryEntity);
commandGateway.send(PayOrderCommand.builder().orderId(orderCreatedEvent.getOrderId())
.productId(orderCreatedEvent.getProductId()).productName(orderCreatedEvent.getProductName())
.orderStatus(orderCreatedEvent.getOrderStatus()).build());
} catch (Exception e) {
log.error("Error {}",e);
}
}
@EndSaga
@SagaEventHandler(associationProperty = "orderId")
public void hnaldeShippment(OrderShippedWellEvent orderShippedWellEvent) {
log.info("hnaldeShippment >>>> {}",orderShippedWellEvent);
commandGateway.send(OrderUpdatedCommand.builder().orderId(orderShippedWellEvent.getOrderId())
.productId(orderShippedWellEvent.getProductId()).productName(orderShippedWellEvent.getProductName())
.orderStatus(orderShippedWellEvent.getOrderStatus()).build());
}
}
and my aggregate class belwo:
@Aggregate
public class OrderAggregator {
private static final Logger log = LoggerFactory.getLogger(OrderAggregator.class);
@AggregateIdentifier
private String orderId;
private String productId;
private String productName;
private Integer price;
private Integer quantity;
private Integer totoalPrice;
private Date creationDate;
private OrderStatus orderStatus;
// first command will get handled will get placed in constructor
@CommandHandler
public OrderAggregator(CreateOrderCommand createOrderCommand) {
try {
if (createOrderCommand.getProductId().isEmpty())
throw new IllegalArgumentException("Product Id is empty");
if (createOrderCommand.getProductName().isEmpty())
throw new IllegalArgumentException("Product Name is empty");
OrderCreatedEvent orderCreatedEvent = OrderCreatedEvent.builder().orderId(createOrderCommand.getOrderId())
.productId(createOrderCommand.getProductId()).productName(createOrderCommand.getProductName())
.price(createOrderCommand.getPrice()).quantity(createOrderCommand.getQuantity())
.creationDate(createOrderCommand.getCreationDate()).orderStatus(OrderStatus.NEW)
.makeOrderResult("not called").build();
log.info("OrderCreatedEvent Fired : {}",orderCreatedEvent);
AggregateLifecycle.apply(orderCreatedEvent);
}catch (Exception e) {
log.error("Error: {}",e);
}
}
@EventSourcingHandler()
public void on(OrderCreatedEvent orderCreatedEvent) {
try {
this.orderId = orderCreatedEvent.getOrderId();//this aggregate id must be set
this.productId = orderCreatedEvent.getProductId();
this.productName = orderCreatedEvent.getProductName();
this.price = orderCreatedEvent.getPrice();
this.quantity = orderCreatedEvent.getQuantity();
this.creationDate = orderCreatedEvent.getCreationDate();
this.totoalPrice = this.price * this.quantity;
this.orderStatus = orderCreatedEvent.getOrderStatus();
log.info("calling >>>>> on(OrderCreatedEvent)");
}catch (Exception e) {
log.error("Error: {}",e);
}
}
}
and my AXON Configuration below:
@Configuration
public class AxonConfig {
@Value("${spring.data.mongodb.host:127.0.0.1}")
private String mongoHost;
@Value("${spring.data.mongodb.port:27017}")
private int mongoPort;
@Value("${spring.data.mongodb.database:testEvent}")
private String mongoDatabase;
@Bean
public MongoSagaStore sagaStore() {
return MongoSagaStore.builder().mongoTemplate(axonMongoTemplate()).build();
}
@Bean
public TokenStore tokenStore() {
return MongoTokenStore.builder().mongoTemplate(axonMongoTemplate())
.serializer(JacksonSerializer.defaultSerializer()).build();
}
@Bean
public EventStorageEngine eventStorageEngine() {
return MongoEventStorageEngine.builder().mongoTemplate(axonMongoTemplate()).build();
}
@Bean
public MongoTemplate axonMongoTemplate() {
return DefaultMongoTemplate.builder().mongoDatabase(mongo()).build();
}
@Bean
public MongoClient mongo() {
final ConnectionString connectionString = new ConnectionString(
"mongodb://" + mongoHost + ":" + mongoPort +"/"+ mongoDatabase);
final MongoClientSettings mongoClientSettings = MongoClientSettings.builder()
.applyConnectionString(connectionString).build();
return MongoClients.create(mongoClientSettings);
}
}
and my pom.xml has the below:
<dependency>
<groupId>org.axonframework</groupId>
<artifactId>axon-spring-boot-starter</artifactId>
<version>4.4</version>
</dependency>
<dependency>
<groupId>org.axonframework.extensions.mongo</groupId>
<artifactId>axon-mongo</artifactId>
<version>4.4</version>
</dependency>
when i send the command it get handled but firing the event not handled although the OrderSagaManager
in the same project
i have created 4 microservice linked using eureka and found in this Link
really thanks in advance for this great framework and appreciate any advice.
Note: i forget to add when starting the microservices i start also the axon-server as a way of communication between the microservices