{"id":77,"date":"2019-11-14T21:27:09","date_gmt":"2019-11-14T21:27:09","guid":{"rendered":"https:\/\/www.kindsonthegenius.com\/microservices\/?p=77"},"modified":"2019-11-14T21:27:09","modified_gmt":"2019-11-14T21:27:09","slug":"cqrs-with-axon-tutorial-part-3-setup-the-commands-events-and-aggregate","status":"publish","type":"post","link":"https:\/\/www.kindsonthegenius.com\/microservices\/cqrs-with-axon-tutorial-part-3-setup-the-commands-events-and-aggregate\/","title":{"rendered":"CQRS With Axon Tutorial: Part 3 &#8211; Setup the Commands, Events and Aggregate"},"content":{"rendered":"<p>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<\/p>\n<ol>\n<li><a href=\"#t1\">Setup the Commands and Events Classes<\/a><\/li>\n<li><a href=\"#t2\">Setup the Aggregate<\/a><\/li>\n<li><a href=\"#t3\">Add the CommandHandlers<\/a><\/li>\n<li><a href=\"#t4\">Add the EventSourcingHandlers<\/a><\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<h5><strong id=\"t1\">1. Write the Command and Events<\/strong><\/h5>\n<p>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<\/p>\n<p>Follow the steps below:<\/p>\n<p><strong>Step 1:<\/strong> Add a kotlin file in the command package. Name it api.kt. This would contain our data classes<\/p>\n<p><strong>Step 2:<\/strong> Write the classes for IssueCommand, IssuedEvent, RedeemCommand and RedeemedEvent. The Content of the file will be as shown below:<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<pre style=\"margin: 0; line-height: 125%;\">import org.axonframework.modelling.command.TargetAggregateIdentifier\r\n\r\ndata <span style=\"color: #008800; font-weight: bold;\">class<\/span> <span style=\"color: #0066bb; font-weight: bold;\">IssueCommand<\/span>(@TargetAggregateIdentifier <span style=\"color: #008800; font-weight: bold;\">val<\/span> id: String, <span style=\"color: #008800; font-weight: bold;\">val<\/span> amount: Int);\r\ndata <span style=\"color: #008800; font-weight: bold;\">class<\/span> <span style=\"color: #0066bb; font-weight: bold;\">IssuedEvent<\/span>(<span style=\"color: #008800; font-weight: bold;\">val<\/span> id: String, <span style=\"color: #008800; font-weight: bold;\">val<\/span> amount: Int);\r\ndata <span style=\"color: #008800; font-weight: bold;\">class<\/span> <span style=\"color: #0066bb; font-weight: bold;\">RedeemCommand<\/span>(@TargetAggregateIdentifier <span style=\"color: #008800; font-weight: bold;\">val<\/span> id: String, <span style=\"color: #008800; font-weight: bold;\">val<\/span> amount: Int);\r\ndata <span style=\"color: #008800; font-weight: bold;\">class<\/span> <span style=\"color: #0066bb; font-weight: bold;\">RedeemedEvent<\/span>(<span style=\"color: #008800; font-weight: bold;\">val<\/span> id: String, <span style=\"color: #008800; font-weight: bold;\">val<\/span> amount: Int);\r\n<\/pre>\n<p>Note the @TargetAggregateIdentifier annotation. This enables targeting the particular aggregate when a command is issued<\/p>\n<p>&nbsp;<\/p>\n<h5><strong id=\"t2\">2. Setup the Aggregate<\/strong><\/h5>\n<p>An aggregate is &#8220;a logical group of entities that is treated as a single unit&#8221;. In this case, our aggregate would be a gift card.<\/p>\n<p>To set up the aggregate:<\/p>\n<p><strong>Step 1<\/strong>: Create a java file in the command package. Name it GiftCard<\/p>\n<p><strong>Step 2:<\/strong> Annotate the class with the @Aggregate annotation<\/p>\n<p><strong>Step 3:<\/strong> Create a private member variable id. It would be a String.<\/p>\n<p><strong>Step 4:<\/strong> Annotate this variable with @AggregateIdentifier annotation<\/p>\n<p>&nbsp;<\/p>\n<h5><strong id=\"t3\">3. Add the CommandHandlers<\/strong><\/h5>\n<p>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.<\/p>\n<p>Now we would add two command handlers for IssueCommand and RedeemCommand.<\/p>\n<p><strong>Step 1:<\/strong> 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.<\/p>\n<pre style=\"margin: 0; line-height: 125%;\">   <span style=\"color: #555555; font-weight: bold;\">@CommandHandler<\/span>\r\n    <span style=\"color: #008800; font-weight: bold;\">public<\/span> <span style=\"color: #0066bb; font-weight: bold;\">GiftCard<\/span><span style=\"color: #333333;\">(<\/span>IssueCommand cmd<span style=\"color: #333333;\">)<\/span> <span style=\"color: #333333;\">{<\/span>\r\n        <span style=\"color: #008800; font-weight: bold;\">if<\/span><span style=\"color: #333333;\">(<\/span>cmd<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">getAmount<\/span><span style=\"color: #333333;\">()&lt;=<\/span><span style=\"color: #0000dd; font-weight: bold;\">0<\/span><span style=\"color: #333333;\">)<\/span>\r\n            <span style=\"color: #008800; font-weight: bold;\">throw<\/span> <span style=\"color: #008800; font-weight: bold;\">new<\/span> <span style=\"color: #0066bb; font-weight: bold;\">IllegalArgumentException<\/span><span style=\"color: #333333;\">(<\/span><span style=\"background-color: #fff0f0;\">\"amount &lt;= 0\"<\/span><span style=\"color: #333333;\">);<\/span>\r\n        \r\n        AggregateLifecycle<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">apply<\/span><span style=\"color: #333333;\">(<\/span><span style=\"color: #008800; font-weight: bold;\">new<\/span> IssuedEvent<span style=\"color: #333333;\">(<\/span>cmd<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">getId<\/span><span style=\"color: #333333;\">(),<\/span> cmd<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">getAmount<\/span><span style=\"color: #333333;\">()));<\/span>\r\n    <span style=\"color: #333333;\">}<\/span>\r\n\r\n    <span style=\"color: #555555; font-weight: bold;\">@CommandHandler<\/span>\r\n    <span style=\"color: #008800; font-weight: bold;\">public<\/span> <span style=\"color: #333399; font-weight: bold;\">void<\/span> <span style=\"color: #0066bb; font-weight: bold;\">handle<\/span><span style=\"color: #333333;\">(<\/span>RedeemCommand cmd<span style=\"color: #333333;\">)<\/span> <span style=\"color: #333333;\">{<\/span>\r\n        <span style=\"color: #008800; font-weight: bold;\">if<\/span><span style=\"color: #333333;\">(<\/span>cmd<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">getAmount<\/span><span style=\"color: #333333;\">()&lt;=<\/span><span style=\"color: #0000dd; font-weight: bold;\">0<\/span><span style=\"color: #333333;\">)<\/span>\r\n            <span style=\"color: #008800; font-weight: bold;\">throw<\/span> <span style=\"color: #008800; font-weight: bold;\">new<\/span> <span style=\"color: #0066bb; font-weight: bold;\">IllegalArgumentException<\/span><span style=\"color: #333333;\">(<\/span><span style=\"background-color: #fff0f0;\">\"amount &lt;= 0\"<\/span><span style=\"color: #333333;\">);<\/span>\r\n        \r\n        <span style=\"color: #008800; font-weight: bold;\">if<\/span><span style=\"color: #333333;\">(<\/span>cmd<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">getAmount<\/span><span style=\"color: #333333;\">()<\/span> <span style=\"color: #333333;\">&gt;<\/span> balance<span style=\"color: #333333;\">)<\/span>\r\n            <span style=\"color: #008800; font-weight: bold;\">throw<\/span> <span style=\"color: #008800; font-weight: bold;\">new<\/span> <span style=\"color: #0066bb; font-weight: bold;\">IllegalArgumentException<\/span><span style=\"color: #333333;\">(<\/span><span style=\"background-color: #fff0f0;\">\"amount &gt; balance\"<\/span><span style=\"color: #333333;\">);<\/span>\r\n        \r\n        AggregateLifecycle<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">apply<\/span><span style=\"color: #333333;\">(<\/span><span style=\"color: #008800; font-weight: bold;\">new<\/span> RedeemedEvent<span style=\"color: #333333;\">(<\/span>cmd<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">getId<\/span><span style=\"color: #333333;\">(),<\/span> cmd<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">getAmount<\/span><span style=\"color: #333333;\">()));<\/span>\r\n    <span style=\"color: #333333;\">}<\/span>\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p><strong>Step 2:<\/strong> Create a private Integer field, balance in the GiftCard<\/p>\n<p><strong>Step 3:<\/strong> Create also an empty private constructor.<\/p>\n<p>&nbsp;<\/p>\n<h5><strong id=\"t4\">4. Add the EventSourcingHandlers<\/strong><\/h5>\n<p>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.<\/p>\n<p><strong>Step 1:<\/strong> Copy and Paste the code after the command handlers<\/p>\n<pre style=\"margin: 0; line-height: 125%;\">    <span style=\"color: #555555; font-weight: bold;\">@EventSourcingHandler<\/span>\r\n    <span style=\"color: #008800; font-weight: bold;\">public<\/span> <span style=\"color: #333399; font-weight: bold;\">void<\/span> <span style=\"color: #0066bb; font-weight: bold;\">on<\/span><span style=\"color: #333333;\">(<\/span>IssuedEvent evt<span style=\"color: #333333;\">){<\/span>\r\n        <span style=\"color: #888888;\">\/\/for a new card, the amount is the balance<\/span>\r\n        id <span style=\"color: #333333;\">=<\/span> evt<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">getId<\/span><span style=\"color: #333333;\">();<\/span>\r\n        balance <span style=\"color: #333333;\">=<\/span> evt<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">getAmount<\/span><span style=\"color: #333333;\">();<\/span>\r\n    <span style=\"color: #333333;\">}<\/span>\r\n\r\n    <span style=\"color: #555555; font-weight: bold;\">@EventSourcingHandler<\/span>\r\n    <span style=\"color: #008800; font-weight: bold;\">public<\/span> <span style=\"color: #333399; font-weight: bold;\">void<\/span> <span style=\"color: #0066bb; font-weight: bold;\">on<\/span><span style=\"color: #333333;\">(<\/span>RedeemedEvent evt<span style=\"color: #333333;\">)<\/span> <span style=\"color: #333333;\">{<\/span>\r\n        <span style=\"color: #888888;\">\/\/update the balance when a card is redeemed<\/span>\r\n        balance <span style=\"color: #333333;\">=<\/span> balance <span style=\"color: #333333;\">-<\/span> evt<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">getAmount<\/span><span style=\"color: #333333;\">();<\/span>\r\n    <span style=\"color: #333333;\">}<\/span>\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>So we&#8217;ve completed writing the handlers. I would recommend you build the project. Just to make sure everything is fine.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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 &hellip; <\/p>\n","protected":false},"author":1,"featured_media":78,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12,27],"tags":[29,30,31],"class_list":["post-77","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-axon","category-axonframework","tag-aggregate","tag-commandhandler","tag-eventsourcinghandler"],"_links":{"self":[{"href":"https:\/\/www.kindsonthegenius.com\/microservices\/wp-json\/wp\/v2\/posts\/77","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.kindsonthegenius.com\/microservices\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.kindsonthegenius.com\/microservices\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.kindsonthegenius.com\/microservices\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.kindsonthegenius.com\/microservices\/wp-json\/wp\/v2\/comments?post=77"}],"version-history":[{"count":1,"href":"https:\/\/www.kindsonthegenius.com\/microservices\/wp-json\/wp\/v2\/posts\/77\/revisions"}],"predecessor-version":[{"id":79,"href":"https:\/\/www.kindsonthegenius.com\/microservices\/wp-json\/wp\/v2\/posts\/77\/revisions\/79"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.kindsonthegenius.com\/microservices\/wp-json\/wp\/v2\/media\/78"}],"wp:attachment":[{"href":"https:\/\/www.kindsonthegenius.com\/microservices\/wp-json\/wp\/v2\/media?parent=77"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.kindsonthegenius.com\/microservices\/wp-json\/wp\/v2\/categories?post=77"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.kindsonthegenius.com\/microservices\/wp-json\/wp\/v2\/tags?post=77"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}