Skip to content

Commit 1f2297d

Browse files
committed
Resolve conflicts
2 parents dcab80b + 9548de9 commit 1f2297d

11 files changed

Lines changed: 113 additions & 168 deletions

File tree

.github/dependabot.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,11 @@ updates:
1212
interval: "weekly"
1313
day: "thursday"
1414
time: "18:00" #UTC
15+
open-pull-requests-limit: 20
1516
commit-message:
1617
prefix: "Upgrade: [dependabot] - "
18+
cooldown:
19+
default-days: 3
1720

1821
###################################
1922
# Poetry #########################
@@ -25,8 +28,11 @@ updates:
2528
day: "thursday"
2629
time: "20:00" #UTC
2730
versioning-strategy: increase
31+
open-pull-requests-limit: 20
2832
commit-message:
2933
prefix: "Upgrade: [dependabot] - "
34+
cooldown:
35+
default-days: 3
3036

3137
###################################
3238
# NPM workspace ##################
@@ -41,3 +47,5 @@ updates:
4147
open-pull-requests-limit: 20
4248
commit-message:
4349
prefix: "Upgrade: [dependabot] - "
50+
cooldown:
51+
default-days: 3

package-lock.json

Lines changed: 23 additions & 145 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/cdkConstructs/src/constructs/RestApiGateway/StateMachineEndpoint.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,26 @@ import {stateMachineRequestTemplate} from "./templates/stateMachineRequest.js"
66
import {stateMachine200ResponseTemplate, stateMachineErrorResponseTemplate} from "./templates/stateMachineResponses.js"
77
import {ExpressStateMachine} from "../StateMachine.js"
88

9+
/** Parameters used to create an API endpoint backed by a Step Functions Express workflow. */
910
export interface StateMachineEndpointProps {
11+
/** Parent API resource under which the state machine endpoint is added. */
1012
parentResource: IResource
13+
/** Path segment used to create the child API resource. */
1114
readonly resourceName: string
15+
/** HTTP verb bound to the Step Functions integration. */
1216
readonly method: HttpMethod
17+
/** Invocation role used by API Gateway when starting workflow executions. */
1318
restApiGatewayRole: IRole
19+
/** State machine wrapper construct providing the target workflow ARN and integration target. */
1420
stateMachine: ExpressStateMachine
1521
}
1622

23+
/** Adds an API Gateway resource/method that starts an Express Step Functions execution. */
1724
export class StateMachineEndpoint extends Construct {
25+
/** API resource created by this construct. */
1826
resource: IResource
1927

28+
/** Wires request and response mapping templates for JSON and FHIR payload flows. */
2029
public constructor(scope: Construct, id: string, props: StateMachineEndpointProps) {
2130
super(scope, id)
2231

@@ -39,21 +48,25 @@ export class StateMachineEndpoint extends Construct {
3948
},
4049
{
4150
statusCode: "400",
42-
selectionPattern: "^4\\d{2}.*",
51+
selectionPattern: String.raw`^4\d{2}.*`,
4352
responseTemplates: {
4453
"application/json": stateMachineErrorResponseTemplate("400")
4554
}
4655
},
4756
{
4857
statusCode: "500",
49-
selectionPattern: "^5\\d{2}.*",
58+
selectionPattern: String.raw`^5\d{2}.*`,
5059
responseTemplates: {
5160
"application/json": stateMachineErrorResponseTemplate("500")
5261
}
5362
}
5463
]
5564
}), {
56-
methodResponses: []
65+
methodResponses: [
66+
{statusCode: "200"},
67+
{statusCode: "400"},
68+
{statusCode: "500"}
69+
]
5770
})
5871

5972
this.resource = resource

