Advanced Use Cases
The current example, doesn’t use the ability to cancel deadlines.
In the case of a gift card, it might be a business rule to publish an event that the gift card expired if it was already depleted.
Let’s make a few changes to enable this.
The first thing to need to do is to add a remainingValue
to the aggregate, so it’s known when there is no value remaining.
Then, adding to the command handler:
@CommandHandler
public void handle(RedeemCardCommand command, DeadlineManager deadlineManager) {
//check validity
apply(new CardRedeemedEvent(giftCardId, command.amount()));
if (remainingValue == 0) {
deadlineManager.cancelAllWithinScope(EXPIRED_GIFT_CARD); (1)
}
}
1 | This call cancels all deadlines with the name EXPIRED_GIFT_CARD for this aggregate instance.
It’s possible to use the return value from scheduling a deadline to cancel a specific deadline.
In this case, there can be at most one deadline scheduled with this name, so this is easier. |
And the event sourcing handler:
@EventSourcingHandler
public void on(CardRedeemedEvent event) {
remainingValue -= event.amount();
}
A test to make sure the deadline cancellation was successful:
@Test
void testCardNotExpiringIfNothingLeft() {
testFixture.givenNoPriorActivity()
.andGivenCommands(
new IssueExpiringCardCommand(CARD_ID, DAYS, AMOUNT),
new RedeemCardCommand(CARD_ID, AMOUNT)
)
.whenTimeElapses(Duration.ofDays(31L))
.expectSuccessfulHandlerExecution()
.expectNoEvents();
}
This should help get you started with deadlines. Don’t forget to switch the implementation to one of the deadline managers which offer persistence before moving to prod.