• Stars
    star
    107
  • Rank 323,587 (Top 7 %)
  • Language
    Java
  • License
    Apache License 2.0
  • Created about 8 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

CQRS with Domain-Driven Design and Event Sourcing using Apache Kafka and Server-Side-Events

CQRS and Event Sourcing Implementation with Kafka and MySQL (JBDC)

Introduction

The aim of this small project is to illustrate the possibility of applying CQRS, Domain-Driven Design and Event Sourcing in a simple way, enabling Reactive architecture and leveraging Kafka as a distributed message broker

See: https://speakerdeck.com/vgoldin/es-and-kafka

Structure

Module Purpose
services-core core marker interfaces shared between all other modules
services-infrastructure-eventstore multiple event store implementations (JDBM 2.0 and MySQL JDBC)
services-infrastructure-messaging event publisher and command listener implementation with Kafka
services-intentoryitem-schema json-schema's of all the events and commands used in API and Domain services
services-inventoryitem-api API micro-service, exposing RESTfull API, creating Projectin with Hazelcast and dispatching commands to Kafka
services-inventoryitem-domain Domain micro-service, encapsulating Aggregate Root, handling commands and publishing events

Pre-Requisites

  • JDK
  • Maven
  • (optional) Docker (for Kafka)

Modifying

services-inventoryitem-api and services-inventoryitem-domain modules are referencing events and commands that are defined in the services-intentoryitem-schema module as JSON.

Java source files are generated in each module that depend on these classes. This is done to avoid runtime dependency. Source files are generated as part of the mvn install cycle and are placed in the target/java-gen folder of each corresponding module.

In order to resolve all the references, this folder needs to be added as an additional java source files directory in your favorite IDE.

Building

mvn clean install

Running Services

Docker Compose

docker-compose build
docker-compose up -d

Standalone

Kafka

docker run -p 2181:2181 -p 9092:9092 --env ADVERTISED_HOST=127.0.0.1 --env ADVERTISED_PORT=9092 spotify/kafka

API Micro-Service

cd services-inventoryitem-api/target
java -jar services-inventoryitem-api-1.0-SNAPSHOT.jar server classes/application-local.yml

Domain Micro-Service

with local jdbm database

cd services-inventoryitem-domain/target
java -jar services-inventoryitem-domain-1.0-SNAPSHOT.jar server classes/application.yml

with MySQL running on 127.0.0.1:3306 (see docker-compose.yml)

cd services-inventoryitem-domain/target
java -jar services-inventoryitem-domain-1.0-SNAPSHOT.jar server classes/application-jdbc.yml

Exposed APIs

GET     /inventory-items (io.plumery.inventoryitem.api.resources.InventoryItemResource)
POST    /inventory-items (io.plumery.inventoryitem.api.resources.InventoryItemResource)
GET     /inventory-items/events.stream (io.plumery.inventoryitem.api.resources.InventoryItemResource)
PUT     /inventory-items/{id} (io.plumery.inventoryitem.api.resources.InventoryItemResource)
POST    /inventory-items/{id}/deactivate (io.plumery.inventoryitem.api.resources.InventoryItemResource)

Swagger API

http://localhost:9901/swagger.json

Replaying Projection

  • Download and unzip Kafka
  • Change to KAFKA_HOME
  • Stop API Micro-Service
  • Execute the following command:
./bin/kafka-streams-application-reset.sh --application-id InventoryItemsDenormalizationApplication \
                                      --input-topics InventoryItem \
                                      --bootstrap-servers localhost:9092 \
                                      --zookeeper localhost:2181

TODO

  • Get rid of ID.class
  • Generate all the events and commands from JSON schema
  • Implement UI Micro-Service