From fc618f97128ab1dc25b735bd634c52f2c47ef457 Mon Sep 17 00:00:00 2001 From: Meng Xin Zhu Date: Tue, 27 Apr 2021 15:59:13 +0800 Subject: [PATCH] feat(neptune): change InstanceType to class that is built from string (#14273) closes #13923 BREAKING CHANGE: `InstanceType` changed from enum to enum-like static factory. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-neptune/lib/cluster.ts | 2 +- packages/@aws-cdk/aws-neptune/lib/instance.ts | 63 ++++++++++++++----- .../aws-neptune/test/instance.test.ts | 36 ++++++++++- 3 files changed, 84 insertions(+), 17 deletions(-) diff --git a/packages/@aws-cdk/aws-neptune/lib/cluster.ts b/packages/@aws-cdk/aws-neptune/lib/cluster.ts index f3c735b78f2c7..4420659499a59 100644 --- a/packages/@aws-cdk/aws-neptune/lib/cluster.ts +++ b/packages/@aws-cdk/aws-neptune/lib/cluster.ts @@ -503,7 +503,7 @@ export class DatabaseCluster extends DatabaseClusterBase implements IDatabaseClu dbClusterIdentifier: cluster.ref, dbInstanceIdentifier: instanceIdentifier, // Instance properties - dbInstanceClass: props.instanceType, + dbInstanceClass: props.instanceType._instanceType, dbParameterGroupName: props.parameterGroup?.parameterGroupName, }); diff --git a/packages/@aws-cdk/aws-neptune/lib/instance.ts b/packages/@aws-cdk/aws-neptune/lib/instance.ts index 8459c710577c8..12920fe95444b 100644 --- a/packages/@aws-cdk/aws-neptune/lib/instance.ts +++ b/packages/@aws-cdk/aws-neptune/lib/instance.ts @@ -10,59 +10,92 @@ import { IParameterGroup } from './parameter-group'; * Possible Instances Types to use in Neptune cluster * used for defining {@link DatabaseInstanceProps.instanceType}. */ -export enum InstanceType { +export class InstanceType { + /** * db.r5.large */ - R5_LARGE = 'db.r5.large', + public static readonly R5_LARGE = InstanceType.of('db.r5.large'); + /** * db.r5.xlarge */ - R5_XLARGE = 'db.r5.xlarge', + public static readonly R5_XLARGE = InstanceType.of('db.r5.xlarge'); + /** * db.r5.2xlarge */ - R5_2XLARGE = 'db.r5.2xlarge', + public static readonly R5_2XLARGE = InstanceType.of('db.r5.2xlarge'); + /** * db.r5.4xlarge */ - R5_4XLARGE = 'db.r5.4xlarge', + public static readonly R5_4XLARGE = InstanceType.of('db.r5.4xlarge'); + /** * db.r5.8xlarge */ - R5_8XLARGE = 'db.r5.8xlarge', + public static readonly R5_8XLARGE = InstanceType.of('db.r5.8xlarge'); + /** * db.r5.12xlarge */ - R5_12XLARGE = 'db.r5.12xlarge', + public static readonly R5_12XLARGE = InstanceType.of('db.r5.12xlarge'); + /** * db.r5.24xlarge */ - R5_24XLARGE = 'db.r5.24xlarge', + public static readonly R5_24XLARGE = InstanceType.of('db.r5.24xlarge'); + /** * db.r4.large */ - R4_LARGE = 'db.r4.large', + public static readonly R4_LARGE = InstanceType.of('db.r4.large'); + /** * db.r4.xlarge */ - R4_XLARGE = 'db.r4.xlarge', + public static readonly R4_XLARGE = InstanceType.of('db.r4.xlarge'); + /** * db.r4.2xlarge */ - R4_2XLARGE = 'db.r4.2xlarge', + public static readonly R4_2XLARGE = InstanceType.of('db.r4.2xlarge'); + /** * db.r4.4xlarge */ - R4_4XLARGE = 'db.r4.4xlarge', + public static readonly R4_4XLARGE = InstanceType.of('db.r4.4xlarge'); + /** * db.r4.8xlarge */ - R4_8XLARGE = 'db.r4.8xlarge', + public static readonly R4_8XLARGE = InstanceType.of('db.r4.8xlarge'); + /** * db.t3.medium */ - T3_MEDIUM = 'db.t3.medium' + public static readonly T3_MEDIUM = InstanceType.of('db.t3.medium'); + + /** + * Build an InstanceType from given string or token, such as CfnParameter. + */ + public static of(instanceType: string): InstanceType { + return new InstanceType(instanceType); + } + + /** + * @internal + */ + readonly _instanceType: string; + + private constructor(instanceType: string) { + if (cdk.Token.isUnresolved(instanceType) || instanceType.startsWith('db.')) { + this._instanceType = instanceType; + } else { + throw new Error(`instance type must start with 'db.'; (got ${instanceType})`); + } + } } /** @@ -212,7 +245,7 @@ export class DatabaseInstance extends cdk.Resource implements IDatabaseInstance const instance = new CfnDBInstance(this, 'Resource', { dbClusterIdentifier: props.cluster.clusterIdentifier, - dbInstanceClass: props.instanceType, + dbInstanceClass: props.instanceType._instanceType, availabilityZone: props.availabilityZone, dbInstanceIdentifier: props.dbInstanceName, dbParameterGroupName: props.parameterGroup?.parameterGroupName, diff --git a/packages/@aws-cdk/aws-neptune/test/instance.test.ts b/packages/@aws-cdk/aws-neptune/test/instance.test.ts index ff9c92d2a404b..dff005199ffc7 100644 --- a/packages/@aws-cdk/aws-neptune/test/instance.test.ts +++ b/packages/@aws-cdk/aws-neptune/test/instance.test.ts @@ -106,6 +106,40 @@ describe('DatabaseInstance', () => { DBParameterGroupName: { Ref: 'ParamsA8366201' }, })); }); + + test('instance type from CfnParameter', () => { + // GIVEN + const stack = testStack(); + + const instanceType = new cdk.CfnParameter(stack, 'NeptuneInstaneType', { + description: 'Instance type of graph database Neptune', + type: 'String', + allowedValues: [ + 'db.r5.xlarge', + 'db.r5.2xlarge', + 'db.r5.4xlarge', + 'db.r5.8xlarge', + 'db.r5.12xlarge', + ], + default: 'db.r5.8xlarge', + }); + // WHEN + new DatabaseInstance(stack, 'Instance', { + cluster: stack.cluster, + instanceType: InstanceType.of(instanceType.valueAsString), + }); + + // THEN + expectCDK(stack).to(haveResource('AWS::Neptune::DBInstance', { + DBInstanceClass: { + Ref: 'NeptuneInstaneType', + }, + })); + }); + + test('instance type from string throws if missing db prefix', () => { + expect(() => { InstanceType.of('r5.xlarge');}).toThrowError(/instance type must start with 'db.'/); + }); }); class TestStack extends cdk.Stack { @@ -128,4 +162,4 @@ class TestStack extends cdk.Stack { function testStack() { const stack = new TestStack(undefined, undefined, { env: { account: '12345', region: 'us-test-1' } }); return stack; -} \ No newline at end of file +}