Top Banner
CQRS and Event Sourcing for Java Developers @myfear blog.eisele.net https://keybase.io/myfear
57

CQRS and Event Sourcing for Java Developers

Jan 12, 2017

Download

Technology

Markus Eisele
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: CQRS and Event Sourcing for Java Developers

CQRS and Event Sourcing for Java Developers

@myfearblog.eisele.nethttps://keybase.io/myfear

Page 2: CQRS and Event Sourcing for Java Developers

• Classicalarchitecturesandmodernization• CRUDvs.CQRS• Alittleexample• Wrappingitup

Agenda

Page 3: CQRS and Event Sourcing for Java Developers

Classical Architectures

Page 4: CQRS and Event Sourcing for Java Developers

ApplicationServer

EAR- EnterpriseArchive

RESTMobileWebUI

.JAR.JAR.JAR

.JAR.JAR.JAR.JAR

.JAR.JAR.JAR

Browser RDBMS

Page 5: CQRS and Event Sourcing for Java Developers

ApplicationServer

ApplicationServer

ApplicationServer

EAR- EnterpriseArchive

RESTMobileWebUI

.JAR.JAR.JAR

.JAR.JAR.JAR.JAR

.JAR.JAR.JAR

Browser RDBMS

Page 6: CQRS and Event Sourcing for Java Developers

Modernization

Page 7: CQRS and Event Sourcing for Java Developers

Module

Module

Module

WebUI

.JAR.JAR.JAR

.JAR.JAR.JAR.JAR

.JAR.JAR.JARBrowser RDBMS

RDBMS

RDBMS

Page 8: CQRS and Event Sourcing for Java Developers

RoutingModule

TrackingModule

OrderModule

Tracker UIBrowser HistoryDB

OrderDB

RoutesDB

Page 9: CQRS and Event Sourcing for Java Developers

CRUD is OK!

Page 10: CQRS and Event Sourcing for Java Developers

• Forsimpledomainmodels!

• Complexmodelsstarttoshowweaknesses• DTOvs.VO• Readvs.Writeperformance• OptimisticLocking• DistributedCaches

but only …

Page 11: CQRS and Event Sourcing for Java Developers

But what else?

Page 12: CQRS and Event Sourcing for Java Developers

ComplexityofDomainModel

Effortto

cha

nge/e

nhan

ce

CRUD

CQRS

Page 13: CQRS and Event Sourcing for Java Developers

• CommandQueryResponsibilitySegregation

CQRS

Page 14: CQRS and Event Sourcing for Java Developers

• TheCommand– forWrites• e.g.CreateCargo

• TheQuery– forReads• e.g.ListCargo

Commands and Queries

Page 15: CQRS and Event Sourcing for Java Developers

Just separating reads from writes?

Page 16: CQRS and Event Sourcing for Java Developers

• TheCommand• handle(CreateCargo command) {…}

• TheEvent• on(CargoCreated event) {…}

Commands evolve into Events

Page 17: CQRS and Event Sourcing for Java Developers

• Occurredinthepast• Changedthesystemstate(Writeoperation)

• CargoCreated,LegAdded,CargoRouted,…

Events

Page 18: CQRS and Event Sourcing for Java Developers

WAIT! WHAT DID YOU DO TO MY ENTITIES?

Page 19: CQRS and Event Sourcing for Java Developers

• Book-keepingofchanges• Containsafullhistoryimplicitly• Storingeventsinsequencewithastrictglobalorder(time-stampbased)

• Noupdatesordeletes.Ever!• Nosingle“currentstate”.Thecollectionofeventsmakeupthesystemstateinanypointoftime.

Persistent Events

Page 20: CQRS and Event Sourcing for Java Developers

• CapturingChangesinsteadofupdatingObjects

JPA Entities vs. Immutable Facts

Page 21: CQRS and Event Sourcing for Java Developers
Page 22: CQRS and Event Sourcing for Java Developers

Current Stateis a second class citizen

Page 23: CQRS and Event Sourcing for Java Developers

