diff --git a/packages/@aws-cdk/aws-neptune/README.md b/packages/@aws-cdk/aws-neptune/README.md index bb1c45dbcfd55..36433215ce57e 100644 --- a/packages/@aws-cdk/aws-neptune/README.md +++ b/packages/@aws-cdk/aws-neptune/README.md @@ -121,7 +121,7 @@ const cluster = new neptune.DatabaseCluster(this, 'Database', { }); ``` -Additionally it is also possible to add replicas using `DatabaseInstance` for an existing cluster. +Additionally, it is also possible to add replicas using `DatabaseInstance` for an existing cluster. ```ts fixture=with-cluster const replica1 = new neptune.DatabaseInstance(this, 'Instance', { @@ -143,3 +143,17 @@ new neptune.DatabaseCluster(this, 'Cluster', { autoMinorVersionUpgrade: true, }); ``` + +## Metrics + +Both `DatabaseCluster` and `DatabaseInstance` provide a `metric()` method to help with cluster-level and instance-level monitoring. + +```ts +declare const cluster: neptune.DatabaseCluster; +declare const instance: neptune.DatabaseInstance; + +cluster.metric('SparqlRequestsPerSec'); // cluster-level SparqlErrors metric +instance.metric('SparqlRequestsPerSec') // instance-level SparqlErrors metric +``` + +For more details on the available metrics, refer to https://docs.aws.amazon.com/neptune/latest/userguide/cw-metrics.html diff --git a/packages/@aws-cdk/aws-neptune/lib/cluster.ts b/packages/@aws-cdk/aws-neptune/lib/cluster.ts index f30bf46851f0f..f2e998332c304 100644 --- a/packages/@aws-cdk/aws-neptune/lib/cluster.ts +++ b/packages/@aws-cdk/aws-neptune/lib/cluster.ts @@ -1,3 +1,4 @@ +import * as cloudwatch from '@aws-cdk/aws-cloudwatch'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as iam from '@aws-cdk/aws-iam'; import * as kms from '@aws-cdk/aws-kms'; @@ -284,6 +285,14 @@ export interface IDatabaseCluster extends IResource, ec2.IConnectable { * Grant the given identity connection access to the database. */ grantConnect(grantee: iam.IGrantable): iam.Grant; + + /** + * Return the given named metric associated with this DatabaseCluster instance + * + * @see https://docs.aws.amazon.com/neptune/latest/userguide/cw-metrics.html + * @see https://docs.aws.amazon.com/neptune/latest/userguide/cw-dimensions.html + */ + metric(metricName: string, props?: cloudwatch.MetricOptions): cloudwatch.Metric; } /** @@ -398,6 +407,17 @@ export abstract class DatabaseClusterBase extends Resource implements IDatabaseC public grantConnect(grantee: iam.IGrantable): iam.Grant { return this.grant(grantee, 'neptune-db:*'); } + + public metric(metricName: string, props?: cloudwatch.MetricOptions): cloudwatch.Metric { + return new cloudwatch.Metric({ + namespace: 'AWS/Neptune', + dimensionsMap: { + DBClusterIdentifier: this.clusterIdentifier, + }, + metricName, + ...props, + }); + } } /** diff --git a/packages/@aws-cdk/aws-neptune/lib/instance.ts b/packages/@aws-cdk/aws-neptune/lib/instance.ts index b05003dffcb40..336606c6b9386 100644 --- a/packages/@aws-cdk/aws-neptune/lib/instance.ts +++ b/packages/@aws-cdk/aws-neptune/lib/instance.ts @@ -1,3 +1,4 @@ +import * as cloudwatch from '@aws-cdk/aws-cloudwatch'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as cdk from '@aws-cdk/core'; import { Construct } from 'constructs'; @@ -165,6 +166,14 @@ export interface IDatabaseInstance extends cdk.IResource { * @attribute Port */ readonly dbInstanceEndpointPort: string; + + /** + * Return the given named metric associated with this database instance + * + * @see https://docs.aws.amazon.com/neptune/latest/userguide/cw-metrics.html + * @see https://docs.aws.amazon.com/neptune/latest/userguide/cw-dimensions.html + */ + metric(metricName: string, props?: cloudwatch.MetricOptions): cloudwatch.Metric; } /** @@ -233,27 +242,64 @@ export interface DatabaseInstanceProps { } /** - * A database instance - * - * @resource AWS::Neptune::DBInstance + * A new or imported database instance. */ -export class DatabaseInstance extends cdk.Resource implements IDatabaseInstance { - +export abstract class DatabaseInstanceBase extends cdk.Resource implements IDatabaseInstance { /** * Import an existing database instance. */ public static fromDatabaseInstanceAttributes(scope: Construct, id: string, attrs: DatabaseInstanceAttributes): IDatabaseInstance { - class Import extends cdk.Resource implements IDatabaseInstance { + class Import extends DatabaseInstanceBase implements IDatabaseInstance { public readonly defaultPort = ec2.Port.tcp(attrs.port); public readonly instanceIdentifier = attrs.instanceIdentifier; public readonly dbInstanceEndpointAddress = attrs.instanceEndpointAddress; public readonly dbInstanceEndpointPort = attrs.port.toString(); public readonly instanceEndpoint = new Endpoint(attrs.instanceEndpointAddress, attrs.port); } - return new Import(scope, id); } + /** + * @inheritdoc + */ + public abstract readonly dbInstanceEndpointAddress: string; + + /** + * @inheritdoc + */ + public abstract readonly dbInstanceEndpointPort: string; + + /** + * @inheritdoc + */ + public abstract readonly instanceEndpoint: Endpoint; + + /** + * @inheritdoc + */ + public abstract readonly instanceIdentifier: string; + + /** + * @inheritdoc + */ + public metric(metricName: string, props?: cloudwatch.MetricOptions): cloudwatch.Metric { + return new cloudwatch.Metric({ + namespace: 'AWS/Neptune', + dimensionsMap: { + DBInstanceIdentifier: this.instanceIdentifier, + }, + metricName, + ...props, + }); + } +} + +/** + * A database instance + * + * @resource AWS::Neptune::DBInstance + */ +export class DatabaseInstance extends DatabaseInstanceBase implements IDatabaseInstance { /** * The instance's database cluster diff --git a/packages/@aws-cdk/aws-neptune/package.json b/packages/@aws-cdk/aws-neptune/package.json index f1fc53edc893c..6b38c7760a3bf 100644 --- a/packages/@aws-cdk/aws-neptune/package.json +++ b/packages/@aws-cdk/aws-neptune/package.json @@ -90,6 +90,7 @@ "@types/jest": "^27.5.2" }, "dependencies": { + "@aws-cdk/aws-cloudwatch": "0.0.0", "@aws-cdk/aws-ec2": "0.0.0", "@aws-cdk/aws-iam": "0.0.0", "@aws-cdk/aws-kms": "0.0.0", @@ -97,6 +98,7 @@ "constructs": "^10.0.0" }, "peerDependencies": { + "@aws-cdk/aws-cloudwatch": "0.0.0", "@aws-cdk/aws-ec2": "0.0.0", "@aws-cdk/aws-iam": "0.0.0", "@aws-cdk/aws-kms": "0.0.0", diff --git a/packages/@aws-cdk/aws-neptune/test/cluster.integ.snapshot/ClusterTestDefaultTestDeployAssert6A1BBA9D.assets.json b/packages/@aws-cdk/aws-neptune/test/cluster.integ.snapshot/ClusterTestDefaultTestDeployAssert6A1BBA9D.assets.json new file mode 100644 index 0000000000000..fed1d52c49ba8 --- /dev/null +++ b/packages/@aws-cdk/aws-neptune/test/cluster.integ.snapshot/ClusterTestDefaultTestDeployAssert6A1BBA9D.assets.json @@ -0,0 +1,19 @@ +{ + "version": "21.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "ClusterTestDefaultTestDeployAssert6A1BBA9D.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-neptune/test/cluster.integ.snapshot/ClusterTestDefaultTestDeployAssert6A1BBA9D.template.json b/packages/@aws-cdk/aws-neptune/test/cluster.integ.snapshot/ClusterTestDefaultTestDeployAssert6A1BBA9D.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk/aws-neptune/test/cluster.integ.snapshot/ClusterTestDefaultTestDeployAssert6A1BBA9D.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-neptune/test/cluster.integ.snapshot/aws-cdk-neptune-integ.assets.json b/packages/@aws-cdk/aws-neptune/test/cluster.integ.snapshot/aws-cdk-neptune-integ.assets.json index 406c273a3a088..8bbc76301c8f1 100644 --- a/packages/@aws-cdk/aws-neptune/test/cluster.integ.snapshot/aws-cdk-neptune-integ.assets.json +++ b/packages/@aws-cdk/aws-neptune/test/cluster.integ.snapshot/aws-cdk-neptune-integ.assets.json @@ -1,7 +1,7 @@ { "version": "21.0.0", "files": { - "315715ffe6004c7bd7c9874629785c10fd8f65a20d6995ea8eb20188dfb82b7d": { + "c3aa283b33e47bc3d0cb943f014017d1742247b6577982270570cb6cbf5a778c": { "source": { "path": "aws-cdk-neptune-integ.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "315715ffe6004c7bd7c9874629785c10fd8f65a20d6995ea8eb20188dfb82b7d.json", + "objectKey": "c3aa283b33e47bc3d0cb943f014017d1742247b6577982270570cb6cbf5a778c.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk/aws-neptune/test/cluster.integ.snapshot/aws-cdk-neptune-integ.template.json b/packages/@aws-cdk/aws-neptune/test/cluster.integ.snapshot/aws-cdk-neptune-integ.template.json index 67f5870712c2a..15290913fcbd9 100644 --- a/packages/@aws-cdk/aws-neptune/test/cluster.integ.snapshot/aws-cdk-neptune-integ.template.json +++ b/packages/@aws-cdk/aws-neptune/test/cluster.integ.snapshot/aws-cdk-neptune-integ.template.json @@ -538,6 +538,26 @@ ], "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" + }, + "Alarm7103F465": { + "Type": "AWS::CloudWatch::Alarm", + "Properties": { + "ComparisonOperator": "LessThanThreshold", + "EvaluationPeriods": 1, + "Dimensions": [ + { + "Name": "DBClusterIdentifier", + "Value": { + "Ref": "DatabaseB269D8BB" + } + } + ], + "MetricName": "SparqlRequestsPerSec", + "Namespace": "AWS/Neptune", + "Period": 300, + "Statistic": "Average", + "Threshold": 1 + } } }, "Parameters": { diff --git a/packages/@aws-cdk/aws-neptune/test/cluster.integ.snapshot/integ.json b/packages/@aws-cdk/aws-neptune/test/cluster.integ.snapshot/integ.json index 7f298dac51aa6..e2061d5ea4e11 100644 --- a/packages/@aws-cdk/aws-neptune/test/cluster.integ.snapshot/integ.json +++ b/packages/@aws-cdk/aws-neptune/test/cluster.integ.snapshot/integ.json @@ -1,14 +1,12 @@ { "version": "21.0.0", "testCases": { - "integ.cluster": { + "ClusterTest/DefaultTest": { "stacks": [ "aws-cdk-neptune-integ" ], - "diffAssets": false, - "stackUpdateWorkflow": true + "assertionStack": "ClusterTest/DefaultTest/DeployAssert", + "assertionStackName": "ClusterTestDefaultTestDeployAssert6A1BBA9D" } - }, - "synthContext": {}, - "enableLookups": false + } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-neptune/test/cluster.integ.snapshot/manifest.json b/packages/@aws-cdk/aws-neptune/test/cluster.integ.snapshot/manifest.json index c9e9d7159e499..add010df1aabf 100644 --- a/packages/@aws-cdk/aws-neptune/test/cluster.integ.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-neptune/test/cluster.integ.snapshot/manifest.json @@ -23,7 +23,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/315715ffe6004c7bd7c9874629785c10fd8f65a20d6995ea8eb20188dfb82b7d.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/c3aa283b33e47bc3d0cb943f014017d1742247b6577982270570cb6cbf5a778c.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -219,74 +219,73 @@ "data": "DatabaseInstance1844F58FD" } ], - "/aws-cdk-neptune-integ/BootstrapVersion": [ - { - "type": "aws:cdk:logicalId", - "data": "BootstrapVersion" - } - ], - "/aws-cdk-neptune-integ/CheckBootstrapVersion": [ - { - "type": "aws:cdk:logicalId", - "data": "CheckBootstrapVersion" - } - ], - "Params1200F93288": [ - { - "type": "aws:cdk:logicalId", - "data": "Params1200F93288", - "trace": [ - "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" - ] - } - ], - "Database12Subnets4179194B": [ + "/aws-cdk-neptune-integ/Alarm/Resource": [ { "type": "aws:cdk:logicalId", - "data": "Database12Subnets4179194B", - "trace": [ - "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" - ] + "data": "Alarm7103F465" } ], - "Database12SecurityGroup4F4302E8": [ + "/aws-cdk-neptune-integ/BootstrapVersion": [ { "type": "aws:cdk:logicalId", - "data": "Database12SecurityGroup4F4302E8", - "trace": [ - "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" - ] + "data": "BootstrapVersion" } ], - "Database12SecurityGroupfrom00000IndirectPort3A40EE2B": [ + "/aws-cdk-neptune-integ/CheckBootstrapVersion": [ { "type": "aws:cdk:logicalId", - "data": "Database12SecurityGroupfrom00000IndirectPort3A40EE2B", - "trace": [ - "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" - ] + "data": "CheckBootstrapVersion" } + ] + }, + "displayName": "aws-cdk-neptune-integ" + }, + "ClusterTestDefaultTestDeployAssert6A1BBA9D.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "ClusterTestDefaultTestDeployAssert6A1BBA9D.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "ClusterTestDefaultTestDeployAssert6A1BBA9D": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "ClusterTestDefaultTestDeployAssert6A1BBA9D.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "ClusterTestDefaultTestDeployAssert6A1BBA9D.assets" ], - "Database12D6A36FB9": [ + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "ClusterTestDefaultTestDeployAssert6A1BBA9D.assets" + ], + "metadata": { + "/ClusterTest/DefaultTest/DeployAssert/BootstrapVersion": [ { "type": "aws:cdk:logicalId", - "data": "Database12D6A36FB9", - "trace": [ - "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" - ] + "data": "BootstrapVersion" } ], - "Database12Instance10D9E6224": [ + "/ClusterTest/DefaultTest/DeployAssert/CheckBootstrapVersion": [ { "type": "aws:cdk:logicalId", - "data": "Database12Instance10D9E6224", - "trace": [ - "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" - ] + "data": "CheckBootstrapVersion" } ] }, - "displayName": "aws-cdk-neptune-integ" + "displayName": "ClusterTest/DefaultTest/DeployAssert" } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-neptune/test/cluster.integ.snapshot/tree.json b/packages/@aws-cdk/aws-neptune/test/cluster.integ.snapshot/tree.json index 0d2da0fe35492..1ca55bc53da8a 100644 --- a/packages/@aws-cdk/aws-neptune/test/cluster.integ.snapshot/tree.json +++ b/packages/@aws-cdk/aws-neptune/test/cluster.integ.snapshot/tree.json @@ -900,12 +900,86 @@ "fqn": "@aws-cdk/aws-neptune.DatabaseCluster", "version": "0.0.0" } + }, + "Alarm": { + "id": "Alarm", + "path": "aws-cdk-neptune-integ/Alarm", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-neptune-integ/Alarm/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::CloudWatch::Alarm", + "aws:cdk:cloudformation:props": { + "comparisonOperator": "GreaterThanThreshold", + "evaluationPeriods": 1, + "dimensions": [ + { + "name": "DBClusterIdentifier", + "value": { + "Ref": "DatabaseB269D8BB" + } + } + ], + "metricName": "SparqlErrors", + "namespace": "AWS/Neptune", + "period": 300, + "statistic": "Sum", + "threshold": 0 + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-cloudwatch.CfnAlarm", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-cloudwatch.Alarm", + "version": "0.0.0" + } } }, "constructInfo": { "fqn": "@aws-cdk/core.Stack", "version": "0.0.0" } + }, + "ClusterTest": { + "id": "ClusterTest", + "path": "ClusterTest", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "ClusterTest/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "ClusterTest/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.92" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "ClusterTest/DefaultTest/DeployAssert", + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.IntegTest", + "version": "0.0.0" + } } }, "constructInfo": { diff --git a/packages/@aws-cdk/aws-neptune/test/cluster.test.ts b/packages/@aws-cdk/aws-neptune/test/cluster.test.ts index e92386cfefcb0..b0b2873572eb8 100644 --- a/packages/@aws-cdk/aws-neptune/test/cluster.test.ts +++ b/packages/@aws-cdk/aws-neptune/test/cluster.test.ts @@ -1,4 +1,5 @@ import { Match, Template } from '@aws-cdk/assertions'; +import * as cloudwatch from '@aws-cdk/aws-cloudwatch'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as iam from '@aws-cdk/aws-iam'; import * as kms from '@aws-cdk/aws-kms'; @@ -660,6 +661,46 @@ describe('DatabaseCluster', () => { }); + test('metric - constructs metric with correct namespace and dimension and inputs', () => { + // GIVEN + const stack = testStack(); + const vpc = new ec2.Vpc(stack, 'VPC'); + const cluster = new DatabaseCluster(stack, 'Cluster', { + vpc, + instanceType: InstanceType.R5_LARGE, + }); + + // WHEN + const metric = cluster.metric('SparqlRequestsPerSec'); + new cloudwatch.Alarm(stack, 'Alarm', { + evaluationPeriods: 1, + threshold: 1, + comparisonOperator: cloudwatch.ComparisonOperator.LESS_THAN_THRESHOLD, + metric: metric, + }); + + // THEN + expect(metric).toEqual(new cloudwatch.Metric({ + namespace: 'AWS/Neptune', + dimensionsMap: { + DBClusterIdentifier: cluster.clusterIdentifier, + }, + metricName: 'SparqlRequestsPerSec', + })); + Template.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Alarm', { + Namespace: 'AWS/Neptune', + MetricName: 'SparqlRequestsPerSec', + Dimensions: [ + { + Name: 'DBClusterIdentifier', + Value: stack.resolve(cluster.clusterIdentifier), + }, + ], + ComparisonOperator: 'LessThanThreshold', + EvaluationPeriods: 1, + Threshold: 1, + }); + }); }); function testStack() { diff --git a/packages/@aws-cdk/aws-neptune/test/instance.test.ts b/packages/@aws-cdk/aws-neptune/test/instance.test.ts index ed83e1506496a..95e6e27d3f4ed 100644 --- a/packages/@aws-cdk/aws-neptune/test/instance.test.ts +++ b/packages/@aws-cdk/aws-neptune/test/instance.test.ts @@ -1,4 +1,5 @@ import { Template } from '@aws-cdk/assertions'; +import * as cloudwatch from '@aws-cdk/aws-cloudwatch'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as cdk from '@aws-cdk/core'; import * as constructs from 'constructs'; @@ -140,6 +141,46 @@ describe('DatabaseInstance', () => { test('instance type from string throws if missing db prefix', () => { expect(() => { InstanceType.of('r5.xlarge');}).toThrowError(/instance type must start with 'db.'/); }); + + test('metric - constructs metric with correct namespace and dimension and inputs', () => { + // GIVEN + const stack = testStack(); + const instance = new DatabaseInstance(stack, 'Instance', { + cluster: stack.cluster, + instanceType: InstanceType.R5_LARGE, + }); + + // WHEN + const metric = instance.metric('SparqlRequestsPerSec'); + new cloudwatch.Alarm(stack, 'Alarm', { + evaluationPeriods: 1, + threshold: 1, + comparisonOperator: cloudwatch.ComparisonOperator.LESS_THAN_THRESHOLD, + metric: metric, + }); + + // THEN + expect(metric).toEqual(new cloudwatch.Metric({ + namespace: 'AWS/Neptune', + dimensionsMap: { + DBInstanceIdentifier: instance.instanceIdentifier, + }, + metricName: 'SparqlRequestsPerSec', + })); + Template.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Alarm', { + Namespace: 'AWS/Neptune', + MetricName: 'SparqlRequestsPerSec', + Dimensions: [ + { + Name: 'DBInstanceIdentifier', + Value: stack.resolve(instance.instanceIdentifier), + }, + ], + ComparisonOperator: 'LessThanThreshold', + EvaluationPeriods: 1, + Threshold: 1, + }); + }); }); class TestStack extends cdk.Stack { @@ -160,6 +201,5 @@ class TestStack extends cdk.Stack { } function testStack() { - const stack = new TestStack(undefined, undefined, { env: { account: '12345', region: 'us-test-1' } }); - return stack; + return new TestStack(undefined, undefined, { env: { account: '12345', region: 'us-test-1' } }); } diff --git a/packages/@aws-cdk/aws-neptune/test/integ.cluster.ts b/packages/@aws-cdk/aws-neptune/test/integ.cluster.ts index 0d7014c049b3a..1b8d4156ef6f5 100644 --- a/packages/@aws-cdk/aws-neptune/test/integ.cluster.ts +++ b/packages/@aws-cdk/aws-neptune/test/integ.cluster.ts @@ -1,3 +1,4 @@ +import * as cloudwatch from '@aws-cdk/aws-cloudwatch'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as kms from '@aws-cdk/aws-kms'; import * as cdk from '@aws-cdk/core'; @@ -43,6 +44,14 @@ const cluster = new DatabaseCluster(stack, 'Database', { cluster.connections.allowDefaultPortFromAnyIpv4('Open to the world'); +const metric = cluster.metric('SparqlRequestsPerSec'); +new cloudwatch.Alarm(stack, 'Alarm', { + evaluationPeriods: 1, + threshold: 1, + comparisonOperator: cloudwatch.ComparisonOperator.LESS_THAN_THRESHOLD, + metric: metric, +}); + new integ.IntegTest(app, 'ClusterTest', { testCases: [stack], });