konokenj.cdk-api-mcp-server 0.31.0__py3-none-any.whl → 0.33.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of konokenj.cdk-api-mcp-server might be problematic. Click here for more details.

Files changed (40) hide show
  1. cdk_api_mcp_server/__about__.py +1 -1
  2. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2/integ.api-dualstack.ts +3 -4
  3. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2/integ.api.ts +2 -4
  4. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2/integ.stage.ts +7 -20
  5. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2-authorizers/integ.iam.ts +34 -38
  6. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-apigatewayv2-integrations/integ.sqs.ts +58 -71
  7. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-cloudfront/README.md +292 -1
  8. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-cloudwatch/README.md +71 -0
  9. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-cloudwatch/integ.alarm-and-dashboard.ts +12 -0
  10. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-cloudwatch/integ.dashboard-with-metric-id-and-visible.ts +70 -0
  11. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-codebuild/README.md +67 -3
  12. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-codebuild/integ.project-s3-cache.ts +71 -0
  13. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecr-assets/integ.assets-docker.ts +6 -0
  14. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/integ.availability-zone-rebalancing.ts +14 -4
  15. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/integ.enable-execute-command.ts +35 -29
  16. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/integ.exec-command.ts +16 -22
  17. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/integ.lb-awsvpc-nw.ts +26 -16
  18. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-ecs/integ.pseudo-terminal.ts +18 -8
  19. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-events/integ.api-destination.ts +42 -0
  20. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-events-targets/README.md +7 -2
  21. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-iam/integ.custom-permissions-boundary-aspect.ts +50 -0
  22. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-kinesisfirehose/README.md +3 -0
  23. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-kinesisfirehose/integ.s3-bucket.lit.ts +1 -0
  24. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-lambda/integ.lambda-policy-with-token-resolution.ts +46 -0
  25. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-rds/README.md +19 -0
  26. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-rds/integ.cluster-lookup.ts +100 -0
  27. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-route53-targets/integ.elastic-beanstalk-hostedzoneid.ts +1 -1
  28. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-stepfunctions-tasks/integ.invoke-jsonata.ts +87 -80
  29. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-stepfunctions-tasks/integ.invoke.ts +87 -69
  30. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-stepfunctions-tasks/integ.start-job-run.ts +96 -43
  31. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-synthetics/README.md +40 -0
  32. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-synthetics/integ.canary-resources-to-replicate-tags.ts +36 -0
  33. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/aws-synthetics/integ.canary-retry.ts +32 -0
  34. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/cx-api/FEATURE_FLAGS.md +29 -0
  35. cdk_api_mcp_server/resources/aws-cdk/constructs/aws-cdk-lib/pipelines/integ.pipeline-with-customsynthesizer.ts +105 -0
  36. {konokenj_cdk_api_mcp_server-0.31.0.dist-info → konokenj_cdk_api_mcp_server-0.33.0.dist-info}/METADATA +2 -2
  37. {konokenj_cdk_api_mcp_server-0.31.0.dist-info → konokenj_cdk_api_mcp_server-0.33.0.dist-info}/RECORD +40 -31
  38. {konokenj_cdk_api_mcp_server-0.31.0.dist-info → konokenj_cdk_api_mcp_server-0.33.0.dist-info}/WHEEL +0 -0
  39. {konokenj_cdk_api_mcp_server-0.31.0.dist-info → konokenj_cdk_api_mcp_server-0.33.0.dist-info}/entry_points.txt +0 -0
  40. {konokenj_cdk_api_mcp_server-0.31.0.dist-info → konokenj_cdk_api_mcp_server-0.33.0.dist-info}/licenses/LICENSE.txt +0 -0
