From d93eea48a906069d46b0b7b62afe47f4c52e1a7c Mon Sep 17 00:00:00 2001 From: Alexander Fenster Date: Thu, 5 Mar 2020 13:49:16 -0800 Subject: [PATCH] feat: deferred initialization (#317) --- .../big_query_storage_client.ts.baseline | 74 ++++++--- ...apic-big_query_storage-v1beta1.ts.baseline | 36 +++++ .../dlp/src/v2/dlp_service_client.ts.baseline | 129 ++++++++++++---- .../dlp/test/gapic-dlp_service-v2.ts.baseline | 140 ++++++++++++++++++ .../key_management_service_client.ts.baseline | 98 +++++++++--- ...apic-key_management_service-v1.ts.baseline | 108 ++++++++++++++ .../alert_policy_service_client.ts.baseline | 119 +++++++++------ .../src/v3/group_service_client.ts.baseline | 123 +++++++++------ .../src/v3/metric_service_client.ts.baseline | 140 +++++++++++------- ...ication_channel_service_client.ts.baseline | 127 ++++++++++------ ...vice_monitoring_service_client.ts.baseline | 127 ++++++++++------ .../uptime_check_service_client.ts.baseline | 123 +++++++++------ .../gapic-alert_policy_service-v3.ts.baseline | 36 +++++ .../test/gapic-group_service-v3.ts.baseline | 40 +++++ .../test/gapic-metric_service-v3.ts.baseline | 48 ++++++ ...otification_channel_service-v3.ts.baseline | 56 +++++++ ...-service_monitoring_service-v3.ts.baseline | 56 +++++++ .../gapic-uptime_check_service-v3.ts.baseline | 40 +++++ .../v1beta1/cloud_redis_client.ts.baseline | 98 ++++++++---- .../gapic-cloud_redis-v1beta1.ts.baseline | 48 ++++++ .../src/v1beta1/echo_client.ts.baseline | 105 ++++++++----- .../src/v1beta1/identity_client.ts.baseline | 85 +++++++---- .../src/v1beta1/messaging_client.ts.baseline | 115 +++++++++----- .../src/v1beta1/testing_client.ts.baseline | 91 ++++++++---- .../test/gapic-echo-v1beta1.ts.baseline | 40 +++++ .../test/gapic-identity-v1beta1.ts.baseline | 36 +++++ .../test/gapic-messaging-v1beta1.ts.baseline | 68 +++++++++ .../test/gapic-testing-v1beta1.ts.baseline | 48 ++++++ .../src/v1/text_to_speech_client.ts.baseline | 65 +++++--- .../test/gapic-text_to_speech-v1.ts.baseline | 24 +++ .../translation_service_client.ts.baseline | 92 ++++++++---- ...ic-translation_service-v3beta1.ts.baseline | 48 ++++++ .../src/$version/$service_client.ts.njk | 88 +++++++---- .../test/gapic-$service-$version.ts.njk | 36 +++++ 34 files changed, 2150 insertions(+), 557 deletions(-) diff --git a/baselines/bigquery-storage/src/v1beta1/big_query_storage_client.ts.baseline b/baselines/bigquery-storage/src/v1beta1/big_query_storage_client.ts.baseline index 1293d8e8d..3a52b7766 100644 --- a/baselines/bigquery-storage/src/v1beta1/big_query_storage_client.ts.baseline +++ b/baselines/bigquery-storage/src/v1beta1/big_query_storage_client.ts.baseline @@ -37,8 +37,13 @@ export class BigQueryStorageClient { private _innerApiCalls: {[name: string]: Function}; private _pathTemplates: {[name: string]: gax.PathTemplate}; private _terminated = false; + private _opts: ClientOptions; + private _gaxModule: typeof gax | typeof gax.fallback; + private _gaxGrpc: gax.GrpcClient | gax.fallback.GrpcClient; + private _protos: {}; + private _defaults: {[method: string]: gax.CallSettings}; auth: gax.GoogleAuth; - bigQueryStorageStub: Promise<{[name: string]: Function}>; + bigQueryStorageStub?: Promise<{[name: string]: Function}>; /** * Construct an instance of BigQueryStorageClient. @@ -89,28 +94,31 @@ export class BigQueryStorageClient { // If we are in browser, we are already using fallback because of the // "browser" field in package.json. // But if we were explicitly requested to use fallback, let's do it now. - const gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; + this._gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; // Create a `gaxGrpc` object, with any grpc-specific options // sent to the client. opts.scopes = (this.constructor as typeof BigQueryStorageClient).scopes; - const gaxGrpc = new gaxModule.GrpcClient(opts); + this._gaxGrpc = new this._gaxModule.GrpcClient(opts); + + // Save options to use in initialize() method. + this._opts = opts; // Save the auth object to the client, for use by other methods. - this.auth = (gaxGrpc.auth as gax.GoogleAuth); + this.auth = (this._gaxGrpc.auth as gax.GoogleAuth); // Determine the client header string. const clientHeader = [ - `gax/${gaxModule.version}`, + `gax/${this._gaxModule.version}`, `gapic/${version}`, ]; if (typeof process !== 'undefined' && 'versions' in process) { clientHeader.push(`gl-node/${process.versions.node}`); } else { - clientHeader.push(`gl-web/${gaxModule.version}`); + clientHeader.push(`gl-web/${this._gaxModule.version}`); } if (!opts.fallback) { - clientHeader.push(`grpc/${gaxGrpc.grpcVersion}`); + clientHeader.push(`grpc/${this._gaxGrpc.grpcVersion}`); } if (opts.libName && opts.libVersion) { clientHeader.push(`${opts.libName}/${opts.libVersion}`); @@ -120,7 +128,7 @@ export class BigQueryStorageClient { // For browsers, pass the JSON content. const nodejsProtoPath = path.join(__dirname, '..', '..', 'protos', 'protos.json'); - const protos = gaxGrpc.loadProto( + this._protos = this._gaxGrpc.loadProto( opts.fallback ? require("../../protos/protos.json") : nodejsProtoPath @@ -130,10 +138,10 @@ export class BigQueryStorageClient { // identifiers to uniquely identify resources within the API. // Create useful helper objects for these. this._pathTemplates = { - readSessionPathTemplate: new gaxModule.PathTemplate( + readSessionPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/locations/{location}/sessions/{session}' ), - streamPathTemplate: new gaxModule.PathTemplate( + streamPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/locations/{location}/streams/{stream}' ), }; @@ -141,11 +149,11 @@ export class BigQueryStorageClient { // Some of the methods on this service provide streaming responses. // Provide descriptors for these. this._descriptors.stream = { - readRows: new gaxModule.StreamDescriptor(gax.StreamType.SERVER_STREAMING) + readRows: new this._gaxModule.StreamDescriptor(gax.StreamType.SERVER_STREAMING) }; // Put together the default options sent with requests. - const defaults = gaxGrpc.constructSettings( + this._defaults = this._gaxGrpc.constructSettings( 'google.cloud.bigquery.storage.v1beta1.BigQueryStorage', gapicConfig as gax.ClientConfig, opts.clientConfig || {}, {'x-goog-api-client': clientHeader.join(' ')}); @@ -153,15 +161,33 @@ export class BigQueryStorageClient { // of calling the API is handled in `google-gax`, with this code // merely providing the destination and request information. this._innerApiCalls = {}; + } + + /** + * Initialize the client. + * Performs asynchronous operations (such as authentication) and prepares the client. + * This function will be called automatically when any class method is called for the + * first time, but if you need to initialize it before calling an actual method, + * feel free to call initialize() directly. + * + * You can await on this method if you want to make sure the client is initialized. + * + * @returns {Promise} A promise that resolves to an authenticated service stub. + */ + initialize() { + // If the client stub promise is already initialized, return immediately. + if (this.bigQueryStorageStub) { + return this.bigQueryStorageStub; + } // Put together the "service stub" for // google.cloud.bigquery.storage.v1beta1.BigQueryStorage. - this.bigQueryStorageStub = gaxGrpc.createStub( - opts.fallback ? - (protos as protobuf.Root).lookupService('google.cloud.bigquery.storage.v1beta1.BigQueryStorage') : + this.bigQueryStorageStub = this._gaxGrpc.createStub( + this._opts.fallback ? + (this._protos as protobuf.Root).lookupService('google.cloud.bigquery.storage.v1beta1.BigQueryStorage') : // tslint:disable-next-line no-any - (protos as any).google.cloud.bigquery.storage.v1beta1.BigQueryStorage, - opts) as Promise<{[method: string]: Function}>; + (this._protos as any).google.cloud.bigquery.storage.v1beta1.BigQueryStorage, + this._opts) as Promise<{[method: string]: Function}>; // Iterate over each of the methods that the service provides // and create an API call method for each. @@ -180,9 +206,9 @@ export class BigQueryStorageClient { throw err; }); - const apiCall = gaxModule.createApiCall( + const apiCall = this._gaxModule.createApiCall( innerCallPromise, - defaults[methodName], + this._defaults[methodName], this._descriptors.page[methodName] || this._descriptors.stream[methodName] || this._descriptors.longrunning[methodName] @@ -196,6 +222,8 @@ export class BigQueryStorageClient { return apiCall(argument, callOptions, callback); }; } + + return this.bigQueryStorageStub; } /** @@ -341,6 +369,7 @@ export class BigQueryStorageClient { 'table_reference.project_id': request.tableReference!.projectId || '', 'table_reference.dataset_id': request.tableReference!.datasetId || '', }); + this.initialize(); return this._innerApiCalls.createReadSession(request, options, callback); } batchCreateReadSessionStreams( @@ -407,6 +436,7 @@ export class BigQueryStorageClient { ] = gax.routingHeader.fromParams({ 'session.name': request.session!.name || '', }); + this.initialize(); return this._innerApiCalls.batchCreateReadSessionStreams(request, options, callback); } finalizeStream( @@ -479,6 +509,7 @@ export class BigQueryStorageClient { ] = gax.routingHeader.fromParams({ 'stream.name': request.stream!.name || '', }); + this.initialize(); return this._innerApiCalls.finalizeStream(request, options, callback); } splitReadStream( @@ -558,6 +589,7 @@ export class BigQueryStorageClient { ] = gax.routingHeader.fromParams({ 'original_stream.name': request.originalStream!.name || '', }); + this.initialize(); return this._innerApiCalls.splitReadStream(request, options, callback); } @@ -596,6 +628,7 @@ export class BigQueryStorageClient { ] = gax.routingHeader.fromParams({ 'read_position.stream.name': request.readPosition!.stream!.name || '', }); + this.initialize(); return this._innerApiCalls.readRows(request, options); } @@ -707,8 +740,9 @@ export class BigQueryStorageClient { * The client will no longer be usable and all future behavior is undefined. */ close(): Promise { + this.initialize(); if (!this._terminated) { - return this.bigQueryStorageStub.then(stub => { + return this.bigQueryStorageStub!.then(stub => { this._terminated = true; stub.close(); }); diff --git a/baselines/bigquery-storage/test/gapic-big_query_storage-v1beta1.ts.baseline b/baselines/bigquery-storage/test/gapic-big_query_storage-v1beta1.ts.baseline index f21cc6581..7d9f3e076 100644 --- a/baselines/bigquery-storage/test/gapic-big_query_storage-v1beta1.ts.baseline +++ b/baselines/bigquery-storage/test/gapic-big_query_storage-v1beta1.ts.baseline @@ -97,12 +97,30 @@ describe('v1beta1.BigQueryStorageClient', () => { }); assert(client); }); + it('has initialize method and supports deferred initialization', async () => { + const client = new bigquerystorageModule.v1beta1.BigQueryStorageClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + assert.strictEqual(client.bigQueryStorageStub, undefined); + await client.initialize(); + assert(client.bigQueryStorageStub); + }); + it('has close method', () => { + const client = new bigquerystorageModule.v1beta1.BigQueryStorageClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + client.close(); + }); describe('createReadSession', () => { it('invokes createReadSession without error', done => { const client = new bigquerystorageModule.v1beta1.BigQueryStorageClient({ credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.bigquery.storage.v1beta1.ICreateReadSessionRequest = {}; request.tableReference = {}; @@ -129,6 +147,8 @@ describe('v1beta1.BigQueryStorageClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.bigquery.storage.v1beta1.ICreateReadSessionRequest = {}; request.tableReference = {}; @@ -157,6 +177,8 @@ describe('v1beta1.BigQueryStorageClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.bigquery.storage.v1beta1.IBatchCreateReadSessionStreamsRequest = {}; request.session = {}; @@ -181,6 +203,8 @@ describe('v1beta1.BigQueryStorageClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.bigquery.storage.v1beta1.IBatchCreateReadSessionStreamsRequest = {}; request.session = {}; @@ -207,6 +231,8 @@ describe('v1beta1.BigQueryStorageClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.bigquery.storage.v1beta1.IFinalizeStreamRequest = {}; request.stream = {}; @@ -231,6 +257,8 @@ describe('v1beta1.BigQueryStorageClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.bigquery.storage.v1beta1.IFinalizeStreamRequest = {}; request.stream = {}; @@ -257,6 +285,8 @@ describe('v1beta1.BigQueryStorageClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.bigquery.storage.v1beta1.ISplitReadStreamRequest = {}; request.originalStream = {}; @@ -281,6 +311,8 @@ describe('v1beta1.BigQueryStorageClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.bigquery.storage.v1beta1.ISplitReadStreamRequest = {}; request.originalStream = {}; @@ -307,6 +339,8 @@ describe('v1beta1.BigQueryStorageClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.bigquery.storage.v1beta1.IReadRowsRequest = {}; request.readPosition = {}; @@ -331,6 +365,8 @@ describe('v1beta1.BigQueryStorageClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.bigquery.storage.v1beta1.IReadRowsRequest = {}; request.readPosition = {}; diff --git a/baselines/dlp/src/v2/dlp_service_client.ts.baseline b/baselines/dlp/src/v2/dlp_service_client.ts.baseline index 17e89de52..fe2de3f28 100644 --- a/baselines/dlp/src/v2/dlp_service_client.ts.baseline +++ b/baselines/dlp/src/v2/dlp_service_client.ts.baseline @@ -44,8 +44,13 @@ export class DlpServiceClient { private _innerApiCalls: {[name: string]: Function}; private _pathTemplates: {[name: string]: gax.PathTemplate}; private _terminated = false; + private _opts: ClientOptions; + private _gaxModule: typeof gax | typeof gax.fallback; + private _gaxGrpc: gax.GrpcClient | gax.fallback.GrpcClient; + private _protos: {}; + private _defaults: {[method: string]: gax.CallSettings}; auth: gax.GoogleAuth; - dlpServiceStub: Promise<{[name: string]: Function}>; + dlpServiceStub?: Promise<{[name: string]: Function}>; /** * Construct an instance of DlpServiceClient. @@ -96,28 +101,31 @@ export class DlpServiceClient { // If we are in browser, we are already using fallback because of the // "browser" field in package.json. // But if we were explicitly requested to use fallback, let's do it now. - const gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; + this._gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; // Create a `gaxGrpc` object, with any grpc-specific options // sent to the client. opts.scopes = (this.constructor as typeof DlpServiceClient).scopes; - const gaxGrpc = new gaxModule.GrpcClient(opts); + this._gaxGrpc = new this._gaxModule.GrpcClient(opts); + + // Save options to use in initialize() method. + this._opts = opts; // Save the auth object to the client, for use by other methods. - this.auth = (gaxGrpc.auth as gax.GoogleAuth); + this.auth = (this._gaxGrpc.auth as gax.GoogleAuth); // Determine the client header string. const clientHeader = [ - `gax/${gaxModule.version}`, + `gax/${this._gaxModule.version}`, `gapic/${version}`, ]; if (typeof process !== 'undefined' && 'versions' in process) { clientHeader.push(`gl-node/${process.versions.node}`); } else { - clientHeader.push(`gl-web/${gaxModule.version}`); + clientHeader.push(`gl-web/${this._gaxModule.version}`); } if (!opts.fallback) { - clientHeader.push(`grpc/${gaxGrpc.grpcVersion}`); + clientHeader.push(`grpc/${this._gaxGrpc.grpcVersion}`); } if (opts.libName && opts.libVersion) { clientHeader.push(`${opts.libName}/${opts.libVersion}`); @@ -127,7 +135,7 @@ export class DlpServiceClient { // For browsers, pass the JSON content. const nodejsProtoPath = path.join(__dirname, '..', '..', 'protos', 'protos.json'); - const protos = gaxGrpc.loadProto( + this._protos = this._gaxGrpc.loadProto( opts.fallback ? require("../../protos/protos.json") : nodejsProtoPath @@ -137,34 +145,34 @@ export class DlpServiceClient { // identifiers to uniquely identify resources within the API. // Create useful helper objects for these. this._pathTemplates = { - dlpJobPathTemplate: new gaxModule.PathTemplate( + dlpJobPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/dlpJobs/{dlp_job}' ), - jobTriggerPathTemplate: new gaxModule.PathTemplate( + jobTriggerPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/jobTriggers/{job_trigger}' ), - organizationPathTemplate: new gaxModule.PathTemplate( + organizationPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}' ), - organizationDeidentifyTemplatePathTemplate: new gaxModule.PathTemplate( + organizationDeidentifyTemplatePathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/deidentifyTemplates/{deidentify_template}' ), - organizationInspectTemplatePathTemplate: new gaxModule.PathTemplate( + organizationInspectTemplatePathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/inspectTemplates/{inspect_template}' ), - organizationStoredInfoTypePathTemplate: new gaxModule.PathTemplate( + organizationStoredInfoTypePathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/storedInfoTypes/{stored_info_type}' ), - projectPathTemplate: new gaxModule.PathTemplate( + projectPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}' ), - projectDeidentifyTemplatePathTemplate: new gaxModule.PathTemplate( + projectDeidentifyTemplatePathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/deidentifyTemplates/{deidentify_template}' ), - projectInspectTemplatePathTemplate: new gaxModule.PathTemplate( + projectInspectTemplatePathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/inspectTemplates/{inspect_template}' ), - projectStoredInfoTypePathTemplate: new gaxModule.PathTemplate( + projectStoredInfoTypePathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/storedInfoTypes/{stored_info_type}' ), }; @@ -174,19 +182,19 @@ export class DlpServiceClient { // pages). Denote the keys used for pagination and results. this._descriptors.page = { listInspectTemplates: - new gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'inspectTemplates'), + new this._gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'inspectTemplates'), listDeidentifyTemplates: - new gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'deidentifyTemplates'), + new this._gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'deidentifyTemplates'), listJobTriggers: - new gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'jobTriggers'), + new this._gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'jobTriggers'), listDlpJobs: - new gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'jobs'), + new this._gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'jobs'), listStoredInfoTypes: - new gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'storedInfoTypes') + new this._gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'storedInfoTypes') }; // Put together the default options sent with requests. - const defaults = gaxGrpc.constructSettings( + this._defaults = this._gaxGrpc.constructSettings( 'google.privacy.dlp.v2.DlpService', gapicConfig as gax.ClientConfig, opts.clientConfig || {}, {'x-goog-api-client': clientHeader.join(' ')}); @@ -194,15 +202,33 @@ export class DlpServiceClient { // of calling the API is handled in `google-gax`, with this code // merely providing the destination and request information. this._innerApiCalls = {}; + } + + /** + * Initialize the client. + * Performs asynchronous operations (such as authentication) and prepares the client. + * This function will be called automatically when any class method is called for the + * first time, but if you need to initialize it before calling an actual method, + * feel free to call initialize() directly. + * + * You can await on this method if you want to make sure the client is initialized. + * + * @returns {Promise} A promise that resolves to an authenticated service stub. + */ + initialize() { + // If the client stub promise is already initialized, return immediately. + if (this.dlpServiceStub) { + return this.dlpServiceStub; + } // Put together the "service stub" for // google.privacy.dlp.v2.DlpService. - this.dlpServiceStub = gaxGrpc.createStub( - opts.fallback ? - (protos as protobuf.Root).lookupService('google.privacy.dlp.v2.DlpService') : + this.dlpServiceStub = this._gaxGrpc.createStub( + this._opts.fallback ? + (this._protos as protobuf.Root).lookupService('google.privacy.dlp.v2.DlpService') : // tslint:disable-next-line no-any - (protos as any).google.privacy.dlp.v2.DlpService, - opts) as Promise<{[method: string]: Function}>; + (this._protos as any).google.privacy.dlp.v2.DlpService, + this._opts) as Promise<{[method: string]: Function}>; // Iterate over each of the methods that the service provides // and create an API call method for each. @@ -221,9 +247,9 @@ export class DlpServiceClient { throw err; }); - const apiCall = gaxModule.createApiCall( + const apiCall = this._gaxModule.createApiCall( innerCallPromise, - defaults[methodName], + this._defaults[methodName], this._descriptors.page[methodName] || this._descriptors.stream[methodName] || this._descriptors.longrunning[methodName] @@ -237,6 +263,8 @@ export class DlpServiceClient { return apiCall(argument, callOptions, callback); }; } + + return this.dlpServiceStub; } /** @@ -369,6 +397,7 @@ export class DlpServiceClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.inspectContent(request, options, callback); } redactImage( @@ -447,6 +476,7 @@ export class DlpServiceClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.redactImage(request, options, callback); } deidentifyContent( @@ -538,6 +568,7 @@ export class DlpServiceClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.deidentifyContent(request, options, callback); } reidentifyContent( @@ -631,6 +662,7 @@ export class DlpServiceClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.reidentifyContent(request, options, callback); } listInfoTypes( @@ -693,6 +725,7 @@ export class DlpServiceClient { options = optionsOrCallback as gax.CallOptions; } options = options || {}; + this.initialize(); return this._innerApiCalls.listInfoTypes(request, options, callback); } createInspectTemplate( @@ -765,6 +798,7 @@ export class DlpServiceClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.createInspectTemplate(request, options, callback); } updateInspectTemplate( @@ -831,6 +865,7 @@ export class DlpServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.updateInspectTemplate(request, options, callback); } getInspectTemplate( @@ -893,6 +928,7 @@ export class DlpServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.getInspectTemplate(request, options, callback); } deleteInspectTemplate( @@ -955,6 +991,7 @@ export class DlpServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.deleteInspectTemplate(request, options, callback); } createDeidentifyTemplate( @@ -1028,6 +1065,7 @@ export class DlpServiceClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.createDeidentifyTemplate(request, options, callback); } updateDeidentifyTemplate( @@ -1095,6 +1133,7 @@ export class DlpServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.updateDeidentifyTemplate(request, options, callback); } getDeidentifyTemplate( @@ -1158,6 +1197,7 @@ export class DlpServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.getDeidentifyTemplate(request, options, callback); } deleteDeidentifyTemplate( @@ -1221,6 +1261,7 @@ export class DlpServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.deleteDeidentifyTemplate(request, options, callback); } createJobTrigger( @@ -1292,6 +1333,7 @@ export class DlpServiceClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.createJobTrigger(request, options, callback); } updateJobTrigger( @@ -1357,6 +1399,7 @@ export class DlpServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.updateJobTrigger(request, options, callback); } getJobTrigger( @@ -1418,6 +1461,7 @@ export class DlpServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.getJobTrigger(request, options, callback); } deleteJobTrigger( @@ -1479,6 +1523,7 @@ export class DlpServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.deleteJobTrigger(request, options, callback); } activateJobTrigger( @@ -1540,6 +1585,7 @@ export class DlpServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.activateJobTrigger(request, options, callback); } createDlpJob( @@ -1617,6 +1663,7 @@ export class DlpServiceClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.createDlpJob(request, options, callback); } getDlpJob( @@ -1678,6 +1725,7 @@ export class DlpServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.getDlpJob(request, options, callback); } deleteDlpJob( @@ -1741,6 +1789,7 @@ export class DlpServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.deleteDlpJob(request, options, callback); } cancelDlpJob( @@ -1804,6 +1853,7 @@ export class DlpServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.cancelDlpJob(request, options, callback); } createStoredInfoType( @@ -1876,6 +1926,7 @@ export class DlpServiceClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.createStoredInfoType(request, options, callback); } updateStoredInfoType( @@ -1946,6 +1997,7 @@ export class DlpServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.updateStoredInfoType(request, options, callback); } getStoredInfoType( @@ -2009,6 +2061,7 @@ export class DlpServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.getStoredInfoType(request, options, callback); } deleteStoredInfoType( @@ -2072,6 +2125,7 @@ export class DlpServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.deleteStoredInfoType(request, options, callback); } @@ -2172,6 +2226,7 @@ export class DlpServiceClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.listInspectTemplates(request, options, callback); } @@ -2235,6 +2290,7 @@ export class DlpServiceClient { 'parent': request.parent || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listInspectTemplates.createStream( this._innerApiCalls.listInspectTemplates as gax.GaxCall, request, @@ -2339,6 +2395,7 @@ export class DlpServiceClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.listDeidentifyTemplates(request, options, callback); } @@ -2402,6 +2459,7 @@ export class DlpServiceClient { 'parent': request.parent || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listDeidentifyTemplates.createStream( this._innerApiCalls.listDeidentifyTemplates as gax.GaxCall, request, @@ -2531,6 +2589,7 @@ export class DlpServiceClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.listJobTriggers(request, options, callback); } @@ -2620,6 +2679,7 @@ export class DlpServiceClient { 'parent': request.parent || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listJobTriggers.createStream( this._innerApiCalls.listJobTriggers as gax.GaxCall, request, @@ -2752,6 +2812,7 @@ export class DlpServiceClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.listDlpJobs(request, options, callback); } @@ -2843,6 +2904,7 @@ export class DlpServiceClient { 'parent': request.parent || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listDlpJobs.createStream( this._innerApiCalls.listDlpJobs as gax.GaxCall, request, @@ -2948,6 +3010,7 @@ export class DlpServiceClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.listStoredInfoTypes(request, options, callback); } @@ -3012,6 +3075,7 @@ export class DlpServiceClient { 'parent': request.parent || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listStoredInfoTypes.createStream( this._innerApiCalls.listStoredInfoTypes as gax.GaxCall, request, @@ -3362,8 +3426,9 @@ export class DlpServiceClient { * The client will no longer be usable and all future behavior is undefined. */ close(): Promise { + this.initialize(); if (!this._terminated) { - return this.dlpServiceStub.then(stub => { + return this.dlpServiceStub!.then(stub => { this._terminated = true; stub.close(); }); diff --git a/baselines/dlp/test/gapic-dlp_service-v2.ts.baseline b/baselines/dlp/test/gapic-dlp_service-v2.ts.baseline index 3d9f65d0e..54c9ad3a0 100644 --- a/baselines/dlp/test/gapic-dlp_service-v2.ts.baseline +++ b/baselines/dlp/test/gapic-dlp_service-v2.ts.baseline @@ -78,12 +78,30 @@ describe('v2.DlpServiceClient', () => { }); assert(client); }); + it('has initialize method and supports deferred initialization', async () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + assert.strictEqual(client.dlpServiceStub, undefined); + await client.initialize(); + assert(client.dlpServiceStub); + }); + it('has close method', () => { + const client = new dlpserviceModule.v2.DlpServiceClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + client.close(); + }); describe('inspectContent', () => { it('invokes inspectContent without error', done => { const client = new dlpserviceModule.v2.DlpServiceClient({ credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IInspectContentRequest = {}; request.parent = ''; @@ -107,6 +125,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IInspectContentRequest = {}; request.parent = ''; @@ -132,6 +152,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IRedactImageRequest = {}; request.parent = ''; @@ -155,6 +177,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IRedactImageRequest = {}; request.parent = ''; @@ -180,6 +204,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IDeidentifyContentRequest = {}; request.parent = ''; @@ -203,6 +229,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IDeidentifyContentRequest = {}; request.parent = ''; @@ -228,6 +256,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IReidentifyContentRequest = {}; request.parent = ''; @@ -251,6 +281,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IReidentifyContentRequest = {}; request.parent = ''; @@ -276,6 +308,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IListInfoTypesRequest = {}; // Mock response @@ -298,6 +332,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IListInfoTypesRequest = {}; // Mock response @@ -322,6 +358,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.ICreateInspectTemplateRequest = {}; request.parent = ''; @@ -345,6 +383,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.ICreateInspectTemplateRequest = {}; request.parent = ''; @@ -370,6 +410,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IUpdateInspectTemplateRequest = {}; request.name = ''; @@ -393,6 +435,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IUpdateInspectTemplateRequest = {}; request.name = ''; @@ -418,6 +462,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IGetInspectTemplateRequest = {}; request.name = ''; @@ -441,6 +487,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IGetInspectTemplateRequest = {}; request.name = ''; @@ -466,6 +514,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IDeleteInspectTemplateRequest = {}; request.name = ''; @@ -489,6 +539,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IDeleteInspectTemplateRequest = {}; request.name = ''; @@ -514,6 +566,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.ICreateDeidentifyTemplateRequest = {}; request.parent = ''; @@ -537,6 +591,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.ICreateDeidentifyTemplateRequest = {}; request.parent = ''; @@ -562,6 +618,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IUpdateDeidentifyTemplateRequest = {}; request.name = ''; @@ -585,6 +643,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IUpdateDeidentifyTemplateRequest = {}; request.name = ''; @@ -610,6 +670,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IGetDeidentifyTemplateRequest = {}; request.name = ''; @@ -633,6 +695,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IGetDeidentifyTemplateRequest = {}; request.name = ''; @@ -658,6 +722,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IDeleteDeidentifyTemplateRequest = {}; request.name = ''; @@ -681,6 +747,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IDeleteDeidentifyTemplateRequest = {}; request.name = ''; @@ -706,6 +774,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.ICreateJobTriggerRequest = {}; request.parent = ''; @@ -729,6 +799,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.ICreateJobTriggerRequest = {}; request.parent = ''; @@ -754,6 +826,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IUpdateJobTriggerRequest = {}; request.name = ''; @@ -777,6 +851,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IUpdateJobTriggerRequest = {}; request.name = ''; @@ -802,6 +878,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IGetJobTriggerRequest = {}; request.name = ''; @@ -825,6 +903,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IGetJobTriggerRequest = {}; request.name = ''; @@ -850,6 +930,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IDeleteJobTriggerRequest = {}; request.name = ''; @@ -873,6 +955,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IDeleteJobTriggerRequest = {}; request.name = ''; @@ -898,6 +982,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IActivateJobTriggerRequest = {}; request.name = ''; @@ -921,6 +1007,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IActivateJobTriggerRequest = {}; request.name = ''; @@ -946,6 +1034,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.ICreateDlpJobRequest = {}; request.parent = ''; @@ -969,6 +1059,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.ICreateDlpJobRequest = {}; request.parent = ''; @@ -994,6 +1086,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IGetDlpJobRequest = {}; request.name = ''; @@ -1017,6 +1111,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IGetDlpJobRequest = {}; request.name = ''; @@ -1042,6 +1138,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IDeleteDlpJobRequest = {}; request.name = ''; @@ -1065,6 +1163,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IDeleteDlpJobRequest = {}; request.name = ''; @@ -1090,6 +1190,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.ICancelDlpJobRequest = {}; request.name = ''; @@ -1113,6 +1215,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.ICancelDlpJobRequest = {}; request.name = ''; @@ -1138,6 +1242,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.ICreateStoredInfoTypeRequest = {}; request.parent = ''; @@ -1161,6 +1267,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.ICreateStoredInfoTypeRequest = {}; request.parent = ''; @@ -1186,6 +1294,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IUpdateStoredInfoTypeRequest = {}; request.name = ''; @@ -1209,6 +1319,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IUpdateStoredInfoTypeRequest = {}; request.name = ''; @@ -1234,6 +1346,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IGetStoredInfoTypeRequest = {}; request.name = ''; @@ -1257,6 +1371,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IGetStoredInfoTypeRequest = {}; request.name = ''; @@ -1282,6 +1398,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IDeleteStoredInfoTypeRequest = {}; request.name = ''; @@ -1305,6 +1423,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IDeleteStoredInfoTypeRequest = {}; request.name = ''; @@ -1330,6 +1450,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IListInspectTemplatesRequest = {}; request.parent = ''; @@ -1353,6 +1475,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IListInspectTemplatesRequest = {}; request.parent = ''; @@ -1378,6 +1502,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IListDeidentifyTemplatesRequest = {}; request.parent = ''; @@ -1401,6 +1527,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IListDeidentifyTemplatesRequest = {}; request.parent = ''; @@ -1426,6 +1554,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IListJobTriggersRequest = {}; request.parent = ''; @@ -1449,6 +1579,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IListJobTriggersRequest = {}; request.parent = ''; @@ -1474,6 +1606,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IListDlpJobsRequest = {}; request.parent = ''; @@ -1497,6 +1631,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IListDlpJobsRequest = {}; request.parent = ''; @@ -1522,6 +1658,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IListStoredInfoTypesRequest = {}; request.parent = ''; @@ -1545,6 +1683,8 @@ describe('v2.DlpServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.privacy.dlp.v2.IListStoredInfoTypesRequest = {}; request.parent = ''; diff --git a/baselines/kms/src/v1/key_management_service_client.ts.baseline b/baselines/kms/src/v1/key_management_service_client.ts.baseline index 06d1b4407..390aca927 100644 --- a/baselines/kms/src/v1/key_management_service_client.ts.baseline +++ b/baselines/kms/src/v1/key_management_service_client.ts.baseline @@ -45,8 +45,13 @@ export class KeyManagementServiceClient { private _descriptors: Descriptors = {page: {}, stream: {}, longrunning: {}}; private _innerApiCalls: {[name: string]: Function}; private _terminated = false; + private _opts: ClientOptions; + private _gaxModule: typeof gax | typeof gax.fallback; + private _gaxGrpc: gax.GrpcClient | gax.fallback.GrpcClient; + private _protos: {}; + private _defaults: {[method: string]: gax.CallSettings}; auth: gax.GoogleAuth; - keyManagementServiceStub: Promise<{[name: string]: Function}>; + keyManagementServiceStub?: Promise<{[name: string]: Function}>; /** * Construct an instance of KeyManagementServiceClient. @@ -97,28 +102,31 @@ export class KeyManagementServiceClient { // If we are in browser, we are already using fallback because of the // "browser" field in package.json. // But if we were explicitly requested to use fallback, let's do it now. - const gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; + this._gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; // Create a `gaxGrpc` object, with any grpc-specific options // sent to the client. opts.scopes = (this.constructor as typeof KeyManagementServiceClient).scopes; - const gaxGrpc = new gaxModule.GrpcClient(opts); + this._gaxGrpc = new this._gaxModule.GrpcClient(opts); + + // Save options to use in initialize() method. + this._opts = opts; // Save the auth object to the client, for use by other methods. - this.auth = (gaxGrpc.auth as gax.GoogleAuth); + this.auth = (this._gaxGrpc.auth as gax.GoogleAuth); // Determine the client header string. const clientHeader = [ - `gax/${gaxModule.version}`, + `gax/${this._gaxModule.version}`, `gapic/${version}`, ]; if (typeof process !== 'undefined' && 'versions' in process) { clientHeader.push(`gl-node/${process.versions.node}`); } else { - clientHeader.push(`gl-web/${gaxModule.version}`); + clientHeader.push(`gl-web/${this._gaxModule.version}`); } if (!opts.fallback) { - clientHeader.push(`grpc/${gaxGrpc.grpcVersion}`); + clientHeader.push(`grpc/${this._gaxGrpc.grpcVersion}`); } if (opts.libName && opts.libVersion) { clientHeader.push(`${opts.libName}/${opts.libVersion}`); @@ -128,7 +136,7 @@ export class KeyManagementServiceClient { // For browsers, pass the JSON content. const nodejsProtoPath = path.join(__dirname, '..', '..', 'protos', 'protos.json'); - const protos = gaxGrpc.loadProto( + this._protos = this._gaxGrpc.loadProto( opts.fallback ? require("../../protos/protos.json") : nodejsProtoPath @@ -139,17 +147,17 @@ export class KeyManagementServiceClient { // pages). Denote the keys used for pagination and results. this._descriptors.page = { listKeyRings: - new gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'keyRings'), + new this._gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'keyRings'), listCryptoKeys: - new gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'cryptoKeys'), + new this._gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'cryptoKeys'), listCryptoKeyVersions: - new gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'cryptoKeyVersions'), + new this._gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'cryptoKeyVersions'), listImportJobs: - new gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'importJobs') + new this._gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'importJobs') }; // Put together the default options sent with requests. - const defaults = gaxGrpc.constructSettings( + this._defaults = this._gaxGrpc.constructSettings( 'google.cloud.kms.v1.KeyManagementService', gapicConfig as gax.ClientConfig, opts.clientConfig || {}, {'x-goog-api-client': clientHeader.join(' ')}); @@ -157,15 +165,33 @@ export class KeyManagementServiceClient { // of calling the API is handled in `google-gax`, with this code // merely providing the destination and request information. this._innerApiCalls = {}; + } + + /** + * Initialize the client. + * Performs asynchronous operations (such as authentication) and prepares the client. + * This function will be called automatically when any class method is called for the + * first time, but if you need to initialize it before calling an actual method, + * feel free to call initialize() directly. + * + * You can await on this method if you want to make sure the client is initialized. + * + * @returns {Promise} A promise that resolves to an authenticated service stub. + */ + initialize() { + // If the client stub promise is already initialized, return immediately. + if (this.keyManagementServiceStub) { + return this.keyManagementServiceStub; + } // Put together the "service stub" for // google.cloud.kms.v1.KeyManagementService. - this.keyManagementServiceStub = gaxGrpc.createStub( - opts.fallback ? - (protos as protobuf.Root).lookupService('google.cloud.kms.v1.KeyManagementService') : + this.keyManagementServiceStub = this._gaxGrpc.createStub( + this._opts.fallback ? + (this._protos as protobuf.Root).lookupService('google.cloud.kms.v1.KeyManagementService') : // tslint:disable-next-line no-any - (protos as any).google.cloud.kms.v1.KeyManagementService, - opts) as Promise<{[method: string]: Function}>; + (this._protos as any).google.cloud.kms.v1.KeyManagementService, + this._opts) as Promise<{[method: string]: Function}>; // Iterate over each of the methods that the service provides // and create an API call method for each. @@ -184,9 +210,9 @@ export class KeyManagementServiceClient { throw err; }); - const apiCall = gaxModule.createApiCall( + const apiCall = this._gaxModule.createApiCall( innerCallPromise, - defaults[methodName], + this._defaults[methodName], this._descriptors.page[methodName] || this._descriptors.stream[methodName] || this._descriptors.longrunning[methodName] @@ -200,6 +226,8 @@ export class KeyManagementServiceClient { return apiCall(argument, callOptions, callback); }; } + + return this.keyManagementServiceStub; } /** @@ -311,6 +339,7 @@ export class KeyManagementServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.getKeyRing(request, options, callback); } getCryptoKey( @@ -371,6 +400,7 @@ export class KeyManagementServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.getCryptoKey(request, options, callback); } getCryptoKeyVersion( @@ -430,6 +460,7 @@ export class KeyManagementServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.getCryptoKeyVersion(request, options, callback); } getPublicKey( @@ -493,6 +524,7 @@ export class KeyManagementServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.getPublicKey(request, options, callback); } getImportJob( @@ -552,6 +584,7 @@ export class KeyManagementServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.getImportJob(request, options, callback); } createKeyRing( @@ -617,6 +650,7 @@ export class KeyManagementServiceClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.createKeyRing(request, options, callback); } createCryptoKey( @@ -692,6 +726,7 @@ export class KeyManagementServiceClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.createCryptoKey(request, options, callback); } createCryptoKeyVersion( @@ -758,6 +793,7 @@ export class KeyManagementServiceClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.createCryptoKeyVersion(request, options, callback); } importCryptoKeyVersion( @@ -849,6 +885,7 @@ export class KeyManagementServiceClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.importCryptoKeyVersion(request, options, callback); } createImportJob( @@ -916,6 +953,7 @@ export class KeyManagementServiceClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.createImportJob(request, options, callback); } updateCryptoKey( @@ -977,6 +1015,7 @@ export class KeyManagementServiceClient { ] = gax.routingHeader.fromParams({ 'crypto_key.name': request.cryptoKey!.name || '', }); + this.initialize(); return this._innerApiCalls.updateCryptoKey(request, options, callback); } updateCryptoKeyVersion( @@ -1044,6 +1083,7 @@ export class KeyManagementServiceClient { ] = gax.routingHeader.fromParams({ 'crypto_key_version.name': request.cryptoKeyVersion!.name || '', }); + this.initialize(); return this._innerApiCalls.updateCryptoKeyVersion(request, options, callback); } encrypt( @@ -1128,6 +1168,7 @@ export class KeyManagementServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.encrypt(request, options, callback); } decrypt( @@ -1195,6 +1236,7 @@ export class KeyManagementServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.decrypt(request, options, callback); } asymmetricSign( @@ -1260,6 +1302,7 @@ export class KeyManagementServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.asymmetricSign(request, options, callback); } asymmetricDecrypt( @@ -1325,6 +1368,7 @@ export class KeyManagementServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.asymmetricDecrypt(request, options, callback); } updateCryptoKeyPrimaryVersion( @@ -1388,6 +1432,7 @@ export class KeyManagementServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.updateCryptoKeyPrimaryVersion(request, options, callback); } destroyCryptoKeyVersion( @@ -1458,6 +1503,7 @@ export class KeyManagementServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.destroyCryptoKeyVersion(request, options, callback); } restoreCryptoKeyVersion( @@ -1523,6 +1569,7 @@ export class KeyManagementServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.restoreCryptoKeyVersion(request, options, callback); } @@ -1612,6 +1659,7 @@ export class KeyManagementServiceClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.listKeyRings(request, options, callback); } @@ -1665,6 +1713,7 @@ export class KeyManagementServiceClient { 'parent': request.parent || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listKeyRings.createStream( this._innerApiCalls.listKeyRings as gax.GaxCall, request, @@ -1759,6 +1808,7 @@ export class KeyManagementServiceClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.listCryptoKeys(request, options, callback); } @@ -1814,6 +1864,7 @@ export class KeyManagementServiceClient { 'parent': request.parent || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listCryptoKeys.createStream( this._innerApiCalls.listCryptoKeys as gax.GaxCall, request, @@ -1909,6 +1960,7 @@ export class KeyManagementServiceClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.listCryptoKeyVersions(request, options, callback); } @@ -1965,6 +2017,7 @@ export class KeyManagementServiceClient { 'parent': request.parent || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listCryptoKeyVersions.createStream( this._innerApiCalls.listCryptoKeyVersions as gax.GaxCall, request, @@ -2057,6 +2110,7 @@ export class KeyManagementServiceClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.listImportJobs(request, options, callback); } @@ -2110,6 +2164,7 @@ export class KeyManagementServiceClient { 'parent': request.parent || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listImportJobs.createStream( this._innerApiCalls.listImportJobs as gax.GaxCall, request, @@ -2123,8 +2178,9 @@ export class KeyManagementServiceClient { * The client will no longer be usable and all future behavior is undefined. */ close(): Promise { + this.initialize(); if (!this._terminated) { - return this.keyManagementServiceStub.then(stub => { + return this.keyManagementServiceStub!.then(stub => { this._terminated = true; stub.close(); }); diff --git a/baselines/kms/test/gapic-key_management_service-v1.ts.baseline b/baselines/kms/test/gapic-key_management_service-v1.ts.baseline index b15bde0a6..ad4b25ba4 100644 --- a/baselines/kms/test/gapic-key_management_service-v1.ts.baseline +++ b/baselines/kms/test/gapic-key_management_service-v1.ts.baseline @@ -78,12 +78,30 @@ describe('v1.KeyManagementServiceClient', () => { }); assert(client); }); + it('has initialize method and supports deferred initialization', async () => { + const client = new keymanagementserviceModule.v1.KeyManagementServiceClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + assert.strictEqual(client.keyManagementServiceStub, undefined); + await client.initialize(); + assert(client.keyManagementServiceStub); + }); + it('has close method', () => { + const client = new keymanagementserviceModule.v1.KeyManagementServiceClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + client.close(); + }); describe('getKeyRing', () => { it('invokes getKeyRing without error', done => { const client = new keymanagementserviceModule.v1.KeyManagementServiceClient({ credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IGetKeyRingRequest = {}; request.name = ''; @@ -107,6 +125,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IGetKeyRingRequest = {}; request.name = ''; @@ -132,6 +152,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IGetCryptoKeyRequest = {}; request.name = ''; @@ -155,6 +177,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IGetCryptoKeyRequest = {}; request.name = ''; @@ -180,6 +204,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IGetCryptoKeyVersionRequest = {}; request.name = ''; @@ -203,6 +229,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IGetCryptoKeyVersionRequest = {}; request.name = ''; @@ -228,6 +256,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IGetPublicKeyRequest = {}; request.name = ''; @@ -251,6 +281,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IGetPublicKeyRequest = {}; request.name = ''; @@ -276,6 +308,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IGetImportJobRequest = {}; request.name = ''; @@ -299,6 +333,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IGetImportJobRequest = {}; request.name = ''; @@ -324,6 +360,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.ICreateKeyRingRequest = {}; request.parent = ''; @@ -347,6 +385,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.ICreateKeyRingRequest = {}; request.parent = ''; @@ -372,6 +412,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.ICreateCryptoKeyRequest = {}; request.parent = ''; @@ -395,6 +437,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.ICreateCryptoKeyRequest = {}; request.parent = ''; @@ -420,6 +464,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.ICreateCryptoKeyVersionRequest = {}; request.parent = ''; @@ -443,6 +489,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.ICreateCryptoKeyVersionRequest = {}; request.parent = ''; @@ -468,6 +516,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IImportCryptoKeyVersionRequest = {}; request.parent = ''; @@ -491,6 +541,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IImportCryptoKeyVersionRequest = {}; request.parent = ''; @@ -516,6 +568,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.ICreateImportJobRequest = {}; request.parent = ''; @@ -539,6 +593,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.ICreateImportJobRequest = {}; request.parent = ''; @@ -564,6 +620,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IUpdateCryptoKeyRequest = {}; request.cryptoKey = {}; @@ -588,6 +646,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IUpdateCryptoKeyRequest = {}; request.cryptoKey = {}; @@ -614,6 +674,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IUpdateCryptoKeyVersionRequest = {}; request.cryptoKeyVersion = {}; @@ -638,6 +700,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IUpdateCryptoKeyVersionRequest = {}; request.cryptoKeyVersion = {}; @@ -664,6 +728,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IEncryptRequest = {}; request.name = ''; @@ -687,6 +753,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IEncryptRequest = {}; request.name = ''; @@ -712,6 +780,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IDecryptRequest = {}; request.name = ''; @@ -735,6 +805,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IDecryptRequest = {}; request.name = ''; @@ -760,6 +832,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IAsymmetricSignRequest = {}; request.name = ''; @@ -783,6 +857,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IAsymmetricSignRequest = {}; request.name = ''; @@ -808,6 +884,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IAsymmetricDecryptRequest = {}; request.name = ''; @@ -831,6 +909,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IAsymmetricDecryptRequest = {}; request.name = ''; @@ -856,6 +936,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IUpdateCryptoKeyPrimaryVersionRequest = {}; request.name = ''; @@ -879,6 +961,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IUpdateCryptoKeyPrimaryVersionRequest = {}; request.name = ''; @@ -904,6 +988,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IDestroyCryptoKeyVersionRequest = {}; request.name = ''; @@ -927,6 +1013,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IDestroyCryptoKeyVersionRequest = {}; request.name = ''; @@ -952,6 +1040,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IRestoreCryptoKeyVersionRequest = {}; request.name = ''; @@ -975,6 +1065,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IRestoreCryptoKeyVersionRequest = {}; request.name = ''; @@ -1000,6 +1092,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IListKeyRingsRequest = {}; request.parent = ''; @@ -1023,6 +1117,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IListKeyRingsRequest = {}; request.parent = ''; @@ -1048,6 +1144,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IListCryptoKeysRequest = {}; request.parent = ''; @@ -1071,6 +1169,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IListCryptoKeysRequest = {}; request.parent = ''; @@ -1096,6 +1196,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IListCryptoKeyVersionsRequest = {}; request.parent = ''; @@ -1119,6 +1221,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IListCryptoKeyVersionsRequest = {}; request.parent = ''; @@ -1144,6 +1248,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IListImportJobsRequest = {}; request.parent = ''; @@ -1167,6 +1273,8 @@ describe('v1.KeyManagementServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.kms.v1.IListImportJobsRequest = {}; request.parent = ''; diff --git a/baselines/monitoring/src/v3/alert_policy_service_client.ts.baseline b/baselines/monitoring/src/v3/alert_policy_service_client.ts.baseline index 5555a338f..d1e456e4b 100644 --- a/baselines/monitoring/src/v3/alert_policy_service_client.ts.baseline +++ b/baselines/monitoring/src/v3/alert_policy_service_client.ts.baseline @@ -44,8 +44,13 @@ export class AlertPolicyServiceClient { private _innerApiCalls: {[name: string]: Function}; private _pathTemplates: {[name: string]: gax.PathTemplate}; private _terminated = false; + private _opts: ClientOptions; + private _gaxModule: typeof gax | typeof gax.fallback; + private _gaxGrpc: gax.GrpcClient | gax.fallback.GrpcClient; + private _protos: {}; + private _defaults: {[method: string]: gax.CallSettings}; auth: gax.GoogleAuth; - alertPolicyServiceStub: Promise<{[name: string]: Function}>; + alertPolicyServiceStub?: Promise<{[name: string]: Function}>; /** * Construct an instance of AlertPolicyServiceClient. @@ -96,28 +101,31 @@ export class AlertPolicyServiceClient { // If we are in browser, we are already using fallback because of the // "browser" field in package.json. // But if we were explicitly requested to use fallback, let's do it now. - const gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; + this._gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; // Create a `gaxGrpc` object, with any grpc-specific options // sent to the client. opts.scopes = (this.constructor as typeof AlertPolicyServiceClient).scopes; - const gaxGrpc = new gaxModule.GrpcClient(opts); + this._gaxGrpc = new this._gaxModule.GrpcClient(opts); + + // Save options to use in initialize() method. + this._opts = opts; // Save the auth object to the client, for use by other methods. - this.auth = (gaxGrpc.auth as gax.GoogleAuth); + this.auth = (this._gaxGrpc.auth as gax.GoogleAuth); // Determine the client header string. const clientHeader = [ - `gax/${gaxModule.version}`, + `gax/${this._gaxModule.version}`, `gapic/${version}`, ]; if (typeof process !== 'undefined' && 'versions' in process) { clientHeader.push(`gl-node/${process.versions.node}`); } else { - clientHeader.push(`gl-web/${gaxModule.version}`); + clientHeader.push(`gl-web/${this._gaxModule.version}`); } if (!opts.fallback) { - clientHeader.push(`grpc/${gaxGrpc.grpcVersion}`); + clientHeader.push(`grpc/${this._gaxGrpc.grpcVersion}`); } if (opts.libName && opts.libVersion) { clientHeader.push(`${opts.libName}/${opts.libVersion}`); @@ -127,7 +135,7 @@ export class AlertPolicyServiceClient { // For browsers, pass the JSON content. const nodejsProtoPath = path.join(__dirname, '..', '..', 'protos', 'protos.json'); - const protos = gaxGrpc.loadProto( + this._protos = this._gaxGrpc.loadProto( opts.fallback ? require("../../protos/protos.json") : nodejsProtoPath @@ -137,76 +145,76 @@ export class AlertPolicyServiceClient { // identifiers to uniquely identify resources within the API. // Create useful helper objects for these. this._pathTemplates = { - folderAlertPolicyPathTemplate: new gaxModule.PathTemplate( + folderAlertPolicyPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/alertPolicies/{alert_policy}' ), - folderAlertPolicyConditionPathTemplate: new gaxModule.PathTemplate( + folderAlertPolicyConditionPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/alertPolicies/{alert_policy}/conditions/{condition}' ), - folderChannelDescriptorPathTemplate: new gaxModule.PathTemplate( + folderChannelDescriptorPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/notificationChannelDescriptors/{channel_descriptor}' ), - folderGroupPathTemplate: new gaxModule.PathTemplate( + folderGroupPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/groups/{group}' ), - folderNotificationChannelPathTemplate: new gaxModule.PathTemplate( + folderNotificationChannelPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/notificationChannels/{notification_channel}' ), - folderServicePathTemplate: new gaxModule.PathTemplate( + folderServicePathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/services/{service}' ), - folderServiceServiceLevelObjectivePathTemplate: new gaxModule.PathTemplate( + folderServiceServiceLevelObjectivePathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/services/{service}/serviceLevelObjectives/{service_level_objective}' ), - folderUptimeCheckConfigPathTemplate: new gaxModule.PathTemplate( + folderUptimeCheckConfigPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/uptimeCheckConfigs/{uptime_check_config}' ), - organizationAlertPolicyPathTemplate: new gaxModule.PathTemplate( + organizationAlertPolicyPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/alertPolicies/{alert_policy}' ), - organizationAlertPolicyConditionPathTemplate: new gaxModule.PathTemplate( + organizationAlertPolicyConditionPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/alertPolicies/{alert_policy}/conditions/{condition}' ), - organizationChannelDescriptorPathTemplate: new gaxModule.PathTemplate( + organizationChannelDescriptorPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/notificationChannelDescriptors/{channel_descriptor}' ), - organizationGroupPathTemplate: new gaxModule.PathTemplate( + organizationGroupPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/groups/{group}' ), - organizationNotificationChannelPathTemplate: new gaxModule.PathTemplate( + organizationNotificationChannelPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/notificationChannels/{notification_channel}' ), - organizationServicePathTemplate: new gaxModule.PathTemplate( + organizationServicePathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/services/{service}' ), - organizationServiceServiceLevelObjectivePathTemplate: new gaxModule.PathTemplate( + organizationServiceServiceLevelObjectivePathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/services/{service}/serviceLevelObjectives/{service_level_objective}' ), - organizationUptimeCheckConfigPathTemplate: new gaxModule.PathTemplate( + organizationUptimeCheckConfigPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/uptimeCheckConfigs/{uptime_check_config}' ), - projectAlertPolicyPathTemplate: new gaxModule.PathTemplate( + projectAlertPolicyPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/alertPolicies/{alert_policy}' ), - projectAlertPolicyConditionPathTemplate: new gaxModule.PathTemplate( + projectAlertPolicyConditionPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/alertPolicies/{alert_policy}/conditions/{condition}' ), - projectChannelDescriptorPathTemplate: new gaxModule.PathTemplate( + projectChannelDescriptorPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/notificationChannelDescriptors/{channel_descriptor}' ), - projectGroupPathTemplate: new gaxModule.PathTemplate( + projectGroupPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/groups/{group}' ), - projectNotificationChannelPathTemplate: new gaxModule.PathTemplate( + projectNotificationChannelPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/notificationChannels/{notification_channel}' ), - projectServicePathTemplate: new gaxModule.PathTemplate( + projectServicePathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/services/{service}' ), - projectServiceServiceLevelObjectivePathTemplate: new gaxModule.PathTemplate( + projectServiceServiceLevelObjectivePathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/services/{service}/serviceLevelObjectives/{service_level_objective}' ), - projectUptimeCheckConfigPathTemplate: new gaxModule.PathTemplate( + projectUptimeCheckConfigPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/uptimeCheckConfigs/{uptime_check_config}' ), }; @@ -216,11 +224,11 @@ export class AlertPolicyServiceClient { // pages). Denote the keys used for pagination and results. this._descriptors.page = { listAlertPolicies: - new gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'alertPolicies') + new this._gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'alertPolicies') }; // Put together the default options sent with requests. - const defaults = gaxGrpc.constructSettings( + this._defaults = this._gaxGrpc.constructSettings( 'google.monitoring.v3.AlertPolicyService', gapicConfig as gax.ClientConfig, opts.clientConfig || {}, {'x-goog-api-client': clientHeader.join(' ')}); @@ -228,15 +236,33 @@ export class AlertPolicyServiceClient { // of calling the API is handled in `google-gax`, with this code // merely providing the destination and request information. this._innerApiCalls = {}; + } + + /** + * Initialize the client. + * Performs asynchronous operations (such as authentication) and prepares the client. + * This function will be called automatically when any class method is called for the + * first time, but if you need to initialize it before calling an actual method, + * feel free to call initialize() directly. + * + * You can await on this method if you want to make sure the client is initialized. + * + * @returns {Promise} A promise that resolves to an authenticated service stub. + */ + initialize() { + // If the client stub promise is already initialized, return immediately. + if (this.alertPolicyServiceStub) { + return this.alertPolicyServiceStub; + } // Put together the "service stub" for // google.monitoring.v3.AlertPolicyService. - this.alertPolicyServiceStub = gaxGrpc.createStub( - opts.fallback ? - (protos as protobuf.Root).lookupService('google.monitoring.v3.AlertPolicyService') : + this.alertPolicyServiceStub = this._gaxGrpc.createStub( + this._opts.fallback ? + (this._protos as protobuf.Root).lookupService('google.monitoring.v3.AlertPolicyService') : // tslint:disable-next-line no-any - (protos as any).google.monitoring.v3.AlertPolicyService, - opts) as Promise<{[method: string]: Function}>; + (this._protos as any).google.monitoring.v3.AlertPolicyService, + this._opts) as Promise<{[method: string]: Function}>; // Iterate over each of the methods that the service provides // and create an API call method for each. @@ -255,9 +281,9 @@ export class AlertPolicyServiceClient { throw err; }); - const apiCall = gaxModule.createApiCall( + const apiCall = this._gaxModule.createApiCall( innerCallPromise, - defaults[methodName], + this._defaults[methodName], this._descriptors.page[methodName] || this._descriptors.stream[methodName] || this._descriptors.longrunning[methodName] @@ -271,6 +297,8 @@ export class AlertPolicyServiceClient { return apiCall(argument, callOptions, callback); }; } + + return this.alertPolicyServiceStub; } /** @@ -385,6 +413,7 @@ export class AlertPolicyServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.getAlertPolicy(request, options, callback); } createAlertPolicy( @@ -455,6 +484,7 @@ export class AlertPolicyServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.createAlertPolicy(request, options, callback); } deleteAlertPolicy( @@ -518,6 +548,7 @@ export class AlertPolicyServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.deleteAlertPolicy(request, options, callback); } updateAlertPolicy( @@ -605,6 +636,7 @@ export class AlertPolicyServiceClient { ] = gax.routingHeader.fromParams({ 'alert_policy.name': request.alertPolicy!.name || '', }); + this.initialize(); return this._innerApiCalls.updateAlertPolicy(request, options, callback); } @@ -707,6 +739,7 @@ export class AlertPolicyServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.listAlertPolicies(request, options, callback); } @@ -773,6 +806,7 @@ export class AlertPolicyServiceClient { 'name': request.name || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listAlertPolicies.createStream( this._innerApiCalls.listAlertPolicies as gax.GaxCall, request, @@ -1731,8 +1765,9 @@ export class AlertPolicyServiceClient { * The client will no longer be usable and all future behavior is undefined. */ close(): Promise { + this.initialize(); if (!this._terminated) { - return this.alertPolicyServiceStub.then(stub => { + return this.alertPolicyServiceStub!.then(stub => { this._terminated = true; stub.close(); }); diff --git a/baselines/monitoring/src/v3/group_service_client.ts.baseline b/baselines/monitoring/src/v3/group_service_client.ts.baseline index 96873934d..b1faf0536 100644 --- a/baselines/monitoring/src/v3/group_service_client.ts.baseline +++ b/baselines/monitoring/src/v3/group_service_client.ts.baseline @@ -47,8 +47,13 @@ export class GroupServiceClient { private _innerApiCalls: {[name: string]: Function}; private _pathTemplates: {[name: string]: gax.PathTemplate}; private _terminated = false; + private _opts: ClientOptions; + private _gaxModule: typeof gax | typeof gax.fallback; + private _gaxGrpc: gax.GrpcClient | gax.fallback.GrpcClient; + private _protos: {}; + private _defaults: {[method: string]: gax.CallSettings}; auth: gax.GoogleAuth; - groupServiceStub: Promise<{[name: string]: Function}>; + groupServiceStub?: Promise<{[name: string]: Function}>; /** * Construct an instance of GroupServiceClient. @@ -99,28 +104,31 @@ export class GroupServiceClient { // If we are in browser, we are already using fallback because of the // "browser" field in package.json. // But if we were explicitly requested to use fallback, let's do it now. - const gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; + this._gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; // Create a `gaxGrpc` object, with any grpc-specific options // sent to the client. opts.scopes = (this.constructor as typeof GroupServiceClient).scopes; - const gaxGrpc = new gaxModule.GrpcClient(opts); + this._gaxGrpc = new this._gaxModule.GrpcClient(opts); + + // Save options to use in initialize() method. + this._opts = opts; // Save the auth object to the client, for use by other methods. - this.auth = (gaxGrpc.auth as gax.GoogleAuth); + this.auth = (this._gaxGrpc.auth as gax.GoogleAuth); // Determine the client header string. const clientHeader = [ - `gax/${gaxModule.version}`, + `gax/${this._gaxModule.version}`, `gapic/${version}`, ]; if (typeof process !== 'undefined' && 'versions' in process) { clientHeader.push(`gl-node/${process.versions.node}`); } else { - clientHeader.push(`gl-web/${gaxModule.version}`); + clientHeader.push(`gl-web/${this._gaxModule.version}`); } if (!opts.fallback) { - clientHeader.push(`grpc/${gaxGrpc.grpcVersion}`); + clientHeader.push(`grpc/${this._gaxGrpc.grpcVersion}`); } if (opts.libName && opts.libVersion) { clientHeader.push(`${opts.libName}/${opts.libVersion}`); @@ -130,7 +138,7 @@ export class GroupServiceClient { // For browsers, pass the JSON content. const nodejsProtoPath = path.join(__dirname, '..', '..', 'protos', 'protos.json'); - const protos = gaxGrpc.loadProto( + this._protos = this._gaxGrpc.loadProto( opts.fallback ? require("../../protos/protos.json") : nodejsProtoPath @@ -140,76 +148,76 @@ export class GroupServiceClient { // identifiers to uniquely identify resources within the API. // Create useful helper objects for these. this._pathTemplates = { - folderAlertPolicyPathTemplate: new gaxModule.PathTemplate( + folderAlertPolicyPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/alertPolicies/{alert_policy}' ), - folderAlertPolicyConditionPathTemplate: new gaxModule.PathTemplate( + folderAlertPolicyConditionPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/alertPolicies/{alert_policy}/conditions/{condition}' ), - folderChannelDescriptorPathTemplate: new gaxModule.PathTemplate( + folderChannelDescriptorPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/notificationChannelDescriptors/{channel_descriptor}' ), - folderGroupPathTemplate: new gaxModule.PathTemplate( + folderGroupPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/groups/{group}' ), - folderNotificationChannelPathTemplate: new gaxModule.PathTemplate( + folderNotificationChannelPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/notificationChannels/{notification_channel}' ), - folderServicePathTemplate: new gaxModule.PathTemplate( + folderServicePathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/services/{service}' ), - folderServiceServiceLevelObjectivePathTemplate: new gaxModule.PathTemplate( + folderServiceServiceLevelObjectivePathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/services/{service}/serviceLevelObjectives/{service_level_objective}' ), - folderUptimeCheckConfigPathTemplate: new gaxModule.PathTemplate( + folderUptimeCheckConfigPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/uptimeCheckConfigs/{uptime_check_config}' ), - organizationAlertPolicyPathTemplate: new gaxModule.PathTemplate( + organizationAlertPolicyPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/alertPolicies/{alert_policy}' ), - organizationAlertPolicyConditionPathTemplate: new gaxModule.PathTemplate( + organizationAlertPolicyConditionPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/alertPolicies/{alert_policy}/conditions/{condition}' ), - organizationChannelDescriptorPathTemplate: new gaxModule.PathTemplate( + organizationChannelDescriptorPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/notificationChannelDescriptors/{channel_descriptor}' ), - organizationGroupPathTemplate: new gaxModule.PathTemplate( + organizationGroupPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/groups/{group}' ), - organizationNotificationChannelPathTemplate: new gaxModule.PathTemplate( + organizationNotificationChannelPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/notificationChannels/{notification_channel}' ), - organizationServicePathTemplate: new gaxModule.PathTemplate( + organizationServicePathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/services/{service}' ), - organizationServiceServiceLevelObjectivePathTemplate: new gaxModule.PathTemplate( + organizationServiceServiceLevelObjectivePathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/services/{service}/serviceLevelObjectives/{service_level_objective}' ), - organizationUptimeCheckConfigPathTemplate: new gaxModule.PathTemplate( + organizationUptimeCheckConfigPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/uptimeCheckConfigs/{uptime_check_config}' ), - projectAlertPolicyPathTemplate: new gaxModule.PathTemplate( + projectAlertPolicyPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/alertPolicies/{alert_policy}' ), - projectAlertPolicyConditionPathTemplate: new gaxModule.PathTemplate( + projectAlertPolicyConditionPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/alertPolicies/{alert_policy}/conditions/{condition}' ), - projectChannelDescriptorPathTemplate: new gaxModule.PathTemplate( + projectChannelDescriptorPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/notificationChannelDescriptors/{channel_descriptor}' ), - projectGroupPathTemplate: new gaxModule.PathTemplate( + projectGroupPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/groups/{group}' ), - projectNotificationChannelPathTemplate: new gaxModule.PathTemplate( + projectNotificationChannelPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/notificationChannels/{notification_channel}' ), - projectServicePathTemplate: new gaxModule.PathTemplate( + projectServicePathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/services/{service}' ), - projectServiceServiceLevelObjectivePathTemplate: new gaxModule.PathTemplate( + projectServiceServiceLevelObjectivePathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/services/{service}/serviceLevelObjectives/{service_level_objective}' ), - projectUptimeCheckConfigPathTemplate: new gaxModule.PathTemplate( + projectUptimeCheckConfigPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/uptimeCheckConfigs/{uptime_check_config}' ), }; @@ -219,13 +227,13 @@ export class GroupServiceClient { // pages). Denote the keys used for pagination and results. this._descriptors.page = { listGroups: - new gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'group'), + new this._gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'group'), listGroupMembers: - new gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'members') + new this._gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'members') }; // Put together the default options sent with requests. - const defaults = gaxGrpc.constructSettings( + this._defaults = this._gaxGrpc.constructSettings( 'google.monitoring.v3.GroupService', gapicConfig as gax.ClientConfig, opts.clientConfig || {}, {'x-goog-api-client': clientHeader.join(' ')}); @@ -233,15 +241,33 @@ export class GroupServiceClient { // of calling the API is handled in `google-gax`, with this code // merely providing the destination and request information. this._innerApiCalls = {}; + } + + /** + * Initialize the client. + * Performs asynchronous operations (such as authentication) and prepares the client. + * This function will be called automatically when any class method is called for the + * first time, but if you need to initialize it before calling an actual method, + * feel free to call initialize() directly. + * + * You can await on this method if you want to make sure the client is initialized. + * + * @returns {Promise} A promise that resolves to an authenticated service stub. + */ + initialize() { + // If the client stub promise is already initialized, return immediately. + if (this.groupServiceStub) { + return this.groupServiceStub; + } // Put together the "service stub" for // google.monitoring.v3.GroupService. - this.groupServiceStub = gaxGrpc.createStub( - opts.fallback ? - (protos as protobuf.Root).lookupService('google.monitoring.v3.GroupService') : + this.groupServiceStub = this._gaxGrpc.createStub( + this._opts.fallback ? + (this._protos as protobuf.Root).lookupService('google.monitoring.v3.GroupService') : // tslint:disable-next-line no-any - (protos as any).google.monitoring.v3.GroupService, - opts) as Promise<{[method: string]: Function}>; + (this._protos as any).google.monitoring.v3.GroupService, + this._opts) as Promise<{[method: string]: Function}>; // Iterate over each of the methods that the service provides // and create an API call method for each. @@ -260,9 +286,9 @@ export class GroupServiceClient { throw err; }); - const apiCall = gaxModule.createApiCall( + const apiCall = this._gaxModule.createApiCall( innerCallPromise, - defaults[methodName], + this._defaults[methodName], this._descriptors.page[methodName] || this._descriptors.stream[methodName] || this._descriptors.longrunning[methodName] @@ -276,6 +302,8 @@ export class GroupServiceClient { return apiCall(argument, callOptions, callback); }; } + + return this.groupServiceStub; } /** @@ -389,6 +417,7 @@ export class GroupServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.getGroup(request, options, callback); } createGroup( @@ -454,6 +483,7 @@ export class GroupServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.createGroup(request, options, callback); } updateGroup( @@ -517,6 +547,7 @@ export class GroupServiceClient { ] = gax.routingHeader.fromParams({ 'group.name': request.group!.name || '', }); + this.initialize(); return this._innerApiCalls.updateGroup(request, options, callback); } deleteGroup( @@ -581,6 +612,7 @@ export class GroupServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.deleteGroup(request, options, callback); } @@ -678,6 +710,7 @@ export class GroupServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.listGroups(request, options, callback); } @@ -739,6 +772,7 @@ export class GroupServiceClient { 'name': request.name || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listGroups.createStream( this._innerApiCalls.listGroups as gax.GaxCall, request, @@ -837,6 +871,7 @@ export class GroupServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.listGroupMembers(request, options, callback); } @@ -896,6 +931,7 @@ export class GroupServiceClient { 'name': request.name || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listGroupMembers.createStream( this._innerApiCalls.listGroupMembers as gax.GaxCall, request, @@ -1854,8 +1890,9 @@ export class GroupServiceClient { * The client will no longer be usable and all future behavior is undefined. */ close(): Promise { + this.initialize(); if (!this._terminated) { - return this.groupServiceStub.then(stub => { + return this.groupServiceStub!.then(stub => { this._terminated = true; stub.close(); }); diff --git a/baselines/monitoring/src/v3/metric_service_client.ts.baseline b/baselines/monitoring/src/v3/metric_service_client.ts.baseline index a9a9468bc..0ed46aae0 100644 --- a/baselines/monitoring/src/v3/metric_service_client.ts.baseline +++ b/baselines/monitoring/src/v3/metric_service_client.ts.baseline @@ -37,8 +37,13 @@ export class MetricServiceClient { private _innerApiCalls: {[name: string]: Function}; private _pathTemplates: {[name: string]: gax.PathTemplate}; private _terminated = false; + private _opts: ClientOptions; + private _gaxModule: typeof gax | typeof gax.fallback; + private _gaxGrpc: gax.GrpcClient | gax.fallback.GrpcClient; + private _protos: {}; + private _defaults: {[method: string]: gax.CallSettings}; auth: gax.GoogleAuth; - metricServiceStub: Promise<{[name: string]: Function}>; + metricServiceStub?: Promise<{[name: string]: Function}>; /** * Construct an instance of MetricServiceClient. @@ -89,28 +94,31 @@ export class MetricServiceClient { // If we are in browser, we are already using fallback because of the // "browser" field in package.json. // But if we were explicitly requested to use fallback, let's do it now. - const gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; + this._gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; // Create a `gaxGrpc` object, with any grpc-specific options // sent to the client. opts.scopes = (this.constructor as typeof MetricServiceClient).scopes; - const gaxGrpc = new gaxModule.GrpcClient(opts); + this._gaxGrpc = new this._gaxModule.GrpcClient(opts); + + // Save options to use in initialize() method. + this._opts = opts; // Save the auth object to the client, for use by other methods. - this.auth = (gaxGrpc.auth as gax.GoogleAuth); + this.auth = (this._gaxGrpc.auth as gax.GoogleAuth); // Determine the client header string. const clientHeader = [ - `gax/${gaxModule.version}`, + `gax/${this._gaxModule.version}`, `gapic/${version}`, ]; if (typeof process !== 'undefined' && 'versions' in process) { clientHeader.push(`gl-node/${process.versions.node}`); } else { - clientHeader.push(`gl-web/${gaxModule.version}`); + clientHeader.push(`gl-web/${this._gaxModule.version}`); } if (!opts.fallback) { - clientHeader.push(`grpc/${gaxGrpc.grpcVersion}`); + clientHeader.push(`grpc/${this._gaxGrpc.grpcVersion}`); } if (opts.libName && opts.libVersion) { clientHeader.push(`${opts.libName}/${opts.libVersion}`); @@ -120,7 +128,7 @@ export class MetricServiceClient { // For browsers, pass the JSON content. const nodejsProtoPath = path.join(__dirname, '..', '..', 'protos', 'protos.json'); - const protos = gaxGrpc.loadProto( + this._protos = this._gaxGrpc.loadProto( opts.fallback ? require("../../protos/protos.json") : nodejsProtoPath @@ -130,94 +138,94 @@ export class MetricServiceClient { // identifiers to uniquely identify resources within the API. // Create useful helper objects for these. this._pathTemplates = { - folderAlertPolicyPathTemplate: new gaxModule.PathTemplate( + folderAlertPolicyPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/alertPolicies/{alert_policy}' ), - folderAlertPolicyConditionPathTemplate: new gaxModule.PathTemplate( + folderAlertPolicyConditionPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/alertPolicies/{alert_policy}/conditions/{condition}' ), - folderChannelDescriptorPathTemplate: new gaxModule.PathTemplate( + folderChannelDescriptorPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/notificationChannelDescriptors/{channel_descriptor}' ), - folderGroupPathTemplate: new gaxModule.PathTemplate( + folderGroupPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/groups/{group}' ), - folderMetricDescriptorPathTemplate: new gaxModule.PathTemplate( + folderMetricDescriptorPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/metricDescriptors/{metric_descriptor=**}' ), - folderMonitoredResourceDescriptorPathTemplate: new gaxModule.PathTemplate( + folderMonitoredResourceDescriptorPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/monitoredResourceDescriptors/{monitored_resource_descriptor}' ), - folderNotificationChannelPathTemplate: new gaxModule.PathTemplate( + folderNotificationChannelPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/notificationChannels/{notification_channel}' ), - folderServicePathTemplate: new gaxModule.PathTemplate( + folderServicePathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/services/{service}' ), - folderServiceServiceLevelObjectivePathTemplate: new gaxModule.PathTemplate( + folderServiceServiceLevelObjectivePathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/services/{service}/serviceLevelObjectives/{service_level_objective}' ), - folderUptimeCheckConfigPathTemplate: new gaxModule.PathTemplate( + folderUptimeCheckConfigPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/uptimeCheckConfigs/{uptime_check_config}' ), - organizationAlertPolicyPathTemplate: new gaxModule.PathTemplate( + organizationAlertPolicyPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/alertPolicies/{alert_policy}' ), - organizationAlertPolicyConditionPathTemplate: new gaxModule.PathTemplate( + organizationAlertPolicyConditionPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/alertPolicies/{alert_policy}/conditions/{condition}' ), - organizationChannelDescriptorPathTemplate: new gaxModule.PathTemplate( + organizationChannelDescriptorPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/notificationChannelDescriptors/{channel_descriptor}' ), - organizationGroupPathTemplate: new gaxModule.PathTemplate( + organizationGroupPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/groups/{group}' ), - organizationMetricDescriptorPathTemplate: new gaxModule.PathTemplate( + organizationMetricDescriptorPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/metricDescriptors/{metric_descriptor=**}' ), - organizationMonitoredResourceDescriptorPathTemplate: new gaxModule.PathTemplate( + organizationMonitoredResourceDescriptorPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/monitoredResourceDescriptors/{monitored_resource_descriptor}' ), - organizationNotificationChannelPathTemplate: new gaxModule.PathTemplate( + organizationNotificationChannelPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/notificationChannels/{notification_channel}' ), - organizationServicePathTemplate: new gaxModule.PathTemplate( + organizationServicePathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/services/{service}' ), - organizationServiceServiceLevelObjectivePathTemplate: new gaxModule.PathTemplate( + organizationServiceServiceLevelObjectivePathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/services/{service}/serviceLevelObjectives/{service_level_objective}' ), - organizationUptimeCheckConfigPathTemplate: new gaxModule.PathTemplate( + organizationUptimeCheckConfigPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/uptimeCheckConfigs/{uptime_check_config}' ), - projectAlertPolicyPathTemplate: new gaxModule.PathTemplate( + projectAlertPolicyPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/alertPolicies/{alert_policy}' ), - projectAlertPolicyConditionPathTemplate: new gaxModule.PathTemplate( + projectAlertPolicyConditionPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/alertPolicies/{alert_policy}/conditions/{condition}' ), - projectChannelDescriptorPathTemplate: new gaxModule.PathTemplate( + projectChannelDescriptorPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/notificationChannelDescriptors/{channel_descriptor}' ), - projectGroupPathTemplate: new gaxModule.PathTemplate( + projectGroupPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/groups/{group}' ), - projectMetricDescriptorPathTemplate: new gaxModule.PathTemplate( + projectMetricDescriptorPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/metricDescriptors/{metric_descriptor=**}' ), - projectMonitoredResourceDescriptorPathTemplate: new gaxModule.PathTemplate( + projectMonitoredResourceDescriptorPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/monitoredResourceDescriptors/{monitored_resource_descriptor}' ), - projectNotificationChannelPathTemplate: new gaxModule.PathTemplate( + projectNotificationChannelPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/notificationChannels/{notification_channel}' ), - projectServicePathTemplate: new gaxModule.PathTemplate( + projectServicePathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/services/{service}' ), - projectServiceServiceLevelObjectivePathTemplate: new gaxModule.PathTemplate( + projectServiceServiceLevelObjectivePathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/services/{service}/serviceLevelObjectives/{service_level_objective}' ), - projectUptimeCheckConfigPathTemplate: new gaxModule.PathTemplate( + projectUptimeCheckConfigPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/uptimeCheckConfigs/{uptime_check_config}' ), }; @@ -227,15 +235,15 @@ export class MetricServiceClient { // pages). Denote the keys used for pagination and results. this._descriptors.page = { listMonitoredResourceDescriptors: - new gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'resourceDescriptors'), + new this._gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'resourceDescriptors'), listMetricDescriptors: - new gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'metricDescriptors'), + new this._gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'metricDescriptors'), listTimeSeries: - new gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'timeSeries') + new this._gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'timeSeries') }; // Put together the default options sent with requests. - const defaults = gaxGrpc.constructSettings( + this._defaults = this._gaxGrpc.constructSettings( 'google.monitoring.v3.MetricService', gapicConfig as gax.ClientConfig, opts.clientConfig || {}, {'x-goog-api-client': clientHeader.join(' ')}); @@ -243,15 +251,33 @@ export class MetricServiceClient { // of calling the API is handled in `google-gax`, with this code // merely providing the destination and request information. this._innerApiCalls = {}; + } + + /** + * Initialize the client. + * Performs asynchronous operations (such as authentication) and prepares the client. + * This function will be called automatically when any class method is called for the + * first time, but if you need to initialize it before calling an actual method, + * feel free to call initialize() directly. + * + * You can await on this method if you want to make sure the client is initialized. + * + * @returns {Promise} A promise that resolves to an authenticated service stub. + */ + initialize() { + // If the client stub promise is already initialized, return immediately. + if (this.metricServiceStub) { + return this.metricServiceStub; + } // Put together the "service stub" for // google.monitoring.v3.MetricService. - this.metricServiceStub = gaxGrpc.createStub( - opts.fallback ? - (protos as protobuf.Root).lookupService('google.monitoring.v3.MetricService') : + this.metricServiceStub = this._gaxGrpc.createStub( + this._opts.fallback ? + (this._protos as protobuf.Root).lookupService('google.monitoring.v3.MetricService') : // tslint:disable-next-line no-any - (protos as any).google.monitoring.v3.MetricService, - opts) as Promise<{[method: string]: Function}>; + (this._protos as any).google.monitoring.v3.MetricService, + this._opts) as Promise<{[method: string]: Function}>; // Iterate over each of the methods that the service provides // and create an API call method for each. @@ -270,9 +296,9 @@ export class MetricServiceClient { throw err; }); - const apiCall = gaxModule.createApiCall( + const apiCall = this._gaxModule.createApiCall( innerCallPromise, - defaults[methodName], + this._defaults[methodName], this._descriptors.page[methodName] || this._descriptors.stream[methodName] || this._descriptors.longrunning[methodName] @@ -286,6 +312,8 @@ export class MetricServiceClient { return apiCall(argument, callOptions, callback); }; } + + return this.metricServiceStub; } /** @@ -402,6 +430,7 @@ export class MetricServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.getMonitoredResourceDescriptor(request, options, callback); } getMetricDescriptor( @@ -464,6 +493,7 @@ export class MetricServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.getMetricDescriptor(request, options, callback); } createMetricDescriptor( @@ -529,6 +559,7 @@ export class MetricServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.createMetricDescriptor(request, options, callback); } deleteMetricDescriptor( @@ -592,6 +623,7 @@ export class MetricServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.deleteMetricDescriptor(request, options, callback); } createTimeSeries( @@ -663,6 +695,7 @@ export class MetricServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.createTimeSeries(request, options, callback); } @@ -753,6 +786,7 @@ export class MetricServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.listMonitoredResourceDescriptors(request, options, callback); } @@ -807,6 +841,7 @@ export class MetricServiceClient { 'name': request.name || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listMonitoredResourceDescriptors.createStream( this._innerApiCalls.listMonitoredResourceDescriptors as gax.GaxCall, request, @@ -901,6 +936,7 @@ export class MetricServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.listMetricDescriptors(request, options, callback); } @@ -956,6 +992,7 @@ export class MetricServiceClient { 'name': request.name || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listMetricDescriptors.createStream( this._innerApiCalls.listMetricDescriptors as gax.GaxCall, request, @@ -1068,6 +1105,7 @@ export class MetricServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.listTimeSeries(request, options, callback); } @@ -1141,6 +1179,7 @@ export class MetricServiceClient { 'name': request.name || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listTimeSeries.createStream( this._innerApiCalls.listTimeSeries as gax.GaxCall, request, @@ -2315,8 +2354,9 @@ export class MetricServiceClient { * The client will no longer be usable and all future behavior is undefined. */ close(): Promise { + this.initialize(); if (!this._terminated) { - return this.metricServiceStub.then(stub => { + return this.metricServiceStub!.then(stub => { this._terminated = true; stub.close(); }); diff --git a/baselines/monitoring/src/v3/notification_channel_service_client.ts.baseline b/baselines/monitoring/src/v3/notification_channel_service_client.ts.baseline index 4a49ca955..beb7654df 100644 --- a/baselines/monitoring/src/v3/notification_channel_service_client.ts.baseline +++ b/baselines/monitoring/src/v3/notification_channel_service_client.ts.baseline @@ -37,8 +37,13 @@ export class NotificationChannelServiceClient { private _innerApiCalls: {[name: string]: Function}; private _pathTemplates: {[name: string]: gax.PathTemplate}; private _terminated = false; + private _opts: ClientOptions; + private _gaxModule: typeof gax | typeof gax.fallback; + private _gaxGrpc: gax.GrpcClient | gax.fallback.GrpcClient; + private _protos: {}; + private _defaults: {[method: string]: gax.CallSettings}; auth: gax.GoogleAuth; - notificationChannelServiceStub: Promise<{[name: string]: Function}>; + notificationChannelServiceStub?: Promise<{[name: string]: Function}>; /** * Construct an instance of NotificationChannelServiceClient. @@ -89,28 +94,31 @@ export class NotificationChannelServiceClient { // If we are in browser, we are already using fallback because of the // "browser" field in package.json. // But if we were explicitly requested to use fallback, let's do it now. - const gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; + this._gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; // Create a `gaxGrpc` object, with any grpc-specific options // sent to the client. opts.scopes = (this.constructor as typeof NotificationChannelServiceClient).scopes; - const gaxGrpc = new gaxModule.GrpcClient(opts); + this._gaxGrpc = new this._gaxModule.GrpcClient(opts); + + // Save options to use in initialize() method. + this._opts = opts; // Save the auth object to the client, for use by other methods. - this.auth = (gaxGrpc.auth as gax.GoogleAuth); + this.auth = (this._gaxGrpc.auth as gax.GoogleAuth); // Determine the client header string. const clientHeader = [ - `gax/${gaxModule.version}`, + `gax/${this._gaxModule.version}`, `gapic/${version}`, ]; if (typeof process !== 'undefined' && 'versions' in process) { clientHeader.push(`gl-node/${process.versions.node}`); } else { - clientHeader.push(`gl-web/${gaxModule.version}`); + clientHeader.push(`gl-web/${this._gaxModule.version}`); } if (!opts.fallback) { - clientHeader.push(`grpc/${gaxGrpc.grpcVersion}`); + clientHeader.push(`grpc/${this._gaxGrpc.grpcVersion}`); } if (opts.libName && opts.libVersion) { clientHeader.push(`${opts.libName}/${opts.libVersion}`); @@ -120,7 +128,7 @@ export class NotificationChannelServiceClient { // For browsers, pass the JSON content. const nodejsProtoPath = path.join(__dirname, '..', '..', 'protos', 'protos.json'); - const protos = gaxGrpc.loadProto( + this._protos = this._gaxGrpc.loadProto( opts.fallback ? require("../../protos/protos.json") : nodejsProtoPath @@ -130,76 +138,76 @@ export class NotificationChannelServiceClient { // identifiers to uniquely identify resources within the API. // Create useful helper objects for these. this._pathTemplates = { - folderAlertPolicyPathTemplate: new gaxModule.PathTemplate( + folderAlertPolicyPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/alertPolicies/{alert_policy}' ), - folderAlertPolicyConditionPathTemplate: new gaxModule.PathTemplate( + folderAlertPolicyConditionPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/alertPolicies/{alert_policy}/conditions/{condition}' ), - folderChannelDescriptorPathTemplate: new gaxModule.PathTemplate( + folderChannelDescriptorPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/notificationChannelDescriptors/{channel_descriptor}' ), - folderGroupPathTemplate: new gaxModule.PathTemplate( + folderGroupPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/groups/{group}' ), - folderNotificationChannelPathTemplate: new gaxModule.PathTemplate( + folderNotificationChannelPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/notificationChannels/{notification_channel}' ), - folderServicePathTemplate: new gaxModule.PathTemplate( + folderServicePathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/services/{service}' ), - folderServiceServiceLevelObjectivePathTemplate: new gaxModule.PathTemplate( + folderServiceServiceLevelObjectivePathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/services/{service}/serviceLevelObjectives/{service_level_objective}' ), - folderUptimeCheckConfigPathTemplate: new gaxModule.PathTemplate( + folderUptimeCheckConfigPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/uptimeCheckConfigs/{uptime_check_config}' ), - organizationAlertPolicyPathTemplate: new gaxModule.PathTemplate( + organizationAlertPolicyPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/alertPolicies/{alert_policy}' ), - organizationAlertPolicyConditionPathTemplate: new gaxModule.PathTemplate( + organizationAlertPolicyConditionPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/alertPolicies/{alert_policy}/conditions/{condition}' ), - organizationChannelDescriptorPathTemplate: new gaxModule.PathTemplate( + organizationChannelDescriptorPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/notificationChannelDescriptors/{channel_descriptor}' ), - organizationGroupPathTemplate: new gaxModule.PathTemplate( + organizationGroupPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/groups/{group}' ), - organizationNotificationChannelPathTemplate: new gaxModule.PathTemplate( + organizationNotificationChannelPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/notificationChannels/{notification_channel}' ), - organizationServicePathTemplate: new gaxModule.PathTemplate( + organizationServicePathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/services/{service}' ), - organizationServiceServiceLevelObjectivePathTemplate: new gaxModule.PathTemplate( + organizationServiceServiceLevelObjectivePathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/services/{service}/serviceLevelObjectives/{service_level_objective}' ), - organizationUptimeCheckConfigPathTemplate: new gaxModule.PathTemplate( + organizationUptimeCheckConfigPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/uptimeCheckConfigs/{uptime_check_config}' ), - projectAlertPolicyPathTemplate: new gaxModule.PathTemplate( + projectAlertPolicyPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/alertPolicies/{alert_policy}' ), - projectAlertPolicyConditionPathTemplate: new gaxModule.PathTemplate( + projectAlertPolicyConditionPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/alertPolicies/{alert_policy}/conditions/{condition}' ), - projectChannelDescriptorPathTemplate: new gaxModule.PathTemplate( + projectChannelDescriptorPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/notificationChannelDescriptors/{channel_descriptor}' ), - projectGroupPathTemplate: new gaxModule.PathTemplate( + projectGroupPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/groups/{group}' ), - projectNotificationChannelPathTemplate: new gaxModule.PathTemplate( + projectNotificationChannelPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/notificationChannels/{notification_channel}' ), - projectServicePathTemplate: new gaxModule.PathTemplate( + projectServicePathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/services/{service}' ), - projectServiceServiceLevelObjectivePathTemplate: new gaxModule.PathTemplate( + projectServiceServiceLevelObjectivePathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/services/{service}/serviceLevelObjectives/{service_level_objective}' ), - projectUptimeCheckConfigPathTemplate: new gaxModule.PathTemplate( + projectUptimeCheckConfigPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/uptimeCheckConfigs/{uptime_check_config}' ), }; @@ -209,13 +217,13 @@ export class NotificationChannelServiceClient { // pages). Denote the keys used for pagination and results. this._descriptors.page = { listNotificationChannelDescriptors: - new gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'channelDescriptors'), + new this._gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'channelDescriptors'), listNotificationChannels: - new gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'notificationChannels') + new this._gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'notificationChannels') }; // Put together the default options sent with requests. - const defaults = gaxGrpc.constructSettings( + this._defaults = this._gaxGrpc.constructSettings( 'google.monitoring.v3.NotificationChannelService', gapicConfig as gax.ClientConfig, opts.clientConfig || {}, {'x-goog-api-client': clientHeader.join(' ')}); @@ -223,15 +231,33 @@ export class NotificationChannelServiceClient { // of calling the API is handled in `google-gax`, with this code // merely providing the destination and request information. this._innerApiCalls = {}; + } + + /** + * Initialize the client. + * Performs asynchronous operations (such as authentication) and prepares the client. + * This function will be called automatically when any class method is called for the + * first time, but if you need to initialize it before calling an actual method, + * feel free to call initialize() directly. + * + * You can await on this method if you want to make sure the client is initialized. + * + * @returns {Promise} A promise that resolves to an authenticated service stub. + */ + initialize() { + // If the client stub promise is already initialized, return immediately. + if (this.notificationChannelServiceStub) { + return this.notificationChannelServiceStub; + } // Put together the "service stub" for // google.monitoring.v3.NotificationChannelService. - this.notificationChannelServiceStub = gaxGrpc.createStub( - opts.fallback ? - (protos as protobuf.Root).lookupService('google.monitoring.v3.NotificationChannelService') : + this.notificationChannelServiceStub = this._gaxGrpc.createStub( + this._opts.fallback ? + (this._protos as protobuf.Root).lookupService('google.monitoring.v3.NotificationChannelService') : // tslint:disable-next-line no-any - (protos as any).google.monitoring.v3.NotificationChannelService, - opts) as Promise<{[method: string]: Function}>; + (this._protos as any).google.monitoring.v3.NotificationChannelService, + this._opts) as Promise<{[method: string]: Function}>; // Iterate over each of the methods that the service provides // and create an API call method for each. @@ -250,9 +276,9 @@ export class NotificationChannelServiceClient { throw err; }); - const apiCall = gaxModule.createApiCall( + const apiCall = this._gaxModule.createApiCall( innerCallPromise, - defaults[methodName], + this._defaults[methodName], this._descriptors.page[methodName] || this._descriptors.stream[methodName] || this._descriptors.longrunning[methodName] @@ -266,6 +292,8 @@ export class NotificationChannelServiceClient { return apiCall(argument, callOptions, callback); }; } + + return this.notificationChannelServiceStub; } /** @@ -380,6 +408,7 @@ export class NotificationChannelServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.getNotificationChannelDescriptor(request, options, callback); } getNotificationChannel( @@ -444,6 +473,7 @@ export class NotificationChannelServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.getNotificationChannel(request, options, callback); } createNotificationChannel( @@ -513,6 +543,7 @@ export class NotificationChannelServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.createNotificationChannel(request, options, callback); } updateNotificationChannel( @@ -578,6 +609,7 @@ export class NotificationChannelServiceClient { ] = gax.routingHeader.fromParams({ 'notification_channel.name': request.notificationChannel!.name || '', }); + this.initialize(); return this._innerApiCalls.updateNotificationChannel(request, options, callback); } deleteNotificationChannel( @@ -643,6 +675,7 @@ export class NotificationChannelServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.deleteNotificationChannel(request, options, callback); } sendNotificationChannelVerificationCode( @@ -703,6 +736,7 @@ export class NotificationChannelServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.sendNotificationChannelVerificationCode(request, options, callback); } getNotificationChannelVerificationCode( @@ -794,6 +828,7 @@ export class NotificationChannelServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.getNotificationChannelVerificationCode(request, options, callback); } verifyNotificationChannel( @@ -863,6 +898,7 @@ export class NotificationChannelServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.verifyNotificationChannel(request, options, callback); } @@ -955,6 +991,7 @@ export class NotificationChannelServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.listNotificationChannelDescriptors(request, options, callback); } @@ -1010,6 +1047,7 @@ export class NotificationChannelServiceClient { 'name': request.name || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listNotificationChannelDescriptors.createStream( this._innerApiCalls.listNotificationChannelDescriptors as gax.GaxCall, request, @@ -1115,6 +1153,7 @@ export class NotificationChannelServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.listNotificationChannels(request, options, callback); } @@ -1181,6 +1220,7 @@ export class NotificationChannelServiceClient { 'name': request.name || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listNotificationChannels.createStream( this._innerApiCalls.listNotificationChannels as gax.GaxCall, request, @@ -2139,8 +2179,9 @@ export class NotificationChannelServiceClient { * The client will no longer be usable and all future behavior is undefined. */ close(): Promise { + this.initialize(); if (!this._terminated) { - return this.notificationChannelServiceStub.then(stub => { + return this.notificationChannelServiceStub!.then(stub => { this._terminated = true; stub.close(); }); diff --git a/baselines/monitoring/src/v3/service_monitoring_service_client.ts.baseline b/baselines/monitoring/src/v3/service_monitoring_service_client.ts.baseline index 090422f82..e48c2082e 100644 --- a/baselines/monitoring/src/v3/service_monitoring_service_client.ts.baseline +++ b/baselines/monitoring/src/v3/service_monitoring_service_client.ts.baseline @@ -39,8 +39,13 @@ export class ServiceMonitoringServiceClient { private _innerApiCalls: {[name: string]: Function}; private _pathTemplates: {[name: string]: gax.PathTemplate}; private _terminated = false; + private _opts: ClientOptions; + private _gaxModule: typeof gax | typeof gax.fallback; + private _gaxGrpc: gax.GrpcClient | gax.fallback.GrpcClient; + private _protos: {}; + private _defaults: {[method: string]: gax.CallSettings}; auth: gax.GoogleAuth; - serviceMonitoringServiceStub: Promise<{[name: string]: Function}>; + serviceMonitoringServiceStub?: Promise<{[name: string]: Function}>; /** * Construct an instance of ServiceMonitoringServiceClient. @@ -91,28 +96,31 @@ export class ServiceMonitoringServiceClient { // If we are in browser, we are already using fallback because of the // "browser" field in package.json. // But if we were explicitly requested to use fallback, let's do it now. - const gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; + this._gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; // Create a `gaxGrpc` object, with any grpc-specific options // sent to the client. opts.scopes = (this.constructor as typeof ServiceMonitoringServiceClient).scopes; - const gaxGrpc = new gaxModule.GrpcClient(opts); + this._gaxGrpc = new this._gaxModule.GrpcClient(opts); + + // Save options to use in initialize() method. + this._opts = opts; // Save the auth object to the client, for use by other methods. - this.auth = (gaxGrpc.auth as gax.GoogleAuth); + this.auth = (this._gaxGrpc.auth as gax.GoogleAuth); // Determine the client header string. const clientHeader = [ - `gax/${gaxModule.version}`, + `gax/${this._gaxModule.version}`, `gapic/${version}`, ]; if (typeof process !== 'undefined' && 'versions' in process) { clientHeader.push(`gl-node/${process.versions.node}`); } else { - clientHeader.push(`gl-web/${gaxModule.version}`); + clientHeader.push(`gl-web/${this._gaxModule.version}`); } if (!opts.fallback) { - clientHeader.push(`grpc/${gaxGrpc.grpcVersion}`); + clientHeader.push(`grpc/${this._gaxGrpc.grpcVersion}`); } if (opts.libName && opts.libVersion) { clientHeader.push(`${opts.libName}/${opts.libVersion}`); @@ -122,7 +130,7 @@ export class ServiceMonitoringServiceClient { // For browsers, pass the JSON content. const nodejsProtoPath = path.join(__dirname, '..', '..', 'protos', 'protos.json'); - const protos = gaxGrpc.loadProto( + this._protos = this._gaxGrpc.loadProto( opts.fallback ? require("../../protos/protos.json") : nodejsProtoPath @@ -132,76 +140,76 @@ export class ServiceMonitoringServiceClient { // identifiers to uniquely identify resources within the API. // Create useful helper objects for these. this._pathTemplates = { - folderAlertPolicyPathTemplate: new gaxModule.PathTemplate( + folderAlertPolicyPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/alertPolicies/{alert_policy}' ), - folderAlertPolicyConditionPathTemplate: new gaxModule.PathTemplate( + folderAlertPolicyConditionPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/alertPolicies/{alert_policy}/conditions/{condition}' ), - folderChannelDescriptorPathTemplate: new gaxModule.PathTemplate( + folderChannelDescriptorPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/notificationChannelDescriptors/{channel_descriptor}' ), - folderGroupPathTemplate: new gaxModule.PathTemplate( + folderGroupPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/groups/{group}' ), - folderNotificationChannelPathTemplate: new gaxModule.PathTemplate( + folderNotificationChannelPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/notificationChannels/{notification_channel}' ), - folderServicePathTemplate: new gaxModule.PathTemplate( + folderServicePathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/services/{service}' ), - folderServiceServiceLevelObjectivePathTemplate: new gaxModule.PathTemplate( + folderServiceServiceLevelObjectivePathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/services/{service}/serviceLevelObjectives/{service_level_objective}' ), - folderUptimeCheckConfigPathTemplate: new gaxModule.PathTemplate( + folderUptimeCheckConfigPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/uptimeCheckConfigs/{uptime_check_config}' ), - organizationAlertPolicyPathTemplate: new gaxModule.PathTemplate( + organizationAlertPolicyPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/alertPolicies/{alert_policy}' ), - organizationAlertPolicyConditionPathTemplate: new gaxModule.PathTemplate( + organizationAlertPolicyConditionPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/alertPolicies/{alert_policy}/conditions/{condition}' ), - organizationChannelDescriptorPathTemplate: new gaxModule.PathTemplate( + organizationChannelDescriptorPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/notificationChannelDescriptors/{channel_descriptor}' ), - organizationGroupPathTemplate: new gaxModule.PathTemplate( + organizationGroupPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/groups/{group}' ), - organizationNotificationChannelPathTemplate: new gaxModule.PathTemplate( + organizationNotificationChannelPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/notificationChannels/{notification_channel}' ), - organizationServicePathTemplate: new gaxModule.PathTemplate( + organizationServicePathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/services/{service}' ), - organizationServiceServiceLevelObjectivePathTemplate: new gaxModule.PathTemplate( + organizationServiceServiceLevelObjectivePathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/services/{service}/serviceLevelObjectives/{service_level_objective}' ), - organizationUptimeCheckConfigPathTemplate: new gaxModule.PathTemplate( + organizationUptimeCheckConfigPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/uptimeCheckConfigs/{uptime_check_config}' ), - projectAlertPolicyPathTemplate: new gaxModule.PathTemplate( + projectAlertPolicyPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/alertPolicies/{alert_policy}' ), - projectAlertPolicyConditionPathTemplate: new gaxModule.PathTemplate( + projectAlertPolicyConditionPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/alertPolicies/{alert_policy}/conditions/{condition}' ), - projectChannelDescriptorPathTemplate: new gaxModule.PathTemplate( + projectChannelDescriptorPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/notificationChannelDescriptors/{channel_descriptor}' ), - projectGroupPathTemplate: new gaxModule.PathTemplate( + projectGroupPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/groups/{group}' ), - projectNotificationChannelPathTemplate: new gaxModule.PathTemplate( + projectNotificationChannelPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/notificationChannels/{notification_channel}' ), - projectServicePathTemplate: new gaxModule.PathTemplate( + projectServicePathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/services/{service}' ), - projectServiceServiceLevelObjectivePathTemplate: new gaxModule.PathTemplate( + projectServiceServiceLevelObjectivePathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/services/{service}/serviceLevelObjectives/{service_level_objective}' ), - projectUptimeCheckConfigPathTemplate: new gaxModule.PathTemplate( + projectUptimeCheckConfigPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/uptimeCheckConfigs/{uptime_check_config}' ), }; @@ -211,13 +219,13 @@ export class ServiceMonitoringServiceClient { // pages). Denote the keys used for pagination and results. this._descriptors.page = { listServices: - new gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'services'), + new this._gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'services'), listServiceLevelObjectives: - new gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'serviceLevelObjectives') + new this._gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'serviceLevelObjectives') }; // Put together the default options sent with requests. - const defaults = gaxGrpc.constructSettings( + this._defaults = this._gaxGrpc.constructSettings( 'google.monitoring.v3.ServiceMonitoringService', gapicConfig as gax.ClientConfig, opts.clientConfig || {}, {'x-goog-api-client': clientHeader.join(' ')}); @@ -225,15 +233,33 @@ export class ServiceMonitoringServiceClient { // of calling the API is handled in `google-gax`, with this code // merely providing the destination and request information. this._innerApiCalls = {}; + } + + /** + * Initialize the client. + * Performs asynchronous operations (such as authentication) and prepares the client. + * This function will be called automatically when any class method is called for the + * first time, but if you need to initialize it before calling an actual method, + * feel free to call initialize() directly. + * + * You can await on this method if you want to make sure the client is initialized. + * + * @returns {Promise} A promise that resolves to an authenticated service stub. + */ + initialize() { + // If the client stub promise is already initialized, return immediately. + if (this.serviceMonitoringServiceStub) { + return this.serviceMonitoringServiceStub; + } // Put together the "service stub" for // google.monitoring.v3.ServiceMonitoringService. - this.serviceMonitoringServiceStub = gaxGrpc.createStub( - opts.fallback ? - (protos as protobuf.Root).lookupService('google.monitoring.v3.ServiceMonitoringService') : + this.serviceMonitoringServiceStub = this._gaxGrpc.createStub( + this._opts.fallback ? + (this._protos as protobuf.Root).lookupService('google.monitoring.v3.ServiceMonitoringService') : // tslint:disable-next-line no-any - (protos as any).google.monitoring.v3.ServiceMonitoringService, - opts) as Promise<{[method: string]: Function}>; + (this._protos as any).google.monitoring.v3.ServiceMonitoringService, + this._opts) as Promise<{[method: string]: Function}>; // Iterate over each of the methods that the service provides // and create an API call method for each. @@ -252,9 +278,9 @@ export class ServiceMonitoringServiceClient { throw err; }); - const apiCall = gaxModule.createApiCall( + const apiCall = this._gaxModule.createApiCall( innerCallPromise, - defaults[methodName], + this._defaults[methodName], this._descriptors.page[methodName] || this._descriptors.stream[methodName] || this._descriptors.longrunning[methodName] @@ -268,6 +294,8 @@ export class ServiceMonitoringServiceClient { return apiCall(argument, callOptions, callback); }; } + + return this.serviceMonitoringServiceStub; } /** @@ -386,6 +414,7 @@ export class ServiceMonitoringServiceClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.createService(request, options, callback); } getService( @@ -446,6 +475,7 @@ export class ServiceMonitoringServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.getService(request, options, callback); } updateService( @@ -508,6 +538,7 @@ export class ServiceMonitoringServiceClient { ] = gax.routingHeader.fromParams({ 'service.name': request.service!.name || '', }); + this.initialize(); return this._innerApiCalls.updateService(request, options, callback); } deleteService( @@ -568,6 +599,7 @@ export class ServiceMonitoringServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.deleteService(request, options, callback); } createServiceLevelObjective( @@ -636,6 +668,7 @@ export class ServiceMonitoringServiceClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.createServiceLevelObjective(request, options, callback); } getServiceLevelObjective( @@ -702,6 +735,7 @@ export class ServiceMonitoringServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.getServiceLevelObjective(request, options, callback); } updateServiceLevelObjective( @@ -764,6 +798,7 @@ export class ServiceMonitoringServiceClient { ] = gax.routingHeader.fromParams({ 'service_level_objective.name': request.serviceLevelObjective!.name || '', }); + this.initialize(); return this._innerApiCalls.updateServiceLevelObjective(request, options, callback); } deleteServiceLevelObjective( @@ -825,6 +860,7 @@ export class ServiceMonitoringServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.deleteServiceLevelObjective(request, options, callback); } @@ -924,6 +960,7 @@ export class ServiceMonitoringServiceClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.listServices(request, options, callback); } @@ -987,6 +1024,7 @@ export class ServiceMonitoringServiceClient { 'parent': request.parent || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listServices.createStream( this._innerApiCalls.listServices as gax.GaxCall, request, @@ -1080,6 +1118,7 @@ export class ServiceMonitoringServiceClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.listServiceLevelObjectives(request, options, callback); } @@ -1134,6 +1173,7 @@ export class ServiceMonitoringServiceClient { 'parent': request.parent || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listServiceLevelObjectives.createStream( this._innerApiCalls.listServiceLevelObjectives as gax.GaxCall, request, @@ -2092,8 +2132,9 @@ export class ServiceMonitoringServiceClient { * The client will no longer be usable and all future behavior is undefined. */ close(): Promise { + this.initialize(); if (!this._terminated) { - return this.serviceMonitoringServiceStub.then(stub => { + return this.serviceMonitoringServiceStub!.then(stub => { this._terminated = true; stub.close(); }); diff --git a/baselines/monitoring/src/v3/uptime_check_service_client.ts.baseline b/baselines/monitoring/src/v3/uptime_check_service_client.ts.baseline index 58edbbce7..b98b04ff5 100644 --- a/baselines/monitoring/src/v3/uptime_check_service_client.ts.baseline +++ b/baselines/monitoring/src/v3/uptime_check_service_client.ts.baseline @@ -43,8 +43,13 @@ export class UptimeCheckServiceClient { private _innerApiCalls: {[name: string]: Function}; private _pathTemplates: {[name: string]: gax.PathTemplate}; private _terminated = false; + private _opts: ClientOptions; + private _gaxModule: typeof gax | typeof gax.fallback; + private _gaxGrpc: gax.GrpcClient | gax.fallback.GrpcClient; + private _protos: {}; + private _defaults: {[method: string]: gax.CallSettings}; auth: gax.GoogleAuth; - uptimeCheckServiceStub: Promise<{[name: string]: Function}>; + uptimeCheckServiceStub?: Promise<{[name: string]: Function}>; /** * Construct an instance of UptimeCheckServiceClient. @@ -95,28 +100,31 @@ export class UptimeCheckServiceClient { // If we are in browser, we are already using fallback because of the // "browser" field in package.json. // But if we were explicitly requested to use fallback, let's do it now. - const gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; + this._gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; // Create a `gaxGrpc` object, with any grpc-specific options // sent to the client. opts.scopes = (this.constructor as typeof UptimeCheckServiceClient).scopes; - const gaxGrpc = new gaxModule.GrpcClient(opts); + this._gaxGrpc = new this._gaxModule.GrpcClient(opts); + + // Save options to use in initialize() method. + this._opts = opts; // Save the auth object to the client, for use by other methods. - this.auth = (gaxGrpc.auth as gax.GoogleAuth); + this.auth = (this._gaxGrpc.auth as gax.GoogleAuth); // Determine the client header string. const clientHeader = [ - `gax/${gaxModule.version}`, + `gax/${this._gaxModule.version}`, `gapic/${version}`, ]; if (typeof process !== 'undefined' && 'versions' in process) { clientHeader.push(`gl-node/${process.versions.node}`); } else { - clientHeader.push(`gl-web/${gaxModule.version}`); + clientHeader.push(`gl-web/${this._gaxModule.version}`); } if (!opts.fallback) { - clientHeader.push(`grpc/${gaxGrpc.grpcVersion}`); + clientHeader.push(`grpc/${this._gaxGrpc.grpcVersion}`); } if (opts.libName && opts.libVersion) { clientHeader.push(`${opts.libName}/${opts.libVersion}`); @@ -126,7 +134,7 @@ export class UptimeCheckServiceClient { // For browsers, pass the JSON content. const nodejsProtoPath = path.join(__dirname, '..', '..', 'protos', 'protos.json'); - const protos = gaxGrpc.loadProto( + this._protos = this._gaxGrpc.loadProto( opts.fallback ? require("../../protos/protos.json") : nodejsProtoPath @@ -136,76 +144,76 @@ export class UptimeCheckServiceClient { // identifiers to uniquely identify resources within the API. // Create useful helper objects for these. this._pathTemplates = { - folderAlertPolicyPathTemplate: new gaxModule.PathTemplate( + folderAlertPolicyPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/alertPolicies/{alert_policy}' ), - folderAlertPolicyConditionPathTemplate: new gaxModule.PathTemplate( + folderAlertPolicyConditionPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/alertPolicies/{alert_policy}/conditions/{condition}' ), - folderChannelDescriptorPathTemplate: new gaxModule.PathTemplate( + folderChannelDescriptorPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/notificationChannelDescriptors/{channel_descriptor}' ), - folderGroupPathTemplate: new gaxModule.PathTemplate( + folderGroupPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/groups/{group}' ), - folderNotificationChannelPathTemplate: new gaxModule.PathTemplate( + folderNotificationChannelPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/notificationChannels/{notification_channel}' ), - folderServicePathTemplate: new gaxModule.PathTemplate( + folderServicePathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/services/{service}' ), - folderServiceServiceLevelObjectivePathTemplate: new gaxModule.PathTemplate( + folderServiceServiceLevelObjectivePathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/services/{service}/serviceLevelObjectives/{service_level_objective}' ), - folderUptimeCheckConfigPathTemplate: new gaxModule.PathTemplate( + folderUptimeCheckConfigPathTemplate: new this._gaxModule.PathTemplate( 'folders/{folder}/uptimeCheckConfigs/{uptime_check_config}' ), - organizationAlertPolicyPathTemplate: new gaxModule.PathTemplate( + organizationAlertPolicyPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/alertPolicies/{alert_policy}' ), - organizationAlertPolicyConditionPathTemplate: new gaxModule.PathTemplate( + organizationAlertPolicyConditionPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/alertPolicies/{alert_policy}/conditions/{condition}' ), - organizationChannelDescriptorPathTemplate: new gaxModule.PathTemplate( + organizationChannelDescriptorPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/notificationChannelDescriptors/{channel_descriptor}' ), - organizationGroupPathTemplate: new gaxModule.PathTemplate( + organizationGroupPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/groups/{group}' ), - organizationNotificationChannelPathTemplate: new gaxModule.PathTemplate( + organizationNotificationChannelPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/notificationChannels/{notification_channel}' ), - organizationServicePathTemplate: new gaxModule.PathTemplate( + organizationServicePathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/services/{service}' ), - organizationServiceServiceLevelObjectivePathTemplate: new gaxModule.PathTemplate( + organizationServiceServiceLevelObjectivePathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/services/{service}/serviceLevelObjectives/{service_level_objective}' ), - organizationUptimeCheckConfigPathTemplate: new gaxModule.PathTemplate( + organizationUptimeCheckConfigPathTemplate: new this._gaxModule.PathTemplate( 'organizations/{organization}/uptimeCheckConfigs/{uptime_check_config}' ), - projectAlertPolicyPathTemplate: new gaxModule.PathTemplate( + projectAlertPolicyPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/alertPolicies/{alert_policy}' ), - projectAlertPolicyConditionPathTemplate: new gaxModule.PathTemplate( + projectAlertPolicyConditionPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/alertPolicies/{alert_policy}/conditions/{condition}' ), - projectChannelDescriptorPathTemplate: new gaxModule.PathTemplate( + projectChannelDescriptorPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/notificationChannelDescriptors/{channel_descriptor}' ), - projectGroupPathTemplate: new gaxModule.PathTemplate( + projectGroupPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/groups/{group}' ), - projectNotificationChannelPathTemplate: new gaxModule.PathTemplate( + projectNotificationChannelPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/notificationChannels/{notification_channel}' ), - projectServicePathTemplate: new gaxModule.PathTemplate( + projectServicePathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/services/{service}' ), - projectServiceServiceLevelObjectivePathTemplate: new gaxModule.PathTemplate( + projectServiceServiceLevelObjectivePathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/services/{service}/serviceLevelObjectives/{service_level_objective}' ), - projectUptimeCheckConfigPathTemplate: new gaxModule.PathTemplate( + projectUptimeCheckConfigPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/uptimeCheckConfigs/{uptime_check_config}' ), }; @@ -215,13 +223,13 @@ export class UptimeCheckServiceClient { // pages). Denote the keys used for pagination and results. this._descriptors.page = { listUptimeCheckConfigs: - new gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'uptimeCheckConfigs'), + new this._gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'uptimeCheckConfigs'), listUptimeCheckIps: - new gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'uptimeCheckIps') + new this._gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'uptimeCheckIps') }; // Put together the default options sent with requests. - const defaults = gaxGrpc.constructSettings( + this._defaults = this._gaxGrpc.constructSettings( 'google.monitoring.v3.UptimeCheckService', gapicConfig as gax.ClientConfig, opts.clientConfig || {}, {'x-goog-api-client': clientHeader.join(' ')}); @@ -229,15 +237,33 @@ export class UptimeCheckServiceClient { // of calling the API is handled in `google-gax`, with this code // merely providing the destination and request information. this._innerApiCalls = {}; + } + + /** + * Initialize the client. + * Performs asynchronous operations (such as authentication) and prepares the client. + * This function will be called automatically when any class method is called for the + * first time, but if you need to initialize it before calling an actual method, + * feel free to call initialize() directly. + * + * You can await on this method if you want to make sure the client is initialized. + * + * @returns {Promise} A promise that resolves to an authenticated service stub. + */ + initialize() { + // If the client stub promise is already initialized, return immediately. + if (this.uptimeCheckServiceStub) { + return this.uptimeCheckServiceStub; + } // Put together the "service stub" for // google.monitoring.v3.UptimeCheckService. - this.uptimeCheckServiceStub = gaxGrpc.createStub( - opts.fallback ? - (protos as protobuf.Root).lookupService('google.monitoring.v3.UptimeCheckService') : + this.uptimeCheckServiceStub = this._gaxGrpc.createStub( + this._opts.fallback ? + (this._protos as protobuf.Root).lookupService('google.monitoring.v3.UptimeCheckService') : // tslint:disable-next-line no-any - (protos as any).google.monitoring.v3.UptimeCheckService, - opts) as Promise<{[method: string]: Function}>; + (this._protos as any).google.monitoring.v3.UptimeCheckService, + this._opts) as Promise<{[method: string]: Function}>; // Iterate over each of the methods that the service provides // and create an API call method for each. @@ -256,9 +282,9 @@ export class UptimeCheckServiceClient { throw err; }); - const apiCall = gaxModule.createApiCall( + const apiCall = this._gaxModule.createApiCall( innerCallPromise, - defaults[methodName], + this._defaults[methodName], this._descriptors.page[methodName] || this._descriptors.stream[methodName] || this._descriptors.longrunning[methodName] @@ -272,6 +298,8 @@ export class UptimeCheckServiceClient { return apiCall(argument, callOptions, callback); }; } + + return this.uptimeCheckServiceStub; } /** @@ -385,6 +413,7 @@ export class UptimeCheckServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.getUptimeCheckConfig(request, options, callback); } createUptimeCheckConfig( @@ -447,6 +476,7 @@ export class UptimeCheckServiceClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.createUptimeCheckConfig(request, options, callback); } updateUptimeCheckConfig( @@ -524,6 +554,7 @@ export class UptimeCheckServiceClient { ] = gax.routingHeader.fromParams({ 'uptime_check_config.name': request.uptimeCheckConfig!.name || '', }); + this.initialize(); return this._innerApiCalls.updateUptimeCheckConfig(request, options, callback); } deleteUptimeCheckConfig( @@ -586,6 +617,7 @@ export class UptimeCheckServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.deleteUptimeCheckConfig(request, options, callback); } @@ -672,6 +704,7 @@ export class UptimeCheckServiceClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.listUptimeCheckConfigs(request, options, callback); } @@ -721,6 +754,7 @@ export class UptimeCheckServiceClient { 'parent': request.parent || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listUptimeCheckConfigs.createStream( this._innerApiCalls.listUptimeCheckConfigs as gax.GaxCall, request, @@ -801,6 +835,7 @@ export class UptimeCheckServiceClient { options = optionsOrCallback as gax.CallOptions; } options = options || {}; + this.initialize(); return this._innerApiCalls.listUptimeCheckIps(request, options, callback); } @@ -842,6 +877,7 @@ export class UptimeCheckServiceClient { request = request || {}; options = options || {}; const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listUptimeCheckIps.createStream( this._innerApiCalls.listUptimeCheckIps as gax.GaxCall, request, @@ -1800,8 +1836,9 @@ export class UptimeCheckServiceClient { * The client will no longer be usable and all future behavior is undefined. */ close(): Promise { + this.initialize(); if (!this._terminated) { - return this.uptimeCheckServiceStub.then(stub => { + return this.uptimeCheckServiceStub!.then(stub => { this._terminated = true; stub.close(); }); diff --git a/baselines/monitoring/test/gapic-alert_policy_service-v3.ts.baseline b/baselines/monitoring/test/gapic-alert_policy_service-v3.ts.baseline index 13fa999b8..d819d6c13 100644 --- a/baselines/monitoring/test/gapic-alert_policy_service-v3.ts.baseline +++ b/baselines/monitoring/test/gapic-alert_policy_service-v3.ts.baseline @@ -78,12 +78,30 @@ describe('v3.AlertPolicyServiceClient', () => { }); assert(client); }); + it('has initialize method and supports deferred initialization', async () => { + const client = new alertpolicyserviceModule.v3.AlertPolicyServiceClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + assert.strictEqual(client.alertPolicyServiceStub, undefined); + await client.initialize(); + assert(client.alertPolicyServiceStub); + }); + it('has close method', () => { + const client = new alertpolicyserviceModule.v3.AlertPolicyServiceClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + client.close(); + }); describe('getAlertPolicy', () => { it('invokes getAlertPolicy without error', done => { const client = new alertpolicyserviceModule.v3.AlertPolicyServiceClient({ credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IGetAlertPolicyRequest = {}; request.name = ''; @@ -107,6 +125,8 @@ describe('v3.AlertPolicyServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IGetAlertPolicyRequest = {}; request.name = ''; @@ -132,6 +152,8 @@ describe('v3.AlertPolicyServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.ICreateAlertPolicyRequest = {}; request.name = ''; @@ -155,6 +177,8 @@ describe('v3.AlertPolicyServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.ICreateAlertPolicyRequest = {}; request.name = ''; @@ -180,6 +204,8 @@ describe('v3.AlertPolicyServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IDeleteAlertPolicyRequest = {}; request.name = ''; @@ -203,6 +229,8 @@ describe('v3.AlertPolicyServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IDeleteAlertPolicyRequest = {}; request.name = ''; @@ -228,6 +256,8 @@ describe('v3.AlertPolicyServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IUpdateAlertPolicyRequest = {}; request.alertPolicy = {}; @@ -252,6 +282,8 @@ describe('v3.AlertPolicyServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IUpdateAlertPolicyRequest = {}; request.alertPolicy = {}; @@ -278,6 +310,8 @@ describe('v3.AlertPolicyServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IListAlertPoliciesRequest = {}; request.name = ''; @@ -301,6 +335,8 @@ describe('v3.AlertPolicyServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IListAlertPoliciesRequest = {}; request.name = ''; diff --git a/baselines/monitoring/test/gapic-group_service-v3.ts.baseline b/baselines/monitoring/test/gapic-group_service-v3.ts.baseline index df8dfb910..5ce2c4377 100644 --- a/baselines/monitoring/test/gapic-group_service-v3.ts.baseline +++ b/baselines/monitoring/test/gapic-group_service-v3.ts.baseline @@ -78,12 +78,30 @@ describe('v3.GroupServiceClient', () => { }); assert(client); }); + it('has initialize method and supports deferred initialization', async () => { + const client = new groupserviceModule.v3.GroupServiceClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + assert.strictEqual(client.groupServiceStub, undefined); + await client.initialize(); + assert(client.groupServiceStub); + }); + it('has close method', () => { + const client = new groupserviceModule.v3.GroupServiceClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + client.close(); + }); describe('getGroup', () => { it('invokes getGroup without error', done => { const client = new groupserviceModule.v3.GroupServiceClient({ credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IGetGroupRequest = {}; request.name = ''; @@ -107,6 +125,8 @@ describe('v3.GroupServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IGetGroupRequest = {}; request.name = ''; @@ -132,6 +152,8 @@ describe('v3.GroupServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.ICreateGroupRequest = {}; request.name = ''; @@ -155,6 +177,8 @@ describe('v3.GroupServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.ICreateGroupRequest = {}; request.name = ''; @@ -180,6 +204,8 @@ describe('v3.GroupServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IUpdateGroupRequest = {}; request.group = {}; @@ -204,6 +230,8 @@ describe('v3.GroupServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IUpdateGroupRequest = {}; request.group = {}; @@ -230,6 +258,8 @@ describe('v3.GroupServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IDeleteGroupRequest = {}; request.name = ''; @@ -253,6 +283,8 @@ describe('v3.GroupServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IDeleteGroupRequest = {}; request.name = ''; @@ -278,6 +310,8 @@ describe('v3.GroupServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IListGroupsRequest = {}; request.name = ''; @@ -301,6 +335,8 @@ describe('v3.GroupServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IListGroupsRequest = {}; request.name = ''; @@ -326,6 +362,8 @@ describe('v3.GroupServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IListGroupMembersRequest = {}; request.name = ''; @@ -349,6 +387,8 @@ describe('v3.GroupServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IListGroupMembersRequest = {}; request.name = ''; diff --git a/baselines/monitoring/test/gapic-metric_service-v3.ts.baseline b/baselines/monitoring/test/gapic-metric_service-v3.ts.baseline index a709a3212..3ad923e29 100644 --- a/baselines/monitoring/test/gapic-metric_service-v3.ts.baseline +++ b/baselines/monitoring/test/gapic-metric_service-v3.ts.baseline @@ -78,12 +78,30 @@ describe('v3.MetricServiceClient', () => { }); assert(client); }); + it('has initialize method and supports deferred initialization', async () => { + const client = new metricserviceModule.v3.MetricServiceClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + assert.strictEqual(client.metricServiceStub, undefined); + await client.initialize(); + assert(client.metricServiceStub); + }); + it('has close method', () => { + const client = new metricserviceModule.v3.MetricServiceClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + client.close(); + }); describe('getMonitoredResourceDescriptor', () => { it('invokes getMonitoredResourceDescriptor without error', done => { const client = new metricserviceModule.v3.MetricServiceClient({ credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IGetMonitoredResourceDescriptorRequest = {}; request.name = ''; @@ -107,6 +125,8 @@ describe('v3.MetricServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IGetMonitoredResourceDescriptorRequest = {}; request.name = ''; @@ -132,6 +152,8 @@ describe('v3.MetricServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IGetMetricDescriptorRequest = {}; request.name = ''; @@ -155,6 +177,8 @@ describe('v3.MetricServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IGetMetricDescriptorRequest = {}; request.name = ''; @@ -180,6 +204,8 @@ describe('v3.MetricServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.ICreateMetricDescriptorRequest = {}; request.name = ''; @@ -203,6 +229,8 @@ describe('v3.MetricServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.ICreateMetricDescriptorRequest = {}; request.name = ''; @@ -228,6 +256,8 @@ describe('v3.MetricServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IDeleteMetricDescriptorRequest = {}; request.name = ''; @@ -251,6 +281,8 @@ describe('v3.MetricServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IDeleteMetricDescriptorRequest = {}; request.name = ''; @@ -276,6 +308,8 @@ describe('v3.MetricServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.ICreateTimeSeriesRequest = {}; request.name = ''; @@ -299,6 +333,8 @@ describe('v3.MetricServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.ICreateTimeSeriesRequest = {}; request.name = ''; @@ -324,6 +360,8 @@ describe('v3.MetricServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IListMonitoredResourceDescriptorsRequest = {}; request.name = ''; @@ -347,6 +385,8 @@ describe('v3.MetricServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IListMonitoredResourceDescriptorsRequest = {}; request.name = ''; @@ -372,6 +412,8 @@ describe('v3.MetricServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IListMetricDescriptorsRequest = {}; request.name = ''; @@ -395,6 +437,8 @@ describe('v3.MetricServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IListMetricDescriptorsRequest = {}; request.name = ''; @@ -420,6 +464,8 @@ describe('v3.MetricServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IListTimeSeriesRequest = {}; request.name = ''; @@ -443,6 +489,8 @@ describe('v3.MetricServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IListTimeSeriesRequest = {}; request.name = ''; diff --git a/baselines/monitoring/test/gapic-notification_channel_service-v3.ts.baseline b/baselines/monitoring/test/gapic-notification_channel_service-v3.ts.baseline index e3fff90fc..f5928fd7d 100644 --- a/baselines/monitoring/test/gapic-notification_channel_service-v3.ts.baseline +++ b/baselines/monitoring/test/gapic-notification_channel_service-v3.ts.baseline @@ -78,12 +78,30 @@ describe('v3.NotificationChannelServiceClient', () => { }); assert(client); }); + it('has initialize method and supports deferred initialization', async () => { + const client = new notificationchannelserviceModule.v3.NotificationChannelServiceClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + assert.strictEqual(client.notificationChannelServiceStub, undefined); + await client.initialize(); + assert(client.notificationChannelServiceStub); + }); + it('has close method', () => { + const client = new notificationchannelserviceModule.v3.NotificationChannelServiceClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + client.close(); + }); describe('getNotificationChannelDescriptor', () => { it('invokes getNotificationChannelDescriptor without error', done => { const client = new notificationchannelserviceModule.v3.NotificationChannelServiceClient({ credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IGetNotificationChannelDescriptorRequest = {}; request.name = ''; @@ -107,6 +125,8 @@ describe('v3.NotificationChannelServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IGetNotificationChannelDescriptorRequest = {}; request.name = ''; @@ -132,6 +152,8 @@ describe('v3.NotificationChannelServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IGetNotificationChannelRequest = {}; request.name = ''; @@ -155,6 +177,8 @@ describe('v3.NotificationChannelServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IGetNotificationChannelRequest = {}; request.name = ''; @@ -180,6 +204,8 @@ describe('v3.NotificationChannelServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.ICreateNotificationChannelRequest = {}; request.name = ''; @@ -203,6 +229,8 @@ describe('v3.NotificationChannelServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.ICreateNotificationChannelRequest = {}; request.name = ''; @@ -228,6 +256,8 @@ describe('v3.NotificationChannelServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IUpdateNotificationChannelRequest = {}; request.notificationChannel = {}; @@ -252,6 +282,8 @@ describe('v3.NotificationChannelServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IUpdateNotificationChannelRequest = {}; request.notificationChannel = {}; @@ -278,6 +310,8 @@ describe('v3.NotificationChannelServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IDeleteNotificationChannelRequest = {}; request.name = ''; @@ -301,6 +335,8 @@ describe('v3.NotificationChannelServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IDeleteNotificationChannelRequest = {}; request.name = ''; @@ -326,6 +362,8 @@ describe('v3.NotificationChannelServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.ISendNotificationChannelVerificationCodeRequest = {}; request.name = ''; @@ -349,6 +387,8 @@ describe('v3.NotificationChannelServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.ISendNotificationChannelVerificationCodeRequest = {}; request.name = ''; @@ -374,6 +414,8 @@ describe('v3.NotificationChannelServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IGetNotificationChannelVerificationCodeRequest = {}; request.name = ''; @@ -397,6 +439,8 @@ describe('v3.NotificationChannelServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IGetNotificationChannelVerificationCodeRequest = {}; request.name = ''; @@ -422,6 +466,8 @@ describe('v3.NotificationChannelServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IVerifyNotificationChannelRequest = {}; request.name = ''; @@ -445,6 +491,8 @@ describe('v3.NotificationChannelServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IVerifyNotificationChannelRequest = {}; request.name = ''; @@ -470,6 +518,8 @@ describe('v3.NotificationChannelServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IListNotificationChannelDescriptorsRequest = {}; request.name = ''; @@ -493,6 +543,8 @@ describe('v3.NotificationChannelServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IListNotificationChannelDescriptorsRequest = {}; request.name = ''; @@ -518,6 +570,8 @@ describe('v3.NotificationChannelServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IListNotificationChannelsRequest = {}; request.name = ''; @@ -541,6 +595,8 @@ describe('v3.NotificationChannelServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IListNotificationChannelsRequest = {}; request.name = ''; diff --git a/baselines/monitoring/test/gapic-service_monitoring_service-v3.ts.baseline b/baselines/monitoring/test/gapic-service_monitoring_service-v3.ts.baseline index 780f79dd4..9392ce2d1 100644 --- a/baselines/monitoring/test/gapic-service_monitoring_service-v3.ts.baseline +++ b/baselines/monitoring/test/gapic-service_monitoring_service-v3.ts.baseline @@ -78,12 +78,30 @@ describe('v3.ServiceMonitoringServiceClient', () => { }); assert(client); }); + it('has initialize method and supports deferred initialization', async () => { + const client = new servicemonitoringserviceModule.v3.ServiceMonitoringServiceClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + assert.strictEqual(client.serviceMonitoringServiceStub, undefined); + await client.initialize(); + assert(client.serviceMonitoringServiceStub); + }); + it('has close method', () => { + const client = new servicemonitoringserviceModule.v3.ServiceMonitoringServiceClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + client.close(); + }); describe('createService', () => { it('invokes createService without error', done => { const client = new servicemonitoringserviceModule.v3.ServiceMonitoringServiceClient({ credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.ICreateServiceRequest = {}; request.parent = ''; @@ -107,6 +125,8 @@ describe('v3.ServiceMonitoringServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.ICreateServiceRequest = {}; request.parent = ''; @@ -132,6 +152,8 @@ describe('v3.ServiceMonitoringServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IGetServiceRequest = {}; request.name = ''; @@ -155,6 +177,8 @@ describe('v3.ServiceMonitoringServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IGetServiceRequest = {}; request.name = ''; @@ -180,6 +204,8 @@ describe('v3.ServiceMonitoringServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IUpdateServiceRequest = {}; request.service = {}; @@ -204,6 +230,8 @@ describe('v3.ServiceMonitoringServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IUpdateServiceRequest = {}; request.service = {}; @@ -230,6 +258,8 @@ describe('v3.ServiceMonitoringServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IDeleteServiceRequest = {}; request.name = ''; @@ -253,6 +283,8 @@ describe('v3.ServiceMonitoringServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IDeleteServiceRequest = {}; request.name = ''; @@ -278,6 +310,8 @@ describe('v3.ServiceMonitoringServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.ICreateServiceLevelObjectiveRequest = {}; request.parent = ''; @@ -301,6 +335,8 @@ describe('v3.ServiceMonitoringServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.ICreateServiceLevelObjectiveRequest = {}; request.parent = ''; @@ -326,6 +362,8 @@ describe('v3.ServiceMonitoringServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IGetServiceLevelObjectiveRequest = {}; request.name = ''; @@ -349,6 +387,8 @@ describe('v3.ServiceMonitoringServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IGetServiceLevelObjectiveRequest = {}; request.name = ''; @@ -374,6 +414,8 @@ describe('v3.ServiceMonitoringServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IUpdateServiceLevelObjectiveRequest = {}; request.serviceLevelObjective = {}; @@ -398,6 +440,8 @@ describe('v3.ServiceMonitoringServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IUpdateServiceLevelObjectiveRequest = {}; request.serviceLevelObjective = {}; @@ -424,6 +468,8 @@ describe('v3.ServiceMonitoringServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IDeleteServiceLevelObjectiveRequest = {}; request.name = ''; @@ -447,6 +493,8 @@ describe('v3.ServiceMonitoringServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IDeleteServiceLevelObjectiveRequest = {}; request.name = ''; @@ -472,6 +520,8 @@ describe('v3.ServiceMonitoringServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IListServicesRequest = {}; request.parent = ''; @@ -495,6 +545,8 @@ describe('v3.ServiceMonitoringServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IListServicesRequest = {}; request.parent = ''; @@ -520,6 +572,8 @@ describe('v3.ServiceMonitoringServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IListServiceLevelObjectivesRequest = {}; request.parent = ''; @@ -543,6 +597,8 @@ describe('v3.ServiceMonitoringServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IListServiceLevelObjectivesRequest = {}; request.parent = ''; diff --git a/baselines/monitoring/test/gapic-uptime_check_service-v3.ts.baseline b/baselines/monitoring/test/gapic-uptime_check_service-v3.ts.baseline index f7c232f70..21a9700c3 100644 --- a/baselines/monitoring/test/gapic-uptime_check_service-v3.ts.baseline +++ b/baselines/monitoring/test/gapic-uptime_check_service-v3.ts.baseline @@ -78,12 +78,30 @@ describe('v3.UptimeCheckServiceClient', () => { }); assert(client); }); + it('has initialize method and supports deferred initialization', async () => { + const client = new uptimecheckserviceModule.v3.UptimeCheckServiceClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + assert.strictEqual(client.uptimeCheckServiceStub, undefined); + await client.initialize(); + assert(client.uptimeCheckServiceStub); + }); + it('has close method', () => { + const client = new uptimecheckserviceModule.v3.UptimeCheckServiceClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + client.close(); + }); describe('getUptimeCheckConfig', () => { it('invokes getUptimeCheckConfig without error', done => { const client = new uptimecheckserviceModule.v3.UptimeCheckServiceClient({ credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IGetUptimeCheckConfigRequest = {}; request.name = ''; @@ -107,6 +125,8 @@ describe('v3.UptimeCheckServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IGetUptimeCheckConfigRequest = {}; request.name = ''; @@ -132,6 +152,8 @@ describe('v3.UptimeCheckServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.ICreateUptimeCheckConfigRequest = {}; request.parent = ''; @@ -155,6 +177,8 @@ describe('v3.UptimeCheckServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.ICreateUptimeCheckConfigRequest = {}; request.parent = ''; @@ -180,6 +204,8 @@ describe('v3.UptimeCheckServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IUpdateUptimeCheckConfigRequest = {}; request.uptimeCheckConfig = {}; @@ -204,6 +230,8 @@ describe('v3.UptimeCheckServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IUpdateUptimeCheckConfigRequest = {}; request.uptimeCheckConfig = {}; @@ -230,6 +258,8 @@ describe('v3.UptimeCheckServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IDeleteUptimeCheckConfigRequest = {}; request.name = ''; @@ -253,6 +283,8 @@ describe('v3.UptimeCheckServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IDeleteUptimeCheckConfigRequest = {}; request.name = ''; @@ -278,6 +310,8 @@ describe('v3.UptimeCheckServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IListUptimeCheckConfigsRequest = {}; request.parent = ''; @@ -301,6 +335,8 @@ describe('v3.UptimeCheckServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IListUptimeCheckConfigsRequest = {}; request.parent = ''; @@ -326,6 +362,8 @@ describe('v3.UptimeCheckServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IListUptimeCheckIpsRequest = {}; // Mock response @@ -348,6 +386,8 @@ describe('v3.UptimeCheckServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.monitoring.v3.IListUptimeCheckIpsRequest = {}; // Mock response diff --git a/baselines/redis/src/v1beta1/cloud_redis_client.ts.baseline b/baselines/redis/src/v1beta1/cloud_redis_client.ts.baseline index cd56952de..a4edbac76 100644 --- a/baselines/redis/src/v1beta1/cloud_redis_client.ts.baseline +++ b/baselines/redis/src/v1beta1/cloud_redis_client.ts.baseline @@ -50,9 +50,14 @@ export class CloudRedisClient { private _innerApiCalls: {[name: string]: Function}; private _pathTemplates: {[name: string]: gax.PathTemplate}; private _terminated = false; + private _opts: ClientOptions; + private _gaxModule: typeof gax | typeof gax.fallback; + private _gaxGrpc: gax.GrpcClient | gax.fallback.GrpcClient; + private _protos: {}; + private _defaults: {[method: string]: gax.CallSettings}; auth: gax.GoogleAuth; operationsClient: gax.OperationsClient; - cloudRedisStub: Promise<{[name: string]: Function}>; + cloudRedisStub?: Promise<{[name: string]: Function}>; /** * Construct an instance of CloudRedisClient. @@ -103,28 +108,31 @@ export class CloudRedisClient { // If we are in browser, we are already using fallback because of the // "browser" field in package.json. // But if we were explicitly requested to use fallback, let's do it now. - const gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; + this._gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; // Create a `gaxGrpc` object, with any grpc-specific options // sent to the client. opts.scopes = (this.constructor as typeof CloudRedisClient).scopes; - const gaxGrpc = new gaxModule.GrpcClient(opts); + this._gaxGrpc = new this._gaxModule.GrpcClient(opts); + + // Save options to use in initialize() method. + this._opts = opts; // Save the auth object to the client, for use by other methods. - this.auth = (gaxGrpc.auth as gax.GoogleAuth); + this.auth = (this._gaxGrpc.auth as gax.GoogleAuth); // Determine the client header string. const clientHeader = [ - `gax/${gaxModule.version}`, + `gax/${this._gaxModule.version}`, `gapic/${version}`, ]; if (typeof process !== 'undefined' && 'versions' in process) { clientHeader.push(`gl-node/${process.versions.node}`); } else { - clientHeader.push(`gl-web/${gaxModule.version}`); + clientHeader.push(`gl-web/${this._gaxModule.version}`); } if (!opts.fallback) { - clientHeader.push(`grpc/${gaxGrpc.grpcVersion}`); + clientHeader.push(`grpc/${this._gaxGrpc.grpcVersion}`); } if (opts.libName && opts.libVersion) { clientHeader.push(`${opts.libName}/${opts.libVersion}`); @@ -134,7 +142,7 @@ export class CloudRedisClient { // For browsers, pass the JSON content. const nodejsProtoPath = path.join(__dirname, '..', '..', 'protos', 'protos.json'); - const protos = gaxGrpc.loadProto( + this._protos = this._gaxGrpc.loadProto( opts.fallback ? require("../../protos/protos.json") : nodejsProtoPath @@ -144,10 +152,10 @@ export class CloudRedisClient { // identifiers to uniquely identify resources within the API. // Create useful helper objects for these. this._pathTemplates = { - instancePathTemplate: new gaxModule.PathTemplate( + instancePathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/locations/{location}/instances/{instance}' ), - locationPathTemplate: new gaxModule.PathTemplate( + locationPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/locations/{location}' ), }; @@ -157,19 +165,19 @@ export class CloudRedisClient { // pages). Denote the keys used for pagination and results. this._descriptors.page = { listInstances: - new gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'instances') + new this._gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'instances') }; // This API contains "long-running operations", which return a // an Operation object that allows for tracking of the operation, // rather than holding a request open. const protoFilesRoot = opts.fallback? - gaxModule.protobuf.Root.fromJSON(require("../../protos/protos.json")) : - gaxModule.protobuf.loadSync(nodejsProtoPath); + this._gaxModule.protobuf.Root.fromJSON(require("../../protos/protos.json")) : + this._gaxModule.protobuf.loadSync(nodejsProtoPath); - this.operationsClient = gaxModule.lro({ + this.operationsClient = this._gaxModule.lro({ auth: this.auth, - grpc: 'grpc' in gaxGrpc ? gaxGrpc.grpc : undefined + grpc: 'grpc' in this._gaxGrpc ? this._gaxGrpc.grpc : undefined }).operationsClient(opts); const createInstanceResponse = protoFilesRoot.lookup( '.google.cloud.redis.v1beta1.Instance') as gax.protobuf.Type; @@ -197,34 +205,34 @@ export class CloudRedisClient { '.google.protobuf.Any') as gax.protobuf.Type; this._descriptors.longrunning = { - createInstance: new gaxModule.LongrunningDescriptor( + createInstance: new this._gaxModule.LongrunningDescriptor( this.operationsClient, createInstanceResponse.decode.bind(createInstanceResponse), createInstanceMetadata.decode.bind(createInstanceMetadata)), - updateInstance: new gaxModule.LongrunningDescriptor( + updateInstance: new this._gaxModule.LongrunningDescriptor( this.operationsClient, updateInstanceResponse.decode.bind(updateInstanceResponse), updateInstanceMetadata.decode.bind(updateInstanceMetadata)), - importInstance: new gaxModule.LongrunningDescriptor( + importInstance: new this._gaxModule.LongrunningDescriptor( this.operationsClient, importInstanceResponse.decode.bind(importInstanceResponse), importInstanceMetadata.decode.bind(importInstanceMetadata)), - exportInstance: new gaxModule.LongrunningDescriptor( + exportInstance: new this._gaxModule.LongrunningDescriptor( this.operationsClient, exportInstanceResponse.decode.bind(exportInstanceResponse), exportInstanceMetadata.decode.bind(exportInstanceMetadata)), - failoverInstance: new gaxModule.LongrunningDescriptor( + failoverInstance: new this._gaxModule.LongrunningDescriptor( this.operationsClient, failoverInstanceResponse.decode.bind(failoverInstanceResponse), failoverInstanceMetadata.decode.bind(failoverInstanceMetadata)), - deleteInstance: new gaxModule.LongrunningDescriptor( + deleteInstance: new this._gaxModule.LongrunningDescriptor( this.operationsClient, deleteInstanceResponse.decode.bind(deleteInstanceResponse), deleteInstanceMetadata.decode.bind(deleteInstanceMetadata)) }; // Put together the default options sent with requests. - const defaults = gaxGrpc.constructSettings( + this._defaults = this._gaxGrpc.constructSettings( 'google.cloud.redis.v1beta1.CloudRedis', gapicConfig as gax.ClientConfig, opts.clientConfig || {}, {'x-goog-api-client': clientHeader.join(' ')}); @@ -232,15 +240,33 @@ export class CloudRedisClient { // of calling the API is handled in `google-gax`, with this code // merely providing the destination and request information. this._innerApiCalls = {}; + } + + /** + * Initialize the client. + * Performs asynchronous operations (such as authentication) and prepares the client. + * This function will be called automatically when any class method is called for the + * first time, but if you need to initialize it before calling an actual method, + * feel free to call initialize() directly. + * + * You can await on this method if you want to make sure the client is initialized. + * + * @returns {Promise} A promise that resolves to an authenticated service stub. + */ + initialize() { + // If the client stub promise is already initialized, return immediately. + if (this.cloudRedisStub) { + return this.cloudRedisStub; + } // Put together the "service stub" for // google.cloud.redis.v1beta1.CloudRedis. - this.cloudRedisStub = gaxGrpc.createStub( - opts.fallback ? - (protos as protobuf.Root).lookupService('google.cloud.redis.v1beta1.CloudRedis') : + this.cloudRedisStub = this._gaxGrpc.createStub( + this._opts.fallback ? + (this._protos as protobuf.Root).lookupService('google.cloud.redis.v1beta1.CloudRedis') : // tslint:disable-next-line no-any - (protos as any).google.cloud.redis.v1beta1.CloudRedis, - opts) as Promise<{[method: string]: Function}>; + (this._protos as any).google.cloud.redis.v1beta1.CloudRedis, + this._opts) as Promise<{[method: string]: Function}>; // Iterate over each of the methods that the service provides // and create an API call method for each. @@ -259,9 +285,9 @@ export class CloudRedisClient { throw err; }); - const apiCall = gaxModule.createApiCall( + const apiCall = this._gaxModule.createApiCall( innerCallPromise, - defaults[methodName], + this._defaults[methodName], this._descriptors.page[methodName] || this._descriptors.stream[methodName] || this._descriptors.longrunning[methodName] @@ -275,6 +301,8 @@ export class CloudRedisClient { return apiCall(argument, callOptions, callback); }; } + + return this.cloudRedisStub; } /** @@ -387,6 +415,7 @@ export class CloudRedisClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.getInstance(request, options, callback); } @@ -471,6 +500,7 @@ export class CloudRedisClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.createInstance(request, options, callback); } updateInstance( @@ -544,6 +574,7 @@ export class CloudRedisClient { ] = gax.routingHeader.fromParams({ 'instance.name': request.instance!.name || '', }); + this.initialize(); return this._innerApiCalls.updateInstance(request, options, callback); } importInstance( @@ -614,6 +645,7 @@ export class CloudRedisClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.importInstance(request, options, callback); } exportInstance( @@ -682,6 +714,7 @@ export class CloudRedisClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.exportInstance(request, options, callback); } failoverInstance( @@ -747,6 +780,7 @@ export class CloudRedisClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.failoverInstance(request, options, callback); } deleteInstance( @@ -809,6 +843,7 @@ export class CloudRedisClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.deleteInstance(request, options, callback); } listInstances( @@ -903,6 +938,7 @@ export class CloudRedisClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.listInstances(request, options, callback); } @@ -955,6 +991,7 @@ export class CloudRedisClient { 'parent': request.parent || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listInstances.createStream( this._innerApiCalls.listInstances as gax.GaxCall, request, @@ -1056,8 +1093,9 @@ export class CloudRedisClient { * The client will no longer be usable and all future behavior is undefined. */ close(): Promise { + this.initialize(); if (!this._terminated) { - return this.cloudRedisStub.then(stub => { + return this.cloudRedisStub!.then(stub => { this._terminated = true; stub.close(); }); diff --git a/baselines/redis/test/gapic-cloud_redis-v1beta1.ts.baseline b/baselines/redis/test/gapic-cloud_redis-v1beta1.ts.baseline index 95ae5616d..acfe49320 100644 --- a/baselines/redis/test/gapic-cloud_redis-v1beta1.ts.baseline +++ b/baselines/redis/test/gapic-cloud_redis-v1beta1.ts.baseline @@ -96,12 +96,30 @@ describe('v1beta1.CloudRedisClient', () => { }); assert(client); }); + it('has initialize method and supports deferred initialization', async () => { + const client = new cloudredisModule.v1beta1.CloudRedisClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + assert.strictEqual(client.cloudRedisStub, undefined); + await client.initialize(); + assert(client.cloudRedisStub); + }); + it('has close method', () => { + const client = new cloudredisModule.v1beta1.CloudRedisClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + client.close(); + }); describe('getInstance', () => { it('invokes getInstance without error', done => { const client = new cloudredisModule.v1beta1.CloudRedisClient({ credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.redis.v1beta1.IGetInstanceRequest = {}; request.name = ''; @@ -125,6 +143,8 @@ describe('v1beta1.CloudRedisClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.redis.v1beta1.IGetInstanceRequest = {}; request.name = ''; @@ -150,6 +170,8 @@ describe('v1beta1.CloudRedisClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.redis.v1beta1.ICreateInstanceRequest = {}; request.parent = ''; @@ -176,6 +198,8 @@ describe('v1beta1.CloudRedisClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.redis.v1beta1.ICreateInstanceRequest = {}; request.parent = ''; @@ -205,6 +229,8 @@ describe('v1beta1.CloudRedisClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.redis.v1beta1.IUpdateInstanceRequest = {}; request.instance = {}; @@ -232,6 +258,8 @@ describe('v1beta1.CloudRedisClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.redis.v1beta1.IUpdateInstanceRequest = {}; request.instance = {}; @@ -262,6 +290,8 @@ describe('v1beta1.CloudRedisClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.redis.v1beta1.IImportInstanceRequest = {}; request.name = ''; @@ -288,6 +318,8 @@ describe('v1beta1.CloudRedisClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.redis.v1beta1.IImportInstanceRequest = {}; request.name = ''; @@ -317,6 +349,8 @@ describe('v1beta1.CloudRedisClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.redis.v1beta1.IExportInstanceRequest = {}; request.name = ''; @@ -343,6 +377,8 @@ describe('v1beta1.CloudRedisClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.redis.v1beta1.IExportInstanceRequest = {}; request.name = ''; @@ -372,6 +408,8 @@ describe('v1beta1.CloudRedisClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.redis.v1beta1.IFailoverInstanceRequest = {}; request.name = ''; @@ -398,6 +436,8 @@ describe('v1beta1.CloudRedisClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.redis.v1beta1.IFailoverInstanceRequest = {}; request.name = ''; @@ -427,6 +467,8 @@ describe('v1beta1.CloudRedisClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.redis.v1beta1.IDeleteInstanceRequest = {}; request.name = ''; @@ -453,6 +495,8 @@ describe('v1beta1.CloudRedisClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.redis.v1beta1.IDeleteInstanceRequest = {}; request.name = ''; @@ -482,6 +526,8 @@ describe('v1beta1.CloudRedisClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.redis.v1beta1.IListInstancesRequest = {}; request.parent = ''; @@ -505,6 +551,8 @@ describe('v1beta1.CloudRedisClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.redis.v1beta1.IListInstancesRequest = {}; request.parent = ''; diff --git a/baselines/showcase/src/v1beta1/echo_client.ts.baseline b/baselines/showcase/src/v1beta1/echo_client.ts.baseline index 677197ee9..06bee7c0f 100644 --- a/baselines/showcase/src/v1beta1/echo_client.ts.baseline +++ b/baselines/showcase/src/v1beta1/echo_client.ts.baseline @@ -40,9 +40,14 @@ export class EchoClient { private _innerApiCalls: {[name: string]: Function}; private _pathTemplates: {[name: string]: gax.PathTemplate}; private _terminated = false; + private _opts: ClientOptions; + private _gaxModule: typeof gax | typeof gax.fallback; + private _gaxGrpc: gax.GrpcClient | gax.fallback.GrpcClient; + private _protos: {}; + private _defaults: {[method: string]: gax.CallSettings}; auth: gax.GoogleAuth; operationsClient: gax.OperationsClient; - echoStub: Promise<{[name: string]: Function}>; + echoStub?: Promise<{[name: string]: Function}>; /** * Construct an instance of EchoClient. @@ -93,28 +98,31 @@ export class EchoClient { // If we are in browser, we are already using fallback because of the // "browser" field in package.json. // But if we were explicitly requested to use fallback, let's do it now. - const gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; + this._gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; // Create a `gaxGrpc` object, with any grpc-specific options // sent to the client. opts.scopes = (this.constructor as typeof EchoClient).scopes; - const gaxGrpc = new gaxModule.GrpcClient(opts); + this._gaxGrpc = new this._gaxModule.GrpcClient(opts); + + // Save options to use in initialize() method. + this._opts = opts; // Save the auth object to the client, for use by other methods. - this.auth = (gaxGrpc.auth as gax.GoogleAuth); + this.auth = (this._gaxGrpc.auth as gax.GoogleAuth); // Determine the client header string. const clientHeader = [ - `gax/${gaxModule.version}`, + `gax/${this._gaxModule.version}`, `gapic/${version}`, ]; if (typeof process !== 'undefined' && 'versions' in process) { clientHeader.push(`gl-node/${process.versions.node}`); } else { - clientHeader.push(`gl-web/${gaxModule.version}`); + clientHeader.push(`gl-web/${this._gaxModule.version}`); } if (!opts.fallback) { - clientHeader.push(`grpc/${gaxGrpc.grpcVersion}`); + clientHeader.push(`grpc/${this._gaxGrpc.grpcVersion}`); } if (opts.libName && opts.libVersion) { clientHeader.push(`${opts.libName}/${opts.libVersion}`); @@ -124,7 +132,7 @@ export class EchoClient { // For browsers, pass the JSON content. const nodejsProtoPath = path.join(__dirname, '..', '..', 'protos', 'protos.json'); - const protos = gaxGrpc.loadProto( + this._protos = this._gaxGrpc.loadProto( opts.fallback ? require("../../protos/protos.json") : nodejsProtoPath @@ -134,25 +142,25 @@ export class EchoClient { // identifiers to uniquely identify resources within the API. // Create useful helper objects for these. this._pathTemplates = { - blueprintPathTemplate: new gaxModule.PathTemplate( + blueprintPathTemplate: new this._gaxModule.PathTemplate( 'sessions/{session}/tests/{test}/blueprints/{blueprint}' ), - roomPathTemplate: new gaxModule.PathTemplate( + roomPathTemplate: new this._gaxModule.PathTemplate( 'rooms/{room_id}' ), - roomIdBlurbIdPathTemplate: new gaxModule.PathTemplate( + roomIdBlurbIdPathTemplate: new this._gaxModule.PathTemplate( 'rooms/{room_id}/blurbs/{blurb_id}' ), - sessionPathTemplate: new gaxModule.PathTemplate( + sessionPathTemplate: new this._gaxModule.PathTemplate( 'sessions/{session}' ), - testPathTemplate: new gaxModule.PathTemplate( + testPathTemplate: new this._gaxModule.PathTemplate( 'sessions/{session}/tests/{test}' ), - userPathTemplate: new gaxModule.PathTemplate( + userPathTemplate: new this._gaxModule.PathTemplate( 'users/{user_id}' ), - userIdBlurbIdPathTemplate: new gaxModule.PathTemplate( + userIdBlurbIdPathTemplate: new this._gaxModule.PathTemplate( 'user/{user_id}/profile/blurbs/{blurb_id}' ), }; @@ -162,27 +170,27 @@ export class EchoClient { // pages). Denote the keys used for pagination and results. this._descriptors.page = { pagedExpand: - new gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'responses') + new this._gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'responses') }; // Some of the methods on this service provide streaming responses. // Provide descriptors for these. this._descriptors.stream = { - expand: new gaxModule.StreamDescriptor(gax.StreamType.SERVER_STREAMING), - collect: new gaxModule.StreamDescriptor(gax.StreamType.CLIENT_STREAMING), - chat: new gaxModule.StreamDescriptor(gax.StreamType.BIDI_STREAMING) + expand: new this._gaxModule.StreamDescriptor(gax.StreamType.SERVER_STREAMING), + collect: new this._gaxModule.StreamDescriptor(gax.StreamType.CLIENT_STREAMING), + chat: new this._gaxModule.StreamDescriptor(gax.StreamType.BIDI_STREAMING) }; // This API contains "long-running operations", which return a // an Operation object that allows for tracking of the operation, // rather than holding a request open. const protoFilesRoot = opts.fallback? - gaxModule.protobuf.Root.fromJSON(require("../../protos/protos.json")) : - gaxModule.protobuf.loadSync(nodejsProtoPath); + this._gaxModule.protobuf.Root.fromJSON(require("../../protos/protos.json")) : + this._gaxModule.protobuf.loadSync(nodejsProtoPath); - this.operationsClient = gaxModule.lro({ + this.operationsClient = this._gaxModule.lro({ auth: this.auth, - grpc: 'grpc' in gaxGrpc ? gaxGrpc.grpc : undefined + grpc: 'grpc' in this._gaxGrpc ? this._gaxGrpc.grpc : undefined }).operationsClient(opts); const waitResponse = protoFilesRoot.lookup( '.google.showcase.v1beta1.WaitResponse') as gax.protobuf.Type; @@ -190,14 +198,14 @@ export class EchoClient { '.google.showcase.v1beta1.WaitMetadata') as gax.protobuf.Type; this._descriptors.longrunning = { - wait: new gaxModule.LongrunningDescriptor( + wait: new this._gaxModule.LongrunningDescriptor( this.operationsClient, waitResponse.decode.bind(waitResponse), waitMetadata.decode.bind(waitMetadata)) }; // Put together the default options sent with requests. - const defaults = gaxGrpc.constructSettings( + this._defaults = this._gaxGrpc.constructSettings( 'google.showcase.v1beta1.Echo', gapicConfig as gax.ClientConfig, opts.clientConfig || {}, {'x-goog-api-client': clientHeader.join(' ')}); @@ -205,15 +213,33 @@ export class EchoClient { // of calling the API is handled in `google-gax`, with this code // merely providing the destination and request information. this._innerApiCalls = {}; + } + + /** + * Initialize the client. + * Performs asynchronous operations (such as authentication) and prepares the client. + * This function will be called automatically when any class method is called for the + * first time, but if you need to initialize it before calling an actual method, + * feel free to call initialize() directly. + * + * You can await on this method if you want to make sure the client is initialized. + * + * @returns {Promise} A promise that resolves to an authenticated service stub. + */ + initialize() { + // If the client stub promise is already initialized, return immediately. + if (this.echoStub) { + return this.echoStub; + } // Put together the "service stub" for // google.showcase.v1beta1.Echo. - this.echoStub = gaxGrpc.createStub( - opts.fallback ? - (protos as protobuf.Root).lookupService('google.showcase.v1beta1.Echo') : + this.echoStub = this._gaxGrpc.createStub( + this._opts.fallback ? + (this._protos as protobuf.Root).lookupService('google.showcase.v1beta1.Echo') : // tslint:disable-next-line no-any - (protos as any).google.showcase.v1beta1.Echo, - opts) as Promise<{[method: string]: Function}>; + (this._protos as any).google.showcase.v1beta1.Echo, + this._opts) as Promise<{[method: string]: Function}>; // Iterate over each of the methods that the service provides // and create an API call method for each. @@ -232,9 +258,9 @@ export class EchoClient { throw err; }); - const apiCall = gaxModule.createApiCall( + const apiCall = this._gaxModule.createApiCall( innerCallPromise, - defaults[methodName], + this._defaults[methodName], this._descriptors.page[methodName] || this._descriptors.stream[methodName] || this._descriptors.longrunning[methodName] @@ -248,6 +274,8 @@ export class EchoClient { return apiCall(argument, callOptions, callback); }; } + + return this.echoStub; } /** @@ -349,6 +377,7 @@ export class EchoClient { options = optionsOrCallback as gax.CallOptions; } options = options || {}; + this.initialize(); return this._innerApiCalls.echo(request, options, callback); } block( @@ -408,6 +437,7 @@ export class EchoClient { options = optionsOrCallback as gax.CallOptions; } options = options || {}; + this.initialize(); return this._innerApiCalls.block(request, options, callback); } @@ -432,6 +462,7 @@ export class EchoClient { gax.CancellableStream{ request = request || {}; options = options || {}; + this.initialize(); return this._innerApiCalls.expand(request, options); } @@ -469,6 +500,7 @@ export class EchoClient { optionsOrCallback = {}; } const options = optionsOrCallback as gax.CallOptions; + this.initialize(); return this._innerApiCalls.collect(null, options, callback); } @@ -486,7 +518,8 @@ export class EchoClient { */ chat( options?: gax.CallOptions): - gax.CancellableStream{ + gax.CancellableStream { + this.initialize(); return this._innerApiCalls.chat(options); } @@ -548,6 +581,7 @@ export class EchoClient { options = optionsOrCallback as gax.CallOptions; } options = options || {}; + this.initialize(); return this._innerApiCalls.wait(request, options, callback); } pagedExpand( @@ -620,6 +654,7 @@ export class EchoClient { options = optionsOrCallback as gax.CallOptions; } options = options || {}; + this.initialize(); return this._innerApiCalls.pagedExpand(request, options, callback); } @@ -656,6 +691,7 @@ export class EchoClient { request = request || {}; options = options || {}; const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.pagedExpand.createStream( this._innerApiCalls.pagedExpand as gax.GaxCall, request, @@ -898,8 +934,9 @@ export class EchoClient { * The client will no longer be usable and all future behavior is undefined. */ close(): Promise { + this.initialize(); if (!this._terminated) { - return this.echoStub.then(stub => { + return this.echoStub!.then(stub => { this._terminated = true; stub.close(); }); diff --git a/baselines/showcase/src/v1beta1/identity_client.ts.baseline b/baselines/showcase/src/v1beta1/identity_client.ts.baseline index 7ad1b70c0..142bf47f7 100644 --- a/baselines/showcase/src/v1beta1/identity_client.ts.baseline +++ b/baselines/showcase/src/v1beta1/identity_client.ts.baseline @@ -36,8 +36,13 @@ export class IdentityClient { private _innerApiCalls: {[name: string]: Function}; private _pathTemplates: {[name: string]: gax.PathTemplate}; private _terminated = false; + private _opts: ClientOptions; + private _gaxModule: typeof gax | typeof gax.fallback; + private _gaxGrpc: gax.GrpcClient | gax.fallback.GrpcClient; + private _protos: {}; + private _defaults: {[method: string]: gax.CallSettings}; auth: gax.GoogleAuth; - identityStub: Promise<{[name: string]: Function}>; + identityStub?: Promise<{[name: string]: Function}>; /** * Construct an instance of IdentityClient. @@ -88,28 +93,31 @@ export class IdentityClient { // If we are in browser, we are already using fallback because of the // "browser" field in package.json. // But if we were explicitly requested to use fallback, let's do it now. - const gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; + this._gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; // Create a `gaxGrpc` object, with any grpc-specific options // sent to the client. opts.scopes = (this.constructor as typeof IdentityClient).scopes; - const gaxGrpc = new gaxModule.GrpcClient(opts); + this._gaxGrpc = new this._gaxModule.GrpcClient(opts); + + // Save options to use in initialize() method. + this._opts = opts; // Save the auth object to the client, for use by other methods. - this.auth = (gaxGrpc.auth as gax.GoogleAuth); + this.auth = (this._gaxGrpc.auth as gax.GoogleAuth); // Determine the client header string. const clientHeader = [ - `gax/${gaxModule.version}`, + `gax/${this._gaxModule.version}`, `gapic/${version}`, ]; if (typeof process !== 'undefined' && 'versions' in process) { clientHeader.push(`gl-node/${process.versions.node}`); } else { - clientHeader.push(`gl-web/${gaxModule.version}`); + clientHeader.push(`gl-web/${this._gaxModule.version}`); } if (!opts.fallback) { - clientHeader.push(`grpc/${gaxGrpc.grpcVersion}`); + clientHeader.push(`grpc/${this._gaxGrpc.grpcVersion}`); } if (opts.libName && opts.libVersion) { clientHeader.push(`${opts.libName}/${opts.libVersion}`); @@ -119,7 +127,7 @@ export class IdentityClient { // For browsers, pass the JSON content. const nodejsProtoPath = path.join(__dirname, '..', '..', 'protos', 'protos.json'); - const protos = gaxGrpc.loadProto( + this._protos = this._gaxGrpc.loadProto( opts.fallback ? require("../../protos/protos.json") : nodejsProtoPath @@ -129,25 +137,25 @@ export class IdentityClient { // identifiers to uniquely identify resources within the API. // Create useful helper objects for these. this._pathTemplates = { - blueprintPathTemplate: new gaxModule.PathTemplate( + blueprintPathTemplate: new this._gaxModule.PathTemplate( 'sessions/{session}/tests/{test}/blueprints/{blueprint}' ), - roomPathTemplate: new gaxModule.PathTemplate( + roomPathTemplate: new this._gaxModule.PathTemplate( 'rooms/{room_id}' ), - roomIdBlurbIdPathTemplate: new gaxModule.PathTemplate( + roomIdBlurbIdPathTemplate: new this._gaxModule.PathTemplate( 'rooms/{room_id}/blurbs/{blurb_id}' ), - sessionPathTemplate: new gaxModule.PathTemplate( + sessionPathTemplate: new this._gaxModule.PathTemplate( 'sessions/{session}' ), - testPathTemplate: new gaxModule.PathTemplate( + testPathTemplate: new this._gaxModule.PathTemplate( 'sessions/{session}/tests/{test}' ), - userPathTemplate: new gaxModule.PathTemplate( + userPathTemplate: new this._gaxModule.PathTemplate( 'users/{user_id}' ), - userIdBlurbIdPathTemplate: new gaxModule.PathTemplate( + userIdBlurbIdPathTemplate: new this._gaxModule.PathTemplate( 'user/{user_id}/profile/blurbs/{blurb_id}' ), }; @@ -157,11 +165,11 @@ export class IdentityClient { // pages). Denote the keys used for pagination and results. this._descriptors.page = { listUsers: - new gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'users') + new this._gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'users') }; // Put together the default options sent with requests. - const defaults = gaxGrpc.constructSettings( + this._defaults = this._gaxGrpc.constructSettings( 'google.showcase.v1beta1.Identity', gapicConfig as gax.ClientConfig, opts.clientConfig || {}, {'x-goog-api-client': clientHeader.join(' ')}); @@ -169,15 +177,33 @@ export class IdentityClient { // of calling the API is handled in `google-gax`, with this code // merely providing the destination and request information. this._innerApiCalls = {}; + } + + /** + * Initialize the client. + * Performs asynchronous operations (such as authentication) and prepares the client. + * This function will be called automatically when any class method is called for the + * first time, but if you need to initialize it before calling an actual method, + * feel free to call initialize() directly. + * + * You can await on this method if you want to make sure the client is initialized. + * + * @returns {Promise} A promise that resolves to an authenticated service stub. + */ + initialize() { + // If the client stub promise is already initialized, return immediately. + if (this.identityStub) { + return this.identityStub; + } // Put together the "service stub" for // google.showcase.v1beta1.Identity. - this.identityStub = gaxGrpc.createStub( - opts.fallback ? - (protos as protobuf.Root).lookupService('google.showcase.v1beta1.Identity') : + this.identityStub = this._gaxGrpc.createStub( + this._opts.fallback ? + (this._protos as protobuf.Root).lookupService('google.showcase.v1beta1.Identity') : // tslint:disable-next-line no-any - (protos as any).google.showcase.v1beta1.Identity, - opts) as Promise<{[method: string]: Function}>; + (this._protos as any).google.showcase.v1beta1.Identity, + this._opts) as Promise<{[method: string]: Function}>; // Iterate over each of the methods that the service provides // and create an API call method for each. @@ -196,9 +222,9 @@ export class IdentityClient { throw err; }); - const apiCall = gaxModule.createApiCall( + const apiCall = this._gaxModule.createApiCall( innerCallPromise, - defaults[methodName], + this._defaults[methodName], this._descriptors.page[methodName] || this._descriptors.stream[methodName] || this._descriptors.longrunning[methodName] @@ -212,6 +238,8 @@ export class IdentityClient { return apiCall(argument, callOptions, callback); }; } + + return this.identityStub; } /** @@ -313,6 +341,7 @@ export class IdentityClient { options = optionsOrCallback as gax.CallOptions; } options = options || {}; + this.initialize(); return this._innerApiCalls.createUser(request, options, callback); } getUser( @@ -372,6 +401,7 @@ export class IdentityClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.getUser(request, options, callback); } updateUser( @@ -434,6 +464,7 @@ export class IdentityClient { ] = gax.routingHeader.fromParams({ 'user.name': request.user!.name || '', }); + this.initialize(); return this._innerApiCalls.updateUser(request, options, callback); } deleteUser( @@ -493,6 +524,7 @@ export class IdentityClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.deleteUser(request, options, callback); } @@ -566,6 +598,7 @@ export class IdentityClient { options = optionsOrCallback as gax.CallOptions; } options = options || {}; + this.initialize(); return this._innerApiCalls.listUsers(request, options, callback); } @@ -603,6 +636,7 @@ export class IdentityClient { request = request || {}; options = options || {}; const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listUsers.createStream( this._innerApiCalls.listUsers as gax.GaxCall, request, @@ -845,8 +879,9 @@ export class IdentityClient { * The client will no longer be usable and all future behavior is undefined. */ close(): Promise { + this.initialize(); if (!this._terminated) { - return this.identityStub.then(stub => { + return this.identityStub!.then(stub => { this._terminated = true; stub.close(); }); diff --git a/baselines/showcase/src/v1beta1/messaging_client.ts.baseline b/baselines/showcase/src/v1beta1/messaging_client.ts.baseline index e2e4a0c3b..0544cd67a 100644 --- a/baselines/showcase/src/v1beta1/messaging_client.ts.baseline +++ b/baselines/showcase/src/v1beta1/messaging_client.ts.baseline @@ -39,9 +39,14 @@ export class MessagingClient { private _innerApiCalls: {[name: string]: Function}; private _pathTemplates: {[name: string]: gax.PathTemplate}; private _terminated = false; + private _opts: ClientOptions; + private _gaxModule: typeof gax | typeof gax.fallback; + private _gaxGrpc: gax.GrpcClient | gax.fallback.GrpcClient; + private _protos: {}; + private _defaults: {[method: string]: gax.CallSettings}; auth: gax.GoogleAuth; operationsClient: gax.OperationsClient; - messagingStub: Promise<{[name: string]: Function}>; + messagingStub?: Promise<{[name: string]: Function}>; /** * Construct an instance of MessagingClient. @@ -92,28 +97,31 @@ export class MessagingClient { // If we are in browser, we are already using fallback because of the // "browser" field in package.json. // But if we were explicitly requested to use fallback, let's do it now. - const gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; + this._gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; // Create a `gaxGrpc` object, with any grpc-specific options // sent to the client. opts.scopes = (this.constructor as typeof MessagingClient).scopes; - const gaxGrpc = new gaxModule.GrpcClient(opts); + this._gaxGrpc = new this._gaxModule.GrpcClient(opts); + + // Save options to use in initialize() method. + this._opts = opts; // Save the auth object to the client, for use by other methods. - this.auth = (gaxGrpc.auth as gax.GoogleAuth); + this.auth = (this._gaxGrpc.auth as gax.GoogleAuth); // Determine the client header string. const clientHeader = [ - `gax/${gaxModule.version}`, + `gax/${this._gaxModule.version}`, `gapic/${version}`, ]; if (typeof process !== 'undefined' && 'versions' in process) { clientHeader.push(`gl-node/${process.versions.node}`); } else { - clientHeader.push(`gl-web/${gaxModule.version}`); + clientHeader.push(`gl-web/${this._gaxModule.version}`); } if (!opts.fallback) { - clientHeader.push(`grpc/${gaxGrpc.grpcVersion}`); + clientHeader.push(`grpc/${this._gaxGrpc.grpcVersion}`); } if (opts.libName && opts.libVersion) { clientHeader.push(`${opts.libName}/${opts.libVersion}`); @@ -123,7 +131,7 @@ export class MessagingClient { // For browsers, pass the JSON content. const nodejsProtoPath = path.join(__dirname, '..', '..', 'protos', 'protos.json'); - const protos = gaxGrpc.loadProto( + this._protos = this._gaxGrpc.loadProto( opts.fallback ? require("../../protos/protos.json") : nodejsProtoPath @@ -133,25 +141,25 @@ export class MessagingClient { // identifiers to uniquely identify resources within the API. // Create useful helper objects for these. this._pathTemplates = { - blueprintPathTemplate: new gaxModule.PathTemplate( + blueprintPathTemplate: new this._gaxModule.PathTemplate( 'sessions/{session}/tests/{test}/blueprints/{blueprint}' ), - roomPathTemplate: new gaxModule.PathTemplate( + roomPathTemplate: new this._gaxModule.PathTemplate( 'rooms/{room_id}' ), - roomIdBlurbIdPathTemplate: new gaxModule.PathTemplate( + roomIdBlurbIdPathTemplate: new this._gaxModule.PathTemplate( 'rooms/{room_id}/blurbs/{blurb_id}' ), - sessionPathTemplate: new gaxModule.PathTemplate( + sessionPathTemplate: new this._gaxModule.PathTemplate( 'sessions/{session}' ), - testPathTemplate: new gaxModule.PathTemplate( + testPathTemplate: new this._gaxModule.PathTemplate( 'sessions/{session}/tests/{test}' ), - userPathTemplate: new gaxModule.PathTemplate( + userPathTemplate: new this._gaxModule.PathTemplate( 'users/{user_id}' ), - userIdBlurbIdPathTemplate: new gaxModule.PathTemplate( + userIdBlurbIdPathTemplate: new this._gaxModule.PathTemplate( 'user/{user_id}/profile/blurbs/{blurb_id}' ), }; @@ -161,29 +169,29 @@ export class MessagingClient { // pages). Denote the keys used for pagination and results. this._descriptors.page = { listRooms: - new gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'rooms'), + new this._gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'rooms'), listBlurbs: - new gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'blurbs') + new this._gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'blurbs') }; // Some of the methods on this service provide streaming responses. // Provide descriptors for these. this._descriptors.stream = { - streamBlurbs: new gaxModule.StreamDescriptor(gax.StreamType.SERVER_STREAMING), - sendBlurbs: new gaxModule.StreamDescriptor(gax.StreamType.CLIENT_STREAMING), - connect: new gaxModule.StreamDescriptor(gax.StreamType.BIDI_STREAMING) + streamBlurbs: new this._gaxModule.StreamDescriptor(gax.StreamType.SERVER_STREAMING), + sendBlurbs: new this._gaxModule.StreamDescriptor(gax.StreamType.CLIENT_STREAMING), + connect: new this._gaxModule.StreamDescriptor(gax.StreamType.BIDI_STREAMING) }; // This API contains "long-running operations", which return a // an Operation object that allows for tracking of the operation, // rather than holding a request open. const protoFilesRoot = opts.fallback? - gaxModule.protobuf.Root.fromJSON(require("../../protos/protos.json")) : - gaxModule.protobuf.loadSync(nodejsProtoPath); + this._gaxModule.protobuf.Root.fromJSON(require("../../protos/protos.json")) : + this._gaxModule.protobuf.loadSync(nodejsProtoPath); - this.operationsClient = gaxModule.lro({ + this.operationsClient = this._gaxModule.lro({ auth: this.auth, - grpc: 'grpc' in gaxGrpc ? gaxGrpc.grpc : undefined + grpc: 'grpc' in this._gaxGrpc ? this._gaxGrpc.grpc : undefined }).operationsClient(opts); const searchBlurbsResponse = protoFilesRoot.lookup( '.google.showcase.v1beta1.SearchBlurbsResponse') as gax.protobuf.Type; @@ -191,14 +199,14 @@ export class MessagingClient { '.google.showcase.v1beta1.SearchBlurbsMetadata') as gax.protobuf.Type; this._descriptors.longrunning = { - searchBlurbs: new gaxModule.LongrunningDescriptor( + searchBlurbs: new this._gaxModule.LongrunningDescriptor( this.operationsClient, searchBlurbsResponse.decode.bind(searchBlurbsResponse), searchBlurbsMetadata.decode.bind(searchBlurbsMetadata)) }; // Put together the default options sent with requests. - const defaults = gaxGrpc.constructSettings( + this._defaults = this._gaxGrpc.constructSettings( 'google.showcase.v1beta1.Messaging', gapicConfig as gax.ClientConfig, opts.clientConfig || {}, {'x-goog-api-client': clientHeader.join(' ')}); @@ -206,15 +214,33 @@ export class MessagingClient { // of calling the API is handled in `google-gax`, with this code // merely providing the destination and request information. this._innerApiCalls = {}; + } + + /** + * Initialize the client. + * Performs asynchronous operations (such as authentication) and prepares the client. + * This function will be called automatically when any class method is called for the + * first time, but if you need to initialize it before calling an actual method, + * feel free to call initialize() directly. + * + * You can await on this method if you want to make sure the client is initialized. + * + * @returns {Promise} A promise that resolves to an authenticated service stub. + */ + initialize() { + // If the client stub promise is already initialized, return immediately. + if (this.messagingStub) { + return this.messagingStub; + } // Put together the "service stub" for // google.showcase.v1beta1.Messaging. - this.messagingStub = gaxGrpc.createStub( - opts.fallback ? - (protos as protobuf.Root).lookupService('google.showcase.v1beta1.Messaging') : + this.messagingStub = this._gaxGrpc.createStub( + this._opts.fallback ? + (this._protos as protobuf.Root).lookupService('google.showcase.v1beta1.Messaging') : // tslint:disable-next-line no-any - (protos as any).google.showcase.v1beta1.Messaging, - opts) as Promise<{[method: string]: Function}>; + (this._protos as any).google.showcase.v1beta1.Messaging, + this._opts) as Promise<{[method: string]: Function}>; // Iterate over each of the methods that the service provides // and create an API call method for each. @@ -233,9 +259,9 @@ export class MessagingClient { throw err; }); - const apiCall = gaxModule.createApiCall( + const apiCall = this._gaxModule.createApiCall( innerCallPromise, - defaults[methodName], + this._defaults[methodName], this._descriptors.page[methodName] || this._descriptors.stream[methodName] || this._descriptors.longrunning[methodName] @@ -249,6 +275,8 @@ export class MessagingClient { return apiCall(argument, callOptions, callback); }; } + + return this.messagingStub; } /** @@ -350,6 +378,7 @@ export class MessagingClient { options = optionsOrCallback as gax.CallOptions; } options = options || {}; + this.initialize(); return this._innerApiCalls.createRoom(request, options, callback); } getRoom( @@ -409,6 +438,7 @@ export class MessagingClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.getRoom(request, options, callback); } updateRoom( @@ -471,6 +501,7 @@ export class MessagingClient { ] = gax.routingHeader.fromParams({ 'room.name': request.room!.name || '', }); + this.initialize(); return this._innerApiCalls.updateRoom(request, options, callback); } deleteRoom( @@ -530,6 +561,7 @@ export class MessagingClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.deleteRoom(request, options, callback); } createBlurb( @@ -594,6 +626,7 @@ export class MessagingClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.createBlurb(request, options, callback); } getBlurb( @@ -653,6 +686,7 @@ export class MessagingClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.getBlurb(request, options, callback); } updateBlurb( @@ -715,6 +749,7 @@ export class MessagingClient { ] = gax.routingHeader.fromParams({ 'blurb.name': request.blurb!.name || '', }); + this.initialize(); return this._innerApiCalls.updateBlurb(request, options, callback); } deleteBlurb( @@ -774,6 +809,7 @@ export class MessagingClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.deleteBlurb(request, options, callback); } @@ -805,6 +841,7 @@ export class MessagingClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.streamBlurbs(request, options); } @@ -841,6 +878,7 @@ export class MessagingClient { optionsOrCallback = {}; } const options = optionsOrCallback as gax.CallOptions; + this.initialize(); return this._innerApiCalls.sendBlurbs(null, options, callback); } @@ -859,7 +897,8 @@ export class MessagingClient { */ connect( options?: gax.CallOptions): - gax.CancellableStream{ + gax.CancellableStream { + this.initialize(); return this._innerApiCalls.connect(options); } @@ -935,6 +974,7 @@ export class MessagingClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.searchBlurbs(request, options, callback); } listRooms( @@ -1007,6 +1047,7 @@ export class MessagingClient { options = optionsOrCallback as gax.CallOptions; } options = options || {}; + this.initialize(); return this._innerApiCalls.listRooms(request, options, callback); } @@ -1044,6 +1085,7 @@ export class MessagingClient { request = request || {}; options = options || {}; const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listRooms.createStream( this._innerApiCalls.listRooms as gax.GaxCall, request, @@ -1131,6 +1173,7 @@ export class MessagingClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.listBlurbs(request, options, callback); } @@ -1178,6 +1221,7 @@ export class MessagingClient { 'parent': request.parent || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listBlurbs.createStream( this._innerApiCalls.listBlurbs as gax.GaxCall, request, @@ -1420,8 +1464,9 @@ export class MessagingClient { * The client will no longer be usable and all future behavior is undefined. */ close(): Promise { + this.initialize(); if (!this._terminated) { - return this.messagingStub.then(stub => { + return this.messagingStub!.then(stub => { this._terminated = true; stub.close(); }); diff --git a/baselines/showcase/src/v1beta1/testing_client.ts.baseline b/baselines/showcase/src/v1beta1/testing_client.ts.baseline index 13e45bd8b..87de5f5b2 100644 --- a/baselines/showcase/src/v1beta1/testing_client.ts.baseline +++ b/baselines/showcase/src/v1beta1/testing_client.ts.baseline @@ -37,8 +37,13 @@ export class TestingClient { private _innerApiCalls: {[name: string]: Function}; private _pathTemplates: {[name: string]: gax.PathTemplate}; private _terminated = false; + private _opts: ClientOptions; + private _gaxModule: typeof gax | typeof gax.fallback; + private _gaxGrpc: gax.GrpcClient | gax.fallback.GrpcClient; + private _protos: {}; + private _defaults: {[method: string]: gax.CallSettings}; auth: gax.GoogleAuth; - testingStub: Promise<{[name: string]: Function}>; + testingStub?: Promise<{[name: string]: Function}>; /** * Construct an instance of TestingClient. @@ -89,28 +94,31 @@ export class TestingClient { // If we are in browser, we are already using fallback because of the // "browser" field in package.json. // But if we were explicitly requested to use fallback, let's do it now. - const gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; + this._gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; // Create a `gaxGrpc` object, with any grpc-specific options // sent to the client. opts.scopes = (this.constructor as typeof TestingClient).scopes; - const gaxGrpc = new gaxModule.GrpcClient(opts); + this._gaxGrpc = new this._gaxModule.GrpcClient(opts); + + // Save options to use in initialize() method. + this._opts = opts; // Save the auth object to the client, for use by other methods. - this.auth = (gaxGrpc.auth as gax.GoogleAuth); + this.auth = (this._gaxGrpc.auth as gax.GoogleAuth); // Determine the client header string. const clientHeader = [ - `gax/${gaxModule.version}`, + `gax/${this._gaxModule.version}`, `gapic/${version}`, ]; if (typeof process !== 'undefined' && 'versions' in process) { clientHeader.push(`gl-node/${process.versions.node}`); } else { - clientHeader.push(`gl-web/${gaxModule.version}`); + clientHeader.push(`gl-web/${this._gaxModule.version}`); } if (!opts.fallback) { - clientHeader.push(`grpc/${gaxGrpc.grpcVersion}`); + clientHeader.push(`grpc/${this._gaxGrpc.grpcVersion}`); } if (opts.libName && opts.libVersion) { clientHeader.push(`${opts.libName}/${opts.libVersion}`); @@ -120,7 +128,7 @@ export class TestingClient { // For browsers, pass the JSON content. const nodejsProtoPath = path.join(__dirname, '..', '..', 'protos', 'protos.json'); - const protos = gaxGrpc.loadProto( + this._protos = this._gaxGrpc.loadProto( opts.fallback ? require("../../protos/protos.json") : nodejsProtoPath @@ -130,25 +138,25 @@ export class TestingClient { // identifiers to uniquely identify resources within the API. // Create useful helper objects for these. this._pathTemplates = { - blueprintPathTemplate: new gaxModule.PathTemplate( + blueprintPathTemplate: new this._gaxModule.PathTemplate( 'sessions/{session}/tests/{test}/blueprints/{blueprint}' ), - roomPathTemplate: new gaxModule.PathTemplate( + roomPathTemplate: new this._gaxModule.PathTemplate( 'rooms/{room_id}' ), - roomIdBlurbIdPathTemplate: new gaxModule.PathTemplate( + roomIdBlurbIdPathTemplate: new this._gaxModule.PathTemplate( 'rooms/{room_id}/blurbs/{blurb_id}' ), - sessionPathTemplate: new gaxModule.PathTemplate( + sessionPathTemplate: new this._gaxModule.PathTemplate( 'sessions/{session}' ), - testPathTemplate: new gaxModule.PathTemplate( + testPathTemplate: new this._gaxModule.PathTemplate( 'sessions/{session}/tests/{test}' ), - userPathTemplate: new gaxModule.PathTemplate( + userPathTemplate: new this._gaxModule.PathTemplate( 'users/{user_id}' ), - userIdBlurbIdPathTemplate: new gaxModule.PathTemplate( + userIdBlurbIdPathTemplate: new this._gaxModule.PathTemplate( 'user/{user_id}/profile/blurbs/{blurb_id}' ), }; @@ -158,13 +166,13 @@ export class TestingClient { // pages). Denote the keys used for pagination and results. this._descriptors.page = { listSessions: - new gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'sessions'), + new this._gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'sessions'), listTests: - new gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'tests') + new this._gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'tests') }; // Put together the default options sent with requests. - const defaults = gaxGrpc.constructSettings( + this._defaults = this._gaxGrpc.constructSettings( 'google.showcase.v1beta1.Testing', gapicConfig as gax.ClientConfig, opts.clientConfig || {}, {'x-goog-api-client': clientHeader.join(' ')}); @@ -172,15 +180,33 @@ export class TestingClient { // of calling the API is handled in `google-gax`, with this code // merely providing the destination and request information. this._innerApiCalls = {}; + } + + /** + * Initialize the client. + * Performs asynchronous operations (such as authentication) and prepares the client. + * This function will be called automatically when any class method is called for the + * first time, but if you need to initialize it before calling an actual method, + * feel free to call initialize() directly. + * + * You can await on this method if you want to make sure the client is initialized. + * + * @returns {Promise} A promise that resolves to an authenticated service stub. + */ + initialize() { + // If the client stub promise is already initialized, return immediately. + if (this.testingStub) { + return this.testingStub; + } // Put together the "service stub" for // google.showcase.v1beta1.Testing. - this.testingStub = gaxGrpc.createStub( - opts.fallback ? - (protos as protobuf.Root).lookupService('google.showcase.v1beta1.Testing') : + this.testingStub = this._gaxGrpc.createStub( + this._opts.fallback ? + (this._protos as protobuf.Root).lookupService('google.showcase.v1beta1.Testing') : // tslint:disable-next-line no-any - (protos as any).google.showcase.v1beta1.Testing, - opts) as Promise<{[method: string]: Function}>; + (this._protos as any).google.showcase.v1beta1.Testing, + this._opts) as Promise<{[method: string]: Function}>; // Iterate over each of the methods that the service provides // and create an API call method for each. @@ -199,9 +225,9 @@ export class TestingClient { throw err; }); - const apiCall = gaxModule.createApiCall( + const apiCall = this._gaxModule.createApiCall( innerCallPromise, - defaults[methodName], + this._defaults[methodName], this._descriptors.page[methodName] || this._descriptors.stream[methodName] || this._descriptors.longrunning[methodName] @@ -215,6 +241,8 @@ export class TestingClient { return apiCall(argument, callOptions, callback); }; } + + return this.testingStub; } /** @@ -318,6 +346,7 @@ export class TestingClient { options = optionsOrCallback as gax.CallOptions; } options = options || {}; + this.initialize(); return this._innerApiCalls.createSession(request, options, callback); } getSession( @@ -377,6 +406,7 @@ export class TestingClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.getSession(request, options, callback); } deleteSession( @@ -436,6 +466,7 @@ export class TestingClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.deleteSession(request, options, callback); } reportSession( @@ -497,6 +528,7 @@ export class TestingClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.reportSession(request, options, callback); } deleteTest( @@ -561,6 +593,7 @@ export class TestingClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.deleteTest(request, options, callback); } verifyTest( @@ -627,6 +660,7 @@ export class TestingClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.verifyTest(request, options, callback); } @@ -697,6 +731,7 @@ export class TestingClient { options = optionsOrCallback as gax.CallOptions; } options = options || {}; + this.initialize(); return this._innerApiCalls.listSessions(request, options, callback); } @@ -731,6 +766,7 @@ export class TestingClient { request = request || {}; options = options || {}; const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listSessions.createStream( this._innerApiCalls.listSessions as gax.GaxCall, request, @@ -813,6 +849,7 @@ export class TestingClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.listTests(request, options, callback); } @@ -856,6 +893,7 @@ export class TestingClient { 'parent': request.parent || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listTests.createStream( this._innerApiCalls.listTests as gax.GaxCall, request, @@ -1098,8 +1136,9 @@ export class TestingClient { * The client will no longer be usable and all future behavior is undefined. */ close(): Promise { + this.initialize(); if (!this._terminated) { - return this.testingStub.then(stub => { + return this.testingStub!.then(stub => { this._terminated = true; stub.close(); }); diff --git a/baselines/showcase/test/gapic-echo-v1beta1.ts.baseline b/baselines/showcase/test/gapic-echo-v1beta1.ts.baseline index 80b20ef95..8d746c59f 100644 --- a/baselines/showcase/test/gapic-echo-v1beta1.ts.baseline +++ b/baselines/showcase/test/gapic-echo-v1beta1.ts.baseline @@ -132,12 +132,30 @@ describe('v1beta1.EchoClient', () => { }); assert(client); }); + it('has initialize method and supports deferred initialization', async () => { + const client = new echoModule.v1beta1.EchoClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + assert.strictEqual(client.echoStub, undefined); + await client.initialize(); + assert(client.echoStub); + }); + it('has close method', () => { + const client = new echoModule.v1beta1.EchoClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + client.close(); + }); describe('echo', () => { it('invokes echo without error', done => { const client = new echoModule.v1beta1.EchoClient({ credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IEchoRequest = {}; // Mock response @@ -160,6 +178,8 @@ describe('v1beta1.EchoClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IEchoRequest = {}; // Mock response @@ -184,6 +204,8 @@ describe('v1beta1.EchoClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IBlockRequest = {}; // Mock response @@ -206,6 +228,8 @@ describe('v1beta1.EchoClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IBlockRequest = {}; // Mock response @@ -230,6 +254,8 @@ describe('v1beta1.EchoClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IWaitRequest = {}; // Mock response @@ -255,6 +281,8 @@ describe('v1beta1.EchoClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IWaitRequest = {}; // Mock response @@ -283,6 +311,8 @@ describe('v1beta1.EchoClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IExpandRequest = {}; // Mock response @@ -304,6 +334,8 @@ describe('v1beta1.EchoClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IExpandRequest = {}; // Mock response @@ -328,6 +360,8 @@ describe('v1beta1.EchoClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IEchoRequest = {}; // Mock response @@ -347,6 +381,8 @@ describe('v1beta1.EchoClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IEchoRequest = {}; // Mock response @@ -369,6 +405,8 @@ describe('v1beta1.EchoClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IPagedExpandRequest = {}; // Mock response @@ -391,6 +429,8 @@ describe('v1beta1.EchoClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IPagedExpandRequest = {}; // Mock response diff --git a/baselines/showcase/test/gapic-identity-v1beta1.ts.baseline b/baselines/showcase/test/gapic-identity-v1beta1.ts.baseline index 8c1aaa3f4..e3521358c 100644 --- a/baselines/showcase/test/gapic-identity-v1beta1.ts.baseline +++ b/baselines/showcase/test/gapic-identity-v1beta1.ts.baseline @@ -78,12 +78,30 @@ describe('v1beta1.IdentityClient', () => { }); assert(client); }); + it('has initialize method and supports deferred initialization', async () => { + const client = new identityModule.v1beta1.IdentityClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + assert.strictEqual(client.identityStub, undefined); + await client.initialize(); + assert(client.identityStub); + }); + it('has close method', () => { + const client = new identityModule.v1beta1.IdentityClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + client.close(); + }); describe('createUser', () => { it('invokes createUser without error', done => { const client = new identityModule.v1beta1.IdentityClient({ credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.ICreateUserRequest = {}; // Mock response @@ -106,6 +124,8 @@ describe('v1beta1.IdentityClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.ICreateUserRequest = {}; // Mock response @@ -130,6 +150,8 @@ describe('v1beta1.IdentityClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IGetUserRequest = {}; request.name = ''; @@ -153,6 +175,8 @@ describe('v1beta1.IdentityClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IGetUserRequest = {}; request.name = ''; @@ -178,6 +202,8 @@ describe('v1beta1.IdentityClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IUpdateUserRequest = {}; request.user = {}; @@ -202,6 +228,8 @@ describe('v1beta1.IdentityClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IUpdateUserRequest = {}; request.user = {}; @@ -228,6 +256,8 @@ describe('v1beta1.IdentityClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IDeleteUserRequest = {}; request.name = ''; @@ -251,6 +281,8 @@ describe('v1beta1.IdentityClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IDeleteUserRequest = {}; request.name = ''; @@ -276,6 +308,8 @@ describe('v1beta1.IdentityClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IListUsersRequest = {}; // Mock response @@ -298,6 +332,8 @@ describe('v1beta1.IdentityClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IListUsersRequest = {}; // Mock response diff --git a/baselines/showcase/test/gapic-messaging-v1beta1.ts.baseline b/baselines/showcase/test/gapic-messaging-v1beta1.ts.baseline index 2d4a2deed..5cb3657f7 100644 --- a/baselines/showcase/test/gapic-messaging-v1beta1.ts.baseline +++ b/baselines/showcase/test/gapic-messaging-v1beta1.ts.baseline @@ -132,12 +132,30 @@ describe('v1beta1.MessagingClient', () => { }); assert(client); }); + it('has initialize method and supports deferred initialization', async () => { + const client = new messagingModule.v1beta1.MessagingClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + assert.strictEqual(client.messagingStub, undefined); + await client.initialize(); + assert(client.messagingStub); + }); + it('has close method', () => { + const client = new messagingModule.v1beta1.MessagingClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + client.close(); + }); describe('createRoom', () => { it('invokes createRoom without error', done => { const client = new messagingModule.v1beta1.MessagingClient({ credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.ICreateRoomRequest = {}; // Mock response @@ -160,6 +178,8 @@ describe('v1beta1.MessagingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.ICreateRoomRequest = {}; // Mock response @@ -184,6 +204,8 @@ describe('v1beta1.MessagingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IGetRoomRequest = {}; request.name = ''; @@ -207,6 +229,8 @@ describe('v1beta1.MessagingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IGetRoomRequest = {}; request.name = ''; @@ -232,6 +256,8 @@ describe('v1beta1.MessagingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IUpdateRoomRequest = {}; request.room = {}; @@ -256,6 +282,8 @@ describe('v1beta1.MessagingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IUpdateRoomRequest = {}; request.room = {}; @@ -282,6 +310,8 @@ describe('v1beta1.MessagingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IDeleteRoomRequest = {}; request.name = ''; @@ -305,6 +335,8 @@ describe('v1beta1.MessagingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IDeleteRoomRequest = {}; request.name = ''; @@ -330,6 +362,8 @@ describe('v1beta1.MessagingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.ICreateBlurbRequest = {}; request.parent = ''; @@ -353,6 +387,8 @@ describe('v1beta1.MessagingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.ICreateBlurbRequest = {}; request.parent = ''; @@ -378,6 +414,8 @@ describe('v1beta1.MessagingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IGetBlurbRequest = {}; request.name = ''; @@ -401,6 +439,8 @@ describe('v1beta1.MessagingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IGetBlurbRequest = {}; request.name = ''; @@ -426,6 +466,8 @@ describe('v1beta1.MessagingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IUpdateBlurbRequest = {}; request.blurb = {}; @@ -450,6 +492,8 @@ describe('v1beta1.MessagingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IUpdateBlurbRequest = {}; request.blurb = {}; @@ -476,6 +520,8 @@ describe('v1beta1.MessagingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IDeleteBlurbRequest = {}; request.name = ''; @@ -499,6 +545,8 @@ describe('v1beta1.MessagingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IDeleteBlurbRequest = {}; request.name = ''; @@ -524,6 +572,8 @@ describe('v1beta1.MessagingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.ISearchBlurbsRequest = {}; request.parent = ''; @@ -550,6 +600,8 @@ describe('v1beta1.MessagingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.ISearchBlurbsRequest = {}; request.parent = ''; @@ -579,6 +631,8 @@ describe('v1beta1.MessagingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IStreamBlurbsRequest = {}; request.name = ''; @@ -601,6 +655,8 @@ describe('v1beta1.MessagingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IStreamBlurbsRequest = {}; request.name = ''; @@ -626,6 +682,8 @@ describe('v1beta1.MessagingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IConnectRequest = {}; // Mock response @@ -645,6 +703,8 @@ describe('v1beta1.MessagingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IConnectRequest = {}; // Mock response @@ -667,6 +727,8 @@ describe('v1beta1.MessagingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IListRoomsRequest = {}; // Mock response @@ -689,6 +751,8 @@ describe('v1beta1.MessagingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IListRoomsRequest = {}; // Mock response @@ -713,6 +777,8 @@ describe('v1beta1.MessagingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IListBlurbsRequest = {}; request.parent = ''; @@ -736,6 +802,8 @@ describe('v1beta1.MessagingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IListBlurbsRequest = {}; request.parent = ''; diff --git a/baselines/showcase/test/gapic-testing-v1beta1.ts.baseline b/baselines/showcase/test/gapic-testing-v1beta1.ts.baseline index 3c27cc0ba..81cb1e560 100644 --- a/baselines/showcase/test/gapic-testing-v1beta1.ts.baseline +++ b/baselines/showcase/test/gapic-testing-v1beta1.ts.baseline @@ -78,12 +78,30 @@ describe('v1beta1.TestingClient', () => { }); assert(client); }); + it('has initialize method and supports deferred initialization', async () => { + const client = new testingModule.v1beta1.TestingClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + assert.strictEqual(client.testingStub, undefined); + await client.initialize(); + assert(client.testingStub); + }); + it('has close method', () => { + const client = new testingModule.v1beta1.TestingClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + client.close(); + }); describe('createSession', () => { it('invokes createSession without error', done => { const client = new testingModule.v1beta1.TestingClient({ credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.ICreateSessionRequest = {}; // Mock response @@ -106,6 +124,8 @@ describe('v1beta1.TestingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.ICreateSessionRequest = {}; // Mock response @@ -130,6 +150,8 @@ describe('v1beta1.TestingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IGetSessionRequest = {}; request.name = ''; @@ -153,6 +175,8 @@ describe('v1beta1.TestingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IGetSessionRequest = {}; request.name = ''; @@ -178,6 +202,8 @@ describe('v1beta1.TestingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IDeleteSessionRequest = {}; request.name = ''; @@ -201,6 +227,8 @@ describe('v1beta1.TestingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IDeleteSessionRequest = {}; request.name = ''; @@ -226,6 +254,8 @@ describe('v1beta1.TestingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IReportSessionRequest = {}; request.name = ''; @@ -249,6 +279,8 @@ describe('v1beta1.TestingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IReportSessionRequest = {}; request.name = ''; @@ -274,6 +306,8 @@ describe('v1beta1.TestingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IDeleteTestRequest = {}; request.name = ''; @@ -297,6 +331,8 @@ describe('v1beta1.TestingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IDeleteTestRequest = {}; request.name = ''; @@ -322,6 +358,8 @@ describe('v1beta1.TestingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IVerifyTestRequest = {}; request.name = ''; @@ -345,6 +383,8 @@ describe('v1beta1.TestingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IVerifyTestRequest = {}; request.name = ''; @@ -370,6 +410,8 @@ describe('v1beta1.TestingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IListSessionsRequest = {}; // Mock response @@ -392,6 +434,8 @@ describe('v1beta1.TestingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IListSessionsRequest = {}; // Mock response @@ -416,6 +460,8 @@ describe('v1beta1.TestingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IListTestsRequest = {}; request.parent = ''; @@ -439,6 +485,8 @@ describe('v1beta1.TestingClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.showcase.v1beta1.IListTestsRequest = {}; request.parent = ''; diff --git a/baselines/texttospeech/src/v1/text_to_speech_client.ts.baseline b/baselines/texttospeech/src/v1/text_to_speech_client.ts.baseline index 0656889b4..f65d9d322 100644 --- a/baselines/texttospeech/src/v1/text_to_speech_client.ts.baseline +++ b/baselines/texttospeech/src/v1/text_to_speech_client.ts.baseline @@ -34,8 +34,13 @@ export class TextToSpeechClient { private _descriptors: Descriptors = {page: {}, stream: {}, longrunning: {}}; private _innerApiCalls: {[name: string]: Function}; private _terminated = false; + private _opts: ClientOptions; + private _gaxModule: typeof gax | typeof gax.fallback; + private _gaxGrpc: gax.GrpcClient | gax.fallback.GrpcClient; + private _protos: {}; + private _defaults: {[method: string]: gax.CallSettings}; auth: gax.GoogleAuth; - textToSpeechStub: Promise<{[name: string]: Function}>; + textToSpeechStub?: Promise<{[name: string]: Function}>; /** * Construct an instance of TextToSpeechClient. @@ -86,28 +91,31 @@ export class TextToSpeechClient { // If we are in browser, we are already using fallback because of the // "browser" field in package.json. // But if we were explicitly requested to use fallback, let's do it now. - const gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; + this._gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; // Create a `gaxGrpc` object, with any grpc-specific options // sent to the client. opts.scopes = (this.constructor as typeof TextToSpeechClient).scopes; - const gaxGrpc = new gaxModule.GrpcClient(opts); + this._gaxGrpc = new this._gaxModule.GrpcClient(opts); + + // Save options to use in initialize() method. + this._opts = opts; // Save the auth object to the client, for use by other methods. - this.auth = (gaxGrpc.auth as gax.GoogleAuth); + this.auth = (this._gaxGrpc.auth as gax.GoogleAuth); // Determine the client header string. const clientHeader = [ - `gax/${gaxModule.version}`, + `gax/${this._gaxModule.version}`, `gapic/${version}`, ]; if (typeof process !== 'undefined' && 'versions' in process) { clientHeader.push(`gl-node/${process.versions.node}`); } else { - clientHeader.push(`gl-web/${gaxModule.version}`); + clientHeader.push(`gl-web/${this._gaxModule.version}`); } if (!opts.fallback) { - clientHeader.push(`grpc/${gaxGrpc.grpcVersion}`); + clientHeader.push(`grpc/${this._gaxGrpc.grpcVersion}`); } if (opts.libName && opts.libVersion) { clientHeader.push(`${opts.libName}/${opts.libVersion}`); @@ -117,14 +125,14 @@ export class TextToSpeechClient { // For browsers, pass the JSON content. const nodejsProtoPath = path.join(__dirname, '..', '..', 'protos', 'protos.json'); - const protos = gaxGrpc.loadProto( + this._protos = this._gaxGrpc.loadProto( opts.fallback ? require("../../protos/protos.json") : nodejsProtoPath ); // Put together the default options sent with requests. - const defaults = gaxGrpc.constructSettings( + this._defaults = this._gaxGrpc.constructSettings( 'google.cloud.texttospeech.v1.TextToSpeech', gapicConfig as gax.ClientConfig, opts.clientConfig || {}, {'x-goog-api-client': clientHeader.join(' ')}); @@ -132,15 +140,33 @@ export class TextToSpeechClient { // of calling the API is handled in `google-gax`, with this code // merely providing the destination and request information. this._innerApiCalls = {}; + } + + /** + * Initialize the client. + * Performs asynchronous operations (such as authentication) and prepares the client. + * This function will be called automatically when any class method is called for the + * first time, but if you need to initialize it before calling an actual method, + * feel free to call initialize() directly. + * + * You can await on this method if you want to make sure the client is initialized. + * + * @returns {Promise} A promise that resolves to an authenticated service stub. + */ + initialize() { + // If the client stub promise is already initialized, return immediately. + if (this.textToSpeechStub) { + return this.textToSpeechStub; + } // Put together the "service stub" for // google.cloud.texttospeech.v1.TextToSpeech. - this.textToSpeechStub = gaxGrpc.createStub( - opts.fallback ? - (protos as protobuf.Root).lookupService('google.cloud.texttospeech.v1.TextToSpeech') : + this.textToSpeechStub = this._gaxGrpc.createStub( + this._opts.fallback ? + (this._protos as protobuf.Root).lookupService('google.cloud.texttospeech.v1.TextToSpeech') : // tslint:disable-next-line no-any - (protos as any).google.cloud.texttospeech.v1.TextToSpeech, - opts) as Promise<{[method: string]: Function}>; + (this._protos as any).google.cloud.texttospeech.v1.TextToSpeech, + this._opts) as Promise<{[method: string]: Function}>; // Iterate over each of the methods that the service provides // and create an API call method for each. @@ -159,9 +185,9 @@ export class TextToSpeechClient { throw err; }); - const apiCall = gaxModule.createApiCall( + const apiCall = this._gaxModule.createApiCall( innerCallPromise, - defaults[methodName], + this._defaults[methodName], this._descriptors.page[methodName] || this._descriptors.stream[methodName] || this._descriptors.longrunning[methodName] @@ -175,6 +201,8 @@ export class TextToSpeechClient { return apiCall(argument, callOptions, callback); }; } + + return this.textToSpeechStub; } /** @@ -285,6 +313,7 @@ export class TextToSpeechClient { options = optionsOrCallback as gax.CallOptions; } options = options || {}; + this.initialize(); return this._innerApiCalls.listVoices(request, options, callback); } synthesizeSpeech( @@ -342,6 +371,7 @@ export class TextToSpeechClient { options = optionsOrCallback as gax.CallOptions; } options = options || {}; + this.initialize(); return this._innerApiCalls.synthesizeSpeech(request, options, callback); } @@ -352,8 +382,9 @@ export class TextToSpeechClient { * The client will no longer be usable and all future behavior is undefined. */ close(): Promise { + this.initialize(); if (!this._terminated) { - return this.textToSpeechStub.then(stub => { + return this.textToSpeechStub!.then(stub => { this._terminated = true; stub.close(); }); diff --git a/baselines/texttospeech/test/gapic-text_to_speech-v1.ts.baseline b/baselines/texttospeech/test/gapic-text_to_speech-v1.ts.baseline index 0ff0b1c89..df81845b3 100644 --- a/baselines/texttospeech/test/gapic-text_to_speech-v1.ts.baseline +++ b/baselines/texttospeech/test/gapic-text_to_speech-v1.ts.baseline @@ -78,12 +78,30 @@ describe('v1.TextToSpeechClient', () => { }); assert(client); }); + it('has initialize method and supports deferred initialization', async () => { + const client = new texttospeechModule.v1.TextToSpeechClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + assert.strictEqual(client.textToSpeechStub, undefined); + await client.initialize(); + assert(client.textToSpeechStub); + }); + it('has close method', () => { + const client = new texttospeechModule.v1.TextToSpeechClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + client.close(); + }); describe('listVoices', () => { it('invokes listVoices without error', done => { const client = new texttospeechModule.v1.TextToSpeechClient({ credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.texttospeech.v1.IListVoicesRequest = {}; // Mock response @@ -106,6 +124,8 @@ describe('v1.TextToSpeechClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.texttospeech.v1.IListVoicesRequest = {}; // Mock response @@ -130,6 +150,8 @@ describe('v1.TextToSpeechClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.texttospeech.v1.ISynthesizeSpeechRequest = {}; // Mock response @@ -152,6 +174,8 @@ describe('v1.TextToSpeechClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.texttospeech.v1.ISynthesizeSpeechRequest = {}; // Mock response diff --git a/baselines/translate/src/v3beta1/translation_service_client.ts.baseline b/baselines/translate/src/v3beta1/translation_service_client.ts.baseline index 012c9265f..26c14c373 100644 --- a/baselines/translate/src/v3beta1/translation_service_client.ts.baseline +++ b/baselines/translate/src/v3beta1/translation_service_client.ts.baseline @@ -36,9 +36,14 @@ export class TranslationServiceClient { private _innerApiCalls: {[name: string]: Function}; private _pathTemplates: {[name: string]: gax.PathTemplate}; private _terminated = false; + private _opts: ClientOptions; + private _gaxModule: typeof gax | typeof gax.fallback; + private _gaxGrpc: gax.GrpcClient | gax.fallback.GrpcClient; + private _protos: {}; + private _defaults: {[method: string]: gax.CallSettings}; auth: gax.GoogleAuth; operationsClient: gax.OperationsClient; - translationServiceStub: Promise<{[name: string]: Function}>; + translationServiceStub?: Promise<{[name: string]: Function}>; /** * Construct an instance of TranslationServiceClient. @@ -89,28 +94,31 @@ export class TranslationServiceClient { // If we are in browser, we are already using fallback because of the // "browser" field in package.json. // But if we were explicitly requested to use fallback, let's do it now. - const gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; + this._gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; // Create a `gaxGrpc` object, with any grpc-specific options // sent to the client. opts.scopes = (this.constructor as typeof TranslationServiceClient).scopes; - const gaxGrpc = new gaxModule.GrpcClient(opts); + this._gaxGrpc = new this._gaxModule.GrpcClient(opts); + + // Save options to use in initialize() method. + this._opts = opts; // Save the auth object to the client, for use by other methods. - this.auth = (gaxGrpc.auth as gax.GoogleAuth); + this.auth = (this._gaxGrpc.auth as gax.GoogleAuth); // Determine the client header string. const clientHeader = [ - `gax/${gaxModule.version}`, + `gax/${this._gaxModule.version}`, `gapic/${version}`, ]; if (typeof process !== 'undefined' && 'versions' in process) { clientHeader.push(`gl-node/${process.versions.node}`); } else { - clientHeader.push(`gl-web/${gaxModule.version}`); + clientHeader.push(`gl-web/${this._gaxModule.version}`); } if (!opts.fallback) { - clientHeader.push(`grpc/${gaxGrpc.grpcVersion}`); + clientHeader.push(`grpc/${this._gaxGrpc.grpcVersion}`); } if (opts.libName && opts.libVersion) { clientHeader.push(`${opts.libName}/${opts.libVersion}`); @@ -120,7 +128,7 @@ export class TranslationServiceClient { // For browsers, pass the JSON content. const nodejsProtoPath = path.join(__dirname, '..', '..', 'protos', 'protos.json'); - const protos = gaxGrpc.loadProto( + this._protos = this._gaxGrpc.loadProto( opts.fallback ? require("../../protos/protos.json") : nodejsProtoPath @@ -130,10 +138,10 @@ export class TranslationServiceClient { // identifiers to uniquely identify resources within the API. // Create useful helper objects for these. this._pathTemplates = { - glossaryPathTemplate: new gaxModule.PathTemplate( + glossaryPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/locations/{location}/glossaries/{glossary}' ), - locationPathTemplate: new gaxModule.PathTemplate( + locationPathTemplate: new this._gaxModule.PathTemplate( 'projects/{project}/locations/{location}' ), }; @@ -143,19 +151,19 @@ export class TranslationServiceClient { // pages). Denote the keys used for pagination and results. this._descriptors.page = { listGlossaries: - new gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'glossaries') + new this._gaxModule.PageDescriptor('pageToken', 'nextPageToken', 'glossaries') }; // This API contains "long-running operations", which return a // an Operation object that allows for tracking of the operation, // rather than holding a request open. const protoFilesRoot = opts.fallback? - gaxModule.protobuf.Root.fromJSON(require("../../protos/protos.json")) : - gaxModule.protobuf.loadSync(nodejsProtoPath); + this._gaxModule.protobuf.Root.fromJSON(require("../../protos/protos.json")) : + this._gaxModule.protobuf.loadSync(nodejsProtoPath); - this.operationsClient = gaxModule.lro({ + this.operationsClient = this._gaxModule.lro({ auth: this.auth, - grpc: 'grpc' in gaxGrpc ? gaxGrpc.grpc : undefined + grpc: 'grpc' in this._gaxGrpc ? this._gaxGrpc.grpc : undefined }).operationsClient(opts); const batchTranslateTextResponse = protoFilesRoot.lookup( '.google.cloud.translation.v3beta1.BatchTranslateResponse') as gax.protobuf.Type; @@ -171,22 +179,22 @@ export class TranslationServiceClient { '.google.cloud.translation.v3beta1.DeleteGlossaryMetadata') as gax.protobuf.Type; this._descriptors.longrunning = { - batchTranslateText: new gaxModule.LongrunningDescriptor( + batchTranslateText: new this._gaxModule.LongrunningDescriptor( this.operationsClient, batchTranslateTextResponse.decode.bind(batchTranslateTextResponse), batchTranslateTextMetadata.decode.bind(batchTranslateTextMetadata)), - createGlossary: new gaxModule.LongrunningDescriptor( + createGlossary: new this._gaxModule.LongrunningDescriptor( this.operationsClient, createGlossaryResponse.decode.bind(createGlossaryResponse), createGlossaryMetadata.decode.bind(createGlossaryMetadata)), - deleteGlossary: new gaxModule.LongrunningDescriptor( + deleteGlossary: new this._gaxModule.LongrunningDescriptor( this.operationsClient, deleteGlossaryResponse.decode.bind(deleteGlossaryResponse), deleteGlossaryMetadata.decode.bind(deleteGlossaryMetadata)) }; // Put together the default options sent with requests. - const defaults = gaxGrpc.constructSettings( + this._defaults = this._gaxGrpc.constructSettings( 'google.cloud.translation.v3beta1.TranslationService', gapicConfig as gax.ClientConfig, opts.clientConfig || {}, {'x-goog-api-client': clientHeader.join(' ')}); @@ -194,15 +202,33 @@ export class TranslationServiceClient { // of calling the API is handled in `google-gax`, with this code // merely providing the destination and request information. this._innerApiCalls = {}; + } + + /** + * Initialize the client. + * Performs asynchronous operations (such as authentication) and prepares the client. + * This function will be called automatically when any class method is called for the + * first time, but if you need to initialize it before calling an actual method, + * feel free to call initialize() directly. + * + * You can await on this method if you want to make sure the client is initialized. + * + * @returns {Promise} A promise that resolves to an authenticated service stub. + */ + initialize() { + // If the client stub promise is already initialized, return immediately. + if (this.translationServiceStub) { + return this.translationServiceStub; + } // Put together the "service stub" for // google.cloud.translation.v3beta1.TranslationService. - this.translationServiceStub = gaxGrpc.createStub( - opts.fallback ? - (protos as protobuf.Root).lookupService('google.cloud.translation.v3beta1.TranslationService') : + this.translationServiceStub = this._gaxGrpc.createStub( + this._opts.fallback ? + (this._protos as protobuf.Root).lookupService('google.cloud.translation.v3beta1.TranslationService') : // tslint:disable-next-line no-any - (protos as any).google.cloud.translation.v3beta1.TranslationService, - opts) as Promise<{[method: string]: Function}>; + (this._protos as any).google.cloud.translation.v3beta1.TranslationService, + this._opts) as Promise<{[method: string]: Function}>; // Iterate over each of the methods that the service provides // and create an API call method for each. @@ -221,9 +247,9 @@ export class TranslationServiceClient { throw err; }); - const apiCall = gaxModule.createApiCall( + const apiCall = this._gaxModule.createApiCall( innerCallPromise, - defaults[methodName], + this._defaults[methodName], this._descriptors.page[methodName] || this._descriptors.stream[methodName] || this._descriptors.longrunning[methodName] @@ -237,6 +263,8 @@ export class TranslationServiceClient { return apiCall(argument, callOptions, callback); }; } + + return this.translationServiceStub; } /** @@ -408,6 +436,7 @@ export class TranslationServiceClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.translateText(request, options, callback); } detectLanguage( @@ -501,6 +530,7 @@ export class TranslationServiceClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.detectLanguage(request, options, callback); } getSupportedLanguages( @@ -591,6 +621,7 @@ export class TranslationServiceClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.getSupportedLanguages(request, options, callback); } getGlossary( @@ -651,6 +682,7 @@ export class TranslationServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.getGlossary(request, options, callback); } @@ -767,6 +799,7 @@ export class TranslationServiceClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.batchTranslateText(request, options, callback); } createGlossary( @@ -829,6 +862,7 @@ export class TranslationServiceClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.createGlossary(request, options, callback); } deleteGlossary( @@ -890,6 +924,7 @@ export class TranslationServiceClient { ] = gax.routingHeader.fromParams({ 'name': request.name || '', }); + this.initialize(); return this._innerApiCalls.deleteGlossary(request, options, callback); } listGlossaries( @@ -977,6 +1012,7 @@ export class TranslationServiceClient { ] = gax.routingHeader.fromParams({ 'parent': request.parent || '', }); + this.initialize(); return this._innerApiCalls.listGlossaries(request, options, callback); } @@ -1028,6 +1064,7 @@ export class TranslationServiceClient { 'parent': request.parent || '', }); const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.listGlossaries.createStream( this._innerApiCalls.listGlossaries as gax.GaxCall, request, @@ -1129,8 +1166,9 @@ export class TranslationServiceClient { * The client will no longer be usable and all future behavior is undefined. */ close(): Promise { + this.initialize(); if (!this._terminated) { - return this.translationServiceStub.then(stub => { + return this.translationServiceStub!.then(stub => { this._terminated = true; stub.close(); }); diff --git a/baselines/translate/test/gapic-translation_service-v3beta1.ts.baseline b/baselines/translate/test/gapic-translation_service-v3beta1.ts.baseline index 63224dcf4..a73aadfea 100644 --- a/baselines/translate/test/gapic-translation_service-v3beta1.ts.baseline +++ b/baselines/translate/test/gapic-translation_service-v3beta1.ts.baseline @@ -96,12 +96,30 @@ describe('v3beta1.TranslationServiceClient', () => { }); assert(client); }); + it('has initialize method and supports deferred initialization', async () => { + const client = new translationserviceModule.v3beta1.TranslationServiceClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + assert.strictEqual(client.translationServiceStub, undefined); + await client.initialize(); + assert(client.translationServiceStub); + }); + it('has close method', () => { + const client = new translationserviceModule.v3beta1.TranslationServiceClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + client.close(); + }); describe('translateText', () => { it('invokes translateText without error', done => { const client = new translationserviceModule.v3beta1.TranslationServiceClient({ credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.translation.v3beta1.ITranslateTextRequest = {}; request.parent = ''; @@ -125,6 +143,8 @@ describe('v3beta1.TranslationServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.translation.v3beta1.ITranslateTextRequest = {}; request.parent = ''; @@ -150,6 +170,8 @@ describe('v3beta1.TranslationServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.translation.v3beta1.IDetectLanguageRequest = {}; request.parent = ''; @@ -173,6 +195,8 @@ describe('v3beta1.TranslationServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.translation.v3beta1.IDetectLanguageRequest = {}; request.parent = ''; @@ -198,6 +222,8 @@ describe('v3beta1.TranslationServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.translation.v3beta1.IGetSupportedLanguagesRequest = {}; request.parent = ''; @@ -221,6 +247,8 @@ describe('v3beta1.TranslationServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.translation.v3beta1.IGetSupportedLanguagesRequest = {}; request.parent = ''; @@ -246,6 +274,8 @@ describe('v3beta1.TranslationServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.translation.v3beta1.IGetGlossaryRequest = {}; request.name = ''; @@ -269,6 +299,8 @@ describe('v3beta1.TranslationServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.translation.v3beta1.IGetGlossaryRequest = {}; request.name = ''; @@ -294,6 +326,8 @@ describe('v3beta1.TranslationServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.translation.v3beta1.IBatchTranslateTextRequest = {}; request.parent = ''; @@ -320,6 +354,8 @@ describe('v3beta1.TranslationServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.translation.v3beta1.IBatchTranslateTextRequest = {}; request.parent = ''; @@ -349,6 +385,8 @@ describe('v3beta1.TranslationServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.translation.v3beta1.ICreateGlossaryRequest = {}; request.parent = ''; @@ -375,6 +413,8 @@ describe('v3beta1.TranslationServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.translation.v3beta1.ICreateGlossaryRequest = {}; request.parent = ''; @@ -404,6 +444,8 @@ describe('v3beta1.TranslationServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.translation.v3beta1.IDeleteGlossaryRequest = {}; request.name = ''; @@ -430,6 +472,8 @@ describe('v3beta1.TranslationServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.translation.v3beta1.IDeleteGlossaryRequest = {}; request.name = ''; @@ -459,6 +503,8 @@ describe('v3beta1.TranslationServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.translation.v3beta1.IListGlossariesRequest = {}; request.parent = ''; @@ -482,6 +528,8 @@ describe('v3beta1.TranslationServiceClient', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request const request: protosTypes.google.cloud.translation.v3beta1.IListGlossariesRequest = {}; request.parent = ''; diff --git a/templates/typescript_gapic/src/$version/$service_client.ts.njk b/templates/typescript_gapic/src/$version/$service_client.ts.njk index 5917a2e88..7d548a972 100644 --- a/templates/typescript_gapic/src/$version/$service_client.ts.njk +++ b/templates/typescript_gapic/src/$version/$service_client.ts.njk @@ -45,11 +45,16 @@ export class {{ service.name }}Client { private _pathTemplates: {[name: string]: gax.PathTemplate}; {%- endif %} private _terminated = false; + private _opts: ClientOptions; + private _gaxModule: typeof gax | typeof gax.fallback; + private _gaxGrpc: gax.GrpcClient | gax.fallback.GrpcClient; + private _protos: {}; + private _defaults: {[method: string]: gax.CallSettings}; auth: gax.GoogleAuth; {%- if (service.longRunning.length > 0) %} operationsClient: gax.OperationsClient; {%- endif %} - {{ service.name.toCamelCase() }}Stub: Promise<{[name: string]: Function}>; + {{ service.name.toCamelCase() }}Stub?: Promise<{[name: string]: Function}>; /** * Construct an instance of {{ service.name }}Client. @@ -100,28 +105,31 @@ export class {{ service.name }}Client { // If we are in browser, we are already using fallback because of the // "browser" field in package.json. // But if we were explicitly requested to use fallback, let's do it now. - const gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; + this._gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; // Create a `gaxGrpc` object, with any grpc-specific options // sent to the client. opts.scopes = (this.constructor as typeof {{ service.name }}Client).scopes; - const gaxGrpc = new gaxModule.GrpcClient(opts); + this._gaxGrpc = new this._gaxModule.GrpcClient(opts); + + // Save options to use in initialize() method. + this._opts = opts; // Save the auth object to the client, for use by other methods. - this.auth = (gaxGrpc.auth as gax.GoogleAuth); + this.auth = (this._gaxGrpc.auth as gax.GoogleAuth); // Determine the client header string. const clientHeader = [ - `gax/${gaxModule.version}`, + `gax/${this._gaxModule.version}`, `gapic/${version}`, ]; if (typeof process !== 'undefined' && 'versions' in process) { clientHeader.push(`gl-node/${process.versions.node}`); } else { - clientHeader.push(`gl-web/${gaxModule.version}`); + clientHeader.push(`gl-web/${this._gaxModule.version}`); } if (!opts.fallback) { - clientHeader.push(`grpc/${gaxGrpc.grpcVersion}`); + clientHeader.push(`grpc/${this._gaxGrpc.grpcVersion}`); } if (opts.libName && opts.libVersion) { clientHeader.push(`${opts.libName}/${opts.libVersion}`); @@ -131,7 +139,7 @@ export class {{ service.name }}Client { // For browsers, pass the JSON content. const nodejsProtoPath = path.join(__dirname, '..', '..', 'protos', 'protos.json'); - const protos = gaxGrpc.loadProto( + this._protos = this._gaxGrpc.loadProto( opts.fallback ? require("../../protos/protos.json") : nodejsProtoPath @@ -143,7 +151,7 @@ export class {{ service.name }}Client { // Create useful helper objects for these. this._pathTemplates = { {%- for template in service.pathTemplates %} - {{ template.name.toCamelCase() }}PathTemplate: new gaxModule.PathTemplate( + {{ template.name.toCamelCase() }}PathTemplate: new this._gaxModule.PathTemplate( '{{ template.pattern }}' ), {%- endfor %} @@ -160,7 +168,7 @@ export class {{ service.name }}Client { {%- for method in service.paging %} {{- pagingJoiner() }} {{ method.name.toCamelCase() }}: - new gaxModule.PageDescriptor('pageToken', 'nextPageToken', '{{ method.pagingFieldName.toCamelCase() }}') + new this._gaxModule.PageDescriptor('pageToken', 'nextPageToken', '{{ method.pagingFieldName.toCamelCase() }}') {%- endfor %} }; {%- endif %} @@ -173,7 +181,7 @@ export class {{ service.name }}Client { {%- set streamingJoiner = joiner() %} {%- for method in service.streaming %} {{- streamingJoiner() }} - {{ method.name.toCamelCase() }}: new gaxModule.StreamDescriptor(gax.StreamType.{{ method.streaming }}) + {{ method.name.toCamelCase() }}: new this._gaxModule.StreamDescriptor(gax.StreamType.{{ method.streaming }}) {%- endfor %} }; {%- endif %} @@ -183,12 +191,12 @@ export class {{ service.name }}Client { // an Operation object that allows for tracking of the operation, // rather than holding a request open. const protoFilesRoot = opts.fallback? - gaxModule.protobuf.Root.fromJSON(require("../../protos/protos.json")) : - gaxModule.protobuf.loadSync(nodejsProtoPath); + this._gaxModule.protobuf.Root.fromJSON(require("../../protos/protos.json")) : + this._gaxModule.protobuf.loadSync(nodejsProtoPath); - this.operationsClient = gaxModule.lro({ + this.operationsClient = this._gaxModule.lro({ auth: this.auth, - grpc: 'grpc' in gaxGrpc ? gaxGrpc.grpc : undefined + grpc: 'grpc' in this._gaxGrpc ? this._gaxGrpc.grpc : undefined }).operationsClient(opts); {%- for method in service.longRunning %} @@ -202,7 +210,7 @@ export class {{ service.name }}Client { {%- set longRunningJoiner = joiner() %} {%- for method in service.longRunning %} {{- longRunningJoiner() }} - {{ method.name.toCamelCase() }}: new gaxModule.LongrunningDescriptor( + {{ method.name.toCamelCase() }}: new this._gaxModule.LongrunningDescriptor( this.operationsClient, {{ method.name.toCamelCase() }}Response.decode.bind({{ method.name.toCamelCase() }}Response), {{ method.name.toCamelCase() }}Metadata.decode.bind({{ method.name.toCamelCase() }}Metadata)) @@ -211,7 +219,7 @@ export class {{ service.name }}Client { {%- endif %} // Put together the default options sent with requests. - const defaults = gaxGrpc.constructSettings( + this._defaults = this._gaxGrpc.constructSettings( '{{ api.naming.protoPackage }}.{{ service.name }}', gapicConfig as gax.ClientConfig, opts.clientConfig || {}, {'x-goog-api-client': clientHeader.join(' ')}); @@ -219,15 +227,33 @@ export class {{ service.name }}Client { // of calling the API is handled in `google-gax`, with this code // merely providing the destination and request information. this._innerApiCalls = {}; + } + + /** + * Initialize the client. + * Performs asynchronous operations (such as authentication) and prepares the client. + * This function will be called automatically when any class method is called for the + * first time, but if you need to initialize it before calling an actual method, + * feel free to call initialize() directly. + * + * You can await on this method if you want to make sure the client is initialized. + * + * @returns {Promise} A promise that resolves to an authenticated service stub. + */ + initialize() { + // If the client stub promise is already initialized, return immediately. + if (this.{{ service.name.toCamelCase() }}Stub) { + return this.{{ service.name.toCamelCase() }}Stub; + } // Put together the "service stub" for // {{api.naming.protoPackage}}.{{ service.name }}. - this.{{ service.name.toCamelCase() }}Stub = gaxGrpc.createStub( - opts.fallback ? - (protos as protobuf.Root).lookupService('{{api.naming.protoPackage}}.{{ service.name }}') : + this.{{ service.name.toCamelCase() }}Stub = this._gaxGrpc.createStub( + this._opts.fallback ? + (this._protos as protobuf.Root).lookupService('{{api.naming.protoPackage}}.{{ service.name }}') : // tslint:disable-next-line no-any - (protos as any).{{api.naming.protoPackage}}.{{ service.name }}, - opts) as Promise<{[method: string]: Function}>; + (this._protos as any).{{api.naming.protoPackage}}.{{ service.name }}, + this._opts) as Promise<{[method: string]: Function}>; // Iterate over each of the methods that the service provides // and create an API call method for each. @@ -252,9 +278,9 @@ export class {{ service.name }}Client { throw err; }); - const apiCall = gaxModule.createApiCall( + const apiCall = this._gaxModule.createApiCall( innerCallPromise, - defaults[methodName], + this._defaults[methodName], this._descriptors.page[methodName] || this._descriptors.stream[methodName] || this._descriptors.longrunning[methodName] @@ -268,6 +294,8 @@ export class {{ service.name }}Client { return apiCall(argument, callOptions, callback); }; } + + return this.{{ service.name.toCamelCase() }}Stub; } /** @@ -371,6 +399,7 @@ export class {{ service.name }}Client { options = optionsOrCallback as gax.CallOptions; } {{ util.buildHeaderRequestParam(method) }} + this.initialize(); return this._innerApiCalls.{{ method.name.toCamelCase() }}(request, options, callback); } {%- endfor %} @@ -381,7 +410,8 @@ export class {{ service.name }}Client { */ {{ method.name.toCamelCase() }}( options?: gax.CallOptions): - gax.CancellableStream{ + gax.CancellableStream { + this.initialize(); return this._innerApiCalls.{{ method.name.toCamelCase() }}(options); } {%- elif method.serverStreaming %} @@ -394,6 +424,7 @@ export class {{ service.name }}Client { gax.CancellableStream{ request = request || {}; {{ util.buildHeaderRequestParam(method) }} + this.initialize(); return this._innerApiCalls.{{ method.name.toCamelCase() }}(request, options); } {%- elif method.clientStreaming %} @@ -424,6 +455,7 @@ export class {{ service.name }}Client { optionsOrCallback = {}; } const options = optionsOrCallback as gax.CallOptions; + this.initialize(); return this._innerApiCalls.{{ method.name.toCamelCase() }}(null, options, callback); } {%- endif %} @@ -469,6 +501,7 @@ export class {{ service.name }}Client { options = optionsOrCallback as gax.CallOptions; } {{ util.buildHeaderRequestParam(method) }} + this.initialize(); return this._innerApiCalls.{{ method.name.toCamelCase() }}(request, options, callback); } {%- endfor %} @@ -516,6 +549,7 @@ export class {{ service.name }}Client { options = optionsOrCallback as gax.CallOptions; } {{ util.buildHeaderRequestParam(method) }} + this.initialize(); return this._innerApiCalls.{{ method.name.toCamelCase() }}(request, options, callback); } @@ -529,6 +563,7 @@ export class {{ service.name }}Client { request = request || {}; {{ util.buildHeaderRequestParam(method) }} const callSettings = new gax.CallSettings(options); + this.initialize(); return this._descriptors.page.{{ method.name.toCamelCase() }}.createStream( this._innerApiCalls.{{ method.name.toCamelCase() }} as gax.GaxCall, request, @@ -584,8 +619,9 @@ export class {{ service.name }}Client { * The client will no longer be usable and all future behavior is undefined. */ close(): Promise { + this.initialize(); if (!this._terminated) { - return this.{{ service.name.toCamelCase() }}Stub.then(stub => { + return this.{{ service.name.toCamelCase() }}Stub!.then(stub => { this._terminated = true; stub.close(); }); diff --git a/templates/typescript_gapic/test/gapic-$service-$version.ts.njk b/templates/typescript_gapic/test/gapic-$service-$version.ts.njk index 84f3e4969..e1a7755cb 100644 --- a/templates/typescript_gapic/test/gapic-$service-$version.ts.njk +++ b/templates/typescript_gapic/test/gapic-$service-$version.ts.njk @@ -143,6 +143,22 @@ describe('{{ api.naming.version }}.{{ service.name }}Client', () => { }); assert(client); }); + it('has initialize method and supports deferred initialization', async () => { + const client = new {{ service.name.toLowerCase() }}Module.{{ api.naming.version }}.{{ service.name }}Client({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + assert.strictEqual(client.{{ service.name.toCamelCase() }}Stub, undefined); + await client.initialize(); + assert(client.{{ service.name.toCamelCase() }}Stub); + }); + it('has close method', () => { + const client = new {{ service.name.toLowerCase() }}Module.{{ api.naming.version }}.{{ service.name }}Client({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + client.close(); + }); {%- for method in service.simpleMethods %} describe('{{ method.name.toCamelCase() }}', () => { it('invokes {{ method.name.toCamelCase() }} without error', done => { @@ -150,6 +166,8 @@ describe('{{ api.naming.version }}.{{ service.name }}Client', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request {{ util.initRequestWithHeaderParam(method) }} // Mock response @@ -172,6 +190,8 @@ describe('{{ api.naming.version }}.{{ service.name }}Client', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request {{ util.initRequestWithHeaderParam(method) }} // Mock response @@ -198,6 +218,8 @@ describe('{{ api.naming.version }}.{{ service.name }}Client', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request {{ util.initRequestWithHeaderParam(method) }} // Mock response @@ -223,6 +245,8 @@ describe('{{ api.naming.version }}.{{ service.name }}Client', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request {{ util.initRequestWithHeaderParam(method) }} // Mock response @@ -253,6 +277,8 @@ describe('{{ api.naming.version }}.{{ service.name }}Client', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request {{ util.initRequestWithHeaderParam(method) }} // Mock response @@ -274,6 +300,8 @@ describe('{{ api.naming.version }}.{{ service.name }}Client', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request {{ util.initRequestWithHeaderParam(method) }} // Mock response @@ -300,6 +328,8 @@ describe('{{ api.naming.version }}.{{ service.name }}Client', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request {{ util.initRequestWithHeaderParam(method) }} // Mock response @@ -319,6 +349,8 @@ describe('{{ api.naming.version }}.{{ service.name }}Client', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request {{ util.initRequestWithHeaderParam(method) }} // Mock response @@ -343,6 +375,8 @@ describe('{{ api.naming.version }}.{{ service.name }}Client', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request {{ util.initRequestWithHeaderParam(method) }} // Mock response @@ -365,6 +399,8 @@ describe('{{ api.naming.version }}.{{ service.name }}Client', () => { credentials: {client_email: 'bogus', private_key: 'bogus'}, projectId: 'bogus', }); + // Initialize client before mocking + client.initialize(); // Mock request {{ util.initRequestWithHeaderParam(method) }} // Mock response