Skip to content

Commit

Permalink
Functions (#120)
Browse files Browse the repository at this point in the history
Split hello world "log" samples into separate samples, and added Cloud Functions Pub/Sub, Datastore, and GCS samples.
  • Loading branch information
jmdobry committed Jun 8, 2016
1 parent 92b9cb5 commit b6dd8c0
Show file tree
Hide file tree
Showing 19 changed files with 1,189 additions and 65 deletions.
54 changes: 54 additions & 0 deletions functions/datastore/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<img src="https://avatars2.githubusercontent.com/u/2810941?v=3&s=96" alt="Google Cloud Platform logo" title="Google Cloud Platform" align="right" height="96" width="96"/>

# Google Cloud Functions Cloud Datastore sample

This recipe shows you how to read and write an entity in Datastore from a Cloud Function.

View the [source code][code].

[code]: index.js

## Deploy and Test

1. Follow the [Cloud Functions quickstart guide](https://cloud.google.com/functions/quickstart) to setup Cloud Functions for your project.

1. Clone this repository:

git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git
cd nodejs-docs-samples/functions/datastore

1. Create a Cloud Storage Bucket to stage our deployment:

gsutil mb gs://<your-bucket-name>

1. Ensure the Cloud Datastore API is enabled:

[Click here to enable the Cloud Datastore API](https://console.cloud.google.com/flows/enableapi?apiid=datastore.googleapis.com&redirect=https://github.com/GoogleCloudPlatform/nodejs-docs-samples/tree/master/functions/datastore)

1. Deploy the "ds-get" function with an HTTP trigger:

gcloud alpha functions deploy ds-get --bucket <your-bucket-name> --trigger-http --entry-point get

1. Deploy the "ds-set" function with an HTTP trigger:

gcloud alpha functions deploy ds-set --bucket <your-bucket-name> --trigger-http --entry-point set

1. Deploy the "ds-del" function with an HTTP trigger:

gcloud alpha functions deploy ds-del --bucket <your-bucket-name> --trigger-http --entry-point del

1. Call the "ds-set" function to create a new entity:

gcloud alpha functions call ds-set --data '{"kind":"gcf-test","key":"foobar","value":{"message": "Hello World!"}}'

1. Call the "ds-get" function to read the newly created entity:

gcloud alpha functions call ds-get --data '{"kind":"gcf-test","key":"foobar"}'

1. Call the "ds-del" function to delete the entity:

gcloud alpha functions call ds-del --data '{"kind":"gcf-test","key":"foobar"}'

1. Call the "ds-get" function again to verify it was deleted:

gcloud alpha functions call ds-get --data '{"kind":"gcf-test","key":"foobar"}'
154 changes: 154 additions & 0 deletions functions/datastore/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
// Copyright 2016, 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';

var gcloud = require('gcloud');

// Create a datastore client.
var datastore = gcloud.datastore();

/**
* Gets a Datastore key from the kind/key pair in the request.
*
* @param {Object} requestData Cloud Function request data.
* @param {string} requestData.key Datastore key string.
* @param {string} requestData.kind Datastore kind.
* @returns {Object} Datastore key object.
*/
function getKeyFromRequestData (requestData) {
if (!requestData.key) {
throw new Error('Key not provided. Make sure you have a "key" property ' +
'in your request');
}

if (!requestData.kind) {
throw new Error('Kind not provided. Make sure you have a "kind" property ' +
'in your request');
}

return datastore.key([requestData.kind, requestData.key]);
}

/**
* Creates and/or updates a record.
*
* @example
* gcloud alpha functions call ds-set --data '{"kind":"gcf-test","key":"foobar","value":{"message": "Hello World!"}}'
*
* @param {Object} context Cloud Function context.
* @param {Function} context.success Success callback.
* @param {Function} context.failure Failure callback.
* @param {Object} data Request data, in this case an object provided by the user.
* @param {string} data.kind The Datastore kind of the data to save, e.g. "user".
* @param {string} data.key Key at which to save the data, e.g. 5075192766267392.
* @param {Object} data.value Value to save to Cloud Datastore, e.g. {"name":"John"}
*/
function set (context, data) {
try {
// The value contains a JSON document representing the entity we want to save
if (!data.value) {
throw new Error('Value not provided. Make sure you have a "value" ' +
'property in your request');
}

var key = getKeyFromRequestData(data);

return datastore.save({
key: key,
data: data.value
}, function (err) {
if (err) {
console.error(err);
return context.failure(err);
}

return context.success('Entity saved');
});
} catch (err) {
console.error(err);
return context.failure(err.message);
}
}

/**
* Retrieves a record.
*
* @example
* gcloud alpha functions call ds-get --data '{"kind":"gcf-test","key":"foobar"}'
*
* @param {Object} context Cloud Function context.
* @param {Function} context.success Success callback.
* @param {Function} context.failure Failure callback.
* @param {Object} data Request data, in this case an object provided by the user.
* @param {string} data.kind The Datastore kind of the data to retrieve, e.g. "user".
* @param {string} data.key Key at which to retrieve the data, e.g. 5075192766267392.
*/
function get (context, data) {
try {
var key = getKeyFromRequestData(data);

return datastore.get(key, function (err, entity) {
if (err) {
console.error(err);
return context.failure(err);
}

// The get operation will not fail for a non-existent entity, it just
// returns null.
if (!entity) {
return context.failure('No entity found for key ' + key.path);
}

return context.success(entity);
});
} catch (err) {
console.error(err);
return context.failure(err.message);
}
}

/**
* Deletes a record.
*
* @example
* gcloud alpha functions call ds-del --data '{"kind":"gcf-test","key":"foobar"}'
*
* @param {Object} context Cloud Function context.
* @param {Function} context.success Success callback.
* @param {Function} context.failure Failure callback.
* @param {Object} data Request data, in this case an object provided by the user.
* @param {string} data.kind The Datastore kind of the data to delete, e.g. "user".
* @param {string} data.key Key at which to delete data, e.g. 5075192766267392.
*/
function del (context, data) {
try {
var key = getKeyFromRequestData(data);

return datastore.delete(key, function (err) {
if (err) {
console.error(err);
return context.failure(err);
}

return context.success('Entity deleted');
});
} catch (err) {
console.error(err);
return context.failure(err.message);
}
}

exports.set = set;
exports.get = get;
exports.del = del;
15 changes: 15 additions & 0 deletions functions/datastore/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "nodejs-docs-samples-functions-datastore",
"description": "Node.js samples found on https://cloud.google.com",
"version": "0.0.1",
"private": true,
"license": "Apache Version 2.0",
"author": "Google Inc.",
"repository": {
"type": "git",
"url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git"
},
"dependencies": {
"gcloud": "^0.35.0"
}
}
38 changes: 38 additions & 0 deletions functions/gcs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<img src="https://avatars2.githubusercontent.com/u/2810941?v=3&s=96" alt="Google Cloud Platform logo" title="Google Cloud Platform" align="right" height="96" width="96"/>

# Google Cloud Functions Cloud Storage sample

This recipe demonstrates how to load a file from Cloud Storage.

View the [source code][code].

[code]: index.js

## Deploy and Test

1. Follow the [Cloud Functions quickstart guide](https://cloud.google.com/functions/quickstart) to setup Cloud Functions for your project.

1. Clone this repository:

git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git
cd nodejs-docs-samples/functions/gcs

1. Create a Cloud Storage Bucket to stage our deployment:

gsutil mb gs://<your-bucket-name>

1. Upload the sample file to the bucket:

gsutil cp sample.txt gs://<your-bucket-name>

1. Deploy the "wordCount" function with an HTTP trigger:

gcloud alpha functions deploy wordCount --bucket <your-bucket-name> --trigger-http --entry-point map

1. Call the "wordCount" function using the sample file:

gcloud alpha functions call wordCount --data '{"bucket":"<your-bucket-name>","file":"sample.txt"}'

You should see something like this in your console

The file sample.txt has 114 words
69 changes: 69 additions & 0 deletions functions/gcs/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Copyright 2016, 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';

var gcloud = require('gcloud');
var readline = require('readline');

function getFileStream (bucketName, fileName) {
if (!bucketName) {
throw new Error('Bucket not provided. Make sure you have a ' +
'"bucket" property in your request');
}
if (!fileName) {
throw new Error('Filename not provided. Make sure you have a ' +
'"file" property in your request');
}

// Create a gcs client.
var gcs = gcloud.storage();
var bucket = gcs.bucket(bucketName);
return bucket.file(fileName).createReadStream();
}

/**
* Reads file and responds with the number of words in the file.
*
* @example
* gcloud alpha functions call wordCount --data '{"bucket":"<your-bucket-name>","file":"sample.txt"}'
*
* @param {Object} context Cloud Function context.
* @param {Function} context.success Success callback.
* @param {Function} context.failure Failure callback.
* @param {Object} data Request data, in this case an object provided by the user.
* @param {Object} data.bucket Name of a Cloud Storage bucket.
* @param {Object} data.file Name of a file in the Cloud Storage bucket.
*/
function wordCount (context, data) {
try {
var count = 0;

// Use the linebyline module to read the stream line by line.
var lineReader = readline.createInterface({
input: getFileStream(data.bucket, data.file)
});

lineReader.on('line', function (line) {
count += line.trim().split(/\s+/).length;
});

lineReader.on('close', function () {
context.success('The file ' + data.file + ' has ' + count + ' words');
});
} catch (err) {
context.failure(err.message);
}
}

exports.wordCount = wordCount;
15 changes: 15 additions & 0 deletions functions/gcs/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "nodejs-docs-samples-functions-cloud-storage",
"description": "Node.js samples found on https://cloud.google.com",
"version": "0.0.1",
"private": true,
"license": "Apache Version 2.0",
"author": "Google Inc.",
"repository": {
"type": "git",
"url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git"
},
"dependencies": {
"gcloud": "^0.35.0"
}
}
14 changes: 14 additions & 0 deletions functions/gcs/sample.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Shall I compare thee to a summer's day?
Thou art more lovely and more temperate:
Rough winds do shake the darling buds of May,
And summer's lease hath all too short a date:
Sometime too hot the eye of heaven shines,
And often is his gold complexion dimm'd;
And every fair from fair sometime declines,
By chance, or nature's changing course, untrimm'd;
But thy eternal summer shall not fade
Nor lose possession of that fair thou ow'st;
Nor shall Death brag thou wander'st in his shade,
When in eternal lines to time thou grow'st;
So long as men can breathe or eyes can see,
So long lives this, and this gives life to thee.
16 changes: 0 additions & 16 deletions functions/log/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,3 @@ exports.helloworld = function (context, data) {
context.success();
};
// [END log]

exports.log = exports.helloworld;

// [START walkthrough_pubsub]
exports.helloworld = function (context, data) {
console.log('My GCF Function: ' + data.message);
context.success();
};
// [END walkthrough_pubsub]

// [START walkthrough_http]
exports.hellohttp = function (context, data) {
// Use the success argument to send data back to the caller
context.success('My GCF Function: ' + data.message);
};
// [END walkthrough_http]
Loading

0 comments on commit b6dd8c0

Please sign in to comment.