diff --git a/packages/logging/src/index.js b/packages/logging/src/index.js index 0af7be6c009..cbbfe72811b 100644 --- a/packages/logging/src/index.js +++ b/packages/logging/src/index.js @@ -24,7 +24,6 @@ var arrify = require('arrify'); var common = require('@google-cloud/common'); var extend = require('extend'); var format = require('string-format-obj'); -var googleAuth = require('google-auto-auth'); var is = require('is'); var pumpify = require('pumpify'); var streamEvents = require('stream-events'); @@ -69,14 +68,18 @@ function Logging(options) { return new Logging(options); } - var options_ = extend({ - scopes: v2.ALL_SCOPES + options = extend({ + projectId: '{{projectId}}' }, options); - this.api = {}; - this.auth = googleAuth(options_); - this.options = options_; - this.projectId = options.projectId || '{{projectId}}'; + this.projectId = options.projectId; + + var gax = v2(options); + + this.api = { + Config: gax.configServiceV2Client(), + Logging: gax.loggingServiceV2Client() + }; } // jscs:disable maximumLineLength @@ -163,12 +166,7 @@ Logging.prototype.createSink = function(name, config, callback) { delete reqOpts.sink.gaxOptions; - this.request({ - client: 'configServiceV2Client', - method: 'createSink', - reqOpts: reqOpts, - gaxOpts: config.gaxOptions - }, function(err, resp) { + this.api.Config.createSink(reqOpts, config.gaxOptions, function(err, resp) { if (err) { callback(err, null, resp); return; @@ -299,12 +297,7 @@ Logging.prototype.getEntries = function(options, callback) { autoPaginate: options.autoPaginate }, options.gaxOptions); - this.request({ - client: 'loggingServiceV2Client', - method: 'listLogEntries', - reqOpts: reqOpts, - gaxOpts: gaxOptions - }, function() { + this.api.Logging.listLogEntries(reqOpts, gaxOptions, function() { var entries = arguments[1]; if (entries) { @@ -435,12 +428,7 @@ Logging.prototype.getSinks = function(options, callback) { autoPaginate: options.autoPaginate }, options.gaxOptions); - this.request({ - client: 'configServiceV2Client', - method: 'listSinks', - reqOpts: reqOpts, - gaxOpts: gaxOptions - }, function() { + this.api.Config.listSinks(reqOpts, gaxOptions, function() { var sinks = arguments[1]; if (sinks) { @@ -513,12 +501,7 @@ Logging.prototype.getSinksStream = function(options) { autoPaginate: options.autoPaginate }, options.gaxOptions); - requestStream = self.request({ - client: 'configServiceV2Client', - method: 'listSinksStream', - reqOpts: reqOpts, - gaxOpts: gaxOptions - }); + requestStream = self.api.Config.listSinksStream(reqOpts, gaxOptions); userStream.setPipeline(requestStream, toSinkStream); }); @@ -569,91 +552,6 @@ Logging.prototype.sink = function(name) { * @param {function=} callback - The callback function. */ Logging.prototype.request = function(config, callback) { - var self = this; - var isStreamMode = !callback; - - var gaxStream; - var stream; - - if (isStreamMode) { - stream = streamEvents(through.obj()); - - stream.abort = function() { - if (gaxStream && gaxStream.cancel) { - gaxStream.cancel(); - } - }; - - stream.once('reading', makeRequestStream); - } else { - makeRequestCallback(); - } - - function prepareGaxRequest(callback) { - self.auth.getProjectId(function(err, projectId) { - if (err) { - callback(err); - return; - } - - var gaxClient = self.api[config.client]; - - if (!gaxClient) { - // Lazily instantiate client. - gaxClient = v2(self.options)[config.client](self.options); - self.api[config.client] = gaxClient; - } - - var reqOpts = extend(true, {}, config.reqOpts); - reqOpts = common.util.replaceProjectIdToken(reqOpts, projectId); - - var requestFn = gaxClient[config.method].bind( - gaxClient, - reqOpts, - config.gaxOpts - ); - - callback(null, requestFn); - }); - } - - function makeRequestCallback() { - if (global.GCLOUD_SANDBOX_ENV) { - return; - } - - prepareGaxRequest(function(err, requestFn) { - if (err) { - callback(err); - return; - } - - requestFn(callback); - }); - } - - function makeRequestStream() { - if (global.GCLOUD_SANDBOX_ENV) { - return through.obj(); - } - - prepareGaxRequest(function(err, requestFn) { - if (err) { - stream.destroy(err); - return; - } - - gaxStream = requestFn(); - - gaxStream - .on('error', function(err) { - stream.destroy(err); - }) - .pipe(stream); - }); - } - - return stream; }; /** diff --git a/packages/logging/src/log.js b/packages/logging/src/log.js index 5891735b921..53b3cb3171d 100644 --- a/packages/logging/src/log.js +++ b/packages/logging/src/log.js @@ -222,12 +222,7 @@ Log.prototype.delete = function(gaxOptions, callback) { logName: this.formattedName_ }; - this.logging.request({ - client: 'loggingServiceV2Client', - method: 'deleteLog', - reqOpts: reqOpts, - gaxOpts: gaxOptions - }, callback); + this.logging.api.Logging.deleteLog(reqOpts, gaxOptions, callback); }; /** @@ -603,12 +598,11 @@ Log.prototype.write = function(entry, options, callback) { delete reqOpts.gaxOptions; - self.logging.request({ - client: 'loggingServiceV2Client', - method: 'writeLogEntries', - reqOpts: reqOpts, - gaxOpts: options.gaxOptions - }, callback); + self.logging.api.Logging.writeLogEntries( + reqOpts, + options.gaxOptions, + callback + ); }); }; diff --git a/packages/logging/src/sink.js b/packages/logging/src/sink.js index 9396cc68fee..a8be2b904d4 100644 --- a/packages/logging/src/sink.js +++ b/packages/logging/src/sink.js @@ -117,12 +117,7 @@ Sink.prototype.delete = function(gaxOptions, callback) { sinkName: this.formattedName_ }; - this.logging.request({ - client: 'configServiceV2Client', - method: 'deleteSink', - reqOpts: reqOpts, - gaxOpts: gaxOptions - }, callback); + this.logging.api.Config.deleteSink(reqOpts, gaxOptions, callback); }; /** @@ -162,12 +157,7 @@ Sink.prototype.getMetadata = function(gaxOptions, callback) { sinkName: this.formattedName_ }; - this.logging.request({ - client: 'configServiceV2Client', - method: 'getSink', - reqOpts: reqOpts, - gaxOpts: gaxOptions - }, function() { + this.logging.api.Config.getSink(reqOpts, gaxOptions, function() { if (arguments[1]) { self.metadata = arguments[1]; } @@ -254,18 +244,16 @@ Sink.prototype.setMetadata = function(metadata, callback) { delete reqOpts.sink.gaxOptions; - self.logging.request({ - client: 'configServiceV2Client', - method: 'updateSink', - reqOpts: reqOpts, - gaxOpts: metadata.gaxOptions - }, function() { - if (arguments[1]) { - self.metadata = arguments[1]; - } + self.logging.api.Config.updateSink( + reqOpts, + metadata.gaxOptions, + function() { + if (arguments[1]) { + self.metadata = arguments[1]; + } - callback.apply(null, arguments); - }); + callback.apply(null, arguments); + }); }); }; diff --git a/packages/logging/src/v2/config_service_v2_client.js b/packages/logging/src/v2/config_service_v2_client.js index 56fbacbb540..8a38b94f64d 100644 --- a/packages/logging/src/v2/config_service_v2_client.js +++ b/packages/logging/src/v2/config_service_v2_client.js @@ -100,9 +100,7 @@ function ConfigServiceV2Client(gaxGrpc, grpcClients, opts) { var self = this; this.auth = gaxGrpc.auth; - var configServiceV2Stub = gaxGrpc.createStub( - grpcClients.google.logging.v2.ConfigServiceV2, - opts); + var configServiceV2StubMethods = [ 'listSinks', 'getSink', @@ -110,17 +108,86 @@ function ConfigServiceV2Client(gaxGrpc, grpcClients, opts) { 'updateSink', 'deleteSink' ]; + + var configServiceV2Stub; + configServiceV2StubMethods.forEach(function(methodName) { - self['_' + methodName] = gax.createApiCall( - configServiceV2Stub.then(function(configServiceV2Stub) { - return function() { - var args = Array.prototype.slice.call(arguments, 0); - return configServiceV2Stub[methodName].apply(configServiceV2Stub, args); - }; - }), - defaults[methodName], - PAGE_DESCRIPTORS[methodName]); + self['_' + methodName] = function() { + var args = [].slice.call(arguments); + var cb; + + if (typeof args[args.length - 1] === 'function') { + cb = args.pop(); + } + + var promise = getStub().then(function(stub) { + var apiCall = gax.createApiCall( + configServiceV2Stub.then(function(configServiceV2Stub) { + return function() { + var args = Array.prototype.slice.call(arguments, 0); + var reqOpts = args[0]; + + try { + reqOpts = replaceProjectIdToken(reqOpts, self.auth.projectId); + } catch(e) { + var callback = args[args.length - 1]; + callback(e); + return; + } + + return configServiceV2Stub[methodName].apply(configServiceV2Stub, args); + }; + }), + defaults[methodName], + PAGE_DESCRIPTORS[methodName]); + + return apiCall.apply(self, args); + }); + + if (!cb) { + return promise; + } + + promise.then(cb.bind(null, null), cb); + }; }); + + function getStub() { + if (configServiceV2Stub) { + return Promise.resolve(configServiceV2Stub); + } + + configServiceV2Stub = gaxGrpc.createStub( + grpcClients.google.logging.v2.ConfigServiceV2, opts); + + return configServiceV2Stub; + } + + function replaceProjectIdToken(value, projectId) { + if (Array.isArray(value)) { + value = value.map(function(val) { + return replaceProjectIdToken(val, projectId); + }); + } + + if (value && typeof value === 'object' && typeof value.hasOwnProperty === 'function') { + for (var opt in value) { + if (value.hasOwnProperty(opt)) { + value[opt] = replaceProjectIdToken(value[opt], projectId); + } + } + } + + if (typeof value === 'string' && value.indexOf('{{projectId}}') > -1) { + if (!projectId) { + throw new Error('Sorry, we cannot connect to Cloud Services without a project ID.'); + } + + value = value.replace(/{{projectId}}/g, projectId); + } + + return value; + } } // Path templates diff --git a/packages/logging/src/v2/logging_service_v2_client.js b/packages/logging/src/v2/logging_service_v2_client.js index bfb9ea05308..57c68a5fcae 100644 --- a/packages/logging/src/v2/logging_service_v2_client.js +++ b/packages/logging/src/v2/logging_service_v2_client.js @@ -119,9 +119,7 @@ function LoggingServiceV2Client(gaxGrpc, grpcClients, opts) { var self = this; this.auth = gaxGrpc.auth; - var loggingServiceV2Stub = gaxGrpc.createStub( - grpcClients.google.logging.v2.LoggingServiceV2, - opts); + var loggingServiceV2StubMethods = [ 'deleteLog', 'writeLogEntries', @@ -129,17 +127,86 @@ function LoggingServiceV2Client(gaxGrpc, grpcClients, opts) { 'listMonitoredResourceDescriptors', 'listLogs' ]; + + var loggingServiceV2Stub; + loggingServiceV2StubMethods.forEach(function(methodName) { - self['_' + methodName] = gax.createApiCall( - loggingServiceV2Stub.then(function(loggingServiceV2Stub) { - return function() { - var args = Array.prototype.slice.call(arguments, 0); - return loggingServiceV2Stub[methodName].apply(loggingServiceV2Stub, args); - }; - }), - defaults[methodName], - PAGE_DESCRIPTORS[methodName] || bundleDescriptors[methodName]); + self['_' + methodName] = function() { + var args = [].slice.call(arguments); + var cb; + + if (typeof args[args.length - 1] === 'function') { + cb = args.pop(); + } + + var promise = getStub().then(function(stub) { + var apiCall = gax.createApiCall( + loggingServiceV2Stub.then(function(loggingServiceV2Stub) { + return function() { + var args = Array.prototype.slice.call(arguments, 0); + var reqOpts = args[0]; + + try { + reqOpts = replaceProjectIdToken(reqOpts, self.auth.projectId); + } catch(e) { + var callback = args[args.length - 1]; + callback(e); + return; + } + + return loggingServiceV2Stub[methodName].apply(loggingServiceV2Stub, args); + }; + }), + defaults[methodName], + PAGE_DESCRIPTORS[methodName] || bundleDescriptors[methodName]); + + return apiCall.apply(self, args); + }); + + if (!cb) { + return promise; + } + + promise.then(cb.bind(null, null), cb); + }; }); + + function getStub() { + if (loggingServiceV2Stub) { + return Promise.resolve(loggingServiceV2Stub); + } + + loggingServiceV2Stub = gaxGrpc.createStub( + grpcClients.google.logging.v2.LoggingServiceV2, opts); + + return loggingServiceV2Stub; + } + + function replaceProjectIdToken(value, projectId) { + if (Array.isArray(value)) { + value = value.map(function(val) { + return replaceProjectIdToken(val, projectId); + }); + } + + if (value && typeof value === 'object' && typeof value.hasOwnProperty === 'function') { + for (var opt in value) { + if (value.hasOwnProperty(opt)) { + value[opt] = replaceProjectIdToken(value[opt], projectId); + } + } + } + + if (typeof value === 'string' && value.indexOf('{{projectId}}') > -1) { + if (!projectId) { + throw new Error('Sorry, we cannot connect to Cloud Services without a project ID.'); + } + + value = value.replace(/{{projectId}}/g, projectId); + } + + return value; + } } // Path templates diff --git a/packages/logging/src/v2/metrics_service_v2_client.js b/packages/logging/src/v2/metrics_service_v2_client.js index 126e3f5513a..8510da29a40 100644 --- a/packages/logging/src/v2/metrics_service_v2_client.js +++ b/packages/logging/src/v2/metrics_service_v2_client.js @@ -99,9 +99,7 @@ function MetricsServiceV2Client(gaxGrpc, grpcClients, opts) { var self = this; this.auth = gaxGrpc.auth; - var metricsServiceV2Stub = gaxGrpc.createStub( - grpcClients.google.logging.v2.MetricsServiceV2, - opts); + var metricsServiceV2StubMethods = [ 'listLogMetrics', 'getLogMetric', @@ -109,17 +107,86 @@ function MetricsServiceV2Client(gaxGrpc, grpcClients, opts) { 'updateLogMetric', 'deleteLogMetric' ]; + + var metricsServiceV2Stub; + metricsServiceV2StubMethods.forEach(function(methodName) { - self['_' + methodName] = gax.createApiCall( - metricsServiceV2Stub.then(function(metricsServiceV2Stub) { - return function() { - var args = Array.prototype.slice.call(arguments, 0); - return metricsServiceV2Stub[methodName].apply(metricsServiceV2Stub, args); - }; - }), - defaults[methodName], - PAGE_DESCRIPTORS[methodName]); + self['_' + methodName] = function() { + var args = [].slice.call(arguments); + var cb; + + if (typeof args[args.length - 1] === 'function') { + cb = args.pop(); + } + + var promise = getStub().then(function(stub) { + var apiCall = gax.createApiCall( + metricsServiceV2Stub.then(function(metricsServiceV2Stub) { + return function() { + var args = Array.prototype.slice.call(arguments, 0); + var reqOpts = args[0]; + + try { + reqOpts = replaceProjectIdToken(reqOpts, self.auth.projectId); + } catch(e) { + var callback = args[args.length - 1]; + callback(e); + return; + } + + return metricsServiceV2Stub[methodName].apply(metricsServiceV2Stub, args); + }; + }), + defaults[methodName], + PAGE_DESCRIPTORS[methodName]); + + return apiCall.apply(self, args); + }); + + if (!cb) { + return promise; + } + + promise.then(cb.bind(null, null), cb); + }; }); + + function getStub() { + if (metricsServiceV2Stub) { + return Promise.resolve(metricsServiceV2Stub); + } + + metricsServiceV2Stub = gaxGrpc.createStub( + grpcClients.google.logging.v2.MetricsServiceV2, opts); + + return metricsServiceV2Stub; + } + + function replaceProjectIdToken(value, projectId) { + if (Array.isArray(value)) { + value = value.map(function(val) { + return replaceProjectIdToken(val, projectId); + }); + } + + if (value && typeof value === 'object' && typeof value.hasOwnProperty === 'function') { + for (var opt in value) { + if (value.hasOwnProperty(opt)) { + value[opt] = replaceProjectIdToken(value[opt], projectId); + } + } + } + + if (typeof value === 'string' && value.indexOf('{{projectId}}') > -1) { + if (!projectId) { + throw new Error('Sorry, we cannot connect to Cloud Services without a project ID.'); + } + + value = value.replace(/{{projectId}}/g, projectId); + } + + return value; + } } // Path templates diff --git a/packages/logging/system-test/logging.js b/packages/logging/system-test/logging.js index cc6b8a4aaae..db7ce0ef02a 100644 --- a/packages/logging/system-test/logging.js +++ b/packages/logging/system-test/logging.js @@ -47,6 +47,7 @@ describe('Logging', function() { before(function(done) { async.parallel([ + deleteSinks, bucket.create.bind(bucket), dataset.create.bind(dataset), topic.create.bind(topic) @@ -60,57 +61,6 @@ describe('Logging', function() { deleteTopics, deleteSinks ], done); - - function deleteBuckets(callback) { - storage.getBuckets({ - prefix: TESTS_PREFIX - }, function(err, buckets) { - if (err) { - done(err); - return; - } - - function deleteBucket(bucket, callback) { - bucket.deleteFiles(function(err) { - if (err) { - callback(err); - return; - } - - bucket.delete(callback); - }); - } - - async.each(buckets, deleteBucket, callback); - }); - } - - function deleteDatasets(callback) { - getAndDelete(bigQuery.getDatasets.bind(bigQuery), callback); - } - - function deleteTopics(callback) { - getAndDelete(pubsub.getTopics.bind(pubsub), callback); - } - - function deleteSinks(callback) { - getAndDelete(logging.getSinks.bind(logging), callback); - } - - function getAndDelete(method, callback) { - method(function(err, objects) { - if (err) { - callback(err); - return; - } - - objects = objects.filter(function(object) { - return (object.name || object.id).indexOf(TESTS_PREFIX) === 0; - }); - - async.each(objects, exec('delete'), callback); - }); - } }); describe('sinks', function() { @@ -541,4 +491,55 @@ describe('Logging', function() { function generateName() { return TESTS_PREFIX + uuid.v1(); } + + function deleteBuckets(callback) { + storage.getBuckets({ + prefix: TESTS_PREFIX + }, function(err, buckets) { + if (err) { + done(err); + return; + } + + function deleteBucket(bucket, callback) { + bucket.deleteFiles(function(err) { + if (err) { + callback(err); + return; + } + + bucket.delete(callback); + }); + } + + async.each(buckets, deleteBucket, callback); + }); + } + + function deleteDatasets(callback) { + getAndDelete(bigQuery.getDatasets.bind(bigQuery), callback); + } + + function deleteTopics(callback) { + getAndDelete(pubsub.getTopics.bind(pubsub), callback); + } + + function deleteSinks(callback) { + getAndDelete(logging.getSinks.bind(logging), callback); + } + + function getAndDelete(method, callback) { + method(function(err, objects) { + if (err) { + callback(err); + return; + } + + objects = objects.filter(function(object) { + return (object.name || object.id).indexOf(TESTS_PREFIX) === 0; + }); + + async.each(objects, exec('delete'), callback); + }); + } });