Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pkged.go

Large diffs are not rendered by default.

27 changes: 22 additions & 5 deletions templates/node/events/README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,29 @@
# 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`.
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`.
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:
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 '{"name": "Tiger", "customerId": "0123456789"}' \
Expand All @@ -24,11 +35,17 @@ curl -X POST -d '{"name": "Tiger", "customerId": "0123456789"}' \
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.
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.
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
Expand Down
25 changes: 19 additions & 6 deletions templates/node/events/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
'use strict';
const { CloudEvent, HTTP } = require('cloudevents');

/**
* An example function that responds to incoming CloudEvents over HTTP. For example,
Expand All @@ -18,17 +19,29 @@
*
* const incomingEvent = context.cloudevent;
*
* @param {Object} customer the CloudEvent data. If the data content type is application/json
* @param {Object} user the CloudEvent data. If the data content type is application/json
* this will be converted to an Object via JSON.parse()
* @param {Context} context the invocation context
*/
function processCustomer(customer, context) {
console.log(customer, context)
function verifyUser(context, user) {
if (!context.cloudevent) {
return 'No cloud event received';
}
context.log.info('Processing customer', customer);

context.log.info('Processing user', user);
context.log.info(`CloudEvent received: ${context.cloudevent.toString()}`);
return { customer };

user = verify(user);
return HTTP.binary(new CloudEvent({
source: 'function.verifyUser',
type: 'user:verified',
data: user
}));
};
module.exports = processCustomer;

function verify(user) {
// do something with the user
return user;
}

module.exports = verifyUser;
76 changes: 32 additions & 44 deletions templates/node/events/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions templates/node/events/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@
"debug": "nodemon --inspect ./node_modules/faas-js-runtime/bin/cli.js ./index.js"
},
"devDependencies": {
"faas-js-runtime": "0.4.0",
"faas-js-runtime": "0.5.1",
"nodemon": "^2.0.4",
"cloudevents": "^3.1.0",
"supertest": "^4.0.2",
"tape": "^4.13.0"
},
"dependencies": {
"cloudevents": "^3.2.0"
}
}
26 changes: 16 additions & 10 deletions templates/node/events/test/integration.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
'use strict';

const { CloudEvent } = require('cloudevents');
const runtime = require('faas-js-runtime');
const request = require('supertest');

Expand All @@ -13,23 +13,29 @@ const Spec = {
source: 'ce-source'
};

const data = {
name: 'tiger',
customerId: '01234'
}

test('Integration: handles a valid event', t => {
runtime(func, server => {
t.plan(1);
t.plan(5);
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')
.send(data)
.set(Spec.id, '01234')
.set(Spec.source, '/test')
.set(Spec.type, 'com.example.cloudevents.test')
.set(Spec.version, '1.0')
.expect(200)
.expect('Content-Type', /json/)
.end((err, res) => {
.end((err, result) => {
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.ok(result);
t.deepEqual(result.body, data);
t.equal(result.headers['ce-type'], 'user:verified');
t.equal(result.headers['ce-source'], 'function.verifyUser');
t.end();
server.close();
});
Expand Down
Loading