@@ -0,0 +1,42 @@
1
+ import { App, CfnOutput, SecretValue, Stack } from 'aws-cdk-lib';
2
+ import { IntegTest } from '@aws-cdk/integ-tests-alpha';
3
+ import * as events from 'aws-cdk-lib/aws-events';
4
+ import * as secretsmanager from 'aws-cdk-lib/aws-secretsmanager';
5
+
6
+ const app = new App();
7
+
8
+ const stack = new Stack(app, 'events-api-destination-stack');
9
+
10
+ const secret = new secretsmanager.Secret(stack, 'Secret', {
11
+ secretStringValue: SecretValue.unsafePlainText('abc123'),
12
+ });
13
+
14
+ const connection = new events.Connection(stack, 'Connection', {
15
+ authorization: events.Authorization.apiKey('x-api-key', secret.secretValue),
16
+ description: 'Connection with API Key x-api-key',
17
+ connectionName: 'MyConnection',
18
+ });
19
+
20
+ const destination = new events.ApiDestination(stack, 'Destination', {
21
+ connection,
22
+ endpoint: 'https://httpbin.org/headers',
23
+ httpMethod: events.HttpMethod.GET,
24
+ apiDestinationName: 'MyDestination',
25
+ rateLimitPerSecond: 1,
26
+ description: 'Calling example.com with API key x-api-key',
27
+ });
28
+
29
+ // arn:aws:events:{region}:{account}:api-destination/{destination-name}/11111111-1111-1111-1111-111111111111
30
+ new CfnOutput(stack, 'DestinationArn', {
31
+ value: destination.apiDestinationArn,
32
+ description: 'The ARN of the API destination',
33
+ });
34
+ // arn:aws:events:{region}:{account}:api-destination/{destination-name}
35
+ new CfnOutput(stack, 'DestinationArnForPolicy', {
36
+ value: destination.apiDestinationArnForPolicy || '',
37
+ description: 'The ARN of the API destination in resource format',
38
+ });
39
+
40
+ new IntegTest(app, 'events-api-destination-integ', {
41
+ testCases: [stack],
42
+ });
@@ -369,11 +369,16 @@ const connection = events.Connection.fromEventBusArn(
369
369
  'arn:aws:secretsmanager:us-east-1:123456789012:secret:SecretName-f3gDy9',
370
370
  );
371
371
 
372
- const apiDestinationArn = 'arn:aws:events:us-east-1:123456789012:api-destination/DestinationName';
372
+ const apiDestinationArn = 'arn:aws:events:us-east-1:123456789012:api-destination/DestinationName/11111111-1111-1111-1111-111111111111';
373
+ const apiDestinationArnForPolicy = 'arn:aws:events:us-east-1:123456789012:api-destination/DestinationName';
373
374
  const destination = events.ApiDestination.fromApiDestinationAttributes(
374
375
  this,
375
376
  'Destination',
376
- { apiDestinationArn, connection },
377
+ {
378
+ apiDestinationArn,
379
+ connection,
380
+ apiDestinationArnForPolicy // optional
381
+ },
377
382
  );
378
383
 
