Skip to content

Commit

Permalink
refactor: Dual-Region API Update (#1977)
Browse files Browse the repository at this point in the history
* refactor: Dual-Region API Update

* 馃 Updates from OwlBot post-processor

See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md

* refactor: `dataPlacement` -> `customPlacementConfig`

* refactor: create `CustomPlacementConfig` type for jsdoc

Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
  • Loading branch information
danielbankhead and gcf-owl-bot[bot] committed Jul 14, 2022
1 parent 4bd30be commit 91aeab6
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 22 deletions.
4 changes: 2 additions & 2 deletions samples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ __Usage:__

### Create a Dual-Region Bucket

Create a Dual-Region Bucket with provided locations.
Create a Dual-Region Bucket with provided location and regions.

View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/createBucketWithDualRegion.js).

Expand All @@ -425,7 +425,7 @@ View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/sa
__Usage:__


`node createBucketWithDualRegion.js <BUCKET_NAME> <REGION1> <REGION2>`
`node createBucketWithDualRegion.js <BUCKET_NAME> <LOCATION> <REGION1> <REGION2>`


-----
Expand Down
13 changes: 9 additions & 4 deletions samples/createBucketWithDualRegion.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@

// sample-metadata:
// title: Create a Dual-Region Bucket
// description: Create a Dual-Region Bucket with provided locations.
// usage: node createBucketWithDualRegion.js <BUCKET_NAME> <REGION1> <REGION2>
// description: Create a Dual-Region Bucket with provided location and regions.
// usage: node createBucketWithDualRegion.js <BUCKET_NAME> <LOCATION> <REGION1> <REGION2>

