Skip to content

Commit 68c1449

Browse files
authored
feat: add eventarc generic sample (#2003)
- Adds a generic Eventarc sample - Re-uses same setup as other Eventarc samples - Logs and returns request headers and body. Deletes auth header (if present). - Tests that: headers and body are logged except auth header - Tested locally Fixes #1989
1 parent 5914401 commit 68c1449

File tree

10 files changed

+351
-0
lines changed

10 files changed

+351
-0
lines changed

eventarc/generic/.dockerignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Dockerfile
2+
.dockerignore
3+
node_modules
4+
npm-debug.log

eventarc/generic/Dockerfile

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Copyright 2020 Google, LLC.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# [START eventarc_generic_dockerfile]
16+
17+
# Use the official lightweight Node.js 10 image.
18+
# https://hub.docker.com/_/node
19+
FROM node:12-slim
20+
21+
# Create and change to the app directory.
22+
WORKDIR /usr/src/app
23+
24+
# Copy application dependency manifests to the container image.
25+
# A wildcard is used to ensure both package.json AND package-lock.json are copied.
26+
# Copying this separately prevents re-running npm install on every code change.
27+
COPY package*.json ./
28+
29+
# Install dependencies.
30+
# If you add a package-lock.json speed your build by switching to 'npm ci'.
31+
# RUN npm ci --only=production
32+
RUN npm install --production
33+
34+
# Copy local code to the container image.
35+
COPY . .
36+
37+
# Run the web service on container startup.
38+
CMD [ "npm", "start" ]
39+
40+
# [END eventarc_generic_dockerfile]

eventarc/generic/app.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright 2020 Google, LLC.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
// [START eventarc_generic_handler]
16+
const express = require('express');
17+
const app = express();
18+
19+
app.use(express.json());
20+
app.post('/', (req, res) => {
21+
console.log('Event received!');
22+
23+
console.log('HEADERS:');
24+
delete req.headers.Authorization; // do not log authorization header
25+
console.log(JSON.stringify(req.headers));
26+
27+
console.log('BODY:');
28+
console.log(JSON.stringify(req.body));
29+
30+
res.send({
31+
headers: req.headers,
32+
body: req.body,
33+
});
34+
});
35+
36+
module.exports = app;
37+
// [END eventarc_generic_handler]

eventarc/generic/index.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright 2020 Google, LLC.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
// [START eventarc_generic_server]
16+
const app = require('./app.js');
17+
const PORT = process.env.PORT || 8080;
18+
19+
app.listen(PORT, () =>
20+
console.log(`nodejs-eventarc-generic listening on port ${PORT}`)
21+
);
22+
// [END eventarc_generic_server]

eventarc/generic/package.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"name": "cloud-eventarc-generic",
3+
"version": "1.0.0",
4+
"private": true,
5+
"main": "index.js",
6+
"author": "Google LLC",
7+
"license": "Apache-2.0",
8+
"repository": {
9+
"type": "git",
10+
"url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git"
11+
},
12+
"engines": {
13+
"node": ">= 12.0.0"
14+
},
15+
"scripts": {
16+
"start": "node index.js",
17+
"test": "mocha test/app.test.js --check-leaks",
18+
"system-test": "test/runner.sh mocha test/system.test.js --timeout=10000"
19+
},
20+
"dependencies": {
21+
"express": "^4.16.4"
22+
},
23+
"devDependencies": {
24+
"got": "^11.5.0",
25+
"mocha": "^8.0.0",
26+
"sinon": "^9.0.0",
27+
"supertest": "^5.0.0",
28+
"uuid": "^8.0.0"
29+
}
30+
}

eventarc/generic/test/app.test.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Copyright 2019, Google LLC.
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
// NOTE:
15+
// This app can only be fully tested when deployed, because
16+
// Pub/Sub requires a live endpoint URL to hit. Nevertheless,
17+
// these tests mock it and partially test it locally.
18+
19+
'use strict';
20+
21+
const assert = require('assert');
22+
const path = require('path');
23+
const supertest = require('supertest');
24+
25+
let request;
26+
27+
describe('Unit Tests', () => {
28+
before(() => {
29+
const app = require(path.join(__dirname, '..', 'app'));
30+
request = supertest(app);
31+
});
32+
33+
describe('should succeed', () => {
34+
it(`should relay the CloudEvent`, async () => {
35+
await request
36+
.post('/')
37+
.type('json')
38+
.set('ce-id', 1234)
39+
.set('Authorization', 'MY-SECRET-VALUE') // never logged
40+
.send({testkey: 'testvalue'})
41+
.expect((res) => {
42+
const responseBody = res.body;
43+
44+
assert.strictEqual(responseBody.headers.host.startsWith('127.0.0.1'), true);
45+
assert.strictEqual(+responseBody.headers['ce-id'], 1234);
46+
assert.strictEqual(responseBody.headers['Authorization'], undefined);
47+
assert.deepStrictEqual(responseBody.body, {testkey: 'testvalue'});
48+
});
49+
});
50+
});
51+
});