packages/cdkConstructs/src/constructs/RestApiGateway/templates/stateMachineRequest.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
/* eslint-disable max-len */
2+
/**
3+
* @returns API Gateway request mapping template for StartExecution payloads.
4+
*/
25
export const stateMachineRequestTemplate = (stateMachineArn: string) => {
3-
return `## Velocity Template used for API Gateway request mapping template
6+
return `## Velocity Template used for API Gateway request mapping template
47
## "@@" is used here as a placeholder for '"' to avoid using escape characters.
58
69
#set($includeHeaders = true)

packages/cdkConstructs/src/constructs/RestApiGateway/templates/stateMachineResponses.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/* eslint-disable max-len */
2+
/** VTL response template that unwraps successful workflow output and forwards status and headers. */
23
export const stateMachine200ResponseTemplate = `#set($payload = $util.parseJson($input.path('$.output')))
34
#set($context.responseOverride.status = $payload.Payload.statusCode)
45
#set($allHeaders = $payload.Payload.headers)
@@ -41,7 +42,7 @@ const getOperationOutcome = (status: string) => {
4142
{
4243
code: errorMap[status].code,
4344
severity: errorMap[status].severity,
44-
diagnostics: errorMap[status],
45+
diagnostics: errorMap[status].diagnostics,
4546
details: {
4647
coding: [
4748
{
@@ -56,5 +57,8 @@ const getOperationOutcome = (status: string) => {
5657
})
5758
}
5859

60+
/**
61+
* @returns VTL response template that maps workflow failures to FHIR OperationOutcome payloads.
62+
*/
5963
export const stateMachineErrorResponseTemplate = (status: string) => `#set($context.responseOverride.header["Content-Type"] ="application/fhir+json")
6064
${getOperationOutcome(status)}`

packages/cdkConstructs/src/constructs/StateMachine.ts

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {Fn, RemovalPolicy} from "aws-cdk-lib"
1+
import {RemovalPolicy} from "aws-cdk-lib"
22
import {
33
IManagedPolicy,
44
IRole,
@@ -20,12 +20,22 @@ import {
2020
} from "aws-cdk-lib/aws-stepfunctions"
2121
import {Construct} from "constructs"
2222
import {CfnDeliveryStream} from "aws-cdk-lib/aws-kinesisfirehose"
23+
import {ACCOUNT_RESOURCES, LAMBDA_RESOURCES} from "../constants"
2324

25+
/**
26+
* Configuration for provisioning an Express Step Functions state machine
27+
* with logging and optional Splunk forwarding.
28+
*/
2429
export interface StateMachineProps {
30+
/** Stack name, used as prefix for resource naming and DNS records. */
2531
readonly stackName: string
32+
/** Friendly state machine name used for both AWS resource and log naming. */
2633
readonly stateMachineName: string
34+
/** Workflow definition chain rendered as the state machine definition body. */
2735
readonly definition: IChainable
36+
/** Extra managed policies merged into the execution role when required. */
2837
readonly additionalPolicies?: Array<IManagedPolicy>
38+
/** Retention period applied to the workflow CloudWatch log group. */
2939
readonly logRetentionInDays: number
3040
/**
3141
* Optional KMS key for encrypting CloudWatch Logs.
@@ -54,21 +64,40 @@ export interface StateMachineProps {
5464
readonly addSplunkSubscriptionFilter?: boolean
5565
}
5666

67+
/** Creates an Express Step Functions workflow with CloudWatch logging and invoke permissions. */
5768
export class ExpressStateMachine extends Construct {
69+
/** Managed policy that grants permission to start this workflow. */
5870
public readonly executionPolicy: ManagedPolicy
71+
72+
/** Created Step Functions state machine resource. */
5973
public readonly stateMachine: StateMachine
6074

75+
/**
76+
* Provisions an Express Step Functions workflow with logging, tracing, and invoke permissions.
77+
* @example
78+
* ```ts
79+
* const sm = new ExpressStateMachine(this, "MyWorkflow", {
80+
* stackName: "my-service",
81+
* stateMachineName: "my-service-workflow",
82+
* definition: new Pass(this, "Start"),
83+
* logRetentionInDays: 30,
84+
* additionalPolicies: [myLambdaInvokePolicy]
85+
* })
86+
* // Attach the generated execution policy to an API Gateway role
87+
* apiGatewayRole.addManagedPolicy(sm.executionPolicy)
88+
* ```
89+
*/
6190
public constructor(scope: Construct, id: string, props: StateMachineProps) {
6291
super(scope, id)
6392

6493
const {
6594
cloudWatchLogsKmsKey = Key.fromKeyArn(
66-
this, "CloudWatchLogsKmsKey", Fn.importValue("account-resources:CloudwatchLogsKmsKeyArn")),
95+
this, "CloudWatchLogsKmsKey", ACCOUNT_RESOURCES.CloudwatchLogsKmsKeyArn),
6796
cloudwatchEncryptionKMSPolicy = ManagedPolicy.fromManagedPolicyArn(
68-
this, "cloudwatchEncryptionKMSPolicy", Fn.importValue("account-resources:CloudwatchEncryptionKMSPolicyArn")),
97+
this, "cloudwatchEncryptionKMSPolicy", ACCOUNT_RESOURCES.CloudwatchEncryptionKMSPolicyArn),
6998
splunkDeliveryStream,
7099
splunkSubscriptionFilterRole = Role.fromRoleArn(
71-
this, "splunkSubscriptionFilterRole", Fn.importValue("lambda-resources:SplunkSubscriptionFilterRole")),
100+
this, "splunkSubscriptionFilterRole", LAMBDA_RESOURCES.SplunkSubscriptionFilterRole),
72101
addSplunkSubscriptionFilter = true
73102
} = props
74103

@@ -90,16 +119,16 @@ export class ExpressStateMachine extends Construct {
90119

91120
if (addSplunkSubscriptionFilter) {
92121
if (splunkDeliveryStream) {
93-
new CfnSubscriptionFilter(this, "LambdaLogsSplunkSubscriptionFilter", {
122+
new CfnSubscriptionFilter(this, "StateMachineLogsSplunkSubscriptionFilter", {
94123
destinationArn: splunkDeliveryStream.attrArn,
95124
filterPattern: "",
96125
logGroupName: logGroup.logGroupName,
97126
roleArn: splunkSubscriptionFilterRole.roleArn
98127
})
99128
} else {
100129
const splunkDeliveryStreamImport = Stream.fromStreamArn(
101-
this, "SplunkDeliveryStream", Fn.importValue("lambda-resources:SplunkDeliveryStream"))
102-
new CfnSubscriptionFilter(this, "LambdaLogsSplunkSubscriptionFilter", {
130+
this, "SplunkDeliveryStream", LAMBDA_RESOURCES.SplunkDeliveryStream)
131+
new CfnSubscriptionFilter(this, "StateMachineLogsSplunkSubscriptionFilter", {
103132
destinationArn: splunkDeliveryStreamImport.streamArn,
104133
filterPattern: "",
105134
logGroupName: logGroup.logGroupName,
@@ -118,7 +147,7 @@ export class ExpressStateMachine extends Construct {
118147
],
119148
resources: [
120149
logGroup.logGroupArn,
121-
`${logGroup.logGroupArn}:log-stream`
150+
`${logGroup.logGroupArn}:log-stream:*`
122151
]
123152
}),
124153
new PolicyStatement({

packages/cdkConstructs/src/constructs/StateMachine/CatchAllErrorPass.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {Pass} from "aws-cdk-lib/aws-stepfunctions"
22
import {Construct} from "constructs"
33

4-
const severErrorOperationOutcome = `{% $string(
4+
const errorOperationOutcome = `{% $string(
55
{
66
"ResourceType": "OperationOutcome",
77
"meta": {
@@ -26,9 +26,12 @@ const severErrorOperationOutcome = `{% $string(
2626
}
2727
) %}`
2828

29+
/** Produces a fixed 500 FHIR OperationOutcome payload for unhandled workflow failures. */
2930
export class CatchAllErrorPass extends Construct {
30-
public readonly state
31+
/** Pass state returned by this construct for chaining in state machine definitions. */
32+
public readonly state: Pass
3133

34+
/** Creates a terminal-style error response payload without exposing internal exception detail. */
3235
public constructor(scope: Construct, id: string) {
3336
super(scope, id)
3437

@@ -38,9 +41,9 @@ export class CatchAllErrorPass extends Construct {
3841
statusCode: 500,
3942
headers: {
4043
"Content-Type": "application/fhir+json",
41-
"Cache-Control": "co-cache"
44+
"Cache-Control": "no-cache"
4245
},
43-
body: severErrorOperationOutcome
46+
body: errorOperationOutcome
4447
}
4548
}
4649
})

packages/cdkConstructs/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export * from "./constructs/TypescriptLambdaFunction.js"
55
export * from "./constructs/RestApiGateway.js"
66
export * from "./constructs/RestApiGateway/accessLogFormat.js"
77
export * from "./constructs/RestApiGateway/LambdaEndpoint.js"
8+
export * from "./constructs/RestApiGateway/StateMachineEndpoint.js"
89
export * from "./constructs/PythonLambdaFunction.js"
910
export * from "./constructs/SsmParametersConstruct.js"
1011
export * from "./apps/createApp.js"

packages/cdkConstructs/tests/constructs/RestApiGateway.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ describe("RestApiGateway without mTLS", () => {
2424
statements: [
2525
new PolicyStatement({
2626
actions: ["lambda:InvokeFunction"],
27-
resources: ["*"]
27+
resources: ["arn:aws:lambda:eu-west-2:123456789012:function:test-function"]
2828
})
2929
]
3030
})
@@ -181,7 +181,7 @@ describe("RestApiGateway with CSOC logs", () => {
181181
statements: [
182182
new PolicyStatement({
183183
actions: ["lambda:InvokeFunction"],
184-
resources: ["*"]
184+
resources: ["arn:aws:lambda:eu-west-2:123456789012:function:test-function"]
185185
})
186186
]
187187
})
@@ -229,7 +229,7 @@ describe("RestApiGateway with mTLS", () => {
229229
statements: [
230230
new PolicyStatement({
231231
actions: ["lambda:InvokeFunction"],
232-
resources: ["*"]
232+
resources: ["arn:aws:lambda:eu-west-2:123456789012:function:test-function"]
233233
})
234234
]
235235
})

packages/cdkConstructs/tests/constructs/RestApiGateway/StateMachineEndpoint.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ describe("StateMachineEndpoint construct", () => {
7272
IntegrationHttpMethod: "POST",
7373
IntegrationResponses: Match.arrayWith([
7474
Match.objectLike({StatusCode: "200"}),
75-
Match.objectLike({StatusCode: "400", SelectionPattern: "^4\\d{2}.*"}),
76-
Match.objectLike({StatusCode: "500", SelectionPattern: "^5\\d{2}.*"})
75+
Match.objectLike({StatusCode: "400", SelectionPattern: String.raw`^4\d{2}.*`}),
76+
Match.objectLike({StatusCode: "500", SelectionPattern: String.raw`^5\d{2}.*`})
7777
])
7878
})
7979
})

0 commit comments

Comments
 (0)