Handler event in specific ProcessingGroup

When i send an event from the aggregate, can i specifiy which ProcessingGroup can handle this event ?
I have 2 ProcessingGroups, the first handles the event when it is sent from the aggregate, the second ProcessingGroup is specific to the replay.

Hi Aymen,

Can you maybe explain a bit better the use case? If the events otherwise look the same, you could for example put something on the metadata, and check that in the handler methods. But I think that’s not what your are looking for.

Typically you want the command side and the read/query side as decoupled as possible. So you command model makes sure of the businesses rules and consistently. The event handlers process events in order, and don’t care who published those events. So it sounds like an anti-pattern to me.

I will trie to explain the use case :grinning:
So i have the below CommandHandler wich publishes an event (PayementConfirmed )

@CommandHandler
private void handle(ConfirmPayement cmd) {
    AggregateLifecycle.apply(PayementConfirmed.builder()
                ....
                .build());
}

the PayementConfirmed is handled in the below saga to call an external system,
the external system does some treatment then publishes an event PayementStatusUpdated, which i handle to save some data in my DB

@Saga
@ProcessingGroup(PAYMENT_VALIDATION_PROCESS)
public class ValidationPayementProcess {

    @StartSaga
    @SagaEventHandler(associationProperty = PAYMENT_ID)
    public void on(PayementConfirmed evt) {
        // call external system
    }

    
    @EndSaga // the external system publish the event PayementStatusUpdated
    @SagaEventHandler(associationProperty = STATUS)
    public void on(PayementStatusUpdated evt) {
        // save in DB
    }
}

now i want to replay the event PayementConfirmed , i want when replay the event i do a different treatment, juste get the data from the event then i save it in the DB, like below

@Component
@ProcessingGroup(REPLAY_EVENTS_PROCESS)
public class ReplayEventHandler {	
	
    @EventHandler
    public void on(PayementConfirmed evt) {
        // save in DB
    }
}
public void replay() {
    configuration.eventProcessor(AxonConstant.REPLAY_EVENTS_PROCESS, TrackingEventProcessor.class).ifPresent(processor -> {
        processor.shutDown();
        processor.resetTokens();
        processor.start();
    });
}

You can leverage the ReplayParameterResolverFactory (Axon Framework 4.9.0 API) to know if it’s replaying. Would that be a solution?

Hello Aymen,

The way you plan to use processing groups is not the reason why processing groups exists. Processing groups are to be used with @Order such that multiple classes can process the same events in some pre-determined ordering. For example, you may want to invoke an external credit card number verification service first to write to database whether the credit card number is good and then invoke the real credit card service for payment processing in another processing group using the same event (just an example).

Having said that, I actually see issues with the way you plan on using “Event Replay” to perform regular processing. Replay is normally used by Axon (administrators) to replay events in order to say e.g. build a new report table. So mixing regular processing and “Event Replay” may lead to problems in the future. So I would recommend you do:

  1. Change your event PaymentConfirmed event to ConfirmingPayment. The reason is that you are trying to “ConfirmingPayment” by invoking some external system to accomplish that.
  2. Have 2 new events “PaymentConfirmed” and “PaymentDenied” and these are the events where the external system acknowledged your payment confirmation request saying “yes payment is good” or “no payment is not approved”. You will to add code to issue the new PaymentConfirmed or PaymentDenied alongside with the PaymentStatusUpdated in the external system.
  3. Potentially have another new event “PendingPaymentConfirmation” and use this when the external service is down of have network access problems.

Imagine you or your system administrator actually replaying events to add a field into the database along side with the current payment (e.g. boolean isWithinDiscountWeek) and you decide to replay all events from the beginning of the current year. Now you can see how these events will still be properly firing without actually calling your external site to run the payment verification code again, just make sure you detect event replaying in the code that actually calls the external service to processing payment and skip these calls. That is the main point of doing what I recommend above to not use “Replay Events” because in Axon it is used for a very specific purpose.