Skip to content

Commit 9f03dc4

Browse files
authoredDec 11, 2021
feat(iotevents): add IoT Events input L2 Construct (#17847)
This is proposed by #17711. This PR was created for implemeting `Input` L2 Construct. Implementing it is needed before `DetectorModel`. The reason is described in here: #17711 (comment) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent de67aae commit 9f03dc4

File tree

8 files changed

+221
-16
lines changed

8 files changed

+221
-16
lines changed
 
+31-8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# AWS::IoTEvents Construct Library
2+
23
<!--BEGIN STABILITY BANNER-->
34

45
---
@@ -9,23 +10,45 @@
910
>
1011
> [CFN Resources]: https://docs.aws.amazon.com/cdk/latest/guide/constructs.html#constructs_lib
1112
13+
![cdk-constructs: Experimental](https://img.shields.io/badge/cdk--constructs-experimental-important.svg?style=for-the-badge)
14+
15+
> The APIs of higher level constructs in this module are experimental and under active development.
16+
> They are subject to non-backward compatible changes or removal in any future version. These are
17+
> not subject to the [Semantic Versioning](https://semver.org/) model and breaking changes will be
18+
> announced in the release notes. This means that while you may use them, you may need to update
19+
> your source code when upgrading to a newer version of this package.
20+
1221
---
1322

1423
<!--END STABILITY BANNER-->
1524

16-
This module is part of the [AWS Cloud Development Kit](https://github.com/aws/aws-cdk) project.
25+
AWS IoT Events enables you to monitor your equipment or device fleets for
26+
failures or changes in operation, and to trigger actions when such events
27+
occur.
28+
29+
## Installation
30+
31+
Install the module:
32+
33+
```console
34+
$ npm i @aws-cdk/aws-iotevents
35+
```
36+
37+
Import it into your code:
1738

1839
```ts nofixture
1940
import * as iotevents from '@aws-cdk/aws-iotevents';
2041
```
2142

22-
<!--BEGIN CFNONLY DISCLAIMER-->
23-
24-
There are no hand-written ([L2](https://docs.aws.amazon.com/cdk/latest/guide/constructs.html#constructs_lib)) constructs for this service yet.
25-
However, you can still use the automatically generated [L1](https://docs.aws.amazon.com/cdk/latest/guide/constructs.html#constructs_l1_using) constructs, and use this service exactly as you would using CloudFormation directly.
43+
## `Input`
2644

27-
For more information on the resources and properties available for this service, see the [CloudFormation documentation for AWS::IoTEvents](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/AWS_IoTEvents.html).
45+
Add an AWS IoT Events input to your stack:
2846

29-
(Read the [CDK Contributing Guide](https://github.com/aws/aws-cdk/blob/master/CONTRIBUTING.md) if you are interested in contributing to this construct library.)
47+
```ts
48+
import * as iotevents from '@aws-cdk/aws-iotevents';
3049

31-
<!--END CFNONLY DISCLAIMER-->
50+
new iotevents.Input(this, 'MyInput', {
51+
inputName: 'my_input',
52+
attributeJsonPaths: ['payload.temperature'],
53+
});
54+
```
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
1+
export * from './input';
2+
13
// AWS::IoTEvents CloudFormation Resources:
24
export * from './iotevents.generated';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { Resource, IResource } from '@aws-cdk/core';
2+
import { Construct } from 'constructs';
3+
import { CfnInput } from './iotevents.generated';
4+
5+
/**
6+
* Represents an AWS IoT Events input
7+
*/
8+
export interface IInput extends IResource {
9+
/**
10+
* The name of the input
11+
* @attribute
12+
*/
13+
readonly inputName: string;
14+
}
15+
16+
/**
17+
* Properties for defining an AWS IoT Events input
18+
*/
19+
export interface InputProps {
20+
/**
21+
* The name of the input
22+
*
23+
* @default - CloudFormation will generate a unique name of the input
24+
*/
25+
readonly inputName?: string,
26+
27+
/**
28+
* An expression that specifies an attribute-value pair in a JSON structure.
29+
* Use this to specify an attribute from the JSON payload that is made available
30+
* by the input. Inputs are derived from messages sent to AWS IoT Events (BatchPutMessage).
31+
* Each such message contains a JSON payload. The attribute (and its paired value)
32+
* specified here are available for use in the condition expressions used by detectors.
33+
*/
34+
readonly attributeJsonPaths: string[];
35+
}
36+
37+
/**
38+
* Defines an AWS IoT Events input in this stack.
39+
*/
40+
export class Input extends Resource implements IInput {
41+
/**
42+
* Import an existing input
43+
*/
44+
public static fromInputName(scope: Construct, id: string, inputName: string): IInput {
45+
class Import extends Resource implements IInput {
46+
public readonly inputName = inputName;
47+
}
48+
return new Import(scope, id);
49+
}
50+
51+
public readonly inputName: string;
52+
53+
constructor(scope: Construct, id: string, props: InputProps) {
54+
super(scope, id, {
55+
physicalName: props.inputName,
56+
});
57+
58+
if (props.attributeJsonPaths.length === 0) {
59+
throw new Error('attributeJsonPaths property cannot be empty');
60+
}
61+
62+
const resource = new CfnInput(this, 'Resource', {
63+
inputName: this.physicalName,
64+
inputDefinition: {
65+
attributes: props.attributeJsonPaths.map(path => ({ jsonPath: path })),
66+
},
67+
});
68+
69+
this.inputName = this.getResourceNameAttribute(resource.ref);
70+
}
71+
}

‎packages/@aws-cdk/aws-iotevents/package.json

+4-2
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,11 @@
7676
"devDependencies": {
7777
"@aws-cdk/assertions": "0.0.0",
7878
"@aws-cdk/cdk-build-tools": "0.0.0",
79+
"@aws-cdk/cdk-integ-tools": "0.0.0",
7980
"@aws-cdk/cfn2ts": "0.0.0",
8081
"@aws-cdk/pkglint": "0.0.0",
81-
"@types/jest": "^27.0.3"
82+
"@types/jest": "^27.0.3",
83+
"jest": "^27.3.1"
8284
},
8385
"dependencies": {
8486
"@aws-cdk/core": "0.0.0",
@@ -92,7 +94,7 @@
9294
"node": ">= 10.13.0 <13 || >=13.7.0"
9395
},
9496
"stability": "experimental",
95-
"maturity": "cfn-only",
97+
"maturity": "experimental",
9698
"awscdkio": {
9799
"announce": false
98100
},
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { Template } from '@aws-cdk/assertions';
2+
import * as cdk from '@aws-cdk/core';
3+
import * as iotevents from '../lib';
4+
5+
test('Default property', () => {
6+
const stack = new cdk.Stack();
7+
8+
// WHEN
9+
new iotevents.Input(stack, 'MyInput', {
10+
attributeJsonPaths: ['payload.temperature'],
11+
});
12+
13+
// THEN
14+
Template.fromStack(stack).hasResourceProperties('AWS::IoTEvents::Input', {
15+
InputDefinition: {
16+
Attributes: [{ JsonPath: 'payload.temperature' }],
17+
},
18+
});
19+
});
20+
21+
test('can get input name', () => {
22+
const stack = new cdk.Stack();
23+
// GIVEN
24+
const input = new iotevents.Input(stack, 'MyInput', {
25+
attributeJsonPaths: ['payload.temperature'],
26+
});
27+
28+
// WHEN
29+
new cdk.CfnResource(stack, 'Res', {
30+
type: 'Test::Resource',
31+
properties: {
32+
InputName: input.inputName,
33+
},
34+
});
35+
36+
// THEN
37+
Template.fromStack(stack).hasResourceProperties('Test::Resource', {
38+
InputName: { Ref: 'MyInput08947B23' },
39+
});
40+
});
41+
42+
test('can set physical name', () => {
43+
const stack = new cdk.Stack();
44+
45+
// WHEN
46+
new iotevents.Input(stack, 'MyInput', {
47+
inputName: 'test_input',
48+
attributeJsonPaths: ['payload.temperature'],
49+
});
50+
51+
// THEN
52+
Template.fromStack(stack).hasResourceProperties('AWS::IoTEvents::Input', {
53+
InputName: 'test_input',
54+
});
55+
});
56+
57+
test('can import a Input by inputName', () => {
58+
const stack = new cdk.Stack();
59+
60+
// WHEN
61+
const inputName = 'test-input-name';
62+
const topicRule = iotevents.Input.fromInputName(stack, 'InputFromInputName', inputName);
63+
64+
// THEN
65+
expect(topicRule).toMatchObject({
66+
inputName,
67+
});
68+
});
69+
70+
test('cannot be created with an empty array of attributeJsonPaths', () => {
71+
const stack = new cdk.Stack();
72+
73+
expect(() => {
74+
new iotevents.Input(stack, 'MyInput', {
75+
attributeJsonPaths: [],
76+
});
77+
}).toThrow('attributeJsonPaths property cannot be empty');
78+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"Resources": {
3+
"MyInput08947B23": {
4+
"Type": "AWS::IoTEvents::Input",
5+
"Properties": {
6+
"InputDefinition": {
7+
"Attributes": [
8+
{
9+
"JsonPath": "payload.temperature"
10+
}
11+
]
12+
},
13+
"InputName": "test_input"
14+
}
15+
}
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import * as cdk from '@aws-cdk/core';
2+
import * as iotevents from '../lib';
3+
4+
const app = new cdk.App();
5+
6+
class TestStack extends cdk.Stack {
7+
constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
8+
super(scope, id, props);
9+
10+
new iotevents.Input(this, 'MyInput', {
11+
inputName: 'test_input',
12+
attributeJsonPaths: ['payload.temperature'],
13+
});
14+
}
15+
}
16+
17+
new TestStack(app, 'test-stack');
18+
app.synth();

‎packages/@aws-cdk/aws-iotevents/test/iotevents.test.ts

-6
This file was deleted.

0 commit comments

Comments
 (0)
Please sign in to comment.