Git Product home page Git Product logo

quarkus-coffeeshop-demo's Introduction

Coffeeshop Demo with Quarkus

Reactive Event Driven Example using Kafka.

Forked from here with openshift additions

This directory contains a set of demo around reactive in Quarkus with Kafka. It demonstrates the elasticity and resilience of the system.

coffee shop image

Build

mvn clean package

Prerequisites

Run Kafka Locally with:

docker-compose up

Then, create the orders topic with (need this for multiple partitions)

`./create-orders.sh`

On OpenShift - install the Strimzi Operator.

Run the demo

You need to run:

  • the coffee shop service
  • the HTTP barista
  • the Kafka barista

Im 3 terminals:

cd coffeeshop-service
mvn compile quarkus:dev
cd barista-http
mvn compile quarkus:dev
cd barista-kafka
mvn compile quarkus:dev

Execute with HTTP

The first part of the demo shows HTTP interactions:

  • Barista code: me.escoffier.quarkus.coffeeshop.BaristaResource
  • CoffeeShop code: me.escoffier.quarkus.coffeeshop.CoffeeShopResource.http
  • Generated client: me.escoffier.quarkus.coffeeshop.http.BaristaService

Important points:

  • Request-reply

Order coffees with:

curl -X POST -H "Content-Type: application/json" http://localhost:8080/http -d '{"product": "latte", "name": "clement"}'
curl -X POST -H "Content-Type: application/json" http://localhost:8080/http -d '{"product": "expresso", "name": "neo"}'
curl -X POST -H "Content-Type: application/json" http://localhost:8080/http -d '{"product": "mocha", "name": "flore"}'

Stop the HTTP Barista, you can't order coffee anymore.

Execute with Kafka

  • Barista code: me.escoffier.quarkus.coffeeshop.KafkaBarista: Read from orders, write to queue

  • Bridge in the CoffeeShop: me.escoffier.quarkus.coffeeshop.messaging.KafkaBaristas just enqueue the orders in a single thread (one counter)

  • Get prepared beverages on me.escoffier.quarkus.coffeeshop.dashboard.BoardResource and send to SSE

  • Open browser to http://localhost:8080/queue

  • Order coffee with:

curl -X POST -H "Content-Type: application/json" http://localhost:8080/messaging -d '{"product": "latte", "name": "clement"}'
curl -X POST -H "Content-Type: application/json" http://localhost:8080/messaging -d '{"product": "expresso", "name": "neo"}'
curl -X POST -H "Content-Type: application/json" http://localhost:8080/messaging -d '{"product": "mocha", "name": "flore"}'

Baristas do breaks

Stop the Kafka barista

Continue to enqueue order

curl -X POST -H "Content-Type: application/json" http://localhost:8080/messaging -d '{"product": "latte", "name": "clement"}'
curl -X POST -H "Content-Type: application/json" http://localhost:8080/messaging -d '{"product": "expresso", "name": "neo"}'
curl -X POST -H "Content-Type: application/json" http://localhost:8080/messaging -d '{"product": "mocha", "name": "flore"}'

On the dashboard, the orders are in the "IN QUEUE" state

Restart the barista

They are processed

2 baristas are better

Start a second barista with:

java -Dquarkus.http.port=9095 -Dbarista.name=tom -jar target/barista-kafka-1.0-SNAPSHOT-runner.jar

Order more coffee

curl -X POST -H "Content-Type: application/json" http://localhost:8080/messaging -d '{"product": "latte", "name": "clement"}'
curl -X POST -H "Content-Type: application/json" http://localhost:8080/messaging -d '{"product": "expresso", "name": "neo"}'
curl -X POST -H "Content-Type: application/json" http://localhost:8080/messaging -d '{"product": "mocha", "name": "flore"}'

The dashboard shows that the load is dispatched among the baristas.

OpenShift

On OpenShift - install the Strimzi Operator

./create-strimzi-openshift.sh

Install Topics

