diff --git a/packages/google-cloud-lifesciences/protos/google/cloud/lifesciences/v2beta/workflows.proto b/packages/google-cloud-lifesciences/protos/google/cloud/lifesciences/v2beta/workflows.proto index b69928ffa8f..2e9c576c63f 100644 --- a/packages/google-cloud-lifesciences/protos/google/cloud/lifesciences/v2beta/workflows.proto +++ b/packages/google-cloud-lifesciences/protos/google/cloud/lifesciences/v2beta/workflows.proto @@ -1,4 +1,4 @@ -// Copyright 2021 Google LLC +// Copyright 2022 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -17,12 +17,12 @@ syntax = "proto3"; package google.cloud.lifesciences.v2beta; import "google/api/annotations.proto"; +import "google/api/client.proto"; import "google/api/field_behavior.proto"; import "google/longrunning/operations.proto"; import "google/protobuf/duration.proto"; import "google/protobuf/timestamp.proto"; import "google/rpc/code.proto"; -import "google/api/client.proto"; option csharp_namespace = "Google.Cloud.LifeSciences.V2Beta"; option go_package = "google.golang.org/genproto/googleapis/cloud/lifesciences/v2beta;lifesciences"; @@ -112,6 +112,15 @@ message Pipeline { // (though they can overwrite it with a different value). map environment = 3; + // The encrypted environment to pass into every action. Each action can also + // specify its own encrypted environment. + // + // The secret must decrypt to a JSON-encoded dictionary where key-value pairs + // serve as environment variable names and their values. The decoded + // environment variables can overwrite the values specified by the + // `environment` field. + Secret encrypted_environment = 5; + // The maximum amount of time to give the pipeline to complete. This includes // the time spent waiting for a worker to be allocated. If the pipeline fails // to complete before the timeout, it will be cancelled and the error code @@ -172,6 +181,17 @@ message Action { // authors to determine whether an individual action has succeeded or failed. map environment = 5; + // The encrypted environment to pass into the container. This environment is + // merged with values specified in the + // [google.cloud.lifesciences.v2beta.Pipeline][google.cloud.lifesciences.v2beta.Pipeline] message, overwriting any + // duplicate values. + // + // The secret must decrypt to a JSON-encoded dictionary where key-value pairs + // serve as environment variable names and their values. The decoded + // environment variables can overwrite the values specified by the + // `environment` field. + Secret encrypted_environment = 21; + // An optional identifier for a PID namespace to run the action inside. // Multiple actions should use the same string to share a namespace. If // unspecified, a separate isolated namespace is used. @@ -408,6 +428,10 @@ message VirtualMachine { // // Specify either the `volumes[]` field or the `disks[]` field, but not both. repeated Volume volumes = 14; + + // If specified, the VM will only be allocated inside the matching + // reservation. It will fail if the VM parameters don't match the reservation. + string reservation = 15; } // Carries information about a Google Cloud service account. diff --git a/packages/google-cloud-lifesciences/protos/protos.d.ts b/packages/google-cloud-lifesciences/protos/protos.d.ts index 60d1bce2e15..797ed218a8f 100644 --- a/packages/google-cloud-lifesciences/protos/protos.d.ts +++ b/packages/google-cloud-lifesciences/protos/protos.d.ts @@ -289,6 +289,9 @@ export namespace google { /** Pipeline environment */ environment?: ({ [k: string]: string }|null); + /** Pipeline encryptedEnvironment */ + encryptedEnvironment?: (google.cloud.lifesciences.v2beta.ISecret|null); + /** Pipeline timeout */ timeout?: (google.protobuf.IDuration|null); } @@ -311,6 +314,9 @@ export namespace google { /** Pipeline environment. */ public environment: { [k: string]: string }; + /** Pipeline encryptedEnvironment. */ + public encryptedEnvironment?: (google.cloud.lifesciences.v2beta.ISecret|null); + /** Pipeline timeout. */ public timeout?: (google.protobuf.IDuration|null); @@ -410,6 +416,9 @@ export namespace google { /** Action environment */ environment?: ({ [k: string]: string }|null); + /** Action encryptedEnvironment */ + encryptedEnvironment?: (google.cloud.lifesciences.v2beta.ISecret|null); + /** Action pidNamespace */ pidNamespace?: (string|null); @@ -477,6 +486,9 @@ export namespace google { /** Action environment. */ public environment: { [k: string]: string }; + /** Action encryptedEnvironment. */ + public encryptedEnvironment?: (google.cloud.lifesciences.v2beta.ISecret|null); + /** Action pidNamespace. */ public pidNamespace: string; @@ -962,6 +974,9 @@ export namespace google { /** VirtualMachine volumes */ volumes?: (google.cloud.lifesciences.v2beta.IVolume[]|null); + + /** VirtualMachine reservation */ + reservation?: (string|null); } /** Represents a VirtualMachine. */ @@ -1015,6 +1030,9 @@ export namespace google { /** VirtualMachine volumes. */ public volumes: google.cloud.lifesciences.v2beta.IVolume[]; + /** VirtualMachine reservation. */ + public reservation: string; + /** * Creates a new VirtualMachine instance using the specified properties. * @param [properties] Properties to set diff --git a/packages/google-cloud-lifesciences/protos/protos.js b/packages/google-cloud-lifesciences/protos/protos.js index ecbff4d199e..27bcba8cb40 100644 --- a/packages/google-cloud-lifesciences/protos/protos.js +++ b/packages/google-cloud-lifesciences/protos/protos.js @@ -632,6 +632,7 @@ * @property {Array.|null} [actions] Pipeline actions * @property {google.cloud.lifesciences.v2beta.IResources|null} [resources] Pipeline resources * @property {Object.|null} [environment] Pipeline environment + * @property {google.cloud.lifesciences.v2beta.ISecret|null} [encryptedEnvironment] Pipeline encryptedEnvironment * @property {google.protobuf.IDuration|null} [timeout] Pipeline timeout */ @@ -676,6 +677,14 @@ */ Pipeline.prototype.environment = $util.emptyObject; + /** + * Pipeline encryptedEnvironment. + * @member {google.cloud.lifesciences.v2beta.ISecret|null|undefined} encryptedEnvironment + * @memberof google.cloud.lifesciences.v2beta.Pipeline + * @instance + */ + Pipeline.prototype.encryptedEnvironment = null; + /** * Pipeline timeout. * @member {google.protobuf.IDuration|null|undefined} timeout @@ -718,6 +727,8 @@ writer.uint32(/* id 3, wireType 2 =*/26).fork().uint32(/* id 1, wireType 2 =*/10).string(keys[i]).uint32(/* id 2, wireType 2 =*/18).string(message.environment[keys[i]]).ldelim(); if (message.timeout != null && Object.hasOwnProperty.call(message, "timeout")) $root.google.protobuf.Duration.encode(message.timeout, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim(); + if (message.encryptedEnvironment != null && Object.hasOwnProperty.call(message, "encryptedEnvironment")) + $root.google.cloud.lifesciences.v2beta.Secret.encode(message.encryptedEnvironment, writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim(); return writer; }; @@ -785,6 +796,10 @@ message.environment[key] = value; break; } + case 5: { + message.encryptedEnvironment = $root.google.cloud.lifesciences.v2beta.Secret.decode(reader, reader.uint32()); + break; + } case 4: { message.timeout = $root.google.protobuf.Duration.decode(reader, reader.uint32()); break; @@ -846,6 +861,11 @@ if (!$util.isString(message.environment[key[i]])) return "environment: string{k:string} expected"; } + if (message.encryptedEnvironment != null && message.hasOwnProperty("encryptedEnvironment")) { + var error = $root.google.cloud.lifesciences.v2beta.Secret.verify(message.encryptedEnvironment); + if (error) + return "encryptedEnvironment." + error; + } if (message.timeout != null && message.hasOwnProperty("timeout")) { var error = $root.google.protobuf.Duration.verify(message.timeout); if (error) @@ -888,6 +908,11 @@ for (var keys = Object.keys(object.environment), i = 0; i < keys.length; ++i) message.environment[keys[i]] = String(object.environment[keys[i]]); } + if (object.encryptedEnvironment != null) { + if (typeof object.encryptedEnvironment !== "object") + throw TypeError(".google.cloud.lifesciences.v2beta.Pipeline.encryptedEnvironment: object expected"); + message.encryptedEnvironment = $root.google.cloud.lifesciences.v2beta.Secret.fromObject(object.encryptedEnvironment); + } if (object.timeout != null) { if (typeof object.timeout !== "object") throw TypeError(".google.cloud.lifesciences.v2beta.Pipeline.timeout: object expected"); @@ -916,6 +941,7 @@ if (options.defaults) { object.resources = null; object.timeout = null; + object.encryptedEnvironment = null; } if (message.actions && message.actions.length) { object.actions = []; @@ -932,6 +958,8 @@ } if (message.timeout != null && message.hasOwnProperty("timeout")) object.timeout = $root.google.protobuf.Duration.toObject(message.timeout, options); + if (message.encryptedEnvironment != null && message.hasOwnProperty("encryptedEnvironment")) + object.encryptedEnvironment = $root.google.cloud.lifesciences.v2beta.Secret.toObject(message.encryptedEnvironment, options); return object; }; @@ -975,6 +1003,7 @@ * @property {Array.|null} [commands] Action commands * @property {string|null} [entrypoint] Action entrypoint * @property {Object.|null} [environment] Action environment + * @property {google.cloud.lifesciences.v2beta.ISecret|null} [encryptedEnvironment] Action encryptedEnvironment * @property {string|null} [pidNamespace] Action pidNamespace * @property {Object.|null} [portMappings] Action portMappings * @property {Array.|null} [mounts] Action mounts @@ -1051,6 +1080,14 @@ */ Action.prototype.environment = $util.emptyObject; + /** + * Action encryptedEnvironment. + * @member {google.cloud.lifesciences.v2beta.ISecret|null|undefined} encryptedEnvironment + * @memberof google.cloud.lifesciences.v2beta.Action + * @instance + */ + Action.prototype.encryptedEnvironment = null; + /** * Action pidNamespace. * @member {string} pidNamespace @@ -1230,6 +1267,8 @@ writer.uint32(/* id 19, wireType 0 =*/152).bool(message.disableStandardErrorCapture); if (message.blockExternalNetwork != null && Object.hasOwnProperty.call(message, "blockExternalNetwork")) writer.uint32(/* id 20, wireType 0 =*/160).bool(message.blockExternalNetwork); + if (message.encryptedEnvironment != null && Object.hasOwnProperty.call(message, "encryptedEnvironment")) + $root.google.cloud.lifesciences.v2beta.Secret.encode(message.encryptedEnvironment, writer.uint32(/* id 21, wireType 2 =*/170).fork()).ldelim(); return writer; }; @@ -1305,6 +1344,10 @@ message.environment[key] = value; break; } + case 21: { + message.encryptedEnvironment = $root.google.cloud.lifesciences.v2beta.Secret.decode(reader, reader.uint32()); + break; + } case 6: { message.pidNamespace = reader.string(); break; @@ -1460,6 +1503,11 @@ if (!$util.isString(message.environment[key[i]])) return "environment: string{k:string} expected"; } + if (message.encryptedEnvironment != null && message.hasOwnProperty("encryptedEnvironment")) { + var error = $root.google.cloud.lifesciences.v2beta.Secret.verify(message.encryptedEnvironment); + if (error) + return "encryptedEnvironment." + error; + } if (message.pidNamespace != null && message.hasOwnProperty("pidNamespace")) if (!$util.isString(message.pidNamespace)) return "pidNamespace: string expected"; @@ -1560,6 +1608,11 @@ for (var keys = Object.keys(object.environment), i = 0; i < keys.length; ++i) message.environment[keys[i]] = String(object.environment[keys[i]]); } + if (object.encryptedEnvironment != null) { + if (typeof object.encryptedEnvironment !== "object") + throw TypeError(".google.cloud.lifesciences.v2beta.Action.encryptedEnvironment: object expected"); + message.encryptedEnvironment = $root.google.cloud.lifesciences.v2beta.Secret.fromObject(object.encryptedEnvironment); + } if (object.pidNamespace != null) message.pidNamespace = String(object.pidNamespace); if (object.portMappings) { @@ -1652,6 +1705,7 @@ object.disableImagePrefetch = false; object.disableStandardErrorCapture = false; object.blockExternalNetwork = false; + object.encryptedEnvironment = null; } if (message.containerName != null && message.hasOwnProperty("containerName")) object.containerName = message.containerName; @@ -1707,6 +1761,8 @@ object.disableStandardErrorCapture = message.disableStandardErrorCapture; if (message.blockExternalNetwork != null && message.hasOwnProperty("blockExternalNetwork")) object.blockExternalNetwork = message.blockExternalNetwork; + if (message.encryptedEnvironment != null && message.hasOwnProperty("encryptedEnvironment")) + object.encryptedEnvironment = $root.google.cloud.lifesciences.v2beta.Secret.toObject(message.encryptedEnvironment, options); return object; }; @@ -2524,6 +2580,7 @@ * @property {boolean|null} [enableStackdriverMonitoring] VirtualMachine enableStackdriverMonitoring * @property {Array.|null} [dockerCacheImages] VirtualMachine dockerCacheImages * @property {Array.|null} [volumes] VirtualMachine volumes + * @property {string|null} [reservation] VirtualMachine reservation */ /** @@ -2658,6 +2715,14 @@ */ VirtualMachine.prototype.volumes = $util.emptyArray; + /** + * VirtualMachine reservation. + * @member {string} reservation + * @memberof google.cloud.lifesciences.v2beta.VirtualMachine + * @instance + */ + VirtualMachine.prototype.reservation = ""; + /** * Creates a new VirtualMachine instance using the specified properties. * @function create @@ -2715,6 +2780,8 @@ if (message.volumes != null && message.volumes.length) for (var i = 0; i < message.volumes.length; ++i) $root.google.cloud.lifesciences.v2beta.Volume.encode(message.volumes[i], writer.uint32(/* id 14, wireType 2 =*/114).fork()).ldelim(); + if (message.reservation != null && Object.hasOwnProperty.call(message, "reservation")) + writer.uint32(/* id 15, wireType 2 =*/122).string(message.reservation); return writer; }; @@ -2832,6 +2899,10 @@ message.volumes.push($root.google.cloud.lifesciences.v2beta.Volume.decode(reader, reader.uint32())); break; } + case 15: { + message.reservation = reader.string(); + break; + } default: reader.skipType(tag & 7); break; @@ -2940,6 +3011,9 @@ return "volumes." + error; } } + if (message.reservation != null && message.hasOwnProperty("reservation")) + if (!$util.isString(message.reservation)) + return "reservation: string expected"; return null; }; @@ -3023,6 +3097,8 @@ message.volumes[i] = $root.google.cloud.lifesciences.v2beta.Volume.fromObject(object.volumes[i]); } } + if (object.reservation != null) + message.reservation = String(object.reservation); return message; }; @@ -3057,6 +3133,7 @@ object.bootImage = ""; object.nvidiaDriverVersion = ""; object.enableStackdriverMonitoring = false; + object.reservation = ""; } if (message.machineType != null && message.hasOwnProperty("machineType")) object.machineType = message.machineType; @@ -3102,6 +3179,8 @@ for (var j = 0; j < message.volumes.length; ++j) object.volumes[j] = $root.google.cloud.lifesciences.v2beta.Volume.toObject(message.volumes[j], options); } + if (message.reservation != null && message.hasOwnProperty("reservation")) + object.reservation = message.reservation; return object; }; diff --git a/packages/google-cloud-lifesciences/protos/protos.json b/packages/google-cloud-lifesciences/protos/protos.json index 0555dbe7747..5a3e377c671 100644 --- a/packages/google-cloud-lifesciences/protos/protos.json +++ b/packages/google-cloud-lifesciences/protos/protos.json @@ -93,6 +93,10 @@ "type": "string", "id": 3 }, + "encryptedEnvironment": { + "type": "Secret", + "id": 5 + }, "timeout": { "type": "google.protobuf.Duration", "id": 4 @@ -126,6 +130,10 @@ "type": "string", "id": 5 }, + "encryptedEnvironment": { + "type": "Secret", + "id": 21 + }, "pidNamespace": { "type": "string", "id": 6 @@ -301,6 +309,10 @@ "rule": "repeated", "type": "Volume", "id": 14 + }, + "reservation": { + "type": "string", + "id": 15 } } }, @@ -660,7 +672,7 @@ "options": { "go_package": "google.golang.org/genproto/googleapis/api/annotations;annotations", "java_multiple_files": true, - "java_outer_classname": "ClientProto", + "java_outer_classname": "FieldBehaviorProto", "java_package": "com.google.api", "objc_class_prefix": "GAPI", "cc_enable_arenas": true @@ -753,6 +765,22 @@ } } }, + "methodSignature": { + "rule": "repeated", + "type": "string", + "id": 1051, + "extend": "google.protobuf.MethodOptions" + }, + "defaultHost": { + "type": "string", + "id": 1049, + "extend": "google.protobuf.ServiceOptions" + }, + "oauthScopes": { + "type": "string", + "id": 1050, + "extend": "google.protobuf.ServiceOptions" + }, "fieldBehavior": { "rule": "repeated", "type": "google.api.FieldBehavior", @@ -770,22 +798,6 @@ "UNORDERED_LIST": 6, "NON_EMPTY_DEFAULT": 7 } - }, - "methodSignature": { - "rule": "repeated", - "type": "string", - "id": 1051, - "extend": "google.protobuf.MethodOptions" - }, - "defaultHost": { - "type": "string", - "id": 1049, - "extend": "google.protobuf.ServiceOptions" - }, - "oauthScopes": { - "type": "string", - "id": 1050, - "extend": "google.protobuf.ServiceOptions" } } }, diff --git a/packages/google-cloud-lifesciences/src/v2beta/workflows_service_v2_beta_client.ts b/packages/google-cloud-lifesciences/src/v2beta/workflows_service_v2_beta_client.ts index 7de1f486f04..3ef49e76f81 100644 --- a/packages/google-cloud-lifesciences/src/v2beta/workflows_service_v2_beta_client.ts +++ b/packages/google-cloud-lifesciences/src/v2beta/workflows_service_v2_beta_client.ts @@ -25,6 +25,8 @@ import type { ClientOptions, GrpcClientOptions, LROperation, + LocationsClient, + LocationProtos, } from 'google-gax'; import * as protos from '../../protos/protos'; @@ -60,6 +62,7 @@ export class WorkflowsServiceV2BetaClient { }; warn: (code: string, message: string, warnType?: string) => void; innerApiCalls: {[name: string]: Function}; + locationsClient: LocationsClient; operationsClient: gax.OperationsClient; workflowsServiceV2BetaStub?: Promise<{[name: string]: Function}>; @@ -122,6 +125,9 @@ export class WorkflowsServiceV2BetaClient { (typeof window !== 'undefined' && typeof window?.fetch === 'function'); opts = Object.assign({servicePath, port, clientConfig, fallback}, opts); + // Request numeric enum values if REST transport is used. + opts.numericEnums = true; + // If scopes are unset in options and we're connecting to a non-default endpoint, set scopes just in case. if (servicePath !== staticMembers.servicePath && !('scopes' in opts)) { opts['scopes'] = staticMembers.scopes; @@ -154,6 +160,10 @@ export class WorkflowsServiceV2BetaClient { if (servicePath === staticMembers.servicePath) { this.auth.defaultScopes = staticMembers.scopes; } + this.locationsClient = new this._gaxModule.LocationsClient( + this._gaxGrpc, + opts + ); // Determine the client header string. const clientHeader = [`gax/${this._gaxModule.version}`, `gapic/${version}`]; @@ -527,6 +537,262 @@ export class WorkflowsServiceV2BetaClient { protos.google.cloud.lifesciences.v2beta.Metadata >; } + /** + * Gets information about a location. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.name + * Resource name for the location. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [Location]{@link google.cloud.location.Location}. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#regular-methods) + * for more details and examples. + * @example + * ``` + * const [response] = await client.getLocation(request); + * ``` + */ + getLocation( + request: LocationProtos.google.cloud.location.IGetLocationRequest, + options?: + | gax.CallOptions + | Callback< + LocationProtos.google.cloud.location.ILocation, + | LocationProtos.google.cloud.location.IGetLocationRequest + | null + | undefined, + {} | null | undefined + >, + callback?: Callback< + LocationProtos.google.cloud.location.ILocation, + | LocationProtos.google.cloud.location.IGetLocationRequest + | null + | undefined, + {} | null | undefined + > + ): Promise { + return this.locationsClient.getLocation(request, options, callback); + } + + /** + * Lists information about the supported locations for this service. Returns an iterable object. + * + * `for`-`await`-`of` syntax is used with the iterable to get response elements on-demand. + * @param {Object} request + * The request object that will be sent. + * @param {string} request.name + * The resource that owns the locations collection, if applicable. + * @param {string} request.filter + * The standard list filter. + * @param {number} request.pageSize + * The standard list page size. + * @param {string} request.pageToken + * The standard list page token. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Object} + * An iterable Object that allows [async iteration](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols). + * When you iterate the returned iterable, each element will be an object representing + * [Location]{@link google.cloud.location.Location}. The API will be called under the hood as needed, once per the page, + * so you can stop the iteration when you don't need more results. + * Please see the + * [documentation](https://github.com/googleapis/gax-nodejs/blob/master/client-libraries.md#auto-pagination) + * for more details and examples. + * @example + * ``` + * const iterable = client.listLocationsAsync(request); + * for await (const response of iterable) { + * // process response + * } + * ``` + */ + listLocationsAsync( + request: LocationProtos.google.cloud.location.IListLocationsRequest, + options?: CallOptions + ): AsyncIterable { + return this.locationsClient.listLocationsAsync(request, options); + } + + /** + * Gets the latest state of a long-running operation. Clients can use this + * method to poll the operation result at intervals as recommended by the API + * service. + * + * @param {Object} request - The request object that will be sent. + * @param {string} request.name - The name of the operation resource. + * @param {Object=} options + * Optional parameters. You can override the default settings for this call, + * e.g, timeout, retries, paginations, etc. See [gax.CallOptions]{@link + * https://googleapis.github.io/gax-nodejs/global.html#CallOptions} for the + * details. + * @param {function(?Error, ?Object)=} callback + * The function which will be called with the result of the API call. + * + * The second parameter to the callback is an object representing + * [google.longrunning.Operation]{@link + * external:"google.longrunning.Operation"}. + * @return {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing + * [google.longrunning.Operation]{@link + * external:"google.longrunning.Operation"}. The promise has a method named + * "cancel" which cancels the ongoing API call. + * + * @example + * ``` + * const client = longrunning.operationsClient(); + * const name = ''; + * const [response] = await client.getOperation({name}); + * // doThingsWith(response) + * ``` + */ + getOperation( + request: protos.google.longrunning.GetOperationRequest, + options?: + | gax.CallOptions + | Callback< + protos.google.longrunning.Operation, + protos.google.longrunning.GetOperationRequest, + {} | null | undefined + >, + callback?: Callback< + protos.google.longrunning.Operation, + protos.google.longrunning.GetOperationRequest, + {} | null | undefined + > + ): Promise<[protos.google.longrunning.Operation]> { + return this.operationsClient.getOperation(request, options, callback); + } + /** + * Lists operations that match the specified filter in the request. If the + * server doesn't support this method, it returns `UNIMPLEMENTED`. Returns an iterable object. + * + * For-await-of syntax is used with the iterable to recursively get response element on-demand. + * + * @param {Object} request - The request object that will be sent. + * @param {string} request.name - The name of the operation collection. + * @param {string} request.filter - The standard list filter. + * @param {number=} request.pageSize - + * The maximum number of resources contained in the underlying API + * response. If page streaming is performed per-resource, this + * parameter does not affect the return value. If page streaming is + * performed per-page, this determines the maximum number of + * resources in a page. + * @param {Object=} options + * Optional parameters. You can override the default settings for this call, + * e.g, timeout, retries, paginations, etc. See [gax.CallOptions]{@link + * https://googleapis.github.io/gax-nodejs/global.html#CallOptions} for the + * details. + * @returns {Object} + * An iterable Object that conforms to @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols. + * + * @example + * ``` + * const client = longrunning.operationsClient(); + * for await (const response of client.listOperationsAsync(request)); + * // doThingsWith(response) + * ``` + */ + listOperationsAsync( + request: protos.google.longrunning.ListOperationsRequest, + options?: gax.CallOptions + ): AsyncIterable { + return this.operationsClient.listOperationsAsync(request, options); + } + /** + * Starts asynchronous cancellation on a long-running operation. The server + * makes a best effort to cancel the operation, but success is not + * guaranteed. If the server doesn't support this method, it returns + * `google.rpc.Code.UNIMPLEMENTED`. Clients can use + * {@link Operations.GetOperation} or + * other methods to check whether the cancellation succeeded or whether the + * operation completed despite cancellation. On successful cancellation, + * the operation is not deleted; instead, it becomes an operation with + * an {@link Operation.error} value with a {@link google.rpc.Status.code} of + * 1, corresponding to `Code.CANCELLED`. + * + * @param {Object} request - The request object that will be sent. + * @param {string} request.name - The name of the operation resource to be cancelled. + * @param {Object=} options + * Optional parameters. You can override the default settings for this call, + * e.g, timeout, retries, paginations, etc. See [gax.CallOptions]{@link + * https://googleapis.github.io/gax-nodejs/global.html#CallOptions} for the + * details. + * @param {function(?Error)=} callback + * The function which will be called with the result of the API call. + * @return {Promise} - The promise which resolves when API call finishes. + * The promise has a method named "cancel" which cancels the ongoing API + * call. + * + * @example + * ``` + * const client = longrunning.operationsClient(); + * await client.cancelOperation({name: ''}); + * ``` + */ + cancelOperation( + request: protos.google.longrunning.CancelOperationRequest, + options?: + | gax.CallOptions + | Callback< + protos.google.protobuf.Empty, + protos.google.longrunning.CancelOperationRequest, + {} | undefined | null + >, + callback?: Callback< + protos.google.longrunning.CancelOperationRequest, + protos.google.protobuf.Empty, + {} | undefined | null + > + ): Promise { + return this.operationsClient.cancelOperation(request, options, callback); + } + + /** + * Deletes a long-running operation. This method indicates that the client is + * no longer interested in the operation result. It does not cancel the + * operation. If the server doesn't support this method, it returns + * `google.rpc.Code.UNIMPLEMENTED`. + * + * @param {Object} request - The request object that will be sent. + * @param {string} request.name - The name of the operation resource to be deleted. + * @param {Object=} options + * Optional parameters. You can override the default settings for this call, + * e.g, timeout, retries, paginations, etc. See [gax.CallOptions]{@link + * https://googleapis.github.io/gax-nodejs/global.html#CallOptions} for the + * details. + * @param {function(?Error)=} callback + * The function which will be called with the result of the API call. + * @return {Promise} - The promise which resolves when API call finishes. + * The promise has a method named "cancel" which cancels the ongoing API + * call. + * + * @example + * ``` + * const client = longrunning.operationsClient(); + * await client.deleteOperation({name: ''}); + * ``` + */ + deleteOperation( + request: protos.google.longrunning.DeleteOperationRequest, + options?: + | gax.CallOptions + | Callback< + protos.google.protobuf.Empty, + protos.google.longrunning.DeleteOperationRequest, + {} | null | undefined + >, + callback?: Callback< + protos.google.protobuf.Empty, + protos.google.longrunning.DeleteOperationRequest, + {} | null | undefined + > + ): Promise { + return this.operationsClient.deleteOperation(request, options, callback); + } /** * Terminate the gRPC channel and close the client. @@ -539,6 +805,7 @@ export class WorkflowsServiceV2BetaClient { return this.workflowsServiceV2BetaStub.then(stub => { this._terminated = true; stub.close(); + this.locationsClient.close(); this.operationsClient.close(); }); } diff --git a/packages/google-cloud-lifesciences/test/gapic_workflows_service_v2_beta_v2beta.ts b/packages/google-cloud-lifesciences/test/gapic_workflows_service_v2_beta_v2beta.ts index 1aa037d758b..4fea0c4993e 100644 --- a/packages/google-cloud-lifesciences/test/gapic_workflows_service_v2_beta_v2beta.ts +++ b/packages/google-cloud-lifesciences/test/gapic_workflows_service_v2_beta_v2beta.ts @@ -23,7 +23,12 @@ import {SinonStub} from 'sinon'; import {describe, it} from 'mocha'; import * as workflowsservicev2betaModule from '../src'; -import {protobuf, LROperation, operationsProtos} from 'google-gax'; +import { + protobuf, + LROperation, + operationsProtos, + LocationProtos, +} from 'google-gax'; // Dynamically loaded proto JSON is needed to get the type information // to fill in default values for request objects @@ -87,6 +92,29 @@ function stubLongRunningCallWithCallback( : sinon.stub().callsArgWith(2, null, mockOperation); } +function stubAsyncIterationCall( + responses?: ResponseType[], + error?: Error +) { + let counter = 0; + const asyncIterable = { + [Symbol.asyncIterator]() { + return { + async next() { + if (error) { + return Promise.reject(error); + } + if (counter >= responses!.length) { + return Promise.resolve({done: true, value: undefined}); + } + return Promise.resolve({done: false, value: responses![counter++]}); + }, + }; + }, + }; + return sinon.stub().returns(asyncIterable); +} + describe('v2beta.WorkflowsServiceV2BetaClient', () => { describe('Common methods', () => { it('has servicePath', () => { @@ -392,4 +420,523 @@ describe('v2beta.WorkflowsServiceV2BetaClient', () => { assert((client.operationsClient.getOperation as SinonStub).getCall(0)); }); }); + describe('getLocation', () => { + it('invokes getLocation without error', async () => { + const client = + new workflowsservicev2betaModule.v2beta.WorkflowsServiceV2BetaClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new LocationProtos.google.cloud.location.GetLocationRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new LocationProtos.google.cloud.location.Location() + ); + client.locationsClient.getLocation = stubSimpleCall(expectedResponse); + const response = await client.getLocation(request, expectedOptions); + assert.deepStrictEqual(response, [expectedResponse]); + assert( + (client.locationsClient.getLocation as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + it('invokes getLocation without error using callback', async () => { + const client = + new workflowsservicev2betaModule.v2beta.WorkflowsServiceV2BetaClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new LocationProtos.google.cloud.location.GetLocationRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage( + new LocationProtos.google.cloud.location.Location() + ); + client.locationsClient.getLocation = sinon + .stub() + .callsArgWith(2, null, expectedResponse); + const promise = new Promise((resolve, reject) => { + client.getLocation( + request, + expectedOptions, + ( + err?: Error | null, + result?: LocationProtos.google.cloud.location.ILocation | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert((client.locationsClient.getLocation as SinonStub).getCall(0)); + }); + it('invokes getLocation with error', async () => { + const client = + new workflowsservicev2betaModule.v2beta.WorkflowsServiceV2BetaClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new LocationProtos.google.cloud.location.GetLocationRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.locationsClient.getLocation = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects( + client.getLocation(request, expectedOptions), + expectedError + ); + assert( + (client.locationsClient.getLocation as SinonStub) + .getCall(0) + .calledWith(request, expectedOptions, undefined) + ); + }); + }); + describe('listLocationsAsync', () => { + it('uses async iteration with listLocations without error', async () => { + const client = + new workflowsservicev2betaModule.v2beta.WorkflowsServiceV2BetaClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new LocationProtos.google.cloud.location.ListLocationsRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedResponse = [ + generateSampleMessage( + new LocationProtos.google.cloud.location.Location() + ), + generateSampleMessage( + new LocationProtos.google.cloud.location.Location() + ), + generateSampleMessage( + new LocationProtos.google.cloud.location.Location() + ), + ]; + client.locationsClient.descriptors.page.listLocations.asyncIterate = + stubAsyncIterationCall(expectedResponse); + const responses: LocationProtos.google.cloud.location.ILocation[] = []; + const iterable = client.listLocationsAsync(request); + for await (const resource of iterable) { + responses.push(resource!); + } + assert.deepStrictEqual(responses, expectedResponse); + assert.deepStrictEqual( + ( + client.locationsClient.descriptors.page.listLocations + .asyncIterate as SinonStub + ).getCall(0).args[1], + request + ); + assert( + ( + client.locationsClient.descriptors.page.listLocations + .asyncIterate as SinonStub + ) + .getCall(0) + .args[2].otherArgs.headers['x-goog-request-params'].includes( + expectedHeaderRequestParams + ) + ); + }); + it('uses async iteration with listLocations with error', async () => { + const client = + new workflowsservicev2betaModule.v2beta.WorkflowsServiceV2BetaClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new LocationProtos.google.cloud.location.ListLocationsRequest() + ); + request.name = ''; + const expectedHeaderRequestParams = 'name='; + const expectedError = new Error('expected'); + client.locationsClient.descriptors.page.listLocations.asyncIterate = + stubAsyncIterationCall(undefined, expectedError); + const iterable = client.listLocationsAsync(request); + await assert.rejects(async () => { + const responses: LocationProtos.google.cloud.location.ILocation[] = []; + for await (const resource of iterable) { + responses.push(resource!); + } + }); + assert.deepStrictEqual( + ( + client.locationsClient.descriptors.page.listLocations + .asyncIterate as SinonStub + ).getCall(0).args[1], + request + ); + assert( + ( + client.locationsClient.descriptors.page.listLocations + .asyncIterate as SinonStub + ) + .getCall(0) + .args[2].otherArgs.headers['x-goog-request-params'].includes( + expectedHeaderRequestParams + ) + ); + }); + }); + describe('getOperation', () => { + it('invokes getOperation without error', async () => { + const client = + new workflowsservicev2betaModule.v2beta.WorkflowsServiceV2BetaClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new operationsProtos.google.longrunning.GetOperationRequest() + ); + const expectedResponse = generateSampleMessage( + new operationsProtos.google.longrunning.Operation() + ); + client.operationsClient.getOperation = stubSimpleCall(expectedResponse); + const response = await client.getOperation(request); + assert.deepStrictEqual(response, [expectedResponse]); + assert( + (client.operationsClient.getOperation as SinonStub) + .getCall(0) + .calledWith(request) + ); + }); + it('invokes getOperation without error using callback', async () => { + const client = + new workflowsservicev2betaModule.v2beta.WorkflowsServiceV2BetaClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + const request = generateSampleMessage( + new operationsProtos.google.longrunning.GetOperationRequest() + ); + const expectedResponse = generateSampleMessage( + new operationsProtos.google.longrunning.Operation() + ); + client.operationsClient.getOperation = sinon + .stub() + .callsArgWith(2, null, expectedResponse); + const promise = new Promise((resolve, reject) => { + client.operationsClient.getOperation( + request, + undefined, + ( + err?: Error | null, + result?: operationsProtos.google.longrunning.Operation | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert((client.operationsClient.getOperation as SinonStub).getCall(0)); + }); + it('invokes getOperation with error', async () => { + const client = + new workflowsservicev2betaModule.v2beta.WorkflowsServiceV2BetaClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + const request = generateSampleMessage( + new operationsProtos.google.longrunning.GetOperationRequest() + ); + const expectedError = new Error('expected'); + client.operationsClient.getOperation = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects(async () => { + await client.getOperation(request); + }, expectedError); + assert( + (client.operationsClient.getOperation as SinonStub) + .getCall(0) + .calledWith(request) + ); + }); + }); + describe('cancelOperation', () => { + it('invokes cancelOperation without error', async () => { + const client = + new workflowsservicev2betaModule.v2beta.WorkflowsServiceV2BetaClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new operationsProtos.google.longrunning.CancelOperationRequest() + ); + const expectedResponse = generateSampleMessage( + new protos.google.protobuf.Empty() + ); + client.operationsClient.cancelOperation = + stubSimpleCall(expectedResponse); + const response = await client.cancelOperation(request); + assert.deepStrictEqual(response, [expectedResponse]); + assert( + (client.operationsClient.cancelOperation as SinonStub) + .getCall(0) + .calledWith(request) + ); + }); + it('invokes cancelOperation without error using callback', async () => { + const client = + new workflowsservicev2betaModule.v2beta.WorkflowsServiceV2BetaClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + const request = generateSampleMessage( + new operationsProtos.google.longrunning.CancelOperationRequest() + ); + const expectedResponse = generateSampleMessage( + new protos.google.protobuf.Empty() + ); + client.operationsClient.cancelOperation = sinon + .stub() + .callsArgWith(2, null, expectedResponse); + const promise = new Promise((resolve, reject) => { + client.operationsClient.cancelOperation( + request, + undefined, + ( + err?: Error | null, + result?: protos.google.protobuf.Empty | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert((client.operationsClient.cancelOperation as SinonStub).getCall(0)); + }); + it('invokes cancelOperation with error', async () => { + const client = + new workflowsservicev2betaModule.v2beta.WorkflowsServiceV2BetaClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + const request = generateSampleMessage( + new operationsProtos.google.longrunning.CancelOperationRequest() + ); + const expectedError = new Error('expected'); + client.operationsClient.cancelOperation = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects(async () => { + await client.cancelOperation(request); + }, expectedError); + assert( + (client.operationsClient.cancelOperation as SinonStub) + .getCall(0) + .calledWith(request) + ); + }); + }); + describe('deleteOperation', () => { + it('invokes deleteOperation without error', async () => { + const client = + new workflowsservicev2betaModule.v2beta.WorkflowsServiceV2BetaClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new operationsProtos.google.longrunning.DeleteOperationRequest() + ); + const expectedResponse = generateSampleMessage( + new protos.google.protobuf.Empty() + ); + client.operationsClient.deleteOperation = + stubSimpleCall(expectedResponse); + const response = await client.deleteOperation(request); + assert.deepStrictEqual(response, [expectedResponse]); + assert( + (client.operationsClient.deleteOperation as SinonStub) + .getCall(0) + .calledWith(request) + ); + }); + it('invokes deleteOperation without error using callback', async () => { + const client = + new workflowsservicev2betaModule.v2beta.WorkflowsServiceV2BetaClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + const request = generateSampleMessage( + new operationsProtos.google.longrunning.DeleteOperationRequest() + ); + const expectedResponse = generateSampleMessage( + new protos.google.protobuf.Empty() + ); + client.operationsClient.deleteOperation = sinon + .stub() + .callsArgWith(2, null, expectedResponse); + const promise = new Promise((resolve, reject) => { + client.operationsClient.deleteOperation( + request, + undefined, + ( + err?: Error | null, + result?: protos.google.protobuf.Empty | null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + } + ); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert((client.operationsClient.deleteOperation as SinonStub).getCall(0)); + }); + it('invokes deleteOperation with error', async () => { + const client = + new workflowsservicev2betaModule.v2beta.WorkflowsServiceV2BetaClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + const request = generateSampleMessage( + new operationsProtos.google.longrunning.DeleteOperationRequest() + ); + const expectedError = new Error('expected'); + client.operationsClient.deleteOperation = stubSimpleCall( + undefined, + expectedError + ); + await assert.rejects(async () => { + await client.deleteOperation(request); + }, expectedError); + assert( + (client.operationsClient.deleteOperation as SinonStub) + .getCall(0) + .calledWith(request) + ); + }); + }); + describe('listOperationsAsync', () => { + it('uses async iteration with listOperations without error', async () => { + const client = + new workflowsservicev2betaModule.v2beta.WorkflowsServiceV2BetaClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + const request = generateSampleMessage( + new operationsProtos.google.longrunning.ListOperationsRequest() + ); + const expectedResponse = [ + generateSampleMessage( + new operationsProtos.google.longrunning.ListOperationsResponse() + ), + generateSampleMessage( + new operationsProtos.google.longrunning.ListOperationsResponse() + ), + generateSampleMessage( + new operationsProtos.google.longrunning.ListOperationsResponse() + ), + ]; + client.operationsClient.descriptor.listOperations.asyncIterate = + stubAsyncIterationCall(expectedResponse); + const responses: operationsProtos.google.longrunning.ListOperationsResponse[] = + []; + const iterable = client.operationsClient.listOperationsAsync(request); + for await (const resource of iterable) { + responses.push(resource!); + } + assert.deepStrictEqual(responses, expectedResponse); + assert.deepStrictEqual( + ( + client.operationsClient.descriptor.listOperations + .asyncIterate as SinonStub + ).getCall(0).args[1], + request + ); + }); + it('uses async iteration with listOperations with error', async () => { + const client = + new workflowsservicev2betaModule.v2beta.WorkflowsServiceV2BetaClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage( + new operationsProtos.google.longrunning.ListOperationsRequest() + ); + const expectedError = new Error('expected'); + client.operationsClient.descriptor.listOperations.asyncIterate = + stubAsyncIterationCall(undefined, expectedError); + const iterable = client.operationsClient.listOperationsAsync(request); + await assert.rejects(async () => { + const responses: operationsProtos.google.longrunning.ListOperationsResponse[] = + []; + for await (const resource of iterable) { + responses.push(resource!); + } + }); + assert.deepStrictEqual( + ( + client.operationsClient.descriptor.listOperations + .asyncIterate as SinonStub + ).getCall(0).args[1], + request + ); + }); + }); });