• CapturingChangesinsteadofupdatingObjects

The read-side

Page 24: CQRS and Event Sourcing for Java Developers

• Wherewasmyvessellastweek?• Whocreatedtheshippingrequest?• Howmuchcargodidweshiplastyear?• Whichvesselshavebeenre-routedmorethantwiceinunderanhour?

Answer all kind of new questions

Page 25: CQRS and Event Sourcing for Java Developers

The read-side

cargoId location

Location

Cargo1 1.2,3Cargo2 1.3,2Cargo3 1.4,1Cargo4 2.2,5

CargoRouted(1.2,3)

CargoRouted(1.3,2)

CargoRouted(1.4,1)

Page 26: CQRS and Event Sourcing for Java Developers

Neo4J

Cassandra

Cassandra

Page 27: CQRS and Event Sourcing for Java Developers

Implementationexample. A little one.

Page 28: CQRS and Event Sourcing for Java Developers

CargoTrackerhttps://github.com/lagom/activator-lagom-cargotracker

Page 29: CQRS and Event Sourcing for Java Developers

Registration

Shipping

Frontend Cassandra

Page 30: CQRS and Event Sourcing for Java Developers
Page 31: CQRS and Event Sourcing for Java Developers

restCall(Method.POST, "/api/registration", register()),

restCall(Method.GET, "/api/registration/all",getAllRegistrations()),

Write-Side

Read-Side

Page 32: CQRS and Event Sourcing for Java Developers

The PersistentEntity

public class CargoEntity extends PersistentEntity<RegistrationCommand, RegistrationEvent, CargoState> {//...}

CargoEntity.java

Page 33: CQRS and Event Sourcing for Java Developers

The write-side

PersistentEntityRef<RegistrationCommand> ref =persistentEntityRegistry.refFor(

CargoEntity.class, request.getId());

RegistrationServiceImpl.java

Page 34: CQRS and Event Sourcing for Java Developers

The read-side (preparation)

prepareCreateTables(session).thenCompose(a -> prepareWriteCargo(session).thenCompose(b -> prepareWriteOffset(session).thenCompose(c -> selectOffset(session))));

CargoEventProcessor.java

Page 35: CQRS and Event Sourcing for Java Developers

The read-side (1)

private CompletionStage<Done> prepareCreateTables(CassandraSession session) {

return session.executeCreateTable("CREATE TABLE IF NOT EXISTS cargo ("+ "cargoId text, name text, description text,"+ "PRIMARY KEY (cargoId, destination))") );

}

Page 36: CQRS and Event Sourcing for Java Developers

The read-side (2)