./create-topics-openshift.sh

Create project

oc new-project quarkus-coffee --description "Quarkus Coffee Shop" --display-name="Quarkus Coffee Shop"

Build Coffee Shop

cd coffeeshop-service
mvn package -Pnative -DskipTests -Dnative-image.docker-build=true

# binary
oc new-build --binary --name=coffeeshop-service -l app=coffeeshop-service
oc start-build coffeeshop-service --from-dir=. --follow
oc new-app coffeeshop-service
oc expose svc coffeeshop-service

Create Barista HTTP

cd barista-http
mvn package -Pnative -DskipTests -Dnative-image.docker-build=true

# binary
oc new-build --binary --name=barista-http -l app=barista-http
oc start-build barista-http --from-dir=. --follow
oc new-app barista-http

Create Barista Kafka

cd barista-kafka
mvn package -Pnative -DskipTests -Dnative-image.docker-build=true

oc new-build --binary --name=barista-kafka-julie -l app=barista-kafka-julie
ln -fs Dockerfile.julie Dockerfile
oc start-build barista-kafka-julie --from-dir=. --follow
oc new-app barista-kafka-julie

oc new-build --binary --name=barista-kafka-tom -l app=barista-kafka-tom
ln -fs Dockerfile.tom Dockerfile
oc start-build barista-kafka-tom --from-dir=. --follow
oc new-app barista-kafka-tom

Tekton S2I Build

Install Tekton Operator

./create-tekton-openshift.sh

Create application definitions

oc new-project quarkus-coffee --description "Quarkus Coffee Shop" --display-name="Quarkus Coffee Shop"
oc apply -f ./manifests.yaml

Build using tekton

oc project quarkus-coffee
PROJECT=$(oc project -q)
oc create serviceaccount pipeline
oc adm policy add-scc-to-user privileged -z pipeline
oc adm policy add-role-to-user edit -z pipeline
--
oc apply -f ./tekton/openshift-client-task.yaml
oc apply -f ./tekton/s2i-quarkus.yaml
--
cat <<EOF | oc apply -f -
apiVersion: tekton.dev/v1alpha1
kind: Pipeline
metadata:
  name: deploy-pipeline
spec:
  resources:
  - name: app-git
    type: git
  - name: app-image
    type: image
  tasks:
  - name: build-base
    taskRef:
      name: s2i-quarkus
    params:
      - name: TLSVERIFY
        value: "false"
    params:
      - name: PATH_CONTEXT
        value: "."
    resources:
      inputs:
      - name: source
        resource: app-git
      outputs:
      - name: image
        resource: app-image
  - name: build-cofeeshop-service
    taskRef:
      name: openshift-client  
    runAfter:
      - build-base
    params:
    - name: ARGS
      value:
       - start-build
       - coffeeshop-service
       - --wait
  - name: build-barista-http
    taskRef:
      name: openshift-client  
    runAfter:
      - build-base
    params:
    - name: ARGS
      value:
       - start-build
       - barista-http
       - --wait
  - name: barista-kafka-julie
    taskRef:
      name: openshift-client  
    runAfter:
      - build-base
    params:
    - name: ARGS
      value:
       - start-build
       - barista-kafka-julie
       - --wait
  - name: barista-kafka-tom
    taskRef:
      name: openshift-client  
    runAfter:
      - build-base
    params:
    - name: ARGS
      value:
       - start-build
       - barista-kafka-tom
       - --wait
  - name: deploy-cofeeshop-service
    taskRef:
      name: openshift-client
    runAfter:
      - build-cofeeshop-service
    params:
    - name: ARGS
      value:
       - rollout
       - latest
       - dc/coffeeshop-service
  - name: deploy-barista-http
    taskRef:
      name: openshift-client
    runAfter:
      - build-barista-http
    params:
    - name: ARGS
      value:
      - rollout
      - latest
      - dc/barista-http
  - name: deploy-barista-kafka-julie
    taskRef:
      name: openshift-client
    runAfter:
      - barista-kafka-julie
    params:
    - name: ARGS
      value:
      - rollout
      - latest
      - dc/barista-kafka-julie
  - name: deploy-barista-kafka-tom
    taskRef:
      name: openshift-client
    runAfter:
      - barista-kafka-tom
    params:
    - name: ARGS
      value:
      - rollout
      - latest
      - dc/barista-kafka-tom