eventarc/generic/test/deploy.sh

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#!/usr/bin/env bash
2+
3+
# Copyright 2020 Google LLC.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
set -eo pipefail;
18+
19+
requireEnv() {
20+
test "${!1}" || (echo "Environment Variable '$1' not found" && exit 1)
21+
}
22+
23+
requireEnv SERVICE_NAME
24+
requireEnv CONTAINER_IMAGE
25+
26+
# Deploy the service
27+
set -x
28+
gcloud run deploy "${SERVICE_NAME}" \
29+
--image="${CONTAINER_IMAGE}" \
30+
--region="${REGION:-us-central1}" \
31+
${FLAGS} \
32+
--platform=managed \
33+
--quiet
34+
set +x
35+
36+
echo 'Cloud Run Links:'
37+
echo "- Logs: https://console.cloud.google.com/logs/viewer?project=${GOOGLE_CLOUD_PROJECT}&resource=cloud_run_revision%2Fservice_name%2F${SERVICE_NAME}"
38+
echo "- Console: https://console.cloud.google.com/run/detail/${REGION:-us-central1}/${SERVICE_NAME}/metrics?project=${GOOGLE_CLOUD_PROJECT}"

eventarc/generic/test/runner.sh

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#!/usr/bin/env bash
2+
3+
# Copyright 2020 Google LLC.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
set -eo pipefail;
18+
19+
requireEnv() {
20+
test "${!1}" || (echo "Environment Variable '$1' not found" && exit 1)
21+
}
22+
requireEnv SERVICE_NAME
23+
24+
echo '---'
25+
test/deploy.sh
26+
27+
echo
28+
echo '---'
29+
echo
30+
31+
# Register post-test cleanup.
32+
# Only needed if deploy completed.
33+
function cleanup {
34+
set -x
35+
gcloud run services delete ${SERVICE_NAME} \
36+
--platform=managed \
37+
--region="${REGION:-us-central1}" \
38+
--quiet
39+
}
40+
trap cleanup EXIT
41+
42+
# TODO: Perform authentication inside the test.
43+
export ID_TOKEN=$(gcloud auth print-identity-token)
44+
export BASE_URL=$(test/url.sh)
45+
46+
test -z "$BASE_URL" && echo "BASE_URL value is empty" && exit 1
47+
48+
# Do not use exec to preserve trap behavior.
49+
"$@"

eventarc/generic/test/system.test.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Copyright 2019 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
const assert = require('assert');
16+
const got = require('got');
17+
const {resolve} = require('url');
18+
19+
const request = (method, route, base_url) => {
20+
const {ID_TOKEN} = process.env;
21+
if (!ID_TOKEN) {
22+
throw Error('"ID_TOKEN" environment variable is required.');
23+
}
24+
25+
return got(resolve(base_url.trim(), route), {
26+
headers: {
27+
Authorization: `Bearer ${ID_TOKEN.trim()}`,
28+
},
29+
method: method || 'get',
30+
throwHttpErrors: false,
31+
});
32+
};
33+
34+
describe('End-to-End Tests', () => {
35+
const {BASE_URL} = process.env;
36+
if (!BASE_URL) {
37+
throw Error(
38+
'"BASE_URL" environment variable is required. For example: https://service-x8xabcdefg-uc.a.run.app'
39+
);
40+
}
41+
42+
it('post(/) without request parameters is a bad request', async () => {
43+
const response = await request('post', '/', BASE_URL);
44+
assert.strictEqual(
45+
response.statusCode,
46+
400,
47+
'Bad Requests status not found'
48+
);
49+
});
50+
});

eventarc/generic/test/url.sh

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#!/usr/bin/env bash
2+
3+
# Copyright 2020 Google LLC.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
set -eo pipefail;
18+
19+
requireEnv() {
20+
test "${!1}" || (echo "Environment Variable '$1' not found" && exit 1)
21+
}
22+
23+
requireEnv SERVICE_NAME
24+
25+
set -x
26+
gcloud run services \
27+
describe "${SERVICE_NAME}" \
28+
--region="${REGION:-us-central1}" \
29+
--format='value(status.url)' \
30+
--platform=managed

0 commit comments

Comments
 (0)