Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ExploreDDD Denver 2017: Tackling Complex Event Flows

ExploreDDD Denver 2017: Tackling Complex Event Flows

ExploreDDD 2017, Denver, Colorado, USA

2999fab21d182294fad0b2cc590fd54d?s=128

Martin Schimak

September 21, 2017
Tweet

Transcript

  1. Tackling complex event flows ExploreDDD – Denver, Colorado, USA –

    Sep 21st 2017 @martinschimak – martin.schimak@plexiti.com With thoughts from http://flowing.io @berndruecker | @martinschimak
  2. Let‘s build a dash button!

  3. We need three steps… Pay item Ship item Fetch item

  4. None
  5. Let‘s do a bit context mapping? Checkout Context Payment Context

    Inventory Context Shipment Context
  6. „The button just blinks green and confirms the order if

    we can ship the item within 72 hours!“
  7. How can we make that work? Checkout Context Payment Context

    Inventory Context Shipment Context
  8. Let‘s look into Domain Events <<root entity>> Good - goodId

    - ... <<value object>> Location - coordinates - ... 0..* <<event>> GoodFetched - goodId - ...
  9. Inventory Shipment Checkout Payment Services Events Event Collaboration decreases services

    coupling… Good fetched Good fetched
  10. Inventory Shipment Checkout Payment Services with decentral data … by

    enabling decentral data management Good shippable within 72 hours!
  11. So let‘s implement everything with event collaboration! Checkout Context Payment

    Context Inventory Context Shipment Context
  12. Inventory Shipment Checkout Payment With choreographies services trigger based on

    events Payment received Good fetched Good shipped Order placed
  13. „Our customer is king. From now on, we fetch the

    items before we collect the money!“ A simple requirement?
  14. Inventory Shipment Checkout Payment Pure event choreographies have some coupling

    issues…. Payment received Good fetched Good shipped Order placed All three event subscriptions have to change – at the same time
  15. https://www.flickr.com/photos/12567713@N00/310639290

  16. „For VIP customers, we will collect the money by invoice!“

    Can it get worse?
  17. Where do we put that kind of „domain logic“? Checkout

    Context Payment Context Inventory Context Shipment Context
  18. Are these the organisation‘s business capabilities? Inventory Shipment Checkout Payment

    Business Capabilities Order placed Payment received Good fetched Good shipped Business Purpose
  19. Or are we missing the organisation‘s core capability? Inventory Shipment

    Checkout Payment Order placed Order Order fulfilled
  20. Let‘s try to add an additional context… Order Context Checkout

    Context Payment Context Inventory Context Shipment Context
  21. … and change the communication patterns, too Order Context Checkout

    Context Payment Context Inventory Context Shipment Context
  22. Does this mean we do not use events anymore? No.

    Inventory Shipment Payment Order Collect payment Checkout Order placed
  23. But the order service translates the event to a command

    Inventory Shipment Payment Order Payment received Collect payment Checkout Order placed
  24. „Our customer is king. From now on, we fetch the

    items before we collect the money!“ A simple requirement? Yes.
  25. „For VIP customers, we will collect the money by invoice!“

    Is this still a problem?
  26. This principle is called orchestration Order Context Checkout Context Payment

    Context Inventory Context Shipment Context
  27. The danger with the so called orchestration principle „A few

    smart god services tell anemic CRUD services what to do!” Sam Newman Inventory Service Shipment Service Payment Service Order Service Checkout Service Inventory Service Shipment Service Payment Service Order Service Checkout Service
  28. A good thing takes time.

  29. Carrying out business capabilities takes time Inventory Shipment Checkout Payment

    Order placed Payment received Good fetched Good shipped Order Order fulfilled
  30. A „responsible“ payment service potentially needs a bit longer Payment

    Retrieve payment Payment received Charge credit card Credit card expired Charging currently not possible
  31. „A customer can update his expired credit card within two

    weeks before we cancel his order!“ The story just began… … …
  32. Exposing fine grained APIs pushes requirements into „god clients“ Inventory

    Shipment Payment Order Checkout Charge credit card Credit card expired Charging currently not possible
  33. Exposing APIs along business capabilities keeps clients lean Inventory Shipment

    Payment Order Checkout Retrieve payment Payment received Charge credit card Credit card expired Charging currently not possible
  34. Are you Event- or Command-Driven?

  35. Who is - organisationally - responsible? Conciously decide where to

    do the coupling Command Something has to happen in the future => 1 recipient Event Something has happend in the past => 0..n recipients Order placed Order Retrieve payment Payment
  36. How to implement? * * How hard can it be?

  37. • Do event command transformation • Handle state for long

    running flows • Implement the flow as 1st class citizen of domain logic
  38. State machine Persistent thing (Entity, Actor, …) Routing slip CADENCE

    Baker
  39. Sophisticated state machines solve some hard developer problems Monitoring &

    Operations Handling of time & timeouts Retry Visibility & Reporting Versioning Compensation Message correlation Performance & scalability
  40. Their explicit flow language helps in tackling complex event flows

    Ubiquitous Language Software Experts Domain Experts
  41. Action!

  42. The payment retrieval as executable flow ( )

  43. An executable Gherkin Spec checking the compensating action

  44. The binding strategy uses the step just when needed for

    example
  45. A visual test report for example #1 (Balance = 50,

    Amount = 70)
  46. A visual test report for example #3 (Balance = 50,

    Amount = 30)
  47. The DSL does not have to be graphical… e.g. {

    "name": "encode_and_deploy", "description": "Encodes a file and deploys to CDN", "version": 1, "tasks": [ { "name": "encode", "taskReferenceName": "encode", "type": "SIMPLE", … offers a JSON DSL Bpmn.createExecutableProcess("order") .startEvent() .serviceTask().name("Retrieve payment").camundaClass(RetrievePaymentAdapter.class) .serviceTask().name("Fetch goods").camundaClass(FetchGoodsAdapter.class) .serviceTask().name("Ship goods").camundaClass(ShipGoodsAdapter.class) .endEvent().camundaExecutionListenerClass("end", GoodsShippedAdapter.class) .done(); offers a Java DSL
  48. Flow logic is full of highly relevant domain concepts Ports

    and Adapters Application Domain State machine Payment Store Aggregates, Domain Events, Domain Services, etc … … but also the DSL defining the flow
  49. Explicit flows add value to the idea of living documentation

  50. Don‘t use formal notations for domain exploration.

  51. Include people with accessible methods one can learn on the

    go.
  52. Consider state machines to code complex event flows

  53. Using flows correctly does not violate your context boundaries Inventory

    Service Shipment Service Checkout Service Order Service Order Payment Payment Service
  54. Building a dash button – extended demo! for demo simplicity,

    just start all services in single Java VM https://github.com/flowing/flowing-retail/ Inventory Payment Order Shipping Shop Monitor
  55. None
  56. Code online: https://github.com/flowing Slides & Blogs: https://plexiti.com https://bernd-ruecker.com With thoughts

    from http://flowing.io @berndruecker | @martinschimak https://www.infoq.com /articles/microservice- event-choreographies
  57. Thank you!