CQRS and Event Sourcing for Java Developers

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

Transcript of CQRS and Event Sourcing for Java Developers

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