[英]How to get Task Token in AWS Lambda Function
我有一個 AWS Step Function 和在 Java 中實現的處理程序。
我的步驟 function 定義:
definition:
Comment: Steps for issuing a card
StartAt: RecipientFraudChecks
States:
RecipientFraudChecks:
Type: Task
Next: SaveTaskToken
Resource: arn:aws:lambda:eu-west-1:099720403855:RecipientFraudChecks
SaveTaskToken:
Type: Task
Resource: arn:aws:lambda:eu-west-1:12345678:function:SaveTaskToken
End: true
我有一個 Java 項目,所有 Lambda Function 處理程序都在那里定義:
public class SaveTaskToken implements RequestHandler<Map<String,String>, String> {
....
@Override
public String handleRequest(Map<String, String> input, final Context context) {
// do the fraud checks
System.out.println("the context is: " + gson.toJson(context));
System.out.println("input: " + gson.toJson(input));
}
我正在使用 AWS SAM 在本地運行步驟 function,並根據此觸發: https://docs.aws.amazon.com/step-functions/latest/dg/sfn-local-lambda.html#install-sam
在context
,我希望看到任務令牌,但我沒有。 日志顯示:
the context is: {
"memoryLimit": 512,
"awsRequestId": "5065a9aa-1a4a-46fe-9b58-7dc2194f92b7",
"logGroupName": "aws/lambda/SaveTaskToken",
"logStreamName": "$LATEST",
"functionName": "SaveTaskToken",
"functionVersion": "$LATEST",
"invokedFunctionArn": "",
"cognitoIdentity": {
"identityId": "",
"poolId": ""
},
"logger": {}
}
事實上,它與我在文檔中所期望的全局上下文完全不同。
我究竟做錯了什么? 如何獲得任務令牌?
編輯
我將Parameters
屬性添加到“SaveTaskToken”並將資源更改為arn:aws:states:::lambda:invoke.waitForTaskToken
並且知道我可以獲得任務令牌:
definition:
Comment: Steps for issuing a card
StartAt: RecipientFraudChecks
States:
RecipientFraudChecks:
Type: Task
Next: SaveTaskToken
Resource: arn:aws:lambda:eu-west-1:099720403855:RecipientFraudChecks
SaveTaskToken:
Type: Task
Resource: arn:aws:states:::lambda:invoke.waitForTaskToken
Parameters:
FunctionName: arn:aws:lambda:eu-west-1:12345678:function:SaveTaskToken
Payload:
taskToken
End: true
在日志中我可以看到:
the input is: {
"taskToken": "5286"
}
它引起了另一個問題 - 它覆蓋了 state 機器的輸入。 我傳入輸入:
{"giftCode": "xxx"}
在第一個 Lambda function, RecipientFraudChecks
中,我可以得到輸入。 但是,在第二個中,由於添加了Parameters
屬性,我現在無法再獲得state機器的輸入,只有任務令牌......
編輯在這里實現了答案: https://stackoverflow.com/a/66995869/1246159
{
"Comment": "Steps for issuing a card",
"StartAt": "RecipientFraudChecks",
"States": {
"RecipientFraudChecks": {
"Type": "Task",
"Next": "PauseCardIfNecessary",
"ResultPath": "$.firstLambdaOutput",
"Resource": "arn:aws:lambda:us-east-1:123456789012:function:RecipientFraudChecks"
},
"PauseCardIfNecessary": {
"Type": "Task",
"Next": "GetOrCreateClient",
"Resource": "arn:aws:states:::lambda:invoke.waitForTaskToken",
"Parameters": {
"FunctionName": "arn:aws:lambda:us-east-1:123456789012:function:PauseCardIfNecessary",
"Payload": {
"token.$": "$$.Task.Token",
"otherInput.$": "$"
}
}
},
"GetOrCreateClient": {
"Type": "Task",
"Next": "GetOrAccountClient",
"Resource": "arn:aws:lambda:us-east-1:123456789012:function:GetOrCreateClient"
},
"GetOrAccountClient": {
"Type": "Task",
"Resource": "arn:aws:lambda:us-east-1:123456789012:function:GetOrAccountClient",
"End": true
}
}
}
但我得到另一個錯誤,這里是日志:
arn: aws: states: eu-west-1: 123456789012: execution: HelloWorld5: cardIssue: {
"Type": "TaskStateExited",
"PreviousEventId": 5,
"StateExitedEventDetails": {
"Name": "RecipientFraudChecks",
"Output": "{\"inputToStep\":\"xxxx\",\"firstLambdaOutput\":\"output of recipient lambda\"}"
}
} arn: aws: states: eu-west-1: 123456789012: execution: HelloWorld5: cardIssue: {
"Type": "TaskStateEntered",
"PreviousEventId": 6,
"StateEnteredEventDetails": {
"Name": "PauseCardIfNecessary",
"Input": "{\"inputToStep\":\"xxxx\",\"firstLambdaOutput\":\"output of recipient lambda\"}"
}
} arn: aws: states: eu-west-1: 123456789012: execution: HelloWorld5: cardIssue: {
"Type": "ExecutionFailed",
"PreviousEventId": 7,
"ExecutionFailedEventDetails": {
"Error": "States.Runtime",
"Cause": "An error occurred while executing the state 'PauseCardIfNecessary' (entered at the event id #7). The value for the field 'token.$' must be a valid JSONPath expression"
}
}
任務令牌不會在 lambda 上下文中自動傳遞,它需要作為輸入傳遞。
這里的上下文不是 lambda function 的上下文,而是任務的上下文以及從上下文中獲取細節,我們可以使用$$.
在步驟 function 定義內,例如:
$$.Task.Token
$$.Execution.StartTime
示例步驟 function:
waitForTaskToken
執行另一個 lambda ,在這里,我們獲取任務令牌並將其與上一步的 output 作為輸入一起傳遞。{
"StartAt": "fist-lambda-invoke-sync",
"States": {
"fist-lambda-invoke-sync": {
"Next": "second-lambda-invoke-task-token",
"Type": "Task",
"ResultPath": "$.firstLambdaOutput",
"Resource": "arn:aws:lambda:us-east-1:11112223333:function:myfirstlambda"
},
"second-lambda-invoke-task-token": {
"End": true,
"Type": "Task",
"Resource": "arn:aws:states:::lambda:invoke.waitForTaskToken",
"Parameters": {
"FunctionName": "arn:aws:lambda:us-east-1:11112223333:function:mysecondlambda",
"Payload": {
"token.$": "$$.Task.Token",
"otherInput.$": "$"
}
}
}
}
}
輸入到步驟 function :
{
"inputToStep": "myValue"
}
第一個 Lambda 的 Output :假設它是一個字符串值“10”。 它將被附加到輸入 Json 因為"ResultPath": "$.firstLambdaOutput"
{
"inputToStep": "myValue",
"firstLambdaOutput": "10"
}
第二個 Lambda 的輸入:將在 json 下方接收作為附加任務令牌的輸入,因為"token.$": "$$.Task.Token"
和"otherInput.$": "$"
{ otherInput: { inputToStep: 'myValue', firstLambdaOutput: '10' },
token: 'This is where Task Token generated by step function will be sent' }
關於輸入,文檔 [1] 中似乎有一個簡單的解決方案:
您可以使用來自 state 機器執行的輸入,而不是在 state 機器定義中硬編碼事件負載。 以下示例使用運行 state 機器時指定的輸入作為事件負載:
"Payload.$": "$"
文檔 [2] 中還有另一個示例:
{
"StartAt":"GetManualReview",
"States":{
"GetManualReview":{
"Type":"Task",
"Resource":"arn:aws:states:::lambda:invoke.waitForTaskToken",
"Parameters":{
"FunctionName":"get-model-review-decision",
"Payload":{
"model.$":"$.new_model",
"token.$":"$$.Task.Token"
},
"Qualifier":"prod-v1"
},
"End":true
}
}
}
您可以將"model.$":"$.new_model"
更改為類似"input.$":"$"
並獲得所需的 Lambda 有效負載。
在 YAML 中轉換為以下內容:
Parameters:
Payload:
input.$: "$"
token.$: "$$.Task.Token"
[1] https://docs.aws.amazon.com/lambda/latest/dg/services-stepfunctions.html#services-stepfunctions-setup
[2] https://docs.amazonaws.cn/en_us/step-functions/latest/dg/connect-lambda.html
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.