{"id":15816559,"url":"https://github.com/lbroudoux/knative-user-registration","last_synced_at":"2025-04-01T03:42:47.372Z","repository":{"id":145929764,"uuid":"316549886","full_name":"lbroudoux/knative-user-registration","owner":"lbroudoux","description":"A demonstration on Knative serving and eventing using Quarkus powered apps","archived":false,"fork":false,"pushed_at":"2022-03-30T09:16:10.000Z","size":1093,"stargazers_count":1,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-10-06T05:05:22.518Z","etag":null,"topics":["kafka","knative","kubernetes","openshift","serverless"],"latest_commit_sha":null,"homepage":"","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lbroudoux.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2020-11-27T16:26:02.000Z","updated_at":"2022-03-30T09:16:14.000Z","dependencies_parsed_at":null,"dependency_job_id":"755f40ec-880a-4070-9514-1d811d2f7db1","html_url":"https://github.com/lbroudoux/knative-user-registration","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lbroudoux%2Fknative-user-registration","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lbroudoux%2Fknative-user-registration/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lbroudoux%2Fknative-user-registration/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lbroudoux%2Fknative-user-registration/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lbroudoux","download_url":"https://codeload.github.com/lbroudoux/knative-user-registration/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246580461,"owners_count":20800108,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["kafka","knative","kubernetes","openshift","serverless"],"created_at":"2024-10-05T05:05:21.350Z","updated_at":"2025-04-01T03:42:47.351Z","avatar_url":"https://github.com/lbroudoux.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Knative user-registration\n\nThis repository holds source code for a demonstration of Knativce Serverless capabilities on OpenShift. It demonstrates basic features of Knative Serving and Eventing modules.\n\nHere's the architecture of the application we're going to deploy and managed with Knative:\n\n![Architecture](assets/architecture.png)\n\nThe application is made of following components:\n* A `user-registration` microservice that is presenting a REST API for registering new users into a system,\n* A Kafka broker that aims to persist the different events emitted by the `user-registration` component on registrations,\n* A bunch of event-driven components that consumes events from Kafka to process the registration events.\n\nIn the demonstration scenario, we are going to deploy 2 differents revisions of the `user-registration` service to illustrate traffic distribution and canary release using Knative. Also we're going to use Knative Eventing concepts (`Source`, `Channel` and `Subscription`) to make the events consumers serverless too.\n\n### Setup\n\n\u003e This current version of the demo was updated for OpenShift 4.9+ cluster. It was initially created at OpenShift 4.5+/4.6 time. It you're running an older version, please navigate to the `/openshift-4.6` folder where you'll find previous version of this README.\n\nSo you should have an OpenShift 4.9+ cluster (or a Kubernetes one but it's trickier to setup) with the different features enabled:\n\n* Strimzi.io Operator up and running for providing a Kafka broker to the app,\n* Knative Serving and Eventing installed and deployed in their own namespaces, as well as a `KnativeKafka` resource created in `knative-eventing` with `spec.source.enabled` set to `true`\n\nYou should also have the `kn` CLI tool available on your laptop or bastion server:\n\n```sh\n$ kn version\nVersion:      v20201110-e8b26e18\nBuild Date:   2020-11-10 10:39:27\nGit Revision: e8b26e18\nSupported APIs:\n* Serving\n  - serving.knative.dev/v1 (knative-serving v0.18.0)\n* Eventing\n  - sources.knative.dev/v1alpha2 (knative-eventing v0.18.0)\n  - eventing.knative.dev/v1beta1 (knative-eventing v0.18.0)\n```\n\nStart creating the new project to host our components and the dedicated broker:\n\n```sh\noc new-project user-registration-serverless\noc create -f kafka-broker-openshift.yml -n user-registration-serverless\n```\n\n### Demonstration\n\n#### Knative Serving\n\nDeploy version `v1` of the `user-registration`:\n\n```\n$ kn service create user-registration --image quay.io/microcks/quarkus-user-registration:0.1 --env QUARKUS_PROFILE=kube --port 8383 -n user-registration-serverless\nCreating service 'user-registration' in namespace 'user-registration-serverless':\n\n  0.039s The Configuration is still working to reflect the latest desired specification.\n  0.106s The Route is still working to reflect the latest desired specification.\n  0.229s Configuration \"user-registration\" is waiting for a Revision to become ready.\n  9.660s ...\n  9.749s Ingress has not yet been reconciled.\n  9.850s unsuccessfully observed a new generation\n 10.021s Ready to serve.\n\nService 'user-registration' created to latest revision 'user-registration-wjhqk-1' is available at URL:\nhttp://user-registration-user-registration-serverless.apps.cluster-7eee.7eee.example.opentlc.com\n\n$ kn service update user-registration --tag user-registration-wjhqk-1=v1\nUpdating Service 'user-registration' in namespace 'user-registration-serverless':\n\n  0.031s The Route is still working to reflect the latest desired specification.\n  0.114s Ingress has not yet been reconciled.\n  0.136s unsuccessfully observed a new generation\n  0.511s Ready to serve.\n\nService 'user-registration' with latest revision 'user-registration-wjhqk-1' (unchanged) is available at URL:\nhttp://user-registration-user-registration-serverless.apps.cluster-7eee.7eee.example.opentlc.com\n\n$ export APP_URL=`oc get ksvc user-registration -o json -n user-registration-serverless | jq -r '.status.url'`\n```\n\nPlay with App through CURL command, registering new users and see the Pods scaling-up and down:\n\n```sh\n$ curl -XPOST $APP_URL/register -H 'Content-type: application/json' -d '{\"fullName\":\"Laurent Broudoux\",\"email\":\"laurent.broudoux@gmail.com\",\"age\":43}' -s | jq .\n{\n  \"age\": 43,\n  \"email\": \"laurent.broudoux@gmail.com\",\n  \"fullName\": \"Laurent Broudoux\",\n  \"id\": \"c637a5f8-ecfe-45be-b44d-69bf08043603\"\n}\n```\n\nWe've got `v1` responses so far with just 4 properties in the response. Deploy version `v2` that adds a new property and send events to Kafka. Do not put traffic on this new revision.\n\n```sh\n$ kn service update user-registration --image quay.io/microcks/quarkus-user-registration:latest --traffic @latest=0 --traffic v1=100\nUpdating Service 'user-registration' in namespace 'user-registration-serverless':\n\n  0.060s The Configuration is still working to reflect the latest desired specification.\n  6.794s Traffic is not yet migrated to the latest revision.\n  6.871s Ingress has not yet been reconciled.\n  6.978s Ready to serve.\n\nService 'user-registration' updated to latest revision 'user-registration-mwmrh-3' is available at URL:\nhttp://user-registration-user-registration-serverless.apps.cluster-7eee.7eee.example.opentlc.com\n```\n\nFrom here, we want to split traffic between the 2 revisions to do a canary release. You can do that through:\n\nthe OpenShift console UI, tagging the new revision with `v2` (see below image),\n\n![Traffic distribution](assets/traffic-splitting.png)\n\nor through the command line (see below commands):\n\n``` sh\n$ kn service update user-registration --tag user-registration-mwmrh-3=v2\n$ kn service update user-registration --traffic v2=10 --traffic v1=90\n```\n\nYou can retrieve the specific `v2` url and check everything is fine:\n\n```sh\n$ export APP_V2_URL=`oc get ksvc user-registration -o json -n user-registration-serverless | jq -r '.status.traffic[1].url'`\n\n$ curl -XPOST $APP_V2_URL/register -H 'Content-type: application/json' -d '{\"fullName\":\"Laurent Broudoux\",\"email\":\"laurent.broudoux@gmail.com\",\"age\":43}' -s | jq .\n{\n  \"age\": 43,\n  \"email\": \"laurent.broudoux@gmail.com\",\n  \"fullName\": \"Laurent Broudoux\",\n  \"id\": \"a34d49f4-5332-4919-bd00-35089af32ee4\",\n  \"registrationDate\": \"1606493455380\"\n}\n```\n\nNow that you're happy, move traffic from `v1` to `v2`\n\n```sh\n$ curl -XPOST $APP_URL/register -H 'Content-type: application/json' -d '{\"fullName\":\"Laurent Broudoux\",\"email\":\"laurent.broudoux@gmail.com\",\"age\":43}' -s | jq .\n{\n  \"age\": 43,\n  \"email\": \"laurent.broudoux@gmail.com\",\n  \"fullName\": \"Laurent Broudoux\",\n  \"id\": \"bba6e464-4cb3-4361-ad20-0e3294bdb00f\"\n}\n\n$ kn service update user-registration --traffic v1=0,v2=100\nUpdating Service 'user-registration' in namespace 'user-registration-serverless':\n\n  0.057s The Route is still working to reflect the latest desired specification.\n  0.134s Ingress has not yet been reconciled.\n  0.235s unsuccessfully observed a new generation\n  0.591s Ready to serve.\n\nService 'user-registration' with latest revision 'user-registration-mwmrh-3' (unchanged) is available at URL:\nhttp://user-registration-user-registration-serverless.apps.cluster-7eee.7eee.example.opentlc.com\n\n$ curl -XPOST $APP_URL/register -H 'Content-type: application/json' -d '{\"fullName\":\"Laurent Broudoux\",\"email\":\"laurent.broudoux@gmail.com\",\"age\":43}' -s | jq .\n{\n  \"age\": 43,\n  \"email\": \"laurent.broudoux@gmail.com\",\n  \"fullName\": \"Laurent Broudoux\",\n  \"id\": \"fafc43d4-46e3-4595-b5d5-e17f31ae3fac\",\n  \"registrationDate\": \"1606493796914\"\n}\n```\n\n#### Knative Eventing\n\nCreate the `Source` and the `Channel`\n\n```sh\noc create -f user-signed-up-channel.yml -n user-registration-serverless\noc create -f user-signed-up-source.yml -n user-registration-serverless\n```\n\nDeploy the `user-registration-consumer`\n\n```sh\n$ kn service create user-registration-consumer --image quay.io/lbroudoux/user-registration-consumer:latest --port 8484 -n user-registration-serverless\n```\n\nDeploy some other consumer...\n\n```sh\n$ kn service create event-display --image gcr.io/knative-releases/knative.dev/eventing-contrib/cmd/event_display\n```\n\nCreate `Subscriptions` to bind the `Channel` to our consumers. You can do that using the OpenShift Console Developer UI by drag-n-dropping connections between the `Channel` and the Knative Services or with this commands:\n\n```sh\noc create -f event-display-subscription.yml -n user-registration-serverless\noc create -f user-registration-consumer-subscription.yml -n user-registration-serverless\n```\n\nNow it's time to demonstrate everything altogether! Be sure that you waited long enough so that there's no pod still running on the different microservices. You should have something like that:\n\n![Scale Zero](assets/scale-zero.png)\n\nThen send a request to the App and you should see everything light-up starting with the `user-registration` component ans just after the 2 events consumers:\n\n```sh\n$ curl -XPOST $APP_URL/register -H 'Content-type: application/json' -d '{\"fullName\":\"Laurent Broudoux\",\"email\":\"laurent.broudoux@gmail.com\",\"age\":43}' -s | jq .\n{\n  \"age\": 43,\n  \"email\": \"laurent.broudoux@gmail.com\",\n  \"fullName\": \"Laurent Broudoux\",\n  \"id\": \"da4acd59-044b-4c8f-a607-3b568c7cee27\",\n  \"registrationDate\": \"1606751232863\"\n}\n```\n\n![Scale Up](assets/scale-up.png)\n\nCheck the logs in the `event-display-*` pod and you should have something like:\n\n```\n☁️  cloudevents.Event\nValidation: valid\nContext Attributes,\n  specversion: 1.0\n  type: dev.knative.kafka.event\n  source: /apis/v1/namespaces/user-registration-serverless/kafkasources/kafka-source#user-signed-up\n  subject: partition:0#2\n  id: partition:0/offset:2\n  time: 2022-03-30T09:00:16.099Z\nExtensions,\n  key: 1648630816093\nData,\n  {\"age\":43,\"email\":\"laurent.broudoux@gmail.com\",\"fullName\":\"Laurent Broudoux\",\"id\":\"ae63eb76-388e-4874-ade7-831f3fabb194\",\"sendAt\":\"1648630816093\"}\n```\n\nCheck the logs in the `user-registration-consumer-*` pod and you should have something like:\n\n```\n__  ____  __  _____   ___  __ ____  ______\n --/ __ \\/ / / / _ | / _ \\/ //_/ / / / __/\n -/ /_/ / /_/ / __ |/ , _/ ,\u003c / /_/ /\\ \\\n--\\___\\_\\____/_/ |_/_/|_/_/|_|\\____/___/\n2022-03-30 09:02:21,363 INFO  [io.quarkus] (main) user-registration-consumer 1.0-SNAPSHOT native (powered by Quarkus 1.9.2.Final) started in 0.033s. Listening on: http://0.0.0.0:8484\n2022-03-30 09:02:21,364 INFO  [io.quarkus] (main) Profile prod activated.\n2022-03-30 09:02:21,364 INFO  [io.quarkus] (main) Installed features: [cdi, resteasy, resteasy-jackson]\n2022-03-30 09:02:22,113 INFO  [org.acm.reg.UserRegistrationResource] (executor-thread-1) cloudEventJson: {\"age\":41,\"email\":\"laurent.broudoux@gmail.com\",\"fullName\":\"Laurent Broudoux\",\"id\":\"ba7267a1-baf1-41f4-ab77-bf0adf9fbf2f\",\"sendAt\":\"1648630938601\"}\n2022-03-30 09:02:22,114 INFO  [org.acm.reg.UserRegistrationResource] (executor-thread-1) Processing registration {ba7267a1-baf1-41f4-ab77-bf0adf9fbf2f} for {Laurent Broudoux}\n```\n\n### Troubleshoot\n\n#### Check on Kafka broker\n\n```sh\n$ oc exec -n user-registration-serverless -it my-cluster-kafka-0 -- /opt/kafka/bin/kafka-console-consumer.sh \\\n    --bootstrap-server localhost:9092 \\\n    --from-beginning \\\n    --property print.key=true \\\n    --topic user-signed-up\n\n$ oc exec -n user-registration-serverless -it my-cluster-kafka-0 -- /opt/kafka/bin/kafka-console-producer.sh \\\n    --broker-list my-cluster-kafka-bootstrap:9092 \\\n    --topic user-signed-up\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flbroudoux%2Fknative-user-registration","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flbroudoux%2Fknative-user-registration","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flbroudoux%2Fknative-user-registration/lists"}