Skip to content

Commit

Permalink
support custom API host and port configuration. fixes #389
Browse files Browse the repository at this point in the history
  • Loading branch information
stephenplusplus committed Feb 23, 2015
1 parent 6938342 commit 009d76c
Show file tree
Hide file tree
Showing 8 changed files with 150 additions and 52 deletions.
8 changes: 8 additions & 0 deletions lib/common/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,14 @@ function makeAuthorizedRequest(config) {

var authorize = gsa(config);

if (config.customApi) {
// Using a custom API override. Do not use `google-service-account` for
// authentication. (ex: connecting to a local Datastore server)
authorize = function(reqOpts, callback) {
callback(null, reqOpts);
};
}

function makeRequest(reqOpts, callback) {
var tokenRefreshAttempts = 0;
reqOpts.headers = reqOpts.headers || {};
Expand Down
14 changes: 14 additions & 0 deletions lib/datastore/dataset.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ var SCOPES = [
* `credentials` object.
* @param {object=} options.credentials - Credentials object, used in place of
* a `keyFilename`.
* @param {string=} options.host - Override the default API endpoint used to
* reach the Datastore. This is useful for connecting to your local
* Datastore server.
* @param {number=} options.port - Useful with `options.host` to set the port.
* @param {string} options.namespace - Namespace to isolate transactions to.
*
* @example
Expand All @@ -93,12 +97,22 @@ function Dataset(options) {

options = options || {};

if (options.host && options.host.indexOf('http') !== 0) {
throw new Error('A protocol must be included when specifying a host.');
}

this.makeAuthorizedRequest_ = util.makeAuthorizedRequest({
customApi: typeof options.host !== 'undefined',
credentials: options.credentials,
keyFile: options.keyFilename,
scopes: SCOPES
});

this.api = {
host: options.host || 'https://www.googleapis.com',
port: util.is(options.port, 'number') ? options.port : 443
};

this.namespace = options.namespace;
this.projectId = options.projectId;
}
Expand Down
31 changes: 18 additions & 13 deletions lib/datastore/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@

'use strict';

var https = require('https');
var streamEvents = require('stream-events');
var request = require('request');
var through = require('through2');

/**
Expand All @@ -42,12 +42,6 @@ var pb = require('./pb.js');
*/
var util = require('../common/util.js');

/**
* @const {string} Host to send with API requests.
* @private
*/
var GOOGLE_APIS_HOST = 'www.googleapis.com';

/**
* @const {string} Non-transaction mode key.
* @private
Expand Down Expand Up @@ -595,8 +589,13 @@ DatastoreRequest.prototype.makeReq_ = function(method, body, callback) {

var reqOpts = {
method: 'POST',
host: GOOGLE_APIS_HOST,
path: '/datastore/v1beta2/datasets/' + this.projectId + '/' + method,
uri: util.format('{host}:{port}/{path}/{projectId}/{method}', {
host: this.api.host,
port: this.api.port,
path: 'datastore/v1beta2/datasets',
projectId: this.projectId,
method: method
}),
headers: {
'Content-Type': 'application/x-protobuf'
}
Expand All @@ -609,7 +608,14 @@ DatastoreRequest.prototype.makeReq_ = function(method, body, callback) {
return;
}

var remoteStream = https.request(authorizedReqOpts, function(resp) {
authorizedReqOpts.headers = authorizedReqOpts.headers || {};
authorizedReqOpts.headers['Content-Length'] = pbRequest.length;

var apiRequest = request(authorizedReqOpts);

apiRequest.on('error', callback);

apiRequest.on('response', function(resp) {
var buffer = new Buffer('');
resp.on('data', function(chunk) {
buffer = Buffer.concat([buffer, chunk]);
Expand All @@ -624,9 +630,8 @@ DatastoreRequest.prototype.makeReq_ = function(method, body, callback) {
});
});
});
remoteStream.on('error', callback);
remoteStream.write(pbRequest);
remoteStream.end();

apiRequest.end(pbRequest);
}
});
};
Expand Down
1 change: 1 addition & 0 deletions lib/datastore/transaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ var extend = require('extend');
*/
function Transaction(dataset, projectId) {
this.id = null;
this.api = dataset.api;
this.makeAuthorizedRequest_ = dataset.makeAuthorizedRequest_;
this.projectId = projectId;

Expand Down
33 changes: 25 additions & 8 deletions test/common/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -299,8 +299,25 @@ describe('common/util', function() {
util.makeAuthorizedRequest(config);
});

it('should not authenticate requests with a custom API', function(done) {
var makeRequest = util.makeAuthorizedRequest({ customApi: true });

var gsaCalled = false;
gsa_Override = function() {
gsaCalled = true;
};

makeRequest({}, {
onAuthorized: function(err) {
assert.ifError(err);
assert.strictEqual(gsaCalled, false);
done();
}
});
});

it('should return gsa.getCredentials function', function() {
var getCredentials = util.makeAuthorizedRequest().getCredentials;
var getCredentials = util.makeAuthorizedRequest({}).getCredentials;
assert.equal(typeof getCredentials, 'function');
});

Expand All @@ -313,7 +330,7 @@ describe('common/util', function() {
};
};

var makeRequest = util.makeAuthorizedRequest();
var makeRequest = util.makeAuthorizedRequest({});
makeRequest({});
});

Expand All @@ -326,7 +343,7 @@ describe('common/util', function() {
};
};

var makeRequest = util.makeAuthorizedRequest();
var makeRequest = util.makeAuthorizedRequest({});
makeRequest({ headers: { 'User-Agent': 'test' } });
});

