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): support SetVariable action #19305

Merged
merged 4 commits into from
Mar 11, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
29 changes: 29 additions & 0 deletions packages/@aws-cdk/aws-iotevents-actions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,37 @@ AWS IoT Events can trigger actions when it detects a specified event or transiti

Currently supported are:

- Set variable to detector instanse
- Invoke a Lambda function

## Set variable to detector instanse

The code snippet below creates an Action that set variable to detector instanse
when it is triggered.

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

declare const input: iotevents.IInput;

const state = new iotevents.State({
stateName: 'MyState',
onEnter: [{
eventName: 'test-event',
condition: iotevents.Expression.currentInput(input),
actions: [
actions: [
new actions.IoteventsSetVariableAction(
skinny85 marked this conversation as resolved.
Show resolved Hide resolved
'MyVariable',
iotevents.Expression.inputAttribute(input, 'payload.temperature'),
),
],
],
}],
});
```

## Invoke a Lambda function

The code snippet below creates an Action that invoke a Lambda function
Expand Down
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-iotevents-actions/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './iotevents-set-variable-action';
export * from './lambda-invoke-action';
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import * as iotevents from '@aws-cdk/aws-iotevents';
import { Construct } from 'constructs';

/**
* The action to create a variable with a specified value.
*/
export class IoteventsSetVariableAction implements iotevents.IAction {
Copy link
Contributor

Choose a reason for hiding this comment

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

What's with the weird name? Why the weird Iotevents prefix?

I think this should be called just SetVariableAction.

I could be convinced to IotSetVariableAction or IotEventsSetVariableAction, but in my opinion, the Iot / IotEvents prefix doesn't add anything here.

/**
* @param variableName the name of the variable
* @param value the new value of the variable
*/
constructor(private readonly variableName: string, private readonly value: iotevents.Expression) {
}

bind(_scope: Construct, _options: iotevents.ActionBindOptions): iotevents.ActionConfig {
return {
configuration: {
setVariable: {
variableName: this.variableName,
value: this.value.evaluate(),
},
},
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
{
"Resources": {
"MyInput08947B23": {
"Type": "AWS::IoTEvents::Input",
"Properties": {
"InputDefinition": {
"Attributes": [
{
"JsonPath": "payload.deviceId"
},
{
"JsonPath": "payload.temperature"
}
]
},
"InputName": "test_input"
}
},
"MyDetectorModelDetectorModelRoleF2FB4D88": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "iotevents.amazonaws.com"
}
}
],
"Version": "2012-10-17"
}
}
},
"MyDetectorModel559C0B0E": {
"Type": "AWS::IoTEvents::DetectorModel",
"Properties": {
"DetectorModelDefinition": {
"InitialStateName": "MyState",
"States": [
{
"OnEnter": {
"Events": [
{
"Actions": [
{
"SetVariable": {
"Value": {
"Fn::Join": [
"",
[
"$input.",
{
"Ref": "MyInput08947B23"
},
".payload.temperature"
]
]
},
"VariableName": "MyVariable"
}
}
],
"Condition": {
"Fn::Join": [
"",
[
"currentInput(\"",
{
"Ref": "MyInput08947B23"
},
"\")"
]
]
},
"EventName": "enter-event"
}
]
},
"StateName": "MyState"
}
]
},
"RoleArn": {
"Fn::GetAtt": [
"MyDetectorModelDetectorModelRoleF2FB4D88",
"Arn"
]
},
"Key": "payload.deviceId"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* Stack verification steps:
* * put a message
* * aws iotevents-data batch-put-message --messages=messageId=(date | md5),inputName=test_input,payload=(echo '{"payload":{"temperature":31.9,"deviceId":"000"}}' | base64)
*/
import * as iotevents from '@aws-cdk/aws-iotevents';
import * as cdk from '@aws-cdk/core';
import * as actions from '../../lib';

class TestStack extends cdk.Stack {
constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
super(scope, id, props);

const input = new iotevents.Input(this, 'MyInput', {
inputName: 'test_input',
attributeJsonPaths: ['payload.deviceId', 'payload.temperature'],
});

const state = new iotevents.State({
stateName: 'MyState',
onEnter: [{
eventName: 'enter-event',
condition: iotevents.Expression.currentInput(input),
actions: [
new actions.IoteventsSetVariableAction(
'MyVariable',
iotevents.Expression.inputAttribute(input, 'payload.temperature'),
),
],
}],
});

new iotevents.DetectorModel(this, 'MyDetectorModel', {
detectorKey: 'payload.deviceId',
initialState: state,
});
}
}

const app = new cdk.App();
new TestStack(app, 'iotevents-set-variable-action-test-stack');
app.synth();
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Template } from '@aws-cdk/assertions';
import * as iotevents from '@aws-cdk/aws-iotevents';
import * as cdk from '@aws-cdk/core';
import * as actions from '../../lib';

let stack: cdk.Stack;
let input: iotevents.IInput;
beforeEach(() => {
stack = new cdk.Stack();
input = iotevents.Input.fromInputName(stack, 'MyInput', 'test-input');
});

test('Default property', () => {
// WHEN
new iotevents.DetectorModel(stack, 'MyDetectorModel', {
initialState: new iotevents.State({
stateName: 'test-state',
onEnter: [{
eventName: 'test-eventName',
condition: iotevents.Expression.currentInput(input),
actions: [new actions.IoteventsSetVariableAction('MyVariable', iotevents.Expression.fromString('foo'))],
}],
}),
});

// THEN
Template.fromStack(stack).hasResourceProperties('AWS::IoTEvents::DetectorModel', {
DetectorModelDefinition: {
States: [{
OnEnter: {
Events: [{
Actions: [{
SetVariable: {
VariableName: 'MyVariable',
Value: 'foo',
},
}],
}],
},
}],
},
});
});