In this part, we are going to be setting up the Commands, Events and Aggregate. We also would set up the command and event handlers.We would cover the following
- Setup the Commands and Events Classes
- Setup the Aggregate
- Add the CommandHandlers
- Add the EventSourcingHandlers
1. Write the Command and Events
Remember that we chose Kotlin when we setup our project. The reason is that Kotlin provides a simple way of writing classes in just one line. Besides, several of such classes can be placed in a single kotlin file. Such classes are called data classes
Follow the steps below:
Step 1: Add a kotlin file in the command package. Name it api.kt. This would contain our data classes
Step 2: Write the classes for IssueCommand, IssuedEvent, RedeemCommand and RedeemedEvent. The Content of the file will be as shown below:
import org.axonframework.modelling.command.TargetAggregateIdentifier data class IssueCommand(@TargetAggregateIdentifier val id: String, val amount: Int); data class IssuedEvent(val id: String, val amount: Int); data class RedeemCommand(@TargetAggregateIdentifier val id: String, val amount: Int); data class RedeemedEvent(val id: String, val amount: Int);
Note the @TargetAggregateIdentifier annotation. This enables targeting the particular aggregate when a command is issued
2. Setup the Aggregate
An aggregate is “a logical group of entities that is treated as a single unit”. In this case, our aggregate would be a gift card.
To set up the aggregate:
Step 1: Create a java file in the command package. Name it GiftCard
Step 2: Annotate the class with the @Aggregate annotation
Step 3: Create a private member variable id. It would be a String.
Step 4: Annotate this variable with @AggregateIdentifier annotation
3. Add the CommandHandlers
CommandHandler is a function that specifies what happen when a command is executed. CommandHandlers are normally void functions with the name handle() and the take as parameter the command they are going to respond to.
Now we would add two command handlers for IssueCommand and RedeemCommand.
Step 1: Simply copy and paste the two event handlers after private variable id. Also note that I have annotated the code to explain what each part means.
@CommandHandler public GiftCard(IssueCommand cmd) { if(cmd.getAmount()<=0) throw new IllegalArgumentException("amount <= 0"); AggregateLifecycle.apply(new IssuedEvent(cmd.getId(), cmd.getAmount())); } @CommandHandler public void handle(RedeemCommand cmd) { if(cmd.getAmount()<=0) throw new IllegalArgumentException("amount <= 0"); if(cmd.getAmount() > balance) throw new IllegalArgumentException("amount > balance"); AggregateLifecycle.apply(new RedeemedEvent(cmd.getId(), cmd.getAmount())); }
Step 2: Create a private Integer field, balance in the GiftCard
Step 3: Create also an empty private constructor.
4. Add the EventSourcingHandlers
An EventSourcingHandler is an event executed when an event occurs. They are normally function with name on(). In this case we have two event sourcing handlers.
Step 1: Copy and Paste the code after the command handlers
@EventSourcingHandler public void on(IssuedEvent evt){ //for a new card, the amount is the balance id = evt.getId(); balance = evt.getAmount(); } @EventSourcingHandler public void on(RedeemedEvent evt) { //update the balance when a card is redeemed balance = balance - evt.getAmount(); }
So we’ve completed writing the handlers. I would recommend you build the project. Just to make sure everything is fine.
