Skip to content

Commit

Permalink
feat: add GetInstanceConfig function (#1438)
Browse files Browse the repository at this point in the history
Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
  • Loading branch information
olavloite and gcf-owl-bot[bot] committed Aug 3, 2021
1 parent 260831d commit 56e0598
Show file tree
Hide file tree
Showing 3 changed files with 196 additions and 1 deletion.
111 changes: 111 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {
PagedCallback,
PagedOptionsWithFilter,
CLOUD_RESOURCE_HEADER,
NormalCallback,
} from './common';
import {Session} from './session';
import {SessionPool} from './session-pool';
Expand Down Expand Up @@ -75,6 +76,12 @@ export type GetInstanceConfigsCallback = PagedCallback<
instanceAdmin.spanner.admin.instance.v1.IListInstanceConfigsResponse
>;

export interface GetInstanceConfigOptions {
gaxOptions?: CallOptions;
}
export type GetInstanceConfigResponse = [IInstanceConfig];
export type GetInstanceConfigCallback = NormalCallback<IInstanceConfig>;

export interface SpannerOptions extends GrpcClientOptions {
apiEndpoint?: string;
servicePath?: string;
Expand Down Expand Up @@ -682,6 +689,9 @@ class Spanner extends GrpcService {
* @property {string} 0.name The unique identifier for the instance config.
* @property {string} 0.displayName The name of the instance config as it
* appears in UIs.
* @property {google.spanner.admin.instance.v1.IReplicaInfo[]} 0.replicas The replicas used by
* this instance config.
* @property {string[]} 0.leaderOptions The possible leader options for this instance config.
* @property {object} 1 A query object to receive more results.
* @property {object} 2 The full API response.
*/
Expand All @@ -693,6 +703,9 @@ class Spanner extends GrpcService {
* config.
* @param {string} instanceConfigs.displayName The name of the instance config
* as it appears in UIs.
* @param {google.spanner.admin.instance.v1.IReplicaInfo[]} instanceConfigs.replicas The replicas used by
* this instance config.
* @param {string[]} instanceConfigs.leaderOptions The possible leader options for this instance config.
* @param {object} nextQuery A query object to receive more results.
* @param {object} apiResponse The full API response.
*/
Expand Down Expand Up @@ -857,6 +870,103 @@ class Spanner extends GrpcService {
});
}

getInstanceConfig(name: string): Promise<GetInstanceConfigResponse>;
getInstanceConfig(
name: string,
options: GetInstanceConfigOptions
): Promise<GetInstanceConfigResponse>;
getInstanceConfig(name: string, callback: GetInstanceConfigCallback): void;
getInstanceConfig(
name: string,
options: GetInstanceConfigOptions,
callback: GetInstanceConfigCallback
): void;
/**
* Gets the instance configuration with the specified name.
*/
/**
* @typedef {array} GetInstanceConfigResponse
* @property {object[]} 0 The metadata of the instance config.
* @property {string} 0.name The unique identifier for the instance config.
* @property {string} 0.displayName The name of the instance config as it
* appears in UIs.
* @property {google.spanner.admin.instance.v1.IReplicaInfo[]} 0.replicas The replicas used by
* this instance config.
* @property {string[]} 0.leaderOptions The possible leader options for this instance config.
*/
/**
* @callback GetInstanceConfigCallback
* @param {?Error} err Request error, if any.
* @param {object} instanceConfig The metadata of the instance config.
* @param {string} instanceConfig.name The unique identifier for the instance
* config.
* @param {string} instanceConfig.displayName The name of the instance config
* as it appears in UIs.
* @param {google.spanner.admin.instance.v1.IReplicaInfo[]} instanceConfig.replicas The replicas used by
* this instance config.
* @param {string[]} 0.leaderOptions The possible leader options for this instance config.
*/
/**
* Get a specific instance config.
*
* Wrapper around {@link v1.InstanceAdminClient#getInstanceConfig}.
*
* @see {@link v1.InstanceAdminClient#getInstanceConfig}
* @see [GetInstanceConfig API Documentation](https://cloud.google.com/spanner/docs/reference/rpc/google.spanner.admin.instance.v1#google.spanner.admin.instance.v1.InstanceAdmin.GetInstanceConfig)
*
* @param {string} [name] The name of the instance config to get.
* @param {GetInstanceConfigCallback} [callback] Callback function.
* @returns {Promise<GetInstanceConfigResponse>}
*
* @example
* const {Spanner} = require('@google-cloud/spanner');
* const spanner = new Spanner();
*
* spanner.getInstanceConfig('nam6', function(err, instanceConfig) {
* // `instanceConfig` is an instance configuration descriptor.
* });
*
* //-
* // If the callback is omitted, we'll return a Promise.
* //-
* spanner.getInstanceConfig().then(function(data) {
* const instanceConfig = data[0];
* });
*/
getInstanceConfig(
name: string,
optionsOrCallback?: GetInstanceConfigOptions | GetInstanceConfigCallback,
cb?: GetInstanceConfigCallback
): Promise<GetInstanceConfigResponse> | void {
const callback =
typeof optionsOrCallback === 'function' ? optionsOrCallback : cb;
const options =
typeof optionsOrCallback === 'object'
? optionsOrCallback
: ({} as GetInstanceConfigOptions);

const reqOpts = extend(
{},
{
name: 'projects/' + this.projectId + '/instanceConfigs/' + name,
}
);
const gaxOpts = extend({}, options.gaxOptions);

return this.request(
{
client: 'InstanceAdminClient',
method: 'getInstanceConfig',
reqOpts,
gaxOpts,
headers: this.resourceHeader_,
},
(err, instanceConfig) => {
callback!(err, instanceConfig);
}
);
}

/**
* Get a reference to an Instance object.
*
Expand Down Expand Up @@ -1290,5 +1400,6 @@ export {Transaction};
* Reference to {@link v1.SpannerClient}
*/
import * as protos from '../protos/protos';
import IInstanceConfig = instanceAdmin.spanner.admin.instance.v1.IInstanceConfig;
export {v1, protos};
export default {Spanner};
25 changes: 25 additions & 0 deletions system-test/spanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -933,6 +933,31 @@ describe('Spanner', () => {
})
);
});

