Skip to content

Commit

Permalink
feat(iotevents): support SetVariable action (#19305)
Browse files Browse the repository at this point in the history
This PR implememts `SetVariable` actions.
This action allow to set variable to detector instanse.

If use this action as following and deploy it:
```ts
actions: [
  new actions.IoteventsSetVariableAction(
    'MyVariable',
    iotevents.Expression.inputAttribute(input, 'payload.temperature'),
  ),
],
```

And send message via cli as following:
```
aws iotevents-data batch-put-message --messages=messageId=(date | md5),inputName=test_input,payload=(echo '{"payload":{"deviceId":"000","temperature":18.5}}' | base64)
```

You can see the created detector instanse on web console:
![image](https://user-images.githubusercontent.com/11013683/157444640-c93e4229-ba75-46dd-8d35-cd171fed6145.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
yamatatsu committed Mar 11, 2022
1 parent 1875c28 commit c222b12
Show file tree
Hide file tree
Showing 6 changed files with 235 additions and 0 deletions.
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.SetVariableAction(
'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 './set-variable-action';
export * from './lambda-invoke-action';
25 changes: 25 additions & 0 deletions packages/@aws-cdk/aws-iotevents-actions/lib/set-variable-action.ts
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 SetVariableAction implements iotevents.IAction {
/**
* @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.SetVariableAction(
'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.SetVariableAction('MyVariable', iotevents.Expression.fromString('foo'))],
}],
}),
});

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

0 comments on commit c222b12

Please sign in to comment.