From fb0b2ec668dd3a61e60d53ded46e04454ab738dd Mon Sep 17 00:00:00 2001 From: Averi Kitsch Date: Thu, 21 Jun 2018 15:10:32 -0700 Subject: [PATCH 01/10] update license --- appengine/cloudtasks/app.flexible.yaml | 13 +++++++++++++ appengine/cloudtasks/app.standard.yaml | 2 +- appengine/cloudtasks/server.js | 4 ++-- appengine/cloudtasks/test/createTask.test.js | 2 +- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/appengine/cloudtasks/app.flexible.yaml b/appengine/cloudtasks/app.flexible.yaml index f1774cbf7f..4b39439b00 100644 --- a/appengine/cloudtasks/app.flexible.yaml +++ b/appengine/cloudtasks/app.flexible.yaml @@ -1,2 +1,15 @@ +# Copyright 2018, Google, Inc. +# 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. + env: flex runtime: nodejs diff --git a/appengine/cloudtasks/app.standard.yaml b/appengine/cloudtasks/app.standard.yaml index 8f8f6fd97a..e938832ccb 100644 --- a/appengine/cloudtasks/app.standard.yaml +++ b/appengine/cloudtasks/app.standard.yaml @@ -1,4 +1,4 @@ -# Copyright 2017, Google, Inc. +# Copyright 2018, Google, Inc. # 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 diff --git a/appengine/cloudtasks/server.js b/appengine/cloudtasks/server.js index 89b196ed4f..4f110fbfdd 100644 --- a/appengine/cloudtasks/server.js +++ b/appengine/cloudtasks/server.js @@ -1,5 +1,5 @@ /** - * Copyright 2017, Google, Inc. + * Copyright 2018, Google, Inc. * 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 @@ -28,7 +28,7 @@ app.use(bodyParser.text()); app.get('/', (req, res, next) => { // Basic index to verify app is serving - res.send('Hello, world!').end(); + res.send('Hello, World!').end(); }); app.post('/log_payload', (req, res, next) => { diff --git a/appengine/cloudtasks/test/createTask.test.js b/appengine/cloudtasks/test/createTask.test.js index 401204259f..237132c112 100644 --- a/appengine/cloudtasks/test/createTask.test.js +++ b/appengine/cloudtasks/test/createTask.test.js @@ -1,5 +1,5 @@ /** - * Copyright 2017, Google, Inc. + * Copyright 2018, Google, Inc. * 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 From fad659a1073249074c1c029307ca662464e2dfcd Mon Sep 17 00:00:00 2001 From: Averi Kitsch Date: Thu, 21 Jun 2018 15:11:55 -0700 Subject: [PATCH 02/10] updated with client library --- appengine/cloudtasks/README.md | 45 ++++++++ appengine/cloudtasks/createTask.js | 176 +++++++++++++++-------------- appengine/cloudtasks/package.json | 11 +- 3 files changed, 140 insertions(+), 92 deletions(-) diff --git a/appengine/cloudtasks/README.md b/appengine/cloudtasks/README.md index 6119bfa4c1..95754b4391 100644 --- a/appengine/cloudtasks/README.md +++ b/appengine/cloudtasks/README.md @@ -86,6 +86,51 @@ HTTP POST request and logs it. The log output can be viewed with: ## Running the Samples +Set environment variables: + +First, your project ID: + +``` +export PROJECT_ID=my-project-id +``` + +Then the queue ID, as specified at queue creation time. Queue IDs already +created can be listed with `gcloud alpha tasks queues list`. + +``` +export QUEUE_ID=my-appengine-queue +``` + +And finally the location ID, which can be discovered with +`gcloud alpha tasks queues describe $QUEUE_ID`, with the location embedded in +the "name" value (for instance, if the name is +"projects/my-project/locations/us-central1/queues/my-appengine-queue", then the +location is "us-central1"). + +``` +export LOCATION_ID=us-central1 +``` + +Create a task, targeted at the `log_payload` endpoint, with a payload specified: + +``` +node createTask.js --project=$PROJECT_ID --queue=$QUEUE_ID --location=$LOCATION_ID --payload=hello +``` + +Now view that the payload was received and verify the payload: + +``` +gcloud app logs read +``` + +Create a task that will be scheduled for a time in the future using the +`--in_seconds` flag: + +``` +node createTask.js --project=$PROJECT_ID --queue=$QUEUE_ID --location=$LOCATION_ID --payload=hello --in_seconds=30 +``` + + To get usage information: `node createTask.js --help` Which prints: diff --git a/appengine/cloudtasks/createTask.js b/appengine/cloudtasks/createTask.js index d329a6e62e..ed0a509b09 100644 --- a/appengine/cloudtasks/createTask.js +++ b/appengine/cloudtasks/createTask.js @@ -1,105 +1,109 @@ /** - * Copyright 2017, Google, Inc. - * 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. - */ +* Copyright 2018, Google, Inc. +* 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. +*/ 'use strict'; -const {google} = require('googleapis'); -const cloudtasks = google.cloudtasks('v2beta2'); - /** - * Create a task for a given queue with an arbitrary payload. - */ +* Create a task for a given queue with an arbitrary payload. +*/ function createTask (project, location, queue, options) { // [START cloud_tasks_appengine_create_task] - google.auth.getClient({ - scopes: ['https://www.googleapis.com/auth/cloud-platform'] - }).then(authClient => { - const task = { - app_engine_http_request: { - http_method: 'POST', - relative_url: '/log_payload' - } - }; + // Imports the Google Cloud Tasks library. + const cloudTasks = require('@google-cloud/tasks'); - if (options.payload !== undefined) { - task.app_engine_http_request.payload = Buffer.from(options.payload).toString('base64'); - } + // Instantiates a client. + const client = new cloudTasks.CloudTasksClient(); + + // Construct the fully qualified queue name. + const parent = client.queuePath(project, location, queue); - if (options.inSeconds !== undefined) { - task.schedule_time = (new Date(options.inSeconds * 1000 + Date.now())).toISOString(); + const task = { + appEngineHttpRequest: { + httpMethod: 'POST', + relativeUrl: '/log_payload' } + }; - const request = { - parent: `projects/${project}/locations/${location}/queues/${queue}`, // TODO: Update placeholder value. - resource: { - task: task - }, - auth: authClient + if (options.payload !== undefined) { + task.appEngineHttpRequest.payload = Buffer.from(options.payload).toString('base64'); + } + + if (options.inSeconds !== undefined) { + task.scheduleTime = { + seconds: (options.inSeconds + Date.now() / 1000) }; + } + + const request = { + parent: parent, + task: task + }; - console.log('Sending task %j', task); - return cloudtasks.projects.locations.queues.tasks.create(request); - }).then(response => { - console.log('Created task.', response.name); - console.log(JSON.stringify(response, null, 2)); - }).catch(console.error); - // [END cloud_tasks_appengine_create_task] + console.log('Sending task %j', task); + // Send create task request. + client.createTask(request).then(response => { + const task = response[0].name; + console.log(`Created task ${task}`); + }).catch(err => { + console.error(`Error in createTask: ${err.message || err}`); + }); +// [END cloud_tasks_appengine_create_task] } const cli = require(`yargs`) - .options({ - location: { - alias: 'l', - description: 'Location of the queue to add the task to.', - type: 'string', - requiresArg: true, - required: true - }, - queue: { - alias: 'q', - description: 'ID (short name) of the queue to add the task to.', - type: 'string', - requiresArg: true, - required: true - }, - project: { - alias: 'p', - description: 'Project of the queue to add the task to.', - default: process.env.GCLOUD_PROJECT, - type: 'string', - requiresArg: true, - required: true - }, - payload: { - alias: 'd', - description: '(Optional) Payload to attach to the push queue.', - type: 'string', - requiresArg: true - }, - inSeconds: { - alias: 's', - description: '(Optional) The number of seconds from now to schedule task attempt.', - type: 'number', - requiresArg: true - } - }) - .example(`node $0 --project my-project-id`) - .wrap(120) - .recommendCommands() - .epilogue(`For more information, see https://cloud.google.com/cloud-tasks`) - .strict(); +.options({ + location: { + alias: 'l', + description: 'Location of the queue to add the task to.', + type: 'string', + requiresArg: true, + required: true + }, + queue: { + alias: 'q', + description: 'ID (short name) of the queue to add the task to.', + type: 'string', + requiresArg: true, + required: true + }, + project: { + alias: 'p', + description: 'Project of the queue to add the task to.', + default: process.env.GCLOUD_PROJECT, + type: 'string', + requiresArg: true, + required: true + }, + payload: { + alias: 'd', + description: '(Optional) Payload to attach to the push queue.', + type: 'string', + requiresArg: true + }, + inSeconds: { + alias: 's', + description: '(Optional) The number of seconds from now to schedule task attempt.', + type: 'number', + requiresArg: true + } +}) +.example(`node $0 --project my-project-id`) +.wrap(120) +.recommendCommands() +.epilogue(`For more information, see https://cloud.google.com/cloud-tasks`) +.strict(); if (module === require.main) { const opts = cli.help().parse(process.argv.slice(2)); diff --git a/appengine/cloudtasks/package.json b/appengine/cloudtasks/package.json index 812536ff3f..0f287a43fd 100644 --- a/appengine/cloudtasks/package.json +++ b/appengine/cloudtasks/package.json @@ -18,15 +18,14 @@ "test": "repo-tools test run --cmd npm -- run all-test" }, "dependencies": { - "body-parser": "1.18.2", - "express": "4.16.2", - "googleapis": "29.0.0", + "body-parser": "^1.18.3", + "express": "4.16.3", "yargs": "11.0.0" }, "devDependencies": { - "@google-cloud/nodejs-repo-tools": "2.2.1", - "proxyquire": "2.0.0", - "sinon": "4.4.2" + "@google-cloud/nodejs-repo-tools": "2.3.0", + "proxyquire": "2.0.1", + "sinon": "6.0.0" }, "cloud-repo-tools": { "requiresKeyFile": true, From 0b0e4507637e087fad7e0128ee9ad8883473cb43 Mon Sep 17 00:00:00 2001 From: Averi Kitsch Date: Thu, 21 Jun 2018 15:45:00 -0700 Subject: [PATCH 03/10] passing tests --- appengine/cloudtasks/createTask.js | 84 ++++++++++---------- appengine/cloudtasks/package.json | 2 +- appengine/cloudtasks/test/createTask.test.js | 80 +++++++------------ 3 files changed, 73 insertions(+), 93 deletions(-) diff --git a/appengine/cloudtasks/createTask.js b/appengine/cloudtasks/createTask.js index ed0a509b09..cc30c62f86 100644 --- a/appengine/cloudtasks/createTask.js +++ b/appengine/cloudtasks/createTask.js @@ -59,51 +59,51 @@ function createTask (project, location, queue, options) { }).catch(err => { console.error(`Error in createTask: ${err.message || err}`); }); -// [END cloud_tasks_appengine_create_task] + // [END cloud_tasks_appengine_create_task] } const cli = require(`yargs`) -.options({ - location: { - alias: 'l', - description: 'Location of the queue to add the task to.', - type: 'string', - requiresArg: true, - required: true - }, - queue: { - alias: 'q', - description: 'ID (short name) of the queue to add the task to.', - type: 'string', - requiresArg: true, - required: true - }, - project: { - alias: 'p', - description: 'Project of the queue to add the task to.', - default: process.env.GCLOUD_PROJECT, - type: 'string', - requiresArg: true, - required: true - }, - payload: { - alias: 'd', - description: '(Optional) Payload to attach to the push queue.', - type: 'string', - requiresArg: true - }, - inSeconds: { - alias: 's', - description: '(Optional) The number of seconds from now to schedule task attempt.', - type: 'number', - requiresArg: true - } -}) -.example(`node $0 --project my-project-id`) -.wrap(120) -.recommendCommands() -.epilogue(`For more information, see https://cloud.google.com/cloud-tasks`) -.strict(); + .options({ + location: { + alias: 'l', + description: 'Location of the queue to add the task to.', + type: 'string', + requiresArg: true, + required: true + }, + queue: { + alias: 'q', + description: 'ID (short name) of the queue to add the task to.', + type: 'string', + requiresArg: true, + required: true + }, + project: { + alias: 'p', + description: 'Project of the queue to add the task to.', + default: process.env.GCLOUD_PROJECT, + type: 'string', + requiresArg: true, + required: true + }, + payload: { + alias: 'd', + description: '(Optional) Payload to attach to the push queue.', + type: 'string', + requiresArg: true + }, + inSeconds: { + alias: 's', + description: '(Optional) The number of seconds from now to schedule task attempt.', + type: 'number', + requiresArg: true + } + }) + .example(`node $0 --project my-project-id`) + .wrap(120) + .recommendCommands() + .epilogue(`For more information, see https://cloud.google.com/cloud-tasks`) + .strict(); if (module === require.main) { const opts = cli.help().parse(process.argv.slice(2)); diff --git a/appengine/cloudtasks/package.json b/appengine/cloudtasks/package.json index 0f287a43fd..1746537883 100644 --- a/appengine/cloudtasks/package.json +++ b/appengine/cloudtasks/package.json @@ -32,7 +32,7 @@ "requiresProjectId": true, "test": { "app": { - "msg": "Hello, world!", + "msg": "Hello, World!", "args": [ "server.js" ] diff --git a/appengine/cloudtasks/test/createTask.test.js b/appengine/cloudtasks/test/createTask.test.js index 237132c112..20f24e731c 100644 --- a/appengine/cloudtasks/test/createTask.test.js +++ b/appengine/cloudtasks/test/createTask.test.js @@ -1,61 +1,41 @@ /** - * Copyright 2018, Google, Inc. - * 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. - */ +* Copyright 2018, Google, Inc. +* 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. +*/ 'use strict'; -const proxyquire = require(`proxyquire`).noCallThru(); -const sinon = require(`sinon`); +const path = require(`path`); const test = require(`ava`); const tools = require(`@google-cloud/nodejs-repo-tools`); -test.before(tools.stubConsole); -test.after.always(tools.restoreConsole); +const { + runAsync +} = require(`@google-cloud/nodejs-repo-tools`); -test.cb(`should create a task`, (t) => { - const responseMock = { - name: 'foo' - }; - const cloudtasksMock = { - projects: { - locations: { - queues: { - tasks: { - create: sinon.stub().yields(responseMock) - } - } - } - } - }; - const authClientMock = {}; +const PROJECT_ID = process.env.GCLOUD_PROJECT; +const QUEUE = process.env.GCP_QUEUE || 'my-appengine-queue'; +const cmd = `node createTask.js`; +const cwd = path.join(__dirname, `..`); - const util = proxyquire(`../createTask`, { - googleapis: { - google: { - cloudtasks: sinon.stub().returns(cloudtasksMock), - auth: { - getApplicationDefault: sinon.stub().yields(null, authClientMock) - } - } - } - }); - - util.createTask('p', 'l', 'q', {}); +test.before((t) => { + if (!QUEUE) { + t.fail(`You must set the GCP_QUEUE environment variable!`); + } +}); +test.before(tools.checkCredentials); - setTimeout(() => { - t.true(console.log.called); - t.is(cloudtasksMock.projects.locations.queues.tasks.create.callCount, 1); - t.end(); - }, 500); +test.serial(`should create a task`, async (t) => { + const output = await runAsync(`${cmd} --project=${PROJECT_ID} --location=us-central1 --queue=${QUEUE}`, cwd); + t.true(output.includes('Created task')); }); From 57903b649b43bb1040d3e0d5ad10c6f7e51d8f2c Mon Sep 17 00:00:00 2001 From: Averi Kitsch Date: Mon, 25 Jun 2018 13:06:06 -0700 Subject: [PATCH 04/10] update env var for QUEUE --- appengine/cloudtasks/package.json | 1 + appengine/cloudtasks/test/createTask.test.js | 8 +++----- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/appengine/cloudtasks/package.json b/appengine/cloudtasks/package.json index 1746537883..9c271f66bd 100644 --- a/appengine/cloudtasks/package.json +++ b/appengine/cloudtasks/package.json @@ -18,6 +18,7 @@ "test": "repo-tools test run --cmd npm -- run all-test" }, "dependencies": { + "@google-cloud/tasks": "0.1.0", "body-parser": "^1.18.3", "express": "4.16.3", "yargs": "11.0.0" diff --git a/appengine/cloudtasks/test/createTask.test.js b/appengine/cloudtasks/test/createTask.test.js index 20f24e731c..697600a80b 100644 --- a/appengine/cloudtasks/test/createTask.test.js +++ b/appengine/cloudtasks/test/createTask.test.js @@ -19,18 +19,16 @@ const path = require(`path`); const test = require(`ava`); const tools = require(`@google-cloud/nodejs-repo-tools`); -const { - runAsync -} = require(`@google-cloud/nodejs-repo-tools`); +const {runAsync} = require(`@google-cloud/nodejs-repo-tools`); const PROJECT_ID = process.env.GCLOUD_PROJECT; -const QUEUE = process.env.GCP_QUEUE || 'my-appengine-queue'; +const QUEUE = process.env.QUEUE_ID || 'my-appengine-queue'; const cmd = `node createTask.js`; const cwd = path.join(__dirname, `..`); test.before((t) => { if (!QUEUE) { - t.fail(`You must set the GCP_QUEUE environment variable!`); + t.fail(`You must set the QUEUE_ID environment variable!`); } }); test.before(tools.checkCredentials); From 56e9daf438e1a421e5e067ff88b9ef53e68f2707 Mon Sep 17 00:00:00 2001 From: Averi Kitsch Date: Wed, 27 Jun 2018 20:08:03 -0700 Subject: [PATCH 05/10] upgrade packages --- appengine/cloudtasks/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appengine/cloudtasks/package.json b/appengine/cloudtasks/package.json index 9c271f66bd..5cfdf1a977 100644 --- a/appengine/cloudtasks/package.json +++ b/appengine/cloudtasks/package.json @@ -18,7 +18,7 @@ "test": "repo-tools test run --cmd npm -- run all-test" }, "dependencies": { - "@google-cloud/tasks": "0.1.0", + "@google-cloud/tasks": "^0.1.0", "body-parser": "^1.18.3", "express": "4.16.3", "yargs": "11.0.0" @@ -26,7 +26,7 @@ "devDependencies": { "@google-cloud/nodejs-repo-tools": "2.3.0", "proxyquire": "2.0.1", - "sinon": "6.0.0" + "sinon": "6.0.1" }, "cloud-repo-tools": { "requiresKeyFile": true, From b1529c439ed372580b5e2f5d363cf7422621dc79 Mon Sep 17 00:00:00 2001 From: Averi Kitsch Date: Thu, 21 Jun 2018 15:10:32 -0700 Subject: [PATCH 06/10] update license --- appengine/cloudtasks/app.flexible.yaml | 13 +++++++++++++ appengine/cloudtasks/app.standard.yaml | 2 +- appengine/cloudtasks/server.js | 4 ++-- appengine/cloudtasks/test/createTask.test.js | 2 +- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/appengine/cloudtasks/app.flexible.yaml b/appengine/cloudtasks/app.flexible.yaml index f1774cbf7f..4b39439b00 100644 --- a/appengine/cloudtasks/app.flexible.yaml +++ b/appengine/cloudtasks/app.flexible.yaml @@ -1,2 +1,15 @@ +# Copyright 2018, Google, Inc. +# 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. + env: flex runtime: nodejs diff --git a/appengine/cloudtasks/app.standard.yaml b/appengine/cloudtasks/app.standard.yaml index 8f8f6fd97a..e938832ccb 100644 --- a/appengine/cloudtasks/app.standard.yaml +++ b/appengine/cloudtasks/app.standard.yaml @@ -1,4 +1,4 @@ -# Copyright 2017, Google, Inc. +# Copyright 2018, Google, Inc. # 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 diff --git a/appengine/cloudtasks/server.js b/appengine/cloudtasks/server.js index 89b196ed4f..4f110fbfdd 100644 --- a/appengine/cloudtasks/server.js +++ b/appengine/cloudtasks/server.js @@ -1,5 +1,5 @@ /** - * Copyright 2017, Google, Inc. + * Copyright 2018, Google, Inc. * 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 @@ -28,7 +28,7 @@ app.use(bodyParser.text()); app.get('/', (req, res, next) => { // Basic index to verify app is serving - res.send('Hello, world!').end(); + res.send('Hello, World!').end(); }); app.post('/log_payload', (req, res, next) => { diff --git a/appengine/cloudtasks/test/createTask.test.js b/appengine/cloudtasks/test/createTask.test.js index 401204259f..237132c112 100644 --- a/appengine/cloudtasks/test/createTask.test.js +++ b/appengine/cloudtasks/test/createTask.test.js @@ -1,5 +1,5 @@ /** - * Copyright 2017, Google, Inc. + * Copyright 2018, Google, Inc. * 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 From 4f5ae7e98c5a9a9d939bec920e7b5c4d0eae415e Mon Sep 17 00:00:00 2001 From: Averi Kitsch Date: Thu, 21 Jun 2018 15:11:55 -0700 Subject: [PATCH 07/10] updated with client library --- appengine/cloudtasks/README.md | 45 ++++++++ appengine/cloudtasks/createTask.js | 176 +++++++++++++++-------------- appengine/cloudtasks/package.json | 11 +- 3 files changed, 140 insertions(+), 92 deletions(-) diff --git a/appengine/cloudtasks/README.md b/appengine/cloudtasks/README.md index 6119bfa4c1..95754b4391 100644 --- a/appengine/cloudtasks/README.md +++ b/appengine/cloudtasks/README.md @@ -86,6 +86,51 @@ HTTP POST request and logs it. The log output can be viewed with: ## Running the Samples +Set environment variables: + +First, your project ID: + +``` +export PROJECT_ID=my-project-id +``` + +Then the queue ID, as specified at queue creation time. Queue IDs already +created can be listed with `gcloud alpha tasks queues list`. + +``` +export QUEUE_ID=my-appengine-queue +``` + +And finally the location ID, which can be discovered with +`gcloud alpha tasks queues describe $QUEUE_ID`, with the location embedded in +the "name" value (for instance, if the name is +"projects/my-project/locations/us-central1/queues/my-appengine-queue", then the +location is "us-central1"). + +``` +export LOCATION_ID=us-central1 +``` + +Create a task, targeted at the `log_payload` endpoint, with a payload specified: + +``` +node createTask.js --project=$PROJECT_ID --queue=$QUEUE_ID --location=$LOCATION_ID --payload=hello +``` + +Now view that the payload was received and verify the payload: + +``` +gcloud app logs read +``` + +Create a task that will be scheduled for a time in the future using the +`--in_seconds` flag: + +``` +node createTask.js --project=$PROJECT_ID --queue=$QUEUE_ID --location=$LOCATION_ID --payload=hello --in_seconds=30 +``` + + To get usage information: `node createTask.js --help` Which prints: diff --git a/appengine/cloudtasks/createTask.js b/appengine/cloudtasks/createTask.js index d329a6e62e..ed0a509b09 100644 --- a/appengine/cloudtasks/createTask.js +++ b/appengine/cloudtasks/createTask.js @@ -1,105 +1,109 @@ /** - * Copyright 2017, Google, Inc. - * 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. - */ +* Copyright 2018, Google, Inc. +* 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. +*/ 'use strict'; -const {google} = require('googleapis'); -const cloudtasks = google.cloudtasks('v2beta2'); - /** - * Create a task for a given queue with an arbitrary payload. - */ +* Create a task for a given queue with an arbitrary payload. +*/ function createTask (project, location, queue, options) { // [START cloud_tasks_appengine_create_task] - google.auth.getClient({ - scopes: ['https://www.googleapis.com/auth/cloud-platform'] - }).then(authClient => { - const task = { - app_engine_http_request: { - http_method: 'POST', - relative_url: '/log_payload' - } - }; + // Imports the Google Cloud Tasks library. + const cloudTasks = require('@google-cloud/tasks'); - if (options.payload !== undefined) { - task.app_engine_http_request.payload = Buffer.from(options.payload).toString('base64'); - } + // Instantiates a client. + const client = new cloudTasks.CloudTasksClient(); + + // Construct the fully qualified queue name. + const parent = client.queuePath(project, location, queue); - if (options.inSeconds !== undefined) { - task.schedule_time = (new Date(options.inSeconds * 1000 + Date.now())).toISOString(); + const task = { + appEngineHttpRequest: { + httpMethod: 'POST', + relativeUrl: '/log_payload' } + }; - const request = { - parent: `projects/${project}/locations/${location}/queues/${queue}`, // TODO: Update placeholder value. - resource: { - task: task - }, - auth: authClient + if (options.payload !== undefined) { + task.appEngineHttpRequest.payload = Buffer.from(options.payload).toString('base64'); + } + + if (options.inSeconds !== undefined) { + task.scheduleTime = { + seconds: (options.inSeconds + Date.now() / 1000) }; + } + + const request = { + parent: parent, + task: task + }; - console.log('Sending task %j', task); - return cloudtasks.projects.locations.queues.tasks.create(request); - }).then(response => { - console.log('Created task.', response.name); - console.log(JSON.stringify(response, null, 2)); - }).catch(console.error); - // [END cloud_tasks_appengine_create_task] + console.log('Sending task %j', task); + // Send create task request. + client.createTask(request).then(response => { + const task = response[0].name; + console.log(`Created task ${task}`); + }).catch(err => { + console.error(`Error in createTask: ${err.message || err}`); + }); +// [END cloud_tasks_appengine_create_task] } const cli = require(`yargs`) - .options({ - location: { - alias: 'l', - description: 'Location of the queue to add the task to.', - type: 'string', - requiresArg: true, - required: true - }, - queue: { - alias: 'q', - description: 'ID (short name) of the queue to add the task to.', - type: 'string', - requiresArg: true, - required: true - }, - project: { - alias: 'p', - description: 'Project of the queue to add the task to.', - default: process.env.GCLOUD_PROJECT, - type: 'string', - requiresArg: true, - required: true - }, - payload: { - alias: 'd', - description: '(Optional) Payload to attach to the push queue.', - type: 'string', - requiresArg: true - }, - inSeconds: { - alias: 's', - description: '(Optional) The number of seconds from now to schedule task attempt.', - type: 'number', - requiresArg: true - } - }) - .example(`node $0 --project my-project-id`) - .wrap(120) - .recommendCommands() - .epilogue(`For more information, see https://cloud.google.com/cloud-tasks`) - .strict(); +.options({ + location: { + alias: 'l', + description: 'Location of the queue to add the task to.', + type: 'string', + requiresArg: true, + required: true + }, + queue: { + alias: 'q', + description: 'ID (short name) of the queue to add the task to.', + type: 'string', + requiresArg: true, + required: true + }, + project: { + alias: 'p', + description: 'Project of the queue to add the task to.', + default: process.env.GCLOUD_PROJECT, + type: 'string', + requiresArg: true, + required: true + }, + payload: { + alias: 'd', + description: '(Optional) Payload to attach to the push queue.', + type: 'string', + requiresArg: true + }, + inSeconds: { + alias: 's', + description: '(Optional) The number of seconds from now to schedule task attempt.', + type: 'number', + requiresArg: true + } +}) +.example(`node $0 --project my-project-id`) +.wrap(120) +.recommendCommands() +.epilogue(`For more information, see https://cloud.google.com/cloud-tasks`) +.strict(); if (module === require.main) { const opts = cli.help().parse(process.argv.slice(2)); diff --git a/appengine/cloudtasks/package.json b/appengine/cloudtasks/package.json index 812536ff3f..0f287a43fd 100644 --- a/appengine/cloudtasks/package.json +++ b/appengine/cloudtasks/package.json @@ -18,15 +18,14 @@ "test": "repo-tools test run --cmd npm -- run all-test" }, "dependencies": { - "body-parser": "1.18.2", - "express": "4.16.2", - "googleapis": "29.0.0", + "body-parser": "^1.18.3", + "express": "4.16.3", "yargs": "11.0.0" }, "devDependencies": { - "@google-cloud/nodejs-repo-tools": "2.2.1", - "proxyquire": "2.0.0", - "sinon": "4.4.2" + "@google-cloud/nodejs-repo-tools": "2.3.0", + "proxyquire": "2.0.1", + "sinon": "6.0.0" }, "cloud-repo-tools": { "requiresKeyFile": true, From 095910c97b81977f92c237bf266dec1ffd6a5f4b Mon Sep 17 00:00:00 2001 From: Averi Kitsch Date: Thu, 21 Jun 2018 15:45:00 -0700 Subject: [PATCH 08/10] passing tests --- appengine/cloudtasks/createTask.js | 84 ++++++++++---------- appengine/cloudtasks/package.json | 2 +- appengine/cloudtasks/test/createTask.test.js | 80 +++++++------------ 3 files changed, 73 insertions(+), 93 deletions(-) diff --git a/appengine/cloudtasks/createTask.js b/appengine/cloudtasks/createTask.js index ed0a509b09..cc30c62f86 100644 --- a/appengine/cloudtasks/createTask.js +++ b/appengine/cloudtasks/createTask.js @@ -59,51 +59,51 @@ function createTask (project, location, queue, options) { }).catch(err => { console.error(`Error in createTask: ${err.message || err}`); }); -// [END cloud_tasks_appengine_create_task] + // [END cloud_tasks_appengine_create_task] } const cli = require(`yargs`) -.options({ - location: { - alias: 'l', - description: 'Location of the queue to add the task to.', - type: 'string', - requiresArg: true, - required: true - }, - queue: { - alias: 'q', - description: 'ID (short name) of the queue to add the task to.', - type: 'string', - requiresArg: true, - required: true - }, - project: { - alias: 'p', - description: 'Project of the queue to add the task to.', - default: process.env.GCLOUD_PROJECT, - type: 'string', - requiresArg: true, - required: true - }, - payload: { - alias: 'd', - description: '(Optional) Payload to attach to the push queue.', - type: 'string', - requiresArg: true - }, - inSeconds: { - alias: 's', - description: '(Optional) The number of seconds from now to schedule task attempt.', - type: 'number', - requiresArg: true - } -}) -.example(`node $0 --project my-project-id`) -.wrap(120) -.recommendCommands() -.epilogue(`For more information, see https://cloud.google.com/cloud-tasks`) -.strict(); + .options({ + location: { + alias: 'l', + description: 'Location of the queue to add the task to.', + type: 'string', + requiresArg: true, + required: true + }, + queue: { + alias: 'q', + description: 'ID (short name) of the queue to add the task to.', + type: 'string', + requiresArg: true, + required: true + }, + project: { + alias: 'p', + description: 'Project of the queue to add the task to.', + default: process.env.GCLOUD_PROJECT, + type: 'string', + requiresArg: true, + required: true + }, + payload: { + alias: 'd', + description: '(Optional) Payload to attach to the push queue.', + type: 'string', + requiresArg: true + }, + inSeconds: { + alias: 's', + description: '(Optional) The number of seconds from now to schedule task attempt.', + type: 'number', + requiresArg: true + } + }) + .example(`node $0 --project my-project-id`) + .wrap(120) + .recommendCommands() + .epilogue(`For more information, see https://cloud.google.com/cloud-tasks`) + .strict(); if (module === require.main) { const opts = cli.help().parse(process.argv.slice(2)); diff --git a/appengine/cloudtasks/package.json b/appengine/cloudtasks/package.json index 0f287a43fd..1746537883 100644 --- a/appengine/cloudtasks/package.json +++ b/appengine/cloudtasks/package.json @@ -32,7 +32,7 @@ "requiresProjectId": true, "test": { "app": { - "msg": "Hello, world!", + "msg": "Hello, World!", "args": [ "server.js" ] diff --git a/appengine/cloudtasks/test/createTask.test.js b/appengine/cloudtasks/test/createTask.test.js index 237132c112..20f24e731c 100644 --- a/appengine/cloudtasks/test/createTask.test.js +++ b/appengine/cloudtasks/test/createTask.test.js @@ -1,61 +1,41 @@ /** - * Copyright 2018, Google, Inc. - * 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. - */ +* Copyright 2018, Google, Inc. +* 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. +*/ 'use strict'; -const proxyquire = require(`proxyquire`).noCallThru(); -const sinon = require(`sinon`); +const path = require(`path`); const test = require(`ava`); const tools = require(`@google-cloud/nodejs-repo-tools`); -test.before(tools.stubConsole); -test.after.always(tools.restoreConsole); +const { + runAsync +} = require(`@google-cloud/nodejs-repo-tools`); -test.cb(`should create a task`, (t) => { - const responseMock = { - name: 'foo' - }; - const cloudtasksMock = { - projects: { - locations: { - queues: { - tasks: { - create: sinon.stub().yields(responseMock) - } - } - } - } - }; - const authClientMock = {}; +const PROJECT_ID = process.env.GCLOUD_PROJECT; +const QUEUE = process.env.GCP_QUEUE || 'my-appengine-queue'; +const cmd = `node createTask.js`; +const cwd = path.join(__dirname, `..`); - const util = proxyquire(`../createTask`, { - googleapis: { - google: { - cloudtasks: sinon.stub().returns(cloudtasksMock), - auth: { - getApplicationDefault: sinon.stub().yields(null, authClientMock) - } - } - } - }); - - util.createTask('p', 'l', 'q', {}); +test.before((t) => { + if (!QUEUE) { + t.fail(`You must set the GCP_QUEUE environment variable!`); + } +}); +test.before(tools.checkCredentials); - setTimeout(() => { - t.true(console.log.called); - t.is(cloudtasksMock.projects.locations.queues.tasks.create.callCount, 1); - t.end(); - }, 500); +test.serial(`should create a task`, async (t) => { + const output = await runAsync(`${cmd} --project=${PROJECT_ID} --location=us-central1 --queue=${QUEUE}`, cwd); + t.true(output.includes('Created task')); }); From ad09f1f071fdbb9f05b566f38fcf5076da670126 Mon Sep 17 00:00:00 2001 From: Averi Kitsch Date: Mon, 25 Jun 2018 13:06:06 -0700 Subject: [PATCH 09/10] update env var for QUEUE --- appengine/cloudtasks/package.json | 1 + appengine/cloudtasks/test/createTask.test.js | 8 +++----- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/appengine/cloudtasks/package.json b/appengine/cloudtasks/package.json index 1746537883..9c271f66bd 100644 --- a/appengine/cloudtasks/package.json +++ b/appengine/cloudtasks/package.json @@ -18,6 +18,7 @@ "test": "repo-tools test run --cmd npm -- run all-test" }, "dependencies": { + "@google-cloud/tasks": "0.1.0", "body-parser": "^1.18.3", "express": "4.16.3", "yargs": "11.0.0" diff --git a/appengine/cloudtasks/test/createTask.test.js b/appengine/cloudtasks/test/createTask.test.js index 20f24e731c..697600a80b 100644 --- a/appengine/cloudtasks/test/createTask.test.js +++ b/appengine/cloudtasks/test/createTask.test.js @@ -19,18 +19,16 @@ const path = require(`path`); const test = require(`ava`); const tools = require(`@google-cloud/nodejs-repo-tools`); -const { - runAsync -} = require(`@google-cloud/nodejs-repo-tools`); +const {runAsync} = require(`@google-cloud/nodejs-repo-tools`); const PROJECT_ID = process.env.GCLOUD_PROJECT; -const QUEUE = process.env.GCP_QUEUE || 'my-appengine-queue'; +const QUEUE = process.env.QUEUE_ID || 'my-appengine-queue'; const cmd = `node createTask.js`; const cwd = path.join(__dirname, `..`); test.before((t) => { if (!QUEUE) { - t.fail(`You must set the GCP_QUEUE environment variable!`); + t.fail(`You must set the QUEUE_ID environment variable!`); } }); test.before(tools.checkCredentials); From d42c785ffa47558fc57a3f4caaccc036389776e3 Mon Sep 17 00:00:00 2001 From: Averi Kitsch Date: Wed, 27 Jun 2018 20:08:03 -0700 Subject: [PATCH 10/10] upgrade packages --- appengine/cloudtasks/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appengine/cloudtasks/package.json b/appengine/cloudtasks/package.json index 9c271f66bd..5cfdf1a977 100644 --- a/appengine/cloudtasks/package.json +++ b/appengine/cloudtasks/package.json @@ -18,7 +18,7 @@ "test": "repo-tools test run --cmd npm -- run all-test" }, "dependencies": { - "@google-cloud/tasks": "0.1.0", + "@google-cloud/tasks": "^0.1.0", "body-parser": "^1.18.3", "express": "4.16.3", "yargs": "11.0.0" @@ -26,7 +26,7 @@ "devDependencies": { "@google-cloud/nodejs-repo-tools": "2.3.0", "proxyquire": "2.0.1", - "sinon": "6.0.0" + "sinon": "6.0.1" }, "cloud-repo-tools": { "requiresKeyFile": true,