This repository contains a sample project that I and some teammates are using to practice event driven programming.
The intention of this project is to simulate a 'Chair company' as it shifts from a tightly coupled set of services to a Message Driven approach. Each branch in this repo will be numerated and build on the previous. The 'task at hand' section below will change
Working with this project requires the following technologies:
- Java 11+ (install using sdkman)
- Docker - a recentish version
- Minikube + kubectl - both are available via homebrow for Mac users.
Note: most of these steps should be done in terminal window 1
, with the exception of building the repos (terminal window 2
) and running the minikube tunnel (terminal window 3
).
minikube start
minikube addons enable ingress
eval $(minikube -p minikube docker-env)
kubectl apply -f shared.yaml
- build the repos (in
terminal window 2
: cd into the sub folders and./gradlew build
) - build the docker images:
docker build -t eventclub/chair-admin admin/.
anddocker build -t eventclub/chairfront chairfront/.
Note: ensure you've run the eval command above, first. This scopes your terminal window to use Minikube's docker environment and not your laptop's. This also means that builds of the apps should be done in another terminal (terminal window 2
). kubectl apply -f jobs.yaml
kubectl apply -f chairfront/kubernetes.yaml
kubectl apply -f admin/kubernetes.yaml
minikube tunnel
(interminal window 3
)
You should now be able to use commands like kubectl get svc
to see the public ips of the two java services (e.g. localhost:8001).
minikube delete
- trash your environment and start overkubectl get pods
- see all your running pods, a great way to spot check everything's workingkubectl logs <pod>
- ideal for spot checking that things are workingminikube dashboard
- or just spawn the UI to peek into the systemkubectl rollout restart deployment <deployment name>
- used after you update an app and rebuild the docker image, restart all pods
- make changes in your java app
- test using
./gradlew clean test
interminal window 2
- package via
./gradlew build
interminal window 2
- jars should appear in./build/libs
- build the docker images
- rolling restart the deployment
Welcome to the Chair Company! We sell chairs of all types. As of now we have two services:
admin
orchairs-admin
: The main API for administration of our platform. Intended to be used by administrators to create and report on our 'Chair' domain objects. It's main endpoint is/chairs
, refer to theevent.club.admin.http.ChairController
for more info.chairfront
: the Customer - oriented api. Will show which types of 'Chairs' we have, if any. It's main endpoint is/catalog
, refer toevent.club.chairfront.http.CatalogController
for more info.
We do not and will never have a UI. API only / use Postman!
Our admins POST data to /chairs on the admin service in order to create new Chair types. The admin service then notifies Chairfront of this new type, although chairfront does not receive inventory information (yet) so there may not be anything to sell.
The problem is that we have a tight coupling between the Admin service and Chairfront, and Chairfront is slow. Our admin users are starting to complain. What can we do?
We want to see if making this call Asynchronous provides better performance in the near term. (We need to crawl before we can run) Research mechanisms on how to execute asynchronous behaviors within Java. For example, Completable Futures seem promising, as do tools like RxJava.
Basic Challenge: Update the Admin service so that it's call to Chairfront is now done asynchronously.
Advanced Challenge: Write an Integration test to prove it.