-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(iot): add the TopicRule L2 construct (#16681)
I tried to implement aws-iot L2 Constructs. I did following: 1. add L2 construct 1. add unit tests 1. add integration test 1. test with deploying to my AWS account and sending MQTT. 1. update package.json resolves: #16602 I should do following for undrafting: - [x] write comments - [x] implement other actions Following is not implemented yet, but I will implements other PR. - Elasticsearch - Kinesis Firehose - Kinesis Stream - http - IoT Analytics - IoT Events - IoT SiteWise - kafka - Step Functions - [x] write README ---- ## Design ### TopicRule and IAction ![image](https://user-images.githubusercontent.com/11013683/136200920-9aa1aa58-2e9f-4a0d-a161-bbe251d02f7d.png) ### Implements of IAction ![image](https://user-images.githubusercontent.com/11013683/136201053-4f693683-3318-4fbf-9a7e-cd3f8ac1a93e.png) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
- Loading branch information
Showing
9 changed files
with
384 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,5 @@ | ||
export * from './iot-sql'; | ||
export * from './topic-rule'; | ||
|
||
// AWS::IoT CloudFormation Resources: | ||
export * from './iot.generated'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import { Construct } from 'constructs'; | ||
|
||
/** | ||
* The type returned from the `bind()` method in {@link IotSql}. | ||
*/ | ||
export interface IotSqlConfig { | ||
/** | ||
* The version of the SQL rules engine to use when evaluating the rule. | ||
*/ | ||
readonly awsIotSqlVersion: string; | ||
|
||
/** | ||
* The SQL statement used to query the topic. | ||
*/ | ||
readonly sql: string; | ||
} | ||
|
||
/** | ||
* Defines AWS IoT SQL. | ||
*/ | ||
export abstract class IotSql { | ||
/** | ||
* Uses the original SQL version built on 2015-10-08. | ||
* | ||
* @param sql The actual SQL-like syntax query | ||
* @returns Instance of IotSql | ||
*/ | ||
public static fromStringAsVer20151008(sql: string): IotSql { | ||
return new IotSqlImpl('2015-10-08', sql); | ||
} | ||
|
||
/** | ||
* Uses the SQL version built on 2016-03-23. | ||
* | ||
* @param sql The actual SQL-like syntax query | ||
* @returns Instance of IotSql | ||
*/ | ||
public static fromStringAsVer20160323(sql: string): IotSql { | ||
return new IotSqlImpl('2016-03-23', sql); | ||
} | ||
|
||
/** | ||
* Uses the most recent beta SQL version. If you use this version, it might | ||
* introduce breaking changes to your rules. | ||
* | ||
* @param sql The actual SQL-like syntax query | ||
* @returns Instance of IotSql | ||
*/ | ||
public static fromStringAsVerNewestUnstable(sql: string): IotSql { | ||
return new IotSqlImpl('beta', sql); | ||
} | ||
|
||
/** | ||
* Returns the IoT SQL configuration. | ||
*/ | ||
public abstract bind(scope: Construct): IotSqlConfig; | ||
} | ||
|
||
|
||
class IotSqlImpl extends IotSql { | ||
constructor(private readonly version: string, private readonly sql: string) { | ||
super(); | ||
|
||
if (sql === '') { | ||
throw new Error('IoT SQL string cannot be empty'); | ||
} | ||
} | ||
|
||
bind(_scope: Construct): IotSqlConfig { | ||
return { | ||
awsIotSqlVersion: this.version, | ||
sql: this.sql, | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
import { ArnFormat, Resource, Stack, IResource } from '@aws-cdk/core'; | ||
import { Construct } from 'constructs'; | ||
import { IotSql } from './iot-sql'; | ||
import { CfnTopicRule } from './iot.generated'; | ||
|
||
/** | ||
* Represents an AWS IoT Rule | ||
*/ | ||
export interface ITopicRule extends IResource { | ||
/** | ||
* The value of the topic rule Amazon Resource Name (ARN), such as | ||
* arn:aws:iot:us-east-2:123456789012:rule/rule_name | ||
* | ||
* @attribute | ||
*/ | ||
readonly topicRuleArn: string; | ||
|
||
/** | ||
* The name topic rule | ||
* | ||
* @attribute | ||
*/ | ||
readonly topicRuleName: string; | ||
} | ||
|
||
/** | ||
* Properties for defining an AWS IoT Rule | ||
*/ | ||
export interface TopicRuleProps { | ||
/** | ||
* The name of the rule. | ||
* @default None | ||
*/ | ||
readonly topicRuleName?: string; | ||
|
||
/** | ||
* A simplified SQL syntax to filter messages received on an MQTT topic and push the data elsewhere. | ||
* | ||
* @see https://docs.aws.amazon.com/iot/latest/developerguide/iot-sql-reference.html | ||
*/ | ||
readonly sql: IotSql; | ||
} | ||
|
||
/** | ||
* Defines an AWS IoT Rule in this stack. | ||
*/ | ||
export class TopicRule extends Resource implements ITopicRule { | ||
/** | ||
* Import an existing AWS IoT Rule provided an ARN | ||
* | ||
* @param scope The parent creating construct (usually `this`). | ||
* @param id The construct's name. | ||
* @param topicRuleArn AWS IoT Rule ARN (i.e. arn:aws:iot:<region>:<account-id>:rule/MyRule). | ||
*/ | ||
public static fromTopicRuleArn(scope: Construct, id: string, topicRuleArn: string): ITopicRule { | ||
const parts = Stack.of(scope).splitArn(topicRuleArn, ArnFormat.SLASH_RESOURCE_NAME); | ||
if (!parts.resourceName) { | ||
throw new Error(`Missing topic rule name in ARN: '${topicRuleArn}'`); | ||
} | ||
const resourceName = parts.resourceName; | ||
|
||
class Import extends Resource implements ITopicRule { | ||
public readonly topicRuleArn = topicRuleArn; | ||
public readonly topicRuleName = resourceName; | ||
} | ||
return new Import(scope, id, { | ||
environmentFromArn: topicRuleArn, | ||
}); | ||
} | ||
|
||
/** | ||
* Arn of this rule | ||
* @attribute | ||
*/ | ||
public readonly topicRuleArn: string; | ||
|
||
/** | ||
* Name of this rule | ||
* @attribute | ||
*/ | ||
public readonly topicRuleName: string; | ||
|
||
constructor(scope: Construct, id: string, props: TopicRuleProps) { | ||
super(scope, id, { | ||
physicalName: props.topicRuleName, | ||
}); | ||
|
||
const sqlConfig = props.sql.bind(this); | ||
|
||
const resource = new CfnTopicRule(this, 'Resource', { | ||
ruleName: this.physicalName, | ||
topicRulePayload: { | ||
actions: [], | ||
awsIotSqlVersion: sqlConfig.awsIotSqlVersion, | ||
sql: sqlConfig.sql, | ||
}, | ||
}); | ||
|
||
this.topicRuleArn = this.getResourceArnAttribute(resource.attrArn, { | ||
service: 'iot', | ||
resource: 'rule', | ||
resourceName: this.physicalName, | ||
}); | ||
this.topicRuleName = this.getResourceNameAttribute(resource.ref); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 14 additions & 0 deletions
14
packages/@aws-cdk/aws-iot/test/integ.topic-rule.expected.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
"Resources": { | ||
"TopicRule40A4EA44": { | ||
"Type": "AWS::IoT::TopicRule", | ||
"Properties": { | ||
"TopicRulePayload": { | ||
"Actions": [], | ||
"AwsIotSqlVersion": "2015-10-08", | ||
"Sql": "SELECT topic(2) as device_id FROM 'device/+/data'" | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
/// !cdk-integ pragma:ignore-assets | ||
import * as cdk from '@aws-cdk/core'; | ||
import * as iot from '../lib'; | ||
|
||
const app = new cdk.App(); | ||
|
||
class TestStack extends cdk.Stack { | ||
constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { | ||
super(scope, id, props); | ||
|
||
new iot.TopicRule(this, 'TopicRule', { | ||
sql: iot.IotSql.fromStringAsVer20151008("SELECT topic(2) as device_id FROM 'device/+/data'"), | ||
}); | ||
} | ||
} | ||
|
||
new TestStack(app, 'test-stack'); | ||
app.synth(); |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.