Skip to content

Commit

Permalink
Handle xfn->Lambda context injection when Payload is used without $
Browse files Browse the repository at this point in the history
  • Loading branch information
lym953 committed Sep 18, 2024
1 parent dc1cc05 commit d14b973
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 5 deletions.
50 changes: 50 additions & 0 deletions src/commands/stepfunctions/__tests__/helpers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
StepType,
injectContextForStepFunctions,
shouldUpdateStepForStepFunctionContextInjection,
PayloadObject,
} from '../helpers'

import {describeStateMachineFixture} from './fixtures/aws-resources'
Expand Down Expand Up @@ -69,6 +70,55 @@ describe('stepfunctions command helpers tests', () => {
expect(injectContextForLambdaFunctions(step, context, 'Lambda Invoke')).toBeFalsy()
})

test('already injected Execution and State into Payload', () => {
const step: StepType = {
Type: 'Task',
Resource: 'arn:aws:states:::lambda:invoke',
Parameters: {
FunctionName: 'arn:aws:lambda:sa-east-1:425362991234:function:unit-test-lambda-function',
Payload: {
'Execution.$': '$$.Execution',
'State.$': '$$.State',
'StateMachine.$': '$$.StateMachine',
},
},
End: true,
}
expect(injectContextForLambdaFunctions(step, context, 'Lambda Invoke')).toBeFalsy()
})

test('custom State field in Payload', () => {
const step: StepType = {
Type: 'Task',
Resource: 'arn:aws:states:::lambda:invoke',
Parameters: {
FunctionName: 'arn:aws:lambda:sa-east-1:425362991234:function:unit-test-lambda-function',
Payload: {
State: {Name: 'Lambda Invoke'},
},
},
End: true,
}
expect(injectContextForLambdaFunctions(step, context, 'Lambda Invoke')).toBeFalsy()
})

test('no Execution, State, or StateMachine field in Payload', () => {
const step: StepType = {
Type: 'Task',
Resource: 'arn:aws:states:::lambda:invoke',
Parameters: {
FunctionName: 'arn:aws:lambda:sa-east-1:425362991234:function:unit-test-lambda-function',
Payload: {},
},
End: true,
}
expect(injectContextForLambdaFunctions(step, context, 'Lambda Invoke')).toBeTruthy()
const payload = step.Parameters?.['Payload'] as PayloadObject
expect(payload['Execution.$']).toEqual('$$.Execution')
expect(payload['State.$']).toEqual('$$.State')
expect(payload['StateMachine.$']).toEqual('$$.StateMachine')
})

test('default payload field of $', () => {
const step: StepType = {
Type: 'Task',
Expand Down
49 changes: 44 additions & 5 deletions src/commands/stepfunctions/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,9 +193,18 @@ export type StepType = {
End?: boolean
}

export type PayloadObject = {
'Execution.$'?: any
Execution?: any
'State.$'?: any
State?: any
'StateMachine.$'?: any
StateMachine?: any
}

export type ParametersType = {
'Payload.$'?: string
Payload?: string
Payload?: string | PayloadObject
FunctionName?: string
StateMachineArn?: string
TableName?: string
Expand Down Expand Up @@ -237,13 +246,43 @@ check out https://docs.datadoghq.com/serverless/step_functions/troubleshooting/\
return true
}

// payload is not a JSON object
if (step.Parameters.hasOwnProperty('Payload') && typeof step.Parameters['Payload'] !== 'object') {
context.stdout.write(`[Warn] Step ${stepName}'s Payload field is not a JSON object. Step Functions Context Object \
if (step.Parameters.hasOwnProperty('Payload')) {
if (typeof step.Parameters['Payload'] !== 'object') {
// payload is not a JSON object
context.stdout
.write(`[Warn] Step ${stepName}'s Payload field is not a JSON object. Step Functions Context Object \
injection skipped. Your Step Functions trace will not be merged with downstream Lambda traces. To manually \
merge these traces, check out https://docs.datadoghq.com/serverless/step_functions/troubleshooting/\n`)

return false
return false
} else {
const payload = step.Parameters.Payload
if (payload['Execution.$'] === '$$.Execution' && payload['State.$'] === '$$.State') {
context.stdout.write(`Step ${stepName}: Context injection is already set up. Skipping context injection.\n`)

return false
} else if (
payload.hasOwnProperty('Execution.$') ||
payload.hasOwnProperty('Execution') ||
payload.hasOwnProperty('State.$') ||
payload.hasOwnProperty('State') ||
payload.hasOwnProperty('StateMachine.$') ||
payload.hasOwnProperty('StateMachine')
) {
context.stdout
.write(`[Warn] Step ${stepName} may be using custom Execution, State or StateMachine field. Step Functions Context Object \
injection skipped. Your Step Functions trace will not be merged with downstream Lambda traces. To manually \
merge these traces, check out https://docs.datadoghq.com/serverless/step_functions/troubleshooting/\n`)

return false
} else {
payload['Execution.$'] = '$$.Execution'
payload['State.$'] = '$$.State'
payload['StateMachine.$'] = '$$.StateMachine'

return true
}
}
}

// default payload
Expand Down

0 comments on commit d14b973

Please sign in to comment.