"use strict";
/*!
* Copyright 2016 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* 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.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const paginator_1 = require("@google-cloud/paginator");
const promisify_1 = require("@google-cloud/promisify");
const is = require("is");
const snakeCase = require("lodash.snakecase");
const app_profile_1 = require("./app-profile");
const cluster_1 = require("./cluster");
const family_1 = require("./family");
const table_1 = require("./table");
/**
* Create an Instance object to interact with a Cloud Bigtable instance.
*
* @class
* @param {Bigtable} bigtable The parent {@link Bigtable} object of this
* instance.
* @param {string} id Id of the instance.
*
* @example
* const Bigtable = require('@google-cloud/bigtable');
* const bigtable = new Bigtable();
* const instance = bigtable.instance('my-instance');
*/
class Instance {
constructor(bigtable, id) {
this.bigtable = bigtable;
let name;
if (id.includes('/')) {
if (id.startsWith(`${bigtable.projectName}/instances/`)) {
name = id;
}
else {
throw new Error(`Instance id '${id}' is not formatted correctly.
Please use the format 'my-instance' or '${bigtable.projectName}/instances/my-instance'.`);
}
}
else {
name = `${bigtable.projectName}/instances/${id}`;
}
this.id = name.split('/').pop();
this.name = name;
}
/**
* Maps the instance type to the proper integer.
*
* @private
*
* @param {string} type The instance type (production, development).
* @returns {number}
*
* @example
* Instance.getTypeType_('production');
* // 1
*/
static getTypeType_(type) {
const types = {
unspecified: 0,
production: 1,
development: 2,
};
if (is.string(type)) {
type = type.toLowerCase();
}
return types[type] || types.unspecified;
}
/**
* Get a reference to a Bigtable App Profile.
*
* @param {string} name The name of the app profile.
* @returns {AppProfile}
*/
appProfile(name) {
return new app_profile_1.AppProfile(this, name);
}
/**
* Create an instance.
*
* @param {object} options See {@link Bigtable#createInstance}.
* @param {object} [options.gaxOptions] Request configuration options, outlined
* here: https://googleapis.github.io/gax-nodejs/global.html#CallOptions.
* @param {function} callback The callback function.
* @param {?error} callback.err An error returned while making this
* request.
* @param {Instance} callback.instance The newly created
* instance.
* @param {Operation} callback.operation An operation object that can be used
* to check the status of the request.
* @param {object} callback.apiResponse The full API response.
*
* @example <caption>include:samples/document-snippets/instance.js</caption>
* region_tag:bigtable_create_instance
*/
create(options, callback) {
if (is.fn(options)) {
callback = options;
options = {};
}
this.bigtable.createInstance(this.id, options, callback);
}
/**
* Create an app profile.
*
* @param {string} id The name to be used when referring to the new
* app profile within its instance.
* @param {object} options AppProfile creation options.
* @param {'any'|Cluster} options.routing The routing policy for all
* read/write requests which use this app profile. This can be either the
* string 'any' or a cluster of an instance. This value is required when
* creating the app profile and optional when setting the metadata.
* @param {object} [options.gaxOptions] Request configuration options, outlined
* here: https://googleapis.github.io/gax-nodejs/global.html#CallOptions.
* @param {boolean} [options.allowTransactionalWrites] Whether or not
* CheckAndMutateRow and ReadModifyWriteRow requests are allowed by this
* app profile. It is unsafe to send these requests to the same
* table/row/column in multiple clusters. This is only used when the
* routing value is a cluster.
* @param {string} [options.description] The long form description of the use
* case for this AppProfile.
* @param {string} [options.ignoreWarnings] Whether to ignore safety checks
* when creating the app profile
* @param {function} callback The callback function.
* @param {?error} callback.err An error returned while making this request.
* @param {Cluster} callback.appProfile The newly created app profile.
*
* @example <caption>include:samples/document-snippets/instance.js</caption>
* region_tag:bigtable_create_app_profile
*/
createAppProfile(id, options, callback) {
if (is.function(options)) {
callback = options;
options = {};
}
if (!options.routing) {
throw new Error('An app profile must contain a routing policy.');
}
const appProfile = app_profile_1.AppProfile.formatAppProfile_(options);
const reqOpts = {
parent: this.name,
appProfileId: id,
appProfile,
};
if (is.boolean(options.ignoreWarnings)) {
reqOpts.ignoreWarnings = options.ignoreWarnings;
}
this.bigtable.request({
client: 'BigtableInstanceAdminClient',
method: 'createAppProfile',
reqOpts,
gaxOpts: options.gaxOptions,
}, (...args) => {
if (args[1]) {
args.splice(1, 0, this.appProfile(id));
}
callback(...args);
});
}
/**
* Create a cluster.
*
* @param {string} id The id to be used when referring to the new
* cluster within its instance.
* @param {object} options Cluster creation options.
* @param {object} [options.gaxOptions] Request configuration options, outlined
* here: https://googleapis.github.io/gax-nodejs/global.html#CallOptions.
* @param {string} options.location The location where this cluster's nodes
* and storage reside. For best performance clients should be located as
* as close as possible to this cluster. Currently only zones are
* supported.
* @param {number} options.nodes The number of nodes allocated to this
* cluster. More nodes enable higher throughput and more consistent
* performance.
* @param {string} [options.storage] The type of storage used by this cluster
* to serve its parent instance's tables. Options are 'hdd' or 'ssd'.
* @param {function} callback The callback function.
* @param {?error} callback.err An error returned while making this request.
* @param {Cluster} callback.cluster The newly created
* cluster.
* @param {Operation} callback.operation An operation object that can be used
* to check the status of the request.
*
* @example <caption>include:samples/document-snippets/instance.js</caption>
* region_tag:bigtable_create_cluster
*/
createCluster(id, options, callback) {
if (is.function(options)) {
callback = options;
options = {};
}
const reqOpts = {
parent: this.name,
clusterId: id,
};
if (!is.empty(options)) {
reqOpts.cluster = {};
}
if (options.location) {
reqOpts.cluster.location = cluster_1.Cluster.getLocation_(this.bigtable.projectId, options.location);
}
if (options.nodes) {
reqOpts.cluster.serveNodes = options.nodes;
}
if (options.storage) {
const storageType = cluster_1.Cluster.getStorageType_(options.storage);
reqOpts.cluster.defaultStorageType = storageType;
}
this.bigtable.request({
client: 'BigtableInstanceAdminClient',
method: 'createCluster',
reqOpts,
gaxOpts: options.gaxOptions,
}, (...args) => {
if (args[1]) {
args.splice(1, 0, this.cluster(id));
}
callback(...args);
});
}
/**
* Create a table on your Bigtable instance.
*
* @see [Designing Your Schema]{@link https://cloud.google.com/bigtable/docs/schema-design}
* @see [Splitting Keys]{@link https://cloud.google.com/bigtable/docs/managing-tables#splits}
*
* @throws {error} If a id is not provided.
*
* @param {string} id Unique identifier of the table.
* @param {object} [options] Table creation options.
* @param {object|string[]} [options.families] Column families to be created
* within the table.
* @param {object} [options.gaxOptions] Request configuration options, outlined
* here: https://googleapis.github.io/gax-nodejs/CallSettings.html.
* @param {string[]} [options.splits] Initial
* [split keys](https://cloud.google.com/bigtable/docs/managing-tables#splits).
* @param {function} callback The callback function.
* @param {?error} callback.err An error returned while making this request.
* @param {Table} callback.table The newly created table.
* @param {object} callback.apiResponse The full API response.
*
* @example <caption>include:samples/document-snippets/instance.js</caption>
* region_tag:bigtable_create_table
*/
createTable(id, options, callback) {
if (!id) {
throw new Error('An id is required to create a table.');
}
options = options || {};
if (is.function(options)) {
callback = options;
options = {};
}
const reqOpts = {
parent: this.name,
tableId: id,
table: {
// The granularity at which timestamps are stored in the table.
// Currently only milliseconds is supported, so it's not
// configurable.
granularity: 0,
},
};
if (options.splits) {
reqOpts.initialSplits = options.splits.map(key => ({
key,
}));
}
if (options.families) {
const columnFamilies = options.families.reduce((families, family) => {
if (is.string(family)) {
family = {
name: family,
};
}
const columnFamily = (families[family.name] = {});
if (family.rule) {
columnFamily.gcRule = family_1.Family.formatRule_(family.rule);
}
return families;
}, {});
reqOpts.table.columnFamilies = columnFamilies;
}
this.bigtable.request({
client: 'BigtableTableAdminClient',
method: 'createTable',
reqOpts,
gaxOpts: options.gaxOptions,
}, (...args) => {
if (args[1]) {
const table = this.table(args[1].name.split('/').pop());
table.metadata = args[1];
args.splice(1, 0, table);
}
callback(...args);
});
}
/**
* Get a reference to a Bigtable Cluster.
*
* @param {string} id The id of the cluster.
* @returns {Cluster}
*/
cluster(id) {
return new cluster_1.Cluster(this, id);
}
/**
* Delete the instance.
*
* @param {object} [gaxOptions] Request configuration options, outlined here:
* https://googleapis.github.io/gax-nodejs/CallSettings.html.
* @param {function} [callback] The callback function.
* @param {?error} callback.err An error returned while making this
* request.
* @param {object} callback.apiResponse The full API response.
*
* @example <caption>include:samples/document-snippets/instance.js</caption>
* region_tag:bigtable_del_instance
*/
delete(gaxOptions, callback) {
if (is.fn(gaxOptions)) {
callback = gaxOptions;
gaxOptions = {};
}
this.bigtable.request({
client: 'BigtableInstanceAdminClient',
method: 'deleteInstance',
reqOpts: {
name: this.name,
},
gaxOpts: gaxOptions,
}, callback);
}
/**
* Check if an instance exists.
*
* @param {object} [gaxOptions] Request configuration options, outlined
* here: https://googleapis.github.io/gax-nodejs/CallSettings.html.
* @param {function} callback The callback function.
* @param {?error} callback.err An error returned while making this
* request.
* @param {boolean} callback.exists Whether the instance exists or not.
*
* @example <caption>include:samples/document-snippets/instance.js</caption>
* region_tag:bigtable_exists_instance
*/
exists(gaxOptions, callback) {
if (is.fn(gaxOptions)) {
callback = gaxOptions;
gaxOptions = {};
}
this.getMetadata(gaxOptions, err => {
if (err) {
if (err.code === 5) {
callback(null, false);
return;
}
callback(err);
return;
}
callback(null, true);
});
}
/**
* Get an instance if it exists.
*
* @param {object} [gaxOptions] Request configuration options, outlined here:
* https://googleapis.github.io/gax-nodejs/CallSettings.html.
* @param {function} callback The callback function.
* @param {?error} callback.error An error returned while making this request.
* @param {Instance} callback.instance The Instance object.
* @param {object} callback.apiResponse The resource as it exists in the API.
*
* @example <caption>include:samples/document-snippets/instance.js</caption>
* region_tag:bigtable_get_instance
*/
get(gaxOptions, callback) {
if (is.fn(gaxOptions)) {
callback = gaxOptions;
gaxOptions = {};
}
this.getMetadata(gaxOptions, (err, metadata) => {
callback(err, err ? null : this, metadata);
});
}
/**
* Get App Profile objects for this instance.
*
* @param {object} [gaxOptions] Request configuration options, outlined here:
* https://googleapis.github.io/gax-nodejs/CallSettings.html.
* @param {function} callback The callback function.
* @param {?error} callback.error An error returned while making this request.
* @param {AppProfile[]} callback.appProfiles List of all AppProfiles.
* @param {object} callback.apiResponse The full API response.
*
* @example <caption>include:samples/document-snippets/instance.js</caption>
* region_tag:bigtable_get_app_profiles
*/
getAppProfiles(gaxOptions, callback) {
if (is.function(gaxOptions)) {
callback = gaxOptions;
gaxOptions = {};
}
const reqOpts = {
parent: this.name,
};
this.bigtable.request({
client: 'BigtableInstanceAdminClient',
method: 'listAppProfiles',
reqOpts,
gaxOpts: gaxOptions,
}, (err, resp) => {
if (err) {
callback(err);
return;
}
const appProfiles = resp.map(appProfileObj => {
const appProfile = this.appProfile(appProfileObj.name.split('/').pop());
appProfile.metadata = appProfileObj;
return appProfile;
});
callback(null, appProfiles, resp);
});
}
/**
* Get Cluster objects for all of your clusters.
*
* @param {object} [gaxOptions] Request configuration options, outlined here:
* https://googleapis.github.io/gax-nodejs/CallSettings.html.
* @param {function} callback The callback function.
* @param {?error} callback.error An error returned while making this request.
* @param {Cluster[]} callback.clusters List of all
* Clusters.
* @param {object} callback.apiResponse The full API response.
*
* @example <caption>include:samples/document-snippets/instance.js</caption>
* region_tag:bigtable_get_clusters
*/
getClusters(gaxOptions, callback) {
if (is.function(gaxOptions)) {
callback = gaxOptions;
gaxOptions = {};
}
const reqOpts = {
parent: this.name,
};
this.bigtable.request({
client: 'BigtableInstanceAdminClient',
method: 'listClusters',
reqOpts,
gaxOpts: gaxOptions,
}, (err, resp) => {
if (err) {
callback(err);
return;
}
const clusters = resp.clusters.map(clusterObj => {
const cluster = this.cluster(clusterObj.name.split('/').pop());
cluster.metadata = clusterObj;
return cluster;
});
callback(null, clusters, resp);
});
}
/**
* Get the instance metadata.
*
* @param {object} [gaxOptions] Request configuration options, outlined here:
* https://googleapis.github.io/gax-nodejs/CallSettings.html.
* @param {function} callback The callback function.
* @param {?error} callback.err An error returned while making this
* request.
* @param {object} callback.metadata The metadata.
*
* @example <caption>include:samples/document-snippets/instance.js</caption>
* region_tag:bigtable_get_instance_metadata
*/
getMetadata(gaxOptions, callback) {
if (is.fn(gaxOptions)) {
callback = gaxOptions;
gaxOptions = {};
}
this.bigtable.request({
client: 'BigtableInstanceAdminClient',
method: 'getInstance',
reqOpts: {
name: this.name,
},
gaxOpts: gaxOptions,
}, (...args) => {
if (args[1]) {
this.metadata = args[1];
}
callback(...args);
});
}
/**
* Get Table objects for all the tables in your Cloud Bigtable instance.
*
* @param {object} [options] Query object.
* @param {boolean} [options.autoPaginate=true] Have pagination handled
* automatically.
* @param {object} [options.gaxOptions] Request configuration options, outlined
* here: https://googleapis.github.io/gax-nodejs/global.html#CallOptions.
* @param {number} [options.maxApiCalls] Maximum number of API calls to make.
* @param {number} [options.maxResults] Maximum number of items to return.
* @param {string} [options.pageToken] A previously-returned page token
* representing part of a larger set of results to view.
* @param {string} [options.view] View over the table's fields. Possible options
* are 'name', 'schema' or 'full'. Default: 'name'.
* @param {function} callback The callback function.
* @param {?error} callback.err An error returned while making this request.
* @param {Table[]} callback.tables List of all Table objects.These objects contains
* only table name & id but is not a complete representation of a table.
* @param {object} callback.apiResponse The full API response.
*
* @example <caption>include:samples/document-snippets/instance.js</caption>
* region_tag:bigtable_get_tables
*/
getTables(options, callback) {
if (is.function(options)) {
callback = options;
options = {};
}
const reqOpts = Object.assign({}, options, {
parent: this.name,
view: table_1.Table.VIEWS[options.view || 'unspecified'],
});
delete reqOpts.gaxOptions;
this.bigtable.request({
client: 'BigtableTableAdminClient',
method: 'listTables',
reqOpts,
gaxOpts: options.gaxOptions,
}, (...args) => {
if (args[1]) {
args[1] = args[1].map(tableObj => {
const table = this.table(tableObj.name.split('/').pop());
table.metadata = tableObj;
return table;
});
}
callback(...args);
});
}
/**
* Set the instance metadata.
*
* @param {object} metadata Metadata object.
* @param {string} metadata.displayName The descriptive name for this
* instance as it appears in UIs. It can be changed at any time, but
* should be kept globally unique to avoid confusion.
* @param {object} [gaxOptions] Request configuration options, outlined here:
* https://googleapis.github.io/gax-nodejs/global.html#CallOptions.
* @param {function} callback The callback function.
* @param {?error} callback.err An error returned while making this
* request.
* @param {object} callback.apiResponse The full API response.
*
* @example <caption>include:samples/document-snippets/instance.js</caption>
* region_tag:bigtable_set_meta_data
*/
setMetadata(metadata, gaxOptions, callback) {
if (is.fn(gaxOptions)) {
callback = gaxOptions;
gaxOptions = {};
}
const reqOpts = {
instance: Object.assign({ name: this.name }, metadata),
updateMask: {
paths: [],
},
};
const fieldsForMask = ['displayName', 'type', 'labels'];
fieldsForMask.forEach(field => {
if (field in reqOpts.instance) {
reqOpts.updateMask.paths.push(snakeCase(field));
}
});
this.bigtable.request({
client: 'BigtableInstanceAdminClient',
method: 'partialUpdateInstance',
reqOpts,
gaxOpts: gaxOptions,
}, (...args) => {
if (args[1]) {
this.metadata = args[1];
}
callback(...args);
});
}
/**
* Get a reference to a Bigtable table.
*
* @param {string} id Unique identifier of the table.
* @returns {Table}
*
* @example
* const Bigtable = require('@google-cloud/bigtable');
* const bigtable = new Bigtable();
* const instance = bigtable.instance('my-instance');
* const table = instance.table('presidents');
*/
table(id) {
return new table_1.Table(this, id);
}
}
exports.Instance = Instance;
/**
* Get {@link Table} objects for all the tables in your Cloud Bigtable
* instance as a readable object stream.
*
* @param {object} [query] Configuration object. See
* {@link Instance#getTables} for a complete list of options.
* @returns {stream}
*
* @example
* const Bigtable = require('@google-cloud/bigtable');
* const bigtable = new Bigtable();
* const instance = bigtable.instance('my-instance');
*
* instance.getTablesStream()
* .on('error', console.error)
* .on('data', function(table) {
* // table is a Table object.
* })
* .on('end', function() {
* // All tables retrieved.
* });
*
* //-
* // If you anticipate many results, you can end a stream early to prevent
* // unnecessary processing and API requests.
* //-
* instance.getTablesStream()
* .on('data', function(table) {
* this.end();
* });
*/
Instance.prototype.getTablesStream = paginator_1.paginator.streamify('getTables');
/*! Developer Documentation
*
* These methods can be auto-paginated.
*/
paginator_1.paginator.extend(Instance, ['getTables']);
/*! Developer Documentation
*
* All async methods (except for streams) will return a Promise in the event
* that a callback is omitted.
*/
promisify_1.promisifyAll(Instance, {
exclude: ['appProfile', 'cluster', 'table'],
});
/**
* Reference to the {@link Instance} class.
* @name module:@google-cloud/bigtable.Instance
* @see Instance
*/
//# sourceMappingURL=instance.js.map