Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Tasks Samples for App Engine #676

Merged
merged 12 commits into from
Jun 28, 2018
45 changes: 45 additions & 0 deletions appengine/cloudtasks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this correct? Further down we check for GCP_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:
Expand Down
13 changes: 13 additions & 0 deletions appengine/cloudtasks/app.flexible.yaml
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion appengine/cloudtasks/app.standard.yaml
Original file line number Diff line number Diff line change
@@ -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
Expand Down
92 changes: 48 additions & 44 deletions appengine/cloudtasks/createTask.js
Original file line number Diff line number Diff line change
@@ -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]
}

Expand Down
13 changes: 6 additions & 7 deletions appengine/cloudtasks/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,21 @@
"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,
"requiresProjectId": true,
"test": {
"app": {
"msg": "Hello, world!",
"msg": "Hello, World!",
"args": [
"server.js"
]
Expand Down
4 changes: 2 additions & 2 deletions appengine/cloudtasks/server.js
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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) => {
Expand Down
80 changes: 30 additions & 50 deletions appengine/cloudtasks/test/createTask.test.js
Original file line number Diff line number Diff line change
@@ -1,61 +1,41 @@
/**
* 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 {
Copy link
Contributor

@fhinkel fhinkel Jun 25, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we fit this in one line or is it too long? If it is too long, I think it should be written as

const {runAsync} = 
  require(...);

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'));
});