private CompletionStage<Done> prepareWriteCargo(CassandraSession session) {

return session.prepare("INSERT INTO cargo (cargoId, name, description, "

+ " owner,destination) VALUES (?, ?,?,?,?)")

.thenApply(ps -> {setWriteCargo(ps);return Done.getInstance();

});

Page 37: CQRS and Event Sourcing for Java Developers

The read-side (offsets?)

private CompletionStage<Optional<UUID>> selectOffset(CassandraSession session) { return session.selectOne("SELECT offset FROM blogevent_offset")

.thenApply( optionalRow -> optionalRow.map(r -> r.getUUID("offset"))); }

Page 38: CQRS and Event Sourcing for Java Developers

The read-side (event trigger) @Overridepublic EventHandlersdefineEventHandlers(EventHandlersBuilder builder) {

builder.setEventHandler(CargoRegistered.class, this::processCargoRegistered);

return builder.build();}

RegistrationEvent!

Page 39: CQRS and Event Sourcing for Java Developers

The read-side (actual persistence) private CompletionStage<List<BoundStatement>> processCargoRegistered(CargoRegistered event, UUID offset) {

BoundStatement bindWriteCargo = writeCargo.bind();bindWriteCargo.setString("cargoId",

event.getCargo().getId());bindWriteCargo.setString("name",

event.getCargo().getName());bindWriteCargo.setString("description");

//...}

Page 40: CQRS and Event Sourcing for Java Developers

WHY IS THIS SO..complicated?

Page 41: CQRS and Event Sourcing for Java Developers

BECAUSE..it’s lightning FAST for users!!

Page 42: CQRS and Event Sourcing for Java Developers

[info] s.c.r.i.RegistrationServiceImpl - Cargo ID: 322667.

[info] s.c.r.i.CargoEventProcessor - Persisted 322667

Page 43: CQRS and Event Sourcing for Java Developers

• Alldatakeptinmemory!• Allstatechangesstoredasevents• ReplayeventsofanPersistentEntity torecreateit• StrongconsistencyforPersistentEntity’s and

Journal-Entries• EventualConsistencyforReadSide

More precisely, because:

Page 44: CQRS and Event Sourcing for Java Developers

BECAUSE..you can do a lot more a lot easier!!

Page 45: CQRS and Event Sourcing for Java Developers

• Recreatebugs• Migratesystems• Introducenewread-sides• Processhighervolumes• Extendedcachingscenarios

For example:

Page 46: CQRS and Event Sourcing for Java Developers

BECAUSE..the examples are based on LAGOM and

it DOES A LOT MORE for you!!

..oO(you can do this with Spring / Hibernate / Java EE – your choice)

Page 47: CQRS and Event Sourcing for Java Developers

• Lagomisasynchronousbydefault.• Developerproductivity• Buildformicroservices• Takesyoutoproduction• ….

You’ve heard this before, but:

Page 48: CQRS and Event Sourcing for Java Developers

..oO(you can do this with Spring / Hibernate / Java EE – your choice)

Page 49: CQRS and Event Sourcing for Java Developers

Links and further reading

Page 50: CQRS and Event Sourcing for Java Developers

ProjectSite:http://www.lightbend.com/lagom

GitHubRepo:https://github.com/lagom

Documentation:http://www.lagomframework.com/documentation/1.0.x/java/Home.html

CargoTrackerExample:https://github.com/lagom/activator-lagom-cargotracker

Page 51: CQRS and Event Sourcing for Java Developers

•Keep all data in memory!• Store all state changes as events• Replay all events of an actor to recreate it • Strong consistency for Actor (aggregate) and Journal• Eventual Consistency for Read Side

https://msdn.microsoft.com/en-us/library/jj554200.aspx

Page 52: CQRS and Event Sourcing for Java Developers

https://www.infoq.com/minibooks/domain-driven-design-quickly

Page 53: CQRS and Event Sourcing for Java Developers

Written for architects and developers that must quickly gain a fundamental understanding of microservice-based architectures, this free O’Reilly report explores the journey from SOA to microservices, discusses approaches to dismantling your monolith, and reviews the key tenets of a Reactive microservice:

• Isolate all the Things• Act Autonomously• Do One Thing, and Do It Well• Own Your State, Exclusively• Embrace Asynchronous Message-Passing• Stay Mobile, but Addressable• Collaborate as Systems to Solve Problems

http://bit.ly/ReactiveMicroservice

Page 54: CQRS and Event Sourcing for Java Developers

The detailed example in this report is based on Lagom, a new framework that helps you follow the requirements for building distributed, reactive systems.

• Get an overview of the Reactive Programming model and basic requirements for developing reactive microservices

• Learn how to create base services, expose endpoints, and then connect them with a simple, web-based user interface

• Understand how to deal with persistence, state, and clients

• Use integration technologies to start a successful migration away from legacy systems

http://bit.ly/DevelopReactiveMicroservice

Page 55: CQRS and Event Sourcing for Java Developers

http://bit.ly/SustainableEnterprise

• Understand the challenges of starting a greenfield development vs tearing apart an existing brownfield application into services

• Examine your business domain to see if microservices would be a good fit

• Explore best practices for automation, high availability, data separation, and performance

• Align your development teams around business capabilities and responsibilities

• Inspect design patterns such as aggregator, proxy, pipeline, or shared resources to model service interactions

Page 56: CQRS and Event Sourcing for Java Developers
Page 57: CQRS and Event Sourcing for Java Developers