Skip to content

Commit 1eeb584

Browse files
committed
pubsub: skip getProjectId for emulator usage
1 parent 8ca2a85 commit 1eeb584

File tree

4 files changed

+180
-77
lines changed

4 files changed

+180
-77
lines changed

packages/pubsub/src/connection-pool.js

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -294,21 +294,12 @@ ConnectionPool.prototype.getClient = function(callback) {
294294
var self = this;
295295
var pubsub = this.subscription.pubsub;
296296

297-
pubsub.auth.getAuthClient(function(err, authClient) {
297+
this.getCredentials(function(err, credentials) {
298298
if (err) {
299299
callback(err);
300300
return;
301301
}
302302

303-
var credentials = grpc.credentials.combineChannelCredentials(
304-
grpc.credentials.createSsl(),
305-
grpc.credentials.createFromGoogleCredential(authClient)
306-
);
307-
308-
if (!self.projectId || self.projectId === '{{projectId}}') {
309-
self.projectId = pubsub.auth.projectId;
310-
}
311-
312303
var Subscriber = v1(pubsub.options).Subscriber;
313304

314305
self.client = new Subscriber(v1.SERVICE_ADDRESS, credentials, {
@@ -320,6 +311,38 @@ ConnectionPool.prototype.getClient = function(callback) {
320311
});
321312
};
322313

314+
/**
315+
* Get/create client credentials.
316+
*
317+
* @param {function} callback - The callback function.
318+
* @param {?error} callback.err - An error occurred while getting the client.
319+
* @param {object} callback.credentials - The client credentials.
320+
*/
321+
ConnectionPool.prototype.getCredentials = function(callback) {
322+
var self = this;
323+
var pubsub = this.subscription.pubsub;
324+
325+
if (pubsub.isEmulator) {
326+
setImmediate(callback, null, grpc.credentials.createInsecure());
327+
return;
328+
}
329+
330+
pubsub.auth.getAuthClient(function(err, authClient) {
331+
if (err) {
332+
callback(err);
333+
return;
334+
}
335+
336+
var credentials = grpc.credentials.combineChannelCredentials(
337+
grpc.credentials.createSsl(),
338+
grpc.credentials.createFromGoogleCredential(authClient)
339+
);
340+
341+
self.projectId = pubsub.auth.projectId;
342+
callback(null, credentials);
343+
});
344+
};
345+
323346
/**
324347
* Check to see if at least one stream in the pool is connected.
325348
* @return {boolean}

packages/pubsub/src/index.js

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ var Subscription = require('./subscription.js');
4747
*/
4848
var Topic = require('./topic.js');
4949

50+
/**
51+
* @type {string} - Project ID placeholder.
52+
* @private
53+
*/
54+
var PROJECT_ID_PLACEHOLDER = '{{projectId}}';
55+
5056
/**
5157
* [Cloud Pub/Sub](https://developers.google.com/pubsub/overview) is a
5258
* reliable, many-to-many, asynchronous messaging service from Cloud
@@ -76,11 +82,12 @@ function PubSub(options) {
7682
libVersion: PKG.version
7783
}, options);
7884

85+
this.isEmulator = false;
7986
this.determineBaseUrl_();
8087

8188
this.api = {};
8289
this.auth = googleAuth(this.options);
83-
this.projectId = this.options.projectId || '{{projectId}}';
90+
this.projectId = this.options.projectId || PROJECT_ID_PLACEHOLDER;
8491
}
8592

8693
/**
@@ -293,6 +300,7 @@ PubSub.prototype.determineBaseUrl_ = function() {
293300
this.options.servicePath = baseUrlParts[0];
294301
this.options.port = baseUrlParts[1];
295302
this.options.sslCreds = grpc.credentials.createInsecure();
303+
this.isEmulator = true;
296304
};
297305

298306
/**
@@ -640,25 +648,34 @@ PubSub.prototype.request = function(config, callback) {
640648
return;
641649
}
642650

643-
self.auth.getProjectId(function(err, projectId) {
644-
if (err) {
645-
callback(err);
646-
return;
647-
}
651+
var hasProjectId = this.projectId &&
652+
this.projectId !== PROJECT_ID_PLACEHOLDER;
648653

649-
var gaxClient = self.api[config.client];
654+
if (!hasProjectId && !this.isEmulator) {
655+
this.auth.getProjectId(function(err, projectId) {
656+
if (err) {
657+
callback(err);
658+
return;
659+
}
650660

651-
if (!gaxClient) {
652-
// Lazily instantiate client.
653-
gaxClient = v1(self.options)[config.client](self.options);
654-
self.api[config.client] = gaxClient;
655-
}
661+
self.projectId = projectId;
662+
self.request(config, callback);
663+
});
664+
return;
665+
}
656666

657-
var reqOpts = extend(true, {}, config.reqOpts);
658-
reqOpts = common.util.replaceProjectIdToken(reqOpts, projectId);
667+
var gaxClient = this.api[config.client];
659668

660-
gaxClient[config.method](reqOpts, config.gaxOpts, callback);
661-
});
669+
if (!gaxClient) {
670+
// Lazily instantiate client.
671+
gaxClient = v1(this.options)[config.client](this.options);
672+
this.api[config.client] = gaxClient;
673+
}
674+
675+
var reqOpts = extend(true, {}, config.reqOpts);
676+
reqOpts = common.util.replaceProjectIdToken(reqOpts, this.projectId);
677+
678+
gaxClient[config.method](reqOpts, config.gaxOpts, callback);
662679
};
663680

664681
/**

packages/pubsub/test/connection-pool.js

Lines changed: 93 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -675,8 +675,7 @@ describe('ConnectionPool', function() {
675675
});
676676

677677
describe('getClient', function() {
678-
var AUTH_PROJECT_ID = 'auth-project-id-123';
679-
var fakeAuthClient = {};
678+
var fakeCreds = {};
680679

681680
function FakeSubscriber(address, creds, options) {
682681
this.address = address;
@@ -685,9 +684,8 @@ describe('ConnectionPool', function() {
685684
}
686685

687686
beforeEach(function() {
688-
PUBSUB.auth.projectId = AUTH_PROJECT_ID;
689-
PUBSUB.auth.getAuthClient = function(callback) {
690-
callback(null, fakeAuthClient);
687+
pool.getCredentials = function(callback) {
688+
callback(null, fakeCreds);
691689
};
692690

693691
v1Override = function() {
@@ -710,7 +708,7 @@ describe('ConnectionPool', function() {
710708
it('should return any auth errors', function(done) {
711709
var error = new Error('err');
712710

713-
PUBSUB.auth.getAuthClient = function(callback) {
711+
pool.getCredentials = function(callback) {
714712
callback(error);
715713
};
716714

@@ -722,49 +720,10 @@ describe('ConnectionPool', function() {
722720
});
723721

724722
it('should create/use grpc credentials', function(done) {
725-
var fakeSslCreds = {};
726-
var fakeGoogCreds = {};
727-
var fakeCombinedCreds = {};
728-
729-
fakeGrpc.credentials = {
730-
createSsl: function() {
731-
return fakeSslCreds;
732-
},
733-
createFromGoogleCredential: function(authClient) {
734-
assert.strictEqual(authClient, fakeAuthClient);
735-
return fakeGoogCreds;
736-
},
737-
combineChannelCredentials: function(sslCreds, googCreds) {
738-
assert.strictEqual(sslCreds, fakeSslCreds);
739-
assert.strictEqual(googCreds, fakeGoogCreds);
740-
return fakeCombinedCreds;
741-
}
742-
};
743-
744723
pool.getClient(function(err, client) {
745724
assert.ifError(err);
746725
assert(client instanceof FakeSubscriber);
747-
assert.strictEqual(client.creds, fakeCombinedCreds);
748-
done();
749-
});
750-
});
751-
752-
it('should capture the projectId when falsey', function(done) {
753-
delete pool.projectId;
754-
755-
pool.getClient(function(err) {
756-
assert.ifError(err);
757-
assert.strictEqual(pool.projectId, AUTH_PROJECT_ID);
758-
done();
759-
});
760-
});
761-
762-
it('should capture the projectId if it needs tokenization', function(done) {
763-
pool.projectId = '{{projectId}}';
764-
765-
pool.getClient(function(err) {
766-
assert.ifError(err);
767-
assert.strictEqual(pool.projectId, AUTH_PROJECT_ID);
726+
assert.strictEqual(client.creds, fakeCreds);
768727
done();
769728
});
770729
});
@@ -783,11 +742,6 @@ describe('ConnectionPool', function() {
783742
});
784743

785744
it('should pass in the correct the args to the Subscriber', function(done) {
786-
var fakeCreds = {};
787-
fakeGrpc.credentials.combineChannelCredentials = function() {
788-
return fakeCreds;
789-
};
790-
791745
var fakeAddress = 'a.b.c';
792746
fakeV1.SERVICE_ADDRESS = fakeAddress;
793747

@@ -813,6 +767,94 @@ describe('ConnectionPool', function() {
813767
});
814768
});
815769

770+
describe('getCredentials', function() {
771+
beforeEach(function() {
772+
fakeGrpc.credentials = {
773+
createInsecure: fakeUtil.noop,
774+
createSsl: fakeUtil.noop,
775+
createFromGoogleCredential: fakeUtil.noop,
776+
combineChannelCredentials: fakeUtil.noop
777+
};
778+
});
779+
780+
it('should return insecure creds for emulator usage', function(done) {
781+
var fakeCreds = {};
782+
fakeGrpc.credentials.createInsecure = function() {
783+
return fakeCreds;
784+
};
785+
786+
PUBSUB.isEmulator = true;
787+
788+
pool.getCredentials(function(err, creds) {
789+
assert.ifError(err);
790+
assert.strictEqual(creds, fakeCreds);
791+
done();
792+
});
793+
});
794+
795+
it('should get grpc creds', function(done) {
796+
var fakeAuthClient = {};
797+
var fakeSslCreds = {};
798+
var fakeGoogCreds = {};
799+
var fakeCombinedCreds = {};
800+
801+
PUBSUB.isEmulator = false;
802+
PUBSUB.auth.getAuthClient = function(callback) {
803+
callback(null, fakeAuthClient);
804+
};
805+
806+
fakeGrpc.credentials = {
807+
createSsl: function() {
808+
return fakeSslCreds;
809+
},
810+
createFromGoogleCredential: function(authClient) {
811+
assert.strictEqual(authClient, fakeAuthClient);
812+
return fakeGoogCreds;
813+
},
814+
combineChannelCredentials: function(sslCreds, googCreds) {
815+
assert.strictEqual(sslCreds, fakeSslCreds);
816+
assert.strictEqual(googCreds, fakeGoogCreds);
817+
return fakeCombinedCreds;
818+
}
819+
};
820+
821+
822+
pool.getCredentials(function(err, creds) {
823+
assert.ifError(err);
824+
assert.strictEqual(creds, fakeCombinedCreds);
825+
done();
826+
});
827+
});
828+
829+
it('should return getAuthClient errors', function(done) {
830+
var error = new Error('err');
831+
832+
PUBSUB.auth.getAuthClient = function(callback) {
833+
callback(error);
834+
};
835+
836+
pool.getCredentials(function(err) {
837+
assert.strictEqual(err, error);
838+
done();
839+
});
840+
});
841+
842+
it('should cache the project ID', function(done) {
843+
PUBSUB.auth.getAuthClient = function(callback) {
844+
PUBSUB.auth.projectId = PROJECT_ID;
845+
callback(null, {});
846+
};
847+
848+
delete pool.projectId;
849+
850+
pool.getCredentials(function(err) {
851+
assert.ifError(err);
852+
assert.strictEqual(pool.projectId, PROJECT_ID);
853+
done();
854+
});
855+
});
856+
});
857+
816858
describe('isConnected', function() {
817859
it('should return true when at least one stream is connected', function() {
818860
var connections = pool.connections = new Map();

packages/pubsub/test/index.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -963,6 +963,8 @@ describe('PubSub', function() {
963963
};
964964

965965
beforeEach(function() {
966+
delete pubsub.projectId;
967+
966968
pubsub.auth = {
967969
getProjectId: function(callback) {
968970
callback(null, PROJECT_ID);
@@ -1043,6 +1045,25 @@ describe('PubSub', function() {
10431045
global.GCLOUD_SANDBOX_ENV = false;
10441046
done();
10451047
});
1048+
1049+
describe('on emulator', function() {
1050+
beforeEach(function() {
1051+
pubsub.isEmulator = true;
1052+
pubsub.auth.getProjectId = function() {
1053+
throw new Error('getProjectId should not be called.');
1054+
};
1055+
});
1056+
1057+
it('should not get the projectId if null', function(done) {
1058+
pubsub.projectId = null;
1059+
pubsub.request(CONFIG, done);
1060+
});
1061+
1062+
it('should not get the projectId if placeholder', function(done) {
1063+
pubsub.projectId = '{{projectId}}';
1064+
pubsub.request(CONFIG, done);
1065+
});
1066+
});
10461067
});
10471068

10481069
describe('snapshot', function() {

0 commit comments

Comments
 (0)