diff --git a/appengine/README.md b/appengine/README.md index 066503ccfe..65b70a46f7 100644 --- a/appengine/README.md +++ b/appengine/README.md @@ -1,6 +1,6 @@ # Google App Engine Node.js Samples -These are samples for using Node.js on Google App Engine Managed VMs. These +These are samples for using Node.js on Google App Engine Flexible Environment. These samples are referenced from the [docs](https://cloud.google.com/appengine/docs). See our other [Google Cloud Platform github repos](https://github.com/GoogleCloudPlatform) diff --git a/appengine/analytics/README.md b/appengine/analytics/README.md index 9e8fdd7381..b40a5f85e3 100644 --- a/appengine/analytics/README.md +++ b/appengine/analytics/README.md @@ -1,7 +1,7 @@ # Google Analytics Measurement Protocol on Google App Engine This sample demonstrates how to use the [Google Analytics Measurement Protocol](https://developers.google.com/analytics/devguides/collection/protocol/v1/) -(or any other SQL server) on [Google App Engine Managed VMs](https://cloud.google.com/appengine). +(or any other SQL server) on [Google App Engine Flexible Environment](https://cloud.google.com/appengine). ## Setup diff --git a/appengine/analytics/app.js b/appengine/analytics/app.js index e18049cc4c..24e34c458a 100644 --- a/appengine/analytics/app.js +++ b/appengine/analytics/app.js @@ -1,35 +1,36 @@ -// Copyright 2015-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. +/** + * 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. + */ // [START app] 'use strict'; // [START setup] -var express = require('express'); -var request = require('request'); +const express = require('express'); +const request = require('request'); -var app = express(); +const app = express(); app.enable('trust proxy'); // [END setup] // [START track] // The following environment variable is set by app.yaml when running on GAE, // but will need to be manually set when running locally. See README.md. -var GA_TRACKING_ID = process.env.GA_TRACKING_ID; +const GA_TRACKING_ID = process.env.GA_TRACKING_ID; function trackEvent (category, action, label, value, cb) { - var data = { + const data = { v: '1', // API Version. tid: GA_TRACKING_ID, // Tracking ID / Property ID. // Anonymous Client Identifier. Ideally, this should be a UUID that @@ -43,15 +44,18 @@ function trackEvent (category, action, label, value, cb) { }; request.post( - 'http://www.google-analytics.com/collect', { + 'http://www.google-analytics.com/collect', + { form: data }, - function (err, response) { + (err, response) => { if (err) { - return cb(err); + cb(err); + return; } if (response.statusCode !== 200) { - return cb(new Error('Tracking failed')); + cb(new Error('Tracking failed')); + return; } cb(); } @@ -60,18 +64,19 @@ function trackEvent (category, action, label, value, cb) { // [END track] // [START endpoint] -app.get('/', function (req, res, next) { +app.get('/', (req, res, next) => { trackEvent( 'Example category', 'Example action', 'Example label', '100', // Event value must be numeric. - function (err) { + (err) => { // This sample treats an event tracking error as a fatal error. Depending // on your application's needs, failing to track an event may not be // considered an error. if (err) { - return next(err); + next(err); + return; } res.status(200).send('Event tracked.'); }); @@ -79,9 +84,9 @@ app.get('/', function (req, res, next) { // [END endpoint] // [START listen] -var PORT = process.env.PORT || 8080; -app.listen(PORT, function () { - console.log('App listening on port %s', PORT); +const PORT = process.env.PORT || 8080; +app.listen(PORT, () => { + console.log(`App listening on port ${PORT}`); console.log('Press Ctrl+C to quit.'); }); // [END listen] diff --git a/appengine/analytics/app.yaml b/appengine/analytics/app.yaml index 3b78f300d2..5b12ed1dd9 100644 --- a/appengine/analytics/app.yaml +++ b/appengine/analytics/app.yaml @@ -1,4 +1,4 @@ -# Copyright 2015-2016, Google, Inc. +# 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 @@ -13,7 +13,7 @@ # [START app_yaml] runtime: nodejs -vm: true +env: flex # [START env] env_variables: diff --git a/appengine/analytics/package.json b/appengine/analytics/package.json index 2b20497274..835b90ffc9 100644 --- a/appengine/analytics/package.json +++ b/appengine/analytics/package.json @@ -6,17 +6,17 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "engines": { - "node": "~4.2" + "node": ">=4.3.2" }, "scripts": { "start": "node app.js", "test": "mocha -R spec -t 120000 --require intelli-espower-loader ../../test/_setup.js test/*.test.js" }, "dependencies": { - "express": "^4.13.4", - "request": "^2.69.0" + "express": "^4.14.0", + "request": "^2.75.0" }, "devDependencies": { - "mocha": "^2.5.3" + "mocha": "^3.1.0" } } diff --git a/appengine/analytics/test/app.test.js b/appengine/analytics/test/app.test.js index c3d25d8eab..af747d177e 100644 --- a/appengine/analytics/test/app.test.js +++ b/appengine/analytics/test/app.test.js @@ -1,42 +1,45 @@ -// 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. +/** + * 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 express = require('express'); -var path = require('path'); -var proxyquire = require('proxyquire').noPreserveCache(); -var request = require('supertest'); +const express = require(`express`); +const path = require(`path`); +const proxyquire = require(`proxyquire`).noPreserveCache(); +const request = require(`supertest`); -var SAMPLE_PATH = path.join(__dirname, '../app.js'); +const SAMPLE_PATH = path.join(__dirname, `../app.js`); function getSample () { - var testApp = express(); - sinon.stub(testApp, 'listen').callsArg(1); - var expressMock = sinon.stub().returns(testApp); - var resultsMock = { + const testApp = express(); + sinon.stub(testApp, `listen`).callsArg(1); + const expressMock = sinon.stub().returns(testApp); + const resultsMock = { statusCode: 200, - foo: 'bar' + foo: `bar` }; - var requestMock = { - post: sinon.stub().callsArgWith(2, null, resultsMock) + const requestMock = { + post: sinon.stub().yields(null, resultsMock) }; - var app = proxyquire(SAMPLE_PATH, { + const app = proxyquire(SAMPLE_PATH, { request: requestMock, express: expressMock }); + return { app: app, mocks: { @@ -47,10 +50,10 @@ function getSample () { }; } -describe('appengine/analytics/app.js', function () { - var sample; +describe(`appengine/analytics/app.js`, () => { + let sample; - beforeEach(function () { + beforeEach(() => { sample = getSample(); assert(sample.mocks.express.calledOnce); @@ -58,33 +61,33 @@ describe('appengine/analytics/app.js', function () { assert.equal(sample.app.listen.firstCall.args[0], process.env.PORT || 8080); }); - it('should record a visit', function (done) { - var expectedResult = 'Event tracked.'; + it(`should record a visit`, (done) => { + const expectedResult = `Event tracked.`; request(sample.app) - .get('/') + .get(`/`) .expect(200) - .expect(function (response) { + .expect((response) => { assert.equal(response.text, expectedResult); }) .end(done); }); - it('should handle request error', function (done) { - var expectedResult = 'request_error'; + it(`should handle request error`, (done) => { + const expectedResult = `request_error`; sample.mocks.request.post.onFirstCall().callsArgWith(2, expectedResult); request(sample.app) - .get('/') + .get(`/`) .expect(500) - .expect(function (response) { - assert.equal(response.text, expectedResult + '\n'); + .expect((response) => { + assert.equal(response.text, expectedResult + `\n`); }) .end(done); }); - it('should handle track error', function (done) { + it(`should handle track error`, (done) => { sample.mocks.request.post.onFirstCall().callsArgWith(2, null, { statusCode: 400 }); @@ -92,7 +95,7 @@ describe('appengine/analytics/app.js', function () { request(sample.app) .get('/') .expect(500) - .expect(function (response) { + .expect((response) => { assert.notEqual(response.text.indexOf('Error: Tracking failed'), -1); }) .end(done); diff --git a/appengine/bower/app.yaml b/appengine/bower/app.yaml index f6ffeb3d5d..95b81be533 100644 --- a/appengine/bower/app.yaml +++ b/appengine/bower/app.yaml @@ -1,4 +1,4 @@ -# Copyright 2015-2016, Google, Inc. +# 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 @@ -13,5 +13,5 @@ # [START app_yaml] runtime: nodejs -vm: true +env: flex # [END app_yaml] diff --git a/appengine/bower/package.json b/appengine/bower/package.json index 177331eb99..86283b04aa 100644 --- a/appengine/bower/package.json +++ b/appengine/bower/package.json @@ -6,18 +6,18 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "engines": { - "node": "~4.2" + "node": ">=4.3.2" }, "scripts": { "postinstall": "bower install --config.interactive=false", "test": "mocha -R spec -t 120000 --require intelli-espower-loader ../../test/_setup.js test/*.test.js" }, "dependencies": { - "bower": "^1.7.7", - "express": "^4.13.4", - "jade": "^1.11.0" + "bower": "^1.7.9", + "express": "^4.14.0", + "pug": "^2.0.0-beta6" }, "devDependencies": { - "mocha": "^2.5.3" + "mocha": "^3.1.0" } } diff --git a/appengine/bower/server.js b/appengine/bower/server.js index f99015d4b3..9fae03a1a4 100644 --- a/appengine/bower/server.js +++ b/appengine/bower/server.js @@ -1,41 +1,43 @@ -// Copyright 2015-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. +/** + * 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. + */ // [START app] 'use strict'; // [START setup] -var express = require('express'); -var path = require('path'); +const express = require('express'); +const path = require('path'); -var app = express(); +const app = express(); app.enable('trust proxy'); // [END setup] // Setup view engine -app.set('view engine', 'jade'); +app.set('view engine', 'pug'); app.set('views', path.join(__dirname, 'views')); app.use(express.static(path.join(__dirname, 'public'))); -app.get('/', function (req, res) { +app.get('/', (req, res) => { res.render('index'); }); // [START listen] -var PORT = process.env.PORT || 8080; -app.listen(PORT, function () { - console.log('App listening on port %s', PORT); +const PORT = process.env.PORT || 8080; +app.listen(PORT, () => { + console.log(`App listening on port ${PORT}`); console.log('Press Ctrl+C to quit.'); }); // [END listen] diff --git a/appengine/bower/test/server.test.js b/appengine/bower/test/server.test.js index 85c54a029c..b13fe5dfb8 100644 --- a/appengine/bower/test/server.test.js +++ b/appengine/bower/test/server.test.js @@ -1,31 +1,33 @@ -// 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. +/** + * 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 express = require('express'); -var path = require('path'); -var proxyquire = require('proxyquire').noPreserveCache(); -var request = require('supertest'); +const express = require(`express`); +const path = require(`path`); +const proxyquire = require(`proxyquire`).noPreserveCache(); +const request = require(`supertest`); -var SAMPLE_PATH = path.join(__dirname, '../server.js'); +const SAMPLE_PATH = path.join(__dirname, `../server.js`); function getSample () { - var testApp = express(); - sinon.stub(testApp, 'listen').callsArg(1); - var expressMock = sinon.stub().returns(testApp); + const testApp = express(); + sinon.stub(testApp, `listen`).yields(); + const expressMock = sinon.stub().returns(testApp); - var app = proxyquire(SAMPLE_PATH, { + const app = proxyquire(SAMPLE_PATH, { express: expressMock }); return { @@ -36,10 +38,10 @@ function getSample () { }; } -describe('appengine/bower/server.js', function () { - var sample; +describe(`appengine/bower/server.js`, () => { + let sample; - beforeEach(function () { + beforeEach(() => { sample = getSample(); assert(sample.mocks.express.calledOnce); @@ -47,13 +49,13 @@ describe('appengine/bower/server.js', function () { assert.equal(sample.app.listen.firstCall.args[0], process.env.PORT || 8080); }); - it('should render a page', function (done) { - var expectedResult = '

Hello World!

Express.js + Bower on Google App Engine.

'; + it(`should render a page`, (done) => { + const expectedResult = `

Hello World!

Express.js + Bower on Google App Engine.

