diff --git a/docs/eventing/samples/writing-event-source-easy-way/Dockerfile b/docs/eventing/samples/writing-event-source-easy-way/Dockerfile new file mode 100644 index 00000000000..9e7a85fe75b --- /dev/null +++ b/docs/eventing/samples/writing-event-source-easy-way/Dockerfile @@ -0,0 +1,19 @@ +FROM node:10 + +# Create app directory +WORKDIR /usr/src/app + +# Install app dependencies +# A wildcard is used to ensure both package.json AND package-lock.json are copied +# where available (npm@5+) +COPY package*.json ./ + +RUN npm install +# If you are building your code for production +# RUN npm ci --only=production + +# Bundle app source +COPY . . + +EXPOSE 8080 +CMD [ "node", "index.js" ] diff --git a/docs/eventing/samples/writing-event-source-easy-way/README.md b/docs/eventing/samples/writing-event-source-easy-way/README.md new file mode 100644 index 00000000000..89ddc86fa45 --- /dev/null +++ b/docs/eventing/samples/writing-event-source-easy-way/README.md @@ -0,0 +1,298 @@ +# Introduction + +As stated in [tutorial on writing a Source with a Receive Adapter](../writing-receive-adapter-source/README.md), there are multiple ways to +create event sources. The way in that tutorial is to create an independent event source that has its own CRD. + +In this tutorial though, you will build an event source in Javascript and use it with +[ContainerSource](../../../eventing/sources/README.md#meta-sources) and / or [SinkBinding](../../../eventing/sources/README.md#meta-sources). + +[ContainerSource](../../../eventing/sources/README.md#meta-sources) is an easy way to turn any dispatcher container into an Event Source. +Similarly, another option is using [SinkBinding](../../../eventing/sources/README.md#meta-sources) +which provides a framework for injecting environment variables into any Kubernetes resource which has a `spec.template` that looks like a Pod (aka PodSpecable). + +Code for this tutorial is available [here](./). + +# Bootstrapping + +Create the project and add the dependencies: +```bash +npm init +npm install cloudevents-sdk --save +``` + +## Making use of ContainerSource + +`ContainerSource` and `SinkBinding` both work by injecting environment variables to an application. +Injected environment variables at minimum contain the URL of a sink that will receive events. + +Following example emits an event to the sink every 1000 milliseconds. +The sink URL to post the events will be made available to the application via the `K_SINK` environment variable by `ContainerSource`. + +```javascript +// File - index.js + +const v1 = require("cloudevents-sdk/v1"); + +let sinkUrl = process.env['K_SINK']; + +console.log("Sink URL is " + sinkUrl); + +let config = { + method: "POST", + url: sinkUrl +}; + +// The binding instance +let binding = new v1.BinaryHTTPEmitter(config); + +let eventIndex = 0; +setInterval(function () { + console.log("Emitting event #" + ++eventIndex); + + // create the event + let myevent = v1.event() + .id('your-event-id') + .type("your.event.source.type") + .source("urn:event:from:your-api/resource/123") + .dataContentType("application/json") + .data({"hello": "World " + eventIndex}); + + // Emit the event + binding.emit(myevent) + .then(response => { + // Treat the response + console.log("Event posted successfully"); + console.log(response.data); + }) + .catch(err => { + // Deal with errors + console.log("Error during event post"); + console.error(err); + }); +}, 1000); +``` + +```dockerfile +# File - Dockerfile + +FROM node:10 +WORKDIR /usr/src/app +COPY package*.json ./ +RUN npm install +COPY . . +EXPOSE 8080 +CMD [ "node", "index.js" ] + +``` + +Build and push the image: +```bash +docker build . -t path/to/image/registry/node-knative-heartbeat-source:v1 +docker push path/to/image/registry/node-knative-heartbeat-source:v1 +``` + +Create the event display service which simply logs any cloudevents posted to it. +```bash +cat < { + // Treat the response + console.log("Event posted successfully"); + console.log(response.data); + }) + .catch(err => { + // Deal with errors + console.log("Error during event post"); + console.error(err); + }); +}, 1000); + +registerGracefulExit(); + +function registerGracefulExit() { + let logExit = function () { + console.log("Exiting"); + process.exit(); + }; + + // handle graceful exit + //do something when app is closing + process.on('exit', logExit); + //catches ctrl+c event + process.on('SIGINT', logExit); + process.on('SIGTERM', logExit); + // catches "kill pid" (for example: nodemon restart) + process.on('SIGUSR1', logExit); + process.on('SIGUSR2', logExit); +} diff --git a/docs/eventing/samples/writing-event-source-easy-way/package.json b/docs/eventing/samples/writing-event-source-easy-way/package.json new file mode 100644 index 00000000000..21339282d10 --- /dev/null +++ b/docs/eventing/samples/writing-event-source-easy-way/package.json @@ -0,0 +1,14 @@ +{ + "name": "event-emitter", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "cloudevents-sdk": "^1.0.0" + } +}