Advanced Use Cases

It’s possible to change the default enqueue behavior. You can do so by implementing the EnqueuePolicy interface. For example like this:

public class CustomEnqueuePolicy implements EnqueuePolicy<EventMessage<?>> {
    @Override
    public EnqueueDecision<EventMessage<?>> decide(DeadLetter<? extends EventMessage<?>> letter, Throwable cause) {
        if (cause instanceof NullPointerException) {
            return Decisions.doNotEnqueue(); (1)
        }
        if (letter.message().getPayload() instanceof NotificationEvent &&
                letter.enqueuedAt().isAfter(Instant.now().plus(Duration.ofMinutes(5L)))) {
            return Decisions.evict(); (2)
        }
        return Decisions.enqueue(cause); (3)
    }
}
1 No need to put this in a dead letter queue. As this always creates the same NullPointerException, don’t enqueue it.
2 If it’s a notification event, which is already in the queue for 5 minutes, evict the event so it’s not retried again.
3 Default to enqueue the event message again.

Below is another example that uses the diagnostics and evicts after trying 5 times:

public class CustomEnqueuePolicy implements EnqueuePolicy<EventMessage<?>> {
    @Override
    public EnqueueDecision<EventMessage<?>> decide(DeadLetter<? extends EventMessage<?>> letter, Throwable cause) {
        final int retries = (int) letter.diagnostics().getOrDefault("retries", -1); (1)
        if (retries < 5) {
            return Decisions.requeue(cause, l -> l.diagnostics().and("retries", retries + 1)); (2)
        }
        return Decisions.evict(); (3)
    }
}
1 Get the retries, default to -1. So on entering the queue, the value is 0.
2 Requeue, increasing the retries.
3 Once it’s retried 5 times, the framework evicts the event message.

You can set the policy for a specific group with something like:

public class AxonConfig {
    // omitting other configuration methods...
    public void configureEnqueuePolicy(EventProcessingConfigurer configurer) {
        // Replace "my-processing-group" for the processing group you want to configure the policy on.
        configurer.registerDeadLetterPolicy("my-processing-group", config -> new CustomEnqueuePolicy());
    }
}