Coder Social home page Coder Social logo

sos's Introduction

Refactoring to a System of Systems

NOTE: This is currently highly work in progress. Be sure to check out every now and then for more detailed information and explanations about the individual modules.

This repository contains some sample code for my talk "Refactoring to a System of Systems" that outlines what problems developers can run into if they split up a system into multiple ones but transfer interaction patterns of typical monolithic applications as is. Slides of that talk and a recording of it will be linked here as soon as they become available.

The repository contains five different projects, each of them potentially split into multiple ones in turn. For details on the individual ones, please refer to the READMEs conatined in the individual project's root.

Context

The sample application is built around an e-commerce domain with the following Bounded Contexts:

  • Catalog - containing product master data (in our case product name and price).
  • Inventory - keeping track of the number of available items per product.
  • Order - keeping track of orders placed by customers.

Domain

The individual modules provide sketch implementations of these Bounded Context and the following interactions between them implemented:

  1. When a product is added, the inventory needs to register empty stock for that product.
  2. When an order is completed, the inventory needs to update the stock for the products ordered.

Modules

  • The Monolith - a typical monolithic Spring Boot application with the Bounded Contexts implemented in packages and the interaction being based on active invocations of Spring beans residing in a different BC.
  • The Microlith - the former approach transferred into separate systems but keeping the same interaction patter of synchronous, non-idempotent operations. The systems invoking each other via HTTP calls.
  • The Modulith - an improved version of the monolith with the Bounded Contexts interacting via Spring application events and event listeners.
  • SOS Messaging - the individual Bounded Contexts implemented as separate systems and the interaction implemented via a Kafka message broker.
  • SOS REST - the individual Bounded Contexts implemented as separate systems and the interaction implemented via the events exposed as REST resources.

Project structure

Build

The repository should build by simply running ./mvnw clean install using a recent JDK 8. Sample code uses Lombok, which means that you need a Lombok-enabled IDE in case you want to import the projects into it. For detailed instructions about how to work with the individual projects, see the individual module's READMEs.

sos's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sos's Issues

Improvements to avoid out-of-order events / lost events in sos-restful

Hello Oliver,
at first, thanks a lot for the comprehensive example and for your efforts to bring more support for DDD into Spring (Data).
I have a suggestion for some minor improvements of sos-restful regarding event timestamps: Currently the timestamp is set in the constructor for the event. In case a transaction takes a bit longer than another one, it might happen that an event with an "earlier" timestamp is seen later by other transactions. That is, we get out-of-order events. Even worse, if a consumer polls between the commit of the first and the second transaction, it might miss the out-of-order event at all, since it has already stored the later timestamp in its database and will never query for "earlier" events again.
To solve this problem, we would need to store the "timestamp of the transaction commit" in the event. However... there is no such thing in JPA (or even in SQL) at all.
But I think, with some simple changes, we can get very close to that:

  • PersistingEventListener could be @TransactionalEventListener with phase "BEFORE_COMMIT", to get as close as possible to the commit
  • PersistingEventListener should perform a flush before persisting the event(s) to make sure most of the SQL work is done before. Again this is to get as close as possible to the commit.
  • Instead of a timestamp, a database sequence should be used. JVM time can be different on each node and even database time might not be reliable (see comment below)
  • The flush in combination with @TransactionalEventListener will make sure that Hibernate does not rearrange the SQL Statements in a way where the sequence number is retrieved before the insert statement(s) for the aggregate are executed. Instead it will be retrieved as close to the commit as possible. Since the aggreagte is locked in the database by the insert statement, there is no danger that some "faster" transaction will commit an event (with a higher sequence number) for the same aggregate meanwhile.

Compilation fails since Upgrade to Spring Boot 2.1.

My configuration:

$ JAVA_HOME=`/usr/libexec/java_home -v 1.8` ./mvnw --version
Apache Maven 3.5.2 (138edd61fd100ec658bfa2d307c43b76940a5d7d; 2017-10-18T09:58:13+02:00)
Maven home: /Users/kristof/.m2/wrapper/dists/apache-maven-3.5.2-bin/28qa8v9e2mq69covern8vmdkj0/apache-maven-3.5.2
Java version: 1.8.0_171, vendor: Oracle Corporation
Java home: /Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre
Default locale: en_BE, platform encoding: UTF-8
OS name: "mac os x", version: "10.14", arch: "x86_64", family: "mac"

Compilation fails since the last commit was added:

$ JAVA_HOME=`/usr/libexec/java_home -v 1.8` ./mvnw clean compile
...
[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR : 
[INFO] -------------------------------------------------------------
[ERROR] /Users/kristof/Projects/Devoxx2018/sos/30-messaging-sos/broker/src/main/java/example/sos/messaging/broker/MessagingConfiguration.java:[32,25] cannot access org.junit.rules.TestRule
  class file for org.junit.rules.TestRule not found
...

Compilation worked before this last change:

$ git checkout 371134d
$ JAVA_HOME=`/usr/libexec/java_home -v 1.8` ./mvnw clean compile
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

Cannot construct instance of OrderCompleted

After running mvc clean install I get the following error. The solution is simply to put @JsonCreator annotation.

-------------------------------------------------------------------------------
Test set: example.sos.modulith.orders.EmailNotificationTest
-------------------------------------------------------------------------------
Tests run: 2, Failures: 1, Errors: 1, Skipped: 0, Time elapsed: 1.026 s <<< FAILURE! - in example.sos.modulith.orders.EmailNotificationTest
completingAnOrderUpdatesInventory(example.sos.modulith.orders.EmailNotificationTest)  Time elapsed: 0.147 s  <<< ERROR!
java.lang.RuntimeException: 
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `example.sos.modulith.orders.Order$OrderCompleted` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (String)"{"order":{"id":13,"lineItems":[{"id":null,"product":{"id":1,"name":"iPad Pro","price":799.99},"amount":5}],"status":"SUBMITTED"}}"; line: 1, column: 2]
	at example.sos.modulith.orders.EmailNotificationTest.lambda$completingAnOrderUpdatesInventory$0(EmailNotificationTest.java:58)
	at example.sos.modulith.orders.EmailNotificationTest.completingAnOrderUpdatesInventory(EmailNotificationTest.java:58)
Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: 
Cannot construct instance of `example.sos.modulith.orders.Order$OrderCompleted` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (String)"{"order":{"id":13,"lineItems":[{"id":null,"product":{"id":1,"name":"iPad Pro","price":799.99},"amount":5}],"status":"SUBMITTED"}}"; line: 1, column: 2]
	at example.sos.modulith.orders.EmailNotificationTest.lambda$completingAnOrderUpdatesInventory$0(EmailNotificationTest.java:58)
	at example.sos.modulith.orders.EmailNotificationTest.completingAnOrderUpdatesInventory(EmailNotificationTest.java:58)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.