diff --git a/doc/api-python.md b/doc/api-python.md index e385e23..22d390a 100644 --- a/doc/api-python.md +++ b/doc/api-python.md @@ -121,38 +121,6 @@ This code is licensed under the MIT-0 License. See the LICENSE file. ### Campaign -export class Campaign extends Construct { readonly name: string = ''; - -readonly arn: string = ''; -readonly target: Vehicle = ({} as Vehicle); - -constructor(scope: Construct, id: string, props: CampaignProps) { -super(scope, id); - -(this.name as string) = props.name; -this.arn = `arn:aws:iotfleetwise:${cdk.Aws.REGION}:${cdk.Aws.ACCOUNT_ID}:vehicle/${props.target}`; -(this.target as Vehicle) = props.target; - -const handler = new Handler(this, 'Handler', { -handler: 'campaignhandler.on_event', -}); - -const resource = new cdk.CustomResource(this, 'Resource', { -serviceToken: Provider.getOrCreate(this, handler).provider.serviceToken, -properties: { -name: this.name, -signal_catalog_arn: this.target.vehicleModel.signalCatalog.arn, -data_destination_configs: JSON.stringify(props.dataDestinationConfigs.map(s => s.toObject())), -target_arn: this.target.arn, -collection_scheme: JSON.stringify(props.collectionScheme.toObject()), -signals_to_collect: JSON.stringify(props.signals.map(s => s.toObject())), -auto_approve: props.autoApprove || false, -}, -}); -resource.node.addDependency(this.target); -} -} - #### Initializers ```python @@ -161,15 +129,12 @@ import cdk_aws_iotfleetwise cdk_aws_iotfleetwise.Campaign( scope: Construct, id: str, - campaign_s3arn: str, collection_scheme: CollectionScheme, - fw_timestream_role: str, + data_destination_configs: typing.List[DataDestinationConfig], name: str, signals: typing.List[CampaignSignal], target: Vehicle, - timestream_arn: str, - auto_approve: bool = None, - use_s3: bool = None + auto_approve: bool = None ) ``` @@ -177,15 +142,12 @@ cdk_aws_iotfleetwise.Campaign( | --- | --- | --- | | scope | constructs.Construct | *No description.* | | id | str | *No description.* | -| campaign_s3arn | str | *No description.* | | collection_scheme | CollectionScheme | *No description.* | -| fw_timestream_role | str | *No description.* | +| data_destination_configs | typing.List[DataDestinationConfig] | *No description.* | | name | str | *No description.* | | signals | typing.List[CampaignSignal] | *No description.* | | target | Vehicle | *No description.* | -| timestream_arn | str | *No description.* | | auto_approve | bool | *No description.* | -| use_s3 | bool | *No description.* | --- @@ -201,21 +163,15 @@ cdk_aws_iotfleetwise.Campaign( --- -##### `campaign_s3arn`Required - -- *Type:* str - ---- - ##### `collection_scheme`Required - *Type:* CollectionScheme --- -##### `fw_timestream_role`Required +##### `data_destination_configs`Required -- *Type:* str +- *Type:* typing.List[DataDestinationConfig] --- @@ -237,24 +193,12 @@ cdk_aws_iotfleetwise.Campaign( --- -##### `timestream_arn`Required - -- *Type:* str - ---- - ##### `auto_approve`Optional - *Type:* bool --- -##### `use_s3`Optional - -- *Type:* bool - ---- - #### Methods | **Name** | **Description** | @@ -1323,15 +1267,12 @@ fully_qualified_name: str import cdk_aws_iotfleetwise cdk_aws_iotfleetwise.CampaignProps( - campaign_s3arn: str, collection_scheme: CollectionScheme, - fw_timestream_role: str, + data_destination_configs: typing.List[DataDestinationConfig], name: str, signals: typing.List[CampaignSignal], target: Vehicle, - timestream_arn: str, - auto_approve: bool = None, - use_s3: bool = None + auto_approve: bool = None ) ``` @@ -1339,25 +1280,12 @@ cdk_aws_iotfleetwise.CampaignProps( | **Name** | **Type** | **Description** | | --- | --- | --- | -| campaign_s3arn | str | *No description.* | | collection_scheme | CollectionScheme | *No description.* | -| fw_timestream_role | str | *No description.* | +| data_destination_configs | typing.List[DataDestinationConfig] | *No description.* | | name | str | *No description.* | | signals | typing.List[CampaignSignal] | *No description.* | | target | Vehicle | *No description.* | -| timestream_arn | str | *No description.* | | auto_approve | bool | *No description.* | -| use_s3 | bool | *No description.* | - ---- - -##### `campaign_s3arn`Required - -```python -campaign_s3arn: str -``` - -- *Type:* str --- @@ -1371,13 +1299,13 @@ collection_scheme: CollectionScheme --- -##### `fw_timestream_role`Required +##### `data_destination_configs`Required ```python -fw_timestream_role: str +data_destination_configs: typing.List[DataDestinationConfig] ``` -- *Type:* str +- *Type:* typing.List[DataDestinationConfig] --- @@ -1411,16 +1339,6 @@ target: Vehicle --- -##### `timestream_arn`Required - -```python -timestream_arn: str -``` - -- *Type:* str - ---- - ##### `auto_approve`Optional ```python @@ -1431,16 +1349,6 @@ auto_approve: bool --- -##### `use_s3`Optional - -```python -use_s3: bool -``` - -- *Type:* bool - ---- - ### CanVehicleInterfaceProps #### Initializer @@ -2829,6 +2737,38 @@ def to_object() -> any +### DataDestinationConfig + +#### Initializers + +```python +import cdk_aws_iotfleetwise + +cdk_aws_iotfleetwise.DataDestinationConfig() +``` + +| **Name** | **Type** | **Description** | +| --- | --- | --- | + +--- + +#### Methods + +| **Name** | **Description** | +| --- | --- | +| to_object | *No description.* | + +--- + +##### `to_object` + +```python +def to_object() -> any +``` + + + + ### NetworkFileDefinition #### Initializers @@ -2861,6 +2801,71 @@ def to_object() -> any +### S3ConfigProperty + +#### Initializers + +```python +import cdk_aws_iotfleetwise + +cdk_aws_iotfleetwise.S3ConfigProperty( + bucket_arn: str, + data_format: str = None, + prefix: str = None, + storage_compression_format: str = None +) +``` + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| bucket_arn | str | *No description.* | +| data_format | str | *No description.* | +| prefix | str | *No description.* | +| storage_compression_format | str | *No description.* | + +--- + +##### `bucket_arn`Required + +- *Type:* str + +--- + +##### `data_format`Optional + +- *Type:* str + +--- + +##### `prefix`Optional + +- *Type:* str + +--- + +##### `storage_compression_format`Optional + +- *Type:* str + +--- + +#### Methods + +| **Name** | **Description** | +| --- | --- | +| to_object | *No description.* | + +--- + +##### `to_object` + +```python +def to_object() -> any +``` + + + + ### SignalCatalogActuator #### Initializers @@ -3274,6 +3279,55 @@ def to_object() -> any +### TimestreamConfigProperty + +#### Initializers + +```python +import cdk_aws_iotfleetwise + +cdk_aws_iotfleetwise.TimestreamConfigProperty( + execution_role_arn: str, + timestream_table_arn: str +) +``` + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| execution_role_arn | str | *No description.* | +| timestream_table_arn | str | *No description.* | + +--- + +##### `execution_role_arn`Required + +- *Type:* str + +--- + +##### `timestream_table_arn`Required + +- *Type:* str + +--- + +#### Methods + +| **Name** | **Description** | +| --- | --- | +| to_object | *No description.* | + +--- + +##### `to_object` + +```python +def to_object() -> any +``` + + + + ### VehicleInterface #### Initializers diff --git a/doc/api-typescript.md b/doc/api-typescript.md index 84a118b..b6388cc 100644 --- a/doc/api-typescript.md +++ b/doc/api-typescript.md @@ -129,38 +129,6 @@ This code is licensed under the MIT-0 License. See the LICENSE file. ### Campaign -export class Campaign extends Construct { readonly name: string = ''; - -readonly arn: string = ''; -readonly target: Vehicle = ({} as Vehicle); - -constructor(scope: Construct, id: string, props: CampaignProps) { -super(scope, id); - -(this.name as string) = props.name; -this.arn = `arn:aws:iotfleetwise:${cdk.Aws.REGION}:${cdk.Aws.ACCOUNT_ID}:vehicle/${props.target}`; -(this.target as Vehicle) = props.target; - -const handler = new Handler(this, 'Handler', { -handler: 'campaignhandler.on_event', -}); - -const resource = new cdk.CustomResource(this, 'Resource', { -serviceToken: Provider.getOrCreate(this, handler).provider.serviceToken, -properties: { - name: this.name, - signal_catalog_arn: this.target.vehicleModel.signalCatalog.arn, - data_destination_configs: JSON.stringify(props.dataDestinationConfigs.map(s => s.toObject())), - target_arn: this.target.arn, - collection_scheme: JSON.stringify(props.collectionScheme.toObject()), - signals_to_collect: JSON.stringify(props.signals.map(s => s.toObject())), - auto_approve: props.autoApprove || false, -}, -}); -resource.node.addDependency(this.target); -} -} - #### Initializers ```typescript @@ -1034,25 +1002,12 @@ const campaignProps: CampaignProps = { ... } | **Name** | **Type** | **Description** | | --- | --- | --- | -| campaignS3arn | string | *No description.* | | collectionScheme | CollectionScheme | *No description.* | -| fwTimestreamRole | string | *No description.* | +| dataDestinationConfigs | DataDestinationConfig[] | *No description.* | | name | string | *No description.* | | signals | CampaignSignal[] | *No description.* | | target | Vehicle | *No description.* | -| timestreamArn | string | *No description.* | | autoApprove | boolean | *No description.* | -| useS3 | boolean | *No description.* | - ---- - -##### `campaignS3arn`Required - -```typescript -public readonly campaignS3arn: string; -``` - -- *Type:* string --- @@ -1066,13 +1021,13 @@ public readonly collectionScheme: CollectionScheme; --- -##### `fwTimestreamRole`Required +##### `dataDestinationConfigs`Required ```typescript -public readonly fwTimestreamRole: string; +public readonly dataDestinationConfigs: DataDestinationConfig[]; ``` -- *Type:* string +- *Type:* DataDestinationConfig[] --- @@ -1106,16 +1061,6 @@ public readonly target: Vehicle; --- -##### `timestreamArn`Required - -```typescript -public readonly timestreamArn: string; -``` - -- *Type:* string - ---- - ##### `autoApprove`Optional ```typescript @@ -1126,16 +1071,6 @@ public readonly autoApprove: boolean; --- -##### `useS3`Optional - -```typescript -public readonly useS3: boolean; -``` - -- *Type:* boolean - ---- - ### CanVehicleInterfaceProps #### Initializer @@ -2339,6 +2274,38 @@ public toObject(): object +### DataDestinationConfig + +#### Initializers + +```typescript +import { DataDestinationConfig } from 'cdk-aws-iotfleetwise' + +new DataDestinationConfig() +``` + +| **Name** | **Type** | **Description** | +| --- | --- | --- | + +--- + +#### Methods + +| **Name** | **Description** | +| --- | --- | +| toObject | *No description.* | + +--- + +##### `toObject` + +```typescript +public toObject(): object +``` + + + + ### NetworkFileDefinition #### Initializers @@ -2371,6 +2338,66 @@ public toObject(): object +### S3ConfigProperty + +#### Initializers + +```typescript +import { S3ConfigProperty } from 'cdk-aws-iotfleetwise' + +new S3ConfigProperty(bucketArn: string, dataFormat?: string, prefix?: string, storageCompressionFormat?: string) +``` + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| bucketArn | string | *No description.* | +| dataFormat | string | *No description.* | +| prefix | string | *No description.* | +| storageCompressionFormat | string | *No description.* | + +--- + +##### `bucketArn`Required + +- *Type:* string + +--- + +##### `dataFormat`Optional + +- *Type:* string + +--- + +##### `prefix`Optional + +- *Type:* string + +--- + +##### `storageCompressionFormat`Optional + +- *Type:* string + +--- + +#### Methods + +| **Name** | **Description** | +| --- | --- | +| toObject | *No description.* | + +--- + +##### `toObject` + +```typescript +public toObject(): object +``` + + + + ### SignalCatalogActuator #### Initializers @@ -2598,6 +2625,52 @@ public toObject(): object +### TimestreamConfigProperty + +#### Initializers + +```typescript +import { TimestreamConfigProperty } from 'cdk-aws-iotfleetwise' + +new TimestreamConfigProperty(executionRoleArn: string, timestreamTableArn: string) +``` + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| executionRoleArn | string | *No description.* | +| timestreamTableArn | string | *No description.* | + +--- + +##### `executionRoleArn`Required + +- *Type:* string + +--- + +##### `timestreamTableArn`Required + +- *Type:* string + +--- + +#### Methods + +| **Name** | **Description** | +| --- | --- | +| toObject | *No description.* | + +--- + +##### `toObject` + +```typescript +public toObject(): object +``` + + + + ### VehicleInterface #### Initializers diff --git a/src/campaign.ts b/src/campaign.ts index 1af85e9..1994aea 100644 --- a/src/campaign.ts +++ b/src/campaign.ts @@ -49,7 +49,7 @@ export class CampaignSignal { } } -/* + export class DataDestinationConfig { protected destinationConfig: object; @@ -100,7 +100,6 @@ export class TimestreamConfigProperty extends DataDestinationConfig { }; } - export interface CampaignProps { readonly name: string; readonly target: Vehicle; @@ -109,23 +108,6 @@ export interface CampaignProps { readonly autoApprove?: boolean; readonly dataDestinationConfigs: DataDestinationConfig[]; } -*/ - - -export interface CampaignProps { - readonly name: string; - readonly target: Vehicle; - readonly collectionScheme: CollectionScheme; - readonly signals: CampaignSignal[]; - readonly autoApprove?: boolean; - readonly useS3?: boolean; - readonly campaignS3arn: string; - readonly timestreamArn: string; - readonly fwTimestreamRole: string; -} - - -/** export class Campaign extends Construct { readonly name: string = ''; @@ -158,40 +140,3 @@ export class Campaign extends Construct { resource.node.addDependency(this.target); } } -*/ - - -export class Campaign extends Construct { - readonly name: string = ''; - readonly arn: string = ''; - readonly target: Vehicle = ({} as Vehicle); - - constructor(scope: Construct, id: string, props: CampaignProps) { - super(scope, id); - - (this.name as string) = props.name; - this.arn = `arn:aws:iotfleetwise:${cdk.Aws.REGION}:${cdk.Aws.ACCOUNT_ID}:vehicle/${props.target}`; - (this.target as Vehicle) = props.target; - - const handler = new Handler(this, 'Handler', { - handler: 'campaignhandler.on_event', - }); - - const resource = new cdk.CustomResource(this, 'Resource', { - serviceToken: Provider.getOrCreate(this, handler).provider.serviceToken, - properties: { - name: this.name, - signal_catalog_arn: this.target.vehicleModel.signalCatalog.arn, - target_arn: this.target.arn, - collection_scheme: JSON.stringify(props.collectionScheme.toObject()), - signals_to_collect: JSON.stringify(props.signals.map(s => s.toObject())), - auto_approve: props.autoApprove || false, - useS3: props.useS3 || false, - campaign_s3_arn: props.campaignS3arn, - timestream_arn: props.timestreamArn, - fw_timestream_role: props.fwTimestreamRole, - }, - }); - resource.node.addDependency(this.target); - } -} diff --git a/src/handlers/campaignhandler.py b/src/handlers/campaignhandler.py index 510308e..3ac0e24 100644 --- a/src/handlers/campaignhandler.py +++ b/src/handlers/campaignhandler.py @@ -20,49 +20,17 @@ def on_create(event): props = event["ResourceProperties"] logger.info(f"create new resource with props {props}") client=boto3.client('iotfleetwise') - - if props['useS3'] == 'true': - campaignS3arn = props['campaign_s3_arn'] - response = client.create_campaign( - name = props['name'], - signalCatalogArn = props['signal_catalog_arn'], - targetArn = props['target_arn'], - collectionScheme = json.loads(props['collection_scheme']), - signalsToCollect = json.loads(props['signals_to_collect']), - dataDestinationConfigs=[ - { - 's3Config': { - 'bucketArn': campaignS3arn, - 'dataFormat': 'JSON' - } - } - ] - ) - logger.info(f"create_campaign response {response}") - - if props['useS3'] == 'false': - - timestream_arn = props['timestream_arn'] - fw_timestream_role = props['fw_timestream_role'] - - response = client.create_campaign( + response = client.create_campaign( name = props['name'], signalCatalogArn = props['signal_catalog_arn'], targetArn = props['target_arn'], collectionScheme = json.loads(props['collection_scheme']), signalsToCollect = json.loads(props['signals_to_collect']), - dataDestinationConfigs=[ - { - 'timestreamConfig': { - 'timestreamTableArn': timestream_arn, - 'executionRoleArn': fw_timestream_role, - } - } - ] - ) - logger.info(f"create_campaign response {response}") + dataDestinationConfigs=json.loads(props['data_destination_configs']) + ) + logger.info(f"create_campaign response {response}") if props['auto_approve'] == 'true': retry_count = 10; diff --git a/src/integ.dbc.ts b/src/integ.dbc.ts index e7bf63e..98993da 100644 --- a/src/integ.dbc.ts +++ b/src/integ.dbc.ts @@ -20,43 +20,50 @@ export class IntegTesting { const stack = new cdk.Stack(app, 'integ-stack', { env }); - const databaseName = 'FleetWise'; - const tableName = 'FleetWise'; + const use_s3 = stack.node.tryGetContext('use_s3'); - const database = new ts.CfnDatabase(stack, 'Database', { - databaseName, - }); - - const table = new ts.CfnTable(stack, 'Table', { - databaseName, - tableName, - }); + if (use_s3 == 'true') { + // add campaign s3 bucket + const s3bucket = new s3.Bucket(stack, 'S3Bucket', { + encryption: s3.BucketEncryption.S3_MANAGED, + removalPolicy: cdk.RemovalPolicy.RETAIN, + }); + // add s3 bucket policy + + s3bucket.addToResourcePolicy( + new iam.PolicyStatement({ + effect: iam.Effect.ALLOW, + principals: [new iam.ServicePrincipal('iotfleetwise.amazonaws.com')], + actions: ['s3:Get*', 's3:Put*'], + resources: [`${s3bucket.bucketArn}/*`], + }), + ); + + s3bucket.policy?.document.addStatements( + new iam.PolicyStatement({ + effect: iam.Effect.ALLOW, + principals: [new iam.ServicePrincipal('iotfleetwise.amazonaws.com')], + actions: ['s3:List*'], + resources: [s3bucket.bucketArn], + }), + ); + + } else { + const databaseName = 'FleetWise'; + const tableName = 'FleetWise'; + + const database = new ts.CfnDatabase(stack, 'Database', { + databaseName, + }); - table.node.addDependency(database); + const table = new ts.CfnTable(stack, 'Table', { + databaseName, + tableName, + }); + table.node.addDependency(database); - // add campaign s3 bucket - const s3bucket = new s3.Bucket(stack, 'S3Bucket', { - encryption: s3.BucketEncryption.S3_MANAGED, - removalPolicy: cdk.RemovalPolicy.RETAIN, - }); + } - // add s3 bucket policy - - s3bucket.addToResourcePolicy( - new iam.PolicyStatement({ - effect: iam.Effect.ALLOW, - principals: [new iam.ServicePrincipal('iotfleetwise.amazonaws.com')], - actions: ['s3:Get*', 's3:Put*'], - resources: [`${s3bucket.bucketArn}/*`], - })); - - s3bucket.policy?.document.addStatements( - new iam.PolicyStatement({ - effect: iam.Effect.ALLOW, - principals: [new iam.ServicePrincipal('iotfleetwise.amazonaws.com')], - actions: ['s3:List*'], - resources: [s3bucket.bucketArn], - })); const canDbc = fs.readFileSync(path.join(__dirname, '/../hscan.dbc'), 'utf8'); diff --git a/src/integ.default.ts b/src/integ.default.ts index b377275..161c139 100644 --- a/src/integ.default.ts +++ b/src/integ.default.ts @@ -20,54 +20,8 @@ export class IntegTesting { const stack = new cdk.Stack(app, 'integ-stack', { env }); - const databaseName = 'FleetWise'; - const tableName = 'FleetWise'; - - const database = new ts.CfnDatabase(stack, 'Database', { - databaseName, - }); - - const table = new ts.CfnTable(stack, 'Table', { - databaseName, - tableName, - }); - - table.node.addDependency(database); - const use_s3 = stack.node.tryGetContext('use_s3'); - // Fleetwise timestream role - const fw_timestream_role = new iam.Role(stack, 'iotfleetwiseRole', { - assumedBy: new iam.ServicePrincipal('iotfleetwise.amazonaws.com'), - managedPolicies: [ - iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonTimestreamFullAccess'), - ], - }); - - // add campaign s3 bucket - const s3bucket = new s3.Bucket(stack, 'S3Bucket', { - encryption: s3.BucketEncryption.S3_MANAGED, - removalPolicy: cdk.RemovalPolicy.RETAIN, - }); - - // add s3 bucket policy - - s3bucket.addToResourcePolicy( - new iam.PolicyStatement({ - effect: iam.Effect.ALLOW, - principals: [new iam.ServicePrincipal('iotfleetwise.amazonaws.com')], - actions: ['s3:Get*', 's3:Put*'], - resources: [`${s3bucket.bucketArn}/*`], - })); - - s3bucket.policy?.document.addStatements( - new iam.PolicyStatement({ - effect: iam.Effect.ALLOW, - principals: [new iam.ServicePrincipal('iotfleetwise.amazonaws.com')], - actions: ['s3:List*'], - resources: [s3bucket.bucketArn], - })); - const signalCatalog = new ifw.SignalCatalog(stack, 'SignalCatalog', { description: 'my signal catalog', nodes: [ @@ -130,25 +84,85 @@ export class IntegTesting { createIotThing: true, }); + if (use_s3 == 'true') { + // add campaign s3 bucket + const s3bucket = new s3.Bucket(stack, 'S3Bucket', { + encryption: s3.BucketEncryption.S3_MANAGED, + removalPolicy: cdk.RemovalPolicy.RETAIN, + }); + // add s3 bucket policy + + s3bucket.addToResourcePolicy( + new iam.PolicyStatement({ + effect: iam.Effect.ALLOW, + principals: [new iam.ServicePrincipal('iotfleetwise.amazonaws.com')], + actions: ['s3:Get*', 's3:Put*'], + resources: [`${s3bucket.bucketArn}/*`], + }), + ); + + s3bucket.policy?.document.addStatements( + new iam.PolicyStatement({ + effect: iam.Effect.ALLOW, + principals: [new iam.ServicePrincipal('iotfleetwise.amazonaws.com')], + actions: ['s3:List*'], + resources: [s3bucket.bucketArn], + }), + ); + + new ifw.Campaign(stack, 'Campaign1', { + name: 'FwTimeBasedCampaign1', + target: vin100, + collectionScheme: new ifw.TimeBasedCollectionScheme(cdk.Duration.seconds(10)), + signals: [ + new ifw.CampaignSignal('Vehicle.EngineTorque'), + new ifw.CampaignSignal( + 'Vehicle.ThrottlePosition', + 20, + cdk.Duration.seconds(10), + ), + ], + dataDestinationConfigs: [new ifw.S3ConfigProperty(s3bucket.bucketArn)], + autoApprove: true, + }); - new ifw.Campaign(stack, 'Campaign1', { - name: 'FwTimeBasedCampaign1', - target: vin100, - collectionScheme: new ifw.TimeBasedCollectionScheme(cdk.Duration.seconds(10)), - signals: [ - new ifw.CampaignSignal('Vehicle.EngineTorque'), - new ifw.CampaignSignal( - 'Vehicle.ThrottlePosition', - 20, - cdk.Duration.seconds(10), - ), - ], - autoApprove: true, - useS3: use_s3, - campaignS3arn: s3bucket.bucketArn, - timestreamArn: table.attrArn, - fwTimestreamRole: fw_timestream_role.roleArn, - }); + } else { + const databaseName = 'FleetWise'; + const tableName = 'FleetWise'; + + const database = new ts.CfnDatabase(stack, 'Database', { + databaseName, + }); + + const table = new ts.CfnTable(stack, 'Table', { + databaseName, + tableName, + }); + table.node.addDependency(database); + + // Fleetwise timestream role + const fw_timestream_role = new iam.Role(stack, 'iotfleetwiseRole', { + assumedBy: new iam.ServicePrincipal('iotfleetwise.amazonaws.com'), + managedPolicies: [ + iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonTimestreamFullAccess'), + ], + }); + new ifw.Campaign(stack, 'Campaign1', { + name: 'FwTimeBasedCampaign1', + target: vin100, + collectionScheme: new ifw.TimeBasedCollectionScheme(cdk.Duration.seconds(10)), + signals: [ + new ifw.CampaignSignal('Vehicle.EngineTorque'), + new ifw.CampaignSignal( + 'Vehicle.ThrottlePosition', + 20, + cdk.Duration.seconds(10), + ), + ], + dataDestinationConfigs: [new ifw.TimestreamConfigProperty(fw_timestream_role.roleArn, table.attrArn )], + autoApprove: true, + }); + } new ifw.Fleet(stack, 'Fleet1', { fleetId: 'fleet1', diff --git a/src/integ.full.ts b/src/integ.full.ts index 8eddb9a..7d4ceae 100644 --- a/src/integ.full.ts +++ b/src/integ.full.ts @@ -20,55 +20,8 @@ export class IntegTesting { const stack = new cdk.Stack(app, 'integ-stack', { env }); - const databaseName = 'FleetWise'; - const tableName = 'FleetWise'; - - const database = new ts.CfnDatabase(stack, 'Database', { - databaseName, - }); - - const table = new ts.CfnTable(stack, 'Table', { - databaseName, - tableName, - }); - - table.node.addDependency(database); - const use_s3 = stack.node.tryGetContext('use_s3'); - // Fleetwise timestream role - const fw_timestream_role = new iam.Role(stack, 'iotfleetwiseRole', { - assumedBy: new iam.ServicePrincipal('iotfleetwise.amazonaws.com'), - managedPolicies: [ - iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonTimestreamFullAccess'), - ], - }); - - // add campaign s3 bucket - const s3bucket = new s3.Bucket(stack, 'S3Bucket', { - encryption: s3.BucketEncryption.S3_MANAGED, - removalPolicy: cdk.RemovalPolicy.RETAIN, - }); - - // add s3 bucket policy - - s3bucket.addToResourcePolicy( - new iam.PolicyStatement({ - effect: iam.Effect.ALLOW, - principals: [new iam.ServicePrincipal('iotfleetwise.amazonaws.com')], - actions: ['s3:Get*', 's3:Put*'], - resources: [`${s3bucket.bucketArn}/*`], - })); - - s3bucket.policy?.document.addStatements( - new iam.PolicyStatement({ - effect: iam.Effect.ALLOW, - principals: [new iam.ServicePrincipal('iotfleetwise.amazonaws.com')], - actions: ['s3:List*'], - resources: [s3bucket.bucketArn], - })); - - const signalCatalog = new ifw.SignalCatalog(stack, 'SignalCatalog', { description: 'my signal catalog', nodes: [ @@ -272,19 +225,76 @@ export class IntegTesting { instance.addUserData(userData); new cdk.CfnOutput(stack, 'Vehicle Sim ssh command', { value: `ssh -i ${keyName}.pem ubuntu@${instance.instancePublicIp}` }); - new ifw.Campaign(stack, 'Campaign', { - name: 'FwTimeBasedCampaign', - target: vin100, - collectionScheme: new ifw.TimeBasedCollectionScheme(cdk.Duration.seconds(10)), - signals: [ - new ifw.CampaignSignal('Vehicle.EngineTorque'), - ], - autoApprove: true, - useS3: use_s3, - campaignS3arn: s3bucket.bucketArn, - timestreamArn: table.attrArn, - fwTimestreamRole: fw_timestream_role.roleArn, - }); + if (use_s3 == 'true') { + // add campaign s3 bucket + const s3bucket = new s3.Bucket(stack, 'S3Bucket', { + encryption: s3.BucketEncryption.S3_MANAGED, + removalPolicy: cdk.RemovalPolicy.RETAIN, + }); + // add s3 bucket policy + + s3bucket.addToResourcePolicy( + new iam.PolicyStatement({ + effect: iam.Effect.ALLOW, + principals: [new iam.ServicePrincipal('iotfleetwise.amazonaws.com')], + actions: ['s3:Get*', 's3:Put*'], + resources: [`${s3bucket.bucketArn}/*`], + }), + ); + + s3bucket.policy?.document.addStatements( + new iam.PolicyStatement({ + effect: iam.Effect.ALLOW, + principals: [new iam.ServicePrincipal('iotfleetwise.amazonaws.com')], + actions: ['s3:List*'], + resources: [s3bucket.bucketArn], + }), + ); + + new ifw.Campaign(stack, 'Campaign', { + name: 'FwTimeBasedCampaign', + target: vin100, + collectionScheme: new ifw.TimeBasedCollectionScheme(cdk.Duration.seconds(10)), + signals: [ + new ifw.CampaignSignal('Vehicle.EngineTorque'), + ], + dataDestinationConfigs: [new ifw.S3ConfigProperty(s3bucket.bucketArn)], + autoApprove: true, + }); + + } else { + const databaseName = 'FleetWise'; + const tableName = 'FleetWise'; + + const database = new ts.CfnDatabase(stack, 'Database', { + databaseName, + }); + + const table = new ts.CfnTable(stack, 'Table', { + databaseName, + tableName, + }); + table.node.addDependency(database); + + // Fleetwise timestream role + const fw_timestream_role = new iam.Role(stack, 'iotfleetwiseRole', { + assumedBy: new iam.ServicePrincipal('iotfleetwise.amazonaws.com'), + managedPolicies: [ + iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonTimestreamFullAccess'), + ], + }); + + new ifw.Campaign(stack, 'Campaign', { + name: 'FwTimeBasedCampaign', + target: vin100, + collectionScheme: new ifw.TimeBasedCollectionScheme(cdk.Duration.seconds(10)), + signals: [ + new ifw.CampaignSignal('Vehicle.EngineTorque'), + ], + dataDestinationConfigs: [new ifw.TimestreamConfigProperty(fw_timestream_role.roleArn, table.attrArn )], + autoApprove: true, + }); + } new ifw.Fleet(stack, 'Fleet', { fleetId: 'fleet', diff --git a/test/__snapshots__/integ.snapshot.test.ts.snap b/test/__snapshots__/integ.snapshot.test.ts.snap index adef823..7bb1793 100644 --- a/test/__snapshots__/integ.snapshot.test.ts.snap +++ b/test/__snapshots__/integ.snapshot.test.ts.snap @@ -26,17 +26,27 @@ Object { ], }, "auto_approve": true, - "campaign_s3_arn": Object { - "Fn::GetAtt": Array [ - "S3Bucket07682993", - "Arn", - ], - }, "collection_scheme": "{\\"timeBasedCollectionScheme\\":{\\"periodMs\\":10000}}", - "fw_timestream_role": Object { - "Fn::GetAtt": Array [ - "iotfleetwiseRoleF64DB4C5", - "Arn", + "data_destination_configs": Object { + "Fn::Join": Array [ + "", + Array [ + "[{\\"timestreamConfig\\":{\\"executionRoleArn\\":\\"", + Object { + "Fn::GetAtt": Array [ + "iotfleetwiseRoleF64DB4C5", + "Arn", + ], + }, + "\\",\\"timestreamTableArn\\":\\"", + Object { + "Fn::GetAtt": Array [ + "Table", + "Arn", + ], + }, + "\\"}}]", + ], ], }, "name": "FwTimeBasedCampaign1", @@ -73,13 +83,6 @@ Object { ], ], }, - "timestream_arn": Object { - "Fn::GetAtt": Array [ - "Table", - "Arn", - ], - }, - "useS3": false, }, "Type": "AWS::CloudFormation::CustomResource", "UpdateReplacePolicy": "Delete", @@ -360,72 +363,6 @@ Object { "Type": "AWS::CloudFormation::CustomResource", "UpdateReplacePolicy": "Delete", }, - "S3Bucket07682993": Object { - "DeletionPolicy": "Retain", - "Properties": Object { - "BucketEncryption": Object { - "ServerSideEncryptionConfiguration": Array [ - Object { - "ServerSideEncryptionByDefault": Object { - "SSEAlgorithm": "AES256", - }, - }, - ], - }, - }, - "Type": "AWS::S3::Bucket", - "UpdateReplacePolicy": "Retain", - }, - "S3BucketPolicyF560589A": Object { - "Properties": Object { - "Bucket": Object { - "Ref": "S3Bucket07682993", - }, - "PolicyDocument": Object { - "Statement": Array [ - Object { - "Action": Array [ - "s3:Get*", - "s3:Put*", - ], - "Effect": "Allow", - "Principal": Object { - "Service": "iotfleetwise.amazonaws.com", - }, - "Resource": Object { - "Fn::Join": Array [ - "", - Array [ - Object { - "Fn::GetAtt": Array [ - "S3Bucket07682993", - "Arn", - ], - }, - "/*", - ], - ], - }, - }, - Object { - "Action": "s3:List*", - "Effect": "Allow", - "Principal": Object { - "Service": "iotfleetwise.amazonaws.com", - }, - "Resource": Object { - "Fn::GetAtt": Array [ - "S3Bucket07682993", - "Arn", - ], - }, - }, - ], - "Version": "2012-10-17", - }, - }, - "Type": "AWS::S3::BucketPolicy", - }, "SignalCatalogCatalogResourceFC71CDF4": Object { "DeletionPolicy": "Delete", "DependsOn": Array [ @@ -532,7 +469,7 @@ Object { "S3Bucket": Object { "Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-us-east-1", }, - "S3Key": "0e7c17a82f52ae33fe9c4eb6036b3f8df1b35d839c94f6d01df8e7d41dc0acd7.zip", + "S3Key": "0f08abb0a97eb6b6b54804552c0be4dee6ec72166d583e4ecea682987ad6e3f0.zip", }, "Handler": "campaignhandler.on_event", "Layers": Array [ @@ -584,7 +521,7 @@ Object { "S3Bucket": Object { "Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-us-east-1", }, - "S3Key": "0e7c17a82f52ae33fe9c4eb6036b3f8df1b35d839c94f6d01df8e7d41dc0acd7.zip", + "S3Key": "0f08abb0a97eb6b6b54804552c0be4dee6ec72166d583e4ecea682987ad6e3f0.zip", }, "Handler": "fleethandler.on_event", "Layers": Array [ @@ -636,7 +573,7 @@ Object { "S3Bucket": Object { "Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-us-east-1", }, - "S3Key": "0e7c17a82f52ae33fe9c4eb6036b3f8df1b35d839c94f6d01df8e7d41dc0acd7.zip", + "S3Key": "0f08abb0a97eb6b6b54804552c0be4dee6ec72166d583e4ecea682987ad6e3f0.zip", }, "Handler": "logginghandler.on_event", "Layers": Array [ @@ -688,7 +625,7 @@ Object { "S3Bucket": Object { "Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-us-east-1", }, - "S3Key": "0e7c17a82f52ae33fe9c4eb6036b3f8df1b35d839c94f6d01df8e7d41dc0acd7.zip", + "S3Key": "0f08abb0a97eb6b6b54804552c0be4dee6ec72166d583e4ecea682987ad6e3f0.zip", }, "Handler": "servicehandler.is_complete", "Layers": Array [ @@ -740,7 +677,7 @@ Object { "S3Bucket": Object { "Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-us-east-1", }, - "S3Key": "0e7c17a82f52ae33fe9c4eb6036b3f8df1b35d839c94f6d01df8e7d41dc0acd7.zip", + "S3Key": "0f08abb0a97eb6b6b54804552c0be4dee6ec72166d583e4ecea682987ad6e3f0.zip", }, "Handler": "servicehandler.on_event", "Layers": Array [ @@ -792,7 +729,7 @@ Object { "S3Bucket": Object { "Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-us-east-1", }, - "S3Key": "0e7c17a82f52ae33fe9c4eb6036b3f8df1b35d839c94f6d01df8e7d41dc0acd7.zip", + "S3Key": "0f08abb0a97eb6b6b54804552c0be4dee6ec72166d583e4ecea682987ad6e3f0.zip", }, "Handler": "signalcataloghandler.on_event", "Layers": Array [ @@ -844,7 +781,7 @@ Object { "S3Bucket": Object { "Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-us-east-1", }, - "S3Key": "0e7c17a82f52ae33fe9c4eb6036b3f8df1b35d839c94f6d01df8e7d41dc0acd7.zip", + "S3Key": "0f08abb0a97eb6b6b54804552c0be4dee6ec72166d583e4ecea682987ad6e3f0.zip", }, "Handler": "vehiclehandler.on_event", "Layers": Array [ @@ -896,7 +833,7 @@ Object { "S3Bucket": Object { "Fn::Sub": "cdk-hnb659fds-assets-\${AWS::AccountId}-us-east-1", }, - "S3Key": "0e7c17a82f52ae33fe9c4eb6036b3f8df1b35d839c94f6d01df8e7d41dc0acd7.zip", + "S3Key": "0f08abb0a97eb6b6b54804552c0be4dee6ec72166d583e4ecea682987ad6e3f0.zip", }, "Handler": "vehiclemodelhandler.on_event", "Layers": Array [