Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(iotevents): allow setting description, evaluation method and key of DetectorModel #18644

Merged
merged 4 commits into from
Jan 27, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion packages/@aws-cdk/aws-iotevents/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ import * as iotevents from '@aws-cdk/aws-iotevents';

const input = new iotevents.Input(this, 'MyInput', {
inputName: 'my_input', // optional
attributeJsonPaths: ['payload.temperature'],
attributeJsonPaths: ['payload.deviceId', 'payload.temperature'],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this change - seems unrelated to the rest of this PR...?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I modified this for the sake of reality.
The path passed in detectorKey must be declared in this attributeJsonPaths. And the value passed in detectorKey is often the unique value of the device or device group.
This is because IoT Events is often used to monitor devices and device groups.

I modified integ test for the same reason.

});

const onlineState = new iotevents.State({
Expand All @@ -64,6 +64,9 @@ const onlineState = new iotevents.State({

new iotevents.DetectorModel(this, 'MyDetectorModel', {
detectorModelName: 'test-detector-model', // optional
description: 'test-detector-model-description', // optional property, default is none
evaluationMethod: iotevents.EventEvaluation.SERIAL, // optional property, default is iotevents.EventEvaluation.BATCH
detectorKey: 'payload.deviceId', // optional property, default is none and single detector instance will be created and all inputs will be routed to it
initialState: onlineState,
});
```
51 changes: 51 additions & 0 deletions packages/@aws-cdk/aws-iotevents/lib/detector-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,22 @@ export interface IDetectorModel extends IResource {
readonly detectorModelName: string;
}

/**
* Information about the order in which events are evaluated and how actions are executed.
*/
export enum EventEvaluation {
/**
* When setting to SERIAL, variables are updated and event conditions are evaluated in the order
* that the events are defined.
*/
BATCH = 'BATCH',
yamatatsu marked this conversation as resolved.
Show resolved Hide resolved
/**
* When setting to BATCH, variables within a state are updated and events within a state are
* performed only after all event conditions are evaluated.
*/
SERIAL = 'SERIAL',
}

/**
* Properties for defining an AWS IoT Events detector model
*/
Expand All @@ -27,6 +43,38 @@ export interface DetectorModelProps {
*/
readonly detectorModelName?: string;

/**
* A brief description of the detector model.
*
* @default none
*/
readonly description?: string;

/**
* Information about the order in which events are evaluated and how actions are executed.
*
* When setting to SERIAL, variables are updated and event conditions are evaluated in the order
* that the events are defined.
* When setting to BATCH, variables within a state are updated and events within a state are
* performed only after all event conditions are evaluated.
*
* @default EventEvaluation.BATCH
*/
readonly evaluationMethod?: EventEvaluation;

/**
* The value used to identify a detector instance. When a device or system sends input, a new
* detector instance with a unique key value is created. AWS IoT Events can continue to route
* input to its corresponding detector instance based on this identifying information.
*
* This parameter uses a JSON-path expression to select the attribute-value pair in the message
* payload that is used for identification. To route the message to the correct detector instance,
* the device must send a message payload that contains the same attribute-value.
*
* @default - none (single detector instance will be created and all inputs will be routed to it)
*/
readonly detectorKey?: string;

/**
* The state that is entered at the creation of each detector.
*/
Expand Down Expand Up @@ -70,6 +118,9 @@ export class DetectorModel extends Resource implements IDetectorModel {

const resource = new CfnDetectorModel(this, 'Resource', {
detectorModelName: this.physicalName,
detectorModelDescription: props.description,
evaluationMethod: props.evaluationMethod,
key: props.detectorKey,
detectorModelDefinition: {
initialStateName: props.initialState.stateName,
states: [props.initialState._toStateJson()],
Expand Down
13 changes: 8 additions & 5 deletions packages/@aws-cdk/aws-iotevents/test/detector-model.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,15 @@ test('can get detector model name', () => {
});
});

test('can set physical name', () => {
test.each([
['physical name', { detectorModelName: 'test-detector-model' }, { DetectorModelName: 'test-detector-model' }],
['description', { description: 'test-detector-model-description' }, { DetectorModelDescription: 'test-detector-model-description' }],
['evaluationMethod', { evaluationMethod: iotevents.EventEvaluation.SERIAL }, { EvaluationMethod: 'SERIAL' }],
['detectorKey', { detectorKey: 'payload.deviceId' }, { Key: 'payload.deviceId' }],
])('can set %s', (_, partialProps, expected) => {
// WHEN
new iotevents.DetectorModel(stack, 'MyDetectorModel', {
detectorModelName: 'test-detector-model',
...partialProps,
initialState: new iotevents.State({
stateName: 'test-state',
onEnter: [{
Expand All @@ -90,9 +95,7 @@ test('can set physical name', () => {
});

// THEN
Template.fromStack(stack).hasResourceProperties('AWS::IoTEvents::DetectorModel', {
DetectorModelName: 'test-detector-model',
});
Template.fromStack(stack).hasResourceProperties('AWS::IoTEvents::DetectorModel', expected);
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's just do all 3 in one test. Spreading them out like that just makes the tests longer, it doesn't really improve coverage in any way.


test('can set multiple events to State', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
"Properties": {
"InputDefinition": {
"Attributes": [
{
"JsonPath": "payload.deviceId"
},
{
"JsonPath": "payload.temperature"
}
Expand Down Expand Up @@ -70,7 +73,10 @@
"Arn"
]
},
"DetectorModelName": "test-detector-model"
"DetectorModelDescription": "test-detector-model-description",
"DetectorModelName": "test-detector-model",
"EvaluationMethod": "SERIAL",
"Key": "payload.deviceId"
}
}
}
Expand Down
5 changes: 4 additions & 1 deletion packages/@aws-cdk/aws-iotevents/test/integ.detector-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class TestStack extends cdk.Stack {

const input = new iotevents.Input(this, 'MyInput', {
inputName: 'test_input',
attributeJsonPaths: ['payload.temperature'],
attributeJsonPaths: ['payload.deviceId', 'payload.temperature'],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, why are we changing existing things?

});

const onlineState = new iotevents.State({
Expand All @@ -27,6 +27,9 @@ class TestStack extends cdk.Stack {

new iotevents.DetectorModel(this, 'MyDetectorModel', {
detectorModelName: 'test-detector-model',
description: 'test-detector-model-description',
evaluationMethod: iotevents.EventEvaluation.SERIAL,
detectorKey: 'payload.deviceId',
initialState: onlineState,
});
}
Expand Down