{"id":17668570,"url":"https://github.com/evanshortiss/rhosak-nodejs-sbo-example","last_synced_at":"2025-05-08T22:14:25.669Z","repository":{"id":66153969,"uuid":"381317044","full_name":"evanshortiss/rhosak-nodejs-sbo-example","owner":"evanshortiss","description":"An application that demonstrates using Service Binding with OpenShift Streams for Apache Kafka and Node.js.","archived":false,"fork":false,"pushed_at":"2021-12-07T18:37:07.000Z","size":5996,"stargazers_count":5,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-05-08T22:14:20.017Z","etag":null,"topics":["kafka","kubernetes","nodejs","openshift","service-binding"],"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/evanshortiss.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":"2021-06-29T09:55:49.000Z","updated_at":"2023-06-12T10:59:07.000Z","dependencies_parsed_at":"2023-07-02T06:36:20.764Z","dependency_job_id":null,"html_url":"https://github.com/evanshortiss/rhosak-nodejs-sbo-example","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/evanshortiss%2Frhosak-nodejs-sbo-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evanshortiss%2Frhosak-nodejs-sbo-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evanshortiss%2Frhosak-nodejs-sbo-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evanshortiss%2Frhosak-nodejs-sbo-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/evanshortiss","download_url":"https://codeload.github.com/evanshortiss/rhosak-nodejs-sbo-example/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253154977,"owners_count":21862623,"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","kubernetes","nodejs","openshift","service-binding"],"created_at":"2024-10-23T23:23:03.529Z","updated_at":"2025-05-08T22:14:25.663Z","avatar_url":"https://github.com/evanshortiss.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# OpenShift Streams Node.js Service Binding Example\n\nA Node.js application that integrates with a Kafka instance hosted on Red Hat\nOpenShift Streams for Apache Kafka.\n\nThe connection credentials and configuration for the Kafka instance are\ninjected into the application using\n[Service Binding](https://github.com/k8s-service-bindings/spec). Specifically,\nthe [kube-service-bindings](https://github.com/nodeshift/kube-service-bindings)\nNode.js module is used to read the bindings.\n\n\u003cdiv align=\"center\"\u003e\n\t\u003cbr\u003e\n    \u003cimg style=\"max-width: 600px;\" src=\"images/service-binding.png\"/\u003e\n\t\u003cbr\u003e\n  \u003ci\u003eA high-level summary of Service Binding with Red Hat OpenShift Streams for Apache Kafka.\u003c/i\u003e\n  \u003cbr\u003e\n  \u003cbr\u003e\n\u003c/div\u003e\n\n## Requirements\n\n### CLI Tooling\n\n* Node.js \u003e= v12\n* [OpenShift CLI v4.x](https://mirror.openshift.com/pub/openshift-v4/clients/ocp/stable/)\n\n### OpenShift Account \u0026 Cluster (free options available)\n\n* Red Hat Cloud Account (Sign-up on the [cloud.redhat.com](https://cloud.redhat.com) Log-in page)\n* OpenShift \u003e= v4.x (use [OpenShift Developer Sandbox](https://developers.redhat.com/developer-sandbox) for free!)\n* [Red Hat OpenShift Application Services Operator](https://github.com/redhat-developer/app-services-operator) (pre-installed on [OpenShift Developer Sandbox](https://developers.redhat.com/developer-sandbox))\n* [Service Binding Operator](https://github.com/redhat-developer/service-binding-operator) (pre-installed on [OpenShift Developer Sandbox](https://developers.redhat.com/developer-sandbox))\n* [Red Hat OpenShift Application Services CLI](https://github.com/redhat-developer/app-services-cli)\n\n## Deployment\n\nTypically, the Service Binding will be managed by the\n[RHOAS Operator](https://github.com/redhat-developer/app-services-operator)\nin your OpenShift or Kubernetes cluster. However, for local development\nthe bindings are managed using the *.bindingroot/* directory.\n\nTake a look at the difference between the `start` and `dev` scripts in the\n*package.json* file. Notice how the `dev` script references the local bindings,\ndirectory but the regular `start` script doesn't? This is because the RHOAS\nOperator manages the `SERVICE_BINDING_ROOT` when deployed on OpenShift or\nKubernetes.\n\n### Create and Prepare a Managed Kafka\n\nYou must create a Kafka on Red Hat OpenShift Streams for Apache Kafka prior to\nusing the Node.js application.\n\nUse the RHOAS CLI to create and configure a managed Kafka instance:\n\n```bash\n# Login using the browser-based flow\nrhoas login\n\n# Create a kafka by following the prompts\nrhoas kafka create --name my-kafka\n\n# Select a Kafka instance to use for future commands\nrhoas kafka use\n\n# Create the topic used by the application\nrhoas kafka topic create --name orders --partitions 3\n```\n\n### Deploy on OpenShift\n\nDeploy the application on OpenShift.\n\nYou'll need to login using the OpenShift CLI first. Instructions to login via\nthe CLI are available in the *Command line tools* help from your cluster UI.\n\n![OpenShift CLI Help](images/oc-cli.png)\n\nOnce you've logged into the cluster using the OpenShift CLI deploy the\napplication:\n\n```bash\n# Choose the project to deploy into. Use the \"oc projects\"\n# command to list available projects.\noc project $PROJECT_NAME_GOES_HERE\n\n# Deploy the application on OpenShift using Nodeshift CLI\n# This will take a minute since it has to build the application\nnpm install\nnpx nodeshift --useDeployment --expose\n```\n\nWhen deployed in production this application expects the bindings to be\nsupplied in the Kubernetes Deployment spec. Without these it will crash loop,\nas indicated by a red ring.\n\n![Application Crashing on OpenShift](images/crash-loop.png)\n\nBindings can be configured using the\n[RHOAS CLI](https://github.com/redhat-developer/app-services-cli):\n\n```bash\n# Login using the browser-based flow\nrhoas login\n\n# Select a Kafka instance to use for future commands\nrhoas kafka use\n\n# Link your OpenShift/Kubernetes project/namespace to the Kafka\nrhoas cluster connect\n```\n\nA new Managed Kafka icon will appear in your application Topology View on\nOpenShift.\n\nYou'll need to bind this to your Node.js application, but first you need to\nconfigure RBAC for the Service Account that was created by the\n`rhoas cluster connect` command. Service Accounts have limited access by\ndefault, and therefore cannot read/write from/to Kafka Topics. The Service\nAccount ID should have been printed by the `rhoas cluster connect` command,\nbut you can find it in the OpenShift Streams UI or using the\n`rhoas service-account list` command.\n\nUse the following commands to provide liberal permissions to your Service\nAccount. These loose permissions *are not* recommended in production.\n\n```bash\n# Replace with your service account ID!\nexport SERVICE_ACCOUNT_ID=\"srvc-acct-replace-me\"\n\nrhoas kafka acl grant-access --producer --consumer \\\n--service-account $SERVICE_ACCOUNT_ID --topic all --group all\n```\n\nNow, create a Service Binding between your Managed Kafka and Node.js `producer`\napplication.\n\n```bash\nrhoas cluster bind\n```\n\nThe Node.js application should restart and stay in a health state, surrounded\nby a blue ring as shown in the Topology View.\n\n![Application Running on OpenShift](images/application-running.png)\n\nUse the following command to get the application URL!\n\n```bash\noc get route producer -o jsonpath='{.spec.host}'\n```\n\nNow you can submit an order via browser. The order is placed into the `orders` topic in your Kafka instance.\n\n![Node.js Application UI](images/order.png)\n\n### Develop Locally\n\nThe *.bindingroot/kafka/* directory already contains some configuration files.\nThink of the filename as a key, and file contents as a value. The SASL mechanism\nand protocol are known ahead of time so they're checked into the repository.\n\nA bootstrap server URL, and connection credentials are not checked-in though,\nsince they're unique to you and should be kept secret.\n\nCreate the following files in the *.bindingroot/kafka/* directory. Each should\ncontain a single line value described below:\n\n* _bootstrapServers_: Obtain from the [OpenShift Streams UI](https://cloud.redhat.com/beta/application-services/streams/kafkas), or via `rhoas kafka describe`\n* _user_ \u0026 _password_: Obtain via the Service Accounts section of the OpenShift Streams UI, or the `rhoas serviceaccounts create` command.\n\nFor example the *bootstrapServers* file should contain a URL such as\n`sbo-exampl--example.bf2.kafka.rhcloud.com:443`.\n\nThe *user* is a value similar to `srvc-acct-a4998163-xxx-yyy-zzz-50149ce63e23`\nand *password* has a format similar to `15edf9b3-7027-4038-b150-998f225d3baf`.\n\nOnce these values are defined, start the the application:\n\n```\nnpm run dev\n```\n\nDuring development the information used to connect to Kafka is printed on\nstartup.\n\n_NOTE: These are sensitive credentials. Do not share them. This image is provided as an example of output._\n\n![Application running locally](images/local-development.png)\n\n## Building an Image\n\nThis requires Docker/Podman and [Source-to-Image](https://github.com/openshift/source-to-image).\n\n```bash\n# Output image name\nexport IMAGE_NAME=quay.io/evanshortiss/rhosak-nodejs-sbo-example\n\n# Base image used to create the build\nexport BUILDER_IMAGE=registry.access.redhat.com/ubi8/nodejs-14\n\n# Don't pass these files/dirs to the build\nexport EXCLUDES=\"(^|/)\\.git|.bindingroot|node_modules(/|$)\"\n\n# Build the local code into a container image\ns2i build -c . --exclude $EXCLUDES $BUILDER_IMAGE $IMAGE_NAME\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fevanshortiss%2Frhosak-nodejs-sbo-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fevanshortiss%2Frhosak-nodejs-sbo-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fevanshortiss%2Frhosak-nodejs-sbo-example/lists"}