Skip to content
This repository has been archived by the owner on Apr 3, 2024. It is now read-only.

Commit

Permalink
switch to using @google-cloud/common
Browse files Browse the repository at this point in the history
This PR starts using the authorized / retry request flow from the
@google-cloud/common library. From an operational perspective This
shouldn't change behaviour significantly – although there are small
differences in how the new library does retries or how it prioritizes
different sources of the projectId & credentials (environment vs.
metadata vs. config).
  • Loading branch information
ofrobots committed Dec 14, 2016
1 parent d3d648e commit 2d15078
Show file tree
Hide file tree
Showing 11 changed files with 109 additions and 67 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ node_modules
coverage
npm-debug.log
.DS_Store
.vscode
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"proxyquire": "^1.4.0"
},
"dependencies": {
"@google-cloud/common": "^0.9.0",
"@google/cloud-diagnostics-common": "0.3.0",
"acorn": "^4.0.3",
"async": "^2.1.2",
Expand Down
7 changes: 5 additions & 2 deletions src/agent/debuglet.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ module.exports = Debuglet;
* @event 'stopped' if the agent stops due to a fatal error after starting
* @constructor
*/
function Debuglet(config, logger) {
function Debuglet(debug, config, logger) {
/** @private {Debug} */
this.debug_ = debug;

/** @private {object} */
this.config_ = config || {};

Expand All @@ -69,7 +72,7 @@ function Debuglet(config, logger) {
this.logger_ = logger;

/** @private {DebugletApi} */
this.debugletApi_ = new DebugletApi(config);
this.debugletApi_ = new DebugletApi(this.config_, this.debug_);

/** @private {Object.<string, Breakpoint>} */
this.activeBreakpointMap_ = {};
Expand Down
35 changes: 13 additions & 22 deletions src/debugletapi.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,15 @@ var API = 'https://clouddebugger.googleapis.com/v2/controller';
/** @const {string} */ var DEBUGGEE_MAJOR_VERSION_LABEL = 'version';
/** @const {string} */ var DEBUGGEE_MINOR_VERSION_LABEL = 'minorversion';

/** @const {Array<string>} list of scopes needed to operate with the debug API */
var SCOPES = [
'https://www.googleapis.com/auth/cloud-platform',
'https://www.googleapis.com/auth/cloud_debugletcontroller'
];

/**
* @constructor
*/
function DebugletApi(config) {
var config_ = config || {};
function DebugletApi(config, debug) {
config = config || {};

/** @private {Object} request style request object */
this.request_ = utils.authorizedRequestFactory(SCOPES, {
keyFile: config_.keyFilename,
credentials: config_.credentials
});
/** @priavate {Debug} */
this.debug_ = debug;

/** @private {string} numeric project id */
this.project_ = null;
Expand All @@ -58,13 +50,13 @@ function DebugletApi(config) {
this.debuggeeId_ = null;

/** @private {string} a descriptor of the current code version */
this.descriptor_ = config_.description;
this.descriptor_ = config.description;

/** @private {string} the service name of the current code */
this.serviceName_ = config_.serviceContext && config_.serviceContext.service;
this.serviceName_ = config.serviceContext && config.serviceContext.service;

/** @private {string} the version of the current code */
this.serviceVersion_ = config_.serviceContext && config_.serviceContext.version;
this.serviceVersion_ = config.serviceContext && config.serviceContext.version;
}

/**
Expand Down Expand Up @@ -196,13 +188,12 @@ DebugletApi.prototype.register_ = function(errorMessage, callback) {
}

var options = {
url: API + '/debuggees/register',
uri: API + '/debuggees/register',
method: 'POST',
json: true,
body: { debuggee: debuggee }
};

that.request_(options, function(err, response, body) {
this.debug_.request(options, function(err, body, response) {
if (err) {
callback(err);
} else if (response.statusCode !== 200) {
Expand Down Expand Up @@ -231,9 +222,9 @@ DebugletApi.prototype.listBreakpoints = function(callback) {
query.waitToken = that.nextWaitToken;
}

var url = API + '/debuggees/' + encodeURIComponent(that.debuggeeId_) +
var uri = API + '/debuggees/' + encodeURIComponent(that.debuggeeId_) +
'/breakpoints?' + qs.stringify(query);
that.request_({url: url, json: true}, function(err, response, body) {
that.debug_.request({uri: uri, json: true}, function(err, body, response) {
if (!response) {
callback(err || new Error('unknown error - request response missing'));
return;
Expand Down Expand Up @@ -266,7 +257,7 @@ DebugletApi.prototype.updateBreakpoint =
breakpoint.action = 'capture';
breakpoint.isFinalState = true;
var options = {
url: API + '/debuggees/' + encodeURIComponent(this.debuggeeId_) +
uri: API + '/debuggees/' + encodeURIComponent(this.debuggeeId_) +
'/breakpoints/' + encodeURIComponent(breakpoint.id),
json: true,
method: 'PUT',
Expand All @@ -281,7 +272,7 @@ DebugletApi.prototype.updateBreakpoint =
// stringify them. The try-catch keeps it resilient and avoids crashing the
// user's app.
try {
this.request_(options, function(err, response, body) {
this.debug_.request(options, function(err, body, response) {
callback(err, body);
});
} catch (error) {
Expand Down
28 changes: 22 additions & 6 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
'use strict';

var logger = require('@google/cloud-diagnostics-common').logger;
var common = require('@google-cloud/common');
var Debuglet = require('./agent/debuglet.js');
var util = require('util');
var _ = require('lodash');

/**
Expand Down Expand Up @@ -45,11 +47,24 @@ var _ = require('lodash');
*/
function Debug(options) {
if (!(this instanceof Debug)) {
//TODO(ofrobots)
//options = common.util.normalizeArguments(this, options);
options = common.util.normalizeArguments(this, options);
return new Debug(options);
}

var config = {
baseUrl: 'https://clouddebugger.googleapis.com/v2',
scopes: [
// TODO: do we still need cloud-platform scope?
'https://www.googleapis.com/auth/cloud-platform',
'https://www.googleapis.com/auth/cloud_debugletcontroller'
// TODO: the client library probably wants cloud_debugger scope as well.
],
packageJson: require('../package.json')
};

common.Service.call(this, config, options);
}
util.inherits(Debug, common.Service);

var initConfig = function(config_) {
var config = config_ || {};
Expand Down Expand Up @@ -77,21 +92,22 @@ var debuglet;
* with Stackdriver Debug.
*
* @param {object=} config - Debug configuration. TODO(ofrobots): get rid of
* config.js and include jsdoc here
* config.js and include jsdoc here?
* TODO: add an optional callback function.
*
* @resource [Introductory video]{@link https://www.youtube.com/watch?v=tyHcK_kAOpw}
*
* @example
* debug.startAgent();
*/
Debug.prototype.startAgent = function(config_) {
Debug.prototype.startAgent = function(config) {
if (debuglet) {
throw new Error('Debug Agent has already been started');
}
var config = initConfig(config_);
config = initConfig(config);
if (config.enabled) {
debuglet = new Debuglet(config, logger.create(config.logLevel, '@google-cloud/debug'));
debuglet = new Debuglet(
this, config, logger.create(config.logLevel, '@google-cloud/debug'));
debuglet.start();
this.private_ = debuglet;
}
Expand Down
23 changes: 23 additions & 0 deletions test/auth-request.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* Copyright 2016 Google Inc. All Rights Reserved.
*
* 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 request = require('request');
module.exports = function(options, callback) {
request(options, function(err, response, body) {
callback(err, body, response);
});
};
16 changes: 6 additions & 10 deletions test/e2e/test-breakpoints.js
Original file line number Diff line number Diff line change
Expand Up @@ -250,15 +250,15 @@ function runTest() {
// and log points.
if (cluster.isMaster) {
cluster.setupMaster({ silent: true });
var handler = function(m) {
var handler = function(a) {
if (!debuggee) {
// Cache the needed info from the first worker.
debuggee = m.private_.debugletApi_.debuggeeId_;
project = m.private_.debugletApi_.project_;
debuggee = a[0];
project = a[1];
} else {
// Make sure all other workers are consistent.
assert.equal(debuggee, m.private_.debugletApi_.debuggeeId_);
assert.equal(project, m.private_.debugletApi_.project_);
assert.equal(debuggee, a[0]);
assert.equal(project, a[1]);
}
};
var stdoutHandler = function(chunk) {
Expand Down Expand Up @@ -288,12 +288,8 @@ if (cluster.isMaster) {
assert.ok(api.uid_, 'debuglet provided unique id');
assert.ok(api.debuggeeId_, 'debuglet has registered');
// The parent process needs to know the debuggeeId and project.
process.send(debug);
process.send([api.debuggeeId_, api.project_]);
setInterval(fib.bind(null, 12), 2000);
}, 7000);

}

process.on('exit', function() {
console.log('worker transcript:', transcript);
});
8 changes: 4 additions & 4 deletions test/e2e/test-log-throttling.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,11 +181,11 @@ function runTest() {

if (cluster.isMaster) {
cluster.setupMaster({ silent: true });
var handler = function(m) {
var handler = function(a) {
// Cache the needed info from the first worker.
if (!debuggee) {
debuggee = m.private_.debugletApi_.debuggeeId_;
project = m.private_.debugletApi_.project_;
debuggee = a[0];
project = a[1];
}
};
var stdoutHandler = function(chunk) {
Expand Down Expand Up @@ -216,7 +216,7 @@ if (cluster.isMaster) {
var api = debuglet.debugletApi_;
assert.ok(api.uid_, 'debuglet provided unique id');
assert.ok(api.debuggeeId_, 'debuglet has registered');
process.send(debug);
process.send([api.debuggeeId_, api.project_]);
setInterval(fib.bind(null, 12), 500);
}, 7000);
}
32 changes: 18 additions & 14 deletions test/standalone/test-config-credentials.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ describe('test-config-credentials', function() {
var config = extend({}, defaultConfig, {
keyFilename: path.join('test', 'fixtures', 'gcloud-credentials.json')
});
var debug = require('../..')(config);
var scope = nock('https://accounts.google.com')
.post('/o/oauth2/token', function(body) {
assert.equal(body.client_id, credentials.client_id);
Expand All @@ -63,14 +64,15 @@ describe('test-config-credentials', function() {
setImmediate(done);
return true;
}).reply(200);
debuglet = new Debuglet(config, logger.create(logger.WARN, 'testing'));
debuglet = new Debuglet(debug, config, logger.create(logger.WARN, 'testing'));
debuglet.start();
});

it('should use the credentials field of the config object', function(done) {
var config = extend({}, defaultConfig, {
credentials: require('../fixtures/gcloud-credentials.json')
});
var debug = require('../..')(config);
var scope = nock('https://accounts.google.com')
.post('/o/oauth2/token', function(body) {
assert.equal(body.client_id, config.credentials.client_id);
Expand All @@ -89,32 +91,34 @@ describe('test-config-credentials', function() {
setImmediate(done);
return true;
}).reply(200);
debuglet = new Debuglet(config, logger.create(undefined, 'testing'));
debuglet = new Debuglet(debug, config, logger.create(undefined, 'testing'));
debuglet.start();
});

it('should ignore credentials if keyFilename is provided', function(done) {
var correctCredentials = require('../fixtures/gcloud-credentials.json');
var config = extend({}, defaultConfig, {
keyFilename: path.join('test', 'fixtures', 'gcloud-credentials.json'),
credentials: {
it('should ignore keyFilename if credentials is provided', function(done) {
var fileCredentials = require('../fixtures/gcloud-credentials.json');
var credentials = {
client_id: 'a',
client_secret: 'b',
refresh_token: 'c',
type: 'authorized_user'
}
};
var config = extend({}, defaultConfig, {
keyFilename: path.join('test', 'fixtures', 'gcloud-credentials.json'),
credentials: credentials
});
var debug = require('../..')(config);
['client_id', 'client_secret', 'refresh_token'].forEach(function (field) {
assert(correctCredentials.hasOwnProperty(field));
assert(fileCredentials.hasOwnProperty(field));
assert(config.credentials.hasOwnProperty(field));
assert.notEqual(config.credentials[field],
correctCredentials[field]);
fileCredentials[field]);
});
var scope = nock('https://accounts.google.com')
.post('/o/oauth2/token', function(body) {
assert.equal(body.client_id, correctCredentials.client_id);
assert.equal(body.client_secret, correctCredentials.client_secret);
assert.equal(body.refresh_token, correctCredentials.refresh_token);
assert.equal(body.client_id, credentials.client_id);
assert.equal(body.client_secret, credentials.client_secret);
assert.equal(body.refresh_token, credentials.refresh_token);
return true;
}).reply(200, {
refresh_token: 'hello',
Expand All @@ -128,7 +132,7 @@ describe('test-config-credentials', function() {
setImmediate(done);
return true;
}).reply(200);
debuglet = new Debuglet(config, logger.create(undefined, 'testing'));
debuglet = new Debuglet(debug, config, logger.create(undefined, 'testing'));
debuglet.start();
});
});
Loading

0 comments on commit 2d15078

Please sign in to comment.