Skip to content

Commit c029cd5

Browse files
author
Kenneth Rosario Acevedo
committed
chore(functions/v2/tips/retry): create new cloud event sample from background sample
1 parent 9d7a533 commit c029cd5

File tree

4 files changed

+232
-0
lines changed

4 files changed

+232
-0
lines changed

functions/v2/tips/retry/index.js

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Copyright 2023 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 functions_cloudevent_tips_retry]
16+
const functions = require('@google-cloud/functions-framework');
17+
18+
/**
19+
* Register a Cloud Event Function that demonstrates
20+
* how to toggle retries using a promise
21+
*
22+
* @param {object} event The Cloud Event for the function trigger.
23+
*/
24+
functions.cloudEvent('retryPromise', cloudEvent => {
25+
// The Pub/Sub event payload is passed as the CloudEvent's data payload.
26+
// See the documentation for more details:
27+
// https://cloud.google.com/eventarc/docs/cloudevents#pubsub
28+
const base64PubsubMessage = cloudEvent.data.message.data;
29+
const jsonString = Buffer.from(base64PubsubMessage, 'base64').toString();
30+
31+
const tryAgain = JSON.parse(jsonString).retry;
32+
33+
if (tryAgain) {
34+
throw new Error('Retrying...');
35+
} else {
36+
console.error('Not retrying...');
37+
return Promise.resolve();
38+
}
39+
});
40+
41+
/**
42+
* Cloud Event Function that demonstrates
43+
* how to toggle retries using a callback
44+
*
45+
* @param {object} event The Cloud Event for the function trigger.
46+
* @param {function} callback The callback function.
47+
*/
48+
functions.cloudEvent('retryCallback', (cloudEvent, callback) => {
49+
// The Pub/Sub event payload is passed as the CloudEvent's data payload.
50+
// See the documentation for more details:
51+
// https://cloud.google.com/eventarc/docs/cloudevents#pubsub
52+
const base64PubsubMessage = cloudEvent.data.message.data;
53+
const jsonString = Buffer.from(base64PubsubMessage, 'base64').toString();
54+
55+
const tryAgain = JSON.parse(jsonString).retry;
56+
const err = new Error('Error!');
57+
58+
if (tryAgain) {
59+
console.error('Retrying:', err);
60+
callback(err);
61+
} else {
62+
console.error('Not retrying:', err);
63+
callback();
64+
}
65+
});
66+
// [END functions_cloudevent_tips_retry]

functions/v2/tips/retry/package.json

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"name": "nodejs-docs-samples-functions-tips-retry",
3+
"version": "0.0.1",
4+
"private": true,
5+
"license": "Apache-2.0",
6+
"author": "Google Inc.",
7+
"repository": {
8+
"type": "git",
9+
"url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git"
10+
},
11+
"engines": {
12+
"node": ">=12.0.0"
13+
},
14+
"scripts": {
15+
"test": "mocha test/*.test.js --timeout=60000 --exit"
16+
},
17+
"devDependencies": {
18+
"mocha": "^9.0.0",
19+
"sinon": "^15.0.0",
20+
"supertest": "^6.3.3"
21+
},
22+
"dependencies": {
23+
"@google-cloud/functions-framework": "^3.1.3"
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// Copyright 2023 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+
const supertest = require('supertest');
16+
const functionsFramework = require('@google-cloud/functions-framework/testing');
17+
18+
require('..');
19+
20+
const jsonRetryObject = JSON.stringify({retry: true});
21+
const encodedRetryMessage = Buffer.from(jsonRetryObject).toString('base64');
22+
23+
const jsonDontRetryObject = JSON.stringify({retry: false});
24+
const encodedDontRetryMessage =
25+
Buffer.from(jsonDontRetryObject).toString('base64');
26+
27+
describe('functions_cloudevent_tips_retry', () => {
28+
it('should raise error to retry', async () => {
29+
const cloudEventData = {data: {message: {}}};
30+
cloudEventData.data.message.data = encodedRetryMessage;
31+
32+
const promiseServer = functionsFramework.getTestServer('retryPromise');
33+
await supertest(promiseServer)
34+
.post('/')
35+
.send(cloudEventData)
36+
.set('Content-Type', 'application/json')
37+
.expect(500);
38+
39+
const callBackServer = functionsFramework.getTestServer('retryCallback');
40+
await supertest(callBackServer)
41+
.post('/')
42+
.send(cloudEventData)
43+
.set('Content-Type', 'application/json')
44+
.expect(500);
45+
});
46+
47+
it('should not raise error to not retry', async () => {
48+
const cloudEventData = {data: {message: {}}};
49+
cloudEventData.data.message.data = encodedDontRetryMessage;
50+
51+
const promiseServer = functionsFramework.getTestServer('retryPromise');
52+
await supertest(promiseServer)
53+
.post('/')
54+
.send(cloudEventData)
55+
.set('Content-Type', 'application/json')
56+
.expect(204);
57+
58+
const callBackServer = functionsFramework.getTestServer('retryCallback');
59+
await supertest(callBackServer)
60+
.post('/')
61+
.send(cloudEventData)
62+
.set('Content-Type', 'application/json')
63+
.expect(204);
64+
});
65+
});
+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Copyright 2023 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+
'use strict';
16+
17+
const {getFunction} = require('@google-cloud/functions-framework/testing');
18+
const sinon = require('sinon');
19+
const assert = require('assert');
20+
require('..');
21+
22+
const jsonRetryObject = JSON.stringify({retry: true});
23+
const encodedRetryMessage = Buffer.from(jsonRetryObject).toString('base64');
24+
25+
const jsonDontRetryObject = JSON.stringify({retry: false});
26+
const encodedDontRetryMessage =
27+
Buffer.from(jsonDontRetryObject).toString('base64');
28+
29+
describe('functions_cloudevent_tips_retry', () => {
30+
it('should demonstrate retry behavior for a promise', async () => {
31+
const retryPromise = getFunction('retryPromise');
32+
33+
// Retry by throwing an error
34+
assert.throws(() => {
35+
retryPromise({
36+
data: {
37+
message: {
38+
data: encodedRetryMessage,
39+
},
40+
},
41+
});
42+
}, new Error('Retrying...'));
43+
44+
// Terminate by returning a rejected promise
45+
try {
46+
await retryPromise({data: {message: {data: encodedDontRetryMessage}}});
47+
} catch (err) {
48+
assert.strictEqual(err.message, 'Not retrying...');
49+
return Promise.resolve();
50+
}
51+
});
52+
53+
it('should demonstrate retry behavior for a callback', done => {
54+
const retryCallback = getFunction('retryCallback');
55+
const cb = sinon.stub();
56+
const err = new Error('Error!');
57+
58+
// Retry by passing an error to the callback
59+
retryCallback(
60+
{
61+
data: {
62+
message: {
63+
data: encodedRetryMessage,
64+
},
65+
},
66+
},
67+
cb
68+
);
69+
assert.deepStrictEqual(cb.firstCall.args, [err]);
70+
71+
// Terminate by passing nothing to the callback
72+
retryCallback({data: {message: {data: encodedDontRetryMessage}}}, cb);
73+
assert.deepStrictEqual(cb.secondCall.args, []);
74+
done();
75+
});
76+
});

0 commit comments

Comments
 (0)