`; request(sample.app) - .get('/') + .get(`/`) .expect(200) - .expect(function (response) { + .expect((response) => { assert.notEqual(response.text.indexOf(expectedResult), -1); }) .end(done); diff --git a/appengine/bower/views/index.jade b/appengine/bower/views/index.pug similarity index 95% rename from appengine/bower/views/index.jade rename to appengine/bower/views/index.pug index 7e8c77ed42..a40fba1863 100644 --- a/appengine/bower/views/index.jade +++ b/appengine/bower/views/index.pug @@ -1,4 +1,4 @@ -// Copyright 2015-2016, Google, Inc. +// 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 @@ -23,4 +23,4 @@ html p Using , installed via Bower. script(type='text/javascript'). $('#module-name').text('jquery') - + diff --git a/appengine/cloudsql/README.md b/appengine/cloudsql/README.md index 640cc12b32..67f15cfeaf 100644 --- a/appengine/cloudsql/README.md +++ b/appengine/cloudsql/README.md @@ -7,6 +7,8 @@ server) on [Google App Engine Flexible][flexible]. Before you can run or deploy the sample, you will need to do the following: +1. In order for some of the commands below to work, you need to enable the +[Cloud SQL Admin API](https://console.cloud.google.com/apis/api/sqladmin-json.googleapis.com/overview). 1. Create a [Second Generation Cloud SQL][gen] instance. You can do this from the [Cloud Console][console] or via the [Cloud SDK][sdk]. To create it via the SDK use the following command: @@ -24,18 +26,17 @@ SDK use the following command: where `[YOUR_INSTANCE_NAME]` is the name you chose in step 1 and `[YOUR_INSTANCE_ROOT_PASSWORD]` is a password of your choice. -1. Create a [Service Account][service] for your project. You will use this -service account to connect to your Cloud SQL instance locally. +1. Create and download a [Service Account][service] for your project. You will +use this service account to connect to your Cloud SQL instance locally. 1. Download and install the [Cloud SQL Proxy][proxy]. 1. [Start the proxy][start] to allow connecting to your instance from your local machine: - cloud_sql_proxy \ - -dir /cloudsql \ - -instances=[YOUR_INSTANCE_CONNECTION_NAME] \ - -credential_file=PATH_TO_YOUR_SERVICE_ACCOUNT_JSON + ./cloud_sql_proxy \ + -instances=[YOUR_INSTANCE_CONNECTION_NAME]=tcp:3306 \ + -credential_file=PATH_TO_YOUR_SERVICE_ACCOUNT_JSON_FILE where `[YOUR_INSTANCE_CONNECTION_NAME]` is the connection name of your instance on its Overview page in the Google Cloud Platform Console, or use @@ -44,18 +45,14 @@ machine: 1. Use the MySQL command line tools (or a management tool of your choice) to create a [new user][user] and [database][database] for your application: - mysql --socket [YOUR_SOCKET_PATH] -u root -p - mysql> create database YOUR_DATABASE; + mysql -h 127.0.0.1 -P 3306 -u root -p + mysql> create database `YOUR_DATABASE`; mysql> create user 'YOUR_USER'@'%' identified by 'PASSWORD'; mysql> grant all on YOUR_DATABASE.* to 'YOUR_USER'@'%'; - where `[YOUR_SOCKET_PATH]` is that socket opened by the proxy. This path was - printed to the console when you started the proxy, and is of the format: - `/[DIR]/[YOUR_PROJECT_ID]:[YOUR_REGION]:[YOUR_INSTANCE_NAME]`. - -1. Set the `MYSQL_USER`, `MYSQL_PASSWORD`, `MYSQL_SOCKET_PATH`, and -`MYSQL_DATABASE` environment variables. This allows the app to connect to your -Cloud SQL instance through the proxy. +1. Set the `MYSQL_USER`, `MYSQL_PASSWORD`, and `MYSQL_DATABASE` environment +variables (see below). This allows your local app to connect to your Cloud SQL +instance through the proxy. 1. Update the values in in `app.yaml` with your instance configuration. @@ -72,7 +69,6 @@ running the sample: export MYSQL_USER="YOUR_USER" export MYSQL_PASSWORD="YOUR_PASSWORD" - export MYSQL_SOCKET_PATH="YOUR_SOCKET_PATH" export MYSQL_DATABASE="YOUR_DATABASE" npm install npm start diff --git a/appengine/cloudsql/app.yaml b/appengine/cloudsql/app.yaml index 61d69eb8b6..2778f28aa9 100644 --- a/appengine/cloudsql/app.yaml +++ b/appengine/cloudsql/app.yaml @@ -1,4 +1,4 @@ -# Copyright 2015-2016, Google, Inc. +# 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 @@ -13,22 +13,21 @@ # [START app_yaml] runtime: nodejs -vm: true +env: flex # [START env] env_variables: - MYSQL_USER: [YOUR_USER] - MYSQL_PASSWORD: [YOUR_PASSWORD] - MYSQL_DATABASE: [YOUR_DATABASE] - # This path was printed to the console when you started the proxy, and is of - # the format: `/[DIR]/[YOUR_PROJECT_ID]:[YOUR_REGION]:[YOUR_INSTANCE_NAME]` - MYSQL_SOCKET_PATH: [YOUR_SOCKET_PATH] + MYSQL_USER: YOUR_USER + MYSQL_PASSWORD: YOUR_PASSWORD + MYSQL_DATABASE: YOUR_DATABASE + # e.g. my-awesome-project:us-central1:my-cloud-sql-instance + INSTANCE_CONNECTION_NAME: YOUR_PROJECT_ID:YOUR_REGION:YOUR_INSTANCE_NAME # [END env] # [START cloudsql_settings] beta_settings: # The connection name of your instance on its Overview page in the Google - # Cloud Platform Console, or use `[YOUR_PROJECT_ID]:[YOUR_REGION]:[YOUR_INSTANCE_NAME]` - cloud_sql_instances: [YOUR_INSTANCE_CONNECTION_NAME] + # Cloud Platform Console, or use `YOUR_PROJECT_ID:YOUR_REGION:YOUR_INSTANCE_NAME` + cloud_sql_instances: YOUR_PROJECT_ID:YOUR_REGION:YOUR_INSTANCE_NAME # [END cloudsql_settings] # [END app_yaml] diff --git a/appengine/cloudsql/createTables.js b/appengine/cloudsql/createTables.js index 541841dded..001f8cefe2 100644 --- a/appengine/cloudsql/createTables.js +++ b/appengine/cloudsql/createTables.js @@ -1,32 +1,33 @@ -// Copyright 2015-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. +/** + * 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. + */ // [START createTables] 'use strict'; // [START setup] -var mysql = require('mysql'); -var prompt = require('prompt'); +const mysql = require('mysql'); +const prompt = require('prompt'); // [END setup] // [START createTable] -var SQL_STRING = 'CREATE TABLE `visits` (\n' + - ' `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,\n' + - ' `timestamp` DATETIME NULL,\n' + - ' `userIp` VARCHAR(46) NULL,\n' + - ' PRIMARY KEY (`id`)\n' + - ');'; +const SQL_STRING = `CREATE TABLE visits ( + id INT UNSIGNED NOT NULL AUTO_INCREMENT, + timestamp DATETIME NULL, + userIp VARCHAR(46) NULL, + PRIMARY KEY (id) +);`; /** * Create the "visits" table. @@ -40,7 +41,7 @@ function createTable (connection, callback) { // [END createTable] // [START getConnection] -var FIELDS = ['socketPath', 'user', 'password', 'database']; +const FIELDS = ['user', 'password', 'database']; /** * Ask the user for connection configuration and create a new connection. @@ -49,34 +50,35 @@ var FIELDS = ['socketPath', 'user', 'password', 'database']; */ function getConnection (callback) { prompt.start(); - prompt.get(FIELDS, function (err, config) { + prompt.get(FIELDS, (err, config) => { if (err) { - return callback(err); + callback(err); + return; } - return callback(null, mysql.createConnection({ - user: config.user, - password: config.password, - socketPath: config.socketPath, - database: config.database - })); + const user = encodeURIComponent(config.user); + const password = encodeURIComponent(config.password); + const database = encodeURIComponent(config.database); + + const uri = `mysql://${user}:${password}@127.0.0.1:3306/${database}`; + callback(null, mysql.createConnection(uri)); }); } // [END getConnection] // [START main] -getConnection(function (err, connection) { - console.log(err, !!connection); +getConnection((err, connection) => { if (err) { - return console.error(err); + console.error(err); + return; } - createTable(connection, function (err, result) { - console.log(err, !!result); + createTable(connection, (err, result) => { + connection.end(); if (err) { - return console.error(err); + console.error(err); + return; } console.log(result); - connection.end(); }); }); // [END main] diff --git a/appengine/cloudsql/package.json b/appengine/cloudsql/package.json index 2b358fad8e..07d64ed0b7 100644 --- a/appengine/cloudsql/package.json +++ b/appengine/cloudsql/package.json @@ -6,7 +6,7 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "engines": { - "node": "~4.2" + "node": ">=4.3.2" }, "scripts": { "test": "mocha -R spec -t 120000 --require intelli-espower-loader ../../test/_setup.js test/*.test.js" @@ -17,6 +17,6 @@ "prompt": "^1.0.0" }, "devDependencies": { - "mocha": "^2.5.3" + "mocha": "^3.1.0" } } diff --git a/appengine/cloudsql/server.js b/appengine/cloudsql/server.js index b8e5bc4ec9..8ebe3e3803 100644 --- a/appengine/cloudsql/server.js +++ b/appengine/cloudsql/server.js @@ -1,37 +1,43 @@ -// Copyright 2015-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. +/** + * 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. + */ // [START app] 'use strict'; // [START setup] -var express = require('express'); -var mysql = require('mysql'); -var crypto = require('crypto'); +const express = require('express'); +const mysql = require('mysql'); +const crypto = require('crypto'); -var app = express(); +const app = express(); app.enable('trust proxy'); // [END setup] // [START connect] -// Connect to the database -var connection = mysql.createConnection({ +var config = { user: process.env.MYSQL_USER, password: process.env.MYSQL_PASSWORD, - socketPath: process.env.MYSQL_SOCKET_PATH, database: process.env.MYSQL_DATABASE -}); +}; + +if (process.env.INSTANCE_CONNECTION_NAME) { + config.socketPath = `/cloudsql/${process.env.INSTANCE_CONNECTION_NAME}`; +} + +// Connect to the database +const connection = mysql.createConnection(config); // [END connect] // [START insertVisit] @@ -42,20 +48,21 @@ var connection = mysql.createConnection({ * @param {function} callback The callback function. */ function insertVisit (visit, callback) { - connection.query('INSERT INTO `visits` SET ?', visit, function (err) { + connection.query('INSERT INTO `visits` SET ?', visit, (err) => { if (err) { - return callback(err); + callback(err); + return; } - return callback(); + callback(); }); } // [END insertVisit] // [START getVisits] -var SQL_STRING = 'SELECT `timestamp`, `userIp`\n' + - 'FROM `visits`\n' + - 'ORDER BY `timestamp` DESC\n' + - 'LIMIT 10;'; +const SQL_STRING = `SELECT timestamp, userIp +FROM visits +ORDER BY timestamp DESC +LIMIT 10;`; /** * Retrieve the latest 10 visit records from the database. @@ -63,49 +70,50 @@ var SQL_STRING = 'SELECT `timestamp`, `userIp`\n' + * @param {function} callback The callback function. */ function getVisits (callback) { - connection.query(SQL_STRING, function (err, results) { + connection.query(SQL_STRING, (err, results) => { if (err) { - return callback(err); + callback(err); + return; } - return callback(null, results.map(function (visit) { - return 'Time: ' + visit.timestamp + ', AddrHash: ' + visit.userIp; - })); + callback(null, results.map((visit) => `Time: ${visit.timestamp}, AddrHash: ${visit.userIp}`)); }); } // [END getVisits] -app.get('/', function (req, res, next) { +app.get('/', (req, res, next) => { // Create a visit record to be stored in the database - var visit = { + const visit = { timestamp: new Date(), // Store a hash of the visitor's ip address userIp: crypto.createHash('sha256').update(req.ip).digest('hex').substr(0, 7) }; - insertVisit(visit, function (err) { + insertVisit(visit, (err, results) => { if (err) { - return next(err); + next(err); + return; } // Query the last 10 visits from the database. - getVisits(function (err, visits) { + getVisits((err, visits) => { if (err) { - return next(err); + next(err); + return; } - return res + res .status(200) .set('Content-Type', 'text/plain') - .send('Last 10 visits:\n' + visits.join('\n')); + .send(`Last 10 visits:\n${visits.join('\n')}`); }); }); }); // [START listen] -var PORT = process.env.PORT || 8080; -app.listen(PORT, function () { - console.log('App listening on port %s', PORT); +const PORT = process.env.PORT || 8080; +app.listen(PORT, () => { + console.log(`App listening on port ${PORT}`); console.log('Press Ctrl+C to quit.'); }); // [END listen] diff --git a/appengine/cloudsql/test/createTables.test.js b/appengine/cloudsql/test/createTables.test.js index 5b574cda88..7b8462af01 100644 --- a/appengine/cloudsql/test/createTables.test.js +++ b/appengine/cloudsql/test/createTables.test.js @@ -1,47 +1,49 @@ -// 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. +/** + * 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 path = require('path'); -var proxyquire = require('proxyquire').noPreserveCache(); +const path = require(`path`); +const proxyquire = require(`proxyquire`).noPreserveCache(); -var SAMPLE_PATH = path.join(__dirname, '../createTables.js'); +const SAMPLE_PATH = path.join(__dirname, `../createTables.js`); function getSample () { - var connectionMock = { + const connectionMock = { query: sinon.stub(), end: sinon.stub() }; - connectionMock.query.onFirstCall().callsArgWith(1, null, 'created visits table!'); - var mysqlMock = { + connectionMock.query.onFirstCall().yields(null, `created visits table!`); + const mysqlMock = { createConnection: sinon.stub().returns(connectionMock) }; - var configMock = { - user: 'user', - password: 'password', - database: 'database', - socketPath: 'socketPath' + const configMock = { + user: `user`, + password: `password`, + database: `database` }; - var promptMock = { + const promptMock = { start: sinon.stub(), - get: sinon.stub().callsArgWith(1, null, configMock) + get: sinon.stub().yields(null, configMock) }; proxyquire(SAMPLE_PATH, { mysql: mysqlMock, prompt: promptMock }); + return { mocks: { connection: connectionMock, @@ -52,30 +54,30 @@ function getSample () { }; } -describe('appengine/cloudsql/createTables.js', function () { - it('should record a visit', function (done) { - var sample = getSample(); - var expectedResult = 'created visits table!'; +describe(`appengine/cloudsql/createTables.js`, () => { + it(`should record a visit`, (done) => { + const sample = getSample(); + const expectedResult = `created visits table!`; assert(sample.mocks.prompt.start.calledOnce); assert(sample.mocks.prompt.get.calledOnce); assert.deepEqual(sample.mocks.prompt.get.firstCall.args[0], [ - 'socketPath', - 'user', - 'password', - 'database' + `user`, + `password`, + `database` ]); - setTimeout(function () { - assert.deepEqual(sample.mocks.mysql.createConnection.firstCall.args[0], sample.mocks.config); + setTimeout(() => { + const uri = `mysql://${sample.mocks.config.user}:${sample.mocks.config.password}@127.0.0.1:3306/${sample.mocks.config.database}`; + assert.deepEqual(sample.mocks.mysql.createConnection.firstCall.args, [uri]); assert(console.log.calledWith(expectedResult)); done(); }, 10); }); - it('should handle prompt error', function (done) { - var expectedResult = 'createTables_prompt_error'; - var sample = getSample(); + it(`should handle prompt error`, (done) => { + const expectedResult = `createTables_prompt_error`; + const sample = getSample(); proxyquire(SAMPLE_PATH, { mysql: sample.mocks.mysql, @@ -85,18 +87,19 @@ describe('appengine/cloudsql/createTables.js', function () { } }); - setTimeout(function () { + setTimeout(() => { assert(console.error.calledWith(expectedResult)); done(); }, 10); }); - it('should handle insert error', function (done) { - var expectedResult = 'createTables_insert_error'; - var sample = getSample(); + it(`should handle insert error`, (done) => { + const expectedResult = `createTables_insert_error`; + const sample = getSample(); - var connectionMock = { - query: sinon.stub().callsArgWith(1, expectedResult) + const connectionMock = { + query: sinon.stub().callsArgWith(1, expectedResult), + end: sinon.stub() }; proxyquire(SAMPLE_PATH, { @@ -106,7 +109,7 @@ describe('appengine/cloudsql/createTables.js', function () { prompt: sample.mocks.prompt }); - setTimeout(function () { + setTimeout(() => { assert(console.error.calledWith(expectedResult)); done(); }, 10); diff --git a/appengine/cloudsql/test/server.test.js b/appengine/cloudsql/test/server.test.js index fbd6dcf9a0..0e4b32dfd3 100644 --- a/appengine/cloudsql/test/server.test.js +++ b/appengine/cloudsql/test/server.test.js @@ -1,46 +1,48 @@ -// 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. +/** + * 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 express = require('express'); -var path = require('path'); -var proxyquire = require('proxyquire').noPreserveCache(); -var request = require('supertest'); +const express = require(`express`); +const path = require(`path`); +const proxyquire = require(`proxyquire`).noPreserveCache(); +const request = require(`supertest`); -var SAMPLE_PATH = path.join(__dirname, '../server.js'); +const SAMPLE_PATH = path.join(__dirname, `../server.js`); function getSample () { - var testApp = express(); - sinon.stub(testApp, 'listen').callsArg(1); - var expressMock = sinon.stub().returns(testApp); - var resultsMock = [ + const testApp = express(); + sinon.stub(testApp, `listen`).yields(); + const expressMock = sinon.stub().returns(testApp); + const resultsMock = [ { - timestamp: '1234', - userIp: 'abcd' + timestamp: `1234`, + userIp: `abcd` } ]; - var connectionMock = { + const connectionMock = { query: sinon.stub() }; - connectionMock.query.onFirstCall().callsArg(2); - connectionMock.query.onSecondCall().callsArgWith(1, null, resultsMock); + connectionMock.query.onFirstCall().yields(); + connectionMock.query.onSecondCall().yields(null, resultsMock); - var mysqlMock = { + const mysqlMock = { createConnection: sinon.stub().returns(connectionMock) }; - var app = proxyquire(SAMPLE_PATH, { + const app = proxyquire(SAMPLE_PATH, { mysql: mysqlMock, express: expressMock }); @@ -55,10 +57,10 @@ function getSample () { }; } -describe('appengine/cloudsql/server.js', function () { - var sample; +describe(`appengine/cloudsql/server.js`, () => { + let sample; - beforeEach(function () { + beforeEach(() => { sample = getSample(); assert(sample.mocks.express.calledOnce); @@ -66,49 +68,48 @@ describe('appengine/cloudsql/server.js', function () { assert.deepEqual(sample.mocks.mysql.createConnection.firstCall.args[0], { user: process.env.MYSQL_USER, password: process.env.MYSQL_PASSWORD, - socketPath: process.env.MYSQL_SOCKET_PATH, database: process.env.MYSQL_DATABASE }); assert(sample.app.listen.calledOnce); assert.equal(sample.app.listen.firstCall.args[0], process.env.PORT || 8080); }); - it('should record a visit', function (done) { - var expectedResult = 'Last 10 visits:\nTime: 1234, AddrHash: abcd'; + it(`should record a visit`, (done) => { + const expectedResult = `Last 10 visits:\nTime: 1234, AddrHash: abcd`; request(sample.app) - .get('/') + .get(`/`) .expect(200) - .expect(function (response) { + .expect((response) => { assert.equal(response.text, expectedResult); }) .end(done); }); - it('should handle insert error', function (done) { - var expectedResult = 'insert_error'; + it(`should handle insert error`, (done) => { + const expectedResult = `insert_error`; - sample.mocks.connection.query.onFirstCall().callsArgWith(2, expectedResult); + sample.mocks.connection.query.onFirstCall().yields(expectedResult); request(sample.app) - .get('/') + .get(`/`) .expect(500) - .expect(function (response) { - assert.equal(response.text, expectedResult + '\n'); + .expect((response) => { + assert.equal(response.text, `${expectedResult}\n`); }) .end(done); }); - it('should handle read error', function (done) { - var expectedResult = 'read_error'; + it(`should handle read error`, (done) => { + const expectedResult = `read_error`; - sample.mocks.connection.query.onSecondCall().callsArgWith(1, expectedResult); + sample.mocks.connection.query.onSecondCall().yields(expectedResult); request(sample.app) - .get('/') + .get(`/`) .expect(500) - .expect(function (response) { - assert.equal(response.text, expectedResult + '\n'); + .expect((response) => { + assert.equal(response.text, `${expectedResult}\n`); }) .end(done); }); diff --git a/appengine/datastore/README.md b/appengine/datastore/README.md index 5d0224ba83..d33c99ae04 100644 --- a/appengine/datastore/README.md +++ b/appengine/datastore/README.md @@ -1,25 +1,9 @@ # Node.js Cloud Datastore sample for Google App Engine This sample demonstrates how to use [Cloud Datastore](https://cloud.google.com/datastore/) -on [Google App Engine Managed VMs](https://cloud.google.com/appengine). - -## Setup - -Before you can run or deploy the sample, you will need to enable the Cloud -Datastore API in the [Google Developers Console](https://console.developers.google.com/project/_/apiui/apiview/datastore/overview). +on [Google App Engine Flexible Environment](https://cloud.google.com/appengine). ## Running locally Refer to the [appengine/README.md](../README.md) file for instructions on running and deploying. - -When running locally, you can use the [Google Cloud SDK](https://cloud.google.com/sdk) -to provide authentication to use Google Cloud APIs: - - gcloud init - -Set the `GCLOUD_PROJECT` environment variable to your Project ID before starting your application: - - export GCLOUD_PROJECT= - npm install - npm start diff --git a/appengine/datastore/app.js b/appengine/datastore/app.js index 680be59aa2..fe8d09298b 100644 --- a/appengine/datastore/app.js +++ b/appengine/datastore/app.js @@ -1,25 +1,26 @@ -// Copyright 2015-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. +/** + * 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. + */ // [START app] 'use strict'; // [START setup] -var express = require('express'); -var crypto = require('crypto'); +const express = require('express'); +const crypto = require('crypto'); -var app = express(); +const app = express(); app.enable('trust proxy'); // By default, the client will authenticate using the service account file @@ -27,10 +28,10 @@ app.enable('trust proxy'); // the project specified by the GCLOUD_PROJECT environment variable. See // https://googlecloudplatform.github.io/gcloud-node/#/docs/google-cloud/latest/guides/authentication // These environment variables are set automatically on Google App Engine -var Datastore = require('@google-cloud/datastore'); +const Datastore = require('@google-cloud/datastore'); // Instantiate a datastore client -var datastore = Datastore(); +const datastore = Datastore(); // [END setup] // [START insertVisit] @@ -44,11 +45,12 @@ function insertVisit (visit, callback) { datastore.save({ key: datastore.key('visit'), data: visit - }, function (err) { + }, (err) => { if (err) { - return callback(err); + callback(err); + return; } - return callback(); + callback(); }); } // [END insertVisit] @@ -60,51 +62,53 @@ function insertVisit (visit, callback) { * @param {function} callback The callback function. */ function getVisits (callback) { - var query = datastore.createQuery('visit') - .order('-timestamp') + const query = datastore.createQuery('visit') + .order('timestamp', { descending: true }) .limit(10); - datastore.runQuery(query, function (err, entities) { + datastore.runQuery(query, (err, entities) => { if (err) { - return callback(err); + callback(err); + return; } - return callback(null, entities.map(function (entity) { - return 'Time: ' + entity.data.timestamp + ', AddrHash: ' + entity.data.userIp; - })); + callback(null, entities.map((entity) => `Time: ${entity.data.timestamp}, AddrHash: ${entity.data.userIp}`)); }); } // [END getVisits] -app.get('/', function (req, res, next) { +app.get('/', (req, res, next) => { // Create a visit record to be stored in the database - var visit = { + const visit = { timestamp: new Date(), // Store a hash of the visitor's ip address userIp: crypto.createHash('sha256').update(req.ip).digest('hex').substr(0, 7) }; - insertVisit(visit, function (err) { + insertVisit(visit, (err) => { if (err) { - return next(err); + next(err); + return; } // Query the last 10 visits from the datastore. - getVisits(function (err, visits) { + getVisits((err, visits) => { if (err) { - return next(err); + next(err); + return; } - return res + res .status(200) .set('Content-Type', 'text/plain') - .send('Last 10 visits:\n' + visits.join('\n')); + .send(`Last 10 visits:\n${visits.join('\n')}`); }); }); }); // [START listen] -var server = app.listen(process.env.PORT || 8080, function () { - console.log('App listening on port %s', server.address().port); +const PORT = process.env.PORT || 8080; +app.listen(process.env.PORT || 8080, () => { + console.log(`App listening on port ${PORT}`); console.log('Press Ctrl+C to quit.'); }); // [END listen] diff --git a/appengine/datastore/app.yaml b/appengine/datastore/app.yaml index 528f265984..248738be70 100644 --- a/appengine/datastore/app.yaml +++ b/appengine/datastore/app.yaml @@ -13,10 +13,5 @@ # [START app_yaml] runtime: nodejs -vm: true - -# [START env_variables] -env_variables: - GCLOUD_PROJECT: -# [END env_variables] +env: flex # [END app_yaml] diff --git a/appengine/datastore/package.json b/appengine/datastore/package.json index 6746bc0252..da5c9f01a8 100644 --- a/appengine/datastore/package.json +++ b/appengine/datastore/package.json @@ -6,17 +6,17 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "engines": { - "node": "^4.2.2" + "node": ">=4.3.2" }, "scripts": { "start": "node app.js", "test": "mocha -R spec -t 120000 --require intelli-espower-loader ../../test/_setup.js test/*.test.js" }, "dependencies": { - "@google-cloud/datastore": "^0.1.1", - "express": "^4.13.4" + "@google-cloud/datastore": "^0.4.0", + "express": "^4.14.0" }, "devDependencies": { - "mocha": "^3.0.2" + "mocha": "^3.1.0" } } diff --git a/appengine/datastore/test/app.test.js b/appengine/datastore/test/app.test.js index 710a27e62c..4d045c5549 100644 --- a/appengine/datastore/test/app.test.js +++ b/appengine/datastore/test/app.test.js @@ -1,64 +1,66 @@ -// 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. +/** + * 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 express = require('express'); -var path = require('path'); -var proxyquire = require('proxyquire').noCallThru(); -var request = require('supertest'); +const express = require(`express`); +const path = require(`path`); +const proxyquire = require(`proxyquire`).noCallThru(); +const request = require(`supertest`); -var SAMPLE_PATH = path.join(__dirname, '../app.js'); +const SAMPLE_PATH = path.join(__dirname, `../app.js`); function getSample () { - var serverMock = { + const serverMock = { address: sinon.stub().returns({ port: 8080 }) }; - var testApp = express(); - sinon.stub(testApp, 'listen', function (port, callback) { + const testApp = express(); + sinon.stub(testApp, `listen`, (port, callback) => { assert.equal(port, 8080); - setTimeout(function () { + setTimeout(() => { callback(); }); return serverMock; }); - var expressMock = sinon.stub().returns(testApp); - var resultsMock = [ + const expressMock = sinon.stub().returns(testApp); + const resultsMock = [ { data: { - timestamp: '1234', - userIp: 'abcd' + timestamp: `1234`, + userIp: `abcd` } } ]; - var queryMock = { + const queryMock = { order: sinon.stub(), limit: sinon.stub() }; queryMock.order.returns(queryMock); queryMock.limit.returns(queryMock); - var datasetMock = { + const datasetMock = { save: sinon.stub().callsArg(1), createQuery: sinon.stub().returns(queryMock), runQuery: sinon.stub().callsArgWith(1, null, resultsMock), key: sinon.stub().returns({}) }; - var DatastoreMock = sinon.stub().returns(datasetMock); + const DatastoreMock = sinon.stub().returns(datasetMock); - var app = proxyquire(SAMPLE_PATH, { + const app = proxyquire(SAMPLE_PATH, { '@google-cloud/datastore': DatastoreMock, express: expressMock }); @@ -74,10 +76,10 @@ function getSample () { }; } -describe('appengine/datastore/app.js', function () { - var sample; +describe(`appengine/datastore/app.js`, () => { + let sample; - beforeEach(function () { + beforeEach(() => { sample = getSample(); assert(sample.mocks.express.calledOnce); @@ -86,43 +88,43 @@ describe('appengine/datastore/app.js', function () { assert.equal(sample.app.listen.firstCall.args[0], process.env.PORT || 8080); }); - it('should record a visit', function (done) { - var expectedResult = 'Last 10 visits:\nTime: 1234, AddrHash: abcd'; + it(`should record a visit`, (done) => { + const expectedResult = `Last 10 visits:\nTime: 1234, AddrHash: abcd`; request(sample.app) - .get('/') + .get(`/`) .expect(200) - .expect(function (response) { + .expect((response) => { console.log(response.body); assert.equal(response.text, expectedResult); }) .end(done); }); - it('should handle insert error', function (done) { - var expectedResult = 'insert_error'; + it(`should handle insert error`, (done) => { + const expectedResult = `insert_error`; sample.mocks.dataset.save.callsArgWith(1, expectedResult); request(sample.app) - .get('/') + .get(`/`) .expect(500) - .expect(function (response) { - assert.equal(response.text, expectedResult + '\n'); + .expect((response) => { + assert.equal(response.text, expectedResult + `\n`); }) .end(done); }); - it('should handle read error', function (done) { - var expectedResult = 'read_error'; + it(`should handle read error`, (done) => { + const expectedResult = `read_error`; sample.mocks.dataset.runQuery.callsArgWith(1, expectedResult); request(sample.app) - .get('/') + .get(`/`) .expect(500) - .expect(function (response) { - assert.equal(response.text, expectedResult + '\n'); + .expect((response) => { + assert.equal(response.text, `${expectedResult}\n`); }) .end(done); }); diff --git a/appengine/disk/README.md b/appengine/disk/README.md index b26859230f..0f54c1e185 100644 --- a/appengine/disk/README.md +++ b/appengine/disk/README.md @@ -1,6 +1,6 @@ # Simple sample for Node.js on Google App Engine -This sample demonstrates reading from and writing to disk on [Google App Engine Managed VMs](https://cloud.google.com/appengine). +This sample demonstrates reading from and writing to disk on [Google App Engine Flexible Environment](https://cloud.google.com/appengine). ## Running locally diff --git a/appengine/disk/app.js b/appengine/disk/app.js index 26dda922a6..96295477d6 100644 --- a/appengine/disk/app.js +++ b/appengine/disk/app.js @@ -1,30 +1,31 @@ -// Copyright 2015-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. +/** + * 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. + */ // [START app] 'use strict'; // [START setup] -var fs = require('fs'); -var express = require('express'); -var crypto = require('crypto'); -var path = require('path'); +const fs = require('fs'); +const express = require('express'); +const crypto = require('crypto'); +const path = require('path'); -var app = express(); +const app = express(); app.enable('trust proxy'); -var FILENAME = path.join(__dirname, 'seen.txt'); +const FILENAME = path.join(__dirname, 'seen.txt'); // [END setup] // [START insertVisit] @@ -35,11 +36,12 @@ var FILENAME = path.join(__dirname, 'seen.txt'); * @param {function} callback The callback function. */ function insertVisit (visit, callback) { - fs.appendFile(FILENAME, JSON.stringify(visit) + '\n', function (err) { + fs.appendFile(FILENAME, `${JSON.stringify(visit)}\n`, (err) => { if (err) { - return callback(err); + callback(err); + return; } - return callback(); + callback(); }); } // [END insertVisit] @@ -51,56 +53,55 @@ function insertVisit (visit, callback) { * @param {function} callback The callback function. */ function getVisits (callback) { - fs.readFile(FILENAME, { encoding: 'utf8' }, function (err, data) { + fs.readFile(FILENAME, { encoding: 'utf8' }, (err, data) => { if (err) { - return callback(err); + callback(err); + return; } - var visits = data.split('\n') - .filter(function (line) { - return line; - }) - .map(function (line) { - var visit = JSON.parse(line); - return 'Time: ' + visit.timestamp + ', AddrHash: ' + visit.userIp; - }); + const visits = data.split('\n') + .filter((line) => line) + .map(JSON.parse) + .map((visit) => `Time: ${visit.timestamp}, AddrHash: ${visit.userIp}`); - return callback(null, visits); + callback(null, visits); }); } // [END getVisits] -app.get('/', function (req, res, next) { +app.get('/', (req, res, next) => { // Create a visit record to be stored on disk - var visit = { + const visit = { timestamp: new Date(), // Store a hash of the visitor's ip address userIp: crypto.createHash('sha256').update(req.ip).digest('hex').substr(0, 7) }; - insertVisit(visit, function (err) { + insertVisit(visit, (err) => { if (err) { - return next(err); + next(err); + return; } // Query the last 10 visits from disk. - getVisits(function (err, visits) { + getVisits((err, visits) => { if (err) { - return next(err); + next(err); + return; } - return res + res .status(200) .set('Content-Type', 'text/plain') - .send('Last 10 visits:\n' + visits.join('\n')); + .send(`Last 10 visits:\n${visits.join('\n')}`); }); }); }); // [START listen] -var PORT = process.env.PORT || 8080; -app.listen(PORT, function () { - console.log('App listening on port %s', PORT); +const PORT = process.env.PORT || 8080; +app.listen(PORT, () => { + console.log(`App listening on port ${PORT}`); console.log('Press Ctrl+C to quit.'); }); // [END listen] diff --git a/appengine/disk/app.yaml b/appengine/disk/app.yaml index 5a04eda9a4..248738be70 100644 --- a/appengine/disk/app.yaml +++ b/appengine/disk/app.yaml @@ -13,6 +13,5 @@ # [START app_yaml] runtime: nodejs -vm: true +env: flex # [END app_yaml] - diff --git a/appengine/disk/package.json b/appengine/disk/package.json index dfecd38ec7..780641bdd4 100644 --- a/appengine/disk/package.json +++ b/appengine/disk/package.json @@ -6,16 +6,16 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "engines": { - "node": "~4.2" + "node": ">=4.3.2" }, "scripts": { "start": "node app.js", "test": "mocha -R spec -t 120000 --require intelli-espower-loader ../../test/_setup.js test/*.test.js" }, "dependencies": { - "express": "^4.13.4" + "express": "^4.14.0" }, "devDependencies": { - "mocha": "^2.5.3" + "mocha": "^3.1.0" } } diff --git a/appengine/disk/test/app.test.js b/appengine/disk/test/app.test.js index 6455872d52..1e1ce8fdb3 100644 --- a/appengine/disk/test/app.test.js +++ b/appengine/disk/test/app.test.js @@ -1,39 +1,41 @@ -// 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. +/** + * 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 express = require('express'); -var path = require('path'); -var proxyquire = require('proxyquire').noPreserveCache(); -var request = require('supertest'); +const express = require(`express`); +const path = require(`path`); +const proxyquire = require(`proxyquire`).noPreserveCache(); +const request = require(`supertest`); -var SAMPLE_PATH = path.join(__dirname, '../app.js'); +const SAMPLE_PATH = path.join(__dirname, `../app.js`); function getSample () { - var testApp = express(); - sinon.stub(testApp, 'listen').callsArg(1); - var expressMock = sinon.stub().returns(testApp); - var resultsMock = JSON.stringify({ - timestamp: '1234', - userIp: 'abcd' - }) + '\n'; - var fsMock = { + const testApp = express(); + sinon.stub(testApp, `listen`).callsArg(1); + const expressMock = sinon.stub().returns(testApp); + const resultsMock = JSON.stringify({ + timestamp: `1234`, + userIp: `abcd` + }) + `\n`; + const fsMock = { appendFile: sinon.stub().callsArg(2), readFile: sinon.stub().callsArgWith(2, null, resultsMock) }; - var app = proxyquire(SAMPLE_PATH, { + const app = proxyquire(SAMPLE_PATH, { fs: fsMock, express: expressMock }); @@ -47,10 +49,10 @@ function getSample () { }; } -describe('appengine/disk/app.js', function () { - var sample; +describe(`appengine/disk/app.js`, () => { + let sample; - beforeEach(function () { + beforeEach(() => { sample = getSample(); assert(sample.mocks.express.calledOnce); @@ -58,42 +60,42 @@ describe('appengine/disk/app.js', function () { assert.equal(sample.app.listen.firstCall.args[0], process.env.PORT || 8080); }); - it('should record a visit', function (done) { - var expectedResult = 'Last 10 visits:\nTime: 1234, AddrHash: abcd'; + it(`should record a visit`, (done) => { + const expectedResult = `Last 10 visits:\nTime: 1234, AddrHash: abcd`; request(sample.app) - .get('/') + .get(`/`) .expect(200) - .expect(function (response) { + .expect((response) => { assert.equal(response.text, expectedResult); }) .end(done); }); - it('should handle insert error', function (done) { - var expectedResult = 'insert_error'; + it(`should handle insert error`, (done) => { + const expectedResult = `insert_error`; sample.mocks.fs.appendFile.callsArgWith(2, expectedResult); request(sample.app) - .get('/') + .get(`/`) .expect(500) - .expect(function (response) { - assert.equal(response.text, expectedResult + '\n'); + .expect((response) => { + assert.equal(response.text, expectedResult + `\n`); }) .end(done); }); - it('should handle read error', function (done) { - var expectedResult = 'read_error'; + it(`should handle read error`, (done) => { + const expectedResult = `read_error`; sample.mocks.fs.readFile.callsArgWith(2, expectedResult); request(sample.app) - .get('/') + .get(`/`) .expect(500) - .expect(function (response) { - assert.equal(response.text, expectedResult + '\n'); + .expect((response) => { + assert.equal(response.text, `${expectedResult}\n`); }) .end(done); }); diff --git a/appengine/endpoints/app.js b/appengine/endpoints/app.js index e882d6b037..f4dd583dcd 100644 --- a/appengine/endpoints/app.js +++ b/appengine/endpoints/app.js @@ -1,16 +1,17 @@ -// Copyright 2015-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. +/** + * 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. + */ // [START app] 'use strict'; diff --git a/appengine/endpoints/app.yaml b/appengine/endpoints/app.yaml index 6a22da0518..bc322c076c 100644 --- a/appengine/endpoints/app.yaml +++ b/appengine/endpoints/app.yaml @@ -12,7 +12,7 @@ # limitations under the License. runtime: nodejs -vm: true +env: flex beta_settings: # Enable Google Cloud Endpoints API management. diff --git a/appengine/endpoints/test/app.test.js b/appengine/endpoints/test/app.test.js index 1d88c55917..ec4d464c46 100644 --- a/appengine/endpoints/test/app.test.js +++ b/appengine/endpoints/test/app.test.js @@ -1,15 +1,17 @@ -// 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. +/** + * 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'; diff --git a/appengine/errorreporting/README.md b/appengine/errorreporting/README.md index 47dffaa879..f4b8f03a6c 100644 --- a/appengine/errorreporting/README.md +++ b/appengine/errorreporting/README.md @@ -1,7 +1,7 @@ # Node.js error reporting sample for Google App Engine This sample demonstrates error reporting in a Node.js app for -[Google App Engine Managed VMs](https://cloud.google.com/appengine). +[Google App Engine Flexible Environment](https://cloud.google.com/appengine). ## Running locally diff --git a/appengine/errorreporting/app.js b/appengine/errorreporting/app.js index 023176a2fa..2a976eb106 100644 --- a/appengine/errorreporting/app.js +++ b/appengine/errorreporting/app.js @@ -1,26 +1,27 @@ -// Copyright 2015-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. +/** + * 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. + */ // [START app] 'use strict'; // [START setup] -var express = require('express'); -var winston = require('winston'); +const express = require('express'); +const winston = require('winston'); -var app = express(); -var logFile = '/var/log/app_engine/custom_logs/myapp.errors.log.json'; +const app = express(); +const logFile = '/var/log/app_engine/custom_logs/myapp.errors.log.json'; winston.add(winston.transports.File, { filename: logFile @@ -28,7 +29,7 @@ winston.add(winston.transports.File, { // [END setup] function report (err, req) { - var payload = { + const payload = { message: err.stack, context: { httpRequest: { @@ -44,23 +45,22 @@ function report (err, req) { winston.error(payload); } -app.get('/', function (req, res, next) { +app.get('/', (req, res, next) => { next(new Error('something is wrong!')); }); -app.use(function (err, req, res, next) { +app.use((err, req, res, next) => { report(err, req); res.status(500).send(err.message || 'Something broke!'); }); // [START listen] -var PORT = process.env.PORT || 8080; -app.listen(PORT, function () { - console.log('App listening on port %s', PORT); +const PORT = process.env.PORT || 8080; +app.listen(PORT, () => { + console.log(`App listening on port ${PORT}`); console.log('Press Ctrl+C to quit.'); }); // [END listen] // [END app] module.exports = app; - diff --git a/appengine/errorreporting/app.yaml b/appengine/errorreporting/app.yaml index f6ffeb3d5d..248738be70 100644 --- a/appengine/errorreporting/app.yaml +++ b/appengine/errorreporting/app.yaml @@ -13,5 +13,5 @@ # [START app_yaml] runtime: nodejs -vm: true +env: flex # [END app_yaml] diff --git a/appengine/errorreporting/package.json b/appengine/errorreporting/package.json index f251f99315..cf10d55057 100644 --- a/appengine/errorreporting/package.json +++ b/appengine/errorreporting/package.json @@ -6,17 +6,17 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "engines": { - "node": "~4.2" + "node": ">=4.3.2" }, "scripts": { "start": "node app.js", "test": "mocha -R spec -t 120000 --require intelli-espower-loader ../../test/_setup.js test/*.test.js" }, "dependencies": { - "express": "^4.13.4", + "express": "^4.14.0", "winston": "^2.2.0" }, "devDependencies": { - "mocha": "^2.5.3" + "mocha": "^3.1.0" } } diff --git a/appengine/errorreporting/test/app.test.js b/appengine/errorreporting/test/app.test.js index 7ba157c1bc..52e99da01a 100644 --- a/appengine/errorreporting/test/app.test.js +++ b/appengine/errorreporting/test/app.test.js @@ -1,40 +1,42 @@ -// 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. +/** + * 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 express = require('express'); -var winston = require('winston'); -var path = require('path'); -var proxyquire = require('proxyquire').noPreserveCache(); -var request = require('supertest'); +const express = require(`express`); +const winston = require(`winston`); +const path = require(`path`); +const proxyquire = require(`proxyquire`).noPreserveCache(); +const request = require(`supertest`); -var SAMPLE_PATH = path.join(__dirname, '../app.js'); +const SAMPLE_PATH = path.join(__dirname, `../app.js`); function getSample () { - var testApp = express(); - sinon.stub(testApp, 'listen').callsArg(1); - var expressMock = sinon.stub().returns(testApp); - var resultsMock = JSON.stringify({ - timestamp: '1234', - userIp: 'abcd' - }) + '\n'; - var winstonMock = { + const testApp = express(); + sinon.stub(testApp, `listen`).callsArg(1); + const expressMock = sinon.stub().returns(testApp); + const resultsMock = JSON.stringify({ + timestamp: `1234`, + userIp: `abcd` + }) + `\n`; + const winstonMock = { add: sinon.stub(), error: sinon.stub() }; - var app = proxyquire(SAMPLE_PATH, { + const app = proxyquire(SAMPLE_PATH, { winston: winstonMock, express: expressMock }); @@ -48,10 +50,10 @@ function getSample () { }; } -describe('appengine/errorreporting/app.js', function () { - var sample; +describe(`appengine/errorreporting/app.js`, () => { + let sample; - beforeEach(function () { + beforeEach(() => { sample = getSample(); assert(sample.mocks.express.calledOnce); @@ -61,13 +63,13 @@ describe('appengine/errorreporting/app.js', function () { assert.equal(sample.app.listen.firstCall.args[0], process.env.PORT || 8080); }); - it('should throw an error', function (done) { - var expectedResult = 'something is wrong!'; + it(`should throw an error`, (done) => { + const expectedResult = `something is wrong!`; request(sample.app) - .get('/') + .get(`/`) .expect(500) - .expect(function (response) { + .expect((response) => { assert(sample.mocks.winston.error.calledOnce); assert.equal(response.text, expectedResult); }) diff --git a/appengine/express-memcached-session/README.md b/appengine/express-memcached-session/README.md index 6a682a2846..7e7f5499e2 100644 --- a/appengine/express-memcached-session/README.md +++ b/appengine/express-memcached-session/README.md @@ -1,10 +1,12 @@ # Express.js + Memcached Sessions on Google App Engine +**Note: This sample uses the older `vm: true` configuration. It will be upgraded +to use the newer `env: flex` configuration when `env: flex` fully supports +Memcached.** + This is a simple guide to using memcached for session state while running -[Express.js](http://expressjs.com/) on Google App Engine. Each Google App Engine -application comes with a memcached service instance, which can be reached with a -standard memcached driver at `memcache:11211`. This sample uses the -[connect-memcached](https://github.com/balor/connect-memcached) module to store +[Express.js](http://expressjs.com/) on Google App Engine. This sample uses the +[connect-memjs](https://github.com/liamdon/connect-memjs) module to store session data in memcached. ## Clone the Express.js + Memcached Sessions app @@ -19,22 +21,20 @@ Alternatively, you can [download the sample][download] as a zip and extract it. ## Run the app on your local computer -1. Install dependencies. Enter the following command: +1. Install dependencies: npm install -1. Run the start script. +1. Run the start script: npm start -1. In your web browser, enter the following address: +1. In your web browser, visit the following address: http://localhost:8080 -You can see the sample app displayed in the page. This page was delivered by the -Express.js web server running on your computer. - -In your terminal window, press Ctrl+C to exit the web server. +You can see the sample app displayed in the page. In your terminal window, press +Ctrl+C to exit the web server. ## Deploy the app to Google Cloud Platform @@ -48,30 +48,12 @@ In your web browser, enter the following address: https://.appspot.com -For convenience, you can use an npm script to run the gcloud command. Add these -lines to your package.json file: - - "scripts": { - "start": "node server.js", - "deploy": "gcloud app deploy" - } - -At the terminal you can now run the following command to deploy your application: - - npm run deploy - ## Configuration -Every Managed VMs application requires an app.yaml file to describe its -deployment configuration. +Every Google App Engine Flexible Environment application requires an `app.yaml` +file to describe its deployment configuration: runtime: nodejs - vm: true - env_variables: - PORT: 8080 - MEMCACHE_URL: memcache:11211 - -Notice the `MEMCACHE_URL` environment variable–this is where you can reach your -standard memcached cluster across instances. + env: flex [download]: https://github.com/GoogleCloudPlatform/nodejs-docs-samples/archive/master.zip diff --git a/appengine/express-memcached-session/app.yaml b/appengine/express-memcached-session/app.yaml index 8fda01e189..9e53787477 100644 --- a/appengine/express-memcached-session/app.yaml +++ b/appengine/express-memcached-session/app.yaml @@ -1,4 +1,4 @@ -# Copyright 2015-2016, Google, Inc. +# 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 @@ -13,7 +13,17 @@ # [START app_yaml] runtime: nodejs -vm: true +env: flex + +# [START env_variables] env_variables: - MEMCACHE_URL: memcache:11211 + # If you are using the App Engine Memcache service (currently in alpha), + # uncomment this section and comment out the other Memcache variables. + # USE_GAE_MEMCACHE: 1 + MEMCACHE_URL: your-memcache-url + # If you are using a Memcached server with SASL authentiation enabled, + # fill in these values with your username and password. + MEMCACHE_USERNAME: your-memcache-username + MEMCACHE_PASSWORD: your-memcache-password +# [END env_variables] # [END app_yaml] diff --git a/appengine/express-memcached-session/package.json b/appengine/express-memcached-session/package.json index 4bea4bb748..d71bf20d8e 100644 --- a/appengine/express-memcached-session/package.json +++ b/appengine/express-memcached-session/package.json @@ -1,25 +1,25 @@ { "name": "appengine-express-memcached-session", - "description": "An example of using memcached for sessions in Express.js on Google App Engine.", + "description": "An example of using memcached for sessions in Express.js on Google App Engine Flexible Environment", "version": "0.0.1", "private": true, "license": "Apache Version 2.0", "author": "Google Inc.", "engines": { - "node": "~4.2" + "node": ">=4.3.2" }, "scripts": { "start": "node server.js", - "test": "mocha -R spec -t 120000 --require intelli-espower-loader ../../test/_setup.js test/*.test.js" + "test": "mocha -R spec -t 1000 --require intelli-espower-loader ../../test/_setup.js test/*.test.js" }, "dependencies": { - "connect-memcached": "^0.1.0", - "cookie-parser": "^1.4.1", - "express": "^4.13.4", - "express-session": "^1.13.0", - "public-ip": "^1.1.0" + "connect-memjs": "^0.1.0", + "cookie-parser": "^1.4.3", + "express": "^4.14.0", + "express-session": "^1.14.2", + "public-ip": "^2.0.1" }, "devDependencies": { - "mocha": "^2.5.3" + "mocha": "^3.1.2" } } diff --git a/appengine/express-memcached-session/server.js b/appengine/express-memcached-session/server.js index f9eae880ee..932e94c629 100644 --- a/appengine/express-memcached-session/server.js +++ b/appengine/express-memcached-session/server.js @@ -1,28 +1,37 @@ -// Copyright 2015-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. +/** + * 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. + */ // [START app] 'use strict'; // [START setup] -var express = require('express'); -var session = require('express-session'); -var cookieParser = require('cookie-parser'); -var MemcachedStore = require('connect-memcached')(session); -var publicIp = require('public-ip'); -var crypto = require('crypto'); +const express = require('express'); +const session = require('express-session'); +const cookieParser = require('cookie-parser'); +const MemcachedStore = require('connect-memjs')(session); +const publicIp = require('public-ip'); +const crypto = require('crypto'); -var app = express(); +// Environment variables are defined in app.yaml. +let MEMCACHE_URL = process.env.MEMCACHE_URL || '127.0.0.1:11211'; + +if (process.env.USE_GAE_MEMCACHE) { + MEMCACHE_URL = `${process.env.GAE_MEMCACHE_HOST}:${process.env.GAE_MEMCACHE_PORT}`; +} + +const app = express(); app.enable('trust proxy'); // [END setup] @@ -32,33 +41,30 @@ app.use(session({ key: 'view:count', proxy: 'true', store: new MemcachedStore({ - hosts: [process.env.MEMCACHE_URL || '127.0.0.1:11211'] + servers: [MEMCACHE_URL] }) })); -app.get('/', function (req, res, next) { +app.get('/', (req, res, next) => { // Discover requester's public IP address - publicIp.v4(function (err, ip) { - if (err) { - return next(err); - } - var userIp = crypto.createHash('sha256').update(ip).digest('hex').substr(0, 7); + publicIp.v4().then((ip) => { + const userIp = crypto.createHash('sha256').update(ip).digest('hex').substr(0, 7); // This shows the hashed IP for each - res.write('
' + userIp + '
'); + res.write(`
${userIp}
`); if (req.session.views) { req.session.views += 1; } else { req.session.views = 1; } - res.end('Viewed ' + req.session.views + ' times.'); - }); + res.end(`Viewed ${req.session.views} times.`); + }).catch(next); }); // [START listen] -var PORT = process.env.PORT || 8080; -app.listen(PORT, function () { +const PORT = process.env.PORT || 8080; +app.listen(PORT, () => { console.log('App listening on port %s', PORT); console.log('Press Ctrl+C to quit.'); }); diff --git a/appengine/express-memcached-session/test/server.test.js b/appengine/express-memcached-session/test/server.test.js index 3cb045ba11..93c1f1e8ec 100644 --- a/appengine/express-memcached-session/test/server.test.js +++ b/appengine/express-memcached-session/test/server.test.js @@ -1,39 +1,41 @@ -// 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. +/** + * 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 express = require('express'); -var session = require('express-session'); -var path = require('path'); -var proxyquire = require('proxyquire').noPreserveCache(); -var request = require('supertest'); +const express = require(`express`); +const session = require(`express-session`); +const path = require(`path`); +const proxyquire = require(`proxyquire`).noPreserveCache(); +const request = require(`supertest`); -var SAMPLE_PATH = path.join(__dirname, '../server.js'); +const SAMPLE_PATH = path.join(__dirname, `../server.js`); function getSample () { - var testApp = express(); - sinon.stub(testApp, 'listen').callsArg(1); - var storeMock = session.MemoryStore; - var expressMock = sinon.stub().returns(testApp); - var memcachedMock = sinon.stub().returns(storeMock); - var publicIpMock = { - v4: sinon.stub().callsArgWith(0, null, '123.45.67.890') + const testApp = express(); + sinon.stub(testApp, `listen`).callsArg(1); + const storeMock = session.MemoryStore; + const expressMock = sinon.stub().returns(testApp); + const memcachedMock = sinon.stub().returns(storeMock); + const publicIpMock = { + v4: sinon.stub().yields(null, `123.45.67.890`) }; - var app = proxyquire(SAMPLE_PATH, { + const app = proxyquire(SAMPLE_PATH, { publicIp: publicIpMock, - 'connect-memcached': memcachedMock, + 'connect-memjs': memcachedMock, express: expressMock }); return { @@ -41,16 +43,16 @@ function getSample () { mocks: { express: expressMock, store: storeMock, - 'connect-memcached': memcachedMock, + 'connect-memjs': memcachedMock, publicIp: publicIpMock } }; } -describe('appengine/express-memcached-session/app.js', function () { - var sample; +describe(`appengine/express-memcached-session/app.js`, () => { + let sample; - beforeEach(function () { + beforeEach(() => { sample = getSample(); assert(sample.mocks.express.calledOnce); @@ -58,13 +60,13 @@ describe('appengine/express-memcached-session/app.js', function () { assert.equal(sample.app.listen.firstCall.args[0], process.env.PORT || 8080); }); - it('should respond with visit count', function (done) { - var expectedResult = 'Viewed 1 times.'; + it(`should respond with visit count`, (done) => { + const expectedResult = `Viewed 1 times.`; request(sample.app) - .get('/') + .get(`/`) .expect(200) - .expect(function (response) { + .expect((response) => { assert(response.text.indexOf(expectedResult) !== -1); }) .end(done); diff --git a/appengine/express/app.js b/appengine/express/app.js index 3962756cf2..7357040d60 100644 --- a/appengine/express/app.js +++ b/appengine/express/app.js @@ -1,33 +1,35 @@ -// Copyright 2015-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. +/** + * 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. + */ // [START app] 'use strict'; // [START setup] -var express = require('express'); -var path = require('path'); -var logger = require('morgan'); -var cookieParser = require('cookie-parser'); -var bodyParser = require('body-parser'); +const express = require('express'); +const path = require('path'); +const logger = require('morgan'); +const cookieParser = require('cookie-parser'); +const bodyParser = require('body-parser'); -var app = express(); +const app = express(); app.enable('trust proxy'); // [END setup] // view engine setup +app.set('view engine', 'pug'); app.set('views', path.join(__dirname, 'views')); -app.set('view engine', 'jade'); app.use(logger('dev')); app.use(bodyParser.json()); @@ -39,8 +41,8 @@ app.use('/', require('./routes/index')); app.use('/users', require('./routes/users')); // catch 404 and forward to error handler -app.use(function (req, res, next) { - var err = new Error('Not Found'); +app.use((req, res, next) => { + const err = new Error('Not Found'); err.status = 404; next(err); }); @@ -50,7 +52,7 @@ app.use(function (req, res, next) { // development error handler // will print stacktrace if (app.get('env') === 'development') { - app.use(function (err, req, res) { + app.use((err, req, res) => { res.status(err.status || 500); res.render('error', { message: err.message, @@ -61,7 +63,8 @@ if (app.get('env') === 'development') { // production error handler // no stacktraces leaked to user -app.use(function (err, req, res) { +app.use((err, req, res) => { + console.log(err); res.status(err.status || 500); res.render('error', { message: err.message, diff --git a/appengine/express/app.yaml b/appengine/express/app.yaml index f6ffeb3d5d..248738be70 100644 --- a/appengine/express/app.yaml +++ b/appengine/express/app.yaml @@ -13,5 +13,5 @@ # [START app_yaml] runtime: nodejs -vm: true +env: flex # [END app_yaml] diff --git a/appengine/express/bin/www b/appengine/express/bin/www index 7d9036ee45..dca57cdbf4 100755 --- a/appengine/express/bin/www +++ b/appengine/express/bin/www @@ -1,5 +1,20 @@ #!/usr/bin/env node +/** + * 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'; // [START server] @@ -7,21 +22,21 @@ /** * Module dependencies. */ -var app = require('../app'); -var debug = require('debug')('express:server'); -var http = require('http'); +const app = require('../app'); +const debug = require('debug')('express:server'); +const http = require('http'); /** * Get port from environment and store in Express. */ -var port = normalizePort(process.env.PORT || 8080); +const port = normalizePort(process.env.PORT || 8080); app.set('port', port); /** * Create HTTP server. */ -var server = http.createServer(app); +const server = http.createServer(app); /** * Listen on provided port, on all network interfaces. @@ -36,7 +51,7 @@ server.on('listening', onListening); * Normalize a port into a number, string, or false. */ function normalizePort(val) { - var port = parseInt(val, 10); + const port = parseInt(val, 10); if (isNaN(port)) { // named pipe @@ -59,7 +74,7 @@ function onError(error) { throw error; } - var bind = typeof port === 'string' + const bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port; @@ -82,8 +97,8 @@ function onError(error) { * Event listener for HTTP server "listening" event. */ function onListening() { - var addr = server.address(); - var bind = typeof addr === 'string' + const addr = server.address(); + const bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port; debug('Listening on ' + bind); diff --git a/appengine/express/package.json b/appengine/express/package.json index 2dc1bd22e2..3d15a96164 100644 --- a/appengine/express/package.json +++ b/appengine/express/package.json @@ -6,22 +6,22 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "engines": { - "node": "~4.2" + "node": ">=4.3.2" }, "scripts": { "start": "node ./bin/www", - "test": "mocha -R spec -t 120000 --require intelli-espower-loader ../../test/_setup.js test/*.test.js" + "test": "mocha -R spec -t 1000 --require intelli-espower-loader ../../test/_setup.js test/*.test.js" }, "dependencies": { - "body-parser": "^1.14.2", - "cookie-parser": "^1.4.1", - "debug": "^2.2.0", - "express": "^4.13.4", - "jade": "^1.11.0", - "morgan": "^1.6.1", + "body-parser": "^1.15.2", + "cookie-parser": "^1.4.3", + "debug": "^2.3.2", + "express": "^4.14.0", + "morgan": "^1.7.0", + "pug": "^2.0.0-beta6", "serve-favicon": "^2.3.0" }, "devDependencies": { - "mocha": "^2.5.3" + "mocha": "^3.1.2" } -} \ No newline at end of file +} diff --git a/appengine/express/routes/index.js b/appengine/express/routes/index.js index 907ebced98..c519a6f258 100644 --- a/appengine/express/routes/index.js +++ b/appengine/express/routes/index.js @@ -1,23 +1,25 @@ -// Copyright 2015-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. +/** + * 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 express = require('express'); -var router = express.Router(); +const express = require('express'); +const router = express.Router(); // [START hello_world] -router.get('/', function (req, res) { +router.get('/', (req, res) => { res.render('index', { title: 'Hello World! Express.js on Google App Engine.' }); diff --git a/appengine/express/routes/users.js b/appengine/express/routes/users.js index 0d400a494f..3c2182913e 100644 --- a/appengine/express/routes/users.js +++ b/appengine/express/routes/users.js @@ -1,23 +1,25 @@ -// Copyright 2015-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. +/** + * 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 express = require('express'); -var router = express.Router(); +const express = require('express'); +const router = express.Router(); /* GET users listing. */ -router.get('/', function (req, res) { +router.get('/', (req, res) => { res.send('respond with a resource'); }); diff --git a/appengine/express/test/app.test.js b/appengine/express/test/app.test.js index c781cc927a..bbf2f9d8c0 100644 --- a/appengine/express/test/app.test.js +++ b/appengine/express/test/app.test.js @@ -1,70 +1,72 @@ -// 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. +/** + * 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 path = require('path'); -var proxyquire = require('proxyquire').noPreserveCache(); -var request = require('supertest'); +const path = require(`path`); +const proxyquire = require(`proxyquire`).noPreserveCache(); +const request = require(`supertest`); -var SAMPLE_PATH = path.join(__dirname, '../app.js'); +const SAMPLE_PATH = path.join(__dirname, `../app.js`); function getSample () { - var app = proxyquire(SAMPLE_PATH, {}); + const app = proxyquire(SAMPLE_PATH, {}); return { app: app, mocks: {} }; } -describe('appengine/express/app.js', function () { - var sample; +describe(`appengine/express/app.js`, () => { + let sample; - beforeEach(function () { + beforeEach(() => { sample = getSample(); }); - it('should render index page', function (done) { - var expectedResult = 'Hello World! Express.js on Google App Engine.'; + it(`should render index page`, (done) => { + const expectedResult = `Hello World! Express.js on Google App Engine.`; request(sample.app) - .get('/') + .get(`/`) .expect(200) - .expect(function (response) { + .expect((response) => { assert(response.text.indexOf(expectedResult) !== -1); }) .end(done); }); - it('should render users page', function (done) { - var expectedResult = 'respond with a resource'; + it(`should render users page`, (done) => { + const expectedResult = `respond with a resource`; request(sample.app) - .get('/users') + .get(`/users`) .expect(200) - .expect(function (response) { + .expect((response) => { assert(response.text.indexOf(expectedResult) !== -1); }) .end(done); }); - it('should catch 404', function (done) { - var expectedResult = 'Error: Not Found'; + it(`should catch 404`, (done) => { + const expectedResult = `Error: Not Found`; request(sample.app) - .get('/doesnotexist') + .get(`/doesnotexist`) .expect(404) - .expect(function (response) { + .expect((response) => { assert(response.text.indexOf(expectedResult) !== -1); }) .end(done); diff --git a/appengine/express/views/error.jade b/appengine/express/views/error.jade deleted file mode 100644 index 28c938f622..0000000000 --- a/appengine/express/views/error.jade +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2015-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. - -extends layout - -block content - h1= message - h2= error.status - pre #{error.stack} diff --git a/appengine/express/views/error.pug b/appengine/express/views/error.pug new file mode 100644 index 0000000000..51ec12c6a2 --- /dev/null +++ b/appengine/express/views/error.pug @@ -0,0 +1,6 @@ +extends layout + +block content + h1= message + h2= error.status + pre #{error.stack} diff --git a/appengine/express/views/index.jade b/appengine/express/views/index.jade deleted file mode 100644 index fb89323e39..0000000000 --- a/appengine/express/views/index.jade +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2015-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. - -extends layout - -block content - h1= title - p Welcome to #{title} diff --git a/appengine/express/views/index.pug b/appengine/express/views/index.pug new file mode 100644 index 0000000000..3d63b9a044 --- /dev/null +++ b/appengine/express/views/index.pug @@ -0,0 +1,5 @@ +extends layout + +block content + h1= title + p Welcome to #{title} diff --git a/appengine/express/views/layout.jade b/appengine/express/views/layout.jade deleted file mode 100644 index fa11512d2a..0000000000 --- a/appengine/express/views/layout.jade +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2015-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. - -doctype html -html - head - title= title - link(rel='stylesheet', href='/stylesheets/style.css') - body - block content \ No newline at end of file diff --git a/appengine/express/views/layout.pug b/appengine/express/views/layout.pug new file mode 100644 index 0000000000..b945f5776e --- /dev/null +++ b/appengine/express/views/layout.pug @@ -0,0 +1,7 @@ +doctype html +html + head + title= title + link(rel='stylesheet', href='/stylesheets/style.css') + body + block content \ No newline at end of file diff --git a/appengine/extending-runtime/Dockerfile b/appengine/extending-runtime/Dockerfile old mode 100755 new mode 100644 index cd2223d311..efb931acd2 --- a/appengine/extending-runtime/Dockerfile +++ b/appengine/extending-runtime/Dockerfile @@ -1,12 +1,12 @@ -# This is the standard Node.js runtime image. It is essentially Debian with -# Node.js pre-installed. +# Dockerfile extending the generic Node image with application files for a +# single application. FROM gcr.io/google_appengine/nodejs # Install something custom RUN apt-get update && apt-get install -y fortunes -# Install a particular version of Node.js -RUN install_node v4.2.3 +# Install Node.js +RUN /usr/local/bin/install_node '>=4.3.2' # Copy application code. COPY . /app/ @@ -15,4 +15,4 @@ COPY . /app/ RUN npm --unsafe-perm install # Run the app, default is "npm start" -CMD npm run start-on-prod +CMD npm start diff --git a/appengine/extending-runtime/README.md b/appengine/extending-runtime/README.md index 96916f0497..f311bdae17 100644 --- a/appengine/extending-runtime/README.md +++ b/appengine/extending-runtime/README.md @@ -1,7 +1,7 @@ -# Sample for extending the Google App Engine Managed VMs Node.js runtime +# Sample for extending the Google App Engine Flexible Environment Node.js runtime This sample demonstrates how to create a custom Dockerfile and extend the -Node.js runtime used by [Google App Engine Managed VMs](https://cloud.google.com/appengine). +Node.js runtime used by [Google App Engine Flexible Environment](https://cloud.google.com/appengine). The Dockerfile in this sample will automatically be used during deployment. diff --git a/appengine/extending-runtime/app.js b/appengine/extending-runtime/app.js index b74ef64fa9..1f61b996e4 100644 --- a/appengine/extending-runtime/app.js +++ b/appengine/extending-runtime/app.js @@ -1,31 +1,33 @@ -// Copyright 2015-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. +/** + * 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. + */ // [START app] 'use strict'; -var exec = require('child_process').exec; -var express = require('express'); +const exec = require('child_process').exec; +const express = require('express'); -var app = express(); +const app = express(); -app.get('/', function (req, res, next) { +app.get('/', (req, res, next) => { // Get the output from the "fortune" program. This is installed into the // environment by the Dockerfile. - exec('/usr/games/fortune', function (err, stdout) { + exec('/usr/games/fortune', (err, stdout) => { if (err) { - return next(err); + next(err); + return; } res.set('Content-Type', 'text/plain'); @@ -33,8 +35,9 @@ app.get('/', function (req, res, next) { }); }); -var server = app.listen(process.env.PORT || 8080, function () { - console.log('App listening on port %s', server.address().port); +const PORT = process.env.PORT || 8080; +app.listen(PORT, () => { + console.log(`App listening on port ${PORT}`); console.log('Press Ctrl+C to quit.'); }); // [END app] diff --git a/appengine/extending-runtime/app.yaml b/appengine/extending-runtime/app.yaml index 45a8be4ffe..8d61a5f4fc 100644 --- a/appengine/extending-runtime/app.yaml +++ b/appengine/extending-runtime/app.yaml @@ -13,8 +13,5 @@ # [START app_yaml] runtime: custom -vm: true - -skip_files: - - ^(.*/)?.*/node_modules/.*$ +env: flex # [END app_yaml] diff --git a/appengine/extending-runtime/package.json b/appengine/extending-runtime/package.json index 8def54bab3..12a064119d 100644 --- a/appengine/extending-runtime/package.json +++ b/appengine/extending-runtime/package.json @@ -1,20 +1,17 @@ { "name": "appengine-extending-runtime", - "description": "Sample for extending the Google App Engine Managed VMs Node.js runtime", + "description": "Sample for extending the Google App Engine Flexible Environment Node.js runtime", "version": "0.0.1", "private": true, "license": "Apache Version 2.0", "author": "Google Inc.", "engines": { - "node": "~4.2" + "node": ">=4.3.2" }, "scripts": { - "start": "node app.js", - "start-on-prod": "node app.js", - "monitor": "nodemon app.js", - "deploy": "gcloud app deploy" + "start": "node app.js" }, "dependencies": { - "express": "^4.13.4" + "express": "^4.14.0" } } diff --git a/appengine/geddy/app.yaml b/appengine/geddy/app.yaml index f6ffeb3d5d..248738be70 100644 --- a/appengine/geddy/app.yaml +++ b/appengine/geddy/app.yaml @@ -13,5 +13,5 @@ # [START app_yaml] runtime: nodejs -vm: true +env: flex # [END app_yaml] diff --git a/appengine/geddy/package.json b/appengine/geddy/package.json index 2ff08d1579..5b436e0976 100644 --- a/appengine/geddy/package.json +++ b/appengine/geddy/package.json @@ -6,13 +6,12 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "engines": { - "node": "~4.2" + "node": ">=4.3.2" }, "scripts": { "prestart": "GEDDY_SECRET=config/secrets.json; [[ -f $GEDDY_SECRET ]] || echo '{}' > $GEDDY_SECRET && geddy gen secret", "start": "geddy", - "debug": "geddy --debug", - "deploy": "gcloud app deploy" + "debug": "geddy --debug" }, "dependencies": { "geddy": "^13.0.8" diff --git a/appengine/grunt/app.yaml b/appengine/grunt/app.yaml index f6ffeb3d5d..248738be70 100644 --- a/appengine/grunt/app.yaml +++ b/appengine/grunt/app.yaml @@ -13,5 +13,5 @@ # [START app_yaml] runtime: nodejs -vm: true +env: flex # [END app_yaml] diff --git a/appengine/grunt/package.json b/appengine/grunt/package.json index 270c01c130..13a724b6f5 100644 --- a/appengine/grunt/package.json +++ b/appengine/grunt/package.json @@ -6,26 +6,25 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "engines": { - "node": "~4.2" + "node": ">=4.3.2" }, "scripts": { "start": "node ./src/bin/www", - "postinstall": "grunt build", - "deploy": "gcloud app deploy" + "postinstall": "grunt build" }, "dependencies": { - "body-parser": "^1.14.2", - "cookie-parser": "^1.4.1", + "body-parser": "^1.15.2", + "cookie-parser": "^1.4.3", "debug": "^2.2.0", - "express": "^4.13.4", - "grunt": "^0.4.5", - "grunt-cli": "^0.1.13", - "grunt-contrib-clean": "^0.7.0", - "grunt-contrib-cssmin": "^0.14.0", - "grunt-contrib-jshint": "^0.12.0", - "grunt-contrib-watch": "^0.6.1", - "jade": "^1.11.0", - "morgan": "^1.6.1", + "express": "^4.14.0", + "grunt": "^1.0.1", + "grunt-cli": "^1.2.0", + "grunt-contrib-clean": "^1.0.0", + "grunt-contrib-cssmin": "^1.0.2", + "grunt-contrib-jshint": "^1.0.0", + "grunt-contrib-watch": "^1.0.0", + "morgan": "^1.7.0", + "pug": "^2.0.0-beta6", "serve-favicon": "^2.3.0" } } diff --git a/appengine/grunt/src/app.js b/appengine/grunt/src/app.js index d363f284fe..258ba988fb 100644 --- a/appengine/grunt/src/app.js +++ b/appengine/grunt/src/app.js @@ -1,32 +1,34 @@ -// Copyright 2015-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. +/** + * 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 express = require('express'); -var path = require('path'); -var logger = require('morgan'); -var cookieParser = require('cookie-parser'); -var bodyParser = require('body-parser'); +const express = require('express'); +const path = require('path'); +const logger = require('morgan'); +const cookieParser = require('cookie-parser'); +const bodyParser = require('body-parser'); -var routes = require('./routes/index'); -var users = require('./routes/users'); +const routes = require('./routes/index'); +const users = require('./routes/users'); -var app = express(); +const app = express(); // view engine setup app.set('views', path.join(__dirname, 'views')); -app.set('view engine', 'jade'); +app.set('view engine', 'pug'); app.use(logger('dev')); app.use(bodyParser.json()); @@ -38,8 +40,8 @@ app.use('/', routes); app.use('/users', users); // catch 404 and forward to error handler -app.use(function (req, res, next) { - var err = new Error('Not Found'); +app.use((req, res, next) => { + const err = new Error('Not Found'); err.status = 404; next(err); }); @@ -49,7 +51,7 @@ app.use(function (req, res, next) { // development error handler // will print stacktrace if (app.get('env') === 'development') { - app.use(function (err, req, res) { + app.use((err, req, res) => { res.status(err.status || 500); res.render('error', { message: err.message, @@ -60,7 +62,7 @@ if (app.get('env') === 'development') { // production error handler // no stacktraces leaked to user -app.use(function (err, req, res) { +app.use((err, req, res) => { res.status(err.status || 500); res.render('error', { message: err.message, diff --git a/appengine/grunt/src/bin/www b/appengine/grunt/src/bin/www index 7d9036ee45..5edc01b635 100755 --- a/appengine/grunt/src/bin/www +++ b/appengine/grunt/src/bin/www @@ -1,5 +1,20 @@ #!/usr/bin/env node +/** + * 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'; // [START server] @@ -7,21 +22,21 @@ /** * Module dependencies. */ -var app = require('../app'); -var debug = require('debug')('express:server'); -var http = require('http'); +const app = require('../app'); +const debug = require('debug')('express:server'); +const http = require('http'); /** * Get port from environment and store in Express. */ -var port = normalizePort(process.env.PORT || 8080); +const port = normalizePort(process.env.PORT || 8080); app.set('port', port); /** * Create HTTP server. */ -var server = http.createServer(app); +const server = http.createServer(app); /** * Listen on provided port, on all network interfaces. @@ -36,7 +51,7 @@ server.on('listening', onListening); * Normalize a port into a number, string, or false. */ function normalizePort(val) { - var port = parseInt(val, 10); + const port = parseInt(val, 10); if (isNaN(port)) { // named pipe @@ -59,18 +74,18 @@ function onError(error) { throw error; } - var bind = typeof port === 'string' + const bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port; // handle specific listen errors with friendly messages switch (error.code) { case 'EACCES': - console.error(bind + ' requires elevated privileges'); + console.error(`${bind} requires elevated privileges`); process.exit(1); break; case 'EADDRINUSE': - console.error(bind + ' is already in use'); + console.error(`${bind} is already in use`); process.exit(1); break; default: @@ -82,8 +97,8 @@ function onError(error) { * Event listener for HTTP server "listening" event. */ function onListening() { - var addr = server.address(); - var bind = typeof addr === 'string' + const addr = server.address(); + const bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port; debug('Listening on ' + bind); diff --git a/appengine/grunt/src/public/stylesheets/style.css b/appengine/grunt/src/public/stylesheets/style.css index e5f6dc8847..0366e2dbb2 100644 --- a/appengine/grunt/src/public/stylesheets/style.css +++ b/appengine/grunt/src/public/stylesheets/style.css @@ -21,5 +21,5 @@ a { } h1 { - color: #FF0; + color: #0079ff; } \ No newline at end of file diff --git a/appengine/grunt/src/routes/index.js b/appengine/grunt/src/routes/index.js index 258dfc6a29..9de523759d 100644 --- a/appengine/grunt/src/routes/index.js +++ b/appengine/grunt/src/routes/index.js @@ -1,23 +1,25 @@ -// Copyright 2015-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. +/** + * 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 express = require('express'); -var router = express.Router(); +const express = require('express'); +const router = express.Router(); // [START hello_world] -router.get('/', function (req, res) { +router.get('/', (req, res) => { res.render('index', { title: 'Hello World! Express.js + Grunt.js on Google App Engine.' }); diff --git a/appengine/grunt/src/routes/users.js b/appengine/grunt/src/routes/users.js index 0b65a3f76d..6f58fbdcfa 100644 --- a/appengine/grunt/src/routes/users.js +++ b/appengine/grunt/src/routes/users.js @@ -1,23 +1,25 @@ -// Copyright 2015-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. +/** + * 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 express = require('express'); -var router = express.Router(); +const express = require('express'); +const router = express.Router(); /* GET users listing. */ -router.get('/', function (req, res, next) { +router.get('/', (req, res, next) => { res.send('respond with a resource'); }); diff --git a/appengine/grunt/src/views/error.jade b/appengine/grunt/src/views/error.jade deleted file mode 100644 index 28c938f622..0000000000 --- a/appengine/grunt/src/views/error.jade +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2015-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. - -extends layout - -block content - h1= message - h2= error.status - pre #{error.stack} diff --git a/appengine/grunt/src/views/error.pug b/appengine/grunt/src/views/error.pug new file mode 100644 index 0000000000..51ec12c6a2 --- /dev/null +++ b/appengine/grunt/src/views/error.pug @@ -0,0 +1,6 @@ +extends layout + +block content + h1= message + h2= error.status + pre #{error.stack} diff --git a/appengine/grunt/src/views/index.jade b/appengine/grunt/src/views/index.jade deleted file mode 100644 index fb89323e39..0000000000 --- a/appengine/grunt/src/views/index.jade +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2015-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. - -extends layout - -block content - h1= title - p Welcome to #{title} diff --git a/appengine/grunt/src/views/index.pug b/appengine/grunt/src/views/index.pug new file mode 100644 index 0000000000..3d63b9a044 --- /dev/null +++ b/appengine/grunt/src/views/index.pug @@ -0,0 +1,5 @@ +extends layout + +block content + h1= title + p Welcome to #{title} diff --git a/appengine/grunt/src/views/layout.jade b/appengine/grunt/src/views/layout.jade deleted file mode 100644 index 2d30f50f53..0000000000 --- a/appengine/grunt/src/views/layout.jade +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2015-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. - -doctype html -html - head - title= title - link(rel='stylesheet', href='/stylesheets/style.min.css') - body - block content \ No newline at end of file diff --git a/appengine/grunt/src/views/layout.pug b/appengine/grunt/src/views/layout.pug new file mode 100644 index 0000000000..b12a293ab7 --- /dev/null +++ b/appengine/grunt/src/views/layout.pug @@ -0,0 +1,7 @@ +doctype html +html + head + title= title + link(rel='stylesheet', href='/stylesheets/style.min.css') + body + block content \ No newline at end of file diff --git a/appengine/hapi/app.yaml b/appengine/hapi/app.yaml index f6ffeb3d5d..248738be70 100644 --- a/appengine/hapi/app.yaml +++ b/appengine/hapi/app.yaml @@ -13,5 +13,5 @@ # [START app_yaml] runtime: nodejs -vm: true +env: flex # [END app_yaml] diff --git a/appengine/hapi/index.js b/appengine/hapi/index.js index 6f4d712157..7a84fa65d1 100644 --- a/appengine/hapi/index.js +++ b/appengine/hapi/index.js @@ -1,23 +1,25 @@ -// Copyright 2015-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. +/** + * 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'; // [START server] -var Hapi = require('hapi'); +const Hapi = require('hapi'); // Create a server with a host and port -var server = new Hapi.Server(); +const server = new Hapi.Server(); server.connection({ host: '0.0.0.0', port: process.env.PORT || 8080 @@ -28,7 +30,7 @@ server.connection({ server.route({ method: 'GET', path: '/', - handler: function (request, reply) { + handler: (request, reply) => { reply('Hello World! Hapi.js on Google App Engine.'); } }); @@ -38,13 +40,13 @@ server.route({ server.route({ method: 'GET', path: '/hello', - handler: function (request, reply) { + handler: (request, reply) => { reply('Hello World! Hapi.js on Google App Engine.'); } }); // [START server_start] -server.start(function () { - console.log('Server running at:', server.info.uri); +server.start(() => { + console.log(`Server running at: ${server.info.uri}`); }); // [END server_start] diff --git a/appengine/hapi/package.json b/appengine/hapi/package.json index 389e101266..bd342ca3c1 100644 --- a/appengine/hapi/package.json +++ b/appengine/hapi/package.json @@ -6,13 +6,12 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "engines": { - "node": "~4.2" + "node": ">=4.3.2" }, "scripts": { - "start": "node index.js", - "deploy": "gcloud app deploy" + "start": "node index.js" }, "dependencies": { - "hapi": "^13.0.0" + "hapi": "^15.1.1" } } diff --git a/appengine/hello-world/README.md b/appengine/hello-world/README.md index 2f7c622afc..993d0a7d8d 100644 --- a/appengine/hello-world/README.md +++ b/appengine/hello-world/README.md @@ -1,6 +1,6 @@ # Simple Hello World Node.js sample for Google App Engine -This sample demonstrates a tiny Hello World Node.js app for [Google App Engine Managed VMs](https://cloud.google.com/appengine). +This sample demonstrates a tiny Hello World Node.js app for [Google App Engine Flexible Environment](https://cloud.google.com/appengine). ## Running locally diff --git a/appengine/hello-world/app.js b/appengine/hello-world/app.js index c4d634324b..fad708e77d 100644 --- a/appengine/hello-world/app.js +++ b/appengine/hello-world/app.js @@ -1,31 +1,32 @@ -// Copyright 2015-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. +/** + * 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. + */ // [START app] 'use strict'; -var express = require('express'); +const express = require('express'); +const app = express(); -var app = express(); - -app.get('/', function (req, res) { +app.get('/', (req, res) => { res.status(200).send('Hello, world!'); }); // Start the server -var server = app.listen(process.env.PORT || '8080', function () { - console.log('App listening on port %s', server.address().port); +const PORT = process.env.PORT || 8080; +app.listen(PORT, () => { + console.log(`App listening on port ${PORT}`); console.log('Press Ctrl+C to quit.'); }); // [END app] diff --git a/appengine/hello-world/app.yaml b/appengine/hello-world/app.yaml index f6ffeb3d5d..248738be70 100644 --- a/appengine/hello-world/app.yaml +++ b/appengine/hello-world/app.yaml @@ -13,5 +13,5 @@ # [START app_yaml] runtime: nodejs -vm: true +env: flex # [END app_yaml] diff --git a/appengine/hello-world/package.json b/appengine/hello-world/package.json index 0397a39b6f..abbba4903b 100644 --- a/appengine/hello-world/package.json +++ b/appengine/hello-world/package.json @@ -6,14 +6,12 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "engines": { - "node": "~4.2" + "node": ">=4.3.2" }, "scripts": { - "start": "node app.js", - "monitor": "nodemon app.js", - "deploy": "gcloud app deploy" + "start": "node app.js" }, "dependencies": { - "express": "^4.13.4" + "express": "^4.14.0" } } diff --git a/appengine/koa/app.js b/appengine/koa/app.js index 76c2748695..3a3340ee2a 100644 --- a/appengine/koa/app.js +++ b/appengine/koa/app.js @@ -1,21 +1,22 @@ -// Copyright 2015-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. +/** + * 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'; // [START server] -var koa = require('koa'); -var app = koa(); +const app = require('koa')(); app.use(function * () { this.body = 'Hello World! Koa.js on Google App Engine.'; diff --git a/appengine/koa/app.yaml b/appengine/koa/app.yaml index f6ffeb3d5d..248738be70 100644 --- a/appengine/koa/app.yaml +++ b/appengine/koa/app.yaml @@ -13,5 +13,5 @@ # [START app_yaml] runtime: nodejs -vm: true +env: flex # [END app_yaml] diff --git a/appengine/koa/package.json b/appengine/koa/package.json index 3d0d3f6ef1..6a6354d388 100644 --- a/appengine/koa/package.json +++ b/appengine/koa/package.json @@ -6,13 +6,12 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "engines": { - "node": "~4.2" + "node": ">=4.3.2" }, "scripts": { - "start": "node --harmony app.js", - "deploy": "gcloud app deploy" + "start": "node --harmony app.js" }, "dependencies": { - "koa": "^1.1.2" + "koa": "^1.2.4" } } diff --git a/appengine/kraken/app.yaml b/appengine/kraken/app.yaml index f6ffeb3d5d..248738be70 100644 --- a/appengine/kraken/app.yaml +++ b/appengine/kraken/app.yaml @@ -13,5 +13,5 @@ # [START app_yaml] runtime: nodejs -vm: true +env: flex # [END app_yaml] diff --git a/appengine/kraken/index.js b/appengine/kraken/index.js index f5a9bca38a..16705f5ac0 100644 --- a/appengine/kraken/index.js +++ b/appengine/kraken/index.js @@ -13,17 +13,17 @@ 'use strict'; -var express = require('express'); -var kraken = require('kraken-js'); +const express = require('express'); +const kraken = require('kraken-js'); -var options, app; +let options, app; /* * Create and configure application. Also exports application instance for use by tests. * See https://github.com/krakenjs/kraken-js#options for additional configuration options. */ options = { - onconfig: function (config, next) { + onconfig: (config, next) => { /* * Add any additional config setup or overrides here. `config` is an initialized * `confit` (https://github.com/krakenjs/confit/) configuration object. @@ -34,7 +34,7 @@ options = { app = module.exports = express(); app.use(kraken(options)); -app.on('start', function () { +app.on('start', () => { console.log('Application ready to serve requests.'); - console.log('Environment: %s', app.kraken.get('env:env')); + console.log(`Environment: ${app.kraken.get('env:env')}`); }); diff --git a/appengine/kraken/package.json b/appengine/kraken/package.json index b47e006e76..84bfcb954f 100644 --- a/appengine/kraken/package.json +++ b/appengine/kraken/package.json @@ -6,14 +6,13 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "engines": { - "node": "~4.2" + "node": ">=4.3.2" }, "scripts": { "test": "node_modules/grunt-cli/bin/grunt test", "build": "node_modules/grunt-cli/bin/grunt build", "all": "npm run build && npm run test", - "start": "node server.js", - "deploy": "gcloud app deploy" + "start": "node server.js" }, "dependencies": { "construx": "^1.0.0", diff --git a/appengine/kraken/server.js b/appengine/kraken/server.js index 9eb91db4d6..df99372d6d 100644 --- a/appengine/kraken/server.js +++ b/appengine/kraken/server.js @@ -14,17 +14,16 @@ 'use strict'; // [START server] -var app = require('./index'); -var http = require('http'); - -var server; +const app = require('./index'); +const http = require('http'); /* * Create and start HTTP server. */ -server = http.createServer(app); -server.listen(process.env.PORT || 8080); -server.on('listening', function () { - console.log('Server listening on http://localhost:%d', this.address().port); +const server = http.createServer(app); +const PORT = process.env.PORT || 8080; +server.listen(PORT); +server.on('listening', () => { + console.log(`Server listening on port ${PORT}`); }); // [END server] diff --git a/appengine/logging/README.md b/appengine/logging/README.md index 247d91cc01..72e02826b4 100644 --- a/appengine/logging/README.md +++ b/appengine/logging/README.md @@ -1,6 +1,6 @@ # Node.js logging sample for Google App Engine -This sample demonstrates logging in a Node.js app for [Google App Engine Managed VMs](https://cloud.google.com/appengine). +This sample demonstrates logging in a Node.js app for [Google App Engine Flexible Environment](https://cloud.google.com/appengine). ## Running locally diff --git a/appengine/logging/app.js b/appengine/logging/app.js index 221876949e..5c5a87b43f 100644 --- a/appengine/logging/app.js +++ b/appengine/logging/app.js @@ -1,27 +1,28 @@ -// Copyright 2015-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. +/** + * 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. + */ // [START app] 'use strict'; -var express = require('express'); -var app = express(); +const express = require('express'); +const app = express(); -var winston = require('winston'); +const winston = require('winston'); require('winston-gae'); -var logger = new winston.Logger({ +const logger = new winston.Logger({ levels: winston.config.GoogleAppEngine.levels, transports: [ new winston.transports.GoogleAppEngine({ @@ -31,13 +32,14 @@ var logger = new winston.Logger({ ] }); -app.get('/', function (req, res) { - logger.info('Request from %s', req.ip); +app.get('/', (req, res) => { + logger.info(`Request from ${req.ip}`); res.status(200).send('Logged'); }); -var server = app.listen(process.env.PORT || '8080', function () { - console.log('App listening on port %s', server.address().port); +const PORT = process.env.PORT || 8080; +app.listen(PORT, () => { + console.log(`App listening on port ${PORT}`); console.log('Press Ctrl+C to quit.'); }); // [END app] diff --git a/appengine/logging/app.yaml b/appengine/logging/app.yaml index f6ffeb3d5d..248738be70 100644 --- a/appengine/logging/app.yaml +++ b/appengine/logging/app.yaml @@ -13,5 +13,5 @@ # [START app_yaml] runtime: nodejs -vm: true +env: flex # [END app_yaml] diff --git a/appengine/logging/package.json b/appengine/logging/package.json index 7b0823cc28..4a131c0920 100644 --- a/appengine/logging/package.json +++ b/appengine/logging/package.json @@ -6,16 +6,14 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "engines": { - "node": "~4.2" + "node": ">=4.3.2" }, "scripts": { - "start": "node app.js", - "monitor": "nodemon app.js", - "deploy": "gcloud app deploy" + "start": "node app.js" }, "dependencies": { - "express": "^4.13.4", - "winston": "^2.1.1", + "express": "^4.14.0", + "winston": "^2.2.0", "winston-gae": "^0.1.0" } } diff --git a/appengine/loopback/app.yaml b/appengine/loopback/app.yaml index f6ffeb3d5d..248738be70 100644 --- a/appengine/loopback/app.yaml +++ b/appengine/loopback/app.yaml @@ -13,5 +13,5 @@ # [START app_yaml] runtime: nodejs -vm: true +env: flex # [END app_yaml] diff --git a/appengine/loopback/package.json b/appengine/loopback/package.json index 8ed12b91d9..182f0e413c 100644 --- a/appengine/loopback/package.json +++ b/appengine/loopback/package.json @@ -6,7 +6,7 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "engines": { - "node": "~4.2" + "node": ">=4.3.2" }, "scripts": { "pretest": "jshint .", diff --git a/appengine/mailgun/app.js b/appengine/mailgun/app.js index 3fee4b70fe..dcf1935c8a 100644 --- a/appengine/mailgun/app.js +++ b/appengine/mailgun/app.js @@ -1,47 +1,49 @@ -// Copyright 2015-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. +/** + * 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 express = require('express'); -var path = require('path'); -var bodyParser = require('body-parser'); +const express = require('express'); +const path = require('path'); +const bodyParser = require('body-parser'); // [START setup] -var Mailgun = require('mailgun').Mailgun; -var mg = new Mailgun(process.env.MAILGUN_API_KEY); +const Mailgun = require('mailgun').Mailgun; +const mg = new Mailgun(process.env.MAILGUN_API_KEY); // [END setup] -var app = express(); +const app = express(); // Setup view engine app.set('views', path.join(__dirname, 'views')); -app.set('view engine', 'jade'); +app.set('view engine', 'pug'); // Parse form data app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); // [START index] -app.get('/', function (req, res) { +app.get('/', (req, res) => { res.render('index'); }); // [END index] // [START hello] -app.post('/hello', function (req, res, next) { - var servername = ''; - var options = {}; +app.post('/hello', (req, res, next) => { + const servername = ''; + const options = {}; mg.sendText( // From @@ -54,12 +56,13 @@ app.post('/hello', function (req, res, next) { 'Mailgun on Google App Engine with Node.js', servername, options, - function (err) { + (err) => { if (err) { - return next(err); + next(err); + return; } // Render the index route on success - return res.render('index', { + res.render('index', { sent: true }); } @@ -68,8 +71,9 @@ app.post('/hello', function (req, res, next) { // [END hello] // [START server] -var server = app.listen(process.env.PORT || 8080, function () { - console.log('App listening on port %s', server.address().port); +const PORT = process.env.PORT || 8080; +app.listen(PORT, () => { + console.log(`App listening on port ${PORT}`); console.log('Press Ctrl+C to quit.'); }); // [END server] diff --git a/appengine/mailgun/app.yaml b/appengine/mailgun/app.yaml index 714d85432a..229d07f21d 100644 --- a/appengine/mailgun/app.yaml +++ b/appengine/mailgun/app.yaml @@ -13,7 +13,7 @@ # [START app_yaml] runtime: nodejs -vm: true +env: flex env_variables: MAILGUN_API_KEY: # [END app_yaml] diff --git a/appengine/mailgun/package.json b/appengine/mailgun/package.json index c3df759736..130a24500c 100644 --- a/appengine/mailgun/package.json +++ b/appengine/mailgun/package.json @@ -13,9 +13,9 @@ "deploy": "gcloud app deploy" }, "dependencies": { - "body-parser": "^1.14.2", - "express": "^4.13.4", - "jade": "^1.11.0", - "mailgun": "^0.5.0" + "body-parser": "^1.15.2", + "express": "^4.14.0", + "mailgun": "^0.5.0", + "pug": "^2.0.0-beta6" } } diff --git a/appengine/mailgun/views/index.jade b/appengine/mailgun/views/index.jade deleted file mode 100644 index e00cf555ff..0000000000 --- a/appengine/mailgun/views/index.jade +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2015-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. - -doctype html -html - head - title= title - body - h1 Hello World! - p Express.js + Mailgun on Google App Engine. - hr - if sent - p Email sent! - else - form(name="hello", action="/hello", method="post") - input(type="email", placeholder="Enter your email to send yourself a Hello World message", name="email", style="width: 50%; margin-right: 15px;") - input(type="submit", value="Send") diff --git a/appengine/mailgun/views/index.pug b/appengine/mailgun/views/index.pug new file mode 100644 index 0000000000..e67edadad1 --- /dev/null +++ b/appengine/mailgun/views/index.pug @@ -0,0 +1,14 @@ +doctype html +html + head + title= title + body + h1 Hello World! + p Express.js + Mailgun on Google App Engine. + hr + if sent + p Email sent! + else + form(name="hello", action="/hello", method="post") + input(type="email", placeholder="Enter your email to send yourself a Hello World message", name="email", style="width: 50%; margin-right: 15px;") + input(type="submit", value="Send") diff --git a/appengine/mailjet/app.js b/appengine/mailjet/app.js index 1bdfb45e51..deb7c29f45 100644 --- a/appengine/mailjet/app.js +++ b/appengine/mailjet/app.js @@ -1,15 +1,17 @@ -// 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. +/** + * 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'; diff --git a/appengine/mailjet/app.yaml b/appengine/mailjet/app.yaml index bbf4ae6144..5e74170900 100644 --- a/appengine/mailjet/app.yaml +++ b/appengine/mailjet/app.yaml @@ -13,7 +13,7 @@ # [START app_yaml] runtime: nodejs -vm: true +env: flex env_variables: MJ_APIKEY_PUBLIC: MJ_APIKEY_PRIVATE: diff --git a/appengine/memcached/README.md b/appengine/memcached/README.md index e5fe6c1fc1..b719581ed9 100644 --- a/appengine/memcached/README.md +++ b/appengine/memcached/README.md @@ -1,7 +1,7 @@ # Memcached sample for Google App Engine This sample demonstrates accessing Memcached from Node.js on -[Google App Engine Managed VMs](https://cloud.google.com/appengine). +[Google App Engine Flexible Environment](https://cloud.google.com/appengine). ## Running locally diff --git a/appengine/memcached/app.js b/appengine/memcached/app.js index 11b808bb89..30715dad2e 100644 --- a/appengine/memcached/app.js +++ b/appengine/memcached/app.js @@ -1,52 +1,63 @@ -// Copyright 2015-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. +/** + * 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. + */ // [START app] 'use strict'; -var express = require('express'); -var Memcached = require('memcached'); +const express = require('express'); +const memjs = require('memjs'); -var app = express(); +const app = express(); -// The environment variables are automatically set by App Engine when running -// on GAE. When running locally, you should have a local instance of the -// memcached daemon running. -var memcachedAddr = process.env.MEMCACHE_PORT_11211_TCP_ADDR || 'localhost'; -var memcachedPort = process.env.MEMCACHE_PORT_11211_TCP_PORT || '11211'; -var memcached = new Memcached(memcachedAddr + ':' + memcachedPort); +// [START client] +// Environment variables are defined in app.yaml. +let MEMCACHE_URL = process.env.MEMCACHE_URL || '127.0.0.1:11211'; -app.get('/', function (req, res, next) { - memcached.get('foo', function (err, value) { +if (process.env.USE_GAE_MEMCACHE) { + MEMCACHE_URL = `${process.env.GAE_MEMCACHE_HOST}:${process.env.GAE_MEMCACHE_PORT}`; +} + +const mc = memjs.Client.create(MEMCACHE_URL); +// [END client] + +// [START example] +app.get('/', (req, res, next) => { + mc.get('foo', (err, value) => { if (err) { - return next(err); + next(err); + return; } if (value) { - return res.status(200).send('Value: ' + value); + res.status(200).send(`Value: ${value.toString('utf-8')}`); + return; } - memcached.set('foo', Math.random(), 60, function (err) { + mc.set('foo', `${Math.random()}`, (err) => { if (err) { - return next(err); + next(err); + return; } - return res.redirect('/'); - }); + res.redirect('/'); + }, 60); }); }); +// [END example] -var server = app.listen(process.env.PORT || 8080, function () { - console.log('App listening on port %s', server.address().port); +const PORT = process.env.PORT || 8080; +app.listen(PORT, () => { + console.log(`App listening on port ${PORT}`); console.log('Press Ctrl+C to quit.'); }); // [END app] diff --git a/appengine/memcached/app.yaml b/appengine/memcached/app.yaml index ac776ed98d..9e53787477 100644 --- a/appengine/memcached/app.yaml +++ b/appengine/memcached/app.yaml @@ -1,4 +1,4 @@ -# Copyright 2015-2016, Google, Inc. +# 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 @@ -13,10 +13,17 @@ # [START app_yaml] runtime: nodejs -vm: true +env: flex -# [START config] -beta_settings: - use_memcache_proxy: true -# [END config] +# [START env_variables] +env_variables: + # If you are using the App Engine Memcache service (currently in alpha), + # uncomment this section and comment out the other Memcache variables. + # USE_GAE_MEMCACHE: 1 + MEMCACHE_URL: your-memcache-url + # If you are using a Memcached server with SASL authentiation enabled, + # fill in these values with your username and password. + MEMCACHE_USERNAME: your-memcache-username + MEMCACHE_PASSWORD: your-memcache-password +# [END env_variables] # [END app_yaml] diff --git a/appengine/memcached/package.json b/appengine/memcached/package.json index a074085d70..ed5123b167 100644 --- a/appengine/memcached/package.json +++ b/appengine/memcached/package.json @@ -1,20 +1,18 @@ { "name": "appengine-memcached", - "description": "Memcached sample for Google App Engine", + "description": "Memcached sample for Google App Engine Flexible Environment", "version": "0.0.1", "private": true, "license": "Apache Version 2.0", "author": "Google Inc.", "engines": { - "node": "~4.2" + "node": ">=4.3.2" }, "scripts": { - "start": "node app.js", - "monitor": "nodemon app.js", - "deploy": "gcloud app deploy" + "start": "node app.js" }, "dependencies": { - "express": "^4.13.3", - "memcached": "^2.2.1" + "express": "^4.14.0", + "memjs": "^0.10.0" } } diff --git a/appengine/mongodb/app.yaml b/appengine/mongodb/app.yaml index f6ffeb3d5d..248738be70 100644 --- a/appengine/mongodb/app.yaml +++ b/appengine/mongodb/app.yaml @@ -13,5 +13,5 @@ # [START app_yaml] runtime: nodejs -vm: true +env: flex # [END app_yaml] diff --git a/appengine/mongodb/package.json b/appengine/mongodb/package.json index 45aa90fd5a..90df9e5dea 100644 --- a/appengine/mongodb/package.json +++ b/appengine/mongodb/package.json @@ -6,14 +6,10 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "engines": { - "node": "~4.2" - }, - "scripts": { - "start": "node server.js", - "deploy": "gcloud app deploy" + "node": ">=4.3.2" }, "dependencies": { "nconf": "^0.8.4", - "mongodb": "^2.1.5" + "mongodb": "^2.2.10" } } diff --git a/appengine/mongodb/server.js b/appengine/mongodb/server.js index 39047e987c..ea7c9e43dd 100644 --- a/appengine/mongodb/server.js +++ b/appengine/mongodb/server.js @@ -1,21 +1,23 @@ -// Copyright 2015-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. +/** + * 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 mongodb = require('mongodb'); -var http = require('http'); -var nconf = require('nconf'); +const mongodb = require('mongodb'); +const http = require('http'); +const nconf = require('nconf'); // read in keys and secrets. You can store these in a variety of ways. // I like to use a keys.json file that is in the .gitignore file, @@ -25,44 +27,47 @@ nconf.argv().env().file('keys.json'); // Connect to a MongoDB server provisioned over at // MongoLab. See the README for more info. +const user = nconf.get('mongoUser'); +const pass = nconf.get('mongoPass'); +const host = nconf.get('mongoHost'); +const port = nconf.get('mongoPort'); + // [START client] -var uri = 'mongodb://' + - nconf.get('mongoUser') + ':' + - nconf.get('mongoPass') + '@' + - nconf.get('mongoHost') + ':' + - nconf.get('mongoPort'); +let uri = `mongodb://${user}:${pass}@${host}:${port}`; if (nconf.get('mongoDatabase')) { - uri = uri + '/' + nconf.get('mongoDatabase'); + uri = `${uri}/${nconf.get('mongoDatabase')}`; } -mongodb.MongoClient.connect(uri, function (err, db) { +console.log(uri); + +mongodb.MongoClient.connect(uri, (err, db) => { if (err) { throw err; } // Create a simple little server. - http.createServer(function (req, res) { + http.createServer((req, res) => { // Track every IP that has visited this site - var collection = db.collection('IPs'); + const collection = db.collection('IPs'); - var ip = { + const ip = { address: req.connection.remoteAddress }; - collection.insert(ip, function (err) { + collection.insert(ip, (err) => { if (err) { throw err; } // push out a range - var iplist = ''; - collection.find().toArray(function (err, data) { + let iplist = ''; + collection.find().toArray((err, data) => { if (err) { throw err; } - data.forEach(function (ip) { - iplist += ip.address + '; '; + data.forEach((ip) => { + iplist += `${ip.address}; `; }); res.writeHead(200, { @@ -72,7 +77,7 @@ mongodb.MongoClient.connect(uri, function (err, db) { res.end(iplist); }); }); - }).listen(process.env.PORT || 8080, function () { + }).listen(process.env.PORT || 8080, () => { console.log('started web process'); }); }); diff --git a/appengine/parse-server/README.md b/appengine/parse-server/README.md index 0821d4b208..d9b932792e 100644 --- a/appengine/parse-server/README.md +++ b/appengine/parse-server/README.md @@ -1,7 +1,7 @@ # Parse-server sample for Google App Engine This sample demonstrates deploying a [Parse-server](https://github.com/ParsePlatform/parse-server) -app to [Google App Engine Managed VMs](https://cloud.google.com/appengine). +app to [Google App Engine Flexible Environment](https://cloud.google.com/appengine). ## Setup @@ -11,7 +11,7 @@ app to [Google App Engine Managed VMs](https://cloud.google.com/appengine). 1. Setup a MongoDB server. Here are two possible options: 1. Create a Google Compute Engine virtual machine with [MongoDB pre-installed](https://cloud.google.com/launcher/?q=mongodb). 1. Use [MongoLab](https://mongolab.com/google/) to create a free MongoDB deployment on Google Cloud Platform. - + ## Downloading Files 1. `git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git` diff --git a/appengine/parse-server/app.yaml b/appengine/parse-server/app.yaml index 1d2041de51..95b81be533 100644 --- a/appengine/parse-server/app.yaml +++ b/appengine/parse-server/app.yaml @@ -13,5 +13,5 @@ # [START app_yaml] runtime: nodejs -vm: true +env: flex # [END app_yaml] diff --git a/appengine/parse-server/cloud/main.js b/appengine/parse-server/cloud/main.js index dac69b161c..96a393b53c 100644 --- a/appengine/parse-server/cloud/main.js +++ b/appengine/parse-server/cloud/main.js @@ -1,16 +1,17 @@ -// 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. +/** + * 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. + */ Parse.Cloud.define('hello', function(req, res) { res.success('Hello, world!'); diff --git a/appengine/parse-server/package.json b/appengine/parse-server/package.json index db471f1cd2..cf3fda77f4 100644 --- a/appengine/parse-server/package.json +++ b/appengine/parse-server/package.json @@ -6,16 +6,11 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "engines": { - "node": "~4.2" - }, - "scripts": { - "start": "node server.js", - "monitor": "nodemon server.js", - "deploy": "gcloud app deploy" + "node": ">=4.3.2" }, "dependencies": { - "express": "^4.13.4", - "parse-server": "^2.1.3", - "nconf": "0.8.4" + "express": "^4.14.0", + "parse-server": "^2.2.22", + "nconf": "^0.8.4" } } diff --git a/appengine/parse-server/server.js b/appengine/parse-server/server.js index af943705f3..b8c9387c2e 100644 --- a/appengine/parse-server/server.js +++ b/appengine/parse-server/server.js @@ -1,30 +1,31 @@ -// 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. +/** + * 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'; // [START app] -var express = require('express'); -var nconf = require('nconf'); -var ParseServer = require('parse-server').ParseServer; -var path = require('path'); +const express = require('express'); +const nconf = require('nconf'); +const ParseServer = require('parse-server').ParseServer; +const path = require('path'); nconf.argv().env().file({ file: 'config.json' }); -var app = express(); +const app = express(); -var parseServer = new ParseServer({ +const parseServer = new ParseServer({ databaseURI: nconf.get('DATABASE_URI') || 'mongodb://localhost:27017/dev', cloud: nconf.get('CLOUD_PATH') || path.join(__dirname, '/cloud/main.js'), appId: nconf.get('APP_ID'), @@ -36,13 +37,13 @@ var parseServer = new ParseServer({ // Mount the Parse API server middleware to /parse app.use(process.env.PARSE_MOUNT_PATH || '/parse', parseServer); -app.get('/', function (req, res) { +app.get('/', (req, res) => { res.status(200).send('Hello, world!'); }); -var server = app.listen(process.env.PORT || 8080, function () { - console.log('App listening on port %s', server.address().port); +const PORT = process.env.PORT || 8080; +app.listen(PORT, () => { + console.log(`App listening on port ${PORT}`); console.log('Press Ctrl+C to quit.'); }); - // [END app] diff --git a/appengine/pubsub/README.md b/appengine/pubsub/README.md index e677d3f306..0799378704 100644 --- a/appengine/pubsub/README.md +++ b/appengine/pubsub/README.md @@ -1,6 +1,6 @@ # Node.js Cloud Pub/Sub sample for Google App Engine -This demonstrates how to send and receive messages using [Google Cloud Pub/Sub](https://cloud.google.com/pubsub) on [Google App Engine Managed VMs](https://cloud.google.com/appengine) using Node.js. +This demonstrates how to send and receive messages using [Google Cloud Pub/Sub](https://cloud.google.com/pubsub) on [Google App Engine Flexible Environment](https://cloud.google.com/appengine) using Node.js. ## Setup @@ -30,7 +30,6 @@ to provide authentication to use Google Cloud APIs: Then set environment variables before starting your application: - export GCLOUD_PROJECT= export PUBSUB_VERIFICATION_TOKEN= export PUBSUB_TOPIC= npm start diff --git a/appengine/pubsub/app.js b/appengine/pubsub/app.js index 33fa14f4e1..7add8fe5ff 100644 --- a/appengine/pubsub/app.js +++ b/appengine/pubsub/app.js @@ -1,63 +1,66 @@ -// Copyright 2015-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. +/** + * 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. + */ // [START app] 'use strict'; -var express = require('express'); -var bodyParser = require('body-parser'); +const express = require('express'); +const bodyParser = require('body-parser'); // By default, the client will authenticate using the service account file // specified by the GOOGLE_APPLICATION_CREDENTIALS environment variable and use // the project specified by the GCLOUD_PROJECT environment variable. See // https://googlecloudplatform.github.io/gcloud-node/#/docs/google-cloud/latest/guides/authentication // These environment variables are set automatically on Google App Engine -var PubSub = require('@google-cloud/pubsub'); +const PubSub = require('@google-cloud/pubsub'); // Instantiate a pubsub client -var pubsub = PubSub(); +const pubsub = PubSub(); -var app = express(); -app.set('view engine', 'jade'); +const app = express(); +app.set('view engine', 'pug'); -var formBodyParser = bodyParser.urlencoded({extended: false}); -var jsonBodyParser = bodyParser.json(); +const formBodyParser = bodyParser.urlencoded({ extended: false }); +const jsonBodyParser = bodyParser.json(); // List of all messages received by this instance -var messages = []; +const messages = []; // The following environment variables are set by app.yaml when running on GAE, // but will need to be manually set when running locally. -var PUBSUB_VERIFICATION_TOKEN = process.env.PUBSUB_VERIFICATION_TOKEN; +const PUBSUB_VERIFICATION_TOKEN = process.env.PUBSUB_VERIFICATION_TOKEN; -var topic = pubsub.topic(process.env.PUBSUB_TOPIC); +const topic = pubsub.topic(process.env.PUBSUB_TOPIC); // [START index] -app.get('/', function (req, res) { +app.get('/', (req, res) => { res.render('index', { messages: messages }); }); -app.post('/', formBodyParser, function (req, res, next) { +app.post('/', formBodyParser, (req, res, next) => { if (!req.body.payload) { - return res.status(400).send('Missing payload'); + res.status(400).send('Missing payload'); + return; } topic.publish({ data: req.body.payload - }, function (err) { + }, (err) => { if (err) { - return next(err); + next(err); + return; } res.status(200).send('Message sent'); }); @@ -65,13 +68,14 @@ app.post('/', formBodyParser, function (req, res, next) { // [END index] // [START push] -app.post('/pubsub/push', jsonBodyParser, function (req, res) { +app.post('/pubsub/push', jsonBodyParser, (req, res) => { if (req.query.token !== PUBSUB_VERIFICATION_TOKEN) { - return res.status(400).send(); + res.status(400).send(); + return; } // The message is a unicode string encoded in base64. - var message = new Buffer(req.body.message.data, 'base64').toString('utf-8'); + const message = new Buffer(req.body.message.data, 'base64').toString('utf-8'); messages.push(message); @@ -80,8 +84,9 @@ app.post('/pubsub/push', jsonBodyParser, function (req, res) { // [END push] // Start the server -var server = app.listen(process.env.PORT || '8080', function () { - console.log('App listening on port %s', server.address().port); +const PORT = process.env.PORT || 8080; +app.listen(PORT, () => { + console.log(`App listening on port ${PORT}`); console.log('Press Ctrl+C to quit.'); }); // [END app] diff --git a/appengine/pubsub/app.yaml b/appengine/pubsub/app.yaml index aab4506465..5348edbe91 100644 --- a/appengine/pubsub/app.yaml +++ b/appengine/pubsub/app.yaml @@ -13,11 +13,10 @@ # [START app_yaml] runtime: nodejs -vm: true +env: flex # [START env] env_variables: - GCLOUD_PROJECT: PUBSUB_TOPIC: # This token is used to verify that requests originate from your # application. It can be any sufficiently random string. diff --git a/appengine/pubsub/package.json b/appengine/pubsub/package.json index 7fa773d0f9..5e55cd7e2e 100644 --- a/appengine/pubsub/package.json +++ b/appengine/pubsub/package.json @@ -6,15 +6,15 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "engines": { - "node": "~4.2" + "node": ">=4.3.2" }, "scripts": { "start": "node app.js" }, "dependencies": { - "@google-cloud/pubsub": "^0.1.1", - "body-parser": "^1.14.2", - "express": "^4.13.4", - "jade": "^1.11.0" + "@google-cloud/pubsub": "^0.3.0", + "body-parser": "^1.15.2", + "express": "^4.14.0", + "pug": "^2.0.0-beta6" } } diff --git a/appengine/pubsub/sample_message.json b/appengine/pubsub/sample_message.json index 8fe62d23fb..c39f4ba371 100644 --- a/appengine/pubsub/sample_message.json +++ b/appengine/pubsub/sample_message.json @@ -1,5 +1,5 @@ { - "message": { - "data": "SGVsbG8sIFdvcmxkIQ==" - } + "message": { + "data": "SGVsbG8sIFdvcmxkIQ==" + } } diff --git a/appengine/pubsub/views/index.jade b/appengine/pubsub/views/index.jade deleted file mode 100644 index ec42f487ef..0000000000 --- a/appengine/pubsub/views/index.jade +++ /dev/null @@ -1,31 +0,0 @@ -//- Copyright 2015, 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. - -doctype html -html(lang='en') - head - title PubSub - meta(charset='utf-8') - body - p Messages received by this instance: - ul - each val in messages - li= val - p - small. - Note: because your application is likely running multiple instances, - each instance will have a different list of messages. - - //- [START form] - form(method='post') - textarea(name='payload', placeholder='Enter message here.') - button(type='submit') Send - //- [END form] diff --git a/appengine/pubsub/views/index.pug b/appengine/pubsub/views/index.pug new file mode 100644 index 0000000000..28860613ba --- /dev/null +++ b/appengine/pubsub/views/index.pug @@ -0,0 +1,20 @@ +doctype html +html(lang='en') + head + title PubSub + meta(charset='utf-8') + body + p Messages received by this instance: + ul + each val in messages + li= val + p + small. + Note: because your application is likely running multiple instances, + each instance will have a different list of messages. + + //- [START form] + form(method='post') + textarea(name='payload', placeholder='Enter message here.') + button(type='submit') Send + //- [END form] diff --git a/appengine/redis/app.yaml b/appengine/redis/app.yaml index f6ffeb3d5d..248738be70 100644 --- a/appengine/redis/app.yaml +++ b/appengine/redis/app.yaml @@ -13,5 +13,5 @@ # [START app_yaml] runtime: nodejs -vm: true +env: flex # [END app_yaml] diff --git a/appengine/redis/package.json b/appengine/redis/package.json index e9085ac415..f9efcf1c0a 100644 --- a/appengine/redis/package.json +++ b/appengine/redis/package.json @@ -6,14 +6,10 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "engines": { - "node": "~4.2" - }, - "scripts": { - "start": "node server.js", - "deploy": "gcloud app deploy" + "node": ">=4.3.2" }, "dependencies": { "nconf": "^0.8.4", - "redis": "^2.4.2" + "redis": "^2.6.2" } } diff --git a/appengine/redis/server.js b/appengine/redis/server.js index 7a070868c5..f5af027aea 100644 --- a/appengine/redis/server.js +++ b/appengine/redis/server.js @@ -1,21 +1,23 @@ -// Copyright 2015-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. +/** + * 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 redis = require('redis'); -var http = require('http'); -var nconf = require('nconf'); +const redis = require('redis'); +const http = require('http'); +const nconf = require('nconf'); // read in keys and secrets. You can store these in a variety of ways. // I like to use a keys.json file that is in the .gitignore file, @@ -25,42 +27,39 @@ nconf.argv().env().file('keys.json'); // [START client] // Connect to a redis server provisioned over at // Redis Labs. See the README for more info. -var client = redis.createClient( +const client = redis.createClient( nconf.get('redisPort') || '6379', nconf.get('redisHost') || '127.0.0.1', { 'auth_pass': nconf.get('redisKey'), 'return_buffers': true } -).on('error', function (err) { - console.error('ERR:REDIS: ' + err); -}); +).on('error', (err) => console.error('ERR:REDIS:', err)); // [END client] // Create a simple little server. -http.createServer(function (req, res) { - client.on('error', function (err) { - console.log('Error ' + err); - }); +http.createServer((req, res) => { + client.on('error', (err) => console.log('Error', err)); // Track every IP that has visited this site - var listName = 'IPs'; + const listName = 'IPs'; client.lpush(listName, req.connection.remoteAddress); client.ltrim(listName, 0, 25); // push out a range - var iplist = ''; - client.lrange(listName, 0, -1, function (err, data) { + let iplist = ''; + client.lrange(listName, 0, -1, (err, data) => { if (err) { console.log(err); + res.status(500).send(err.message); + return; } - console.log('listing data...\n'); - data.forEach(function (ip) { - console.log('IP: ' + ip + '\n'); - iplist += ip + '; '; + + data.forEach((ip) => { + iplist += `${ip}; `; }); - res.writeHead(200, {'Content-Type': 'text/plain'}); + res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end(iplist); }); }).listen(process.env.PORT || 8080); diff --git a/appengine/restify/app.yaml b/appengine/restify/app.yaml index f6ffeb3d5d..248738be70 100644 --- a/appengine/restify/app.yaml +++ b/appengine/restify/app.yaml @@ -13,5 +13,5 @@ # [START app_yaml] runtime: nodejs -vm: true +env: flex # [END app_yaml] diff --git a/appengine/restify/package.json b/appengine/restify/package.json index fcd25621a1..d30d677871 100644 --- a/appengine/restify/package.json +++ b/appengine/restify/package.json @@ -6,11 +6,7 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "engines": { - "node": "~4.2" - }, - "scripts": { - "start": "node server.js", - "deploy": "gcloud app deploy" + "node": ">=4.3.2" }, "dependencies": { "restify": "^4.0.0" diff --git a/appengine/restify/server.js b/appengine/restify/server.js index 8000ee08e8..8c71ab7bff 100644 --- a/appengine/restify/server.js +++ b/appengine/restify/server.js @@ -1,23 +1,25 @@ -// Copyright 2015-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. +/** + * 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'; // [START server] -var PORT = process.env.PORT || 8080; -var restify = require('restify'); +const PORT = process.env.PORT || 8080; +const restify = require('restify'); -var server = restify.createServer({ +const server = restify.createServer({ name: 'appengine-restify', version: '1.0.0' }); @@ -27,19 +29,20 @@ server.use(restify.acceptParser(server.acceptable)); server.use(restify.queryParser()); server.use(restify.bodyParser()); -server.get('/echo/:name', function (req, res, next) { +server.get('/echo/:name', (req, res, next) => { res.send(req.params); - return next(); + next(); + return; }); // [START index] -server.get('/', function (req, res) { +server.get('/', (req, res) => { res.send('Hello World! Restify.js on Google App Engine.'); }); // [END index] // [START server_start] -server.listen(PORT, function () { - console.log('App listening on port %s', PORT); +server.listen(PORT, () => { + console.log(`App listening on port ${PORT}`); }); // [END server_start] diff --git a/appengine/sails/app.js b/appengine/sails/app.js index 78de525fdc..31ad645b9d 100644 --- a/appengine/sails/app.js +++ b/appengine/sails/app.js @@ -1,15 +1,17 @@ -// Copyright 2015-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. +/** + * 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'; diff --git a/appengine/sails/app.yaml b/appengine/sails/app.yaml index f6ffeb3d5d..248738be70 100644 --- a/appengine/sails/app.yaml +++ b/appengine/sails/app.yaml @@ -13,5 +13,5 @@ # [START app_yaml] runtime: nodejs -vm: true +env: flex # [END app_yaml] diff --git a/appengine/sails/package.json b/appengine/sails/package.json index f9adfedf20..a70794bfa0 100644 --- a/appengine/sails/package.json +++ b/appengine/sails/package.json @@ -6,12 +6,11 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "engines": { - "node": "~4.2" + "node": ">=4.3.2" }, "scripts": { "debug": "node debug app.js", - "start": "node app.js", - "deploy": "gcloud app deploy" + "start": "node app.js" }, "dependencies": { "ejs": "^2.3.4", diff --git a/appengine/sendgrid/README.md b/appengine/sendgrid/README.md index 486de6b3e5..0f2e3b1f75 100644 --- a/appengine/sendgrid/README.md +++ b/appengine/sendgrid/README.md @@ -1,7 +1,7 @@ # Node.js SendGrid email sample for Google App Engine This sample demonstrates how to use [SendGrid](https://www.sendgrid.com) on -[Google App Engine Managed VMs](https://cloud.google.com/appengine). +[Google App Engine Flexible Environment](https://cloud.google.com/appengine). For more information about SendGrid, see their [documentation](https://sendgrid.com/docs/User_Guide/index.html). diff --git a/appengine/sendgrid/app.js b/appengine/sendgrid/app.js index b6010680c3..b074874d88 100644 --- a/appengine/sendgrid/app.js +++ b/appengine/sendgrid/app.js @@ -1,49 +1,51 @@ -// Copyright 2015-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. +/** + * 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. + */ // [START app] 'use strict'; -var express = require('express'); -var path = require('path'); -var bodyParser = require('body-parser'); +const express = require('express'); +const path = require('path'); +const bodyParser = require('body-parser'); // [START setup] // The following environment variables are set by app.yaml when running on GAE, // but will need to be manually set when running locally. -var SENDGRID_API_KEY = process.env.SENDGRID_API_KEY; -var SENDGRID_SENDER = process.env.SENDGRID_SENDER; -var Sendgrid = require('sendgrid')(SENDGRID_API_KEY); +const SENDGRID_API_KEY = process.env.SENDGRID_API_KEY; +const SENDGRID_SENDER = process.env.SENDGRID_SENDER; +const Sendgrid = require('sendgrid')(SENDGRID_API_KEY); // [END setup] -var app = express(); +const app = express(); // Setup view engine app.set('views', path.join(__dirname, 'views')); -app.set('view engine', 'jade'); +app.set('view engine', 'pug'); // Parse form data app.use(bodyParser.urlencoded({ extended: false })); // [START index] -app.get('/', function (req, res) { +app.get('/', (req, res) => { res.render('index'); }); // [END index] // [START hello] -app.post('/hello', function (req, res, next) { - var sgReq = Sendgrid.emptyRequest({ +app.post('/hello', (req, res, next) => { + const sgReq = Sendgrid.emptyRequest({ method: 'POST', path: '/v3/mail/send', body: { @@ -59,22 +61,25 @@ app.post('/hello', function (req, res, next) { } }); - Sendgrid.API(sgReq, function (err) { + Sendgrid.API(sgReq, (err) => { if (err) { - return next(err); + next(err); + return; } // Render the index route on success - return res.render('index', { + res.render('index', { sent: true }); + return; }); }); // [END hello] if (module === require.main) { // [START server] - var server = app.listen(process.env.PORT || 8080, function () { - console.log('App listening on port %s', server.address().port); + const PORT = process.env.PORT || 8080; + app.listen(PORT, () => { + console.log(`App listening on port ${PORT}`); console.log('Press Ctrl+C to quit.'); }); // [END server] diff --git a/appengine/sendgrid/app.yaml b/appengine/sendgrid/app.yaml index 74aa9debac..8582bd77d5 100644 --- a/appengine/sendgrid/app.yaml +++ b/appengine/sendgrid/app.yaml @@ -13,7 +13,7 @@ # [START app_yaml] runtime: nodejs -vm: true +env: flex # [START env_variables] env_variables: diff --git a/appengine/sendgrid/package.json b/appengine/sendgrid/package.json index 712643ad06..c5530d6151 100644 --- a/appengine/sendgrid/package.json +++ b/appengine/sendgrid/package.json @@ -6,16 +6,15 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "engines": { - "node": "~4.2" + "node": ">=4.3.2" }, "scripts": { - "start": "node app.js", - "deploy": "gcloud app deploy" + "start": "node app.js" }, "dependencies": { "body-parser": "^1.14.2", - "express": "^4.13.4", - "jade": "^1.11.0", + "express": "^4.14.0", + "pug": "^2.0.0-beta6", "sendgrid": "^4.0.1" } } diff --git a/appengine/sendgrid/views/index.jade b/appengine/sendgrid/views/index.jade deleted file mode 100644 index 171f74f8a1..0000000000 --- a/appengine/sendgrid/views/index.jade +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2015-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. - -doctype html -html - head - title= title - body - h1 Hello World! - p Express.js + Sendgrid on Google App Engine. - hr - if sent - p Email sent! - else - form(name="hello", action="/hello", method="post") - input(type="email", placeholder="Enter your email to send yourself a Hello World message", name="email", style="width: 50%; margin-right: 15px;") - input(type="submit", value="Send") diff --git a/appengine/sendgrid/views/index.pug b/appengine/sendgrid/views/index.pug new file mode 100644 index 0000000000..2f20c4eb52 --- /dev/null +++ b/appengine/sendgrid/views/index.pug @@ -0,0 +1,14 @@ +doctype html +html + head + title= title + body + h1 Hello World! + p Express.js + Sendgrid on Google App Engine. + hr + if sent + p Email sent! + else + form(name="hello", action="/hello", method="post") + input(type="email", placeholder="Enter your email to send yourself a Hello World message", name="email", style="width: 50%; margin-right: 15px;") + input(type="submit", value="Send") diff --git a/appengine/static-files/README.md b/appengine/static-files/README.md index bd60667d22..05b23425b5 100644 --- a/appengine/static-files/README.md +++ b/appengine/static-files/README.md @@ -1,6 +1,6 @@ # Serving static files in Node.js sample for Google App Engine -This sample demonstrates serving static files in a Node.js app for [Google App Engine Managed VMs](https://cloud.google.com/appengine). +This sample demonstrates serving static files in a Node.js app for [Google App Engine Flexible Environment](https://cloud.google.com/appengine). ## Running locally diff --git a/appengine/static-files/app.js b/appengine/static-files/app.js index 806b4849a9..d839b35563 100644 --- a/appengine/static-files/app.js +++ b/appengine/static-files/app.js @@ -1,35 +1,37 @@ -// Copyright 2015-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. +/** + * 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. + */ // [START app] 'use strict'; -var express = require('express'); -var app = express(); +const express = require('express'); +const app = express(); -app.set('view engine', 'jade'); +app.set('view engine', 'pug'); // Use the built-in express middleware for serving static files from './public' app.use('/static', express.static('public')); -app.get('/', function (req, res) { +app.get('/', (req, res) => { res.render('index'); }); // Start the server -var server = app.listen(process.env.PORT || '8080', function () { - console.log('App listening on port %s', server.address().port); +const PORT = process.env.PORT || 8080; +app.listen(PORT, () => { + console.log(`App listening on port ${PORT}`); console.log('Press Ctrl+C to quit.'); }); // [END app] diff --git a/appengine/static-files/app.yaml b/appengine/static-files/app.yaml index f6ffeb3d5d..248738be70 100644 --- a/appengine/static-files/app.yaml +++ b/appengine/static-files/app.yaml @@ -13,5 +13,5 @@ # [START app_yaml] runtime: nodejs -vm: true +env: flex # [END app_yaml] diff --git a/appengine/static-files/package.json b/appengine/static-files/package.json index 6bef65f8c8..c075e80798 100644 --- a/appengine/static-files/package.json +++ b/appengine/static-files/package.json @@ -6,15 +6,13 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "engines": { - "node": "~4.2" + "node": ">=4.3.2" }, "scripts": { - "start": "node app.js", - "monitor": "nodemon app.js", - "deploy": "gcloud app deploy" + "start": "node app.js" }, "dependencies": { - "express": "^4.13.4", - "jade": "^1.11.0" + "express": "^4.14.0", + "pug": "^2.0.0-beta6" } } diff --git a/appengine/static-files/views/index.jade b/appengine/static-files/views/index.jade deleted file mode 100644 index 5d27e8e415..0000000000 --- a/appengine/static-files/views/index.jade +++ /dev/null @@ -1,19 +0,0 @@ -//- Copyright 2015, 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. - -doctype html -html(lang="en") - head - title Static Files - meta(charset='utf-8') - link(rel="stylesheet", href="/static/main.css") - body - p This is a static file serving example. diff --git a/appengine/static-files/views/index.pug b/appengine/static-files/views/index.pug new file mode 100644 index 0000000000..fd6e6f4464 --- /dev/null +++ b/appengine/static-files/views/index.pug @@ -0,0 +1,8 @@ +doctype html +html(lang="en") + head + title Static Files + meta(charset='utf-8') + link(rel="stylesheet", href="/static/main.css") + body + p This is a static file serving example. diff --git a/appengine/storage/README.md b/appengine/storage/README.md index 7cb0f58bd0..ebc95e3e3d 100644 --- a/appengine/storage/README.md +++ b/appengine/storage/README.md @@ -1,7 +1,7 @@ # Node.js Google Cloud Storage sample for Google App Engine This sample demonstrates how to use [Google Cloud Storage](https://cloud.google.com/storage/) -on [Google App Engine Managed VMs](https://cloud.google.com/appengine). +on [Google App Engine Flexible Environment](https://cloud.google.com/appengine). ## Setup diff --git a/appengine/storage/app.js b/appengine/storage/app.js index 28598f6866..f6e6ccd8cb 100644 --- a/appengine/storage/app.js +++ b/appengine/storage/app.js @@ -1,75 +1,76 @@ -// Copyright 2015-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. +/** + * 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. + */ // [START app] 'use strict'; -var format = require('util').format; -var express = require('express'); +const format = require('util').format; +const express = require('express'); // By default, the client will authenticate using the service account file // specified by the GOOGLE_APPLICATION_CREDENTIALS environment variable and use // the project specified by the GCLOUD_PROJECT environment variable. See // https://googlecloudplatform.github.io/gcloud-node/#/docs/google-cloud/latest/guides/authentication // These environment variables are set automatically on Google App Engine -var Storage = require('@google-cloud/storage'); +const Storage = require('@google-cloud/storage'); // Instantiate a storage client -var storage = Storage(); +const storage = Storage(); -var app = express(); -app.set('view engine', 'jade'); +const app = express(); +app.set('view engine', 'pug'); // [START config] // Multer is required to process file uploads and make them available via // req.files. -var multer = require('multer')({ +const multer = require('multer')({ inMemory: true, fileSize: 5 * 1024 * 1024 // no larger than 5mb, you can change as needed. }); // A bucket is a container for objects (files). -var bucket = storage.bucket(process.env.GCLOUD_STORAGE_BUCKET); +const bucket = storage.bucket(process.env.GCLOUD_STORAGE_BUCKET); // [END config] // [START form] // Display a form for uploading files. -app.get('/', function (req, res) { - res.render('form.jade'); +app.get('/', (req, res) => { + res.render('form.pug'); }); // [END form] // [START process] // Process the file upload and upload to Google Cloud Storage. -app.post('/upload', multer.single('file'), function (req, res, next) { +app.post('/upload', multer.single('file'), (req, res, next) => { if (!req.file) { - return res.status(400).send('No file uploaded.'); + res.status(400).send('No file uploaded.'); + return; } // Create a new blob in the bucket and upload the file data. - var blob = bucket.file(req.file.originalname); - var blobStream = blob.createWriteStream(); + const blob = bucket.file(req.file.originalname); + const blobStream = blob.createWriteStream(); - blobStream.on('error', function (err) { - return next(err); + blobStream.on('error', (err) => { + next(err); + return; }); - blobStream.on('finish', function () { + blobStream.on('finish', () => { // The public URL can be used to directly access the file via HTTP. - var publicUrl = format( - 'https://storage.googleapis.com/%s/%s', - bucket.name, blob.name); + const publicUrl = format(`https://storage.googleapis.com/${bucket.name}/${blob.name}`); res.status(200).send(publicUrl); }); @@ -77,8 +78,9 @@ app.post('/upload', multer.single('file'), function (req, res, next) { }); // [END process] -var server = app.listen(process.env.PORT || '8080', function () { - console.log('App listening on port %s', server.address().port); +const PORT = process.env.PORT || 8080; +app.listen(PORT, () => { + console.log(`App listening on port ${PORT}`); console.log('Press Ctrl+C to quit.'); }); // [END app] diff --git a/appengine/storage/app.yaml b/appengine/storage/app.yaml index 50debbe884..bed8c3128a 100644 --- a/appengine/storage/app.yaml +++ b/appengine/storage/app.yaml @@ -13,11 +13,10 @@ # [START app_yaml] runtime: nodejs -vm: true +env: flex # [START env] env_variables: - GCLOUD_PROJECT: GCLOUD_STORAGE_BUCKET: # [END env] # [END app_yaml] diff --git a/appengine/storage/package.json b/appengine/storage/package.json index c51a803e79..627c256d34 100644 --- a/appengine/storage/package.json +++ b/appengine/storage/package.json @@ -4,11 +4,14 @@ "scripts": { "start": "node app.js" }, + "engines": { + "node": ">=4.3.2" + }, "dependencies": { - "@google-cloud/storage": "^0.1.1", - "body-parser": "^1.14.2", - "express": "^4.13.4", - "jade": "^1.11.0", - "multer": "^1.2.0" + "@google-cloud/storage": "^0.3.0", + "body-parser": "^1.15.2", + "express": "^4.14.0", + "multer": "^1.2.0", + "pug": "^2.0.0-beta6" } } diff --git a/appengine/storage/views/form.jade b/appengine/storage/views/form.jade deleted file mode 100644 index 55ac0359b3..0000000000 --- a/appengine/storage/views/form.jade +++ /dev/null @@ -1,21 +0,0 @@ -//- Copyright 2015, 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. - -doctype html -html(lang="en") - head - title Static Files - meta(charset='utf-8') - link(rel="stylesheet", href="/static/main.css") - body - form(method="POST", action="/upload", enctype="multipart/form-data") - input(type="file", name="file") - input(type="submit") diff --git a/appengine/storage/views/form.pug b/appengine/storage/views/form.pug new file mode 100644 index 0000000000..1089129a82 --- /dev/null +++ b/appengine/storage/views/form.pug @@ -0,0 +1,10 @@ +doctype html +html(lang="en") + head + title Static Files + meta(charset='utf-8') + link(rel="stylesheet", href="/static/main.css") + body + form(method="POST", action="/upload", enctype="multipart/form-data") + input(type="file", name="file") + input(type="submit") diff --git a/appengine/twilio/README.md b/appengine/twilio/README.md index 493b99a877..69e1dbf9fa 100644 --- a/appengine/twilio/README.md +++ b/appengine/twilio/README.md @@ -1,7 +1,7 @@ # Node.js Twilio voice and SMS sample for Google App Engine This sample demonstrates how to use [Twilio](https://www.twilio.com) on -[Google App Engine Managed VMs](https://cloud.google.com/appengine). +[Google App Engine Flexible Environment](https://cloud.google.com/appengine). For more information about Twilio, see the [Twilio Node library](https://www.twilio.com/docs/node/install). diff --git a/appengine/twilio/app.js b/appengine/twilio/app.js index 36772c93be..0690290fd8 100644 --- a/appengine/twilio/app.js +++ b/appengine/twilio/app.js @@ -1,46 +1,47 @@ -// Copyright 2015-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. +/** + * 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. + */ // [START app] 'use strict'; -var format = require('util').format; -var express = require('express'); -var bodyParser = require('body-parser').urlencoded({ +const format = require('util').format; +const express = require('express'); +const bodyParser = require('body-parser').urlencoded({ extended: false }); -var app = express(); +const app = express(); // [START config] -var TWILIO_NUMBER = process.env.TWILIO_NUMBER; +const TWILIO_NUMBER = process.env.TWILIO_NUMBER; if (!TWILIO_NUMBER) { - console.log( - 'Please configure environment variables as described in README.md'); + console.log('Please configure environment variables as described in README.md'); process.exit(1); } -var twilio = require('twilio')( +const twilio = require('twilio')( process.env.TWILIO_ACCOUNT_SID, - process.env.TWILIO_AUTH_TOKEN); + process.env.TWILIO_AUTH_TOKEN +); -var TwimlResponse = require('twilio').TwimlResponse; +const TwimlResponse = require('twilio').TwimlResponse; // [END config] // [START receive_call] -app.post('/call/receive', function (req, res) { - var resp = new TwimlResponse(); +app.post('/call/receive', (req, res) => { + const resp = new TwimlResponse(); resp.say('Hello from Google App Engine.'); res.status(200) @@ -50,20 +51,21 @@ app.post('/call/receive', function (req, res) { // [END receive_call] // [START send_sms] -app.get('/sms/send', function (req, res, next) { - var to = req.query.to; +app.get('/sms/send', (req, res, next) => { + const to = req.query.to; if (!to) { - return res.status(400).send( - 'Please provide an number in the "to" query string parameter.'); + res.status(400).send('Please provide an number in the "to" query string parameter.'); + return; } twilio.sendMessage({ to: to, from: TWILIO_NUMBER, body: 'Hello from Google App Engine' - }, function (err) { + }, (err) => { if (err) { - return next(err); + next(err); + return; } res.status(200).send('Message sent.'); }); @@ -71,11 +73,11 @@ app.get('/sms/send', function (req, res, next) { // [END send_sms] // [START receive_sms] -app.post('/sms/receive', bodyParser, function (req, res) { - var sender = req.body.From; - var body = req.body.Body; +app.post('/sms/receive', bodyParser, (req, res) => { + const sender = req.body.From; + const body = req.body.Body; - var resp = new TwimlResponse(); + const resp = new TwimlResponse(); resp.message(format('Hello, %s, you said: %s', sender, body)); res.status(200) @@ -85,8 +87,9 @@ app.post('/sms/receive', bodyParser, function (req, res) { // [END receive_sms] // Start the server -var server = app.listen(process.env.PORT || '8080', function () { - console.log('App listening on port %s', server.address().port); +const PORT = process.env.PORT; +app.listen(PORT, () => { + console.log(`App listening on port ${PORT}`); console.log('Press Ctrl+C to quit.'); }); // [END app] diff --git a/appengine/twilio/app.yaml b/appengine/twilio/app.yaml index cb6e87e57c..4de44bd625 100644 --- a/appengine/twilio/app.yaml +++ b/appengine/twilio/app.yaml @@ -13,7 +13,7 @@ # [START app_yaml] runtime: nodejs -vm: true +env: flex # [START env_variables] env_variables: diff --git a/appengine/twilio/package.json b/appengine/twilio/package.json index 7b8166f7cc..8d2db34852 100644 --- a/appengine/twilio/package.json +++ b/appengine/twilio/package.json @@ -1,21 +1,19 @@ { "name": "appengine-twilio", - "description": "Samples for Google App Engine Managed VMs", + "description": "Samples for Google App Engine Flexible Environment", "version": "0.0.1", "private": true, "license": "Apache Version 2.0", "author": "Google Inc.", "engines": { - "node": "~4.2" + "node": ">=4.3.2" }, "scripts": { - "start": "node app.js", - "monitor": "nodemon app.js", - "deploy": "gcloud app deploy" + "start": "node app.js" }, "dependencies": { - "body-parser": "^1.14.2", - "express": "^4.13.4", + "body-parser": "^1.15.2", + "express": "^4.14.0", "twilio": "^2.9.0" } } diff --git a/appengine/webpack/app.yaml b/appengine/webpack/app.yaml index f6ffeb3d5d..248738be70 100644 --- a/appengine/webpack/app.yaml +++ b/appengine/webpack/app.yaml @@ -13,5 +13,5 @@ # [START app_yaml] runtime: nodejs -vm: true +env: flex # [END app_yaml] diff --git a/appengine/webpack/package.json b/appengine/webpack/package.json index 16d9b0bc57..d5737d9e2e 100644 --- a/appengine/webpack/package.json +++ b/appengine/webpack/package.json @@ -6,17 +6,15 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "engines": { - "node": "~4.2" + "node": ">=4.3.2" }, "scripts": { "bundle": "webpack --config webpack.config.js", - "prestart": "npm run bundle", - "start": "node server.js", - "deploy": "gcloud app deploy" + "prestart": "npm run bundle" }, "dependencies": { - "express": "^4.13.4", - "jade": "^1.11.0", + "express": "^4.14.0", + "pug": "^2.0.0-beta6", "webpack": "^1.12.13" } } diff --git a/appengine/webpack/public/app.js b/appengine/webpack/public/app.js index c56a63244c..ce9b3e2579 100644 --- a/appengine/webpack/public/app.js +++ b/appengine/webpack/public/app.js @@ -1,15 +1,17 @@ -// Copyright 2015-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. +/** + * 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. + */ /* global document:true */ 'use strict'; diff --git a/appengine/webpack/public/foo.js b/appengine/webpack/public/foo.js index f2dd681153..c5f330013e 100644 --- a/appengine/webpack/public/foo.js +++ b/appengine/webpack/public/foo.js @@ -1,15 +1,17 @@ -// Copyright 2015-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. +/** + * 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'; diff --git a/appengine/webpack/server.js b/appengine/webpack/server.js index 28f917304d..ab5159e01b 100644 --- a/appengine/webpack/server.js +++ b/appengine/webpack/server.js @@ -1,33 +1,36 @@ -// Copyright 2015-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. +/** + * 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 express = require('express'); -var path = require('path'); +const express = require('express'); +const path = require('path'); -var app = express(); +const app = express(); // Setup view engine -app.set('view engine', 'jade'); +app.set('view engine', 'pug'); app.use(express.static(path.resolve(path.join(__dirname, '/dist')))); -app.get('/', function (req, res) { +app.get('/', (req, res) => { res.render('index'); }); -var server = app.listen(process.env.PORT || 8080, function () { - console.log('App listening on port %s', server.address().port); +const PORT = process.env.PORT || 8080; +app.listen(PORT, () => { + console.log(`App listening on port ${PORT}`); console.log('Press Ctrl+C to quit.'); }); diff --git a/appengine/webpack/views/index.jade b/appengine/webpack/views/index.jade deleted file mode 100644 index 5dcc1934e2..0000000000 --- a/appengine/webpack/views/index.jade +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2015-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. - -doctype html -html - head - title= title - body - h1 Hello World! - p Express.js + Webpack on Google App Engine. - hr - p Loaded module via Webpack. - script(type='text/javascript', src='app.js') diff --git a/appengine/webpack/views/index.pug b/appengine/webpack/views/index.pug new file mode 100644 index 0000000000..d851d80ae6 --- /dev/null +++ b/appengine/webpack/views/index.pug @@ -0,0 +1,10 @@ +doctype html +html + head + title= title + body + h1 Hello World! + p Express.js + Webpack on Google App Engine. + hr + p Loaded module via Webpack. + script(type='text/javascript', src='app.js') diff --git a/appengine/websockets/README.md b/appengine/websockets/README.md index 9d537714ad..d2e42cb9aa 100644 --- a/appengine/websockets/README.md +++ b/appengine/websockets/README.md @@ -1,9 +1,9 @@ # Node.js websockets sample for Google App Engine This sample demonstrates how to use websockets on -[Google App Engine Managed VMs](https://cloud.google.com/appengine) with Node.js. +[Google App Engine Flexible Environment](https://cloud.google.com/appengine) with Node.js. -__Note:__ Secure WebSockets are currently not supported by Managed VMs. +__Note:__ Secure WebSockets are currently not supported by App Engine Flexible Environment. WebSockets will only work if you load your page over HTTP (not HTTPS). To use Secure WebSockets now, you can launch a VM on Google Compute Engine using diff --git a/appengine/websockets/app.js b/appengine/websockets/app.js index 377b4beb5d..72f931bd53 100644 --- a/appengine/websockets/app.js +++ b/appengine/websockets/app.js @@ -1,40 +1,41 @@ -// Copyright 2015-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. +/** + * 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. + */ // [START app] 'use strict'; -var http = require('http'); -var express = require('express'); -var request = require('request'); +const http = require('http'); +const express = require('express'); +const request = require('request'); -var app = express(); -app.set('view engine', 'jade'); +const app = express(); +app.set('view engine', 'pug'); // Use express-ws to enable web sockets. require('express-ws')(app); // A simple echo service. -app.ws('/echo', function (ws) { - ws.on('message', function (msg) { +app.ws('/echo', (ws) => { + ws.on('message', (msg) => { ws.send(msg); }); }); -app.get('/', function (req, res) { - getExternalIp(function (externalIp) { - res.render('index.jade', {externalIp: externalIp}); +app.get('/', (req, res) => { + getExternalIp((externalIp) => { + res.render('index.pug', {externalIp: externalIp}); }); }); @@ -42,37 +43,39 @@ app.get('/', function (req, res) { // In order to use websockets on App Engine, you need to connect directly to // application instance using the instance's public external IP. This IP can // be obtained from the metadata server. -var METADATA_NETWORK_INTERFACE_URL = 'http://metadata/computeMetadata/v1/' + +const METADATA_NETWORK_INTERFACE_URL = 'http://metadata/computeMetadata/v1/' + '/instance/network-interfaces/0/access-configs/0/external-ip'; function getExternalIp (cb) { - var options = { + const options = { url: METADATA_NETWORK_INTERFACE_URL, headers: { 'Metadata-Flavor': 'Google' } }; - request(options, function (err, resp, body) { + request(options, (err, resp, body) => { if (err || resp.statusCode !== 200) { console.log('Error while talking to metadata server, assuming localhost'); - return cb('localhost'); + cb('localhost'); + return; } - return cb(body); + cb(body); }); } // [END external_ip] // Start the websocket server -var wsServer = app.listen('65080', function () { +const wsServer = app.listen('65080', () => { console.log('Websocket server listening on port %s', wsServer.address().port); }); // Additionally listen for non-websocket connections on the default App Engine // port 8080. Using http.createServer will skip express-ws's logic to upgrade // websocket connections. -var server = http.createServer(app).listen(process.env.PORT || '8080', function () { - console.log('App listening on port %s', server.address().port); +const PORT = process.env.PORT || 8080; +http.createServer(app).listen(PORT, () => { + console.log(`App listening on port ${PORT}`); console.log('Press Ctrl+C to quit.'); }); // [END app] diff --git a/appengine/websockets/package.json b/appengine/websockets/package.json index 02682b7d13..b62e6ef361 100644 --- a/appengine/websockets/package.json +++ b/appengine/websockets/package.json @@ -6,17 +6,15 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "engines": { - "node": "~4.2" + "node": ">=4.3.2" }, "scripts": { - "start": "node app.js", - "monitor": "nodemon app.js", - "deploy": "gcloud app deploy" + "start": "node app.js" }, "dependencies": { - "express": "^4.13.4", + "express": "^4.14.0", "express-ws": "^1.0.0-rc.2", - "jade": "^1.11.0", - "request": "^2.69.0" + "pug": "^2.0.0-beta6", + "request": "^2.75.0" } } diff --git a/appengine/websockets/views/index.jade b/appengine/websockets/views/index.pug similarity index 77% rename from appengine/websockets/views/index.jade rename to appengine/websockets/views/index.pug index dfe71aa257..0a8dc691f8 100644 --- a/appengine/websockets/views/index.jade +++ b/appengine/websockets/views/index.pug @@ -1,14 +1,3 @@ -//- Copyright 2015-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. - doctype html html(lang="en") head diff --git a/computeengine/vms_api.js b/computeengine/vms_api.js index 9e3e5ff083..cead13e59d 100644 --- a/computeengine/vms_api.js +++ b/computeengine/vms_api.js @@ -28,7 +28,7 @@ function auth (callback) { // The createScopedRequired method returns true when running on GAE or a // local developer machine. In that case, the desired scopes must be passed - // in manually. When the code is running in GCE or a Managed VM, the scopes + // in manually. When the code is running in GCE or GAE Flexible, the scopes // are pulled from the GCE metadata server. // See https://cloud.google.com/compute/docs/authentication for more // information. diff --git a/debugger/app.yaml b/debugger/app.yaml index f6ffeb3d5d..248738be70 100644 --- a/debugger/app.yaml +++ b/debugger/app.yaml @@ -13,5 +13,5 @@ # [START app_yaml] runtime: nodejs -vm: true +env: flex # [END app_yaml] diff --git a/prediction/hostedmodels.js b/prediction/hostedmodels.js index eb7c643fa4..35f7e549fa 100644 --- a/prediction/hostedmodels.js +++ b/prediction/hostedmodels.js @@ -25,7 +25,7 @@ function auth (callback) { // The createScopedRequired method returns true when running on GAE or a // local developer machine. In that case, the desired scopes must be passed - // in manually. When the code is running in GCE or a Managed VM, the scopes + // in manually. When the code is running in GCE or GAE Flexible, the scopes // are pulled from the GCE metadata server. // See https://cloud.google.com/compute/docs/authentication for more // information. diff --git a/storage/transfer.js b/storage/transfer.js index 1fcc80aa09..c9d47c24b4 100644 --- a/storage/transfer.js +++ b/storage/transfer.js @@ -33,7 +33,7 @@ function auth (callback) { // The createScopedRequired method returns true when running on GAE or a // local developer machine. In that case, the desired scopes must be passed - // in manually. When the code is running in GCE or a Managed VM, the scopes + // in manually. When the code is running in GCE or GAE Flexible, the scopes // are pulled from the GCE metadata server. // See https://cloud.google.com/compute/docs/authentication for more // information. diff --git a/trace/app.yaml b/trace/app.yaml index f6ffeb3d5d..248738be70 100644 --- a/trace/app.yaml +++ b/trace/app.yaml @@ -13,5 +13,5 @@ # [START app_yaml] runtime: nodejs -vm: true +env: flex # [END app_yaml]