Skip to content

Commit

Permalink
feat(iot-events): support input action and exit action
Browse files Browse the repository at this point in the history
  • Loading branch information
yamatatsu committed Mar 6, 2022
1 parent f109720 commit 22cc6ef
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@
}
]
},
"OnExit": {},
"OnInput": {},
"StateName": "MyState"
}
Expand Down
10 changes: 9 additions & 1 deletion packages/@aws-cdk/aws-iotevents/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,18 @@ const input = new iotevents.Input(this, 'MyInput', {
const warmState = new iotevents.State({
stateName: 'warm',
onEnter: [{
eventName: 'test-event',
eventName: 'test-enter-event',
condition: iotevents.Expression.currentInput(input),
actions: [new actions.LambdaInvokeAction(func)], // optional
}],
onInput: [{
eventName: 'test-input-event',
actions: [new actions.LambdaInvokeAction(func)], // optional
}],
onExit: [{
eventName: 'test-exit-event',
actions: [new actions.LambdaInvokeAction(func)], // optional
}],
});
const coldState = new iotevents.State({
stateName: 'cold',
Expand Down
40 changes: 33 additions & 7 deletions packages/@aws-cdk/aws-iotevents/lib/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,28 @@ export interface StateProps {
readonly stateName: string;

/**
* Specifies the events on enter. the conditions of the events are evaluated when the state is entered.
* If the condition is `TRUE`, the actions of the event are performed.
* Specifies the events on enter. The conditions of the events will be evaluated when entering this state.
* If the condition of the event evaluates to `true`, the actions of the event will be executed.
*
* @default - events on enter will not be set
* @default - no events will trigger on entering this state
*/
readonly onEnter?: Event[];

/**
* Specifies the events on input. The conditions of the events will be evaluated when any input is received.
* If the condition of the event evaluates to `true`, the actions of the event will be executed.
*
* @default - no events will trigger on input in this state
*/
readonly onInput?: Event[];

/**
* Specifies the events on exit. The conditions of the events are evaluated when an exiting this state.
* If the condition evaluates to `true`, the actions of the event will be executed.
*
* @default - no events will trigger on exiting this state
*/
readonly onExit?: Event[];
}

/**
Expand Down Expand Up @@ -141,22 +157,32 @@ export class State {
}

private toStateJson(scope: Construct, actionBindOptions: ActionBindOptions): CfnDetectorModel.StateProperty {
const { onEnter } = this.props;
const { onEnter, onInput, onExit } = this.props;
return {
stateName: this.stateName,
onEnter: onEnter && { events: toEventsJson(scope, actionBindOptions, onEnter) },
onEnter: {
events: toEventsJson(scope, actionBindOptions, onEnter),
},
onInput: {
events: toEventsJson(scope, actionBindOptions, onInput),
transitionEvents: toTransitionEventsJson(scope, actionBindOptions, this.transitionEvents),
},
onExit: {
events: toEventsJson(scope, actionBindOptions, onExit),
},
};
}
}

function toEventsJson(
scope: Construct,
actionBindOptions: ActionBindOptions,
events: Event[],
): CfnDetectorModel.EventProperty[] {
events?: Event[],
): CfnDetectorModel.EventProperty[] | undefined {
if (!events) {
return undefined;
}

return events.map(event => ({
eventName: event.eventName,
condition: event.condition?.evaluate(),
Expand Down
20 changes: 20 additions & 0 deletions packages/@aws-cdk/aws-iotevents/test/detector-model.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,26 @@ test('can set actions to events', () => {
});
});

test.each([
['onInput', { onInput: [{ eventName: 'test-eventName1' }] }, { OnInput: { Events: [{ EventName: 'test-eventName1' }] } }],
['onExit', { onExit: [{ eventName: 'test-eventName1' }] }, { OnExit: { Events: [{ EventName: 'test-eventName1' }] } }],
])('can set %s to State', (_, events, expected) => {
// WHEN
new iotevents.DetectorModel(stack, 'MyDetectorModel', {
initialState: new iotevents.State({
stateName: 'test-state',
onEnter: [{ eventName: 'test-eventName1', condition: iotevents.Expression.currentInput(input) }],
...events,
}),
});

// THEN
Template.fromStack(stack).hasResourceProperties('AWS::IoTEvents::DetectorModel', {
DetectorModelDefinition: {
States: [Match.objectLike(expected)],
},
});
});

test('can set an action to multiple detector models', () => {
// GIVEN an action
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,43 @@
}
]
},
"OnExit": {
"Events": [
{
"Condition": {
"Fn::Join": [
"",
[
"$input.",
{
"Ref": "MyInput08947B23"
},
".payload.temperature == 31.7"
]
]
},
"EventName": "test-exit-event"
}
]
},
"OnInput": {
"Events": [
{
"Condition": {
"Fn::Join": [
"",
[
"$input.",
{
"Ref": "MyInput08947B23"
},
".payload.temperature == 31.6"
]
]
},
"EventName": "test-input-event"
}
],
"TransitionEvents": [
{
"Condition": {
Expand All @@ -86,6 +122,8 @@
"StateName": "online"
},
{
"OnEnter": {},
"OnExit": {},
"OnInput": {
"TransitionEvents": [
{
Expand Down
14 changes: 14 additions & 0 deletions packages/@aws-cdk/aws-iotevents/test/integ.detector-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,20 @@ class TestStack extends cdk.Stack {
),
),
}],
onInput: [{
eventName: 'test-input-event',
condition: iotevents.Expression.eq(
iotevents.Expression.inputAttribute(input, 'payload.temperature'),
iotevents.Expression.fromString('31.6'),
),
}],
onExit: [{
eventName: 'test-exit-event',
condition: iotevents.Expression.eq(
iotevents.Expression.inputAttribute(input, 'payload.temperature'),
iotevents.Expression.fromString('31.7'),
),
}],
});
const offlineState = new iotevents.State({
stateName: 'offline',
Expand Down

0 comments on commit 22cc6ef

Please sign in to comment.