Skip to content

Commit

Permalink
feat(iotevents): add IoT Events input L2 Construct (#17847)
Browse files Browse the repository at this point in the history
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*
  • Loading branch information
yamatatsu authored Dec 11, 2021
1 parent de67aae commit 9f03dc4
Show file tree
Hide file tree
Showing 8 changed files with 221 additions and 16 deletions.
39 changes: 31 additions & 8 deletions packages/@aws-cdk/aws-iotevents/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# AWS::IoTEvents Construct Library

<!--BEGIN STABILITY BANNER-->

---
Expand All @@ -9,23 +10,45 @@
>
> [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-->

This module is part of the [AWS Cloud Development Kit](https://github.com/aws/aws-cdk) project.
AWS IoT Events enables you to monitor your equipment or device fleets for
failures or changes in operation, and to trigger actions when such events
occur.

## Installation

Install the module:

```console
$ npm i @aws-cdk/aws-iotevents
```

Import it into your code:

```ts nofixture
import * as iotevents from '@aws-cdk/aws-iotevents';
```

<!--BEGIN CFNONLY DISCLAIMER-->

There are no hand-written ([L2](https://docs.aws.amazon.com/cdk/latest/guide/constructs.html#constructs_lib)) constructs for this service yet.
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.
## `Input`

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).
Add an AWS IoT Events input to your stack:

(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.)
```ts
import * as iotevents from '@aws-cdk/aws-iotevents';

<!--END CFNONLY DISCLAIMER-->
new iotevents.Input(this, 'MyInput', {
inputName: 'my_input',
attributeJsonPaths: ['payload.temperature'],
});
```
2 changes: 2 additions & 0 deletions packages/@aws-cdk/aws-iotevents/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
export * from './input';

// AWS::IoTEvents CloudFormation Resources:
export * from './iotevents.generated';
71 changes: 71 additions & 0 deletions packages/@aws-cdk/aws-iotevents/lib/input.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { Resource, IResource } from '@aws-cdk/core';
import { Construct } from 'constructs';
import { CfnInput } from './iotevents.generated';

/**
* Represents an AWS IoT Events input
*/
export interface IInput extends IResource {
/**
* The name of the input
* @attribute
*/
readonly inputName: string;
}

/**
* Properties for defining an AWS IoT Events input
*/
export interface InputProps {
/**
* The name of the input
*
* @default - CloudFormation will generate a unique name of the input
*/
readonly inputName?: string,

/**
* An expression that specifies an attribute-value pair in a JSON structure.
* Use this to specify an attribute from the JSON payload that is made available
* by the input. Inputs are derived from messages sent to AWS IoT Events (BatchPutMessage).
* Each such message contains a JSON payload. The attribute (and its paired value)
* specified here are available for use in the condition expressions used by detectors.
*/
readonly attributeJsonPaths: string[];
}

/**
* Defines an AWS IoT Events input in this stack.
*/
export class Input extends Resource implements IInput {
/**
* Import an existing input
*/
public static fromInputName(scope: Construct, id: string, inputName: string): IInput {
class Import extends Resource implements IInput {
public readonly inputName = inputName;
}
return new Import(scope, id);
}

public readonly inputName: string;

constructor(scope: Construct, id: string, props: InputProps) {
super(scope, id, {
physicalName: props.inputName,
});

if (props.attributeJsonPaths.length === 0) {
throw new Error('attributeJsonPaths property cannot be empty');
}

const resource = new CfnInput(this, 'Resource', {
inputName: this.physicalName,
inputDefinition: {
attributes: props.attributeJsonPaths.map(path => ({ jsonPath: path })),
},
});

this.inputName = this.getResourceNameAttribute(resource.ref);
}
}
6 changes: 4 additions & 2 deletions packages/@aws-cdk/aws-iotevents/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,11 @@
"devDependencies": {
"@aws-cdk/assertions": "0.0.0",
"@aws-cdk/cdk-build-tools": "0.0.0",
"@aws-cdk/cdk-integ-tools": "0.0.0",
"@aws-cdk/cfn2ts": "0.0.0",
"@aws-cdk/pkglint": "0.0.0",
"@types/jest": "^27.0.3"
"@types/jest": "^27.0.3",
"jest": "^27.3.1"
},
"dependencies": {
"@aws-cdk/core": "0.0.0",
Expand All @@ -92,7 +94,7 @@
"node": ">= 10.13.0 <13 || >=13.7.0"
},
"stability": "experimental",
"maturity": "cfn-only",
"maturity": "experimental",
"awscdkio": {
"announce": false
},
Expand Down
78 changes: 78 additions & 0 deletions packages/@aws-cdk/aws-iotevents/test/input.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { Template } from '@aws-cdk/assertions';
import * as cdk from '@aws-cdk/core';
import * as iotevents from '../lib';

test('Default property', () => {
const stack = new cdk.Stack();

// WHEN
new iotevents.Input(stack, 'MyInput', {
attributeJsonPaths: ['payload.temperature'],
});

// THEN
Template.fromStack(stack).hasResourceProperties('AWS::IoTEvents::Input', {
InputDefinition: {
Attributes: [{ JsonPath: 'payload.temperature' }],
},
});
});

test('can get input name', () => {
const stack = new cdk.Stack();
// GIVEN
const input = new iotevents.Input(stack, 'MyInput', {
attributeJsonPaths: ['payload.temperature'],
});

// WHEN
new cdk.CfnResource(stack, 'Res', {
type: 'Test::Resource',
properties: {
InputName: input.inputName,
},
});

// THEN
Template.fromStack(stack).hasResourceProperties('Test::Resource', {
InputName: { Ref: 'MyInput08947B23' },
});
});

test('can set physical name', () => {
const stack = new cdk.Stack();

// WHEN
new iotevents.Input(stack, 'MyInput', {
inputName: 'test_input',
attributeJsonPaths: ['payload.temperature'],
});

// THEN
Template.fromStack(stack).hasResourceProperties('AWS::IoTEvents::Input', {
InputName: 'test_input',
});
});

test('can import a Input by inputName', () => {
const stack = new cdk.Stack();

// WHEN
const inputName = 'test-input-name';
const topicRule = iotevents.Input.fromInputName(stack, 'InputFromInputName', inputName);

// THEN
expect(topicRule).toMatchObject({
inputName,
});
});

test('cannot be created with an empty array of attributeJsonPaths', () => {
const stack = new cdk.Stack();

expect(() => {
new iotevents.Input(stack, 'MyInput', {
attributeJsonPaths: [],
});
}).toThrow('attributeJsonPaths property cannot be empty');
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"Resources": {
"MyInput08947B23": {
"Type": "AWS::IoTEvents::Input",
"Properties": {
"InputDefinition": {
"Attributes": [
{
"JsonPath": "payload.temperature"
}
]
},
"InputName": "test_input"
}
}
}
}
18 changes: 18 additions & 0 deletions packages/@aws-cdk/aws-iotevents/test/integ.detector-model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import * as cdk from '@aws-cdk/core';
import * as iotevents 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 iotevents.Input(this, 'MyInput', {
inputName: 'test_input',
attributeJsonPaths: ['payload.temperature'],
});
}
}

new TestStack(app, 'test-stack');
app.synth();
6 changes: 0 additions & 6 deletions packages/@aws-cdk/aws-iotevents/test/iotevents.test.ts

This file was deleted.

0 comments on commit 9f03dc4

Please sign in to comment.