Skip to content

Commit 3ed0c0e

Browse files
committed
feat(aws-cloudwatch): CompositeAlarm
1 parent 471ccd5 commit 3ed0c0e

10 files changed

+28
-267
lines changed

packages/@aws-cdk/aws-cloudwatch/README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,9 @@ can be created from existing Alarm resources.
183183
const alarmRule = AlarmRule.anyOf(
184184
AlarmRule.allOf(
185185
AlarmRule.anyOf(
186-
AlarmRule.fromAlarm(alarm1, AlarmState.ALARM),
186+
alarm1,
187187
AlarmRule.fromAlarm(alarm2, AlarmState.OK),
188-
AlarmRule.fromAlarm(alarm3, AlarmState.ALARM),
188+
alarm3,
189189
),
190190
AlarmRule.not(AlarmRule.fromAlarm(alarm4, AlarmState.INSUFFICIENT_DATA)),
191191
),

packages/@aws-cdk/aws-cloudwatch/lib/alarm-action.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Construct } from '@aws-cdk/core';
2-
import { IAlarm } from './alarm';
2+
import { IAlarm } from './alarm-base';
33

44
/**
55
* Interface for objects that can be the targets of CloudWatch alarm actions

packages/@aws-cdk/aws-cloudwatch/lib/alarm.ts

+3-133
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { Construct, IResource, Lazy, Resource, Stack, Token } from '@aws-cdk/core';
2-
import { IAlarmAction } from './alarm-action';
1+
import { Construct, Lazy, Stack, Token } from '@aws-cdk/core';
2+
import { AlarmBase, IAlarm } from './alarm-base';
33
import { CfnAlarm, CfnAlarmProps } from './cloudwatch.generated';
44
import { HorizontalAnnotation } from './graph';
55
import { CreateAlarmOptions } from './metric';
@@ -9,37 +9,6 @@ import { dropUndefined } from './private/object';
99
import { MetricSet } from './private/rendering';
1010
import { parseStatistic } from './private/statistic';
1111

12-
/**
13-
* Interface for Alarm Rule.
14-
*/
15-
export interface IAlarmRule {
16-
17-
/**
18-
* serialized representation of Alarm Rule to be used when building the Composite Alarm resource.
19-
*/
20-
toAlarmRule(): string;
21-
22-
}
23-
24-
/**
25-
* Represents a CloudWatch Alarm
26-
*/
27-
export interface IAlarm extends IAlarmRule, IResource {
28-
/**
29-
* Alarm ARN (i.e. arn:aws:cloudwatch:<region>:<account-id>:alarm:Foo)
30-
*
31-
* @attribute
32-
*/
33-
readonly alarmArn: string;
34-
35-
/**
36-
* Name of the alarm
37-
*
38-
* @attribute
39-
*/
40-
readonly alarmName: string;
41-
}
42-
4312
/**
4413
* Properties for Alarms
4514
*/
@@ -51,14 +20,6 @@ export interface AlarmProps extends CreateAlarmOptions {
5120
* custom Metric objects by instantiating one.
5221
*/
5322
readonly metric: IMetric;
54-
55-
/**
56-
* AlarmState to build composite alarm expressions.
57-
*
58-
* @default - ALARM
59-
*/
60-
readonly alarmState?: AlarmState;
61-
6223
}
6324

