Skip to content

Commit

Permalink
feat(iot): TopicRule and RepublishAction
Browse files Browse the repository at this point in the history
1. add L2 construct
2. add unit tests
3. add integration test
4. update package.json
  • Loading branch information
yamatatsu committed Sep 29, 2021
1 parent 6390cb5 commit 49a0bb2
Show file tree
Hide file tree
Showing 12 changed files with 1,021 additions and 3 deletions.
8 changes: 8 additions & 0 deletions packages/@aws-cdk/aws-iot/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@
>
> [CFN Resources]: https://docs.aws.amazon.com/cdk/latest/guide/constructs.html#constructs_lib
![cdk-constructs: Experimental](https://img.shields.io/badge/cdk--constructs-experimental-important.svg?style=for-the-badge)

> The APIs of higher level constructs in this module are experimental and under active development.
> They are subject to non-backward compatible changes or removal in any future version. These are
> not subject to the [Semantic Versioning](https://semver.org/) model and breaking changes will be
> announced in the release notes. This means that while you may use them, you may need to update
> your source code when upgrading to a newer version of this package.
---

<!--END STABILITY BANNER-->
Expand Down
120 changes: 120 additions & 0 deletions packages/@aws-cdk/aws-iot/lib/action.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import { IConstruct } from '@aws-cdk/core';
import { CfnTopicRule } from './iot.generated';

/**
* An abstract action for TopicRule.
*/
export interface IAction {
/**
* Returns the topic rule action specification.
*
* @param rule The TopicRule that would trigger this action.
*/
bind(rule: IConstruct): ActionConfig;
}

/**
* Properties for an topic rule action
*/
export interface ActionConfig {
/**
* An action to set state of an Amazon CloudWatch alarm.
* @default None
*/
readonly cloudwatchAlarm?: CfnTopicRule.CloudwatchAlarmActionProperty;
/**
* An action to send data to Amazon CloudWatch Logs.
* @default None
*/
readonly cloudwatchLogs?: CfnTopicRule.CloudwatchLogsActionProperty;
/**
* An action to capture an Amazon CloudWatch metric.
* @default None
*/
readonly cloudwatchMetric?: CfnTopicRule.CloudwatchMetricActionProperty;
/**
* An action to write all or part of an MQTT message to an Amazon DynamoDB table.
* @default None
*/
readonly dynamoDb?: CfnTopicRule.DynamoDBActionProperty;
/**
* An action to write all or part of an MQTT message to an Amazon DynamoDB table.
* @default None
*/
readonly dynamoDBv2?: CfnTopicRule.DynamoDBv2ActionProperty;
/**
* An action to write data from MQTT messages to an Amazon OpenSearch Service domain.
* @default None
*/
readonly elasticsearch?: CfnTopicRule.ElasticsearchActionProperty;
/**
* An action to send data from an MQTT message to an Amazon Kinesis Data Firehose stream.
* @default None
*/
readonly firehose?: CfnTopicRule.FirehoseActionProperty;
/**
* An action to send data from an MQTT message to a web application or service.
* @default None
*/
readonly http?: CfnTopicRule.HttpActionProperty;
/**
* An action to send data from an MQTT message to an AWS IoT Analytics channel.
* @default None
*/
readonly iotAnalytics?: CfnTopicRule.IotAnalyticsActionProperty;
/**
* An action to send data from an MQTT message to an AWS IoT Events input.
* @default None
*/
readonly iotEvents?: CfnTopicRule.IotEventsActionProperty;
/**
* An action to send data from an MQTT message to asset properties in AWS IoT SiteWise.
* @default None
*/
readonly iotSiteWise?: CfnTopicRule.IotSiteWiseActionProperty;
/**
* An action to sends messages directly to your Amazon MSK or self-managed Apache Kafka clusters for data analysis and visualization.
* @default None
*/
readonly kafka?: CfnTopicRule.KafkaActionProperty;
/**
* An action to write data from an MQTT message to Amazon Kinesis Data Streams.
* @default None
*/
readonly kinesis?: CfnTopicRule.KinesisActionProperty;
/**
* An action to invoke an AWS Lambda function, passing in an MQTT message.
* @default None
*/
readonly lambda?: CfnTopicRule.LambdaActionProperty;
/**
* An action to republish an MQTT message to another MQTT topic.
* @default None
*/
readonly republish?: CfnTopicRule.RepublishActionProperty;
/**
* An action to write the data from an MQTT message to an Amazon S3 bucket.
* @default None
*/
readonly s3?: CfnTopicRule.S3ActionProperty;
/**
* An action to send the data from an MQTT message as an Amazon SNS push notification.
* @default None
*/
readonly sns?: CfnTopicRule.SnsActionProperty;
/**
* An action to send data from an MQTT message to an Amazon SQS queue.
* @default None
*/
readonly sqs?: CfnTopicRule.SqsActionProperty;
/**
* An action to start an AWS Step Functions state machine.
* @default None
*/
readonly stepFunctions?: CfnTopicRule.StepFunctionsActionProperty;
/**
* An action to write attributes (measures) from an MQTT message into an Amazon Timestream table.
* @default None
*/
readonly timestream?: CfnTopicRule.TimestreamActionProperty;
}
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-iot/lib/actions/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './republish-action';
79 changes: 79 additions & 0 deletions packages/@aws-cdk/aws-iot/lib/actions/republish-action.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import * as iam from '@aws-cdk/aws-iam';
import { IConstruct, Arn, Stack } from '@aws-cdk/core';
import { IAction, ActionConfig } from '../';
import { singletonActionRole } from './util';

/**
* Configuration properties of an action for republishing
*/
export interface RepublishActionProps {
/**
* The Quality of Service (QoS) level to use when republishing messages.
*
* @default QOS.LEVEL_0
*/
readonly qos?: QOS;
/**
* The IAM role that allows AWS IoT to publish to the MQTT topic.
*
* @default a new role will be created
*/
readonly role?: iam.IRole;
}

/**
* The Quality of Service (QoS) level to use when republishing messages.
*
* @see MQTT Quality of Service (QoS) options
*/
export enum QOS {
/**
* Sent zero or more times
*/
LEVEL_0,
/**
* Sent at least one time, and then repeatedly until a PUBACK response is received
*/
LEVEL_1,
}

/**
* The action to republish an MQTT message to another MQTT topic.
*/
export class RepublishAction implements IAction {
private readonly qos?: number;
private readonly role?: iam.IRole;

/**
* @param topic The MQTT topic to which to republish the message.
* @param props Optional properties to not use default
*/
constructor(private readonly topic: string, props: RepublishActionProps = {}) {
this.qos = props.qos;
this.role = props.role;
}

bind(rule: IConstruct): ActionConfig {
const role = this.role ?? singletonActionRole(rule);
role.addToPrincipalPolicy(this.putEventStatement(rule));

return {
republish: {
qos: this.qos ?? QOS.LEVEL_0,
roleArn: role.roleArn,
topic: this.topic,
},
};
}

private putEventStatement(scope: IConstruct) {
return new iam.PolicyStatement({
actions: ['iot:Publish'],
resources: [
Arn.format({
service: 'iot', resource: 'topic', resourceName: this.topic,
}, Stack.of(scope)),
],
});
}
}
25 changes: 25 additions & 0 deletions packages/@aws-cdk/aws-iot/lib/actions/util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import * as iam from '@aws-cdk/aws-iam';
import { IConstruct, PhysicalName } from '@aws-cdk/core';

// keep this import separate from other imports to reduce chance for merge conflicts with v2-main
// eslint-disable-next-line no-duplicate-imports, import/order
import { Construct } from '@aws-cdk/core';

/**
* Obtain the Role for the TopicRule
*
* If a role already exists, it will be returned. This ensures that if a rule have multiple
* actions, they will share a role.
* @internal
*/
export function singletonActionRole(scope: IConstruct): iam.IRole {
const id = 'TopicRuleActionRole';
const existing = scope.node.tryFindChild(id) as iam.IRole;
if (existing) return existing;

const role = new iam.Role(scope as Construct, id, {
roleName: PhysicalName.GENERATE_IF_NEEDED,
assumedBy: new iam.ServicePrincipal('iot.amazonaws.com'),
});
return role;
}
3 changes: 3 additions & 0 deletions packages/@aws-cdk/aws-iot/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
export * from './action';
export * from './topic-rule';

// AWS::IoT CloudFormation Resources:
export * from './iot.generated';
Loading

0 comments on commit 49a0bb2

Please sign in to comment.