-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Add sample for cloudevents-nodejs #2446
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
knative-prow-robot
merged 3 commits into
knative:master
from
csantanapr:issuexx-add-cloudevent-sample-nodejs
May 22, 2020
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 4 additions & 0 deletions
4
docs/serving/samples/cloudevents/cloudevents-nodejs/.dockerignore
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
Dockerfile | ||
README.md | ||
node_modules/ | ||
npm-debug.log |
2 changes: 2 additions & 0 deletions
2
docs/serving/samples/cloudevents/cloudevents-nodejs/.gitignore
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
node_modules/ | ||
npm-debug.log* |
38 changes: 38 additions & 0 deletions
38
docs/serving/samples/cloudevents/cloudevents-nodejs/Dockerfile
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# Copyright 2020 The Knative Authors | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# https://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
FROM registry.access.redhat.com/ubi8/nodejs-12 | ||
|
||
# Copy application dependency manifests to the container image. | ||
# A wildcard is used to ensure both package.json AND package-lock.json are copied. | ||
# Copying this separately prevents re-running npm install on every code change. | ||
COPY package*.json ./ | ||
|
||
# Use ci is faster and more reliable following package-lock.json | ||
RUN npm ci --only=production | ||
|
||
# Doc port listening port | ||
ENV PORT 8080 | ||
|
||
EXPOSE $PORT | ||
|
||
ARG ENV=production | ||
|
||
ENV NODE_ENV $ENV | ||
|
||
# Run the web service on container startup. | ||
CMD npm run $NODE_ENV | ||
csantanapr marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
# Copy local code to the container image. | ||
COPY . ./ |
100 changes: 100 additions & 0 deletions
100
docs/serving/samples/cloudevents/cloudevents-nodejs/README.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
A simple web app written in Node.js that can receive and send Cloud Events that you | ||
mattmoor marked this conversation as resolved.
Show resolved
Hide resolved
|
||
can use for testing. It supports running in two modes: | ||
|
||
1. The default mode has the app reply to your input events with the output | ||
event, which is simplest for demonstrating things working in isolation, but | ||
is also the model for working for the Knative Eventing `Broker` concept. | ||
|
||
2. `K_SINK` mode has the app send events to the destination encoded in | ||
`$K_SINK`, which is useful to demonstrate how folks can synthesize events to | ||
send to a Service or Broker when not initiated by a Broker invocation (e.g. | ||
implementing an event source) | ||
|
||
The application will use `$K_SINK`-mode whenever the environment variable is | ||
specified. | ||
|
||
Follow the steps below to create the sample code and then deploy the app to your | ||
cluster. You can also download a working copy of the sample, by running the | ||
following commands: | ||
|
||
```shell | ||
git clone -b "{{< branch >}}" https://github.com/knative/docs knative-docs | ||
cd knative-docs/docs/serving/samples/cloudevents/cloudevents-nodejs | ||
``` | ||
|
||
## Before you begin | ||
|
||
- A Kubernetes cluster with Knative installed and DNS configured. Follow the | ||
[installation instructions](../../../../install/README.md) if you need to | ||
create one. | ||
- [Docker](https://www.docker.com) installed and running on your local machine, | ||
and a Docker Hub account configured (we'll use it for a container registry). | ||
|
||
## The sample code. | ||
|
||
1. If you look in `index.js`, you will see two key functions for the | ||
different modes of operation: | ||
|
||
```js | ||
const receiveAndSend = (cloudEvent, res) => { | ||
// This is called whenever an event is received if $K_SINK is set, and sends a new event | ||
// to the url in $K_SINK. | ||
} | ||
|
||
const receiveAndReply = (cloudEvent, res) => { | ||
// This is called whenever an event is received if $K_SINK is NOT set, and it replies with | ||
// the new event instead. | ||
} | ||
``` | ||
|
||
1. If you look in `Dockerfile`, you will see how the dependencies are installed using npm. | ||
You can build and push this to your registry of choice via: | ||
|
||
```shell | ||
docker build -t <image> . | ||
docker push <image> | ||
``` | ||
|
||
1. If you look in `service.yaml`, take the `<image>` name above and insert it | ||
into the `image:`. | ||
|
||
```shell | ||
kubectl apply -f service.yaml | ||
``` | ||
|
||
## Testing the sample | ||
|
||
Get the URL for your Service with: | ||
|
||
```shell | ||
$ kubectl get ksvc | ||
NAME URL LATESTCREATED LATESTREADY READY REASON | ||
cloudevents-nodejs http://cloudevents-nodejs.default.1.2.3.4.xip.io cloudevents-nodejs-ss5pj cloudevents-nodejs-ss5pj True | ||
``` | ||
|
||
Then send a cloud event to it with: | ||
|
||
```shell | ||
$ curl -X POST \ | ||
-H "content-type: application/json" \ | ||
-H "ce-specversion: 1.0" \ | ||
-H "ce-source: curl-command" \ | ||
-H "ce-type: curl.demo" \ | ||
-H "ce-id: 123-abc" \ | ||
-d '{"name":"Dave"}' \ | ||
http://cloudevents-nodejs.default.1.2.3.4.xip.io | ||
``` | ||
|
||
You will get back: | ||
|
||
```shell | ||
{"message":"Hello, Dave"} | ||
``` | ||
|
||
## Removing the sample app deployment | ||
|
||
To remove the sample app from your cluster, delete the service record: | ||
|
||
```shell | ||
kubectl delete --filename service.yaml | ||
``` |
107 changes: 107 additions & 0 deletions
107
docs/serving/samples/cloudevents/cloudevents-nodejs/index.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
/* | ||
Copyright 2020 The Knative Authors | ||
|
||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
|
||
http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
const express = require('express') | ||
csantanapr marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const { CloudEvent, HTTPEmitter, HTTPReceiver } = require('cloudevents-sdk') | ||
const PORT = process.env.PORT || 8080 | ||
const target = process.env.K_SINK | ||
const app = express() | ||
const receiver = new HTTPReceiver() | ||
|
||
const main = () => { | ||
app.listen(PORT, function () { | ||
console.log(`Cookie monster is hungry for some cloudevents on port ${PORT}!`) | ||
csantanapr marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const modeMessage = target ? `send cloudevents to K_SINK: ${target}` : 'reply back with cloudevents' | ||
console.log(`Cookie monster is going to ${modeMessage}`) | ||
}) | ||
} | ||
|
||
// handle shared the logic for producing the Response event from the Request. | ||
const handle = (data) => { | ||
return { message: `Hello, ${data.name ? data.name : 'nameless'}` } | ||
} | ||
|
||
// receiveAndSend responds with ack, and send a new event forward | ||
const receiveAndSend = (cloudEvent, res) => { | ||
const data = handle(cloudEvent.getData()) | ||
const newCloudEvent = new CloudEvent() | ||
.type('dev.knative.docs.sample') | ||
.source('https://github.com/knative/docs/docs/serving/samples/cloudevents/cloudevents-nodejs') | ||
.time(new Date()) | ||
csantanapr marked this conversation as resolved.
Show resolved
Hide resolved
|
||
.data(data) | ||
|
||
// With only an endpoint URL, this creates a v1 emitter | ||
const emitter = new HTTPEmitter({ | ||
url: target | ||
}) | ||
// Reply back to dispatcher/client as soon as possible | ||
res.status(202).end() | ||
// Send the new Event to the K_SINK | ||
emitter.send(newCloudEvent) | ||
.then((res) => { | ||
console.log(`Sent event: ${JSON.stringify(newCloudEvent.format(), null, 2)}`) | ||
console.log(`K_SINK responded: ${JSON.stringify({ status: res.status, headers: res.headers, data: res.data }, null, 2)}`) | ||
}) | ||
.catch(console.error) | ||
} | ||
csantanapr marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
// receiveAndReply responds with new event | ||
const receiveAndReply = (cloudEvent, res) => { | ||
const data = handle(cloudEvent.getData()) | ||
const newCloudEvent = new CloudEvent() | ||
.type('dev.knative.docs.sample') | ||
.source('https://github.com/knative/docs/docs/serving/samples/cloudevents/cloudevents-nodejs') | ||
.time(new Date()) | ||
|
||
console.log(`Reply event: ${JSON.stringify(newCloudEvent.format(), null, 2)}`) | ||
res.set(getHeaders(newCloudEvent)) | ||
res.status(200).send(data) | ||
} | ||
|
||
const getHeaders = (cloudEvent) => { | ||
/* TODO: SDK should provide a better way to get the headers from a cloudEvent, using fake url for now ¯\_(ツ)_/¯ */ | ||
const emitter = new HTTPEmitter({ | ||
url: 'http://example.com' | ||
csantanapr marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}) | ||
return emitter.headers(cloudEvent) | ||
} | ||
|
||
app.use((req, res, next) => { | ||
let data = '' | ||
req.setEncoding('utf8') | ||
req.on('data', function (chunk) { | ||
data += chunk | ||
}) | ||
req.on('end', function () { | ||
req.body = data | ||
next() | ||
}) | ||
}) | ||
|
||
app.post('/', function (req, res) { | ||
try { | ||
const event = receiver.accept(req.headers, req.body) | ||
console.log(`Accepted event: ${JSON.stringify(event.format(), null, 2)}`) | ||
target ? receiveAndSend(event, res) : receiveAndReply(event, res) | ||
} catch (err) { | ||
console.error(err) | ||
res.status(415) | ||
.header('Content-Type', 'application/json') | ||
.send(JSON.stringify(err)) | ||
} | ||
}) | ||
|
||
main() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
--- | ||
title: "Cloud Events - Node.js" | ||
linkTitle: "Node.js" | ||
weight: 1 | ||
type: "docs" | ||
--- | ||
|
||
{{% readfile file="README.md" %}} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.