About policies, sagas and processes. @martinschimak -> May 8th, 2018 -> Budapest -> Microservices Meetup Long live the purple sticky! Order placed Request payment Policy?
Events are easy to grasp. Happy customers want facts! Goods shipped Order placed Goods fetched Payment received „We need to achieve some facts to create value for customers!“ Events are a concept easy to grasp for everybody in the room.
Shipment Service Relying on events only leads to suboptimal coupling To change the order of two services, we touch 4 sticky notes… but wait, all three services! Goods shipped Order placed Inventory Service Payment Service Payment received Goods fetched
Who owns the policy in a pure event choreography? Payment received Start Fetching Policy Fetch goods listened to by triggers Payment Service Inventory Service
Who owns the policy in a commanding approach? Payment received Start Fetching Policy Fetch goods listened to by triggers Payment Service Inventory Service
Extracting the policy into a mediator service Payment received Fetch goods listened to by triggers Payment Service Inventory Service Order Service Start Fetching Policy
The order as the company‘s core business Place order Order placed Request payment Order Service Payment received Fetch goods Goods fetched Ship goods Goods shipped “When the order is placed…” “When the payment is received…” “When the goods are fetched…” “Then we are done!” Mark order as fulfilled Order fulfilled Payment Service Inventory Service Shipment Service
Double check: what happens when we charge later? Place order Order placed Request payment Order Service Payment received Fetch goods Goods fetched Ship goods Goods shipped “When the order is placed…” “When the payment is received…” “When the goods are fetched…” “Then we are done!” Mark order as fulfilled Order fulfilled Payment Service Inventory Service Shipment Service “When the order is placed…” “When the payment is received…” “When the goods are fetched…”
Trade offs. Events and commands in between services… Payment received Policy Fetch goods listened to by triggers Payment Service Inventory Service Order Service
… do we introduce the central „god-like“ super service? Payment received Policy Fetch goods listened to by triggers Payment Service Inventory Service Order Service
„Place order“ seen as a multi-step service Order fulfilled Order canceled Payment received Goods shipped Place order Order placed From a client perspective, the service is „long-running“
Atomic vs. composite command execution Place order Order placed Typically we see a „command“ as the intent to change a write model... … but the customer‘s or service clients intent is often targeted at a more valuable business result, which needs many steps to be achieved. Place order Order fulfilled Atomic, trans- actional execution Composite, long- running execution
Let‘s do some event storming… Request payment Payment received Payment requested Charge credit card Depending on account balance Withdraw amount from account Amount Withdrawn Credit card charged Credit card failed Update credit card details Account details Credit card details updated Whenever card details are updated After two weeks Depending on the amount Amount credited Mark payment received Mark payment canceled Payment canceled Credit amount to account Whenever payment is canceled Mark payment received Payment received
What happens if we expose those atomic commands? Charge credit card Credit card charged Credit card failed Payment Service Retry with new credit card details Who owns the policy?
What happens if we expose troubles with some steps? Request payment Payment received Credit card failed Payment Service Retry with new credit card details Who owns the policy?
„Delegating our problems to our clients forces them to deal with the mitigation. They become god services.“ Credit card failed Retry with new credit card details Charge credit card listened to by triggers Payment Service Order Service
A „long-running“ smart endpoint … Request payment Payment received Payment canceled 1) creates value – serving a result its client is really interested in 2) assumes responsibility – instead of delegating troubles with internal steps to its client 3) may go asynchronous – if needed for composite execution Payment Service
Write Model Read Model Domain Event Command Domain Event Domain Event Domain Event Domain Event Event Sourcing Events as the source of truth Invariant Protection Events to (re-)project
How do we implement the payment service? Request payment Payment received Payment requested Charge credit card Depending on account balance Withdraw amount from account Amount Withdrawn Credit card charged Credit card failed Update credit card details Account details Credit card details updated Whenever card details are updated After two weeks Depending on the amount Amount credited Mark payment received Mark payment canceled Payment canceled Credit amount to account Whenever payment is canceled Mark payment received Payment received
What are the „ingredients“ of process managers? Domain Event Payment Retrieval Payment Retrieval Stateful component instantiates or correlates Process state projects relevant event data onto listened to by Stateless component evaluates Policy Command triggers does nothing does nothing Timer Event schedules (iow waits for further events)
@Saga class Payment { private var paymentAmount = 0F @StartSaga @SagaEventHandler(associationProperty = "paymentId") fun on(event: PaymentRequested) { } } e.g. Axon Messaging & Saga Management is cool, but Java works as well! :-) 1) Correlate domain event 2) Save process state 3) Evaluate business policy 4) Create and issue command