-
Notifications
You must be signed in to change notification settings - Fork 4.2k
feat(iotevents): add DetectorModel L2 Construct #18049
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
Merged
Merged
Changes from all commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
e5f18b2
feat(iotevents): add DetectorModel L2 Construct
yamatatsu 7873d17
cut out the event.
yamatatsu 07081ed
fix readme
yamatatsu 3d2db07
address comments
yamatatsu 9c24a19
Merge branch 'master' into iotevents-dm
yamatatsu 0723a1c
implement Expressions
yamatatsu 8f82cbb
Update packages/@aws-cdk/aws-iotevents/README.md
yamatatsu fceea45
Update packages/@aws-cdk/aws-iotevents/README.md
yamatatsu 8ae95cd
Update packages/@aws-cdk/aws-iotevents/lib/detector-model.ts
yamatatsu ff69d77
Update packages/@aws-cdk/aws-iotevents/lib/detector-model.ts
yamatatsu d197256
Update packages/@aws-cdk/aws-iotevents/lib/event.ts
yamatatsu f3511b2
Update packages/@aws-cdk/aws-iotevents/lib/event.ts
yamatatsu e5baa25
Update packages/@aws-cdk/aws-iotevents/lib/detector-model.ts
yamatatsu 581ddef
Update packages/@aws-cdk/aws-iotevents/lib/state.ts
yamatatsu 50c183c
Update packages/@aws-cdk/aws-iotevents/lib/detector-model.ts
yamatatsu 971d5c4
Update packages/@aws-cdk/aws-iotevents/lib/detector-model.ts
yamatatsu fbfe028
Update packages/@aws-cdk/aws-iotevents/lib/detector-model.ts
yamatatsu 0b6600d
Update packages/@aws-cdk/aws-iotevents/lib/expression.ts
yamatatsu 18e86d0
Update packages/@aws-cdk/aws-iotevents/lib/state.ts
yamatatsu 9744d78
Update packages/@aws-cdk/aws-iotevents/lib/state.ts
yamatatsu d89d0a0
fix tests
yamatatsu 6ff671e
address comments
yamatatsu 78fc88c
fix JSDoc of onEnter and rename
yamatatsu 5506cb5
Update packages/@aws-cdk/aws-iotevents/test/detector-model.test.ts
yamatatsu 087bb42
address comments
yamatatsu 2b4301e
Merge branch 'master' into iotevents-dm
mergify[bot] File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import * as iam from '@aws-cdk/aws-iam'; | ||
import { Resource, IResource } from '@aws-cdk/core'; | ||
import { Construct } from 'constructs'; | ||
import { CfnDetectorModel } from './iotevents.generated'; | ||
import { State } from './state'; | ||
|
||
/** | ||
* Represents an AWS IoT Events detector model | ||
*/ | ||
export interface IDetectorModel extends IResource { | ||
/** | ||
* The name of the detector model. | ||
* | ||
* @attribute | ||
*/ | ||
readonly detectorModelName: string; | ||
} | ||
|
||
/** | ||
* Properties for defining an AWS IoT Events detector model | ||
*/ | ||
export interface DetectorModelProps { | ||
/** | ||
* The name of the detector model. | ||
* | ||
* @default - CloudFormation will generate a unique name of the detector model | ||
*/ | ||
readonly detectorModelName?: string; | ||
|
||
/** | ||
* The state that is entered at the creation of each detector. | ||
*/ | ||
readonly initialState: State; | ||
|
||
/** | ||
* The role that grants permission to AWS IoT Events to perform its operations. | ||
* | ||
* @default - a role will be created with default permissions | ||
*/ | ||
readonly role?: iam.IRole; | ||
} | ||
|
||
/** | ||
* Defines an AWS IoT Events detector model in this stack. | ||
*/ | ||
export class DetectorModel extends Resource implements IDetectorModel { | ||
/** | ||
* Import an existing detector model. | ||
*/ | ||
public static fromDetectorModelName(scope: Construct, id: string, detectorModelName: string): IDetectorModel { | ||
return new class extends Resource implements IDetectorModel { | ||
public readonly detectorModelName = detectorModelName; | ||
}(scope, id); | ||
} | ||
|
||
public readonly detectorModelName: string; | ||
|
||
constructor(scope: Construct, id: string, props: DetectorModelProps) { | ||
super(scope, id, { | ||
physicalName: props.detectorModelName, | ||
}); | ||
|
||
if (!props.initialState._onEnterEventsHaveAtLeastOneCondition()) { | ||
throw new Error('Detector Model must have at least one Input with a condition'); | ||
} | ||
|
||
const role = props.role ?? new iam.Role(this, 'DetectorModelRole', { | ||
assumedBy: new iam.ServicePrincipal('iotevents.amazonaws.com'), | ||
}); | ||
|
||
const resource = new CfnDetectorModel(this, 'Resource', { | ||
detectorModelName: this.physicalName, | ||
detectorModelDefinition: { | ||
initialStateName: props.initialState.stateName, | ||
states: [props.initialState._toStateJson()], | ||
}, | ||
roleArn: role.roleArn, | ||
}); | ||
|
||
this.detectorModelName = this.getResourceNameAttribute(resource.ref); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { Expression } from './expression'; | ||
|
||
/** | ||
* Specifies the actions to be performed when the condition evaluates to TRUE. | ||
skinny85 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
*/ | ||
export interface Event { | ||
/** | ||
* The name of the event. | ||
*/ | ||
readonly eventName: string; | ||
|
||
/** | ||
* The Boolean expression that, when TRUE, causes the actions to be performed. | ||
* | ||
* @default - none (the actions are always executed) | ||
*/ | ||
readonly condition?: Expression; | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import { IInput } from './input'; | ||
|
||
/** | ||
* Expression for events in Detector Model state | ||
* @see https://docs.aws.amazon.com/iotevents/latest/developerguide/iotevents-expressions.html | ||
*/ | ||
export abstract class Expression { | ||
yamatatsu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/** | ||
* Create a expression from the given string | ||
*/ | ||
public static fromString(value: string): Expression { | ||
return new StringExpression(value); | ||
} | ||
|
||
/** | ||
* Create a expression for function `currentInput()`. | ||
* It is evaluated to true if the specified input message was received. | ||
*/ | ||
public static currentInput(input: IInput): Expression { | ||
return this.fromString(`currentInput("${input.inputName}")`); | ||
} | ||
yamatatsu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/** | ||
* Create a expression for get an input attribute as `$input.TemperatureInput.temperatures[2]`. | ||
*/ | ||
public static inputAttribute(input: IInput, path: string): Expression { | ||
return this.fromString(`$input.${input.inputName}.${path}`); | ||
} | ||
|
||
/** | ||
* Create a expression for the Equal operator | ||
*/ | ||
public static eq(left: Expression, right: Expression): Expression { | ||
return new BinaryOperationExpression(left, '==', right); | ||
} | ||
|
||
/** | ||
* Create a expression for the AND operator | ||
*/ | ||
public static and(left: Expression, right: Expression): Expression { | ||
return new BinaryOperationExpression(left, '&&', right); | ||
} | ||
|
||
constructor() { | ||
} | ||
|
||
/** | ||
* this is called to evaluate the expression | ||
*/ | ||
public abstract evaluate(): string; | ||
} | ||
|
||
class StringExpression extends Expression { | ||
constructor(private readonly value: string) { | ||
super(); | ||
} | ||
|
||
public evaluate() { | ||
return this.value; | ||
} | ||
} | ||
|
||
class BinaryOperationExpression extends Expression { | ||
constructor( | ||
private readonly left: Expression, | ||
private readonly operator: string, | ||
private readonly right: Expression, | ||
) { | ||
super(); | ||
} | ||
|
||
public evaluate() { | ||
return `${this.left.evaluate()} ${this.operator} ${this.right.evaluate()}`; | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,8 @@ | ||
export * from './detector-model'; | ||
export * from './event'; | ||
export * from './expression'; | ||
export * from './input'; | ||
export * from './state'; | ||
|
||
// AWS::IoTEvents CloudFormation Resources: | ||
export * from './iotevents.generated'; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import { Event } from './event'; | ||
import { CfnDetectorModel } from './iotevents.generated'; | ||
|
||
/** | ||
* Properties for defining a state of a detector | ||
*/ | ||
export interface StateProps { | ||
/** | ||
* The name of the state. | ||
*/ | ||
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. | ||
* | ||
* @default - events on enter will not be set | ||
*/ | ||
readonly onEnter?: Event[]; | ||
} | ||
|
||
/** | ||
* Defines a state of a detector | ||
*/ | ||
export class State { | ||
/** | ||
* The name of the state | ||
*/ | ||
public readonly stateName: string; | ||
|
||
constructor(private readonly props: StateProps) { | ||
this.stateName = props.stateName; | ||
} | ||
|
||
/** | ||
* Return the state property JSON | ||
* | ||
* @internal | ||
*/ | ||
public _toStateJson(): CfnDetectorModel.StateProperty { | ||
const { stateName, onEnter } = this.props; | ||
return { | ||
stateName, | ||
onEnter: onEnter && { events: getEventJson(onEnter) }, | ||
}; | ||
} | ||
|
||
/** | ||
* returns true if this state has at least one condition via events | ||
* | ||
* @internal | ||
*/ | ||
public _onEnterEventsHaveAtLeastOneCondition(): boolean { | ||
return this.props.onEnter?.some(event => event.condition) ?? false; | ||
} | ||
} | ||
|
||
function getEventJson(events: Event[]): CfnDetectorModel.EventProperty[] { | ||
return events.map(e => { | ||
return { | ||
eventName: e.eventName, | ||
condition: e.condition?.evaluate(), | ||
}; | ||
}); | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.