EOF

cat <<EOF | oc apply -f -
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
  name: quarkus-coffeeshop-git
spec:
  type: git
  params:
  - name: url
    value: https://github.com/eformat/quarkus-coffeeshop-demo.git
EOF

cat <<EOF | oc apply -f -
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
  name: quarkus-coffeeshop-image
spec:
  type: image
  params:
  - name: url
    value: image-registry.openshift-image-registry.svc:5000/${PROJECT}/quarkus-coffeeshop-demo
EOF

-- can create multiple of these

cat <<EOF | oc create -f -
apiVersion: tekton.dev/v1alpha1
kind: PipelineRun
metadata:
  generateName: quarkus-coffeeshop-demo-deploy-pipelinerun-
spec:
  timeout: '60m'
  pipelineRef:
    name: deploy-pipeline
  serviceAccount: 'pipeline'
  resources:
  - name: app-git
    resourceRef:
      name: quarkus-coffeeshop-git
  - name: app-image
    resourceRef:
      name: quarkus-coffeeshop-image
EOF

OR you can start the pipeline using the CLI

tkn pipeline start deploy-pipeline \
        -r app-git=quarkus-coffeeshop-git \
        -r app-image=quarkus-coffeeshop-image \
        -s pipeline

Watch the pipeline logs using stern quarkus-coffeeshop-demo-deploy-pipelinerun-<random name>

S2I

If not using Tekton, you can use s2i

# s2i
oc new-build --name=quarkus-coffeeshop-demo -l app=quarkus-coffeeshop-demo quay.io/eformat/quarkus-native-s2i:graalvm-19.0.2~https://github.com/eformat/quarkus-coffeeshop-demo

# coffeeshop-service
oc new-build --name=coffeeshop-service \
    --docker-image=registry.access.redhat.com/ubi8/ubi:8.0 \
    --source-image=quarkus-coffeeshop-demo \
    --source-image-path='/home/quarkus/application-coffeeshop-service:.' \
    --dockerfile=$'FROM registry.access.redhat.com/ubi8/ubi:8.0\nCOPY application-coffeeshop-service /application\n\nEXPOSE 8080\nCMD ./application -Xmx10m -Xms10m -Xmn10m -XX:+PrintGC -XX:+VerboseGC -XX:+PrintGCTimeStamps +XX:+PrintHeapShape -Dquarkus.http.host=0.0.0.0 -Dme.escoffier.quarkus.coffeeshop.http.BaristaService/mp-rest/url=http://barista-http:8080 -Dmp.messaging.outgoing.orders.bootstrap.servers=my-cluster-kafka-bootstrap.strimzi.svc:9092 -Dmp.messaging.incoming.beverages.bootstrap.servers=my-cluster-kafka-bootstrap.strimzi.svc:9092 -Dmp.messaging.outgoing.queue.bootstrap.servers=my-cluster-kafka-bootstrap.strimzi.svc:9092' \
    --allow-missing-imagestream-tags
oc new-app --image-stream=coffeeshop-service -l app=coffeeshop-service
oc expose svc coffeeshop-service

# barista-http
oc new-build --name=barista-http \
    --docker-image=registry.access.redhat.com/ubi8/ubi:8.0 \
    --source-image=quarkus-coffeeshop-demo \
    --source-image-path='/home/quarkus/application-barista-http:.' \
    --dockerfile=$'FROM registry.access.redhat.com/ubi8/ubi:8.0\nCOPY application-barista-http /application\n\nEXPOSE 8080\nCMD ./application -Xmx10m -Xms10m -Xmn10m -XX:+PrintGC -XX:+VerboseGC -XX:+PrintGCTimeStamps +XX:+PrintHeapShape -Dquarkus.http.host=0.0.0.0 -Dquarkus.http.port=8080' \
    --allow-missing-imagestream-tags