379
384
  const rule = new events.Rule(this, 'OtherRule', {
@@ -0,0 +1,50 @@
1
+ /**
2
+ * This integration test tests the case of a customer setting a permissions boundary using a custom aspect,
3
+ * then trying to override at a more specific level using the PermissionsBoundary.of() API.
4
+ *
5
+ * Overriding should work.
6
+ */
7
+ import { App, Stack, IAspect, Aspects } from 'aws-cdk-lib';
8
+ import { IntegTest } from '@aws-cdk/integ-tests-alpha';
9
+ import { CfnRole, ManagedPolicy, PermissionsBoundary, Role, ServicePrincipal } from 'aws-cdk-lib/aws-iam';
10
+ import { IConstruct } from 'constructs';
11
+
12
+ class CustomAspect implements IAspect {
13
+ public visit(node: IConstruct): void {
14
+ if (node instanceof CfnRole) {
15
+ node.addPropertyOverride('PermissionsBoundary', 'arn:aws:iam::aws:policy/ReadOnlyAccess');
16
+ }
17
+ }
18
+ }
19
+
20
+ const app = new App({
21
+ postCliContext: {
22
+ // Force the intended behavior, from before we found this bug
23
+ '@aws-cdk/core:aspectPrioritiesMutating': false,
24
+ },
25
+ });
26
+
27
+ const stack = new Stack(app, 'integ-permissions-boundary', {
28
+ env: {
29
+ account: process.env.CDK_INTEG_ACCOUNT ?? process.env.CDK_DEFAULT_ACCOUNT,
30
+ region: process.env.CDK_INTEG_REGION ?? process.env.CDK_DEFAULT_REGION,
31
+ },
32
+ });
33
+
34
+ Aspects.of(stack).add(new CustomAspect());
35
+
36
+ new Role(stack, 'NormalRole', {
37
+ assumedBy: new ServicePrincipal('sqs.amazonaws.com'),
38
+ });
39
+
40
+ const powerRole = new Role(stack, 'PowerRole', {
41
+ assumedBy: new ServicePrincipal('sqs.amazonaws.com'),
42
+ });
43
+
44
+ PermissionsBoundary.of(powerRole).apply(ManagedPolicy.fromAwsManagedPolicyName('AdministratorAccess'));
45
+
46
+ new IntegTest(app, 'integ-test', {
47
+ testCases: [stack],
48
+ });
49
+
50
+ app.synth();
@@ -102,10 +102,13 @@ will be used for files successfully delivered to S3. `errorOutputPrefix` will be
102
102
  failed records before writing them to S3.
103
103
 
104
104
  ```ts
105
+ import { TimeZone } from 'aws-cdk-lib';
105
106
  declare const bucket: s3.Bucket;
106
107
  const s3Destination = new firehose.S3Bucket(bucket, {
107
108
  dataOutputPrefix: 'myFirehose/DeliveredYear=!{timestamp:yyyy}/anyMonth/rand=!{firehose:random-string}',
108
109
  errorOutputPrefix: 'myFirehoseFailures/!{firehose:error-output-type}/!{timestamp:yyyy}/anyMonth/!{timestamp:dd}',
110
+ // The time zone of timestamps (default UTC)
111
+ timeZone: TimeZone.ASIA_TOKYO,
109
112
  });
110
113
  ```
111
114
 
@@ -56,6 +56,7 @@ const deliveryStream = new firehose.DeliveryStream(stack, 'DeliveryStream', {
56
56
  dataOutputPrefix: 'regularPrefix',
57
57
  errorOutputPrefix: 'errorPrefix',
58
58
  fileExtension: '.log.gz',
59
+ timeZone: cdk.TimeZone.ASIA_TOKYO,
59
60
  bufferingInterval: cdk.Duration.seconds(60),
60
61
  bufferingSize: cdk.Size.mebibytes(1),
61
62
  encryptionKey: key,
@@ -0,0 +1,46 @@
1
+ import * as cdk from 'aws-cdk-lib';
2
+ import * as lambda from 'aws-cdk-lib/aws-lambda';
3
+ import * as iam from 'aws-cdk-lib/aws-iam';
4
+ import * as integ from '@aws-cdk/integ-tests-alpha';
5
+
6
+ const app = new cdk.App({
7
+ postCliContext: {
8
+ '@aws-cdk/aws-lambda:useCdkManagedLogGroup': false,
9
+ },
10
+ });
11
+ const stack = new cdk.Stack(app, 'stack');
12
+
13
+ const mappingName = 'testmapping';
14
+ const mapping = new cdk.CfnMapping(stack, 'testmapping', {
15
+ mapping: {
16
+ us: {
17
+ regionalModels:
18
+ 'arn:aws:bedrock:us-west-2::foundation-model/amazon.nova-lite-v1:0',
19
+ },
20
+ },
21
+ });
22
+ mapping.overrideLogicalId(mappingName);
23
+
24
+ const func = new lambda.Function(stack, 'test-function', {
25
+ code: new lambda.InlineCode('exports.handler = async (event) => { console.log(event); return {\'statusCode\': 200, \'body\': \'\'}; }'),
26
+ runtime: lambda.Runtime.NODEJS_20_X,
27
+ handler: 'index.handler',
28
+ });
29
+
30
+ // Literal resources in statement
31
+ func.addToRolePolicy(new iam.PolicyStatement({
32
+ actions: ['bedrock:Invoke*'],
33
+ resources: [
34
+ '*',
35
+ ],
36
+ }));
37
+
38
+ // Array token resources in statement
39
+ func.addToRolePolicy(new iam.PolicyStatement({
40
+ actions: ['bedrock:Invoke*'],
41
+ resources: cdk.Fn.split(',', cdk.Fn.findInMap(mappingName, 'us', 'regionalModels')),
42
+ }));
43
+
44
+ new integ.IntegTest(app, 'lambda-policy-with-token-resolution', {
45
+ testCases: [stack],
46
+ });
@@ -1605,6 +1605,25 @@ const dbFromLookup = rds.DatabaseInstance.fromLookup(this, 'dbFromLookup', {
1605
1605
  dbFromLookup.grantConnect(myUserRole, 'my-user-id');
1606
1606
  ```
1607
1607
 
1608
+ ## Importing existing DatabaseCluster
1609
+
1610
+ ### Lookup DatabaseCluster by clusterIdentifier
1611
+
1612
+ You can lookup an existing DatabaseCluster by its clusterIdentifier using `DatabaseCluster.fromLookup()`. This method returns an `IDatabaseCluster`.
1613
+
1614
+ Here's how `DatabaseCluster.fromLookup()` can be used:
1615
+
1616
+ ```ts
1617
+ declare const myUserRole: iam.Role;
1618
+
1619
+ const clusterFromLookup = rds.DatabaseCluster.fromLookup(this, 'ClusterFromLookup', {
1620
+ clusterIdentifier: 'my-cluster-id',
1621
+ });
1622
+
1623
+ // Grant a connection
1624
+ clusterFromLookup.grantConnect(myUserRole, 'my-user-id');
1625
+ ```
1626
+
1608
1627
  ## Limitless Database Cluster
1609
1628
 
1610
1629
  Amazon Aurora [PostgreSQL Limitless Database](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/limitless.html) provides automated horizontal scaling to process millions of write transactions per second and manages petabytes of data while maintaining the simplicity of operating inside a single database.
@@ -0,0 +1,100 @@
1
+ import { IntegTest } from '@aws-cdk/integ-tests-alpha';
2
+ import { App, CfnOutput, Stack } from 'aws-cdk-lib';
3
+ import * as cloudwatch from 'aws-cdk-lib/aws-cloudwatch';
4
+ import * as iam from 'aws-cdk-lib/aws-iam';
5
+ import * as rds from 'aws-cdk-lib/aws-rds';
6
+
7
+ const app = new App();
8
+ const clusterIdentifier = 'test-cluster-lookup';
9
+
10
+ const stackLookup = new Stack(app, 'aws-cdk-rds-cluster-lookup', {
11
+ env: {
12
+ account: process.env.CDK_INTEG_ACCOUNT ?? process.env.CDK_DEFAULT_ACCOUNT,
13
+ region: process.env.CDK_INTEG_REGION ?? process.env.CDK_DEFAULT_REGION,
14
+ },
15
+ });
16
+
17
+ // Lookup the existing cluster created by the preDeploy hook
18
+ const lookedUpCluster = rds.DatabaseCluster.fromLookup(stackLookup, 'LookedUpCluster', {
19
+ clusterIdentifier,
20
+ });
21
+
22
+ new CfnOutput(stackLookup, 'LookedUpClusterEndpoint', {
23
+ value: lookedUpCluster.clusterEndpoint.socketAddress,
24
+ });
25
+
26
+ new CfnOutput(stackLookup, 'LookedUpClusterReadEndpoint', {
27
+ value: lookedUpCluster.clusterReadEndpoint.socketAddress,
28
+ });
29
+
30
+ new CfnOutput(stackLookup, 'LookedUpClusterIdentifier', {
31
+ value: lookedUpCluster.clusterIdentifier,
32
+ });
33
+
34
+ new CfnOutput(stackLookup, 'LookedUpClusterResourceIdentifier', {
35
+ value: lookedUpCluster.clusterResourceIdentifier,
36
+ });
37
+
38
+ new CfnOutput(stackLookup, 'LookedUpClusterArn', {
39
+ value: lookedUpCluster.clusterArn,
40
+ });
41
+
42
+ new CfnOutput(stackLookup, 'SecurityGroupIds', {
43
+ value: lookedUpCluster.connections.securityGroups.map(sg => sg.securityGroupId).join(','),
44
+ });
45
+
46
+ // test grant
47
+ const dbAccessRole = new iam.Role(stackLookup, 'DbAccessRole', {
48
+ assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'),
49
+ description: 'Role for accessing the Aurora cluster via IAM authentication',
50
+ });
51
+
52
+ lookedUpCluster.grantConnect(dbAccessRole, 'admin');
53
+ lookedUpCluster.grantDataApiAccess(dbAccessRole);
54
+
55
+ // test metric
56
+ lookedUpCluster.metricDatabaseConnections().createAlarm(stackLookup, 'HighConnectionsAlarm', {
57
+ threshold: 100,
58
+ evaluationPeriods: 3,
59
+ alarmDescription: 'Database has high number of connections',
60
+ comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_THRESHOLD,
61
+ });
62
+
63
+ lookedUpCluster.metricCPUUtilization().createAlarm(stackLookup, 'HighCPUAlarm', {
64
+ threshold: 90,
65
+ evaluationPeriods: 3,
66
+ alarmDescription: 'Database CPU utilization is high',
67
+ comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_THRESHOLD,
68
+ });
69
+
70
+ lookedUpCluster.metricFreeableMemory().createAlarm(stackLookup, 'LowMemoryAlarm', {
71
+ threshold: 100 * 1024 * 1024,
72
+ evaluationPeriods: 3,
73
+ alarmDescription: 'Database is running low on memory',
74
+ comparisonOperator: cloudwatch.ComparisonOperator.LESS_THAN_THRESHOLD,
75
+ });
76
+
77
+ lookedUpCluster.metricDeadlocks().createAlarm(stackLookup, 'DeadlockAlarm', {
78
+ threshold: 5,
79
+ evaluationPeriods: 2,
80
+ alarmDescription: 'Database has deadlocks',
81
+ comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_THRESHOLD,
82
+ });
83
+
84
+ new IntegTest(app, 'integ-rds-cluster-from-lookup', {
85
+ testCases: [stackLookup],
86
+ enableLookups: true,
87
+ stackUpdateWorkflow: false,
88
+ // Create Aurora cluster before the test and delete it after
89
+ hooks: {
90
+ preDeploy: [
91
+ `aws rds create-db-cluster --db-cluster-identifier ${clusterIdentifier} --engine aurora-mysql --engine-version 8.0.mysql_aurora.3.09.0 --master-username admin --master-user-password Admin1234 --enable-http-endpoint --enable-iam-database-authentication --region us-east-1`,
92
+ `aws rds create-db-instance --db-instance-identifier ${clusterIdentifier}-instance --db-cluster-identifier ${clusterIdentifier} --engine aurora-mysql --db-instance-class db.r5.large --region us-east-1`,
93
+ `aws rds wait db-instance-available --db-instance-identifier ${clusterIdentifier}-instance --region us-east-1`,
94
+ ],
95
+ postDeploy: [
96
+ `aws rds delete-db-instance --db-instance-identifier ${clusterIdentifier}-instance --skip-final-snapshot --region us-east-1`,
97
+ `aws rds delete-db-cluster --db-cluster-identifier ${clusterIdentifier} --skip-final-snapshot --region us-east-1`,
98
+ ],
99
+ },
100
+ });
@@ -6,7 +6,7 @@ import * as targets from 'aws-cdk-lib/aws-route53-targets';
6
6
  import { IntegTest } from '@aws-cdk/integ-tests-alpha';
7
7
  import * as elasticbeanstalk from 'aws-cdk-lib/aws-elasticbeanstalk';
8
8
  import * as custom from 'aws-cdk-lib/custom-resources';
9
- import { RegionInfo } from 'aws-cdk-lib/region-info';
9
+ import { RegionInfo } from '@aws-cdk/region-info';
10
10
 
11
11
  const app = new App({
12
12
  postCliContext: {
@@ -1,112 +1,119 @@
1
- import * as path from 'path';
2
- import { IntegTest, ExpectedResult } from '@aws-cdk/integ-tests-alpha';
3
- import * as cdk from 'aws-cdk-lib';
4
- import * as apigateway from 'aws-cdk-lib/aws-apigateway';
5
- import * as events from 'aws-cdk-lib/aws-events';
1
+ import { Code, Function } from 'aws-cdk-lib/aws-lambda';
6
2
  import * as sfn from 'aws-cdk-lib/aws-stepfunctions';
7
- import * as lambda from 'aws-cdk-lib/aws-lambda-nodejs';
8
- import * as tasks from 'aws-cdk-lib/aws-stepfunctions-tasks';
9
- import { password, username } from './my-lambda-handler';
3
+ import * as cdk from 'aws-cdk-lib';
4
+ import { LambdaInvoke } from 'aws-cdk-lib/aws-stepfunctions-tasks';
5
+ import { IntegTest, ExpectedResult } from '@aws-cdk/integ-tests-alpha';
6
+ import { STANDARD_NODEJS_RUNTIME } from '../../../config';
10
7
 
11
8
  /*
12
- * Creates an API Gateway instance with a GET method and mock integration,
13
- * secured with basic auth. It then creates a matching Connection and uses it
14
- * in a state machine with a task state to invoke the endpoint.
9
+ * Creates a state machine with a task state to invoke a Lambda function
10
+ * The state machine creates a couple of Lambdas that pass results forward
11
+ * and into a Choice state that validates the output.
12
+ *
13
+ * Stack verification steps:
14
+ * The generated State Machine can be executed from the CLI (or Step Functions console)
15
+ * and runs with an execution status of `Succeeded`.
15
16
  *
16
- * Stack verification steps :
17
- * * aws stepfunctions start-execution --state-machine-arn <deployed state machine arn> : should return execution arn
18
- * * aws stepfunctions describe-execution --execution-arn <execution-arn generated before> : should return status as SUCCEEDED
17
+ * -- aws stepfunctions start-execution --state-machine-arn <state-machine-arn-from-output> provides execution arn
18
+ * -- aws stepfunctions describe-execution --execution-arn <state-machine-arn-from-output> returns a status of `Succeeded`
19
19
  */
20
20
  const app = new cdk.App({
21
21
  postCliContext: {
22
22
  '@aws-cdk/aws-lambda:useCdkManagedLogGroup': false,
23
23
  },
24
24
  });
25
- const stack = new cdk.Stack(app, 'aws-stepfunctions-tasks-http-invoke-integ');
25
+ const stack = new cdk.Stack(app, 'aws-stepfunctions-tasks-lambda-invoke-jsonata-integ');
26
26
 
27
- const authorizerHandler = new lambda.NodejsFunction(stack, 'AuthorizerHandler', {
28
- entry: path.resolve(__dirname, 'my-lambda-handler', 'index.ts'),
29
- handler: 'handler',
27
+ const submitJobLambda = new Function(stack, 'submitJobLambda', {
28
+ code: Code.fromInline(`exports.handler = async (event, context) => {
29
+ return {
30
+ statusCode: '200',
31
+ body: 'hello, world!',
32
+ ...event,
33
+ };
34
+ };`),
35
+ runtime: STANDARD_NODEJS_RUNTIME,
36
+ handler: 'index.handler',
30
37
  });
31
38
 
32
- const authorizer = new apigateway.TokenAuthorizer(stack, 'Authorizer', {
33
- handler: authorizerHandler,
34
- identitySource: 'method.request.header.Authorization',
35
- resultsCacheTtl: cdk.Duration.seconds(0),
36
- });
37
-
38
- const api = new apigateway.RestApi(stack, 'IntegRestApi');
39
-
40
- api.root.addResource('test').addMethod(
41
- 'GET',
42
- new apigateway.MockIntegration({
43
- integrationResponses: [
44
- {
45
- statusCode: '200',
46
- responseTemplates: {
47
- 'application/json': JSON.stringify({ message: 'Hello, tester!' }),
48
- },
49
- },
50
- ],
51
- passthroughBehavior: apigateway.PassthroughBehavior.NEVER,
52
- requestTemplates: {
53
- 'application/json': '{ "statusCode": 200 }',
54
- },
39
+ const submitJob = LambdaInvoke.jsonata(stack, 'Invoke Handler', {
40
+ lambdaFunction: submitJobLambda,
41
+ payload: sfn.TaskInput.fromObject({
42
+ execId: '{% $states.context.Execution.Id %}',
43
+ execInput: '{% $states.context.Execution.Input %}',
44
+ execName: '{% $states.context.Execution.Name %}',
45
+ execRoleArn: '{% $states.context.Execution.RoleArn %}',
46
+ execStartTime: '{% $states.context.Execution.StartTime %}',
47
+ stateEnteredTime: '{% $states.context.State.EnteredTime %}',
48
+ stateName: '{% $states.context.State.Name %}',
49
+ stateRetryCount: '{% $states.context.State.RetryCount %}',
50
+ stateMachineId: '{% $states.context.StateMachine.Id %}',
51
+ stateMachineName: '{% $states.context.StateMachine.Name %}',
55
52
  }),
56
- {
57
- authorizer,
58
- methodResponses: [
59
- {
60
- statusCode: '200',
61
- },
62
- ],
63
- },
64
- );
53
+ outputs: '{% $states.result.Payload %}',
54
+ });
65
55
 
66
- const connection = new events.Connection(stack, 'Connection', {
67
- authorization: events.Authorization.basic(username, cdk.SecretValue.unsafePlainText(password)),
56
+ const checkJobStateLambda = new Function(stack, 'checkJobStateLambda', {
57
+ code: Code.fromInline(`exports.handler = async function(event, context) {
58
+ const expectedFields = [
59
+ 'execId', 'execInput', 'execName', 'execRoleArn',
60
+ 'execStartTime', 'stateEnteredTime', 'stateName',
61
+ 'stateRetryCount', 'stateMachineId', 'stateMachineName',
62
+ ];
63
+ const fieldsAreSet = expectedFields.every(field => event[field] !== undefined);
64
+ return {
65
+ status: event.statusCode === '200' && fieldsAreSet ? 'SUCCEEDED' : 'FAILED'
66
+ };
67
+ };`),
68
+ runtime: STANDARD_NODEJS_RUNTIME,
69
+ handler: 'index.handler',
68
70
  });
69
71
 
70
- const httpInvokeTask = tasks.HttpInvoke.jsonata(stack, 'Invoke HTTP Endpoint', {
71
- apiRoot: api.urlForPath('/'),
72
- apiEndpoint: sfn.TaskInput.fromText('{% $states.input.apiEndpoint %}'),
73
- connection,
74
- method: sfn.TaskInput.fromText('GET'),
72
+ const checkJobState = LambdaInvoke.jsonata(stack, 'Check the job state', {
73
+ lambdaFunction: checkJobStateLambda,
75
74
  outputs: {
76
- ResponseBody: '{% $states.result.ResponseBody %}',
75
+ status: '{% $states.result.Payload.status %}',
77
76
  },
78
77
  });
79
78
 
79
+ const isComplete = sfn.Choice.jsonata(stack, 'Job Complete?');
80
+ const jobFailed = sfn.Fail.jsonata(stack, 'Job Failed', {
81
+ cause: 'Job Failed',
82
+ error: 'Received a status that was not 200',
83
+ });
84
+ const finalStatus = sfn.Pass.jsonata(stack, 'Final step');
85
+
86
+ const chain = sfn.Chain.start(submitJob)
87
+ .next(checkJobState)
88
+ .next(
89
+ isComplete
90
+ .when(sfn.Condition.jsonata("{% $states.input.status = 'FAILED' %}"), jobFailed)
91
+ .when(sfn.Condition.jsonata("{% $states.input.status = 'SUCCEEDED' %}"), finalStatus),
92
+ );
93
+
80
94
  const sm = new sfn.StateMachine(stack, 'StateMachine', {
81
- definition: httpInvokeTask,
95
+ definition: chain,
82
96
  timeout: cdk.Duration.seconds(30),
83
97
  });
84
98
 
85
- const testCase = new IntegTest(app, 'HttpInvokeTest', {
86
- testCases: [stack],
99
+ new cdk.CfnOutput(stack, 'stateMachineArn', {
100
+ value: sm.stateMachineArn,
87
101
  });
88
102
 
89
- // Start an execution
90
- const start = testCase.assertions.awsApiCall('@aws-sdk/client-sfn', 'StartExecution', {
91
- stateMachineArn: sm.stateMachineArn,
92
- input: JSON.stringify({
93
- apiEndpoint: '/test',
94
- }),
103
+ const integ = new IntegTest(app, 'IntegTest', {
104
+ testCases: [stack],
95
105
  });
96
-
97
- // describe the results of the execution
98
- const describe = testCase.assertions.awsApiCall('@aws-sdk/client-sfn', 'DescribeExecution', {
99
- executionArn: start.getAttString('executionArn'),
106
+ const res = integ.assertions.awsApiCall('@aws-sdk/client-sfn', 'StartExecution', {
107
+ stateMachineArn: sm.stateMachineArn,
100
108
  });
101
-
102
- // assert the results
103
- describe.expect(ExpectedResult.objectLike({
109
+ const executionArn = res.getAttString('executionArn');
110
+ integ.assertions.awsApiCall('@aws-sdk/client-sfn', 'DescribeExecution', {
111
+ executionArn,
112
+ }).expect(ExpectedResult.objectLike({
104
113
  status: 'SUCCEEDED',
105
- output: JSON.stringify({
106
- ResponseBody: {
107
- message: 'Hello, tester!',
108
- },
109
- }),
110
- }));
114
+ })).waitForAssertions({
115
+ totalTimeout: cdk.Duration.seconds(10),
116
+ interval: cdk.Duration.seconds(3),
117
+ });
111
118
 
112
119
  app.synth();