Expand All @@ -339,7 +356,7 @@ describe('common/util', function() {
};
};

var makeRequest = util.makeAuthorizedRequest();
var makeRequest = util.makeAuthorizedRequest({});
makeRequest({}, function(err) {
assert.equal(err, error);
done();
Expand Down Expand Up @@ -392,7 +409,7 @@ describe('common/util', function() {
};
};

var makeRequest = util.makeAuthorizedRequest();
var makeRequest = util.makeAuthorizedRequest({});
makeRequest({}, function (err) {
assert.equal(attempts, expectedAttempts);
assert.equal(err, error);
Expand All @@ -407,7 +424,7 @@ describe('common/util', function() {
};
};

var makeRequest = util.makeAuthorizedRequest();
var makeRequest = util.makeAuthorizedRequest({});
makeRequest({}, { onAuthorized: done });
});

Expand All @@ -420,7 +437,7 @@ describe('common/util', function() {
};
};

var makeRequest = util.makeAuthorizedRequest();
var makeRequest = util.makeAuthorizedRequest({});
makeRequest({}, {
onAuthorized: function(err) {
assert.equal(err, error);
Expand All @@ -443,7 +460,7 @@ describe('common/util', function() {
done();
};

var makeRequest = util.makeAuthorizedRequest();
var makeRequest = util.makeAuthorizedRequest({});
makeRequest({}, assert.ifError);
});
});
Expand Down
14 changes: 14 additions & 0 deletions test/datastore/dataset.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,20 @@ var Dataset = require('../../lib/datastore/dataset');
var util = require('../../lib/common/util.js');

describe('Dataset', function() {
describe('instantiation', function() {
it('should set default API connection details', function() {
var ds = new Dataset();
assert.equal(ds.api.host, 'https://www.googleapis.com');
assert.equal(ds.api.port, 443);
});

it('should set API connection details', function() {
var ds = new Dataset({ host: 'http://localhost', port: 8080 });
assert.equal(ds.api.host, 'http://localhost');
assert.equal(ds.api.port, 8080);
});
});

describe('key', function() {
it('should return key scoped by default namespace', function() {
var ds = new Dataset({ projectId: 'test', namespace: 'my-ns' });
Expand Down
Loading

0 comments on commit 009d76c

Please sign in to comment.