From e64032f99e0bb77b97893b79b66b081652d22d57 Mon Sep 17 00:00:00 2001 From: Eugene Cheung Date: Thu, 12 Sep 2024 15:55:34 -0400 Subject: [PATCH] fix(api-gatewayv2): use API name in fallback name when possible Avoids potentially referring to an API ID that ends up being a token. --- .../ApiGatewayV2HttpApiMonitoring.ts | 7 +- .../MonitoringAspect.test.ts.snap | 12 +- .../ApiGatewayV2HttpApiMonitoring.test.ts | 36 ++- ...ApiGatewayV2HttpApiMonitoring.test.ts.snap | 305 +++++++++++++++++- 4 files changed, 340 insertions(+), 20 deletions(-) diff --git a/lib/monitoring/aws-apigatewayv2/ApiGatewayV2HttpApiMonitoring.ts b/lib/monitoring/aws-apigatewayv2/ApiGatewayV2HttpApiMonitoring.ts index 3d6fc03f..26d4c20c 100644 --- a/lib/monitoring/aws-apigatewayv2/ApiGatewayV2HttpApiMonitoring.ts +++ b/lib/monitoring/aws-apigatewayv2/ApiGatewayV2HttpApiMonitoring.ts @@ -1,3 +1,4 @@ +import { HttpApi } from "aws-cdk-lib/aws-apigatewayv2"; import { GraphWidget, HorizontalAnnotation, @@ -158,7 +159,11 @@ export class ApiGatewayV2HttpApiMonitoring extends Monitoring { super(scope, props); // used when humanReadableName is not provided by user - const fallbackNameArray = [props.api.apiId]; + const fallbackNameArray = [ + (props.api as HttpApi)?.httpApiName ?? + (props.api as HttpApi)?.httpApiId ?? + props.api.apiId, + ]; fallbackNameArray.push(props.apiStage ?? "$default"); if (props.apiMethod) { fallbackNameArray.push(props.apiMethod); diff --git a/test/facade/__snapshots__/MonitoringAspect.test.ts.snap b/test/facade/__snapshots__/MonitoringAspect.test.ts.snap index 526dbbc0..9a5c0976 100644 --- a/test/facade/__snapshots__/MonitoringAspect.test.ts.snap +++ b/test/facade/__snapshots__/MonitoringAspect.test.ts.snap @@ -457,11 +457,7 @@ Object { "Fn::Join": Array [ "", Array [ - "{\\"start\\":\\"-PT8H\\",\\"periodOverride\\":\\"inherit\\",\\"widgets\\":[{\\"type\\":\\"text\\",\\"width\\":24,\\"height\\":1,\\"x\\":0,\\"y\\":0,\\"properties\\":{\\"markdown\\":\\"### API Gateway V2 HTTP Endpoint **", - Object { - "Ref": "DummyHttpApi8EEBCC85", - }, - " $default**\\"}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":0,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"TPS\\",\\"region\\":\\"", + "{\\"start\\":\\"-PT8H\\",\\"periodOverride\\":\\"inherit\\",\\"widgets\\":[{\\"type\\":\\"text\\",\\"width\\":24,\\"height\\":1,\\"x\\":0,\\"y\\":0,\\"properties\\":{\\"markdown\\":\\"### API Gateway V2 HTTP Endpoint **DummyHttpApi $default**\\"}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":0,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"TPS\\",\\"region\\":\\"", Object { "Ref": "AWS::Region", }, @@ -535,11 +531,7 @@ Object { "Fn::Join": Array [ "", Array [ - "{\\"start\\":\\"-P14D\\",\\"periodOverride\\":\\"inherit\\",\\"widgets\\":[{\\"type\\":\\"text\\",\\"width\\":24,\\"height\\":1,\\"x\\":0,\\"y\\":0,\\"properties\\":{\\"markdown\\":\\"### API Gateway V2 HTTP Endpoint **", - Object { - "Ref": "DummyHttpApi8EEBCC85", - }, - " $default**\\"}},{\\"type\\":\\"metric\\",\\"width\\":8,\\"height\\":6,\\"x\\":0,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"TPS\\",\\"region\\":\\"", + "{\\"start\\":\\"-P14D\\",\\"periodOverride\\":\\"inherit\\",\\"widgets\\":[{\\"type\\":\\"text\\",\\"width\\":24,\\"height\\":1,\\"x\\":0,\\"y\\":0,\\"properties\\":{\\"markdown\\":\\"### API Gateway V2 HTTP Endpoint **DummyHttpApi $default**\\"}},{\\"type\\":\\"metric\\",\\"width\\":8,\\"height\\":6,\\"x\\":0,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"TPS\\",\\"region\\":\\"", Object { "Ref": "AWS::Region", }, diff --git a/test/monitoring/aws-apigatewayv2/ApiGatewayV2HttpApiMonitoring.test.ts b/test/monitoring/aws-apigatewayv2/ApiGatewayV2HttpApiMonitoring.test.ts index ae251ddf..f9db4c27 100644 --- a/test/monitoring/aws-apigatewayv2/ApiGatewayV2HttpApiMonitoring.test.ts +++ b/test/monitoring/aws-apigatewayv2/ApiGatewayV2HttpApiMonitoring.test.ts @@ -9,19 +9,43 @@ import { import { addMonitoringDashboardsToStack } from "../../utils/SnapshotUtil"; import { TestMonitoringScope } from "../TestMonitoringScope"; -test("snapshot test: no alarms", () => { +test("snapshot test: no alarms with explicit API name", () => { const stack = new Stack(); const scope = new TestMonitoringScope(stack, "Scope"); - const testHttpApi = new HttpApi(stack, "testHttpApi", { - apiName: "testHttpApi", + const monitoring = new ApiGatewayV2HttpApiMonitoring(scope, { + api: new HttpApi(stack, "testHttpApi", { + apiName: "testHttpApiName", + }), }); + addMonitoringDashboardsToStack(stack, monitoring); + expect(Template.fromStack(stack)).toMatchSnapshot(); +}); + +test("snapshot test: no alarms with no explicit API name", () => { + const stack = new Stack(); + + const scope = new TestMonitoringScope(stack, "Scope"); + const monitoring = new ApiGatewayV2HttpApiMonitoring(scope, { - api: testHttpApi, - humanReadableName: "Dummy API Gateway for testing", - alarmFriendlyName: "DummyApi", + api: new HttpApi(stack, "testHttpApi"), + }); + + addMonitoringDashboardsToStack(stack, monitoring); + expect(Template.fromStack(stack)).toMatchSnapshot(); +}); + +test("snapshot test: no alarms with imported IHttpApi", () => { + const stack = new Stack(); + + const scope = new TestMonitoringScope(stack, "Scope"); + + const monitoring = new ApiGatewayV2HttpApiMonitoring(scope, { + api: HttpApi.fromHttpApiAttributes(scope, "Imported", { + httpApiId: "imported-id", + }), }); addMonitoringDashboardsToStack(stack, monitoring); diff --git a/test/monitoring/aws-apigatewayv2/__snapshots__/ApiGatewayV2HttpApiMonitoring.test.ts.snap b/test/monitoring/aws-apigatewayv2/__snapshots__/ApiGatewayV2HttpApiMonitoring.test.ts.snap index b66e0c57..34163986 100644 --- a/test/monitoring/aws-apigatewayv2/__snapshots__/ApiGatewayV2HttpApiMonitoring.test.ts.snap +++ b/test/monitoring/aws-apigatewayv2/__snapshots__/ApiGatewayV2HttpApiMonitoring.test.ts.snap @@ -2833,7 +2833,7 @@ Object { } `; -exports[`snapshot test: no alarms 1`] = ` +exports[`snapshot test: no alarms with explicit API name 1`] = ` Object { "Parameters": Object { "BootstrapVersion": Object { @@ -2855,7 +2855,7 @@ Object { "Fn::Join": Array [ "", Array [ - "{\\"widgets\\":[{\\"type\\":\\"text\\",\\"width\\":24,\\"height\\":1,\\"x\\":0,\\"y\\":0,\\"properties\\":{\\"markdown\\":\\"### API Gateway V2 HTTP Endpoint **Dummy API Gateway for testing**\\"}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":0,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"TPS\\",\\"region\\":\\"", + "{\\"widgets\\":[{\\"type\\":\\"text\\",\\"width\\":24,\\"height\\":1,\\"x\\":0,\\"y\\":0,\\"properties\\":{\\"markdown\\":\\"### API Gateway V2 HTTP Endpoint **testHttpApiName $default**\\"}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":0,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"TPS\\",\\"region\\":\\"", Object { "Ref": "AWS::Region", }, @@ -2928,7 +2928,306 @@ Object { "Fn::Join": Array [ "", Array [ - "{\\"widgets\\":[{\\"type\\":\\"text\\",\\"width\\":24,\\"height\\":1,\\"x\\":0,\\"y\\":0,\\"properties\\":{\\"markdown\\":\\"### API Gateway V2 HTTP Endpoint **Dummy API Gateway for testing**\\"}},{\\"type\\":\\"metric\\",\\"width\\":8,\\"height\\":6,\\"x\\":0,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"TPS\\",\\"region\\":\\"", + "{\\"widgets\\":[{\\"type\\":\\"text\\",\\"width\\":24,\\"height\\":1,\\"x\\":0,\\"y\\":0,\\"properties\\":{\\"markdown\\":\\"### API Gateway V2 HTTP Endpoint **testHttpApiName $default**\\"}},{\\"type\\":\\"metric\\",\\"width\\":8,\\"height\\":6,\\"x\\":0,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"TPS\\",\\"region\\":\\"", + Object { + "Ref": "AWS::Region", + }, + "\\",\\"metrics\\":[[{\\"label\\":\\"TPS\\",\\"expression\\":\\"requests / PERIOD(requests)\\"}],[\\"AWS/ApiGateway\\",\\"Count\\",\\"ApiId\\",\\"", + Object { + "Ref": "testHttpApiC57B300F", + }, + "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"Invocations\\",\\"stat\\":\\"Sum\\",\\"visible\\":false,\\"id\\":\\"requests\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"Rate\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":8,\\"height\\":6,\\"x\\":8,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Latency\\",\\"region\\":\\"", + Object { + "Ref": "AWS::Region", + }, + "\\",\\"metrics\\":[[\\"AWS/ApiGateway\\",\\"Latency\\",\\"ApiId\\",\\"", + Object { + "Ref": "testHttpApiC57B300F", + }, + "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P50 (avg: \${AVG})\\",\\"stat\\":\\"p50\\"}],[\\"AWS/ApiGateway\\",\\"IntegrationLatency\\",\\"ApiId\\",\\"", + Object { + "Ref": "testHttpApiC57B300F", + }, + "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P50 (avg: \${AVG})\\",\\"stat\\":\\"p50\\"}],[\\"AWS/ApiGateway\\",\\"Latency\\",\\"ApiId\\",\\"", + Object { + "Ref": "testHttpApiC57B300F", + }, + "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P90 (avg: \${AVG})\\",\\"stat\\":\\"p90\\"}],[\\"AWS/ApiGateway\\",\\"IntegrationLatency\\",\\"ApiId\\",\\"", + Object { + "Ref": "testHttpApiC57B300F", + }, + "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P90 (avg: \${AVG})\\",\\"stat\\":\\"p90\\"}],[\\"AWS/ApiGateway\\",\\"Latency\\",\\"ApiId\\",\\"", + Object { + "Ref": "testHttpApiC57B300F", + }, + "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P99 (avg: \${AVG})\\",\\"stat\\":\\"p99\\"}],[\\"AWS/ApiGateway\\",\\"IntegrationLatency\\",\\"ApiId\\",\\"", + Object { + "Ref": "testHttpApiC57B300F", + }, + "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P99 (avg: \${AVG})\\",\\"stat\\":\\"p99\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"ms\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":8,\\"height\\":6,\\"x\\":16,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Errors (rate)\\",\\"region\\":\\"", + Object { + "Ref": "AWS::Region", + }, + "\\",\\"metrics\\":[[\\"AWS/ApiGateway\\",\\"4xx\\",\\"ApiId\\",\\"", + Object { + "Ref": "testHttpApiC57B300F", + }, + "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"4xx (avg)\\"}],[\\"AWS/ApiGateway\\",\\"5xx\\",\\"ApiId\\",\\"", + Object { + "Ref": "testHttpApiC57B300F", + }, + "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"5xx (avg)\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"Rate\\",\\"showUnits\\":false}}}}]}", + ], + ], + }, + }, + "Type": "AWS::CloudWatch::Dashboard", + }, + "testHttpApiC57B300F": Object { + "Properties": Object { + "Name": "testHttpApiName", + "ProtocolType": "HTTP", + }, + "Type": "AWS::ApiGatewayV2::Api", + }, + "testHttpApiDefaultStageBA851B68": Object { + "Properties": Object { + "ApiId": Object { + "Ref": "testHttpApiC57B300F", + }, + "AutoDeploy": true, + "StageName": "$default", + }, + "Type": "AWS::ApiGatewayV2::Stage", + }, + }, + "Rules": Object { + "CheckBootstrapVersion": Object { + "Assertions": Array [ + Object { + "Assert": Object { + "Fn::Not": Array [ + Object { + "Fn::Contains": Array [ + Array [ + "1", + "2", + "3", + "4", + "5", + ], + Object { + "Ref": "BootstrapVersion", + }, + ], + }, + ], + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI.", + }, + ], + }, + }, +} +`; + +exports[`snapshot test: no alarms with imported IHttpApi 1`] = ` +Object { + "Parameters": Object { + "BootstrapVersion": Object { + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]", + "Type": "AWS::SSM::Parameter::Value", + }, + }, + "Resources": Object { + "Alarm7103F465": Object { + "Properties": Object { + "DashboardBody": "{\\"widgets\\":[]}", + }, + "Type": "AWS::CloudWatch::Dashboard", + }, + "Resource": Object { + "Properties": Object { + "DashboardBody": Object { + "Fn::Join": Array [ + "", + Array [ + "{\\"widgets\\":[{\\"type\\":\\"text\\",\\"width\\":24,\\"height\\":1,\\"x\\":0,\\"y\\":0,\\"properties\\":{\\"markdown\\":\\"### API Gateway V2 HTTP Endpoint **imported-id $default**\\"}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":0,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"TPS\\",\\"region\\":\\"", + Object { + "Ref": "AWS::Region", + }, + "\\",\\"metrics\\":[[{\\"label\\":\\"TPS\\",\\"expression\\":\\"requests / PERIOD(requests)\\"}],[\\"AWS/ApiGateway\\",\\"Count\\",\\"ApiId\\",\\"imported-id\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"Invocations\\",\\"stat\\":\\"Sum\\",\\"visible\\":false,\\"id\\":\\"requests\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"Rate\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":6,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Latency\\",\\"region\\":\\"", + Object { + "Ref": "AWS::Region", + }, + "\\",\\"metrics\\":[[\\"AWS/ApiGateway\\",\\"Latency\\",\\"ApiId\\",\\"imported-id\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P50 (avg: \${AVG})\\",\\"stat\\":\\"p50\\"}],[\\"AWS/ApiGateway\\",\\"IntegrationLatency\\",\\"ApiId\\",\\"imported-id\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P50 (avg: \${AVG})\\",\\"stat\\":\\"p50\\"}],[\\"AWS/ApiGateway\\",\\"Latency\\",\\"ApiId\\",\\"imported-id\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P90 (avg: \${AVG})\\",\\"stat\\":\\"p90\\"}],[\\"AWS/ApiGateway\\",\\"IntegrationLatency\\",\\"ApiId\\",\\"imported-id\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P90 (avg: \${AVG})\\",\\"stat\\":\\"p90\\"}],[\\"AWS/ApiGateway\\",\\"Latency\\",\\"ApiId\\",\\"imported-id\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P99 (avg: \${AVG})\\",\\"stat\\":\\"p99\\"}],[\\"AWS/ApiGateway\\",\\"IntegrationLatency\\",\\"ApiId\\",\\"imported-id\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P99 (avg: \${AVG})\\",\\"stat\\":\\"p99\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"ms\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":12,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Errors\\",\\"region\\":\\"", + Object { + "Ref": "AWS::Region", + }, + "\\",\\"metrics\\":[[\\"AWS/ApiGateway\\",\\"4xx\\",\\"ApiId\\",\\"imported-id\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"4xx\\",\\"stat\\":\\"Sum\\"}],[\\"AWS/ApiGateway\\",\\"5xx\\",\\"ApiId\\",\\"imported-id\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"5xx\\",\\"stat\\":\\"Sum\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"Count\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":18,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Errors (rate)\\",\\"region\\":\\"", + Object { + "Ref": "AWS::Region", + }, + "\\",\\"metrics\\":[[\\"AWS/ApiGateway\\",\\"4xx\\",\\"ApiId\\",\\"imported-id\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"4xx (avg)\\"}],[\\"AWS/ApiGateway\\",\\"5xx\\",\\"ApiId\\",\\"imported-id\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"5xx (avg)\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"Rate\\",\\"showUnits\\":false}}}}]}", + ], + ], + }, + }, + "Type": "AWS::CloudWatch::Dashboard", + }, + "Summary68521F81": Object { + "Properties": Object { + "DashboardBody": Object { + "Fn::Join": Array [ + "", + Array [ + "{\\"widgets\\":[{\\"type\\":\\"text\\",\\"width\\":24,\\"height\\":1,\\"x\\":0,\\"y\\":0,\\"properties\\":{\\"markdown\\":\\"### API Gateway V2 HTTP Endpoint **imported-id $default**\\"}},{\\"type\\":\\"metric\\",\\"width\\":8,\\"height\\":6,\\"x\\":0,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"TPS\\",\\"region\\":\\"", + Object { + "Ref": "AWS::Region", + }, + "\\",\\"metrics\\":[[{\\"label\\":\\"TPS\\",\\"expression\\":\\"requests / PERIOD(requests)\\"}],[\\"AWS/ApiGateway\\",\\"Count\\",\\"ApiId\\",\\"imported-id\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"Invocations\\",\\"stat\\":\\"Sum\\",\\"visible\\":false,\\"id\\":\\"requests\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"Rate\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":8,\\"height\\":6,\\"x\\":8,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Latency\\",\\"region\\":\\"", + Object { + "Ref": "AWS::Region", + }, + "\\",\\"metrics\\":[[\\"AWS/ApiGateway\\",\\"Latency\\",\\"ApiId\\",\\"imported-id\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P50 (avg: \${AVG})\\",\\"stat\\":\\"p50\\"}],[\\"AWS/ApiGateway\\",\\"IntegrationLatency\\",\\"ApiId\\",\\"imported-id\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P50 (avg: \${AVG})\\",\\"stat\\":\\"p50\\"}],[\\"AWS/ApiGateway\\",\\"Latency\\",\\"ApiId\\",\\"imported-id\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P90 (avg: \${AVG})\\",\\"stat\\":\\"p90\\"}],[\\"AWS/ApiGateway\\",\\"IntegrationLatency\\",\\"ApiId\\",\\"imported-id\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P90 (avg: \${AVG})\\",\\"stat\\":\\"p90\\"}],[\\"AWS/ApiGateway\\",\\"Latency\\",\\"ApiId\\",\\"imported-id\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P99 (avg: \${AVG})\\",\\"stat\\":\\"p99\\"}],[\\"AWS/ApiGateway\\",\\"IntegrationLatency\\",\\"ApiId\\",\\"imported-id\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P99 (avg: \${AVG})\\",\\"stat\\":\\"p99\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"ms\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":8,\\"height\\":6,\\"x\\":16,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Errors (rate)\\",\\"region\\":\\"", + Object { + "Ref": "AWS::Region", + }, + "\\",\\"metrics\\":[[\\"AWS/ApiGateway\\",\\"4xx\\",\\"ApiId\\",\\"imported-id\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"4xx (avg)\\"}],[\\"AWS/ApiGateway\\",\\"5xx\\",\\"ApiId\\",\\"imported-id\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"5xx (avg)\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"Rate\\",\\"showUnits\\":false}}}}]}", + ], + ], + }, + }, + "Type": "AWS::CloudWatch::Dashboard", + }, + }, + "Rules": Object { + "CheckBootstrapVersion": Object { + "Assertions": Array [ + Object { + "Assert": Object { + "Fn::Not": Array [ + Object { + "Fn::Contains": Array [ + Array [ + "1", + "2", + "3", + "4", + "5", + ], + Object { + "Ref": "BootstrapVersion", + }, + ], + }, + ], + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI.", + }, + ], + }, + }, +} +`; + +exports[`snapshot test: no alarms with no explicit API name 1`] = ` +Object { + "Parameters": Object { + "BootstrapVersion": Object { + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]", + "Type": "AWS::SSM::Parameter::Value", + }, + }, + "Resources": Object { + "Alarm7103F465": Object { + "Properties": Object { + "DashboardBody": "{\\"widgets\\":[]}", + }, + "Type": "AWS::CloudWatch::Dashboard", + }, + "Resource": Object { + "Properties": Object { + "DashboardBody": Object { + "Fn::Join": Array [ + "", + Array [ + "{\\"widgets\\":[{\\"type\\":\\"text\\",\\"width\\":24,\\"height\\":1,\\"x\\":0,\\"y\\":0,\\"properties\\":{\\"markdown\\":\\"### API Gateway V2 HTTP Endpoint **testHttpApi $default**\\"}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":0,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"TPS\\",\\"region\\":\\"", + Object { + "Ref": "AWS::Region", + }, + "\\",\\"metrics\\":[[{\\"label\\":\\"TPS\\",\\"expression\\":\\"requests / PERIOD(requests)\\"}],[\\"AWS/ApiGateway\\",\\"Count\\",\\"ApiId\\",\\"", + Object { + "Ref": "testHttpApiC57B300F", + }, + "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"Invocations\\",\\"stat\\":\\"Sum\\",\\"visible\\":false,\\"id\\":\\"requests\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"Rate\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":6,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Latency\\",\\"region\\":\\"", + Object { + "Ref": "AWS::Region", + }, + "\\",\\"metrics\\":[[\\"AWS/ApiGateway\\",\\"Latency\\",\\"ApiId\\",\\"", + Object { + "Ref": "testHttpApiC57B300F", + }, + "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P50 (avg: \${AVG})\\",\\"stat\\":\\"p50\\"}],[\\"AWS/ApiGateway\\",\\"IntegrationLatency\\",\\"ApiId\\",\\"", + Object { + "Ref": "testHttpApiC57B300F", + }, + "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P50 (avg: \${AVG})\\",\\"stat\\":\\"p50\\"}],[\\"AWS/ApiGateway\\",\\"Latency\\",\\"ApiId\\",\\"", + Object { + "Ref": "testHttpApiC57B300F", + }, + "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P90 (avg: \${AVG})\\",\\"stat\\":\\"p90\\"}],[\\"AWS/ApiGateway\\",\\"IntegrationLatency\\",\\"ApiId\\",\\"", + Object { + "Ref": "testHttpApiC57B300F", + }, + "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P90 (avg: \${AVG})\\",\\"stat\\":\\"p90\\"}],[\\"AWS/ApiGateway\\",\\"Latency\\",\\"ApiId\\",\\"", + Object { + "Ref": "testHttpApiC57B300F", + }, + "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P99 (avg: \${AVG})\\",\\"stat\\":\\"p99\\"}],[\\"AWS/ApiGateway\\",\\"IntegrationLatency\\",\\"ApiId\\",\\"", + Object { + "Ref": "testHttpApiC57B300F", + }, + "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"P99 (avg: \${AVG})\\",\\"stat\\":\\"p99\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"ms\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":12,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Errors\\",\\"region\\":\\"", + Object { + "Ref": "AWS::Region", + }, + "\\",\\"metrics\\":[[\\"AWS/ApiGateway\\",\\"4xx\\",\\"ApiId\\",\\"", + Object { + "Ref": "testHttpApiC57B300F", + }, + "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"4xx\\",\\"stat\\":\\"Sum\\"}],[\\"AWS/ApiGateway\\",\\"5xx\\",\\"ApiId\\",\\"", + Object { + "Ref": "testHttpApiC57B300F", + }, + "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"5xx\\",\\"stat\\":\\"Sum\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"Count\\",\\"showUnits\\":false}}}},{\\"type\\":\\"metric\\",\\"width\\":6,\\"height\\":5,\\"x\\":18,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"Errors (rate)\\",\\"region\\":\\"", + Object { + "Ref": "AWS::Region", + }, + "\\",\\"metrics\\":[[\\"AWS/ApiGateway\\",\\"4xx\\",\\"ApiId\\",\\"", + Object { + "Ref": "testHttpApiC57B300F", + }, + "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"4xx (avg)\\"}],[\\"AWS/ApiGateway\\",\\"5xx\\",\\"ApiId\\",\\"", + Object { + "Ref": "testHttpApiC57B300F", + }, + "\\",\\"Stage\\",\\"$default\\",{\\"label\\":\\"5xx (avg)\\"}]],\\"yAxis\\":{\\"left\\":{\\"min\\":0,\\"label\\":\\"Rate\\",\\"showUnits\\":false}}}}]}", + ], + ], + }, + }, + "Type": "AWS::CloudWatch::Dashboard", + }, + "Summary68521F81": Object { + "Properties": Object { + "DashboardBody": Object { + "Fn::Join": Array [ + "", + Array [ + "{\\"widgets\\":[{\\"type\\":\\"text\\",\\"width\\":24,\\"height\\":1,\\"x\\":0,\\"y\\":0,\\"properties\\":{\\"markdown\\":\\"### API Gateway V2 HTTP Endpoint **testHttpApi $default**\\"}},{\\"type\\":\\"metric\\",\\"width\\":8,\\"height\\":6,\\"x\\":0,\\"y\\":1,\\"properties\\":{\\"view\\":\\"timeSeries\\",\\"title\\":\\"TPS\\",\\"region\\":\\"", Object { "Ref": "AWS::Region", },