From c77f6217e294c5114ef0773c4514da2f56b79671 Mon Sep 17 00:00:00 2001 From: Yoshi Automation Bot <44816363+yoshi-automation@users.noreply.github.com> Date: Fri, 22 Feb 2019 07:50:19 -0800 Subject: [PATCH] feat: add import and export instance methods (#132) --- .../google/cloud/redis/v1/cloud_redis.proto | 152 ++++++- .../src/v1/cloud_redis_client.js | 347 ++++++++++++++++ .../src/v1/cloud_redis_client_config.json | 15 + .../google/cloud/redis/v1/doc_cloud_redis.js | 185 ++++++++- packages/google-cloud-redis/synth.metadata | 10 +- packages/google-cloud-redis/test/gapic-v1.js | 387 ++++++++++++++++++ 6 files changed, 1079 insertions(+), 17 deletions(-) diff --git a/packages/google-cloud-redis/protos/google/cloud/redis/v1/cloud_redis.proto b/packages/google-cloud-redis/protos/google/cloud/redis/v1/cloud_redis.proto index 08cdf270cdf..fc5893a0770 100644 --- a/packages/google-cloud-redis/protos/google/cloud/redis/v1/cloud_redis.proto +++ b/packages/google-cloud-redis/protos/google/cloud/redis/v1/cloud_redis.proto @@ -1,4 +1,4 @@ -// Copyright 2018 Google LLC +// Copyright 2018 Google LLC. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -11,6 +11,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. +// syntax = "proto3"; @@ -95,6 +96,43 @@ service CloudRedis { }; } + // Import a Redis RDB snapshot file from GCS into a Redis instance. + // + // Redis may stop serving during this operation. Instance state will be + // IMPORTING for entire operation. When complete, the instance will contain + // only data from the imported file. + // + // The returned operation is automatically deleted after a few hours, so + // there is no need to call DeleteOperation. + rpc ImportInstance(ImportInstanceRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + post: "/v1/{name=projects/*/locations/*/instances/*}:import" + body: "*" + }; + } + + // Export Redis instance data into a Redis RDB format file in GCS. + // + // Redis will continue serving during this operation. + // + // The returned operation is automatically deleted after a few hours, so + // there is no need to call DeleteOperation. + rpc ExportInstance(ExportInstanceRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + post: "/v1/{name=projects/*/locations/*/instances/*}:export" + body: "*" + }; + } + + // Failover the master role to current replica node against a specific + // STANDARD tier redis instance. + rpc FailoverInstance(FailoverInstanceRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + post: "/v1/{name=projects/*/locations/*/instances/*}:failover" + body: "*" + }; + } + // Deletes a specific Redis instance. Instance stops serving and data is // deleted. rpc DeleteInstance(DeleteInstanceRequest) returns (google.longrunning.Operation) { @@ -125,12 +163,17 @@ message Instance { // Redis instance is being deleted. DELETING = 4; - // Redis instance is being repaired and may be unusable. Details can be - // found in the `status_message` field. + // Redis instance is being repaired and may be unusable. REPAIRING = 5; // Maintenance is being performed on this Redis instance. MAINTENANCE = 6; + + // Redis instance is importing data (availability may be affected). + IMPORTING = 8; + + // Redis instance is failing over (availability may be affected). + FAILING_OVER = 9; } // Available service tiers to choose from @@ -177,7 +220,9 @@ message Instance { // Optional. The version of Redis software. // If not provided, latest supported version will be used. Updating the // version will perform an upgrade/downgrade to the new version. Currently, - // the supported values are `REDIS_3_2` for Redis 3.2. + // the supported values are: + // * `REDIS_4_0` for Redis 4.0 compatibility + // * `REDIS_3_2` for Redis 3.2 compatibility string redis_version = 7; // Optional. The CIDR range of internal addresses that are reserved for this @@ -214,8 +259,14 @@ message Instance { // http://redis.io/topics/config. Currently, the only supported parameters // are: // - // * maxmemory-policy - // * notify-keyspace-events + // Redis 3.2 and above: + // * maxmemory-policy + // * notify-keyspace-events + // + // Redis 4.0 and above: + // * activedefrag + // * lfu-log-factor + // * lfu-decay-time map redis_configs = 16; // Required. The service tier of the instance. @@ -229,6 +280,13 @@ message Instance { // instance is connected. If left unspecified, the `default` network // will be used. string authorized_network = 20; + + // Output only. Cloud IAM identity used by import / export operations to + // transfer data to/from Cloud Storage. Format is + // "serviceAccount:". The value may change over time + // for a given instance so should be checked before each import/export + // operation. + string persistence_iam_identity = 21; } // Request for [ListInstances][google.cloud.redis.v1.CloudRedis.ListInstances]. @@ -269,6 +327,9 @@ message ListInstancesResponse { // Token to retrieve the next page of results, or empty if there are no more // results in the list. string next_page_token = 2; + + // Locations that could not be reached. + repeated string unreachable = 3; } // Request for [GetInstance][google.cloud.redis.v1.CloudRedis.GetInstance]. @@ -325,6 +386,85 @@ message DeleteInstanceRequest { string name = 1; } +// The GCS location for the input content +message GcsSource { + // Required. Source data URI. (e.g. 'gs://my_bucket/my_object'). + string uri = 1; +} + +// The input content +message InputConfig { + // Required. Specify source location of input data + oneof source { + // Google Cloud Storage location where input content is located. + GcsSource gcs_source = 1; + } +} + +// Request for [Import][google.cloud.redis.v1.CloudRedis.ImportInstance]. +message ImportInstanceRequest { + // Required. Redis instance resource name using the form: + // `projects/{project_id}/locations/{location_id}/instances/{instance_id}` + // where `location_id` refers to a GCP region + string name = 1; + + // Required. Specify data to be imported. + InputConfig input_config = 3; +} + + +// The GCS location for the output content +message GcsDestination { + // Required. Data destination URI (e.g. + // 'gs://my_bucket/my_object'). Existing files will be overwritten. + string uri = 1; +} + +// The output content +message OutputConfig { + // Required. Specify destination location of output data + oneof destination { + // Google Cloud Storage destination for output content. + GcsDestination gcs_destination = 1; + } +} + +// Request for [Export][google.cloud.redis.v1.CloudRedis.ExportInstance]. +message ExportInstanceRequest { + // Required. Redis instance resource name using the form: + // `projects/{project_id}/locations/{location_id}/instances/{instance_id}` + // where `location_id` refers to a GCP region + string name = 1; + + // Required. Specify data to be exported. + OutputConfig output_config = 3; +} + +// Request for [Failover][google.cloud.redis.v1.CloudRedis.FailoverInstance]. +message FailoverInstanceRequest { + enum DataProtectionMode { + DATA_PROTECTION_MODE_UNSPECIFIED = 0; + + // Instance failover will be protected with data loss control. More + // specifically, the failover will only be performed if the current + // replication offset diff between master and replica is under a certain + // threshold. + LIMITED_DATA_LOSS = 1; + + // Instance failover will be performed without data loss control. + FORCE_DATA_LOSS = 2; + } + + // Required. Redis instance resource name using the form: + // `projects/{project_id}/locations/{location_id}/instances/{instance_id}` + // where `location_id` refers to a GCP region + string name = 1; + + // Optional. Available data protection modes that the user can choose. If it's + // unspecified, data protection mode will be LIMITED_DATA_LOSS by default. + DataProtectionMode data_protection_mode = 2; +} + // Represents the v1 metadata of the long-running operation. message OperationMetadata { // Creation timestamp. diff --git a/packages/google-cloud-redis/src/v1/cloud_redis_client.js b/packages/google-cloud-redis/src/v1/cloud_redis_client.js index a31a2c624de..215cd5cbb2c 100644 --- a/packages/google-cloud-redis/src/v1/cloud_redis_client.js +++ b/packages/google-cloud-redis/src/v1/cloud_redis_client.js @@ -171,6 +171,24 @@ class CloudRedisClient { const deleteInstanceMetadata = protoFilesRoot.lookup( 'google.cloud.redis.v1.OperationMetadata' ); + const importInstanceResponse = protoFilesRoot.lookup( + 'google.cloud.redis.v1.Instance' + ); + const importInstanceMetadata = protoFilesRoot.lookup( + 'google.cloud.redis.v1.OperationMetadata' + ); + const exportInstanceResponse = protoFilesRoot.lookup( + 'google.cloud.redis.v1.Instance' + ); + const exportInstanceMetadata = protoFilesRoot.lookup( + 'google.cloud.redis.v1.OperationMetadata' + ); + const failoverInstanceResponse = protoFilesRoot.lookup( + 'google.cloud.redis.v1.Instance' + ); + const failoverInstanceMetadata = protoFilesRoot.lookup( + 'google.cloud.redis.v1.OperationMetadata' + ); this._descriptors.longrunning = { createInstance: new gax.LongrunningDescriptor( @@ -188,6 +206,21 @@ class CloudRedisClient { deleteInstanceResponse.decode.bind(deleteInstanceResponse), deleteInstanceMetadata.decode.bind(deleteInstanceMetadata) ), + importInstance: new gax.LongrunningDescriptor( + this.operationsClient, + importInstanceResponse.decode.bind(importInstanceResponse), + importInstanceMetadata.decode.bind(importInstanceMetadata) + ), + exportInstance: new gax.LongrunningDescriptor( + this.operationsClient, + exportInstanceResponse.decode.bind(exportInstanceResponse), + exportInstanceMetadata.decode.bind(exportInstanceMetadata) + ), + failoverInstance: new gax.LongrunningDescriptor( + this.operationsClient, + failoverInstanceResponse.decode.bind(failoverInstanceResponse), + failoverInstanceMetadata.decode.bind(failoverInstanceMetadata) + ), }; // Put together the default options sent with requests. @@ -218,6 +251,9 @@ class CloudRedisClient { 'createInstance', 'updateInstance', 'deleteInstance', + 'importInstance', + 'exportInstance', + 'failoverInstance', ]; for (const methodName of cloudRedisStubMethods) { this._innerApiCalls[methodName] = gax.createApiCall( @@ -832,6 +868,317 @@ class CloudRedisClient { return this._innerApiCalls.deleteInstance(request, options, callback); } + /** + * Import a Redis RDB snapshot file from GCS into a Redis instance. + * + * Redis may stop serving during this operation. Instance state will be + * IMPORTING for entire operation. When complete, the instance will contain + * only data from the imported file. + * + * The returned operation is automatically deleted after a few hours, so + * there is no need to call DeleteOperation. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.name + * Required. Redis instance resource name using the form: + * `projects/{project_id}/locations/{location_id}/instances/{instance_id}` + * where `location_id` refers to a GCP region + * @param {Object} request.inputConfig + * Required. Specify data to be imported. + * + * This object should have the same structure as [InputConfig]{@link google.cloud.redis.v1.InputConfig} + * @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 a [gax.Operation]{@link https://googleapis.github.io/gax-nodejs/Operation} object. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is a [gax.Operation]{@link https://googleapis.github.io/gax-nodejs/Operation} object. + * The promise has a method named "cancel" which cancels the ongoing API call. + * + * @example + * + * const redis = require('redis.v1'); + * + * const client = new redis.v1.CloudRedisClient({ + * // optional auth parameters. + * }); + * + * const formattedName = client.instancePath('[PROJECT]', '[LOCATION]', '[INSTANCE]'); + * const inputConfig = {}; + * const request = { + * name: formattedName, + * inputConfig: inputConfig, + * }; + * + * // Handle the operation using the promise pattern. + * client.importInstance(request) + * .then(responses => { + * const [operation, initialApiResponse] = responses; + * + * // Operation#promise starts polling for the completion of the LRO. + * return operation.promise(); + * }) + * .then(responses => { + * const result = responses[0]; + * const metadata = responses[1]; + * const finalApiResponse = responses[2]; + * }) + * .catch(err => { + * console.error(err); + * }); + * + * const formattedName = client.instancePath('[PROJECT]', '[LOCATION]', '[INSTANCE]'); + * const inputConfig = {}; + * const request = { + * name: formattedName, + * inputConfig: inputConfig, + * }; + * + * // Handle the operation using the event emitter pattern. + * client.importInstance(request) + * .then(responses => { + * const [operation, initialApiResponse] = responses; + * + * // Adding a listener for the "complete" event starts polling for the + * // completion of the operation. + * operation.on('complete', (result, metadata, finalApiResponse) => { + * // doSomethingWith(result); + * }); + * + * // Adding a listener for the "progress" event causes the callback to be + * // called on any change in metadata when the operation is polled. + * operation.on('progress', (metadata, apiResponse) => { + * // doSomethingWith(metadata) + * }); + * + * // Adding a listener for the "error" event handles any errors found during polling. + * operation.on('error', err => { + * // throw(err); + * }); + * }) + * .catch(err => { + * console.error(err); + * }); + */ + importInstance(request, options, callback) { + if (options instanceof Function && callback === undefined) { + callback = options; + options = {}; + } + options = options || {}; + + return this._innerApiCalls.importInstance(request, options, callback); + } + + /** + * Export Redis instance data into a Redis RDB format file in GCS. + * + * Redis will continue serving during this operation. + * + * The returned operation is automatically deleted after a few hours, so + * there is no need to call DeleteOperation. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.name + * Required. Redis instance resource name using the form: + * `projects/{project_id}/locations/{location_id}/instances/{instance_id}` + * where `location_id` refers to a GCP region + * @param {Object} request.outputConfig + * Required. Specify data to be exported. + * + * This object should have the same structure as [OutputConfig]{@link google.cloud.redis.v1.OutputConfig} + * @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 a [gax.Operation]{@link https://googleapis.github.io/gax-nodejs/Operation} object. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is a [gax.Operation]{@link https://googleapis.github.io/gax-nodejs/Operation} object. + * The promise has a method named "cancel" which cancels the ongoing API call. + * + * @example + * + * const redis = require('redis.v1'); + * + * const client = new redis.v1.CloudRedisClient({ + * // optional auth parameters. + * }); + * + * const formattedName = client.instancePath('[PROJECT]', '[LOCATION]', '[INSTANCE]'); + * const outputConfig = {}; + * const request = { + * name: formattedName, + * outputConfig: outputConfig, + * }; + * + * // Handle the operation using the promise pattern. + * client.exportInstance(request) + * .then(responses => { + * const [operation, initialApiResponse] = responses; + * + * // Operation#promise starts polling for the completion of the LRO. + * return operation.promise(); + * }) + * .then(responses => { + * const result = responses[0]; + * const metadata = responses[1]; + * const finalApiResponse = responses[2]; + * }) + * .catch(err => { + * console.error(err); + * }); + * + * const formattedName = client.instancePath('[PROJECT]', '[LOCATION]', '[INSTANCE]'); + * const outputConfig = {}; + * const request = { + * name: formattedName, + * outputConfig: outputConfig, + * }; + * + * // Handle the operation using the event emitter pattern. + * client.exportInstance(request) + * .then(responses => { + * const [operation, initialApiResponse] = responses; + * + * // Adding a listener for the "complete" event starts polling for the + * // completion of the operation. + * operation.on('complete', (result, metadata, finalApiResponse) => { + * // doSomethingWith(result); + * }); + * + * // Adding a listener for the "progress" event causes the callback to be + * // called on any change in metadata when the operation is polled. + * operation.on('progress', (metadata, apiResponse) => { + * // doSomethingWith(metadata) + * }); + * + * // Adding a listener for the "error" event handles any errors found during polling. + * operation.on('error', err => { + * // throw(err); + * }); + * }) + * .catch(err => { + * console.error(err); + * }); + */ + exportInstance(request, options, callback) { + if (options instanceof Function && callback === undefined) { + callback = options; + options = {}; + } + options = options || {}; + + return this._innerApiCalls.exportInstance(request, options, callback); + } + + /** + * Failover the master role to current replica node against a specific + * STANDARD tier redis instance. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.name + * Required. Redis instance resource name using the form: + * `projects/{project_id}/locations/{location_id}/instances/{instance_id}` + * where `location_id` refers to a GCP region + * @param {number} request.dataProtectionMode + * Optional. Available data protection modes that the user can choose. If it's + * unspecified, data protection mode will be LIMITED_DATA_LOSS by default. + * + * The number should be among the values of [DataProtectionMode]{@link google.cloud.redis.v1.DataProtectionMode} + * @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 a [gax.Operation]{@link https://googleapis.github.io/gax-nodejs/Operation} object. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is a [gax.Operation]{@link https://googleapis.github.io/gax-nodejs/Operation} object. + * The promise has a method named "cancel" which cancels the ongoing API call. + * + * @example + * + * const redis = require('redis.v1'); + * + * const client = new redis.v1.CloudRedisClient({ + * // optional auth parameters. + * }); + * + * const formattedName = client.instancePath('[PROJECT]', '[LOCATION]', '[INSTANCE]'); + * const dataProtectionMode = 'DATA_PROTECTION_MODE_UNSPECIFIED'; + * const request = { + * name: formattedName, + * dataProtectionMode: dataProtectionMode, + * }; + * + * // Handle the operation using the promise pattern. + * client.failoverInstance(request) + * .then(responses => { + * const [operation, initialApiResponse] = responses; + * + * // Operation#promise starts polling for the completion of the LRO. + * return operation.promise(); + * }) + * .then(responses => { + * const result = responses[0]; + * const metadata = responses[1]; + * const finalApiResponse = responses[2]; + * }) + * .catch(err => { + * console.error(err); + * }); + * + * const formattedName = client.instancePath('[PROJECT]', '[LOCATION]', '[INSTANCE]'); + * const dataProtectionMode = 'DATA_PROTECTION_MODE_UNSPECIFIED'; + * const request = { + * name: formattedName, + * dataProtectionMode: dataProtectionMode, + * }; + * + * // Handle the operation using the event emitter pattern. + * client.failoverInstance(request) + * .then(responses => { + * const [operation, initialApiResponse] = responses; + * + * // Adding a listener for the "complete" event starts polling for the + * // completion of the operation. + * operation.on('complete', (result, metadata, finalApiResponse) => { + * // doSomethingWith(result); + * }); + * + * // Adding a listener for the "progress" event causes the callback to be + * // called on any change in metadata when the operation is polled. + * operation.on('progress', (metadata, apiResponse) => { + * // doSomethingWith(metadata) + * }); + * + * // Adding a listener for the "error" event handles any errors found during polling. + * operation.on('error', err => { + * // throw(err); + * }); + * }) + * .catch(err => { + * console.error(err); + * }); + */ + failoverInstance(request, options, callback) { + if (options instanceof Function && callback === undefined) { + callback = options; + options = {}; + } + options = options || {}; + + return this._innerApiCalls.failoverInstance(request, options, callback); + } + // -------------------- // -- Path templates -- // -------------------- diff --git a/packages/google-cloud-redis/src/v1/cloud_redis_client_config.json b/packages/google-cloud-redis/src/v1/cloud_redis_client_config.json index 79bcd13c4be..632a23dbb44 100644 --- a/packages/google-cloud-redis/src/v1/cloud_redis_client_config.json +++ b/packages/google-cloud-redis/src/v1/cloud_redis_client_config.json @@ -44,6 +44,21 @@ "timeout_millis": 60000, "retry_codes_name": "non_idempotent", "retry_params_name": "default" + }, + "ImportInstance": { + "timeout_millis": 60000, + "retry_codes_name": "non_idempotent", + "retry_params_name": "default" + }, + "ExportInstance": { + "timeout_millis": 60000, + "retry_codes_name": "non_idempotent", + "retry_params_name": "default" + }, + "FailoverInstance": { + "timeout_millis": 60000, + "retry_codes_name": "non_idempotent", + "retry_params_name": "default" } } } diff --git a/packages/google-cloud-redis/src/v1/doc/google/cloud/redis/v1/doc_cloud_redis.js b/packages/google-cloud-redis/src/v1/doc/google/cloud/redis/v1/doc_cloud_redis.js index 840e319a4dd..88c4f8fa948 100644 --- a/packages/google-cloud-redis/src/v1/doc/google/cloud/redis/v1/doc_cloud_redis.js +++ b/packages/google-cloud-redis/src/v1/doc/google/cloud/redis/v1/doc_cloud_redis.js @@ -51,7 +51,9 @@ * Optional. The version of Redis software. * If not provided, latest supported version will be used. Updating the * version will perform an upgrade/downgrade to the new version. Currently, - * the supported values are `REDIS_3_2` for Redis 3.2. + * the supported values are: + * * `REDIS_4_0` for Redis 4.0 compatibility + * * `REDIS_3_2` for Redis 3.2 compatibility * * @property {string} reservedIpRange * Optional. The CIDR range of internal addresses that are reserved for this @@ -92,8 +94,14 @@ * http://redis.io/topics/config. Currently, the only supported parameters * are: * - * * maxmemory-policy - * * notify-keyspace-events + * Redis 3.2 and above: + * * maxmemory-policy + * * notify-keyspace-events + * + * Redis 4.0 and above: + * * activedefrag + * * lfu-log-factor + * * lfu-decay-time * * @property {number} tier * Required. The service tier of the instance. @@ -109,6 +117,13 @@ * instance is connected. If left unspecified, the `default` network * will be used. * + * @property {string} persistenceIamIdentity + * Output only. Cloud IAM identity used by import / export operations to + * transfer data to/from Cloud Storage. Format is + * "serviceAccount:". The value may change over time + * for a given instance so should be checked before each import/export + * operation. + * * @typedef Instance * @memberof google.cloud.redis.v1 * @see [google.cloud.redis.v1.Instance definition in proto format]{@link https://github.com/googleapis/googleapis/blob/master/google/cloud/redis/v1/cloud_redis.proto} @@ -152,15 +167,24 @@ const Instance = { DELETING: 4, /** - * Redis instance is being repaired and may be unusable. Details can be - * found in the `status_message` field. + * Redis instance is being repaired and may be unusable. */ REPAIRING: 5, /** * Maintenance is being performed on this Redis instance. */ - MAINTENANCE: 6 + MAINTENANCE: 6, + + /** + * Redis instance is importing data (availability may be affected). + */ + IMPORTING: 8, + + /** + * Redis instance is failing over (availability may be affected). + */ + FAILING_OVER: 9 }, /** @@ -238,6 +262,9 @@ const ListInstancesRequest = { * Token to retrieve the next page of results, or empty if there are no more * results in the list. * + * @property {string[]} unreachable + * Locations that could not be reached. + * * @typedef ListInstancesResponse * @memberof google.cloud.redis.v1 * @see [google.cloud.redis.v1.ListInstancesResponse definition in proto format]{@link https://github.com/googleapis/googleapis/blob/master/google/cloud/redis/v1/cloud_redis.proto} @@ -338,6 +365,152 @@ const DeleteInstanceRequest = { // This is for documentation. Actual contents will be loaded by gRPC. }; +/** + * The GCS location for the input content + * + * @property {string} uri + * Required. Source data URI. (e.g. 'gs://my_bucket/my_object'). + * + * @typedef GcsSource + * @memberof google.cloud.redis.v1 + * @see [google.cloud.redis.v1.GcsSource definition in proto format]{@link https://github.com/googleapis/googleapis/blob/master/google/cloud/redis/v1/cloud_redis.proto} + */ +const GcsSource = { + // This is for documentation. Actual contents will be loaded by gRPC. +}; + +/** + * The input content + * + * @property {Object} gcsSource + * Google Cloud Storage location where input content is located. + * + * This object should have the same structure as [GcsSource]{@link google.cloud.redis.v1.GcsSource} + * + * @typedef InputConfig + * @memberof google.cloud.redis.v1 + * @see [google.cloud.redis.v1.InputConfig definition in proto format]{@link https://github.com/googleapis/googleapis/blob/master/google/cloud/redis/v1/cloud_redis.proto} + */ +const InputConfig = { + // This is for documentation. Actual contents will be loaded by gRPC. +}; + +/** + * Request for Import. + * + * @property {string} name + * Required. Redis instance resource name using the form: + * `projects/{project_id}/locations/{location_id}/instances/{instance_id}` + * where `location_id` refers to a GCP region + * + * @property {Object} inputConfig + * Required. Specify data to be imported. + * + * This object should have the same structure as [InputConfig]{@link google.cloud.redis.v1.InputConfig} + * + * @typedef ImportInstanceRequest + * @memberof google.cloud.redis.v1 + * @see [google.cloud.redis.v1.ImportInstanceRequest definition in proto format]{@link https://github.com/googleapis/googleapis/blob/master/google/cloud/redis/v1/cloud_redis.proto} + */ +const ImportInstanceRequest = { + // This is for documentation. Actual contents will be loaded by gRPC. +}; + +/** + * The GCS location for the output content + * + * @property {string} uri + * Required. Data destination URI (e.g. + * 'gs://my_bucket/my_object'). Existing files will be overwritten. + * + * @typedef GcsDestination + * @memberof google.cloud.redis.v1 + * @see [google.cloud.redis.v1.GcsDestination definition in proto format]{@link https://github.com/googleapis/googleapis/blob/master/google/cloud/redis/v1/cloud_redis.proto} + */ +const GcsDestination = { + // This is for documentation. Actual contents will be loaded by gRPC. +}; + +/** + * The output content + * + * @property {Object} gcsDestination + * Google Cloud Storage destination for output content. + * + * This object should have the same structure as [GcsDestination]{@link google.cloud.redis.v1.GcsDestination} + * + * @typedef OutputConfig + * @memberof google.cloud.redis.v1 + * @see [google.cloud.redis.v1.OutputConfig definition in proto format]{@link https://github.com/googleapis/googleapis/blob/master/google/cloud/redis/v1/cloud_redis.proto} + */ +const OutputConfig = { + // This is for documentation. Actual contents will be loaded by gRPC. +}; + +/** + * Request for Export. + * + * @property {string} name + * Required. Redis instance resource name using the form: + * `projects/{project_id}/locations/{location_id}/instances/{instance_id}` + * where `location_id` refers to a GCP region + * + * @property {Object} outputConfig + * Required. Specify data to be exported. + * + * This object should have the same structure as [OutputConfig]{@link google.cloud.redis.v1.OutputConfig} + * + * @typedef ExportInstanceRequest + * @memberof google.cloud.redis.v1 + * @see [google.cloud.redis.v1.ExportInstanceRequest definition in proto format]{@link https://github.com/googleapis/googleapis/blob/master/google/cloud/redis/v1/cloud_redis.proto} + */ +const ExportInstanceRequest = { + // This is for documentation. Actual contents will be loaded by gRPC. +}; + +/** + * Request for Failover. + * + * @property {string} name + * Required. Redis instance resource name using the form: + * `projects/{project_id}/locations/{location_id}/instances/{instance_id}` + * where `location_id` refers to a GCP region + * + * @property {number} dataProtectionMode + * Optional. Available data protection modes that the user can choose. If it's + * unspecified, data protection mode will be LIMITED_DATA_LOSS by default. + * + * The number should be among the values of [DataProtectionMode]{@link google.cloud.redis.v1.DataProtectionMode} + * + * @typedef FailoverInstanceRequest + * @memberof google.cloud.redis.v1 + * @see [google.cloud.redis.v1.FailoverInstanceRequest definition in proto format]{@link https://github.com/googleapis/googleapis/blob/master/google/cloud/redis/v1/cloud_redis.proto} + */ +const FailoverInstanceRequest = { + // This is for documentation. Actual contents will be loaded by gRPC. + + /** + * @enum {number} + * @memberof google.cloud.redis.v1 + */ + DataProtectionMode: { + DATA_PROTECTION_MODE_UNSPECIFIED: 0, + + /** + * Instance failover will be protected with data loss control. More + * specifically, the failover will only be performed if the current + * replication offset diff between master and replica is under a certain + * threshold. + */ + LIMITED_DATA_LOSS: 1, + + /** + * Instance failover will be performed without data loss control. + */ + FORCE_DATA_LOSS: 2 + } +}; + /** * Represents the v1 metadata of the long-running operation. * diff --git a/packages/google-cloud-redis/synth.metadata b/packages/google-cloud-redis/synth.metadata index 43c887ebee5..16803402049 100644 --- a/packages/google-cloud-redis/synth.metadata +++ b/packages/google-cloud-redis/synth.metadata @@ -1,19 +1,19 @@ { - "updateTime": "2019-02-13T12:22:31.590631Z", + "updateTime": "2019-02-22T12:18:55.016811Z", "sources": [ { "generator": { "name": "artman", - "version": "0.16.13", - "dockerImage": "googleapis/artman@sha256:5fd9aee1d82a00cebf425c8fa431f5457539562f5867ad9c54370f0ec9a7ccaa" + "version": "0.16.14", + "dockerImage": "googleapis/artman@sha256:f3d61ae45abaeefb6be5f228cda22732c2f1b00fb687c79c4bd4f2c42bb1e1a7" } }, { "git": { "name": "googleapis", "remote": "https://github.com/googleapis/googleapis.git", - "sha": "ca61898878f0926dd9dcc68ba90764f17133efe4", - "internalRef": "233680013" + "sha": "ccdcb03bb137c13f75d87303607101ced8988f85", + "internalRef": "235085569" } }, { diff --git a/packages/google-cloud-redis/test/gapic-v1.js b/packages/google-cloud-redis/test/gapic-v1.js index a6e0c7864c7..a5da3b27019 100644 --- a/packages/google-cloud-redis/test/gapic-v1.js +++ b/packages/google-cloud-redis/test/gapic-v1.js @@ -120,6 +120,7 @@ describe('CloudRedisClient', () => { const statusMessage = 'statusMessage-239442758'; const memorySizeGb = 34199707; const authorizedNetwork = 'authorizedNetwork-1733809270'; + const persistenceIamIdentity = 'persistenceIamIdentity1061944584'; const expectedResponse = { name: name2, displayName: displayName, @@ -133,6 +134,7 @@ describe('CloudRedisClient', () => { statusMessage: statusMessage, memorySizeGb: memorySizeGb, authorizedNetwork: authorizedNetwork, + persistenceIamIdentity: persistenceIamIdentity, }; // Mock Grpc layer @@ -215,6 +217,7 @@ describe('CloudRedisClient', () => { const statusMessage = 'statusMessage-239442758'; const memorySizeGb2 = 1493816946; const authorizedNetwork = 'authorizedNetwork-1733809270'; + const persistenceIamIdentity = 'persistenceIamIdentity1061944584'; const expectedResponse = { name: name, displayName: displayName, @@ -228,6 +231,7 @@ describe('CloudRedisClient', () => { statusMessage: statusMessage, memorySizeGb: memorySizeGb2, authorizedNetwork: authorizedNetwork, + persistenceIamIdentity: persistenceIamIdentity, }; // Mock Grpc layer @@ -349,6 +353,7 @@ describe('CloudRedisClient', () => { const statusMessage = 'statusMessage-239442758'; const memorySizeGb2 = 1493816946; const authorizedNetwork = 'authorizedNetwork-1733809270'; + const persistenceIamIdentity = 'persistenceIamIdentity1061944584'; const expectedResponse = { name: name, displayName: displayName2, @@ -362,6 +367,7 @@ describe('CloudRedisClient', () => { statusMessage: statusMessage, memorySizeGb: memorySizeGb2, authorizedNetwork: authorizedNetwork, + persistenceIamIdentity: persistenceIamIdentity, }; // Mock Grpc layer @@ -543,6 +549,387 @@ describe('CloudRedisClient', () => { ); }); }); + + describe('importInstance', function() { + it('invokes importInstance without error', done => { + const client = new redisModule.v1.CloudRedisClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + + // Mock request + const formattedName = client.instancePath( + '[PROJECT]', + '[LOCATION]', + '[INSTANCE]' + ); + const inputConfig = {}; + const request = { + name: formattedName, + inputConfig: inputConfig, + }; + + // Mock response + const name2 = 'name2-1052831874'; + const displayName = 'displayName1615086568'; + const locationId = 'locationId552319461'; + const alternativeLocationId = 'alternativeLocationId-718920621'; + const redisVersion = 'redisVersion-685310444'; + const reservedIpRange = 'reservedIpRange-1082940580'; + const host = 'host3208616'; + const port = 3446913; + const currentLocationId = 'currentLocationId1312712735'; + const statusMessage = 'statusMessage-239442758'; + const memorySizeGb = 34199707; + const authorizedNetwork = 'authorizedNetwork-1733809270'; + const persistenceIamIdentity = 'persistenceIamIdentity1061944584'; + const expectedResponse = { + name: name2, + displayName: displayName, + locationId: locationId, + alternativeLocationId: alternativeLocationId, + redisVersion: redisVersion, + reservedIpRange: reservedIpRange, + host: host, + port: port, + currentLocationId: currentLocationId, + statusMessage: statusMessage, + memorySizeGb: memorySizeGb, + authorizedNetwork: authorizedNetwork, + persistenceIamIdentity: persistenceIamIdentity, + }; + + // Mock Grpc layer + client._innerApiCalls.importInstance = mockLongRunningGrpcMethod( + request, + expectedResponse + ); + + client + .importInstance(request) + .then(responses => { + const operation = responses[0]; + return operation.promise(); + }) + .then(responses => { + assert.deepStrictEqual(responses[0], expectedResponse); + done(); + }) + .catch(err => { + done(err); + }); + }); + + it('invokes importInstance with error', done => { + const client = new redisModule.v1.CloudRedisClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + + // Mock request + const formattedName = client.instancePath( + '[PROJECT]', + '[LOCATION]', + '[INSTANCE]' + ); + const inputConfig = {}; + const request = { + name: formattedName, + inputConfig: inputConfig, + }; + + // Mock Grpc layer + client._innerApiCalls.importInstance = mockLongRunningGrpcMethod( + request, + null, + error + ); + + client + .importInstance(request) + .then(responses => { + const operation = responses[0]; + return operation.promise(); + }) + .then(() => { + assert.fail(); + }) + .catch(err => { + assert(err instanceof Error); + assert.strictEqual(err.code, FAKE_STATUS_CODE); + done(); + }); + }); + + it('has longrunning decoder functions', () => { + const client = new redisModule.v1.CloudRedisClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + assert( + client._descriptors.longrunning.importInstance + .responseDecoder instanceof Function + ); + assert( + client._descriptors.longrunning.importInstance + .metadataDecoder instanceof Function + ); + }); + }); + + describe('exportInstance', function() { + it('invokes exportInstance without error', done => { + const client = new redisModule.v1.CloudRedisClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + + // Mock request + const formattedName = client.instancePath( + '[PROJECT]', + '[LOCATION]', + '[INSTANCE]' + ); + const outputConfig = {}; + const request = { + name: formattedName, + outputConfig: outputConfig, + }; + + // Mock response + const name2 = 'name2-1052831874'; + const displayName = 'displayName1615086568'; + const locationId = 'locationId552319461'; + const alternativeLocationId = 'alternativeLocationId-718920621'; + const redisVersion = 'redisVersion-685310444'; + const reservedIpRange = 'reservedIpRange-1082940580'; + const host = 'host3208616'; + const port = 3446913; + const currentLocationId = 'currentLocationId1312712735'; + const statusMessage = 'statusMessage-239442758'; + const memorySizeGb = 34199707; + const authorizedNetwork = 'authorizedNetwork-1733809270'; + const persistenceIamIdentity = 'persistenceIamIdentity1061944584'; + const expectedResponse = { + name: name2, + displayName: displayName, + locationId: locationId, + alternativeLocationId: alternativeLocationId, + redisVersion: redisVersion, + reservedIpRange: reservedIpRange, + host: host, + port: port, + currentLocationId: currentLocationId, + statusMessage: statusMessage, + memorySizeGb: memorySizeGb, + authorizedNetwork: authorizedNetwork, + persistenceIamIdentity: persistenceIamIdentity, + }; + + // Mock Grpc layer + client._innerApiCalls.exportInstance = mockLongRunningGrpcMethod( + request, + expectedResponse + ); + + client + .exportInstance(request) + .then(responses => { + const operation = responses[0]; + return operation.promise(); + }) + .then(responses => { + assert.deepStrictEqual(responses[0], expectedResponse); + done(); + }) + .catch(err => { + done(err); + }); + }); + + it('invokes exportInstance with error', done => { + const client = new redisModule.v1.CloudRedisClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + + // Mock request + const formattedName = client.instancePath( + '[PROJECT]', + '[LOCATION]', + '[INSTANCE]' + ); + const outputConfig = {}; + const request = { + name: formattedName, + outputConfig: outputConfig, + }; + + // Mock Grpc layer + client._innerApiCalls.exportInstance = mockLongRunningGrpcMethod( + request, + null, + error + ); + + client + .exportInstance(request) + .then(responses => { + const operation = responses[0]; + return operation.promise(); + }) + .then(() => { + assert.fail(); + }) + .catch(err => { + assert(err instanceof Error); + assert.strictEqual(err.code, FAKE_STATUS_CODE); + done(); + }); + }); + + it('has longrunning decoder functions', () => { + const client = new redisModule.v1.CloudRedisClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + assert( + client._descriptors.longrunning.exportInstance + .responseDecoder instanceof Function + ); + assert( + client._descriptors.longrunning.exportInstance + .metadataDecoder instanceof Function + ); + }); + }); + + describe('failoverInstance', function() { + it('invokes failoverInstance without error', done => { + const client = new redisModule.v1.CloudRedisClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + + // Mock request + const formattedName = client.instancePath( + '[PROJECT]', + '[LOCATION]', + '[INSTANCE]' + ); + const dataProtectionMode = 'DATA_PROTECTION_MODE_UNSPECIFIED'; + const request = { + name: formattedName, + dataProtectionMode: dataProtectionMode, + }; + + // Mock response + const name2 = 'name2-1052831874'; + const displayName = 'displayName1615086568'; + const locationId = 'locationId552319461'; + const alternativeLocationId = 'alternativeLocationId-718920621'; + const redisVersion = 'redisVersion-685310444'; + const reservedIpRange = 'reservedIpRange-1082940580'; + const host = 'host3208616'; + const port = 3446913; + const currentLocationId = 'currentLocationId1312712735'; + const statusMessage = 'statusMessage-239442758'; + const memorySizeGb = 34199707; + const authorizedNetwork = 'authorizedNetwork-1733809270'; + const persistenceIamIdentity = 'persistenceIamIdentity1061944584'; + const expectedResponse = { + name: name2, + displayName: displayName, + locationId: locationId, + alternativeLocationId: alternativeLocationId, + redisVersion: redisVersion, + reservedIpRange: reservedIpRange, + host: host, + port: port, + currentLocationId: currentLocationId, + statusMessage: statusMessage, + memorySizeGb: memorySizeGb, + authorizedNetwork: authorizedNetwork, + persistenceIamIdentity: persistenceIamIdentity, + }; + + // Mock Grpc layer + client._innerApiCalls.failoverInstance = mockLongRunningGrpcMethod( + request, + expectedResponse + ); + + client + .failoverInstance(request) + .then(responses => { + const operation = responses[0]; + return operation.promise(); + }) + .then(responses => { + assert.deepStrictEqual(responses[0], expectedResponse); + done(); + }) + .catch(err => { + done(err); + }); + }); + + it('invokes failoverInstance with error', done => { + const client = new redisModule.v1.CloudRedisClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + + // Mock request + const formattedName = client.instancePath( + '[PROJECT]', + '[LOCATION]', + '[INSTANCE]' + ); + const dataProtectionMode = 'DATA_PROTECTION_MODE_UNSPECIFIED'; + const request = { + name: formattedName, + dataProtectionMode: dataProtectionMode, + }; + + // Mock Grpc layer + client._innerApiCalls.failoverInstance = mockLongRunningGrpcMethod( + request, + null, + error + ); + + client + .failoverInstance(request) + .then(responses => { + const operation = responses[0]; + return operation.promise(); + }) + .then(() => { + assert.fail(); + }) + .catch(err => { + assert(err instanceof Error); + assert.strictEqual(err.code, FAKE_STATUS_CODE); + done(); + }); + }); + + it('has longrunning decoder functions', () => { + const client = new redisModule.v1.CloudRedisClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + assert( + client._descriptors.longrunning.failoverInstance + .responseDecoder instanceof Function + ); + assert( + client._descriptors.longrunning.failoverInstance + .metadataDecoder instanceof Function + ); + }); + }); }); function mockSimpleGrpcMethod(expectedRequest, response, error) {