{"id":21369180,"url":"https://github.com/sshaaf/coolstore-knative","last_synced_at":"2026-04-19T03:31:05.064Z","repository":{"id":205168127,"uuid":"713559989","full_name":"sshaaf/coolstore-knative","owner":"sshaaf","description":"This is a demo repo showcasing the use of knative with KEDA in an shopping store order processing scenario. most of the source code is written using Quarkus.","archived":false,"fork":false,"pushed_at":"2023-12-08T10:13:05.000Z","size":5061,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-29T16:57:11.695Z","etag":null,"topics":["java","keda","knative","kubernetes","nodejs","nodeshift","openshift","quarkus"],"latest_commit_sha":null,"homepage":"","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sshaaf.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-11-02T19:10:46.000Z","updated_at":"2023-12-09T10:51:23.000Z","dependencies_parsed_at":"2024-11-22T07:41:08.750Z","dependency_job_id":null,"html_url":"https://github.com/sshaaf/coolstore-knative","commit_stats":null,"previous_names":["sshaaf/coolstore-quarkus-serverless","sshaaf/coolstore-kubecon-knative-demo","sshaaf/coolstore-knative"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sshaaf/coolstore-knative","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sshaaf%2Fcoolstore-knative","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sshaaf%2Fcoolstore-knative/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sshaaf%2Fcoolstore-knative/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sshaaf%2Fcoolstore-knative/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sshaaf","download_url":"https://codeload.github.com/sshaaf/coolstore-knative/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sshaaf%2Fcoolstore-knative/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31993639,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T20:23:30.271Z","status":"online","status_checked_at":"2026-04-19T02:00:07.110Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["java","keda","knative","kubernetes","nodejs","nodeshift","openshift","quarkus"],"created_at":"2024-11-22T07:30:58.324Z","updated_at":"2026-04-19T03:31:05.019Z","avatar_url":"https://github.com/sshaaf.png","language":"HTML","readme":"\n![Alt text](./docs/images/overview.svg)\n\nThis is a demo repository. The demo walks through a modernization scenario where a developer has already broken down the architecture into microservices. How can they leverage the Knative project and further enhance that with the KEDA. How does the interaction work under scale. We also outline the differences and when to use which technology.\nA Coolstore app where users can buy some cool merchandise.\n\n\n- The UI is built with NodeJS and Angular. And the backend includes multiple services. such as\n- *Inventory* , The stores inventory, how much items are available etc. \n- *Catalog* , The products API\n- *Cart*, Stores all users carts and intiates the order process by sending a message to Orders\n- *Orders*, Completion and checking of orders\n- *Payments*, Checks whether an payment is successfull given a certain Credit Card. \n\nThe demo is simple. Add an item to the cart. Checkout the item by going to the `Cart` tab. Add payment details. If the Card number starts with 4 the payment is successful else it will show status failed. this is a hard check in the payment service. \nOnce done, goto the `Orders` tab. The Order status should be `In Progress`, refresh after a couple of seconds and the status will appear as `COMPLETED` or `FAILED`. It takes a couple of seconds as their is a wait timer in Payment service + the whole process is done in a reactive and event driven way using Kafka and Quarkus.\n\n\n\n![Alt text](./docs/images/coolstore-ui.png)\n\n## Setup\nDeploying the operators required for this demo.\n```yaml\n# These are the operators that need to be installed\n\n# OpenShift Serverless operator\napiVersion: operators.coreos.com/v1alpha1\nkind: Subscription\nmetadata:\n  name: serverless-operator\n  namespace: openshift-operators\nspec:\n  channel: stable\n  installPlanApproval: Automatic\n  name: serverless-operator\n  source: redhat-operators\n  sourceNamespace: openshift-marketplace\n---\napiVersion: v1\nkind: Namespace\nmetadata:\n  name: openshift-keda\n  labels:\n    name: openshift-keda\n---\napiVersion: operators.coreos.com/v1\nkind: OperatorGroup\nmetadata:\n  name: openshift-keda\n  namespace: openshift-keda\nspec:\n  targetNamespaces:\n  - openshift-keda\n---\n# Custom Metrics Autoscaler operator\napiVersion: operators.coreos.com/v1alpha1\nkind: Subscription\nmetadata:\n  name: openshift-custom-metrics-autoscaler-operator\n  namespace: openshift-keda\nspec:\n  channel: stable\n  installPlanApproval: Automatic\n  name: openshift-custom-metrics-autoscaler-operator\n  source: redhat-operators\n  sourceNamespace: openshift-marketplace\n---\n# AMQ Streams operator\napiVersion: operators.coreos.com/v1alpha1\nkind: Subscription\nmetadata:\n  name: amq-streams\n  namespace: openshift-operators\nspec:\n  channel: stable\n  installPlanApproval: Automatic\n  name: amq-streams\n  source: redhat-operators\n  sourceNamespace: openshift-marketplace\n```\n\nDeploying the CRs for the Operators\n\n```yaml\n---\n# Set up Knative serving\napiVersion: operator.knative.dev/v1beta1\nkind: KnativeServing\nmetadata:\n  name: knative-serving\n  namespace: knative-serving\nspec: {}\n---\n# Set up Knative eventing\nkind: KnativeEventing\napiVersion: operator.knative.dev/v1beta1\nmetadata:\n  name: knative-eventing\n  namespace: knative-eventing\nspec: {}\n---\napiVersion: operator.serverless.openshift.io/v1alpha1\nkind: KnativeKafka\nmetadata:\n  name: knative-kafka\n  namespace: knative-eventing\nspec:\n  broker:\n    enabled: false\n  channel:\n    enabled: false\n  sink:\n    enabled: true\n  source:\n    enabled: true\n---\n# Set up custom metrics autoscaler\napiVersion: v1\nkind: Namespace\nmetadata:\n  name: openshift-keda\n---\nkind: KedaController\napiVersion: keda.sh/v1alpha1\nmetadata:\n  name: keda\n  namespace: openshift-keda\nspec:\n  watchNamespace: ''\n  operator:\n    logLevel: info\n    logEncoder: console\n  metricsServer:\n    logLevel: '0'\n  serviceAccount: {}\n```\n\nDeploying Kafka for communication between services. \n```yaml\nkind: Kafka\napiVersion: kafka.strimzi.io/v1beta2\nmetadata:\n  name: my-cluster\n  namespace: YOURNAMESPACE\nspec:\n  kafka:\n    replicas: 3\n    listeners:\n      - name: plain\n        port: 9092\n        type: internal\n        tls: false\n      - name: tls\n        port: 9093\n        type: internal\n        tls: true\n    config:\n      offsets.topic.replication.factor: 3\n      transaction.state.log.replication.factor: 3\n      transaction.state.log.min.isr: 2\n      default.replication.factor: 3\n      min.insync.replicas: 2\n    storage:\n      type: ephemeral\n  zookeeper:\n    replicas: 3\n    storage:\n      type: ephemeral\n  entityOperator:\n    topicOperator: {}\n    userOperator: {}\n---\nkind: KafkaTopic\napiVersion: kafka.strimzi.io/v1beta2\nmetadata:\n  name: orders\n  labels:\n    strimzi.io/cluster: my-cluster\n  namespace: YOURNAMESPACE\nspec:\n  partitions: 10\n  replicas: 3\n  config:\n    retention.ms: 604800000\n    segment.bytes: 1073741824\n---\nkind: KafkaTopic\napiVersion: kafka.strimzi.io/v1beta2\nmetadata:\n  name: payments\n  labels:\n    strimzi.io/cluster: my-cluster\n  namespace: YOURNAMESPACE\nspec:\n  partitions: 10\n  replicas: 3\n  config:\n    retention.ms: 604800000\n    segment.bytes: 1073741824    \n    \n```\n\n\n\n## Deployment\nThe deployment is done via the sourcecode. you will need \n- Apache Maven  \n- Java 17 or above\n- Node version 16\n- Graal VM - 23 or above (This can be skipped if the payment service is not compiled into Native)\n\n\n![Alt text](./docs/images/deployment.png)\n\n### Inventory\nCreate the postgresql inventory database to store inventory data. Once the inventory service is deployed it will create default entires in the database. The SQL can be found in src/main/resources/import.sql\n```\noc new-app -e POSTGRESQL_USER=inventory -e POSTGRESQL_PASSWORD=mysecretpassword -e POSTGRESQL_DATABASE=inventory openshift/postgresql:latest --name=inventory-database\n```\n\nBuild and deploy the inventory service to OpenShift namespace.\n```\nmvn clean compile package -DskipTests -f inventory-service\n```\nApply application grouping labels (Optional)\n```\noc label dc/inventory app.kubernetes.io/part-of=inventory --overwrite \u0026\u0026 \\\noc label dc/inventory-database app.kubernetes.io/part-of=inventory app.openshift.io/runtime=postgresql --overwrite \u0026\u0026 \\\noc annotate dc/inventory app.openshift.io/connects-to=inventory-database --overwrite \u0026\u0026 \\\noc annotate dc/inventory app.openshift.io/vcs-ref=ocp-4.13 --overwrite\n```\nThe inventory service has a UI for all data in the inventory via http only\n![Alt text](./docs/images/coolstore-inventory.png)\n\n\n### Catalog\nCreate database for storing the catalog entries, the Catalog entries are created once the service is deployed. you can find them in schema.sql in the catalog-service source/java/resources\n```\noc new-app -e POSTGRESQL_USER=catalog -e POSTGRESQL_PASSWORD=mysecretpassword -e POSTGRESQL_DATABASE=catalog openshift/postgresql:latest --name=catalog-database\n```\nBuild and deploy the Catalog service to our OpenShift namespace\n```\nmvn clean install -Ddekorate.deploy=true -DskipTests -f catalog-service\n```\nApply application grouping labels (Optional)\n```\noc label dc/catalog app.kubernetes.io/part-of=catalog app.openshift.io/runtime=spring-boot --overwrite \u0026\u0026 \\\noc label dc/catalog-database app.kubernetes.io/part-of=catalog app.openshift.io/runtime=postgresql --overwrite \u0026\u0026 \\\noc annotate dc/catalog app.openshift.io/connects-to=inventory,catalog-database --overwrite \u0026\u0026 \\\noc annotate dc/catalog app.openshift.io/vcs-uri=https://github.com:sshaaf/coolstore-knative.git --overwrite \u0026\u0026 \\\noc annotate dc/catalog app.openshift.io/vcs-ref=ocp-4.13 --overwrite\n```\nThe catalot service has a UI for all data in the catalog via http only\n![Alt text](./docs/images/catalog.png)\n\n###  Cart\nCreate an Infinispan cache server (single instance) for caching the user carts.\n```\noc new-app --as-deployment-config quay.io/openshiftlabs/ccn-infinispan:12.0.0.Final-1 --name=datagrid-service -e USER=user -e PASS=pass\n```\nBuild and deploy the Cart service to OpenShift namespace\n```\nmvn clean package -DskipTests -f cart-service\n```\n\nApply application grouping labels (Optional)\n```\noc label dc/cart app.kubernetes.io/part-of=cart app.openshift.io/runtime=quarkus --overwrite \u0026\u0026 \\\noc label dc/datagrid-service app.kubernetes.io/part-of=cart app.openshift.io/runtime=datagrid --overwrite \u0026\u0026 \\\noc annotate dc/cart app.openshift.io/connects-to=catalog,datagrid-service --overwrite \u0026\u0026 \\\noc annotate dc/cart app.openshift.io/vcs-ref=ocp-4.13 --overwrite\n```\n\nThe cart service also deploys a swagger UI under the following path `/q/swagger-ui/`\n![Alt text](./docs/images/cart-swagger-ui.png)\n\n\n### Orders\nCreate an a mongodDB instance to store orders. \n```\noc new-app --as-deployment-config --docker-image quay.io/openshiftlabs/ccn-mongo:4.0 --name=order-database\n```\n\nBuilding and deploying the Orders service. \n```\nmvn clean package -DskipTests -f order-service\n```\n\nAdding labels for application grouping (optional)\n```\noc label dc/order app.kubernetes.io/part-of=order --overwrite \u0026\u0026 \\\noc label dc/order-database app.kubernetes.io/part-of=order app.openshift.io/runtime=mongodb --overwrite \u0026\u0026 \\\noc annotate dc/order app.openshift.io/connects-to=order-database --overwrite \u0026\u0026 \\\noc annotate dc/order app.openshift.io/vcs-ref=ocp-4.13 --overwrite\n```\ndetails of all orders can also be seen via the REST endpoint at `/api/orders`\n\n\n### Coolstore-ui\n\nInstall NodeShift so it can deploy the frontend to OpenShift\n\n```\nmore .nvmrc\ncd coolstore-ui \nnpm ci\n```\n\nDeploy to OpenShift and set labels\n```\nnpm run nodeshift \u0026\u0026 oc expose svc/coolstore-ui \u0026\u0026 \\\noc label dc/coolstore-ui app.kubernetes.io/part-of=coolstore --overwrite \u0026\u0026 \\\noc annotate dc/coolstore-ui app.openshift.io/connects-to=order-cart,catalog,inventory,order --overwrite \u0026\u0026 \\\noc annotate dc/coolstore-ui app.openshift.io/vcs-uri=https://github.com:sshaaf/coolstore-knative.git --overwrite \u0026\u0026 \\\noc annotate dc/coolstore-ui app.openshift.io/vcs-ref=ocp-4.13 --overwrite\n```\n\n### Payment\n\nChange the following in the application.properties to the namespace the coolstore is being deployed in\n```\nquarkus.container-image.group=user2-cloudnativeapps\n```\n\ncreating a native image with GraalVM and deploying it to our namespace.\n```\nmvn clean package -Pnative -DskipTests -f payment-service\n```\n\n#### Using Knative Eventing and KEDA\n\nUse the following CR for the Knative Eventing with the payments service.\n```yaml\napiVersion: sources.knative.dev/v1beta1\nkind: KafkaSource\nmetadata:\nname: kafka-source\nspec:\nconsumerGroup: knative-group\nbootstrapServers:\n- my-cluster-kafka-bootstrap.YOURNAMESPACE:9092\n  topics:\n- orders\n  sink:\n  ref:\n  apiVersion: serving.knative.dev/v1\n  kind: Service\n  name: payment\n```\n\n\n\nThe following CR is used for KEDA and Payment service\n```yaml\napiVersion: sources.knative.dev/v1beta1\nkind: KafkaSource\nmetadata:\n  name: kafka-source\n  namespace: user2-cloudnativeapps\n  annotations:\n    autoscaling.knative.dev/class: keda.autoscaling.knative.dev\n    autoscaling.knative.dev/minScale: \"0\" \n    autoscaling.knative.dev/maxScale: \"10\" \n    keda.autoscaling.knative.dev/pollingInterval: \"10\"\n    keda.autoscaling.knative.dev/cooldownPeriod: \"10\"\n    keda.autoscaling.knative.dev/kafkaLagThreshold: \"10\"\nspec:\n  consumerGroup: knative-group\n  bootstrapServers:\n    - my-cluster-kafka-bootstrap.user2-cloudnativeapps:9092\n  topics:\n    - orders\n  sink:\n    ref:\n      apiVersion: serving.knative.dev/v1\n      kind: Service\n      name: payment\n```","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsshaaf%2Fcoolstore-knative","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsshaaf%2Fcoolstore-knative","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsshaaf%2Fcoolstore-knative/lists"}