it('should get an instanceConfig', function (done) {
if (IS_EMULATOR_ENABLED) {
this.skip();
}
spanner.getInstanceConfig('nam6', (err, instanceConfig) => {
assert.ifError(err);
assert(instanceConfig!.displayName);
done();
});
});

it('should get an instanceConfig in promise mode', function (done) {
if (IS_EMULATOR_ENABLED) {
this.skip();
}
spanner
.getInstanceConfig('nam6')
.then(data => {
const instanceConfig = data[0];
assert(instanceConfig.displayName);
done();
})
.catch(done);
});
});

describe('Databases', () => {
Expand Down
61 changes: 60 additions & 1 deletion test/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ import * as sinon from 'sinon';
import * as spnr from '../src';
import {Duplex} from 'stream';
import {CreateInstanceRequest} from '../src/index';
import {GetInstanceConfigsOptions, GetInstancesOptions} from '../src';
import {
GetInstanceConfigOptions,
GetInstanceConfigsOptions,
GetInstancesOptions,
} from '../src';
import {CLOUD_RESOURCE_HEADER} from '../src/common';

// Verify that CLOUD_RESOURCE_HEADER is set to a correct value.
Expand Down Expand Up @@ -1286,6 +1290,61 @@ describe('Spanner', () => {
});
});

describe('getInstanceConfig', () => {
beforeEach(() => {
spanner.request = util.noop;
});

it('should make and return the correct request', () => {
const options: GetInstanceConfigOptions = {
gaxOptions: {timeout: 5},
};
const expectedReqOpts = {
name: `projects/${spanner.projectId}/instanceConfigs/nam1`,
};

function callback() {}

const returnValue = {};

spanner.request = config => {
assert.strictEqual(config.client, 'InstanceAdminClient');
assert.strictEqual(config.method, 'getInstanceConfig');

const reqOpts = config.reqOpts;
assert.deepStrictEqual(reqOpts, expectedReqOpts);
assert.notStrictEqual(reqOpts, options);

const gaxOpts = config.gaxOpts;
assert.deepStrictEqual(gaxOpts, options.gaxOptions);
assert.deepStrictEqual(config.headers, spanner.resourceHeader_);

return returnValue;
};

const returnedValue = spanner.getInstanceConfig(
'nam1',
options,
callback
);
assert.strictEqual(returnedValue, returnValue);
});

it('should not require options', done => {
spanner.request = config => {
const reqOpts = config.reqOpts;
assert.deepStrictEqual(reqOpts, {
name: `projects/${spanner.projectId}/instanceConfigs/nam1`,
});
assert.deepStrictEqual(config.gaxOpts, {});

done();
};

spanner.getInstanceConfig('nam1', assert.ifError);
});
});

describe('instance', () => {
const NAME = 'instance-name';

Expand Down

0 comments on commit 56e0598

Please sign in to comment.