Download - Event Sourcing using Akka on AWS
![Page 1: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/1.jpg)
EVENT‐DRIVEN‐ARCHITECTURE ONAWS USING AKKA
![Page 2: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/2.jpg)
Software Engineer @firstbird
Contact me: @pfeiffer_d_
DANIEL PFEIFFER
![Page 3: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/3.jpg)
THE JOURNEY OF EVENTSthat are stored with Akka Persistenceto be then distributed via AWSto be consumed with Akka Streamwhat comes after that
![Page 4: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/4.jpg)
THE EXAMPLE
![Page 5: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/5.jpg)
DOMAIN DRIVEN DESIGNWe are talking about Aggregates and Events
![Page 6: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/6.jpg)
EVENT SOURCING"Capture all changes to an application
state as a sequence of events" -Martin Fowler, 2005
![Page 7: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/7.jpg)
CQRS"Asking a question should not changethe answer." - Bertrand Meyer, 2012
![Page 8: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/8.jpg)
THE DIFFERENCE
![Page 9: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/9.jpg)
PERSISTENTACTORclass TimeEntryAggregate(id: String) extends PersistentActor{ override def persistenceId: String = ??? override def receiveCommand: Receive = ??? override def receiveRecover: Receive = ???}
![Page 10: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/10.jpg)
A PersistentActor class represents one DDDaggregate.
class TimeEntryAggregate(id: String) extends PersistentActor{ ... override def persistenceId: String = s"time-entry-$id" ...}
![Page 11: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/11.jpg)
A PersistentActor receives commands andpersists events.
case class CreateTimeEntry( begin: DateTime, end: DateTime)
case class TimeEntryCreated( begin: DateTime, end: DateTime, sequenceNr: Long)
![Page 12: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/12.jpg)
A PersistentActor receives commands andpersists events.
class TimeEntryAggregate(id: String) extends PersistentActor{ ... override def receiveCommand: Receive = case CreateTimeEntry(start, end) => val event = TimeEntryCreated(start,end, lastSequenceNr + 1) persist(event){e => // update internal state // here we go after the event is persisted } } ...}
![Page 13: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/13.jpg)
A PersistentActor recovers from the journalclass TimeEntryAggregate(id: String) extends PersistentActor{ ... override def receiveRecover: Receive = { case TimeEntryCreated(start,end) => // update internal state } ...}
![Page 14: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/14.jpg)
STORING EVENTS TO A JOURNALIS NICE, BUT ...
others may be as well interested, so we have todistribute them.
![Page 15: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/15.jpg)
WITHIN ONE JVM WE COULD...use Akka EventStream to publish events ...
class TimeEntryActor() extends PersistentActor{ ... persist(event){e => context.system.eventStream.publish(e) } ...}
![Page 16: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/16.jpg)
... and subscribe from interested actorsclass EventConsumer extends Actor{ override def preStart: Unit = { context.system.eventStream.subscribe(classOf[TimeEntryActor.TimeEntryCreated } override def receive: Receive = { case e: TimeEntryCreated => //do something with that event }}
![Page 17: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/17.jpg)
HOW DO I INTERACT WITH MYAGGREGATES?
![Page 18: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/18.jpg)
DON'T CALL ME! CALL MYOFFICE!
![Page 19: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/19.jpg)
EXAMPLE 1
![Page 20: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/20.jpg)
BUT WE WANT TO BE COOL
![Page 21: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/21.jpg)
DISTRIBUTED SYSTEMS AREHARD
![Page 22: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/22.jpg)
WE WANT TO MAKE THEMEASIER
![Page 23: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/23.jpg)
INTRODUCE A MESSAGEBROKER, PUB/SUB ...
![Page 24: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/24.jpg)
THE EXAMPLE ONAWS STEROIDS
![Page 25: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/25.jpg)
![Page 26: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/26.jpg)
TIME ENTRY SERVICE
![Page 27: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/27.jpg)
EMAIL SERVICE
![Page 28: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/28.jpg)
SQS FLOWSqsSource(...) .map(msg => Envelope(msg.receiptHandle, msg.body)) .via(unmarshal()) .via(process()) .runWith(ack(...))
![Page 29: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/29.jpg)
SQS MESSAGE{ "messageId" : "", "receiptHandle" : "", "md5OfBody" : "", "body" : ""}
![Page 30: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/30.jpg)
SNS NOTIFICATION ENVELOPE{ "Type" : "Notification", "MessageId" : "", "TopicArn" : "", "Subject" : "time_entry.approved", "Message" : "", "Timestamp" : "", "SignatureVersion" : "", "Signature" : "", "SigningCertURL" : "", "UnsubscribeURL" : ""}
![Page 31: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/31.jpg)
CHALLENGES
![Page 32: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/32.jpg)
EVENT SCHEMA EVOLUTIONadding a field to an event type,remove or rename field in event type,remove event type,split event into multiple smaller events.
![Page 33: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/33.jpg)
case class TimeEntryCreated( id: UUID, begin: DateTime, end: DateTime, timeEntryUserId: UUID, userId: UUID)
gets marshalled to{ "id" : "123456", "begin" : "2016-09-01 12:00:00", "end" : "2016-09-01 12:15:00", "timeEntryUserId" : "00000000-0000-0000-0000-000000000000", "userId" : "00000000-0000-0000-0000-000000000000"}
![Page 34: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/34.jpg)
Then something within our schema changescase class TimeEntryCreated( ... description: String ...)
and we will have fun with that one{ "id" : "123456", "begin" : "2016-09-01 12:00:00", "end" : "2016-09-01 12:15:00", "timeEntryUserId" : "00000000-0000-0000-0000-000000000000", "userId" : "00000000-0000-0000-0000-000000000000"}
![Page 35: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/35.jpg)
{ "id" : "123456", "begin" : "2016-09-01 12:00:00", "end" : "2016-09-01 12:15:00", "timeEntryUserId" : "00000000-0000-0000-0000-000000000000", "userId" : "00000000-0000-0000-0000-000000000000"}
needs to be transformed to that{ "id" : "123456", "begin" : "2016-09-01 12:00:00", "end" : "2016-09-01 12:15:00", "timeEntryUserId" : "00000000-0000-0000-0000-000000000000", "userId" : "00000000-0000-0000-0000-000000000000", "description" : "N/A"}
![Page 36: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/36.jpg)
class Evolution(system: ExtendedActorSystem) extends EventAdapter{} override def fromJournal(event: Any, manifest: String): EventSeq = { val es = ... //doing evolution on event EventSeq(es) } override def manifest(event: Any): String = { val version = ??? event.getClass.getSimpleName + ":" + version } override def toJournal(event: Any): Any = ??? //write to the journal}
![Page 37: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/37.jpg)
SCALING WITH AKKA CLUSTERON AWS
or "Who am I, and where are all the others?"
![Page 38: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/38.jpg)
JOINING A CLUSTER
gives you information about your instancehttp://169.254.169.254/latest/meta-data/instance-id
![Page 39: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/39.jpg)
PRESERVING MESSAGE ORDER
![Page 40: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/40.jpg)
The query side could look like that| id | ... | version || --- | --- | ------- || 1 | ... | 45 || 2 | ... | 3 || 3 | ... | 58 |
![Page 41: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/41.jpg)
CHOOSING THE RIGHTDATASTORE
you will make mistakes so plan for it
![Page 42: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/42.jpg)
ASYNCHRONOUS MEANS NOTIMMEDIATE
![Page 43: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/43.jpg)
WHY DO WE REALLY WANT TODO THAT?
![Page 44: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/44.jpg)
WE WANT TO SLEEP BETTER
![Page 45: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/45.jpg)
WE WANT TO GET RID OF OURMONOLITH
![Page 46: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/46.jpg)
OUR DEVELOPMENT PROCESS BENEFITS
![Page 47: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/47.jpg)
WE CAN ALWAYS AGGREGATE OUREVENTS
![Page 48: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/48.jpg)
IF SOMEONE STARTS TO ASKQUESTIONS...
An audit log is included in your application for free!
![Page 49: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/49.jpg)
SUMMARY
![Page 50: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/50.jpg)
THE FIRST PROTOTYPE IS EASY BUT TOTACKLE THE CHALLENGES NEEDS
EFFORT!
![Page 51: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/51.jpg)
CONFIGURE YOUR SQS QUEUESPROPERLY
![Page 52: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/52.jpg)
LET EACH SERVICE MANAGE IT'SRESOURCES ITSELF.
![Page 53: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/53.jpg)
ONE TOPIC PER AGGREGATE
![Page 54: Event Sourcing using Akka on AWS](https://reader031.vdocument.in/reader031/viewer/2022022413/58ecd58f1a28ab79458b474d/html5/thumbnails/54.jpg)
LITERATURE
https://www.infoq.com/articles/AmazonPubSubhttp://martinfowler.com/eaaDev/EventCollaboration.html
http://martinfowler.com/bliki/CQRS.htmlhttps://github.com/dpfeiffer/event-sourcing-aws-
akka-showcasehttp://www.oreilly.com/programming/free/reactive-
microservices-architecture.htmlhttp://doc.akka.io/docs/akka/snapshot/scala/persistence-
schema-evolution.html#persistence-schema-evolution-scala http://chrisloy.net/2014/05/11/akka-
cluster-ec2-autoscaling.html