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

From Legacy to Reactive: The First Mile

From Legacy to Reactive: The First Mile

The first few decisions an architect must make on a modernization project are critical, but while most learning materials concentrate on the end goal of a modern architecture, we’re going to focus on the first few steps. While not revolutionary, the most common question asked by architects and consultants in the modernization space is “where do we even begin?”

Many teams get stuck on how to properly kick off a project of this scope. We’ll discuss modernization from the very first few steps. Event storming will bring all key stakeholders together in a collaborative environment in order to define the business processes involved and how to translate them into event-driven systems. This will show us a path towards the scope of initial work, while also planting the seeds for cultural change within an organization by focusing on the most interesting events that already occur within your business.

Once we have define the scope of initial work, we’ll pick up speed by diving into the first key architectural decisions and how make those decisions guided by the first-principles of Domain-Driven Design. We’ll dive deep into the nitty gritty by turning our DDD models into user stories and then implementing a few of those stories. We must do this while balancing the complexities of enterprise integration. How do we integrate new microservices into an old, brittle legacy system? How do we handle new and old systems living alongside each other?

This talk is inspired by Kevin’s upcoming mini-book from O’Reilly, Migrating Java to the Cloud: Modernize Enterprise Systems Without Starting From Scratch. By the end of this session, it will be apparent why a forceful revolution doesn’t work at enterprise scale. Instead, we’ll make the case for a calm, methodical, and measurable evolution of enterprise systems.

“You say you got a real solution? Well, you know, we'd all love to see the plan.”

Kevin Webber

October 19, 2017

More Decks by Kevin Webber

Other Decks in Programming


  1. From Legacy to Reactive: The First Mile Kevin Webber Principal

    Consultant @ RedElastic e: [email protected] m: medium.com/@kvnwbbr t: @kvnwbbr
  2. Why? — Enterprise software continues to be built piecemeal as

    applications rather than systems — Complex integrations — Most enterprise software is complex because we continue to be encumbered by the chains of the past
  3. Traditional architecture — Unbounded in complexity and side effects —

    Batch-mode, high-latency, high-failure rates — Has an impact — Customer happiness — The ability to hire the best — Visit TheDailyWTF
  4. Steps to enterprise modernization 1. Define business processes → Events

    & Event Storming 2. Create structure for systems → Domain Driven Design 3. Translate models into requirements → User Stories 4. Code → Java, Play, Akka
  5. Events enable flexibility — Publishers publish interesting events by default

    — System components integrate with minimal coordination costs
  6. The most interesting events cause a reaction. O!en you need

    to know why a system reacts in the way it did. — Martin Fowler
  7. Fear the fear — Fear paralyzes progress because cause and

    effect is unclear in traditional legacy systems — One of our first goals should be to remove fear and increase confidence — Events help us with both
  8. Event Storming — A design and collaboration methodology in workshop

    format — Use event storming to collaborate on design with all stakeholders — Define new business processes and revisit existing ones — Create high-level models that can be shaped into blueprints for software
  9. Modeling event flows What you'll need: — A room —

    Sticky notes — A wall Sounds simple? It is!
  10. Translating Events to DDD — The one thing missing from

    event storming models is a root entity — This models state changes caused by commands and events — State changes must be modeled explicitly
  11. Defining bounded contexts — Group together related business concepts —

    Contain domain complexity — A single person can master an aggregate — A single team can master a bounded context
  12. — As a user — I can add items to

    my cart — So that I may continue shopping
  13. — As a user — I can receive an email

    about my cart contents — So that I may remember to fulfill my order
  14. Acceptance Criteria — Given a user is inactive for x

    minutes — When they have products in their cart — Then send them a follow up email and emit an event
  15. Akka and DDD — Akka provides isolation around state —

    State can only be influenced through messaging — Actors are a perfect abstraction for aggregates
  16. Shopping Cart Example (Scala) def receive = { case AddItem(item)

    => // 1. accept a command persist(ItemAdded(item)) { // 2. create the event and persist contents += item // 3. apply the event emitEvent(ItemAdded(item)) // 4. emit the event } case AbandonSession => // 5. handle reminders emitEvent(SessionAbandoned) }
  17. Journal backed actors — Actors handle commands and queries —

    Events are generated from commands and journaled — The log is immutable and durable — Each actor is resilient without requiring databases
  18. Cluster Sharding (Java) — Distribute aggregates (actors) across several nodes

    in the cluster — Interact with aggregates using their logical identifier — Not care about their physical location in the cluster public CompletionStage updateCartItems(String userId, List<CartItem> cartItems) { return PatternsCS.ask( shardRegion, new UpdateCart(userId, cartItems), timeout); }
  19. Persistent Cart Actor (Java) @Override public Receive createReceive() { return

    receiveBuilder() .match(UpdateCart.class, msg -> { persist(msg, (UpdateCart m) -> { // apply the command setCartItems(m.getCartItems()); // tell the sender we're successful sender().tell("done", null); // TODO, emit an event to Kafka? }); }) .matchEquals(ReceiveTimeout.getInstance(), msg -> passivate()) .build(); }
  20. Onion architecture Onion architecture fits DDD perfectly. — Infrastructure →

    health checks, tracing, auth — API → routing, validations — Domain → bounded context — Core → aggregates
  21. Play structure Onion architecture lends well to Play package structures.

    !"" controllers !"" domain | !"" cart # | !"" api # | $"" core | !"" order # | !"" api # | $"" core | $"" product # !"" api # $"" core $"" infrastructure
  22. Decompose without destroying — The legacy system is never modified

    — Transaction scripts can be thousands of lines long and have numerous side effects! — Our worst case scenario with this approach is that we revert to an unmodified, still working legacy system
  23. Strangler pa!ern Named after the strangler vine that grows upward

    and around existing trees, “replacing” them. Goals: — Replace legacy functionality with the target system — Implement new functionality without modifying the existing system
  24. From Monolith to Microservices !"" domain !"" product #"" api

    | #"" Price.java | #"" Product.java | !"" ProductService.java !"" core !"" ProductServiceImpl.java
  25. What is Cloud Native? The Cloud Native Computing Foundation defines

    cloud native systems as: 1. Container packaged 2. Dynamically managed 3. Microservices oriented
  26. Business Value — Revisit prior assumptions through event storming —

    Transition to a target system without modifying your existing system — Gain cloud readiness incrementally — Get the most out of microservices (as a refactoring pattern) — Break the chains of the past
  27. Migrating Java to the Cloud Stop by the RedElastic booth

    for a free copy of our latest book from O'Reilly. — [email protected] — Twitter: @kvnwbbr — redelastic.com