oc new-app --image-stream=barista-http -l app=barista-http
oc expose svc barista-http

# barista-kafka-julie 
oc new-build --name=barista-kafka-julie \
    --docker-image=registry.access.redhat.com/ubi8/ubi:8.0 \
    --source-image=quarkus-coffeeshop-demo \
    --source-image-path='/home/quarkus/application-barista-kafka:.' \
    --dockerfile=$'FROM registry.access.redhat.com/ubi8/ubi:8.0\nCOPY application-barista-kafka /application\n\nEXPOSE 8080\nCMD ./application -Xmx10m -Xms10m -Xmn10m -XX:+PrintGC -XX:+VerboseGC -XX:+PrintGCTimeStamps +XX:+PrintHeapShape -Dbarista.name=julie -Dmp.messaging.incoming.orders.client.id=julie -Dmp.messaging.incoming.orders.bootstrap.servers=my-cluster-kafka-bootstrap.strimzi.svc:9092 -Dmp.messaging.outgoing.queue.bootstrap.servers=my-cluster-kafka-bootstrap.strimzi.svc:9092' \
    --allow-missing-imagestream-tags
oc new-app --image-stream=barista-kafka-julie -l app=barista-kafka-julie
oc expose svc barista-kafka-julie

# barista-kafka-tom
oc new-build --name=barista-kafka-tom \
    --docker-image=registry.access.redhat.com/ubi8/ubi:8.0 \
    --source-image=quarkus-coffeeshop-demo \
    --source-image-path='/home/quarkus/application-barista-kafka:.' \
    --dockerfile=$'FROM registry.access.redhat.com/ubi8/ubi:8.0\nCOPY application-barista-kafka /application\n\nEXPOSE 8080\nCMD ./application -Xmx10m -Xms10m -Xmn10m -XX:+PrintGC -XX:+VerboseGC -XX:+PrintGCTimeStamps +XX:+PrintHeapShape -Dbarista.name=tom -Dmp.messaging.incoming.orders.client.id=tom -Dmp.messaging.incoming.orders.bootstrap.servers=my-cluster-kafka-bootstrap.strimzi.svc:9092 -Dmp.messaging.outgoing.queue.bootstrap.servers=my-cluster-kafka-bootstrap.strimzi.svc:9092' \
    --allow-missing-imagestream-tags
oc new-app --image-stream=barista-kafka-tom -l app=barista-kafka-tom --allow-missing-imagestream-tags
oc expose svc barista-kafka-tom

Test OpenShift

Tail Coffee Shop

oc logs $(oc get pods -l app=coffeeshop-service -o name) -f

OR

stern coffeeshop-service

Tail Barista HTTP

oc logs $(oc get pods -l app=barista-http -o name) -f

OR

stern barista-http

Order Coffee via synchronous http

export SHOPURL=$(oc get route coffeeshop-service -n quarkus-coffee --template='{{ .spec.host }}')
./order-coffees-serial-http.sh

Tail Barista Kafka

oc logs $(oc get pods -l app=barista-kafka-julie -o name) -f

OR 

stern barista-kafka-julie

oc logs $(oc get pods -l app=barista-kafka-tom -o name) -f

OR

stern barista-kafka-tom

Order Coffee kafka

export SHOPURL=$(oc get route coffeeshop-service -n quarkus-coffee --template='{{ .spec.host }}')
./order-coffees.sh

Order lots more coffee

while true; do ./order-coffees.sh; sleep 0.5; done

quarkus-coffeeshop-demo's People

Contributors

eformat avatar cescoffier avatar

Watchers

James Cloos avatar  avatar

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.