6425
/**
@@ -124,86 +85,6 @@ export enum TreatMissingData {
12485
MISSING = 'missing'
12586
}
12687

127-
/**
128-
* Enumeration indicates state of Alarm used in building Alarm Rule.
129-
*/
130-
export enum AlarmState {
131-
132-
/**
133-
* State indicates resource is in ALARM
134-
*/
135-
ALARM = 'ALARM',
136-
137-
/**
138-
* State indicates resource is not in ALARM
139-
*/
140-
OK = 'OK',
141-
142-
/**
143-
* State indicates there is not enough data to determine is resource is in ALARM
144-
*/
145-
INSUFFICIENT_DATA = 'INSUFFICIENT_DATA',
146-
147-
}
148-
149-
/**
150-
* The base class for Alarm and CompositeAlarm resources.
151-
*/
152-
export abstract class AlarmBase extends Resource implements IAlarm {
153-
154-
/**
155-
* @attribute
156-
*/
157-
public abstract readonly alarmArn: string;
158-
public abstract readonly alarmName: string;
159-
160-
protected alarmActionArns?: string[];
161-
protected insufficientDataActionArns?: string[];
162-
protected okActionArns?: string[];
163-
164-
public abstract toAlarmRule(): string;
165-
166-
/**
167-
* Trigger this action if the alarm fires
168-
*
169-
* Typically the ARN of an SNS topic or ARN of an AutoScaling policy.
170-
*/
171-
public addAlarmAction(...actions: IAlarmAction[]) {
172-
if (this.alarmActionArns === undefined) {
173-
this.alarmActionArns = [];
174-
}
175-
176-
this.alarmActionArns.push(...actions.map(a => a.bind(this, this).alarmActionArn));
177-
}
178-
179-
/**
180-
* Trigger this action if there is insufficient data to evaluate the alarm
181-
*
182-
* Typically the ARN of an SNS topic or ARN of an AutoScaling policy.
183-
*/
184-
public addInsufficientDataAction(...actions: IAlarmAction[]) {
185-
if (this.insufficientDataActionArns === undefined) {
186-
this.insufficientDataActionArns = [];
187-
}
188-
189-
this.insufficientDataActionArns.push(...actions.map(a => a.bind(this, this).alarmActionArn));
190-
}
191-
192-
/**
193-
* Trigger this action if the alarm returns from breaching state into ok state
194-
*
195-
* Typically the ARN of an SNS topic or ARN of an AutoScaling policy.
196-
*/
197-
public addOkAction(...actions: IAlarmAction[]) {
198-
if (this.okActionArns === undefined) {
199-
this.okActionArns = [];
200-
}
201-
202-
this.okActionArns.push(...actions.map(a => a.bind(this, this).alarmActionArn));
203-
}
204-
205-
}
206-
20788
/**
20889
* An alarm on a CloudWatch metric
20990
*/
@@ -217,13 +98,9 @@ export class Alarm extends AlarmBase {
21798
* @param alarmArn Alarm ARN (i.e. arn:aws:cloudwatch:<region>:<account-id>:alarm:Foo)
21899
*/
219100
public static fromAlarmArn(scope: Construct, id: string, alarmArn: string): IAlarm {
220-
class Import extends Resource implements IAlarm {
101+
class Import extends AlarmBase implements IAlarm {
221102
public readonly alarmArn = alarmArn;
222103
public readonly alarmName = Stack.of(scope).parseArn(alarmArn, ':').resourceName!;
223-
224-
public toAlarmRule(): string {
225-
throw new Error('Method not implemented.');
226-
}
227104
}
228105
return new Import(scope, id);
229106
}
@@ -252,8 +129,6 @@ export class Alarm extends AlarmBase {
252129
*/
253130
private readonly annotation: HorizontalAnnotation;
254131

255-
private readonly alarmState: AlarmState;
256-
257132
constructor(scope: Construct, id: string, props: AlarmProps) {
258133
super(scope, id, {
259134
physicalName: props.alarmName,
@@ -314,7 +189,6 @@ export class Alarm extends AlarmBase {
314189
label: `${this.metric} ${OPERATOR_SYMBOLS[comparisonOperator]} ${props.threshold} for ${datapoints} datapoints within ${describePeriod(props.evaluationPeriods * metricPeriod(props.metric).toSeconds())}`,
315190
value: props.threshold,
316191
};
317-
this.alarmState = props.alarmState || AlarmState.ALARM;
318192
}
319193

320194
/**
@@ -337,10 +211,6 @@ export class Alarm extends AlarmBase {
337211
return this.annotation;
338212
}
339213

340-
public toAlarmRule(): string {
341-
return `${this.alarmState}(${this.alarmArn})`;
342-
}
343-
344214
private renderMetric(metric: IMetric) {
345215
const self = this;
346216
return dispatchMetric(metric, {

packages/@aws-cdk/aws-cloudwatch/lib/composite-alarm.ts

+5-117
Original file line numberDiff line numberDiff line change
@@ -1,111 +1,7 @@
1-
import { Construct, Lazy, Resource, Stack } from '@aws-cdk/core';
2-
import { AlarmBase, AlarmState, IAlarm, IAlarmRule } from './alarm';
1+
import { Construct, Lazy, Stack } from '@aws-cdk/core';
2+
import { AlarmBase, IAlarm, IAlarmRule } from './alarm-base';
33
import { CfnCompositeAlarm } from './cloudwatch.generated';
44

5-
/**
6-
* Enumeration of supported Composite Alarms operators.
7-
*/
8-
enum Operator {
9-
10-
AND = 'AND',
11-
OR = 'OR',
12-
NOT = 'NOT',
13-
14-
}
15-
16-
/**
17-
* Class with static functions to build AlarmRule for Composite Alarms.
18-
*/
19-
export class AlarmRule {
20-
21-
/**
22-
* function to join all provided AlarmRules with AND operator.
23-
*
24-
* @param operands IAlarmRules to be joined with AND operator.
25-
*/
26-
public static allOf(...operands: IAlarmRule[]): IAlarmRule {
27-
return this.concat(Operator.AND, ...operands);
28-
}
29-
30-
/**
31-
* function to join all provided AlarmRules with OR operator.
32-
*
33-
* @param operands IAlarmRules to be joined with OR operator.
34-
*/
35-
public static anyOf(...operands: IAlarmRule[]): IAlarmRule {
36-
return this.concat(Operator.OR, ...operands);
37-
}
38-
39-
/**
40-
* function to wrap provided AlarmRule in NOT operator.
41-
*
42-
* @param operand IAlarmRule to be wrapped in NOT operator.
43-
*/
44-
public static not(operand: IAlarmRule): IAlarmRule {
45-
// tslint:disable-next-line:new-parens
46-
return new class implements IAlarmRule {
47-
public toAlarmRule(): string {
48-
return `(NOT ${operand.toAlarmRule()})`;
49-
}
50-
};
51-
}
52-
53-
/**
54-
* function to build TRUE/FALSE intent for Rule Expression.
55-
*
56-
* @param value boolean value to be used in rule expression.
57-
*/
58-
public static fromBoolean(value: boolean): IAlarmRule {
59-
// tslint:disable-next-line:new-parens
60-
return new class implements IAlarmRule {
61-
public toAlarmRule(): string {
62-
return `${String(value).toUpperCase()}`;
63-
}
64-
};
65-
}
66-
67-
/**
68-
* function to build Rule Expression for given IAlarm and AlarmState.
69-
*
70-
* @param alarm IAlarm to be used in Rule Expression.
71-
* @param alarmState AlarmState to be used in Rule Expression.
72-
*/
73-
public static fromAlarm(alarm: IAlarm, alarmState: AlarmState): IAlarmRule {
74-
// tslint:disable-next-line:new-parens
75-
return new class implements IAlarmRule {
76-
public toAlarmRule(): string {
77-
return `${alarmState}(${alarm.alarmArn})`;
78-
}
79-
};
80-
}
81-
82-
/**
83-
* function to build Rule Expression for given Alarm Rule string.
84-
*
85-
* @param alarmRule string to be used in Rule Expression.
86-
*/
87-
public static fromString(alarmRule: string): IAlarmRule {
88-
// tslint:disable-next-line:new-parens
89-
return new class implements IAlarmRule {
90-
public toAlarmRule(): string {
91-
return alarmRule;
92-
}
93-
};
94-
}
95-
96-
private static concat(operator: Operator, ...operands: IAlarmRule[]): IAlarmRule {
97-
// tslint:disable-next-line:new-parens
98-
return new class implements IAlarmRule {
99-
public toAlarmRule(): string {
100-
return operands
101-
.map(operand => `(${operand.toAlarmRule()})`)
102-
.join(` ${operator} `);
103-
}
104-
};
105-
}
106-
107-
}
108-
1095
/**
1106
* Properties for creating a Composite Alarm
1117
*/
@@ -169,13 +65,9 @@ export class CompositeAlarm extends AlarmBase {
16965
* @param compositeAlarmArn Composite Alarm ARN (i.e. arn:aws:cloudwatch:<region>:<account-id>:alarm/CompositeAlarmName)
17066
*/
17167
public static fromCompositeAlarmArn(scope: Construct, id: string, compositeAlarmArn: string): IAlarm {
172-
class Import extends Resource implements IAlarm {
68+
class Import extends AlarmBase implements IAlarm {
17369
public readonly alarmArn = compositeAlarmArn;
17470
public readonly alarmName = Stack.of(scope).parseArn(compositeAlarmArn).resourceName!;
175-
176-
public toAlarmRule(): string {
177-
throw new Error('Method not implemented.');
178-
}
17971
}
18072
return new Import(scope, id);
18173
}
@@ -201,11 +93,11 @@ export class CompositeAlarm extends AlarmBase {
20193
physicalName: props.compositeAlarmName ?? Lazy.stringValue({ produce: () => this.generateUniqueId() }),
20294
});
20395

204-
if (props.alarmRule.toAlarmRule().length > 10240) {
96+
if (props.alarmRule.renderAlarmRule().length > 10240) {
20597
throw new Error('Alarm Rule expression cannot be greater than 10240 characters, please reduce the conditions in the Alarm Rule');
20698
}
20799

208-
this.alarmRule = props.alarmRule.toAlarmRule();
100+
this.alarmRule = props.alarmRule.renderAlarmRule();
209101

210102
const alarm = new CfnCompositeAlarm(this, 'Resource', {
211103
alarmName: this.physicalName,
@@ -226,10 +118,6 @@ export class CompositeAlarm extends AlarmBase {
226118

227119
}
228120

229-
public toAlarmRule(): string {
230-
return this.alarmRule;
231-
}
232-
233121
private generateUniqueId(): string {
234122
const name = this.node.uniqueId;
235123
if (name.length > 240) {

packages/@aws-cdk/aws-cloudwatch/lib/graph.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as cdk from '@aws-cdk/core';
2-
import { IAlarm } from './alarm';
2+
import { IAlarm } from './alarm-base';
33
import { IMetric } from './metric-types';
44
import { allMetricsGraphJson } from './private/rendering';
55
import { ConcreteWidget } from './widget';

packages/@aws-cdk/aws-cloudwatch/lib/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
export * from './alarm';
22
export * from './alarm-action';
3+
export * from './alarm-base';
4+
export * from './alarm-rule';
35
export * from './composite-alarm';
46
export * from './dashboard';
57
export * from './graph';

0 commit comments

Comments
 (0)