function main(
bucketName = 'my-bucket',
location = 'US',
region1 = 'US-EAST1',
region2 = 'US-WEST1'
) {
Expand All @@ -36,6 +37,7 @@ function main(
// The bucket's pair of regions. Case-insensitive.
// See this documentation for other valid locations:
// https://cloud.google.com/storage/docs/locations
// const location = 'US';
// const region1 = 'US-EAST1';
// const region2 = 'US-WEST1';

Expand All @@ -50,10 +52,13 @@ function main(
async function createDualRegionBucket() {
// For regions supporting dual-regions see: https://cloud.google.com/storage/docs/locations
const [bucket] = await storage.createBucket(bucketName, {
location: `${region1}+${region2}`, // e.g. `US-EAST1+US-WEST1`
location,
customPlacementConfig: {
dataLocations: [region1, region2],
},
});

console.log(`${bucket.name} created in '${region1}+${region2}'`);
console.log(`${bucket.name} created in '${region1}' and '${region2}'`);
}

createDualRegionBucket().catch(console.error);
Expand Down
26 changes: 20 additions & 6 deletions samples/system-test/buckets.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ const dualRegionBucketTurbo = storage.bucket(bucketNameDualRegionTurbo);
const PUBLIC_ACCESS_PREVENTION_INHERITED = 'inherited';
const PUBLIC_ACCESS_PREVENTION_ENFORCED = 'enforced';

const DUAL_REGION = ['US-EAST1', 'US-WEST1'];
const DUAL_REGION = {
LOCATION: 'US',
REGIONS: ['US-EAST1', 'US-WEST1'],
};
const RPO_ASYNC_TURBO = 'ASYNC_TURBO';
const RPO_DEFAULT = 'DEFAULT';

Expand Down Expand Up @@ -216,19 +219,30 @@ it('should set public access prevention to inherited', async () => {
});

it('should create a dual-region bucket', async () => {
const dualRegion = `${DUAL_REGION[0]}+${DUAL_REGION[1]}`;

const output = execSync(
`node createBucketWithDualRegion.js ${bucketNameDualRegion} ${DUAL_REGION[0]} ${DUAL_REGION[1]}`
`node createBucketWithDualRegion.js ${bucketNameDualRegion} ${DUAL_REGION.LOCATION} ${DUAL_REGION.REGIONS[0]} ${DUAL_REGION.REGIONS[1]}`
);

assert.include(output, `${bucketNameDualRegion} created in '${dualRegion}'`);
assert.include(
output,
`${bucketNameDualRegion} created in '${DUAL_REGION.REGIONS[0]}' and '${DUAL_REGION.REGIONS[1]}'`
);

const [exists] = await dualRegionBucket.exists();
assert.strictEqual(exists, true);

const [metadata] = await dualRegionBucket.getMetadata();
assert.strictEqual(metadata.location, dualRegion);

assert.strictEqual(metadata.location, DUAL_REGION.LOCATION);

assert(metadata.customPlacementConfig);
assert(Array.isArray(metadata.customPlacementConfig.dataLocations));

const dataLocations = metadata.customPlacementConfig.dataLocations;

assert(dataLocations.includes(DUAL_REGION.REGIONS[0]));
assert(dataLocations.includes(DUAL_REGION.REGIONS[1]));

assert.strictEqual(metadata.locationType, 'dual-region');
});

Expand Down
29 changes: 22 additions & 7 deletions src/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,19 @@ interface Versioning {
enabled: boolean;
}

/**
* Custom placement configuration.
* Initially used for dual-region buckets.
**/
export interface CustomPlacementConfig {
dataLocations?: string[];
}

export interface CreateBucketRequest {
archive?: boolean;
coldline?: boolean;
cors?: Cors[];
customPlacementConfig?: CustomPlacementConfig;
dra?: boolean;
location?: string;
multiRegional?: boolean;
Expand Down Expand Up @@ -728,10 +737,12 @@ export class Storage extends Service {
* @property {boolean} [archive=false] Specify the storage class as Archive.
* @property {boolean} [coldline=false] Specify the storage class as Coldline.
* @property {Cors[]} [cors=[]] Specify the CORS configuration to use.
* @property {CustomPlacementConfig} [customPlacementConfig={}] Specify the bucket's regions for dual-region buckets.
* For more information, see {@link https://cloud.google.com/storage/docs/locations| Bucket Locations}.
* @property {boolean} [dra=false] Specify the storage class as Durable Reduced
* Availability.
* @property {string} [location] Specify the bucket's location(s). If specifying
* a dual-region, can be specified as a string `"US-CENTRAL1+US-WEST1"`.
* @property {string} [location] Specify the bucket's location. If specifying
* a dual-region, the `customPlacementConfig` property should be set in conjunction.
* For more information, see {@link https://cloud.google.com/storage/docs/locations| Bucket Locations}.
* @property {boolean} [multiRegional=false] Specify the storage class as
* Multi-Regional.
Expand Down Expand Up @@ -845,8 +856,9 @@ export class Storage extends Service {
metadata = metadataOrCallback as CreateBucketRequest;
}

const body = Object.assign({}, metadata, {name}) as {} as {
[index: string]: string | {};
const body: CreateBucketRequest & {[index: string]: string | {}} = {
...metadata,
name,
};

const storageClasses = {
Expand All @@ -857,9 +869,12 @@ export class Storage extends Service {
nearline: 'NEARLINE',
regional: 'REGIONAL',
standard: 'STANDARD',
} as {[index: string]: string};
} as const;
const storageClassKeys = Object.keys(
storageClasses
) as (keyof typeof storageClasses)[];

Object.keys(storageClasses).forEach(storageClass => {
for (const storageClass of storageClassKeys) {
if (body[storageClass]) {
if (metadata.storageClass && metadata.storageClass !== storageClass) {
throw new Error(
Expand All @@ -869,7 +884,7 @@ export class Storage extends Service {
body.storageClass = storageClasses[storageClass];
delete body[storageClass];
}
});
}

if (body.requesterPays) {
body.billing = {
Expand Down
21 changes: 18 additions & 3 deletions system-test/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -949,6 +949,7 @@ describe('storage', () => {
describe('dual-region', () => {
let bucket: Bucket;

const LOCATION = 'US';
const REGION1 = 'US-EAST1';
const REGION2 = 'US-WEST1';

Expand All @@ -957,14 +958,28 @@ describe('storage', () => {
});

it('creates a dual-region bucket', async () => {
const dualRegion = `${REGION1}+${REGION2}`;
await bucket.create({location: dualRegion});
await bucket.create({
location: LOCATION,
customPlacementConfig: {
dataLocations: [REGION1, REGION2],
},
});

const [exists] = await bucket.exists();
assert.strictEqual(exists, true);

const [bucketMetadata] = await bucket.getMetadata();
assert.strictEqual(bucketMetadata.location, dualRegion);

assert.strictEqual(bucketMetadata.location, LOCATION);

assert(bucketMetadata.customPlacementConfig);
assert(Array.isArray(bucketMetadata.customPlacementConfig.dataLocations));

const dataLocations = bucketMetadata.customPlacementConfig.dataLocations;

assert(dataLocations.includes(REGION1));
assert(dataLocations.includes(REGION2));

assert.strictEqual(bucketMetadata.locationType, 'dual-region');
});
});
Expand Down

0 comments on commit 91aeab6

Please sign in to comment.