js events template

This commit is contained in:
Luke K 2020-06-09 14:47:48 +00:00
parent 50da540bfb
commit 4122522f23
No known key found for this signature in database
GPG Key ID: 4896F75BAF2E1966
6 changed files with 151 additions and 0 deletions

View File

@ -0,0 +1,35 @@
# Node.js Cloud Events Function
Welcome to your new Node.js function project! The boilerplate function code can be found in [`index.js`](./index.js). This function is meant to respond exclusively to [Cloud Events](https://cloudevents.io/), but you can remove the check for this in the function and it will respond just fine to plain vanilla incoming HTTP requests. Additionally, this example function is written asynchronously, returning a `Promise`. If your function does not perform any asynchronous execution, you can safely remove the `async` keyword from the function, and return raw values intead of a `Promise`.
## Local execution
After executing `npm install`, you can run this function locally by executing `npm run local`.
The runtime will expose three endpoints.
* `/` The endpoint for your function.
* `/health/readiness` The endpoint for a readiness health check
* `/health/liveness` The endpoint for a liveness health check
The health checks can be accessed in your browser at [http://localhost:8080/health/readiness]() and [http://localhost:8080/health/liveness](). You can use `curl` to `POST` an event to the function endpoint:
```console
curl -X POST -d '{"hello": "world"}' \
-H'Content-type: application/json' \
-H'Ce-id: 1' \
-H'Ce-source: cloud-event-example' \
-H'Ce-type: dev.knative.example' \
-H'Ce-specversion: 1.0' \
http://localhost:8080
```
The readiness and liveness endpoints use [overload-protection](https://www.npmjs.com/package/overload-protection) and will respond with `HTTP 503 Service Unavailable` with a `Client-Retry` header if your function is determined to be overloaded, based on the memory usage and event loop delay.
## Testing
This function project includes a [unit test](./test/unit.js) and an [integration test](./test/integration.js). All `.js` files in the test directory are run.
```console
npm test
```

View File

@ -0,0 +1,11 @@
'use strict';
module.exports = async function (context) {
if (!context.cloudevent) {
return Promise.reject(new Error('No cloud event received'));
}
context.log.info(`Cloud event received: ${JSON.stringify(context.cloudevent)}`);
return new Promise((resolve, reject) => {
setTimeout(_ => resolve({ data: context.cloudevent.data }), 500);
});
};

View File

@ -0,0 +1,25 @@
"use strict";
const runtime = require('@redhat/faas-js-runtime');
const func = require('./index.js');
const ON_DEATH = require('death')({ uncaughtException: true });
runtime(func, server => {
ON_DEATH(_ => {
server.close();
});
console.log(`
The server has started.
You can use curl to POST an event to the endpoint:
curl -X POST -d '{"hello": "world"}' \\
-H'Content-type: application/json' \\
-H'Ce-id: 1' \\
-H'Ce-source: cloud-event-example' \\
-H'Ce-type: dev.knative.example' \\
-H'Ce-specversion: 1.0' \\
http://localhost:8080
`);
});

View File

@ -0,0 +1,21 @@
{
"name": "event-handler",
"version": "0.1.0",
"description": "Node.js CloudEvent Handler",
"license": "Apache-2.0",
"repository": {
"type": "git",
"url": ""
},
"scripts": {
"test": "node test/unit.js && node test/integration.js",
"local": "node local.js"
},
"devDependencies": {
"@redhat/faas-js-runtime": "0.2.0",
"cloudevents-sdk": "^1.0.0",
"death": "^1.1.0",
"supertest": "^4.0.2",
"tape": "^4.13.0"
}
}

View File

@ -0,0 +1,39 @@
'use strict';
const runtime = require('@redhat/faas-js-runtime');
const request = require('supertest');
const func = require('..');
const test = require('tape');
const cloudevents = require('cloudevents-sdk/v1');
const Spec = {
version: 'ce-specversion',
type: 'ce-type',
id: 'ce-id',
source: 'ce-source'
};
test('Integration: handles a valid event', t => {
runtime(func, server => {
t.plan(1);
request(server)
.post('/')
.send({ message: 'hello' })
.set(Spec.id, 'TEST-EVENT-1')
.set(Spec.source, 'http://localhost:8080/integration-test')
.set(Spec.type, 'dev.faas.example')
.set(Spec.version, '1.0')
.expect(200)
.expect('Content-Type', /json/)
.end((err, res) => {
t.error(err, 'No error');
// Check response values that your function produces
// Uncomment this line to validate the template implementation
// t.equal(res.body.data.message, 'hello');
t.end();
server.close();
});
}, { log: false });
});

View File

@ -0,0 +1,20 @@
'use strict';
const func = require('..');
const test = require('tape');
const cloudevents = require('cloudevents-sdk/v1');
// Ensure that the function completes cleanly when passed a valid event.
test('Unit: andles a valid event', t => {
t.plan(1);
// A valid event includes id, type and source at a minimum.
const cloudevent = cloudevents.event()
.id('TEST-EVENT-01')
.type('com.example.cloudevents.test')
.source('http://localhost:8080/')
.data({ message: 'hello' });
// Invoke the function with the valid event, which should compelte without error.
t.ok(func({ cloudevent, log: { info: console.log } }));
t.end();
});