Skip to content

Commit

Permalink
Address comments
Browse files Browse the repository at this point in the history
  • Loading branch information
jerry-shao committed Dec 16, 2021
1 parent ae3ab61 commit eabefe7
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 79 deletions.
9 changes: 4 additions & 5 deletions packages/@aws-cdk/aws-iot-actions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,9 @@ const topicRule = new iot.TopicRule(this, 'TopicRule', {
});
```

## Change state for a CloudWatch alarm
## Change the state of an Amazon CloudWatch alarm

The code snippet below creates an AWS IoT Rule that changes a CloudWatch alarm
when it is triggered.
The code snippet below creates an AWS IoT Rule that changes the state of an Amazon CloudWatch alarm when it is triggered.

```ts
import * as cloudwatch from '@aws-cdk/aws-cloudwatch';
Expand All @@ -178,9 +177,9 @@ const topicRule = new iot.TopicRule(this, 'TopicRule', {
actions: [
new actions.CloudWatchAlarmAction(alarm, {
stateReason: 'AWS Iot Rule action is triggered',
stateValue: 'ALARM',
stateValue: cloudwatch.AlarmState.ALARM,
}),
]
],
});
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,27 @@ import { singletonActionRole } from './private/role';
/**
* Configuration properties of an action for CloudWatch alarm.
*/
export interface CloudWatchAlarmActionProps extends CommonActionProps {
export interface CloudWatchSetAlarmStateActionProps extends CommonActionProps {
/**
* The reason for the alarm change.
*
* @default None
*/
readonly stateReason: string;
readonly reason?: string;

/**
* The value of the alarm state.
* The value of the alarm state to set.
*/
readonly stateValue: string;
readonly alarmStateToSet: cloudwatch.AlarmState;
}

/**
* The action to change a CloudWatch alarm state.
* The action to change the state of an Amazon CloudWatch alarm.
*/
export class CloudWatchAlarmAction implements iot.IAction {
export class CloudWatchSetAlarmStateAction implements iot.IAction {
constructor(
private readonly alarm: cloudwatch.IAlarm,
private readonly props: CloudWatchAlarmActionProps,
private readonly props: CloudWatchSetAlarmStateActionProps,
) {
}

Expand All @@ -40,8 +43,8 @@ export class CloudWatchAlarmAction implements iot.IAction {
cloudwatchAlarm: {
alarmName: this.alarm.alarmName,
roleArn: role.roleArn,
stateReason: this.props.stateReason,
stateValue: this.props.stateValue,
stateReason: this.props.reason ?? 'AWS IoT Rule action triggers a change',
stateValue: this.props.alarmStateToSet,
},
},
};
Expand Down
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-iot-actions/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export * from './cloudwatch-logs-action';
export * from './cloudwatch-put-metric-action';
export * from './cloudwatch-alarm-action';
export * from './cloudwatch-set-alarm-state-action';
export * from './common-action-props';
export * from './firehose-stream-action';
export * from './lambda-function-action';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,26 @@ import * as cloudwatch from '@aws-cdk/aws-cloudwatch';
import * as iam from '@aws-cdk/aws-iam';
import * as iot from '@aws-cdk/aws-iot';
import * as cdk from '@aws-cdk/core';
import { CloudWatchAlarmAction, CloudWatchAlarmActionProps } from '../../lib/cloudwatch-alarm-action';
import * as actions from '../../lib';

test('Default cloudwatch alarm action', () => {
// Given
const stack = new cdk.Stack();
const topicRule = new iot.TopicRule(stack, 'MyTopicRule', {
sql: iot.IotSql.fromStringAsVer20160323("SELECT topic(2) as device_id, stateReason, stateValue FROM 'device/+/data'"),
});
const alarmArn = 'arn:aws:cloudwatch:us-east-1:123456789012:alarm:MyAlarm';
const alarm = cloudwatch.Alarm.fromAlarmArn(stack, 'MyAlarm', alarmArn);
const cloudWatchAlarmActionProps: CloudWatchAlarmActionProps = {
stateReason: '${stateReason}',
stateValue: '${stateValue}',
};
const alarm = cloudwatch.Alarm.fromAlarmArn(stack, 'MyAlarm', 'arn:aws:cloudwatch:us-east-1:123456789012:alarm:MyAlarm');

// When
topicRule.addAction(new CloudWatchAlarmAction(alarm, cloudWatchAlarmActionProps));
topicRule.addAction(
new actions.CloudWatchSetAlarmStateAction(
alarm,
{
reason: 'Test reason',
alarmStateToSet: cloudwatch.AlarmState.ALARM,
},
),
);

// Then
Template.fromStack(stack).hasResourceProperties('AWS::IoT::TopicRule', {
Expand All @@ -31,8 +34,8 @@ test('Default cloudwatch alarm action', () => {
RoleArn: {
'Fn::GetAtt': ['MyTopicRuleTopicRuleActionRoleCE2D05DA', 'Arn'],
},
StateReason: '${stateReason}',
StateValue: '${stateValue}',
StateReason: 'Test reason',
StateValue: cloudwatch.AlarmState.ALARM,
},
},
],
Expand Down Expand Up @@ -60,7 +63,7 @@ test('Default cloudwatch alarm action', () => {
{
Action: 'cloudwatch:SetAlarmState',
Effect: 'Allow',
Resource: alarmArn,
Resource: alarm.alarmArn,
},
],
Version: '2012-10-17',
Expand All @@ -70,87 +73,73 @@ test('Default cloudwatch alarm action', () => {
});
});

test('can set stateReason', () => {
test('can set role', () => {
// Given
const stack = new cdk.Stack();
const topicRule = new iot.TopicRule(stack, 'MyTopicRule', {
sql: iot.IotSql.fromStringAsVer20160323("SELECT topic(2) as device_id, stateReason, stateValue FROM 'device/+/data'"),
});
const alarmArn = 'arn:aws:cloudwatch:us-east-1:123456789012:alarm:MyAlarm';
const alarm = cloudwatch.Alarm.fromAlarmArn(stack, 'MyAlarm', alarmArn);
const cloudWatchAlarmActionProps: CloudWatchAlarmActionProps = {
stateReason: 'Test SetAlarmState',
stateValue: '${stateValue}',
};

// When
topicRule.addAction(new CloudWatchAlarmAction(alarm, cloudWatchAlarmActionProps));
topicRule.addAction(
new actions.CloudWatchSetAlarmStateAction(
cloudwatch.Alarm.fromAlarmArn(stack, 'MyAlarm', 'arn:aws:cloudwatch:us-east-1:123456789012:alarm:MyAlarm'),
{
reason: '${stateReason}',
alarmStateToSet: cloudwatch.AlarmState.ALARM,
role: iam.Role.fromRoleArn(stack, 'MyRole', 'arn:aws:iam::123456789012:role/ForTest'),
},
),
);

// Then
Template.fromStack(stack).hasResourceProperties('AWS::IoT::TopicRule', {
TopicRulePayload: {
Actions: [
Match.objectLike({ CloudwatchAlarm: { StateReason: 'Test SetAlarmState' } }),
Match.objectLike({ CloudwatchAlarm: { RoleArn: 'arn:aws:iam::123456789012:role/ForTest' } }),
],
},
});
});

test('can set stateValue', () => {
// Given
const stack = new cdk.Stack();
const topicRule = new iot.TopicRule(stack, 'MyTopicRule', {
sql: iot.IotSql.fromStringAsVer20160323("SELECT topic(2) as device_id, stateReason, stateValue FROM 'device/+/data'"),
});
const alarmArn = 'arn:aws:cloudwatch:us-east-1:123456789012:alarm:MyAlarm';
const alarm = cloudwatch.Alarm.fromAlarmArn(stack, 'MyAlarm', alarmArn);
const cloudWatchAlarmActionProps: CloudWatchAlarmActionProps = {
stateReason: '${stateReason}',
stateValue: 'ALARM',
};

// When
topicRule.addAction(new CloudWatchAlarmAction(alarm, cloudWatchAlarmActionProps));

// Then
Template.fromStack(stack).hasResourceProperties('AWS::IoT::TopicRule', {
TopicRulePayload: {
Actions: [
Match.objectLike({ CloudwatchAlarm: { StateValue: 'ALARM' } }),
],
},
Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', {
PolicyName: 'MyRolePolicy64AB00A5',
Roles: ['ForTest'],
});
});

test('can set role', () => {
test('set default reason', () => {
// Given
const stack = new cdk.Stack();
const topicRule = new iot.TopicRule(stack, 'MyTopicRule', {
sql: iot.IotSql.fromStringAsVer20160323("SELECT topic(2) as device_id, stateReason, stateValue FROM 'device/+/data'"),
});
const alarmArn = 'arn:aws:cloudwatch:us-east-1:123456789012:alarm:MyAlarm';
const alarm = cloudwatch.Alarm.fromAlarmArn(stack, 'MyAlarm', alarmArn);
const role = iam.Role.fromRoleArn(stack, 'MyRole', 'arn:aws:iam::123456789012:role/ForTest');
const cloudWatchAlarmActionProps: CloudWatchAlarmActionProps = {
stateReason: '${stateReason}',
stateValue: '${stateValue}',
role: role,
};
const alarm = cloudwatch.Alarm.fromAlarmArn(stack, 'MyAlarm', 'arn:aws:cloudwatch:us-east-1:123456789012:alarm:MyAlarm');

// When
topicRule.addAction(new CloudWatchAlarmAction(alarm, cloudWatchAlarmActionProps));
topicRule.addAction(
new actions.CloudWatchSetAlarmStateAction(
alarm,
{
alarmStateToSet: cloudwatch.AlarmState.ALARM,
},
),
);

// Then
Template.fromStack(stack).hasResourceProperties('AWS::IoT::TopicRule', {
TopicRulePayload: {
Actions: [
Match.objectLike({ CloudwatchAlarm: { RoleArn: 'arn:aws:iam::123456789012:role/ForTest' } }),
{
CloudwatchAlarm: {
AlarmName: 'MyAlarm',
RoleArn: {
'Fn::GetAtt': ['MyTopicRuleTopicRuleActionRoleCE2D05DA', 'Arn'],
},
StateReason: 'AWS IoT Rule action triggers a change',
StateValue: cloudwatch.AlarmState.ALARM,
},
},
],
},
});

Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', {
PolicyName: 'MyRolePolicy64AB00A5',
Roles: ['ForTest'],
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ class TestStack extends cdk.Stack {
datapointsToAlarm: 2,
});

topicRule.addAction(new actions.CloudWatchAlarmAction(alarm, {
stateReason: 'Test reason',
stateValue: 'ALARM',
topicRule.addAction(new actions.CloudWatchSetAlarmStateAction(alarm, {
reason: 'Test reason',
alarmStateToSet: cloudwatch.AlarmState.ALARM,
}));
}
}
Expand Down

0 comments on commit eabefe7

Please sign in to comment.