From 28976dcbfd5415efdeac9ee6687f3bb2a918f350 Mon Sep 17 00:00:00 2001
From: Averi Kitsch <akitsch@google.com>
Date: Thu, 28 Jun 2018 12:37:10 -0700
Subject: [PATCH] Update Tasks Samples for App Engine (#676)

* update license

* updated with client library

* passing tests

* update env var for QUEUE

* upgrade packages

* update license

* updated with client library

* passing tests

* update env var for QUEUE

* upgrade packages
---
 appengine/cloudtasks/README.md               | 45 ++++++++++
 appengine/cloudtasks/app.flexible.yaml       | 13 +++
 appengine/cloudtasks/app.standard.yaml       |  2 +-
 appengine/cloudtasks/createTask.js           | 92 ++++++++++----------
 appengine/cloudtasks/package.json            | 14 +--
 appengine/cloudtasks/server.js               |  4 +-
 appengine/cloudtasks/test/createTask.test.js | 78 ++++++-----------
 7 files changed, 144 insertions(+), 104 deletions(-)

diff --git a/appengine/cloudtasks/README.md b/appengine/cloudtasks/README.md
index 6119bfa4c16..95754b43918 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/app.flexible.yaml b/appengine/cloudtasks/app.flexible.yaml
index f1774cbf7fc..4b39439b005 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 8f8f6fd97a6..e938832ccb8 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/createTask.js b/appengine/cloudtasks/createTask.js
index d329a6e62ef..cc30c62f86f 100644
--- a/appengine/cloudtasks/createTask.js
+++ b/appengine/cloudtasks/createTask.js
@@ -1,60 +1,64 @@
 /**
- * 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();
 
-    if (options.inSeconds !== undefined) {
-      task.schedule_time = (new Date(options.inSeconds * 1000 + Date.now())).toISOString();
+  // Construct the fully qualified queue name.
+  const parent = client.queuePath(project, location, queue);
+
+  const task = {
+    appEngineHttpRequest: {
+      httpMethod: 'POST',
+      relativeUrl: '/log_payload'
     }
+  };
+
+  if (options.payload !== undefined) {
+    task.appEngineHttpRequest.payload = Buffer.from(options.payload).toString('base64');
+  }
 
-    const request = {
-      parent: `projects/${project}/locations/${location}/queues/${queue}`, // TODO: Update placeholder value.
-      resource: {
-        task: task
-      },
-      auth: authClient
+  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);
+  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]
 }
 
diff --git a/appengine/cloudtasks/package.json b/appengine/cloudtasks/package.json
index 812536ff3f1..5cfdf1a977c 100644
--- a/appengine/cloudtasks/package.json
+++ b/appengine/cloudtasks/package.json
@@ -18,22 +18,22 @@
     "test": "repo-tools test run --cmd npm -- run all-test"
   },
   "dependencies": {
-    "body-parser": "1.18.2",
-    "express": "4.16.2",
-    "googleapis": "29.0.0",
+    "@google-cloud/tasks": "^0.1.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.1"
   },
   "cloud-repo-tools": {
     "requiresKeyFile": true,
     "requiresProjectId": true,
     "test": {
       "app": {
-        "msg": "Hello, world!",
+        "msg": "Hello, World!",
         "args": [
           "server.js"
         ]
diff --git a/appengine/cloudtasks/server.js b/appengine/cloudtasks/server.js
index 89b196ed4f6..4f110fbfdd3 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 401204259f6..697600a80b6 100644
--- a/appengine/cloudtasks/test/createTask.test.js
+++ b/appengine/cloudtasks/test/createTask.test.js
@@ -1,61 +1,39 @@
 /**
- * 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 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.QUEUE_ID || '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 QUEUE_ID 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'));
 });