pilo Software Developer http://pillopl.github.io CQRS with Spring <p style="text-align:justify;"> Hi folks. The New Stack just published my article about CQRS. It is a full story about how, when and why to apply this pattern with various Spring tools. You can find it <a href="https://thenewstack.io/how-cqrs-works-with-spring-tools/">here</a>. And I did the drawings myself! </p> Tue, 16 Oct 2018 00:00:00 +0000 http://pillopl.github.io/cqrs-with-spring/ http://pillopl.github.io/cqrs-with-spring/ How To Test Your Distributed Message-Driven Application With Spring? <p style="text-align:justify;"> Messaging is cool. It allows to deal with a broad set of various problems that developers face on a daily basis. It is not a silver bullet though. One must assess if their architectural drivers fit this pattern. A list of <b>tips</b> that might help you with this decision: </p> <ul> <li>Communication between some components needs to be asynchronous - producer fires and forgets. </li> <li>Consumer should process the messages at its own pace - independent from producer’s pace. This is so-called <i>throttling</i>.</li> <li>Communication should be reliable - message broker can store and forward messages. Thus, producer does not need to care about retrying.</li> <li>We deal with <i>occasionally connected</i> devices. Those are component that tend to be offline or down but need to synchronize as soon as the reconnect. Disconnection must not affect the producer. The need for two components to be alive at the same time is called <i>temporal coupling</i>.</li> <li>There is a need for multicast/broadcast.</li> <li>One of our components uses <i>event sourcing</i>. You can learn about that concept listening to this <a href="https://www.youtube.com/watch?v=WRUMjjqF1nc">talk.</a></li> <li>There is already a production setup of a message broker in your infrastructure.</li> </ul> <p style="text-align:justify;"> Note that those are mosty tips at distributed level. One can think about benefits of having messaging in monoliths architectures too. Like <i>Inversion of Control</i> - a way to continue a business process in a different part of same application. Or concurrency control implemented in actor model. An actor has its internal queue of messages processed one at a time. In this article we will read about testing message-driven systems in distributed syastems. Systems which use messaging as transport mechanism (first five tips) and event sourcing. </p> <p style="text-align:justify;"> Let’s imagine an enterprise that issues credit cards under one condition - a potential client’s age. There is a REST API to do so: </p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@RestController</span><span class="o">(</span><span class="s">"/applications"</span><span class="o">)</span> <span class="kd">class</span> <span class="nc">CreditCardApplicationController</span> <span class="o">{</span> <span class="kd">private</span> <span class="kd">final</span> <span class="n">ApplyForCardService</span> <span class="n">applyForCardService</span><span class="o">;</span> <span class="n">CreditCardApplicationController</span><span class="o">(</span><span class="n">ApplyForCardService</span> <span class="n">applyForCardService</span><span class="o">)</span> <span class="o">{</span> <span class="k">this</span><span class="o">.</span><span class="na">applyForCardService</span> <span class="o">=</span> <span class="n">applyForCardService</span><span class="o">;</span> <span class="o">}</span> <span class="nd">@PostMapping</span> <span class="n">ResponseEntity</span> <span class="nf">applyForCard</span><span class="o">(</span><span class="nd">@RequestBody</span> <span class="n">CardApplication</span> <span class="n">cardApplication</span><span class="o">)</span> <span class="o">{</span> <span class="k">return</span> <span class="n">applyForCardService</span> <span class="o">.</span><span class="na">apply</span><span class="o">(</span><span class="n">cardApplication</span><span class="o">.</span><span class="na">getPesel</span><span class="o">())</span> <span class="o">.</span><span class="na">map</span><span class="o">(</span><span class="n">card</span> <span class="o">-&gt;</span> <span class="n">ok</span><span class="o">().</span><span class="na">build</span><span class="o">())</span> <span class="o">.</span><span class="na">orElse</span><span class="o">(</span><span class="n">status</span><span class="o">(</span><span class="n">FORBIDDEN</span><span class="o">).</span><span class="na">build</span><span class="o">());</span> <span class="o">}</span> <span class="o">}</span> </code></pre></div></div> <p>And an application service responsible for the decision:</p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Service</span> <span class="kd">class</span> <span class="nc">ApplyForCardService</span> <span class="o">{</span> <span class="kd">private</span> <span class="kd">final</span> <span class="n">CreditCardRepository</span> <span class="n">creditCardRepository</span><span class="o">;</span> <span class="n">ApplyForCardService</span><span class="o">(</span><span class="n">CreditCardRepository</span> <span class="n">creditCardRepository</span><span class="o">)</span> <span class="o">{</span> <span class="k">this</span><span class="o">.</span><span class="na">creditCardRepository</span> <span class="o">=</span> <span class="n">creditCardRepository</span><span class="o">;</span> <span class="o">}</span> <span class="nd">@Transactional</span> <span class="kd">public</span> <span class="n">Optional</span><span class="o">&lt;</span><span class="n">CreditCard</span><span class="o">&gt;</span> <span class="nf">apply</span><span class="o">(</span><span class="kt">int</span> <span class="n">age</span><span class="o">)</span> <span class="o">{</span> <span class="k">if</span> <span class="o">(</span><span class="n">bornBeforeSeventies</span><span class="o">(</span><span class="n">age</span><span class="o">))</span> <span class="o">{</span> <span class="k">return</span> <span class="n">Optional</span><span class="o">.</span><span class="na">empty</span><span class="o">();</span> <span class="o">}</span> <span class="n">CreditCard</span> <span class="n">card</span> <span class="o">=</span> <span class="n">CreditCard</span><span class="o">.</span><span class="na">withDefaultLimit</span><span class="o">(</span><span class="n">age</span><span class="o">);</span> <span class="n">creditCardRepository</span><span class="o">.</span><span class="na">save</span><span class="o">(</span><span class="n">card</span><span class="o">);</span> <span class="k">return</span> <span class="nf">of</span><span class="o">(</span><span class="n">card</span><span class="o">);</span> <span class="o">}</span> <span class="o">}</span> </code></pre></div></div> <p style="text-align:justify;"> Imagine a new business need. System must react to a certain decision. If a card is granted, system must deal with that fact in a particular manner. If a card application is rejected, it must do something else. Whatever it is. It might be an email, an update in a reporting tool or anything else. But this process continues in a different application in the distributed environment. Plus this application can be temporary offline. Of course, it should not affect the granting/rejecting process. Did I mention that there is a huge probability that more applications would like to know final result of the process? </p> <p style="text-align:justify;"> By now, it should be clear that messaging might be a good fit for this problem. We will add one line of coded escribing what has happened. A message saying that either the card was granted or the application was rejected. Nothing more. A special kind of a message that represent a fact in a past is called an <i>event</i>. We need a component that will be responsible for publishing those events. Its responsibility is clear, but let’s postpone the implementation. Additionally, there might be several ones, so let’s add an interface for the time being: </p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">interface</span> <span class="nc">DomainEventPublisher</span> <span class="o">{</span> <span class="kt">void</span> <span class="nf">publish</span><span class="o">(</span><span class="n">DomainEvent</span> <span class="n">event</span><span class="o">);</span> <span class="o">}</span> <span class="kd">interface</span> <span class="nc">DomainEvent</span> <span class="o">{</span> <span class="n">String</span> <span class="nf">getType</span><span class="o">();</span> <span class="o">}</span> </code></pre></div></div> <p style="text-align:justify;"> <i>DomainEvent</i> interface contains only an information about the event’s type. This might be handy while distributing or subscribing to specific messages. </p> <p><strong><em>After you, dear test</em></strong></p> <p>Any production code that is not proved by a test is just a rumour, so here goes an unit test:</p> <div class="language-groovy highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">def</span> <span class="s1">'should emit CardGranted when client born in 70s or later'</span><span class="o">()</span> <span class="o">{</span> <span class="nl">when:</span> <span class="n">applyForCardService</span><span class="o">.</span><span class="na">apply</span><span class="o">(</span><span class="s2">"89121514667"</span><span class="o">)</span> <span class="nl">then:</span> <span class="mi">1</span> <span class="o">*</span> <span class="n">domainEventsPublisher</span><span class="o">.</span><span class="na">publish</span><span class="o">(</span> <span class="o">{</span> <span class="n">it</span> <span class="k">instanceof</span> <span class="n">CardGranted</span> <span class="o">}</span> <span class="o">)</span> <span class="o">}</span> <span class="kt">def</span> <span class="s1">'should emit CardApplicationRejected when client born before 70s'</span><span class="o">()</span> <span class="o">{</span> <span class="nl">when:</span> <span class="n">applyForCardService</span><span class="o">.</span><span class="na">apply</span><span class="o">(</span><span class="s2">"66121514667"</span><span class="o">)</span> <span class="nl">then:</span> <span class="mi">1</span> <span class="o">*</span> <span class="n">domainEventsPublisher</span><span class="o">.</span><span class="na">publish</span><span class="o">(</span> <span class="o">{</span> <span class="n">it</span> <span class="k">instanceof</span> <span class="n">CardApplicationRejected</span> <span class="o">}</span> <span class="o">)</span> <span class="o">}</span> </code></pre></div></div> <p>And in order for the test to pass:</p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Transactional</span> <span class="kd">public</span> <span class="n">Optional</span><span class="o">&lt;</span><span class="n">CreditCard</span><span class="o">&gt;</span> <span class="nf">apply</span><span class="o">(</span><span class="n">String</span> <span class="n">pesel</span><span class="o">)</span> <span class="o">{</span> <span class="k">if</span> <span class="o">(</span><span class="n">bornBeforeSeventies</span><span class="o">(</span><span class="n">pesel</span><span class="o">))</span> <span class="o">{</span> <span class="n">domainEventsPublisher</span><span class="o">.</span><span class="na">publish</span><span class="o">(</span><span class="k">new</span> <span class="n">CardApplicationRejected</span><span class="o">(</span><span class="n">pesel</span><span class="o">));</span> <span class="k">return</span> <span class="n">Optional</span><span class="o">.</span><span class="na">empty</span><span class="o">();</span> <span class="o">}</span> <span class="n">CreditCard</span> <span class="n">card</span> <span class="o">=</span> <span class="n">CreditCard</span><span class="o">.</span><span class="na">withDefaultLimit</span><span class="o">(</span><span class="n">pesel</span><span class="o">);</span> <span class="n">creditCardRepository</span><span class="o">.</span><span class="na">save</span><span class="o">(</span><span class="n">card</span><span class="o">);</span> <span class="n">domainEventsPublisher</span><span class="o">.</span><span class="na">publish</span><span class="o">(</span><span class="k">new</span> <span class="n">CardGranted</span><span class="o">(</span><span class="n">card</span><span class="o">.</span><span class="na">getCardNo</span><span class="o">(),</span> <span class="n">card</span><span class="o">.</span><span class="na">getCardLimit</span><span class="o">(),</span> <span class="n">pesel</span><span class="o">));</span> <span class="k">return</span> <span class="nf">of</span><span class="o">(</span><span class="n">card</span><span class="o">);</span> <span class="o">}</span> </code></pre></div></div> <p style="text-align:justify;"> Voilà. Let’s go to production. All tests are green and that means we are good to go. But ... the application does not start on my local machine. There is no spring bean that implements the DomainEventPublisher interface. The unit test might be useful to drive a good design. Especially if you are a <a href="https://martinfowler.com/articles/mocksArentStubs.html">mockist TDD practitioner</a>. But it is clearly not enough. Communicating with an external infrastructure from a business code is rather an integration task, isn’t it? So how about an integration test? But do we want to have a dependency on a message broker in our tests? Does it need to run to build the application? Or should each of the developers have their own local instance of the broker? The answer to every of those questions is no. Tests should run in isolation. Let’s finally implement the interface. And let's test the whole process with an integration test. </p> <p style="text-align:justify;"> We can use a wonderful tool - <a href="https://cloud.spring.io/spring-cloud-stream">Spring Cloud Stream</a> - to implement the messaging part. In short, this is a framework that abstracts messaging paths with so-called channels. Channels are bound to a specific broker’s destinations by classpath scanning. The tools looks for binders to Kafka or RabbitMQ. Let’s choose RabbitMQ. Our credit card application is a producer to one channel. That means it is a source for messages. Simillary, the consumer is a sink. We need to remove the dependency to a real broker in tests. To do so, we are going to replace the production implementation with <a href="https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/test/mock/mockito/MockBean.html">@MockBean</a>. </p> <p>The integration test (in jUnit, because it is easier to use @MockBean in jUnit):</p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@MockBean</span> <span class="n">DomainEventsPublisher</span> <span class="n">domainEventsPublisher</span><span class="o">;</span> <span class="nd">@Autowired</span> <span class="n">CreditCardApplicationController</span> <span class="n">cardApplicationController</span><span class="o">;</span> <span class="nd">@Test</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">shouldEmitCardGrantedEvent</span><span class="o">()</span> <span class="o">{</span> <span class="c1">// when</span> <span class="n">cardApplicationController</span><span class="o">.</span><span class="na">applyForCard</span><span class="o">(</span><span class="k">new</span> <span class="n">CardApplication</span><span class="o">(</span><span class="s">"70345678"</span><span class="o">));</span> <span class="c1">// then</span> <span class="n">verify</span><span class="o">(</span><span class="n">domainEventsPublisher</span><span class="o">).</span><span class="na">publish</span><span class="o">(</span><span class="n">isA</span><span class="o">(</span><span class="n">CardGranted</span><span class="o">.</span><span class="na">class</span><span class="o">));</span> <span class="o">}</span> <span class="nd">@Test</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">shouldEmitCardApplicationRejectedEvent</span><span class="o">()</span> <span class="o">{</span> <span class="c1">// when</span> <span class="n">cardApplicationController</span><span class="o">.</span><span class="na">applyForCard</span><span class="o">(</span><span class="k">new</span> <span class="n">CardApplication</span><span class="o">(</span><span class="s">"60345678"</span><span class="o">));</span> <span class="c1">// then</span> <span class="n">verify</span><span class="o">(</span><span class="n">domainEventsPublisher</span><span class="o">).</span><span class="na">publish</span><span class="o">(</span><span class="n">isA</span><span class="o">(</span><span class="n">CardApplicationRejected</span><span class="o">.</span><span class="na">class</span><span class="o">));</span> <span class="o">}</span> </code></pre></div></div> <p>Implementation:</p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">RabbitMqDomainEventPublisher</span> <span class="kd">implements</span> <span class="n">DomainEventsPublisher</span> <span class="o">{</span> <span class="kd">private</span> <span class="kd">final</span> <span class="n">Source</span> <span class="n">source</span><span class="o">;</span> <span class="n">RabbitMqDomainEventPublisher</span><span class="o">(</span><span class="n">Source</span> <span class="n">source</span><span class="o">)</span> <span class="o">{</span> <span class="k">this</span><span class="o">.</span><span class="na">source</span> <span class="o">=</span> <span class="n">source</span><span class="o">;</span> <span class="o">}</span> <span class="nd">@Override</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">publish</span><span class="o">(</span><span class="n">DomainEvent</span> <span class="n">domainEvent</span><span class="o">)</span> <span class="o">{</span> <span class="n">Map</span><span class="o">&lt;</span><span class="n">String</span><span class="o">,</span> <span class="n">Object</span><span class="o">&gt;</span> <span class="n">headers</span> <span class="o">=</span> <span class="k">new</span> <span class="n">HashMap</span><span class="o">&lt;&gt;();</span> <span class="n">headers</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"type"</span><span class="o">,</span> <span class="n">domainEvent</span><span class="o">.</span><span class="na">getType</span><span class="o">());</span> <span class="n">source</span><span class="o">.</span><span class="na">output</span><span class="o">().</span><span class="na">send</span><span class="o">(</span><span class="k">new</span> <span class="n">GenericMessage</span><span class="o">&lt;&gt;(</span><span class="n">domainEvent</span><span class="o">,</span> <span class="n">headers</span><span class="o">));</span> <span class="o">}</span> <span class="o">}</span> </code></pre></div></div> <p>And listener at consumer’s side:</p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Component</span> <span class="kd">class</span> <span class="nc">Listener</span> <span class="o">{</span> <span class="kd">private</span> <span class="kd">static</span> <span class="kd">final</span> <span class="n">Logger</span> <span class="n">log</span> <span class="o">=</span> <span class="n">LoggerFactory</span><span class="o">.</span><span class="na">getLogger</span><span class="o">(</span><span class="n">Listener</span><span class="o">.</span><span class="na">class</span><span class="o">);</span> <span class="nd">@StreamListener</span><span class="o">(</span><span class="n">target</span> <span class="o">=</span> <span class="n">Sink</span><span class="o">.</span><span class="na">INPUT</span><span class="o">,</span> <span class="n">condition</span> <span class="o">=</span> <span class="s">"headers['type'] == 'card-granted'"</span><span class="o">)</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">receiveGranted</span><span class="o">(</span><span class="nd">@Payload</span> <span class="n">CardGranted</span> <span class="n">granted</span><span class="o">)</span> <span class="o">{</span> <span class="n">log</span><span class="o">.</span><span class="na">info</span><span class="o">(</span><span class="s">"\n\nGRANTED ["</span> <span class="o">+</span> <span class="n">granted</span><span class="o">.</span><span class="na">getClientPesel</span><span class="o">()</span> <span class="o">+</span> <span class="s">"] !!!! :) :) :)\n\n"</span><span class="o">);</span> <span class="o">}</span> <span class="nd">@StreamListener</span><span class="o">(</span><span class="n">target</span> <span class="o">=</span> <span class="n">Sink</span><span class="o">.</span><span class="na">INPUT</span><span class="o">,</span> <span class="n">condition</span> <span class="o">=</span> <span class="s">"headers['type'] == 'card-application-rejected'"</span><span class="o">)</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">receiveRejected</span><span class="o">(</span><span class="nd">@Payload</span> <span class="n">CardApplicationRejected</span> <span class="n">rejected</span><span class="o">)</span> <span class="o">{</span> <span class="n">log</span><span class="o">.</span><span class="na">info</span><span class="o">(</span><span class="s">"\n\nREJECTED ["</span> <span class="o">+</span> <span class="n">rejected</span><span class="o">.</span><span class="na">getClientPesel</span><span class="o">()</span> <span class="o">+</span> <span class="s">"] !!!! :( :( :(\n\n"</span><span class="o">);</span> <span class="o">}</span> <span class="o">}</span> </code></pre></div></div> <p style="text-align:justify;"> Note the use of headers - this allows us to distribute messages to specific methods at the consumer’s side. </p> <p style="text-align:justify;"> This time we are definitely good to deploy to production. We have both unit and integration tests. Let’s run the application on our local machine for the last time. ...and it failed for the same reason. No bean that implements the DomainEventPublisher interface. We forgot to register the implementation as a spring bean. But wait a minute, how come the integration test passes? Take a closer look at the @MockBean docs: </p> <blockquote class="cite"> <p>“Mocks can be registered by type or by bean name. Any existing single bean of the same type defined in the context will be replaced by the mock. <b>If no existing bean is defined a new one will be added.</b> “ </p> </blockquote> <p><strong><em>Unit test vs Integration test</em></strong></p> <p style="text-align:justify;"> So the tool added the bean to the application context. Even though its real implementation was not there. And this is by design. We should have been more careful. Let's notice some facts about our new integration test:</p> <ul> <li>It setups the whole context.</li> <li>It is significantly longer than the unit test.</li> <li>It even uses an embedded H2 database by default.</li> <li>… but it still tests our messaging in the mockist’s way!</li> <li>… but it still can be green without the actual implementation (just like the unit test)</li> <li>… but still the communication with broker is not tested.</li> </ul> <p style="text-align:justify;"> The architectural diagram is worth more than a thousand words so let’s take a look at two of those: </p> <p style="text-align:center"> <img src="/images/archs.png" style="width: 50%; height: 50%; align: center" />​ </p> <p style="text-align:justify;"> The left one shows what was tested by the unit test. Everything else is blurred. And the second one highlights what was tested by the integration test. </p> <p style="text-align:justify;"> In both cases, the actual messaging (DomainEventPublisher) was not tested. Moreover, the integration test examines more not that essential components. Not essential, taking into account that DomainEventPublisher is still left untested. There must be a better way. Let’s take a deeper look at Spring Cloud Stream’s documentation. <a href="https://docs.spring.io/spring-cloud-stream/docs/current/reference/html/_testing.html">In a paragraph about testing</a> we can find an interesting note:</p> <blockquote class="cite"> <p>“... we are using the <b>MessageCollector</b> provided by Spring Cloud Stream’s test support to capture the message has been sent to the output channel as a result. Once we have received the message, we can validate that the component functions correctly.”</p> </blockquote> <p><strong><em>Spring Cloud Stream Testing Support</em></strong></p> <p style="text-align:justify;"> So here it is! Testing support and in particular <i>MessageCollector</i> can help us test our code. Without a dependency to a real broker. Instead, the messages can be held in an internal in-memory blocking queue. Here goes the test: </p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@SpringBootTest</span> <span class="kd">class</span> <span class="nc">ApplyForCardWithEventMessageCollectorTest</span> <span class="kd">extends</span> <span class="n">Specification</span> <span class="o">{</span> <span class="nd">@Autowired</span> <span class="n">CreditCardApplicationController</span> <span class="n">cardApplicationController</span> <span class="nd">@Autowired</span> <span class="n">Source</span> <span class="n">source</span> <span class="nd">@Autowired</span> <span class="n">MessageCollector</span> <span class="n">messageCollector</span> <span class="n">BlockingQueue</span><span class="o">&lt;</span><span class="n">GenericMessage</span><span class="o">&lt;</span><span class="n">String</span><span class="o">&gt;&gt;</span> <span class="n">events</span> <span class="n">def</span> <span class="nf">setup</span><span class="o">()</span> <span class="o">{</span> <span class="n">events</span> <span class="o">=</span> <span class="n">messageCollector</span><span class="o">.</span><span class="na">forChannel</span><span class="o">(</span><span class="n">source</span><span class="o">.</span><span class="na">output</span><span class="o">())</span> <span class="o">}</span> <span class="n">def</span> <span class="err">'</span><span class="n">should</span> <span class="n">be</span> <span class="n">able</span> <span class="n">to</span> <span class="n">get</span> <span class="n">card</span> <span class="n">when</span> <span class="n">born</span> <span class="n">in</span> <span class="mi">70</span><span class="n">s</span> <span class="n">or</span> <span class="n">later</span><span class="err">'</span><span class="o">()</span> <span class="o">{</span> <span class="nl">when:</span> <span class="n">cardApplicationController</span><span class="o">.</span><span class="na">applyForCard</span><span class="o">(</span><span class="k">new</span> <span class="n">CardApplication</span><span class="o">(</span><span class="mi">20</span><span class="o">))</span> <span class="nl">then:</span> <span class="n">events</span><span class="o">.</span><span class="na">poll</span><span class="o">().</span><span class="na">getHeaders</span><span class="o">().</span><span class="na">containsValue</span><span class="o">(</span><span class="s">"card-granted"</span><span class="o">)</span> <span class="o">}</span> <span class="n">def</span> <span class="err">'</span><span class="n">should</span> <span class="n">not</span> <span class="n">be</span> <span class="n">able</span> <span class="n">to</span> <span class="n">get</span> <span class="n">card</span> <span class="n">when</span> <span class="n">born</span> <span class="n">before</span> <span class="mi">70</span><span class="n">s</span><span class="err">'</span><span class="o">()</span> <span class="o">{</span> <span class="nl">when:</span> <span class="n">cardApplicationController</span><span class="o">.</span><span class="na">applyForCard</span><span class="o">(</span><span class="k">new</span> <span class="n">CardApplication</span><span class="o">(</span><span class="mi">90</span><span class="o">))</span> <span class="nl">then:</span> <span class="n">events</span><span class="o">.</span><span class="na">poll</span><span class="o">().</span><span class="na">getHeaders</span><span class="o">().</span><span class="na">containsValue</span><span class="o">(</span><span class="s">"card-application-rejected"</span><span class="o">)</span> <span class="o">}</span> <span class="o">}</span> </code></pre></div></div> <p style="text-align:justify;"> That means we can finally use the same bean as in production code. We finally test the whole producer's side: </p> <p style="text-align:center"> <img src="/images/collector-arch.png" style="width: 25%; height: 25%" align="middle" />​ </p> <p style="text-align:justify;"> Our application is starting on our local machine! We can finally deploy to production. Just before doing so, let’s also start a consumer application and a docker image of RabbitMQ. Let’s trigger some messages and see them received at the consumer’s side: </p> <p style="text-align:center"> <img src="/images/got-failure.png" style="width: 100%; height: 100%" />​ </p> <p style="text-align:justify;"> It worked! Or did it? Wait a minute. The listener is able to get the message, but its content is empty! Why there is null value? What could have gone wrong? The complete test was created. Plus, it examines exactly the same path as the production code. But there is one thing that we need to know about it. <i>MessageCollector</i> captures the message in an internal queue <b>before</b> actual serialization. This serialization happens in the production code. It happens while sending a message to a channel! That leads us to a point that there must be something wrong with our serialization. The channel is configured to talk in JSON, so probably we need to help Jackson a bit. Let’s have a quick look at the classes that represent events: </p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">CardApplicationRejected</span> <span class="kd">implements</span> <span class="n">DomainEvent</span> <span class="o">{</span> <span class="kd">private</span> <span class="kd">final</span> <span class="n">String</span> <span class="n">clientPesel</span><span class="o">;</span> <span class="kd">private</span> <span class="kd">final</span> <span class="n">Instant</span> <span class="n">timestamp</span> <span class="o">=</span> <span class="n">Instant</span><span class="o">.</span><span class="na">now</span><span class="o">();</span> <span class="kd">public</span> <span class="nf">CardApplicationRejected</span><span class="o">(</span><span class="n">String</span> <span class="n">clientPesel</span><span class="o">)</span> <span class="o">{</span> <span class="k">this</span><span class="o">.</span><span class="na">clientPesel</span> <span class="o">=</span> <span class="n">clientPesel</span><span class="o">;</span> <span class="o">}</span> <span class="nd">@Override</span> <span class="kd">public</span> <span class="n">String</span> <span class="nf">getType</span><span class="o">()</span> <span class="o">{</span> <span class="k">return</span> <span class="s">"card-application-rejected"</span><span class="o">;</span> <span class="o">}</span> <span class="o">}</span> </code></pre></div></div> <p style="text-align:justify;"> A careful reader will quickly spot the problem. The getters are not there and Jackson by default will not serialize any field without a getter. Let’s fix that and rerun: </p> <p style="text-align:center"> <img src="/images/got-success.png" style="width: 100%; height: 100%" />​ </p> <p style="text-align:justify;"> Success. It finally worked. The producer and consumer can communicate without issues. But does it mean there is no way of testing it without doing the manual check? Does it mean that each time we develop a message-driven system, we must set it up on a local machine? And manually prove its correctness? Of course not. </p> <p><strong><em>Spring Cloud Contract</em></strong></p> <p style="text-align:justify;"> To automatically test the whole process we would have to bring up the consumer side as a dependency. Plus a message broker. We have already said that this is not the best idea since we want to run tests in isolation. They should not be dependent on a presence of another component. Fortunately, there is a tool called <a href="https://cloud.spring.io/spring-cloud-contract/">Spring Cloud Contract</a>. With this framework we can check if microservices will communicate on production environment. And all that without having to create a test that brings all of them up. Plus, it works with both messaging and REST APIs. Sounds like a perfect fit. </p> <p style="text-align:justify;"> The producer declares a contract. It says that if there is a rejection of a card application, some message should be sent to a specific channel. The contract defines the body of that message: </p> <div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">label</span><span class="pi">:</span> <span class="s">card_rejected</span> <span class="na">input</span><span class="pi">:</span> <span class="na">triggeredBy</span><span class="pi">:</span> <span class="s">sendRejected()</span> <span class="na">outputMessage</span><span class="pi">:</span> <span class="na">sentTo</span><span class="pi">:</span> <span class="s">channel</span> <span class="na">headers</span><span class="pi">:</span> <span class="na">type</span><span class="pi">:</span> <span class="s">card-application-rejected</span> <span class="na">contentType</span><span class="pi">:</span> <span class="s">application/json</span> <span class="na">body</span><span class="pi">:</span> <span class="na">clientPesel</span><span class="pi">:</span> <span class="s">86010156812</span> <span class="na">timestamp</span><span class="pi">:</span> <span class="s">2018-01-01T12:12:12.000Z</span> <span class="na">matchers</span><span class="pi">:</span> <span class="na">body</span><span class="pi">:</span> <span class="pi">-</span> <span class="na">path</span><span class="pi">:</span> <span class="s">$.timestamp</span> <span class="na">type</span><span class="pi">:</span> <span class="s">by_regex</span> <span class="na">predefined</span><span class="pi">:</span> <span class="s">iso_8601_with_offset</span> </code></pre></div></div> <p style="text-align:justify;"> The contract is packaged as a maven artifact. Based on that contract, a test is <b>automatically</b> generated. Its purpose is to check if the producer adheres to what is in the contract. It looks like this: </p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Test</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">validate_shouldSendACardRejectedEvent</span><span class="o">()</span> <span class="kd">throws</span> <span class="n">Exception</span> <span class="o">{</span> <span class="c1">// when:</span> <span class="n">sendRejected</span><span class="o">();</span> <span class="c1">// then:</span> <span class="n">ContractVerifierMessage</span> <span class="n">response</span> <span class="o">=</span> <span class="n">contractVerifierMessaging</span><span class="o">.</span><span class="na">receive</span><span class="o">(</span><span class="s">"channel"</span><span class="o">);</span> <span class="n">assertThat</span><span class="o">(</span><span class="n">response</span><span class="o">).</span><span class="na">isNotNull</span><span class="o">();</span> <span class="n">assertThat</span><span class="o">(</span><span class="n">response</span><span class="o">.</span><span class="na">getHeader</span><span class="o">(</span><span class="s">"type"</span><span class="o">)).</span><span class="na">isNotNull</span><span class="o">();</span> <span class="n">assertThat</span><span class="o">(</span><span class="n">response</span><span class="o">.</span><span class="na">getHeader</span><span class="o">(</span><span class="s">"type"</span><span class="o">).</span><span class="na">toString</span><span class="o">()).</span><span class="na">isEqualTo</span><span class="o">(</span><span class="s">"card-application-rejected"</span><span class="o">);</span> <span class="n">assertThat</span><span class="o">(</span><span class="n">response</span><span class="o">.</span><span class="na">getHeader</span><span class="o">(</span><span class="s">"contentType"</span><span class="o">)).</span><span class="na">isNotNull</span><span class="o">();</span> <span class="n">assertThat</span><span class="o">(</span><span class="n">response</span><span class="o">.</span><span class="na">getHeader</span><span class="o">(</span><span class="s">"contentType"</span><span class="o">).</span><span class="na">toString</span><span class="o">()).</span><span class="na">isEqualTo</span><span class="o">(</span><span class="s">"application/json"</span><span class="o">);</span> <span class="c1">// and:</span> <span class="n">DocumentContext</span> <span class="n">parsedJson</span> <span class="o">=</span> <span class="n">JsonPath</span><span class="o">.</span><span class="na">parse</span><span class="o">(</span><span class="n">contractVerifierObjectMapper</span><span class="o">.</span><span class="na">writeValueAsString</span><span class="o">(</span><span class="n">response</span><span class="o">.</span><span class="na">getPayload</span><span class="o">()));</span> <span class="n">assertThatJson</span><span class="o">(</span><span class="n">parsedJson</span><span class="o">).</span><span class="na">field</span><span class="o">(</span><span class="s">"['clientPesel']"</span><span class="o">).</span><span class="na">isEqualTo</span><span class="o">(</span><span class="mi">86010156812L</span><span class="o">);</span> <span class="c1">// and:</span> <span class="n">assertThat</span><span class="o">(</span><span class="n">parsedJson</span><span class="o">.</span><span class="na">read</span><span class="o">(</span><span class="s">"$.timestamp"</span><span class="o">,</span> <span class="n">String</span><span class="o">.</span><span class="na">class</span><span class="o">)).</span><span class="na">matches</span><span class="o">(</span><span class="s">"([0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(\\.\\d{3})?(Z|[+-][01]\\d:[0-5]\\d)"</span><span class="o">);</span> <span class="o">}</span> </code></pre></div></div> <p style="text-align:justify;"> Note that the test examines the message body. So in our previous example, it would have spotted the problem with the lack of any getter. Plus, this test is fired each time we would build the producer application. Each version of a producer comes with a corresponding version of stubs defined in a contract. How cool is that? </p> <p><strong><em>Transaction semantics</em></strong></p> <p style="text-align:justify;"> Have you noticed any problem with the code that grants/rejects credit cards? Something about events, maybe? Let’s have a second look: </p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Transactional</span> <span class="kd">public</span> <span class="n">Optional</span><span class="o">&lt;</span><span class="n">CreditCard</span><span class="o">&gt;</span> <span class="nf">apply</span><span class="o">(</span><span class="n">String</span> <span class="n">pesel</span><span class="o">)</span> <span class="o">{</span> <span class="c1">// (...)</span> <span class="n">creditCardRepository</span><span class="o">.</span><span class="na">save</span><span class="o">(</span><span class="n">card</span><span class="o">);</span> <span class="n">domainEventsPublisher</span> <span class="o">.</span><span class="na">publish</span><span class="o">(</span><span class="k">new</span> <span class="n">CardGranted</span><span class="o">(</span><span class="n">card</span><span class="o">.</span><span class="na">getCardNo</span><span class="o">(),</span> <span class="n">card</span><span class="o">.</span><span class="na">getCardLimit</span><span class="o">(),</span> <span class="n">pesel</span><span class="o">));</span> <span class="k">return</span> <span class="nf">of</span><span class="o">(</span><span class="n">card</span><span class="o">);</span> <span class="o">}</span> </code></pre></div></div> <p style="text-align:justify;"> How to atomically save a newly created card to our database and send a message to our message broker? Remember that actual commit to the database takes place after returning from the body of this method. The proxy does that. <i>Two-phase-commit</i> is not an option because we don’t want to downgrade the performance. Let’s examine following scenarios: <ul> <li>Sending to the broker failed. Database transaction rollbacks and everything is fine. Neither credit card nor message was saved.</li> <li>Sending to the broker was successful. Spring proxy tries to commit and database is down. The message was sent while the card was not saved.</li> </ul> </p> <p style="text-align:justify;"> One can come up with an idea of reordering the steps. First, let’s make sure that the card was saved. Only then we are entitled to announce that via event. This scenario can be implemented using a callback registered with <a href="https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/transaction/support/TransactionSynchronizationManager.html">TransactionSynchronizationManager</a>. But what if the broker is not online? Or our application was killed between successful commit and callback execution? . The system will try to send that only once, it is crucial to understand that this is <i>at-most-once</i> guaranty. </p> <p style="text-align:justify;"> What if we must send this message eventually? What if the requirement says that it must appear if a card was successfully saved? We can take advantage of the fact that most probably there is an ACID database in our toolbox. Let’s store both in one storage, using one transaction! A separate thread can take a look at all events saved in that storage and fetch ones not yet sent to the broker. Then send them and mark as sent. All in a couple of lines in new implementation of DomainEventPublisher:</p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Component</span> <span class="kd">public</span> <span class="kd">class</span> <span class="nc">FromDBDomainEventPublisher</span> <span class="kd">implements</span> <span class="n">DomainEventsPublisher</span> <span class="o">{</span> <span class="kd">private</span> <span class="kd">final</span> <span class="n">DomainEventStorage</span> <span class="n">domainEventStorage</span><span class="o">;</span> <span class="kd">private</span> <span class="kd">final</span> <span class="n">ObjectMapper</span> <span class="n">objectMapper</span><span class="o">;</span> <span class="kd">private</span> <span class="kd">final</span> <span class="n">Source</span> <span class="n">source</span><span class="o">;</span> <span class="kd">public</span> <span class="nf">FromDBDomainEventPublisher</span><span class="o">(</span><span class="n">DomainEventStorage</span> <span class="n">domainEventStorage</span><span class="o">,</span> <span class="n">ObjectMapper</span> <span class="n">objectMapper</span><span class="o">,</span> <span class="n">Source</span> <span class="n">source</span><span class="o">)</span> <span class="o">{</span> <span class="k">this</span><span class="o">.</span><span class="na">domainEventStorage</span> <span class="o">=</span> <span class="n">domainEventStorage</span><span class="o">;</span> <span class="k">this</span><span class="o">.</span><span class="na">objectMapper</span> <span class="o">=</span> <span class="n">objectMapper</span><span class="o">;</span> <span class="k">this</span><span class="o">.</span><span class="na">source</span> <span class="o">=</span> <span class="n">source</span><span class="o">;</span> <span class="o">}</span> <span class="nd">@Override</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">publish</span><span class="o">(</span><span class="n">DomainEvent</span> <span class="n">domainEvent</span><span class="o">)</span> <span class="o">{</span> <span class="k">try</span> <span class="o">{</span> <span class="n">domainEventStorage</span> <span class="o">.</span><span class="na">save</span><span class="o">(</span><span class="k">new</span> <span class="n">StoredDomainEvent</span><span class="o">(</span><span class="n">objectMapper</span><span class="o">.</span><span class="na">writeValueAsString</span><span class="o">(</span><span class="n">domainEvent</span><span class="o">)));</span> <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="n">JsonProcessingException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span> <span class="k">throw</span> <span class="k">new</span> <span class="nf">RuntimeException</span><span class="o">(</span><span class="n">e</span><span class="o">);</span> <span class="o">}</span> <span class="o">}</span> <span class="nd">@Scheduled</span><span class="o">(</span><span class="n">fixedRate</span> <span class="o">=</span> <span class="mi">2000</span><span class="o">)</span> <span class="nd">@Transactional</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">publishExternally</span><span class="o">()</span> <span class="o">{</span> <span class="n">domainEventStorage</span> <span class="o">.</span><span class="na">findAllBySentOrderByTimestampDesc</span><span class="o">(</span><span class="kc">false</span><span class="o">)</span> <span class="o">.</span><span class="na">forEach</span><span class="o">(</span><span class="n">event</span> <span class="o">-&gt;</span> <span class="o">{</span> <span class="n">source</span><span class="o">.</span><span class="na">output</span><span class="o">().</span><span class="na">send</span><span class="o">(</span><span class="k">new</span> <span class="n">GenericMessage</span><span class="o">&lt;&gt;(</span><span class="n">event</span><span class="o">.</span><span class="na">getContent</span><span class="o">()));</span> <span class="n">event</span><span class="o">.</span><span class="na">sent</span><span class="o">();</span> <span class="o">});</span> <span class="o">}</span> <span class="o">}</span> </code></pre></div></div> <p style="text-align:justify;"> Notice that the method which periodically publishes new events suffers from the same problem of lack of an atomic transaction. It tries to connect to the broker and to save state. But this time it is <b>after</b> successful card creation. And it has retries. If the broker is down, we will retry. After successful communication with the broker, the database can be offline. Hence, we will not mark the event as processed. We will resend it, implementing what is called <i>at-least-once guaranty</i>. Whether you should go with at-least-once or at-most-once depends on the business problem. For marketing purposes probably at-most-once is fine. But if a message carries a significant information (like how to activate the card), then probably the clients want that message. And will not mind getting it twice. At least they will be less angry than when not receiving it at all. And if your consumer is idempotent, then there is no problem at all. </p> <p><strong><em>Store only one thing</em></strong></p> <p style="text-align:justify;"> How we can deal with cooridnation of two different components? With database and with message broker? Can we not send to one of them? Is state or message redundant? Can one of them be derived from another? If we think of messages as events or as changes that affect state, then it becomes clear that state can be derived from events. Thus, only the communication with the broker would be needed. The state can be queried from a log of changes represented by events. This is what event sourcing is about. You can read more about reliable events delivery <a href="http://pillopl.github.io/reliable-domain-events/">here</a>.</p> <p style="text-align:justify;"> The code used in this example is <a href="https://github.com/spring-cloud-samples/messaging-application">here</a>.</p> Sat, 05 May 2018 00:00:00 +0000 http://pillopl.github.io/testing-messaging/ http://pillopl.github.io/testing-messaging/ Event Storming with Spring and a Splash of DDD <p style="text-align:justify;">I wrote a post on the spring blog. It is about how to tackle complex enterprises with Event Storming, Spring and DDD. You can find it <a href="https://spring.io/blog/2018/04/11/event-storming-and-spring-with-a-splash-of-ddd">here</a> </p> Wed, 11 Apr 2018 00:00:00 +0000 http://pillopl.github.io/event-storming-ddd-spring/ http://pillopl.github.io/event-storming-ddd-spring/ On Eventual Consistency and REST <p style="text-align:justify;"> Typically in event-sourced systems (with Command Query Responsibility Segregation) that need to display data to a client, we have three components that must co-operate <ul> <li>write model that accepts commands and writes events to its event store</li> <li>read model that accepts events and returns DTOs to a client</li> <li>client (e.g. web browsers) that writes commands to write model and queries read model for DTOs</li> </ul> </p> <p style="text-align:justify;"> <img src="/images/wd.png" /> </p> <p style="text-align:justify;"> This actually leads us to a situation where we have 3 well defined boundaries with well defined contracts. That means we can easily distribute work among 3 teams. Write model team need to have deep knowledge in the domain, but do not need to touch UI and database (!). Read model team need to perform simple database updates and provide an API for front-end. Front-end in turn must do as usual - request (to write model) and queries (to read model). </p> <p style="text-align:justify;"> Events from the write model can be delivered to subscribers (here, read models) synchronously. That means that we ACK a command if and only if both write model and read model were successfully updated. If one of them fails, client must retry the request. This actually favors <i>Consistency vs. Availability</i> and tangles read model and write model to be backed by the same data source. This solution does not allow us to scale our read models independently from our write model. Another option is to use distributed transactions, which reduce performance. To cut the long story short, synchronous mode reduces flexibility, scalability and autonomy - things that ES/CQRS gave us in the first place. </p> <p style="text-align:justify;"> Having said that, we often prefer asynchronous mode and acknowledging a command as soon as events were produced and saved in the write model. This is also in-line with our natural notion of imperative tense and past tense: <ul> <li>1. "DoSomething! (command)"</li> <li>2. "OK, SomethingDone (ACK with event)" or "Nope, piss off!" (N-ACK)</li> </ul> </p> <p style="text-align:justify;"> In this mode the information that something was done (event) is delivered to our read model slightly later by the means of read model subscription. The subscription can be fulfilled by the means of a message broker or by pulling the write model by read model for new changes. The way of delivery does not really matter. What matters is that we now favor <i>Availability</i> with the cost of losing <i>Strong Consistency</i>. Our read model will be actually <i>Eventually Consistent</i> - if no further updates are done to the write model, it will return the last updated data. Otherwise, it can return data that is a little stale. </p> <p><strong><em>Is that a problem?</em></strong></p> <p style="text-align:justify;"> Let's consider a read model that is being used by a reporting team to feed their Excel sheets and send e-mails. By the time they update their excel sheet or return from a coffee to check e-mail or go to a printer to fetch the printed version, received data can be already stale. Even though a read model is strongly consistent with the write model, it does not prevent end users from <b>USING</b> this data in eventually consistent way. </p> <p style="text-align:justify;"> Imagine how companies used to work back then without computers. It took time to deliver information on a piece of paper from one desk to another. Everything was eventually consistent. Than we (developers) came and introduced strong consistency and ACID. That is why business people now think of "eventually consistent" data as "incorrect" data. Even when they use their strongly consistent data to print reports and analyze them at home few hours later. Banks worked perfectly fine without computers back then. Moreover, now bank systems are eventually consistent. Even in critical parts of the data, <a href="http://highscalability.com/blog/2013/5/1/myth-eric-brewer-on-why-banks-are-base-not-acid-availability.html">like your account balance</a>. Having said that, eventual consistency is almost always fine. All you need to do is slightly educate users of your system. </p> <p><strong><em>But…Read your own Writes</em></strong></p> <p style="text-align:justify;"> There are some guaranties you would like to ensure. Imagine situation when user issues a command "ChangeHomeAddress" and refreshes the browser. If he is unlucky, new address is not there and he feels like the system is broken. He will probably retry his request. It is HIS update, so he cares about it. He does not care if updates that are consequences of other users actions arrive 1 sec later or earlier. But he would like to see EFFECTS of HIS actions. That guaranty is called <i>"Read your own writes"</i>. </p> <p style="text-align:justify;"> How to ensure "Read your own writes" when the read model is asynchronously updated? First let's talk about how events are stored in the write model. Consider we have a ShopItem with UUID. ShopItem produces events in response to a command (e.g. Pay command and ItemPaid event). Produced events are stored in event store (write model). Each event has <i>UUID</i> of a ShopItem, <i>occurred_at</i> date and <i>sequence number</i>. Events related to ShopItem with particular UUID are grouped into so-called <i>Event Steams</i>. Event Stream is responsible for tracking events from one instance of an aggregate. An aggregate in Domain Driven Design terms is a cluster of objects that create a transactional boundary. Aggregate is stored as a series of events in events stream, that means that event stream is our transactional boundary - only one person can write to event-stream at a time (because only one person can modify an aggregate at a time). That means that we can have a <i>version counter</i> for optimistic locking for each of the streams. Each write to an event-stream bumps up version counter or raises optimistic locking exception. That means that when we have 3 events in event stream (with sequence numbers 1, 2 and 3) the version counter of corresponding event stream is 3. In other words, version counter is denormalized value from max sequence number in given event stream. </p> <p style="text-align:justify;"> Let's now go back to our three components: client, write model and read model. We previously said that in asynchronous mode, a command is accepted when events are persisted in write model. That means that when write model returns and ACK to a client, it knows what event it had just written. In particular, he <b>knows</b> what is a version counter (sequence number of last event) of domain item modified by the command. He can return this information to a client, so that client will know what version of domain item was created due to his change. Now the client can include this information when querying read model. He can specify that he <b>EXPECTS</b> to get data at a version equal or greater to the one returned with ACK. Why equal or greater? Because someone could have written a new value in between requests to write and read model. The server can then do two things. It can either return the data or fail because it has not received expected event yet. The important is that the server knows that the value will be delivered just soon. That is a powerful information, because the server can return <a href="https://tools.ietf.org/html/rfc7231#section-7.1.3"><i>Retry-After</i></a> X seconds HTTP header. Client's browser will (or should) retry the request after X seconds, so that the initial failure is transparent to the client. To cut it short: <ul> <li>Issue a command to write model</li> <li>Read current version from ACK</li> <li>Put expected version to request to read model</li> <li>Expect data or expect browser to retry soon transparently (because of Retry-After header set by read model server)</li> </ul> </p> <p style="text-align:justify;"> Let's see how read model server can implement that logic. First we have to create an endpoint for querying a particular shop item by UUID. We will use Spring Boot. </p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="nd">@RequestMapping</span><span class="o">(</span><span class="n">method</span> <span class="o">=</span> <span class="n">RequestMethod</span><span class="o">.</span><span class="na">GET</span><span class="o">,</span> <span class="n">value</span> <span class="o">=</span> <span class="s">"/{uuid}"</span><span class="o">)</span> <span class="kd">public</span> <span class="n">ResponseEntity</span><span class="o">&lt;</span><span class="n">ShopItem</span><span class="o">&gt;</span> <span class="nf">readById</span><span class="o">(</span> <span class="nd">@PathVariable</span> <span class="n">String</span> <span class="n">uuid</span><span class="o">,</span> <span class="nd">@RequestHeader</span><span class="o">(</span><span class="n">value</span><span class="o">=</span><span class="s">"Expect"</span><span class="o">)</span> <span class="n">Integer</span> <span class="n">expectedVersion</span><span class="o">)</span> <span class="o">{</span> <span class="c1">//..</span> <span class="o">}</span> </code></pre></div></div> <p style="text-align:justify;"> But how do we pass expected version in the request to the read model? One option is to put it as request parameter and query under URL <i>/uuid?expectedVersion=2</i>, when we expect version number equal of greater than 2. The other option is to use HTTP header. Which one? There actually is one called EXPECT. According to &lt;a href=https://tools.ietf.org/html/rfc7231#section-5.1.1"&gt;RFC7231&lt;/a&gt; it is used to: </p> <blockquote class="cite"> <p>The "Expect" header field in a request indicates a certain set of behaviors (expectations) that need to be supported by the server in order to properly handle this request.</p> </blockquote> <p style="text-align:justify;"> To align more with HTTP, let's put expected version under EXPECT parameter instead of request parameter. We do test first. When expected version is greater than current version we expect that server says <i>Retry-After</i> 2 seconds. </p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="n">def</span> <span class="err">'</span><span class="n">should</span> <span class="n">ask</span> <span class="n">to</span> <span class="n">retry</span> <span class="n">after</span> <span class="n">when</span> <span class="n">state</span> <span class="n">is</span> <span class="n">not</span> <span class="n">yet</span> <span class="n">present</span><span class="err">'</span><span class="o">()</span> <span class="o">{</span> <span class="nl">given:</span> <span class="n">UUID</span> <span class="n">itemUUID</span> <span class="o">=</span> <span class="n">UUID</span><span class="o">.</span><span class="na">randomUUID</span><span class="o">()</span> <span class="n">itemIsOrderedAtVersion</span><span class="o">(</span><span class="n">itemUUID</span><span class="o">,</span> <span class="n">ANY_TIME</span><span class="o">,</span> <span class="n">currentVersion</span><span class="o">)</span> <span class="nl">when:</span> <span class="n">ResultActions</span> <span class="n">result</span> <span class="o">=</span> <span class="n">mockMvc</span> <span class="o">.</span><span class="na">perform</span><span class="o">(</span><span class="n">get</span><span class="o">(</span><span class="s">"/${itemUUID}"</span><span class="o">)</span> <span class="o">.</span><span class="na">header</span><span class="o">(</span><span class="n">EXPECT</span><span class="o">,</span> <span class="n">expectedVersion</span><span class="o">))</span> <span class="nl">then:</span> <span class="n">result</span><span class="o">.</span><span class="na">andExpect</span><span class="o">(</span><span class="n">header</span><span class="o">().</span><span class="na">longValue</span><span class="o">(</span><span class="s">"Retry-After"</span><span class="o">,</span> <span class="mi">2</span><span class="o">))</span> <span class="n">result</span><span class="o">.</span><span class="na">andExpect</span><span class="o">(</span><span class="n">status</span><span class="o">().</span><span class="na">isServiceUnavailable</span><span class="o">())</span> <span class="nl">where:</span> <span class="n">currentVersion</span> <span class="o">||</span> <span class="n">expectedVersion</span> <span class="mi">1</span> <span class="o">||</span> <span class="mi">2</span> <span class="mi">2</span> <span class="o">||</span> <span class="mi">3</span> <span class="mi">4</span> <span class="o">||</span> <span class="mi">10</span> <span class="mi">100</span> <span class="o">||</span> <span class="mi">201</span> <span class="o">}</span> </code></pre></div></div> <p style="text-align:justify;"> The second scenario ensures that when expected version is smaller or equal to current version, we return the data. </p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="n">def</span> <span class="err">'</span><span class="n">should</span> <span class="k">return</span> <span class="n">the</span> <span class="n">data</span> <span class="n">when</span> <span class="n">expected</span> <span class="n">version</span> <span class="n">is</span> <span class="n">equal</span> <span class="n">or</span> <span class="n">smaller</span> <span class="n">than</span> <span class="n">current</span> <span class="n">version</span><span class="err">'</span><span class="o">()</span> <span class="o">{</span> <span class="nl">given:</span> <span class="n">UUID</span> <span class="n">itemUUID</span> <span class="o">=</span> <span class="n">UUID</span><span class="o">.</span><span class="na">randomUUID</span><span class="o">()</span> <span class="n">itemIsOrderedAtVersion</span><span class="o">(</span><span class="n">itemUUID</span><span class="o">,</span> <span class="n">ANY_TIME</span><span class="o">,</span> <span class="n">currentVersion</span><span class="o">)</span> <span class="nl">when:</span> <span class="n">ResultActions</span> <span class="n">result</span> <span class="o">=</span> <span class="n">mockMvc</span> <span class="o">.</span><span class="na">perform</span><span class="o">(</span><span class="n">get</span><span class="o">(</span><span class="s">"/${itemUUID}"</span><span class="o">)</span> <span class="o">.</span><span class="na">header</span><span class="o">(</span><span class="n">EXPECT</span><span class="o">,</span> <span class="n">expectedVersion</span><span class="o">))</span> <span class="nl">then:</span> <span class="n">result</span><span class="o">.</span><span class="na">andExpect</span><span class="o">(</span><span class="n">status</span><span class="o">().</span><span class="na">isOk</span><span class="o">())</span> <span class="nl">where:</span> <span class="n">currentVersion</span> <span class="o">||</span> <span class="n">expectedVersion</span> <span class="mi">2</span> <span class="o">||</span> <span class="mi">2</span> <span class="mi">3</span> <span class="o">||</span> <span class="mi">3</span> <span class="mi">40</span> <span class="o">||</span> <span class="mi">10</span> <span class="mi">1000</span> <span class="o">||</span> <span class="mi">201</span> <span class="o">}</span> </code></pre></div></div> <p style="text-align:justify;"> Now let's take a look at the endpoint implementation. The client can leave expected version as empty. Let's assume that when it is not defined then the data is as good as it gets - the recent one. </p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="nd">@RequestMapping</span><span class="o">(</span><span class="n">method</span> <span class="o">=</span> <span class="n">RequestMethod</span><span class="o">.</span><span class="na">GET</span><span class="o">,</span> <span class="n">value</span> <span class="o">=</span> <span class="s">"/{uuid}"</span><span class="o">)</span> <span class="kd">public</span> <span class="n">ResponseEntity</span><span class="o">&lt;</span><span class="n">ShopItem</span><span class="o">&gt;</span> <span class="nf">readById</span><span class="o">(</span> <span class="nd">@PathVariable</span> <span class="n">String</span> <span class="n">uuid</span><span class="o">,</span> <span class="nd">@RequestHeader</span><span class="o">(</span><span class="n">value</span><span class="o">=</span><span class="n">HttpHeaders</span><span class="o">.</span><span class="na">EXPECT</span><span class="o">)</span> <span class="n">Integer</span> <span class="n">expectedVersion</span><span class="o">)</span> <span class="o">{</span> <span class="kd">final</span> <span class="n">ShopItem</span> <span class="n">item</span> <span class="o">=</span> <span class="n">jdbcReadModel</span><span class="o">.</span><span class="na">getItemBy</span><span class="o">(</span><span class="n">UUID</span><span class="o">.</span><span class="na">fromString</span><span class="o">(</span><span class="n">uuid</span><span class="o">));</span> <span class="k">if</span> <span class="o">(</span><span class="n">dataAtExpectedState</span><span class="o">(</span><span class="n">item</span><span class="o">,</span> <span class="n">expectedVersion</span><span class="o">))</span> <span class="o">{</span> <span class="k">return</span> <span class="n">ResponseEntity</span><span class="o">.</span><span class="na">ok</span><span class="o">(</span><span class="n">item</span><span class="o">);</span> <span class="o">}</span> <span class="k">return</span> <span class="nf">retrySoon</span><span class="o">();</span> <span class="o">}</span> <span class="kd">private</span> <span class="kt">boolean</span> <span class="nf">dataAtExpectedState</span><span class="o">(</span><span class="n">ShopItem</span> <span class="n">item</span><span class="o">,</span> <span class="n">Integer</span> <span class="n">expectedVersion</span><span class="o">)</span> <span class="o">{</span> <span class="k">return</span> <span class="n">expectedVersion</span> <span class="o">==</span> <span class="kc">null</span> <span class="o">||</span> <span class="n">expectedVersion</span> <span class="o">&lt;=</span> <span class="n">item</span><span class="o">.</span><span class="na">getVersion_value</span><span class="o">();</span> <span class="o">}</span> <span class="kd">private</span> <span class="n">ResponseEntity</span><span class="o">&lt;</span><span class="n">ShopItem</span><span class="o">&gt;</span> <span class="nf">retrySoon</span><span class="o">()</span> <span class="o">{</span> <span class="kd">final</span> <span class="n">HttpHeaders</span> <span class="n">headers</span> <span class="o">=</span> <span class="k">new</span> <span class="n">HttpHeaders</span><span class="o">();</span> <span class="n">headers</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="n">HttpHeaders</span><span class="o">.</span><span class="na">RETRY_AFTER</span><span class="o">,</span> <span class="n">Integer</span><span class="o">.</span><span class="na">toString</span><span class="o">(</span><span class="mi">2</span><span class="o">));</span> <span class="k">return</span> <span class="k">new</span> <span class="n">ResponseEntity</span><span class="o">&lt;&gt;(</span><span class="n">headers</span><span class="o">,</span> <span class="n">HttpStatus</span><span class="o">.</span><span class="na">SERVICE_UNAVAILABLE</span><span class="o">);</span> <span class="o">}</span> </code></pre></div></div> <p style="text-align:justify;"> The last scenario ensures that after retrying client gets expected data. Of course, if read model was updated in between two requests. </p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="n">def</span> <span class="err">'</span><span class="n">should</span> <span class="k">return</span> <span class="n">the</span> <span class="n">data</span> <span class="n">after</span> <span class="n">retrying</span><span class="err">'</span><span class="o">()</span> <span class="o">{</span> <span class="nl">given:</span> <span class="n">UUID</span> <span class="n">itemUUID</span> <span class="o">=</span> <span class="n">UUID</span><span class="o">.</span><span class="na">randomUUID</span><span class="o">()</span> <span class="n">itemIsOrderedAtVersion</span><span class="o">(</span><span class="n">itemUUID</span><span class="o">,</span> <span class="n">ANY_TIME</span><span class="o">,</span> <span class="mi">1</span><span class="o">)</span> <span class="nl">when:</span> <span class="n">ResultActions</span> <span class="n">result</span> <span class="o">=</span> <span class="n">mockMvc</span> <span class="o">.</span><span class="na">perform</span><span class="o">(</span><span class="n">get</span><span class="o">(</span><span class="s">"/${itemUUID}"</span><span class="o">)</span> <span class="o">.</span><span class="na">header</span><span class="o">(</span><span class="s">"Expect"</span><span class="o">,</span> <span class="mi">2</span><span class="o">))</span> <span class="nl">then:</span> <span class="n">result</span><span class="o">.</span><span class="na">andExpect</span><span class="o">(</span><span class="n">header</span><span class="o">().</span><span class="na">longValue</span><span class="o">(</span><span class="s">"Retry-After"</span><span class="o">,</span> <span class="mi">2</span><span class="o">))</span> <span class="n">result</span><span class="o">.</span><span class="na">andExpect</span><span class="o">(</span><span class="n">status</span><span class="o">().</span><span class="na">isServiceUnavailable</span><span class="o">())</span> <span class="nl">when:</span> <span class="n">itemIsPaidAtVersion</span><span class="o">(</span><span class="n">itemUUID</span><span class="o">,</span> <span class="n">ANY_TIME</span><span class="o">,</span> <span class="mi">2</span><span class="o">)</span> <span class="nl">and:</span> <span class="n">ResultActions</span> <span class="n">secondResult</span> <span class="o">=</span> <span class="n">mockMvc</span> <span class="o">.</span><span class="na">perform</span><span class="o">(</span><span class="n">get</span><span class="o">(</span><span class="s">"/${itemUUID}"</span><span class="o">)</span> <span class="o">.</span><span class="na">header</span><span class="o">(</span><span class="s">"Expect"</span><span class="o">,</span> <span class="mi">2</span><span class="o">))</span> <span class="nl">then:</span> <span class="n">secondResult</span><span class="o">.</span><span class="na">andExpect</span><span class="o">(</span><span class="n">status</span><span class="o">().</span><span class="na">isOk</span><span class="o">())</span> <span class="o">}</span> </code></pre></div></div> <p style="text-align:justify;"> This was an example of using Http Headers (Expect and Retry-After) to implement transparent retries and ensure "read your own writes" in eventually consistent system. </p> <p style="text-align:justify;"> The other option is to inform the user that we are only able to return data from a concrete point of time (our last known update). The read model can keep track of when a concrete event stream was recently updated. On the screen, next to our data there can be a time-stamp which says how stale it is. This is actually pretty easy to introduce by the means of &lt;a href="https://tools.ietf.org/html/rfc7232#section-2.2"<i>Last-Modified</i>&lt;/a&gt; HTTP Header. Take a look at the test: </p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="n">def</span> <span class="err">'</span><span class="n">should</span> <span class="k">return</span> <span class="n">last</span> <span class="n">modified</span> <span class="n">date</span> <span class="n">in</span> <span class="n">response</span><span class="err">'</span><span class="o">()</span> <span class="o">{</span> <span class="nl">given:</span> <span class="n">UUID</span> <span class="n">itemUUID</span> <span class="o">=</span> <span class="n">UUID</span><span class="o">.</span><span class="na">randomUUID</span><span class="o">()</span> <span class="n">itemIsOrderedAtVersion</span><span class="o">(</span><span class="n">itemUUID</span><span class="o">,</span> <span class="n">ANY_TIME</span><span class="o">,</span> <span class="mi">1</span><span class="o">)</span> <span class="nl">when:</span> <span class="n">ResultActions</span> <span class="n">result</span> <span class="o">=</span> <span class="n">mockMvc</span> <span class="o">.</span><span class="na">perform</span><span class="o">(</span><span class="n">get</span><span class="o">(</span><span class="s">"/${itemUUID}"</span><span class="o">)</span> <span class="o">.</span><span class="na">header</span><span class="o">(</span><span class="s">"Expect"</span><span class="o">,</span> <span class="mi">1</span><span class="o">))</span> <span class="nl">then:</span> <span class="n">result</span><span class="o">.</span><span class="na">andExpect</span><span class="o">(</span> <span class="n">header</span><span class="o">()</span> <span class="o">.</span><span class="na">string</span><span class="o">(</span> <span class="n">LAST_MODIFIED</span><span class="o">,</span> <span class="n">HTTP_DATE_FORMAT</span><span class="o">.</span><span class="na">format</span><span class="o">(</span><span class="n">from</span><span class="o">(</span><span class="n">ANY_TIME</span><span class="o">))))</span> <span class="n">result</span><span class="o">.</span><span class="na">andExpect</span><span class="o">(</span><span class="n">status</span><span class="o">().</span><span class="na">isOk</span><span class="o">())</span> <span class="o">}</span> </code></pre></div></div> <p style="text-align:justify;"> And we had to modify previous implementation, so that it returns new header: </p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="nd">@RequestMapping</span><span class="o">(</span><span class="n">method</span> <span class="o">=</span> <span class="n">RequestMethod</span><span class="o">.</span><span class="na">GET</span><span class="o">,</span> <span class="n">value</span> <span class="o">=</span> <span class="s">"/{uuid}"</span><span class="o">)</span> <span class="kd">public</span> <span class="n">ResponseEntity</span><span class="o">&lt;</span><span class="n">ShopItem</span><span class="o">&gt;</span> <span class="nf">readById</span><span class="o">(</span> <span class="nd">@PathVariable</span> <span class="n">String</span> <span class="n">uuid</span><span class="o">,</span> <span class="nd">@RequestHeader</span><span class="o">(</span><span class="n">value</span><span class="o">=</span> <span class="n">EXPECT</span><span class="o">)</span> <span class="n">Integer</span> <span class="n">expectedVersion</span><span class="o">)</span> <span class="o">{</span> <span class="kd">final</span> <span class="n">ShopItem</span> <span class="n">item</span> <span class="o">=</span> <span class="n">jdbcReadModel</span><span class="o">.</span><span class="na">getItemBy</span><span class="o">(</span><span class="n">UUID</span><span class="o">.</span><span class="na">fromString</span><span class="o">(</span><span class="n">uuid</span><span class="o">));</span> <span class="k">if</span> <span class="o">(</span><span class="n">dataAtExpectedState</span><span class="o">(</span><span class="n">item</span><span class="o">,</span> <span class="n">expectedVersion</span><span class="o">))</span> <span class="o">{</span> <span class="k">return</span> <span class="nf">okWithLastModifiedDate</span><span class="o">(</span><span class="n">item</span><span class="o">);</span> <span class="o">}</span> <span class="k">return</span> <span class="nf">retrySoon</span><span class="o">();</span> <span class="o">}</span> <span class="kd">private</span> <span class="n">ResponseEntity</span><span class="o">&lt;</span><span class="n">ShopItem</span><span class="o">&gt;</span> <span class="nf">okWithLastModifiedDate</span><span class="o">(</span><span class="n">ShopItem</span> <span class="n">item</span><span class="o">)</span> <span class="o">{</span> <span class="kd">final</span> <span class="n">HttpHeaders</span> <span class="n">headers</span> <span class="o">=</span> <span class="k">new</span> <span class="n">HttpHeaders</span><span class="o">();</span> <span class="n">headers</span><span class="o">.</span><span class="na">set</span><span class="o">(</span> <span class="n">HttpHeaders</span><span class="o">.</span><span class="na">LAST_MODIFIED</span><span class="o">,</span> <span class="n">HTTP_DATE_FORMAT</span><span class="o">.</span><span class="na">format</span><span class="o">(</span><span class="n">item</span><span class="o">.</span><span class="na">getLastModifiedDate</span><span class="o">()));</span> <span class="k">return</span> <span class="k">new</span> <span class="n">ResponseEntity</span><span class="o">&lt;&gt;(</span><span class="n">item</span><span class="o">,</span> <span class="n">headers</span><span class="o">,</span> <span class="n">HttpStatus</span><span class="o">.</span><span class="na">OK</span><span class="o">);</span> <span class="o">}</span> </code></pre></div></div> <p style="text-align:justify;"> With this behavior, we can notify our client that the data he is seeing might be a little stale, so he might refresh the browser. Be careful here. A common mistake in a read model is to save last updated date as a process date (arrival date). Our real model can be down for 2 days and when it gets up again it will process events that happened 2 days ago. That would in turns display wrong information to a client - the date is actually 2 days older. We always have to take into account the date of the creation of an event, which is passed to the read model. </p> <p style="text-align:justify;"> The last option is tricking the user directly in the client UI. As soon as we got the ACK, we know the data will be eventually in the read model. So we might directly modify our temporal view in web browser and hope that user will not refresh the page until expected version arrived in read model. This is rather rare way of dealing with eventual consistency. </p> <p><strong><em>Couple of notes</em></strong></p> <p style="text-align:justify;"> How we return current version in ACK from write model? Most often custom return type is introduced - it contains status code and the current version. Another way is to use the <i>E-tag</i> HTTP header, which &lt;a href=https://tools.ietf.org/html/rfc7232#section-2.3.1&gt; according to specification&lt;/a&gt; can be used for: </p> <blockquote class="cite"> "The "E-Tag" header field in a response provides the current entity-tag for the selected representation, as determined at the conclusion of handling the request. An entity-tag is an opaque validator for differentiating between multiple representations of the same resource, regardless of whether those multiple representations are due to resource state changes over time, content negotiation resulting in multiple representations being valid at the same time, or both." </blockquote> <p style="text-align:justify;"> As it is described, the value should be opaque, so we should encrypt our version parameter. We don't want to reveal how big our event-stream is and how it is build due to the security reasons. The same should be actually done when we query read model and specify expected version. </p> <p style="text-align:justify;"> RFC also says that we can specify concrete time in Retry-After header. We should avoid that, because this can result in very high traffic at this specific time. Imagine we inform many of our clients to retry at a specific time. Although the clocks of the clients are not synchronized, the traffic around <i>that time</i> can be significant. </p> <p style="text-align:justify;"> Sadly although both <a href="http://stackoverflow.com/questions/3764075/retry-after-http-response-header-does-it-affect-anything">Mozilla and Chrome</a> ensure supporting Retry-After header, it does not work in the newest versions. The browsers do not care that much, because the servers rarely send that header. It creates an endless circle. But remember, the client is not always a browser. So it is good to have Retry-After header. </p> <p style="text-align:justify;"> Code can be found <a href="https://github.com/pilloPl/shop-ui">here</a> </p> Mon, 16 Jan 2017 00:00:00 +0000 http://pillopl.github.io/eventual-consistency-and-rest/ http://pillopl.github.io/eventual-consistency-and-rest/ My talk about Spring Stream, Event Sourcing and CQRS at spring.io <p style="text-align:justify;"> Last month I did a few talks about leveraging Spring Cloud Stream to create fault tolerant and loosely coupled services that use Event Sourcing and Command Query Responsibility Segregation. Unfortuneatly, none of those was recorded due to technical reasons. But, I also had a great pleasure to had a Google Hangout about those subjects with guys from the Spring team. They liked it up to the point to putting the video online, <a href="https://spring.io/blog/2016/11/08/cqrs-and-event-sourcing-with-jakub-pilimon">at their blog page</a>. So if you are interested and have fifty minutes, please leave a comment. </p> <p style="text-align:justify;"> In the next month (hopefully), I will be creating a series of blog posts about techniques I've mentioned in that video. We will also see an example of Process Manager implemented as Akka actor. Stay tuned! </p> <p style="text-align:justify;"> <iframe width="560" height="315" src="https://www.youtube.com/embed/rhn-T9b_Mvs" frameborder="0" allowfullscreen=""></iframe> </p> Sat, 12 Nov 2016 00:00:00 +0000 http://pillopl.github.io/Spring-Stream-with-CQRS-and-ES/ http://pillopl.github.io/Spring-Stream-with-CQRS-and-ES/ Event sourcing with CQRS sample revisited <p style="text-align:justify;"> <a href="http://pillopl.github.io/event-sourcing-with-cqrs">Previously</a> I posted a short note about my sample event sourced application that follows Command Query Responsibility Segregation principle. Today I would like to go a little bit further and describe its particular components and their responsibilities. </p> <p><strong><em>Overall structure</em></strong></p> <p style="text-align:justify;"> There are 4 sub packages: <ul> <li><b>domain</b> - which is the core of the business. In so called onion architecture it stays in the middle, it does not depend on any other package. It does not even depend on spring, since no container is needed there. Hence, there are only unit tests provided. It exposes one interface to get ShopItem, this interface is called <a href="https://github.com/pilloPl/event-source-cqrs-sample/blob/master/src/main/java/io/pillopl/eventsource/domain/shopitem/ShopItemRepository.java">ShopItemRepository</a>. Its presence let the application to inverse the dependencies - every implementation of ShopItemRepository points towards domain</li> <li><b>boundary</b> - entry point to the application. It contains only one service, called <a href="https://github.com/pilloPl/event-source-cqrs-sample/blob/master/src/main/java/io/pillopl/eventsource/boundary/ShopItems.java">ShopItems. It receives <a href="https://github.com/pilloPl/event-source-cqrs-sample/tree/master/src/main/java/io/pillopl/eventsource/domain/shopitem/commands">commands exposed by domain</a> and invokes them on proper ShopItem instance.</a>. This service could be represented as a REST controller (although it does not handle REST, but a few more annotations could change that)</li> <li><b>eventstore</b> - it exposes one public class - <a href="https://github.com/pilloPl/event-source-cqrs-sample/blob/master/src/main/java/io/pillopl/eventsource/eventstore/EventSourcedShopItemRepository.java">EventSourcedShopItemRepository</a>, which implements ShopItemRepository exposed by domain. Hence, it can be treated as plug-in shipped with application. Currently, it uses relational database to store events, but probably document database would be more suitable choice, since events <a href="https://github.com/pilloPl/event-source-cqrs-sample/blob/master/src/main/java/io/pillopl/eventsource/eventstore/EventSerializer.java">are serialized to JSON by EventSerializer</a>. Every single stored event is also published to any other interested party with the help of <a href="http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/ApplicationEventPublisher.html">ApplicationEventPublisher</a></li> <li><b>readmodel</b> - listens to events published by mentioned ApplicationEventPublisher and mutates denormalized shop item model represented by <a href="https://github.com/pilloPl/event-source-cqrs-sample/blob/master/src/main/java/io/pillopl/eventsource/readmodel/ShopItemDto.java">ShopItemDto.</a></li> </ul> </p> <p><strong><em>Package: domain</em></strong></p> <p style="text-align:justify;"> Application simulates a shop with various items. Since shopping domain is much more complicated, it probably would not be modeled like this in a real software. Anyway, a shop item can be in 4 states: INITIALIZED, BOUGHT, PAID, PAYMENT_MISSING. Changing a state means emitting an event. Let's take a look at state diagram. <img src="/images/states.png" /> </p> <p style="text-align:justify;"> The most important mind shift is how the shop item aggregate is modeled. <a href="https://github.com/pilloPl/event-source-cqrs-sample/blob/master/src/main/java/io/pillopl/eventsource/domain/shopitem/ShopItem.java">It is not a traditional entity, but a simple POJO</a>. Hence, no external dependencies are needed. Note that ShopItem is immutable, which favors functional programming and gives a lot of benefits. Every business method returns new instance of ShopItem. </p> <p style="text-align:justify;"> Secondly, it is worth seeing how easy it is to test such an aggregate. We only care about what is being emitted as event, we don't care about internal state representations. Thus, test for paying for shop item looks as follows: </p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="n">def</span> <span class="err">'</span><span class="n">should</span> <span class="n">emit</span> <span class="n">item</span> <span class="n">paid</span> <span class="n">event</span> <span class="n">when</span> <span class="n">paying</span> <span class="k">for</span> <span class="n">bought</span> <span class="n">item</span><span class="err">'</span><span class="o">()</span> <span class="o">{</span> <span class="nl">when:</span> <span class="n">ShopItem</span> <span class="n">tx</span> <span class="o">=</span> <span class="n">bought</span><span class="o">(</span><span class="n">uuid</span><span class="o">).</span><span class="na">pay</span><span class="o">(</span><span class="n">now</span><span class="o">())</span> <span class="nl">then:</span> <span class="n">tx</span><span class="o">.</span><span class="na">getUncommittedChanges</span><span class="o">().</span><span class="na">size</span><span class="o">()</span> <span class="o">==</span> <span class="mi">1</span> <span class="n">tx</span><span class="o">.</span><span class="na">getUncommittedChanges</span><span class="o">().</span><span class="na">head</span><span class="o">().</span><span class="na">type</span><span class="o">()</span> <span class="o">==</span> <span class="n">ItemPaid</span><span class="o">.</span><span class="na">TYPE</span> <span class="o">}</span> </code></pre></div></div> <p style="text-align:justify;"> <b>&lt;/i&gt;getUncommitedChanges()</b>&lt;/i&gt; returns events created during business method invocation. We also should take care of illegal state transitions, for example marking payment as missing when when someone already has paid should be impossible: </p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">def</span> <span class="err">'</span><span class="n">cannot</span> <span class="n">mark</span> <span class="n">payment</span> <span class="n">missing</span> <span class="n">when</span> <span class="n">item</span> <span class="n">already</span> <span class="n">paid</span><span class="err">'</span><span class="o">()</span> <span class="o">{</span> <span class="nl">when:</span> <span class="n">paid</span><span class="o">(</span><span class="n">uuid</span><span class="o">).</span><span class="na">markTimeout</span><span class="o">(</span><span class="n">now</span><span class="o">())</span> <span class="nl">then:</span> <span class="n">thrown</span><span class="o">(</span><span class="n">IllegalStateException</span><span class="o">)</span> <span class="o">}</span> </code></pre></div></div> <p style="text-align:justify;"> Last, but not least - we want those operations to be idempotent. Idempotency in this context means not emitting the same event twice. </p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="n">def</span> <span class="err">'</span><span class="n">marking</span> <span class="n">payment</span> <span class="n">timeout</span> <span class="n">should</span> <span class="n">be</span> <span class="n">idempotent</span><span class="err">'</span><span class="o">()</span> <span class="o">{</span> <span class="nl">when:</span> <span class="n">ShopItem</span> <span class="n">tx</span> <span class="o">=</span> <span class="n">withTimeout</span><span class="o">(</span><span class="n">uuid</span><span class="o">).</span><span class="na">markTimeout</span><span class="o">(</span><span class="n">now</span><span class="o">())</span> <span class="nl">then:</span> <span class="n">tx</span><span class="o">.</span><span class="na">getUncommittedChanges</span><span class="o">().</span><span class="na">isEmpty</span><span class="o">()</span> <span class="o">}</span> </code></pre></div></div> <p><strong><em>Package: eventstore</em></strong></p> <p style="text-align:justify;"> Mentioned above&lt;/i&gt;getUncommitedChanges()&lt;/i&gt;method is crucial point for implementing storage with events. Every time we try to save a new change, we call "save" in EventSourceShopItemRepository, which looks as follows: </p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">public</span> <span class="n">ShopItem</span> <span class="nf">save</span><span class="o">(</span><span class="n">ShopItem</span> <span class="n">aggregate</span><span class="o">)</span> <span class="o">{</span> <span class="kd">final</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">DomainEvent</span><span class="o">&gt;</span> <span class="n">pendingEvents</span> <span class="o">=</span> <span class="n">aggregate</span><span class="o">.</span><span class="na">getUncommittedChanges</span><span class="o">();</span> <span class="n">eventStore</span><span class="o">.</span><span class="na">saveEvents</span><span class="o">(</span> <span class="n">aggregate</span><span class="o">.</span><span class="na">getUuid</span><span class="o">(),</span> <span class="n">pendingEvents</span> <span class="o">.</span><span class="na">stream</span><span class="o">()</span> <span class="o">.</span><span class="na">map</span><span class="o">(</span><span class="nl">eventSerializer:</span><span class="o">:</span><span class="n">serialize</span><span class="o">)</span> <span class="o">.</span><span class="na">collect</span><span class="o">(</span><span class="n">toList</span><span class="o">()));</span> <span class="k">return</span> <span class="n">aggregate</span><span class="o">.</span><span class="na">markChangesAsCommitted</span><span class="o">();</span> <span class="o">}</span> </code></pre></div></div> <p style="text-align:justify;"> So basically we get all changes emitted by an aggregate, serialize them to JSON, store in database and flush pending events in aggregate. Let's look how event store handles saving an event. </p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">interface</span> <span class="nc">EventStore</span> <span class="kd">extends</span> <span class="n">JpaRepository</span><span class="o">&lt;</span><span class="n">EventStream</span><span class="o">,</span> <span class="n">Long</span><span class="o">&gt;</span> <span class="o">{</span> <span class="n">Optional</span><span class="o">&lt;</span><span class="n">EventStream</span><span class="o">&gt;</span> <span class="nf">findByAggregateUUID</span><span class="o">(</span><span class="n">UUID</span> <span class="n">uuid</span><span class="o">);</span> <span class="k">default</span> <span class="kt">void</span> <span class="nf">saveEvents</span><span class="o">(</span><span class="n">UUID</span> <span class="n">aggregateId</span><span class="o">,</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">EventDescriptor</span><span class="o">&gt;</span> <span class="n">events</span><span class="o">)</span> <span class="o">{</span> <span class="kd">final</span> <span class="n">EventStream</span> <span class="n">eventStream</span> <span class="o">=</span> <span class="n">findByAggregateUUID</span><span class="o">(</span><span class="n">aggregateId</span><span class="o">)</span> <span class="o">.</span><span class="na">orElseGet</span><span class="o">(()</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="n">EventStream</span><span class="o">(</span><span class="n">aggregateId</span><span class="o">));</span> <span class="n">eventStream</span><span class="o">.</span><span class="na">addEvents</span><span class="o">(</span><span class="n">events</span><span class="o">);</span> <span class="n">save</span><span class="o">(</span><span class="n">eventStream</span><span class="o">);</span> <span class="o">}</span> <span class="k">default</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">EventDescriptor</span><span class="o">&gt;</span> <span class="nf">getEventsForAggregate</span><span class="o">(</span><span class="n">UUID</span> <span class="n">aggregateId</span><span class="o">)</span> <span class="o">{</span> <span class="k">return</span> <span class="nf">findByAggregateUUID</span><span class="o">(</span><span class="n">aggregateId</span><span class="o">)</span> <span class="o">.</span><span class="na">map</span><span class="o">(</span><span class="nl">EventStream:</span><span class="o">:</span><span class="n">getEvents</span><span class="o">)</span> <span class="o">.</span><span class="na">orElse</span><span class="o">(</span><span class="n">emptyList</span><span class="o">());</span> <span class="o">}</span> <span class="o">}</span> </code></pre></div></div> <p style="text-align:justify;"> It just looks for <a href="https://github.com/pilloPl/event-source-cqrs-sample/blob/master/src/main/java/io/pillopl/eventsource/eventstore/EventStream.java">EventStream</a> connected with this aggregate UUID and adds new serialized events in a form of <a href="https://github.com/pilloPl/event-source-cqrs-sample/blob/master/src/main/java/io/pillopl/eventsource/eventstore/EventDescriptor.java">EventDescriptor</a> with event serialized to JSON. If there is no stream yet (means we try to store the brand new item, new stream is created). Everything is implemented with help of spring data jpa repository. Concurrent changes done in EventStream (adding new EventDescriptors to it) can be done with optimistic locking. </p> <p style="text-align:justify;"> Having EventStore implemented helped us to create <a href="https://github.com/pilloPl/event-source-cqrs-sample/blob/master/src/main/java/io/pillopl/eventsource/eventstore/EventSourcedShopItemRepository.java">EventSourcedShopItemRepository</a>. It delegates to event store and looks for events connected with given aggregate. Next, it applies them sequentially, creating an aggregate instance. <b>State can be reconstructed to represent aggregate from any given time. This is visible in the following test case.</b> </p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="n">def</span> <span class="err">'</span><span class="n">should</span> <span class="n">reconstruct</span> <span class="n">item</span> <span class="n">at</span> <span class="n">given</span> <span class="n">moment</span><span class="err">'</span><span class="o">()</span> <span class="o">{</span> <span class="nl">given:</span> <span class="n">ShopItem</span> <span class="n">stored</span> <span class="o">=</span> <span class="n">initialized</span><span class="o">()</span> <span class="o">.</span><span class="na">buy</span><span class="o">(</span><span class="n">uuid</span><span class="o">,</span> <span class="n">TOMORROW</span><span class="o">,</span> <span class="n">PAYMENT_DEADLINE_IN_HOURS</span><span class="o">)</span> <span class="o">.</span><span class="na">pay</span><span class="o">(</span><span class="n">DAY_AFTER_TOMORROW</span><span class="o">)</span> <span class="nl">when:</span> <span class="n">shopItemRepository</span><span class="o">.</span><span class="na">save</span><span class="o">(</span><span class="n">stored</span><span class="o">)</span> <span class="nl">and:</span> <span class="n">ShopItem</span> <span class="n">bought</span> <span class="o">=</span> <span class="n">shopItemRepository</span><span class="o">.</span><span class="na">getByUUIDat</span><span class="o">(</span><span class="n">uuid</span><span class="o">,</span> <span class="n">TOMORROW</span><span class="o">)</span> <span class="n">ShopItem</span> <span class="n">paid</span> <span class="o">=</span> <span class="n">shopItemRepository</span><span class="o">.</span><span class="na">getByUUIDat</span><span class="o">(</span><span class="n">uuid</span><span class="o">,</span> <span class="n">DAY_AFTER_TOMORROW</span><span class="o">)</span> <span class="nl">then:</span> <span class="n">bought</span><span class="o">.</span><span class="na">state</span> <span class="o">==</span> <span class="n">BOUGHT</span> <span class="n">paid</span><span class="o">.</span><span class="na">state</span> <span class="o">==</span> <span class="n">PAID</span> <span class="o">}</span> </code></pre></div></div> <p><strong><em>Package: readmodel</em></strong></p> <p style="text-align:justify;"> <a href="https://github.com/pilloPl/event-source-cqrs-sample/blob/master/src/main/java/io/pillopl/eventsource/readmodel/ReadModelOnDomainEventUpdater.java">Take a look how read model is updated.</a> Basically it uses jdbc and direct sql calls to update denormalized database schema. No fany ORM needed here. Read model update is triggered with help of <a href="http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/transaction/event/TransactionalEventListener.html">TransactionalEventListener</a>. </p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="c1">//...</span> <span class="nd">@TransactionalEventListener</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">handle</span><span class="o">(</span><span class="n">DomainEvent</span> <span class="n">event</span><span class="o">)</span> <span class="o">{</span> <span class="k">if</span> <span class="o">(</span><span class="n">event</span> <span class="k">instanceof</span> <span class="n">ItemBought</span><span class="o">)</span> <span class="o">{</span> <span class="kd">final</span> <span class="n">ItemBought</span> <span class="n">itemBought</span> <span class="o">=</span> <span class="o">(</span><span class="n">ItemBought</span><span class="o">)</span> <span class="n">event</span><span class="o">;</span> <span class="n">jdbcReadModelUpdater</span><span class="o">.</span><span class="na">updateOrCreateItemAsBlocked</span><span class="o">(</span><span class="n">event</span><span class="o">.</span><span class="na">uuid</span><span class="o">(),</span> <span class="n">event</span><span class="o">.</span><span class="na">when</span><span class="o">(),</span> <span class="n">itemBought</span><span class="o">.</span><span class="na">getPaymentTimeoutDate</span><span class="o">());</span> <span class="o">}</span> <span class="k">else</span> <span class="k">if</span> <span class="o">(</span><span class="n">event</span> <span class="k">instanceof</span> <span class="n">ItemPaid</span><span class="o">)</span> <span class="o">{</span> <span class="n">jdbcReadModelUpdater</span><span class="o">.</span><span class="na">updateItemAsPaid</span><span class="o">(</span><span class="n">event</span><span class="o">.</span><span class="na">uuid</span><span class="o">(),</span> <span class="n">event</span><span class="o">.</span><span class="na">when</span><span class="o">());</span> <span class="o">}</span> <span class="k">else</span> <span class="k">if</span> <span class="o">(</span><span class="n">event</span> <span class="k">instanceof</span> <span class="n">ItemPaymentTimeout</span><span class="o">)</span> <span class="o">{</span> <span class="n">jdbcReadModelUpdater</span><span class="o">.</span><span class="na">updateItemAsPaymentMissing</span><span class="o">(</span><span class="n">event</span><span class="o">.</span><span class="na">uuid</span><span class="o">(),</span> <span class="n">event</span><span class="o">.</span><span class="na">when</span><span class="o">());</span> <span class="o">}</span> <span class="k">else</span> <span class="o">{</span> <span class="k">throw</span> <span class="k">new</span> <span class="nf">IllegalArgumentException</span><span class="o">(</span><span class="s">"Cannot handle event "</span> <span class="o">+</span> <span class="n">event</span><span class="o">.</span><span class="na">getClass</span><span class="o">());</span> <span class="o">}</span> <span class="o">}</span> </code></pre></div></div> <p style="text-align:justify;"> Note that we update read model in the same transaction, hence usage of TransactionalEventListener. Thus, the read model is consistent with write model, because they share the same data source. Normally we want our write model to be decoupled from read model, preferably in different data source. Read model would be eventually consistent and would read all the events stored by write model in event store. There is one more interesting thing in readmodel package. Since it knows about all the data and has it in denormalized form, it is able to perform actions. Here, <a href="https://github.com/pilloPl/event-source-cqrs-sample/blob/master/src/main/java/io/pillopl/eventsource/readmodel/PaymentTimeoutChecker.java">PaymentTimeoutChecker</a> periodically checks whether payment is missing. If that happens, it <b>throws a command to write model</b>. That causes aggregate state change. </p> <p><strong><em>Conclusion</em></strong></p> <p style="text-align:justify;"> With usage of CQRS we have simple and performant read model, that we can query without complex joins. Our read model is decoupled from write model and does not pollute domain model. That means that it is just a projection of domain events and has no impact of how domain is implemented. Having all the events stored in event store gives us huge debugging possibilities. We can reconstruct aggregate state from any given moment. Storing only events results in having simple shema for write model (only 2 tables here), throwing away all the work that db admins need to do when storing complex domain in relational database. </p> Sun, 14 Aug 2016 00:00:00 +0000 http://pillopl.github.io/ES-and-CQRS-sample-revisited/ http://pillopl.github.io/ES-and-CQRS-sample-revisited/ Sample event sourced application <p style="text-align:justify;"> <a href="http://pillopl.github.io/reliable-domain-events/">In my last post</a> I wrote about domain events publishing. Events were published at the end of aggregate public methods as a natural consequence of internal state modification. Let's look again at this code sample: </p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">class</span> <span class="nc">User</span> <span class="o">{</span> <span class="c1">//...</span> <span class="nd">@Transactional</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">register</span><span class="o">(</span><span class="n">LocalDateTime</span> <span class="n">at</span><span class="o">,</span> <span class="n">RegisteredBy</span> <span class="n">by</span><span class="o">)</span> <span class="o">{</span> <span class="n">markRegistered</span><span class="o">();</span> <span class="n">markSuspiciousIfAtNight</span><span class="o">(</span><span class="n">at</span><span class="o">);</span> <span class="n">DomainEventsPublisher</span><span class="o">.</span><span class="na">publish</span><span class="o">(</span><span class="k">new</span> <span class="n">UserRegistered</span><span class="o">(</span><span class="k">this</span><span class="o">.</span><span class="na">id</span><span class="o">(),</span> <span class="n">at</span><span class="o">));</span> <span class="o">}</span> <span class="o">}</span> </code></pre></div></div> <p style="text-align:justify;"> The problem that we might face is different source of truth between created <i>UserRegistered</i> and internal changes done by <i>markRegistered</i> and <i>markSuspiciousIfAtNight(at)</i> method invocations. The path to mistake is fairly simple, we could throw this domain event with <i>Instant.now()</i> instead of <i>at</i> parameter. Thus, misleading listeners of domain events, because internal state was modified differently. </p> <p style="text-align:justify;"> If we were storing our aggregate state with the help of <a href="http://martinfowler.com/eaaDev/EventSourcing.html">event sourcing</a>, so by serializing domain events, this mistake cannot be done. I've created <a href="https://github.com/pilloPl/event-source-cqrs-sample">a sample application that might show how to deal with such an approach</a>. Those serialized events can be published to external listeners. The same events from which we rebuild our domain object&lt;/a&gt; <p style="text-align:justify;"> Take a look <a href="https://github.com/pilloPl/event-source-cqrs-sample/blob/master/src/test/groovy/io/pillopl/eventsource/domain/ShopItemSpec.groovy">how ease it is to test such an aggregate</a>. By invocking public method, we expect that proper domain events were raised. Simple as that. It is also tested in <a href="https://github.com/pilloPl/event-source-cqrs-sample/blob/master/src/test/groovy/io/pillopl/eventsource/integration/boundary/ShopItemsIntegrationSpec.groovy">integration test</a>, together with storage. Please note, that with this approach it is simple to create <a href="https://github.com/pilloPl/event-source-cqrs-sample/blob/master/src/main/java/io/pillopl/eventsource/domain/shopitem/ShopItem.java">Shop Item as truly immutable aggregate</a> and favour functional programming. </p> ***Event Store*** <p style="text-align:justify;"> Event store was implemented very simply - as database table <a href="https://github.com/pilloPl/event-source-cqrs-sample/blob/master/src/main/java/io/pillopl/eventsource/eventstore/EventStream.java">EventStream</a> that represents all events comming from one aggregate instance, which holds collection of all events (<a href="https://github.com/pilloPl/event-source-cqrs-sample/blob/master/src/main/java/io/pillopl/eventsource/eventstore/EventDescriptor.java">EventDescriptors</a>). </p> ***CQRS*** <p style="text-align:justify;"> Read model in CQRS applcations is build when changes to write model are performed. That is why event sourcing can naturally lead to CQRS usage - is there any better way for listening for write model changes than subscribing to events raised from write model? The same events, from which write model is built? Take a look <a href="https://github.com/pilloPl/event-source-cqrs-sample/blob/master/src/main/java/io/pillopl/eventsource/readmodel/ReadModelOnDomainEventUpdater.java">how simply it is to update read model</a> in event sourced application. Read model there is implemented by directly using JDBC queries with <a href="https://github.com/pilloPl/event-source-cqrs-sample/blob/master/src/main/java/io/pillopl/eventsource/readmodel/ShopItemDto.java">denormalized table<a />, beacuse why not? &lt;/p&gt; </a></p></p> Mon, 27 Jun 2016 00:00:00 +0000 http://pillopl.github.io/event-sourcing-with-cqrs/ http://pillopl.github.io/event-sourcing-with-cqrs/ Reliable Domain Events <p style="text-align:justify;"> We already know that domain events are a great tool to integrate different parts of your system (so called bounded contexts) and decouple them. Instead of directly calling outside component, we can notify our infrastructure, which in turn informs interested parties about what has just occurred. This another form of <b>Inversion of Control</b> helps us to achieve our goal. Consider following piece of code: </p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">class</span> <span class="nc">User</span> <span class="o">{</span> <span class="c1">//...</span> <span class="nd">@Transactional</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">register</span><span class="o">(</span><span class="n">LocalDateTime</span> <span class="n">at</span><span class="o">,</span> <span class="n">RegisteredBy</span> <span class="n">by</span><span class="o">)</span> <span class="o">{</span> <span class="n">markRegistered</span><span class="o">();</span> <span class="n">markSuspiciousIfAtNight</span><span class="o">(</span><span class="n">at</span><span class="o">);</span> <span class="n">DomainEventsPublisher</span><span class="o">.</span><span class="na">publish</span><span class="o">(</span><span class="k">new</span> <span class="n">UserRegistered</span><span class="o">(</span><span class="k">this</span><span class="o">.</span><span class="na">id</span><span class="o">(),</span> <span class="n">at</span><span class="o">));</span> <span class="o">}</span> <span class="o">}</span> <span class="kd">public</span> <span class="kd">class</span> <span class="nc">UserRegistered</span> <span class="kd">implements</span> <span class="n">DomainEvent</span> <span class="o">{</span> <span class="kd">private</span> <span class="kd">final</span> <span class="n">UserRegistered</span> <span class="n">userId</span><span class="o">;</span> <span class="kd">private</span> <span class="kd">final</span> <span class="n">LocalDateTime</span> <span class="n">at</span><span class="o">;</span> <span class="c1">//getters, constructor</span> <span class="o">}</span> <span class="kd">class</span> <span class="nc">DomainEventsPublisher</span> <span class="o">{</span> <span class="c1">//...</span> <span class="kd">private</span> <span class="kd">final</span> <span class="n">Register</span> <span class="n">handlersRegistry</span><span class="o">;</span> <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">publish</span><span class="o">(</span><span class="n">DomainEvent</span> <span class="n">event</span><span class="o">)</span> <span class="o">{</span> <span class="n">handlersRegistry</span> <span class="o">.</span><span class="na">getHandlers</span><span class="o">(</span><span class="n">event</span><span class="o">.</span><span class="na">getClass</span><span class="o">())</span> <span class="o">.</span><span class="na">forEach</span><span class="o">(</span><span class="n">handler</span> <span class="o">-&gt;</span> <span class="n">handler</span><span class="o">.</span><span class="na">handle</span><span class="o">(</span><span class="n">event</span><span class="o">));</span> <span class="o">}</span> <span class="o">}</span> <span class="kd">class</span> <span class="nc">SendCommunicationOnUserRegistered</span> <span class="kd">implements</span> <span class="n">DomainEventHandler</span><span class="o">&lt;</span><span class="n">UserRegistered</span><span class="o">&gt;</span> <span class="o">{</span> <span class="nd">@Override</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">handle</span><span class="o">(</span><span class="n">UserRegistered</span> <span class="n">event</span><span class="o">)</span> <span class="o">{</span> <span class="n">Communication</span> <span class="n">c</span> <span class="o">=</span> <span class="n">sendRegistrationEmail</span><span class="o">(</span><span class="n">event</span><span class="o">.</span><span class="na">getUserId</span><span class="o">());</span> <span class="n">storeCommunication</span><span class="o">(</span><span class="n">c</span><span class="o">);</span> <span class="o">}</span> </code></pre></div></div> <p style="text-align:justify;"> There is a big problem with this simple <b>Observer</b> pattern in above example. Namely, everything happens in the same database transaction, which has started at the time of calling <i>register</i> method. This has several implications. First of all, we did not decouple user registration from e-mail sending and we just have mentioned this is what domain events are for. If our mail server is down, registration fails. Why would our user care about an email? He correctly filled registration form and does not even know there is an email coming. </p> <p style="text-align:justify;"> From the <b>use case</b> point of view, sending an email should not imply successful invocation. Secondly, even though it looks like the code deals only with users (it registers and marks as suspicious when needed), it modifies another aggregate - communications (communication would be probably modeled as a Generic Subdomain, but to simplify things consider it as another bounded context). The rule of thumb says that we should not modify several aggregates in one transaction, because these concepts should not be so directly related. Sending an email (or any other action done as a consequence of registering user) may take a lot of time, do I/O calls, etc. </p> <p style="text-align:justify;"> But things get worse. Consider situation when everything was fine with our mail server, we want to save user to database and something fails and transaction rollbacks. Now we have a big problem, because confused user got error page as a response, but seconds later successful email with registration greetings. </p> <p style="text-align:justify;"> This clearly shows that those concepts should be unrelated. One may come with an idea to fire all handlers asynchronously (so outside current transaction) but that solves only one issue: we could register users when we cannot send emails. We need something better. Fortunately, we can fire our emails just after transaction commit. Thus, we are sure everything was fine during registration and without doubts we can send the welcoming message. Spring gives us possibility to do that in a few lines of code with <a href="http://docs.spring.io/spring/docs/3.0.6.RELEASE_to_3.1.0.BUILD-SNAPSHOT/3.0.6.RELEASE/org/springframework/transaction/support/TransactionSynchronizationManager.html"> TransactionSynchronizationManager</a>: </p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">class</span> <span class="nc">DomainEventsPublisher</span> <span class="o">{</span> <span class="c1">//...</span> <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">publish</span><span class="o">(</span><span class="n">DomainEvent</span> <span class="n">event</span><span class="o">)</span> <span class="o">{</span> <span class="n">handlersRegistry</span> <span class="o">.</span><span class="na">getHandlers</span><span class="o">(</span><span class="n">event</span><span class="o">.</span><span class="na">getClass</span><span class="o">())</span> <span class="o">.</span><span class="na">forEach</span><span class="o">(</span><span class="n">handler</span> <span class="o">-&gt;</span> <span class="n">handleAsynchronously</span><span class="o">(</span><span class="n">event</span><span class="o">,</span> <span class="n">handlers</span><span class="o">));</span> <span class="o">}</span> <span class="kd">private</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">handleAsynchronously</span><span class="o">(</span><span class="n">DomainEvent</span> <span class="n">event</span><span class="o">,</span> <span class="n">DomainEventHandler</span> <span class="n">handler</span><span class="o">)</span> <span class="o">{</span> <span class="k">if</span> <span class="o">(</span><span class="n">TransactionSynchronizationManager</span><span class="o">.</span><span class="na">isActualTransactionActive</span><span class="o">())</span> <span class="o">{</span> <span class="n">processAfterCommit</span><span class="o">(</span><span class="n">event</span><span class="o">,</span> <span class="n">handler</span><span class="o">);</span> <span class="o">}</span> <span class="k">else</span> <span class="o">{</span> <span class="n">processNow</span><span class="o">(</span><span class="n">event</span><span class="o">,</span> <span class="n">handler</span><span class="o">);</span> <span class="o">}</span> <span class="o">}</span> <span class="kd">private</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">processNow</span><span class="o">(</span><span class="kd">final</span> <span class="n">DomainEvent</span> <span class="n">event</span><span class="o">,</span> <span class="n">DomainEventHandler</span> <span class="n">handler</span><span class="o">)</span> <span class="o">{</span> <span class="n">handler</span><span class="o">.</span><span class="na">handle</span><span class="o">(</span><span class="n">event</span><span class="o">);</span> <span class="o">}</span> <span class="kd">private</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">processAfterCommit</span><span class="o">(</span><span class="kd">final</span> <span class="n">DomainEvent</span> <span class="n">event</span><span class="o">,</span> <span class="n">DomainEventHandler</span> <span class="n">handler</span><span class="o">)</span> <span class="o">{</span> <span class="n">TransactionSynchronizationManager</span><span class="o">.</span><span class="na">registerSynchronization</span><span class="o">(</span><span class="k">new</span> <span class="n">TransactionSynchronizationAdapter</span><span class="o">()</span> <span class="o">{</span> <span class="nd">@Override</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">afterCommit</span><span class="o">()</span> <span class="o">{</span> <span class="n">handler</span><span class="o">.</span><span class="na">handle</span><span class="o">(</span><span class="n">event</span><span class="o">);</span> <span class="o">}</span> <span class="o">});</span> <span class="o">}</span> <span class="o">}</span> </code></pre></div></div> <p>&lt;/p&gt;</p> <p style="text-align:justify;"> This example could be simplified with Spring 4.2 and <a href="http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#transaction-event"> @TransactionalEventListener</a>. Thanks to this code, we are fine with cause and effect relationship. Taking advantage of java memory model nomenclature: we know that successful registration <b>happens before</b> sending an email. One may argue that there is a slight window of time when we are not consistent. As stated at the beginning, we don't need to be consistent when working with several bounded context. The important is that they will be <b>eventually consistent</b>. Anyway, we still did not solve the problem with unresponsive mail server. When it fails, the information is lost. We can implement something which will retry this operation with a reasonable back-off, but when our application crashes, we still don't have any mean to recover to former state. We need to deal with that issue. </p> <p style="text-align:justify;"> It gets clearer that we need to store somewhere the <b>intent</b> of sending the email. The intent was of course <i>UserRegistered</i> event. By exposing this intent to for example JMS infrastructure, we can implement the retry mechanism. We can go further and store any event coming from a given bounded context. Repository of all domain events is in fact called <b>Event Store</b>. Below example contains code that serializes events to JSON and publishes them to JMS. We could publish them anywhere else, for example to a file on a local disk or to an Akka actor. </p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">ExternalEventStore</span> <span class="o">{</span> <span class="c1">//...</span> <span class="kd">private</span> <span class="kd">final</span> <span class="n">ProducerTemplate</span> <span class="n">producerTemplate</span><span class="o">;</span> <span class="kd">private</span> <span class="kd">final</span> <span class="n">ObjectMapper</span> <span class="n">objectMapper</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ObjectMapper</span><span class="o">();</span> <span class="kt">void</span> <span class="nf">publish</span><span class="o">(</span><span class="n">DomainEvent</span> <span class="n">event</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">JsonProcessingException</span> <span class="o">{</span> <span class="kd">final</span> <span class="n">String</span> <span class="n">body</span> <span class="o">=</span> <span class="n">objectMapper</span><span class="o">.</span><span class="na">writeValueAsString</span><span class="o">(</span><span class="n">event</span><span class="o">);</span> <span class="n">producerTemplate</span><span class="o">.</span><span class="na">sendBody</span><span class="o">(</span><span class="s">"queue.url"</span><span class="o">,</span> <span class="n">InOnly</span><span class="o">,</span> <span class="n">body</span><span class="o">);</span> <span class="o">}</span> <span class="o">}</span> </code></pre></div></div> <p style="text-align:justify;"> We could invoke <i>ExternalEventStore</i> from our <i>handleNow</i> method from previous example and make some other component consume those messages and send emails. But that would be just delegating the problem from mail server to another part of infrastructure - our queue. Putting a message to a queue might fail and the message would be lost. Moreover, our application can fail somewhere in between commit and invoking this asynchronous transaction listener. We also cannot move this code back to the transaction, because that would make us stuck at the beginning of our problem and queue failures would result in our users not being able to register. </p> <p style="text-align:justify;"> We have to develop a consistent solution in which an <b>occurrence of an event reflects that it really happened in our system</b>. Also <b>when it really happens, it should be followed by an event</b>. In other words, those two statements should be in bi-conditional logical connective. </p> <p style="text-align:justify;"> The problem is that our JMS component is not backed by the same data source as our domain model. One solution is to use global transaction and two-phase commits. The problem is that it might decrease performance significantly. Plus, not every part of our infrastructure must support that mechanism. More clever idea is to share the same data source for our messaging infrastructure and domain model (if those two parts support this kind of data soure). The side effect here is that we need to share the same schema, which might not be the nicest solution. </p> <p style="text-align:justify;"> In my opinion the best option is to translate our events to our domain model storage and save them in the same transaction. Later on, another pool of threads should process them and publish somewhere else. Now our event store would look as follows: </p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">public</span> <span class="kd">class</span> <span class="nc">InternalEventStore</span> <span class="o">{</span> <span class="c1">//...</span> <span class="kd">private</span> <span class="kd">final</span> <span class="n">ObjectMapper</span> <span class="n">eventSerializer</span><span class="o">;</span> <span class="kd">private</span> <span class="kd">final</span> <span class="n">SessionFactory</span> <span class="n">sessionFactory</span><span class="o">;</span> <span class="kt">void</span> <span class="nf">store</span><span class="o">(</span><span class="n">DomainEvent</span> <span class="n">event</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">JsonProcessingException</span> <span class="o">{</span> <span class="n">session</span><span class="o">().</span><span class="na">save</span><span class="o">(</span><span class="n">serialized</span><span class="o">(</span><span class="n">event</span><span class="o">));</span> <span class="o">}</span> <span class="kd">private</span> <span class="n">PersistentEvent</span> <span class="nf">serialized</span><span class="o">(</span><span class="n">DomainEvent</span> <span class="n">event</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">JsonProcessingException</span> <span class="o">{</span> <span class="k">return</span> <span class="k">new</span> <span class="nf">PersistentEvent</span><span class="o">(</span><span class="n">eventSerializer</span><span class="o">.</span><span class="na">writeValueAsString</span><span class="o">(</span><span class="n">event</span><span class="o">));</span> <span class="o">}</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">PersistentEvent</span><span class="o">&gt;</span> <span class="nf">listPending</span><span class="o">(</span><span class="kt">int</span> <span class="n">limit</span><span class="o">)</span> <span class="o">{</span> <span class="c1">//...</span> <span class="o">}</span> <span class="o">}</span> <span class="kd">public</span> <span class="kd">class</span> <span class="nc">PersistentEvent</span> <span class="o">{</span> <span class="kd">public</span> <span class="kd">enum</span> <span class="n">Status</span> <span class="o">{</span> <span class="n">PENDING</span><span class="o">,</span> <span class="n">SENT</span> <span class="o">}</span> <span class="kd">private</span> <span class="n">Long</span> <span class="n">id</span><span class="o">;</span> <span class="kd">private</span> <span class="n">String</span> <span class="n">uuid</span> <span class="o">=</span> <span class="n">UUID</span><span class="o">.</span><span class="na">randomUUID</span><span class="o">().</span><span class="na">toString</span><span class="o">();</span> <span class="kd">private</span> <span class="n">LocalDateTime</span> <span class="n">occuredAt</span> <span class="o">=</span> <span class="n">LocalDateTime</span><span class="o">.</span><span class="na">now</span><span class="o">();</span> <span class="kd">private</span> <span class="n">LocalDateTime</span> <span class="n">sentAt</span><span class="o">;</span> <span class="kd">private</span> <span class="n">String</span> <span class="n">body</span><span class="o">;</span> <span class="kd">private</span> <span class="n">Status</span> <span class="n">status</span> <span class="o">=</span> <span class="n">PENDING</span><span class="o">;</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">sent</span><span class="o">(</span><span class="n">LocalDateTime</span> <span class="n">at</span><span class="o">)</span> <span class="o">{</span> <span class="k">this</span><span class="o">.</span><span class="na">sentAt</span> <span class="o">=</span> <span class="n">at</span><span class="o">;</span> <span class="k">this</span><span class="o">.</span><span class="na">status</span> <span class="o">=</span> <span class="n">SENT</span><span class="o">;</span> <span class="o">}</span> <span class="c1">//...</span> <span class="o">}</span> </code></pre></div></div> <p style="text-align:justify;"> and it would be invoked from <i>DomainEventProcessor</i> in the same transaction (so we came back to synchronous observator pattern): </p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">class</span> <span class="nc">DomainEventsPublisher</span> <span class="o">{</span> <span class="c1">//...</span> <span class="kd">private</span> <span class="kd">final</span> <span class="n">Register</span> <span class="n">handlersRegistry</span><span class="o">;</span> <span class="kd">private</span> <span class="kd">final</span> <span class="n">EventStore</span> <span class="n">eventStore</span><span class="o">;</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">publish</span><span class="o">(</span><span class="n">DomainEvent</span> <span class="n">event</span><span class="o">)</span> <span class="o">{</span> <span class="n">handlersRegistry</span> <span class="o">.</span><span class="na">getHandlers</span><span class="o">(</span><span class="n">event</span><span class="o">.</span><span class="na">getClass</span><span class="o">())</span> <span class="o">.</span><span class="na">forEach</span><span class="o">(</span><span class="n">handler</span> <span class="o">-&gt;</span> <span class="n">handler</span><span class="o">.</span><span class="na">handle</span><span class="o">(</span><span class="n">event</span><span class="o">));</span> <span class="n">eventStore</span><span class="o">.</span><span class="na">store</span><span class="o">(</span><span class="n">event</span><span class="o">);</span> <span class="o">}</span> <span class="o">}</span> </code></pre></div></div> <p style="text-align:justify;"> Note that we left the register with handlers working under the same transaction. It is fine, because we may need to listen to this event somewhere else in the same bounded context. That way we won't modify another aggregates. </p> <p>But we still want our events to appear in our JMS infrastructure. We can run a periodic job which scans list of our events and sends them to a queue or a topic: &lt;/p&gt;</p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">PublishPendingEventsScheduler</span> <span class="o">{</span> <span class="kd">private</span> <span class="kd">final</span> <span class="n">ExternalEventStore</span> <span class="n">eventStore</span><span class="o">;</span> <span class="kd">private</span> <span class="kd">final</span> <span class="n">ExternalEventStore</span> <span class="n">publisher</span><span class="o">;</span> <span class="nd">@Scheduled</span><span class="o">(</span><span class="n">initialDelay</span> <span class="o">=</span> <span class="mi">3000</span><span class="o">,</span> <span class="n">fixedDelayString</span> <span class="o">=</span> <span class="s">"${events.publisher.freq:3000}"</span><span class="o">)</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">sendEvents</span><span class="o">()</span> <span class="o">{</span> <span class="n">eventStore</span><span class="o">.</span><span class="na">listPending</span><span class="o">(</span><span class="mi">100</span><span class="o">).</span><span class="na">forEach</span><span class="o">(</span><span class="k">this</span><span class="o">::</span><span class="n">publish</span><span class="o">);</span> <span class="o">}</span> <span class="kd">private</span> <span class="kt">void</span> <span class="nf">publish</span><span class="o">(</span><span class="n">PersistentEvent</span> <span class="n">event</span><span class="o">)</span> <span class="o">{</span> <span class="n">publisher</span><span class="o">.</span><span class="na">publish</span><span class="o">(</span><span class="n">event</span><span class="o">);</span> <span class="c1">// publisher needs to have publish(PersistentEvent event) method</span> <span class="n">event</span><span class="o">.</span><span class="na">sent</span><span class="o">(</span><span class="n">now</span><span class="o">());</span> <span class="o">}</span> <span class="o">}</span> </code></pre></div></div> <p style="text-align:justify;"> We mark every event as sent, so that it won't be picked up in further invocation. If our message infrastructure fails, we try again soon. We might argue that this code suffers from the same problem as the whole example. Our database might fails at the time we want to save this event as sent. That is a fair concern, because we already have sent it to JMS. That means it can arrive at consumer side several times. It is important that consumer handles those events in an idempotent way - by for example storing PersistentEvent's uuid and doing de-duplication. Resending at producer side and idempotency at consumer side gives us <b>at most once delivery.</b> </p> <p style="text-align:justify;">In this post I tried to describe reliable domain events mechanism by implementing simple event store. Actually, events stores have much more benefits: we can examine every historical result of commands invoked in our system, run some forecasting algorithms, do event sourcing (reconstructing an aggregate by composing events it has produced) in different bounded contexts.</p> Sat, 23 Apr 2016 00:00:00 +0000 http://pillopl.github.io/reliable-domain-events/ http://pillopl.github.io/reliable-domain-events/ Stub and Verify? <p style="text-align:justify;"> Several times lately I came across Spock tests, which conceptually looked as follows: </p> <div class="language-groovy highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">private</span> <span class="kd">static</span> <span class="kd">final</span> <span class="n">BigDecimal</span> <span class="n">ANY_AMOUNT</span> <span class="o">=</span> <span class="k">new</span> <span class="n">BigDecimal</span><span class="o">(</span><span class="s2">"100.00"</span><span class="o">)</span> <span class="n">Payment</span> <span class="n">payment</span> <span class="o">=</span> <span class="n">aSamplePayment</span><span class="o">()</span> <span class="n">Client</span> <span class="n">client</span> <span class="o">=</span> <span class="n">aSampleClient</span><span class="o">()</span> <span class="n">PaymentCreator</span> <span class="n">paymentCreator</span> <span class="o">=</span> <span class="n">Mock</span><span class="o">(</span><span class="n">PaymentCreator</span><span class="o">)</span> <span class="n">PaymentRepository</span> <span class="n">repository</span> <span class="o">=</span> <span class="n">Mock</span><span class="o">(</span><span class="n">PaymentRepository</span><span class="o">)</span> <span class="nd">@Subject</span> <span class="n">Payments</span> <span class="n">payments</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Payments</span><span class="o">(</span><span class="n">paymentCreator</span><span class="o">,</span> <span class="n">repository</span><span class="o">)</span> <span class="kt">def</span> <span class="s2">"should create outgoing payment for loan"</span><span class="o">()</span> <span class="o">{</span> <span class="nl">when:</span> <span class="n">Payment</span> <span class="n">actualPayment</span> <span class="o">=</span> <span class="n">payments</span><span class="o">.</span><span class="na">saveOutgoingFor</span><span class="o">(</span><span class="n">client</span><span class="o">,</span> <span class="n">ANY_AMOUNT</span><span class="o">)</span> <span class="nl">then:</span> <span class="mi">1</span> <span class="o">*</span> <span class="n">paymentCreator</span><span class="o">.</span><span class="na">createOutgoing</span><span class="o">(</span><span class="n">client</span><span class="o">,</span> <span class="n">ANY_AMOUNT</span><span class="o">)</span> <span class="o">&gt;&gt;</span> <span class="n">payment</span> <span class="mi">1</span> <span class="o">*</span> <span class="n">repository</span><span class="o">.</span><span class="na">save</span><span class="o">(</span><span class="n">payment</span><span class="o">)</span> <span class="n">actualPayment</span> <span class="o">==</span> <span class="n">payment</span> <span class="o">}</span> </code></pre></div></div> <p style="text-align:justify;"> Spock allows you to stub and verify collaborator at once.<a href="https://spockframework.github.io/spock/docs/1.0/interaction_based_testing.html"> See section 'Combining Mocking and Stubbing'</a>. It is followed by sections which describe couple of discouraged solutions to testing, like partial stubs or stubbing static methods. In my opinion above section should also have this sidenote: </p> <blockquote class="cite"> <p>(Think twice before using this feature. It might be better to change the design of the code under specification.)</p> </blockquote> <p><strong><em>Design smell!</em></strong></p> <p>Consider following implementation under test:</p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="n">Payment</span> <span class="nf">saveOutgoingFor</span><span class="o">(</span><span class="n">Client</span> <span class="n">client</span><span class="o">,</span> <span class="n">BigDecimal</span> <span class="n">amount</span><span class="o">)</span> <span class="o">{</span> <span class="n">Payment</span> <span class="n">payment</span> <span class="o">=</span> <span class="n">paymentCreator</span><span class="o">.</span><span class="na">createOutgoing</span><span class="o">(</span><span class="n">client</span><span class="o">,</span> <span class="n">amount</span><span class="o">);</span> <span class="n">paymentRepository</span><span class="o">.</span><span class="na">save</span><span class="o">(</span><span class="n">payment</span><span class="o">);</span> <span class="k">return</span> <span class="n">payment</span><span class="o">;</span> <span class="o">}</span> </code></pre></div></div> <p style="text-align:justify;"> What it does is creating new payment and saving it in some kind of storage. Actually, the paymentRepository.save() method could return stored payment, so that we could get rid of last line. Such design can be explained like the following "do something with the payment, return it, do something else, and return it". Two actions are being done by two collaborating services. Actually we can cut it to "do something <i>andThen</i> do something else". Rings a bell? It is just function composition and you can read why dependency injection in most cases is just function composition <a href="http://www.nurkiewicz.com/2015/08/dependency-injection-syntax-sugar-over.html">here</a>. What we care about is the result of function composition, which is being done inside one method. We don't care about partial steps and about their implementation. We are interested in the result, to be more precise we check <b>expected state</b>. </p> <p style="text-align:justify;"> I bolded state not without a reason. Classical TDD user would tend to use stubs and check state, mockist TDD user likes mocks and <b>behaviours</b>. More about that you can read in <a href="http://martinfowler.com/articles/mocksArentStubs.html">famous Fowler's article</a>. So what is actually wrong in checking partial steps in such scenarios? Well, it leaks implementation details. Now, we force the implementation to actually use PaymentCreator in a fixed way, contrary to stub, which can be desribed as "<b>if</b> you use one of my methods, I'll return this fixture". Both classical and mockists TDD enthusiasts have their rights, but in my opinion those two concepts should not be combined. </p> <p style="text-align:justify;"> I express this opinion to one of my friends and he replied: "But what if your first step does something very important that you want to check. Plus it returns value that is used in next lines. Let's say it sends an email". That is a fair question and for simplicity reasons let's assume that mail sender sends information about payment being created to the client and actually really returns something that we care of later (for example a result indicating mail failure/success). The approach showed at the beginning of this article solves that issue, but... </p> <p><strong><em>Test isolation</em></strong></p> <p style="text-align:justify;"> You want your tests to fail for one reason. That is one of the most ground rules when writing tests. That means that we don't want to check how the payment looks like and if client was informed in the same test. To me, the tests should look like: </p> <div class="language-groovy highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">def</span> <span class="s2">"should create outgoing payment for loan"</span><span class="o">()</span> <span class="o">{</span> <span class="nl">given:</span> <span class="n">paymentCreator</span><span class="o">.</span><span class="na">createOutgoing</span><span class="o">(</span><span class="n">client</span><span class="o">,</span> <span class="n">ANY_AMOUNT</span><span class="o">)</span> <span class="o">&gt;&gt;</span> <span class="n">payment</span> <span class="nl">expect:</span> <span class="n">payments</span><span class="o">.</span><span class="na">saveOutgoingFor</span><span class="o">(</span><span class="n">client</span><span class="o">,</span> <span class="n">ANY_AMOUNT</span><span class="o">)</span> <span class="o">==</span> <span class="n">payment</span> <span class="o">}</span> <span class="kt">def</span> <span class="s2">"should store the payment"</span><span class="o">()</span> <span class="o">{</span> <span class="nl">given:</span> <span class="n">paymentCreator</span><span class="o">.</span><span class="na">createOutgoing</span><span class="o">(</span><span class="n">client</span><span class="o">,</span> <span class="n">ANY_AMOUNT</span><span class="o">)</span> <span class="o">&gt;&gt;</span> <span class="n">payment</span> <span class="nl">when:</span> <span class="n">payments</span><span class="o">.</span><span class="na">saveOutgoingFor</span><span class="o">(</span><span class="n">client</span><span class="o">,</span> <span class="n">ANY_AMOUNT</span><span class="o">)</span> <span class="nl">then:</span> <span class="mi">1</span> <span class="o">*</span> <span class="n">repository</span><span class="o">.</span><span class="na">save</span><span class="o">(</span><span class="n">payment</span><span class="o">)</span> <span class="o">}</span> <span class="kt">def</span> <span class="s2">"should inform the client"</span><span class="o">()</span> <span class="o">{</span> <span class="nl">when:</span> <span class="n">payments</span><span class="o">.</span><span class="na">saveOutgoingFor</span><span class="o">(</span><span class="n">client</span><span class="o">,</span> <span class="n">ANY_AMOUNT</span><span class="o">)</span> <span class="nl">then:</span> <span class="mi">1</span> <span class="o">*</span> <span class="n">mailSender</span><span class="o">.</span><span class="na">informClient</span><span class="o">()</span> <span class="o">}</span> </code></pre></div></div> <p style="text-align:justify;"> That way every test fail only for one reason. Not more. It is easier to refractor code, it stops rigidity. Rigidity means that the software is difficult to change. A small change causes a cascade of subsequent changes. In that case, small change breaks unrelated tests. </p> <p><strong><em>My personal rule of thumb</em></strong></p> <p style="text-align:justify;"> I (try to) practise TDD all the time. I faced descirbed problems several times, and I came up with my rule when to use mocks and when go for stubs. I am a big fan of <b>CQRS</b> idea and I truly love it how it fits into above considerations. So when my unit test needs to check whether some action was perfomed (command was sent) I choose mocks and verify behaviours. When i rely on my collaborators to return something (queries) I always go for stubs. I don't think that "veryfing what you stubbed" is a good idea. </p> Fri, 13 Nov 2015 00:00:00 +0000 http://pillopl.github.io/stub-and-verify/ http://pillopl.github.io/stub-and-verify/ spring.io.2015 <p style="text-align:justify;"> Last month I had chance to attend an event hosted by spring.io guys, namely conference Spring IO 2015. It was held in Barcelona and gathered 41 speakers, whose talks were around spring framework, groovy, grails and clouds. As a developer, I can hardly live without spring, so this was a perfect chance to enhance my spring-related experience. Although I was not amazed by all of the presented subjects, some talks brought my attention. I would like to quickly summarize one of those.</p> <p><strong><em>&lt;a href=http://www.springio.net/inside-an-spring-event-sourced-cqrs-application-or-why-microservices-can-actually-work/”&gt;Inside an Spring Event Sourced CQRS application&lt;/a&gt;</em></strong></p> <p style="text-align:justify;"> You are probably familiar with concept of Command and Query Responsibility Segregation. If not I recommend <a href="https://msdn.microsoft.com/en-us/library/jj554200.aspx">this great reference</a>. To cut the long story short, it deals with having two different models: one for writes and one for reads. The read model is user-friendly, meaning it is often denormalized for a convinient projections. Thus, it is faster. Especially comparing to traditional CRUD-based system which makes a dozens of join operations for a reader.</p> <p style="text-align:justify;"> Eugen Paraschiv has shown his experience with using this technique together with event sourcing. Event sourcing is a concept which ensures that every change in application is related in an event. Those events are stored in a chronological order and then replayed. It was shown how CQRS-like nature of the system naturally leads to event sourcing. Having multiple reads models is easy when there is a single point of truth - an event - that we can listen to and update ourself as we want</p> <p style="text-align:justify;"> The buttom line here is another thing. As those projections are independent of each other and rely only on domain events, we can run them in separated spring contexts. We can go further and run them in different processes and JVMs. Do you see how far it goes? Yep, we can run them on separated hardware gaining the buzzworld of 2015: microservice-oriented architecture. Starting with CQRS, event sourcing and different projections for different domain areas naturally leads there.</p> <p style="text-align:justify;"> Event sourcing with CQRS brings another values to us. Events are immutable, simple standalone objects. Storing those is better for performance than persisting complex relational model. It is also simplification of the model - it really tells you what exactly have just happened. Events help you integrating with different systems, because they can just start listening to our events. Moreover, they can replay all the events from the beginning - meaning they can pretend being integrated ever since the first event was emitted.</p> <p style="text-align:justify;"> This is not over yet. Event sourcing is great debugging tool. Imagine that you need to troubleshoot your application on production and check what happen say 10 days ago. With event sourcing it is super easy - you just need to replay all the events before that timestamp. Voila, you have just replicated the requested situation. One may say, that replayng millions of events is not efficient. Sure, that is a valid point, but for this reason snapshots are introduced. You can store snapshots for example once for 100 events, reducing the maximum number of events to be replayed to 100.</p> <p style="text-align:justify;">Talk by Eugen was one of the bests ones in the whole event. Check out summary of others that may interest you: &lt;a href=http://www.springio.net/everything-you-need-to-know-about-java-classloaders//"&gt;Everything you need to know about Java Classloaders&lt;/a&gt;, <a href="http://www.springio.net/designing-for-distributed-systems-with-reactor-and-reactive-streams/"> Designing for Distributed Systems with Reactor and Reactive Streams</a> and <a href="http://www.springio.net/real-time-with-spring-sse-and-websockets/">Real-time with Spring: SSE and WebSockets</a></p> Thu, 14 May 2015 00:00:00 +0000 http://pillopl.github.io/spring-io-2015/ http://pillopl.github.io/spring-io-2015/