简体   繁体   English

如何在 AWS Lambda Function 中获取任务令牌

[英]How to get Task Token in AWS Lambda Function

I have an AWS Step Function with the handlers implemented in Java.我有一个 AWS Step Function 和在 Java 中实现的处理程序。

My step function definition:我的步骤 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

I have a Java project and all the Lambda Function handlers are defined there:我有一个 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));

}

I'm running the step function locally using AWS SAM, and triggering according to this: https://docs.aws.amazon.com/step-functions/latest/dg/sfn-local-lambda.html#install-sam我正在使用 AWS SAM 在本地运行步骤 function,并根据此触发: https://docs.aws.amazon.com/step-functions/latest/dg/sfn-local-lambda.html#install-sam

Within context I would expect to see the Task Token, but I do not.context ,我希望看到任务令牌,但我没有。 Logs show:日志显示:

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": {}
}

In fact its nothing like the global Context I should expect in the docs .事实上,它与我在文档中所期望的全局上下文完全不同。

What am I doing wrong?我究竟做错了什么? How can I get the Task Token?如何获得任务令牌?

EDIT编辑

I added Parameters property to 'SaveTaskToken' and changed resource to arn:aws:states:::lambda:invoke.waitForTaskToken and know I can get the Task Token:我将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

In the logs I can see:在日志中我可以看到:

the input is: {
  "taskToken": "5286"
}

It has caused another problem - it overrides the input to the state machine.它引起了另一个问题 - 它覆盖了 state 机器的输入。 Im passing in the input:我传入输入:

{"giftCode": "xxx"}

In the first Lambda function, RecipientFraudChecks , I can get the input.在第一个 Lambda function, RecipientFraudChecks中,我可以得到输入。 However, in the second, since adding the Parameters property, I now can no longer get the input to the state machine, only the task token...但是,在第二个中,由于添加了Parameters属性,我现在无法再获得state机器的输入,只有任务令牌......

EDIT Have implemented the answer here: https://stackoverflow.com/a/66995869/1246159编辑在这里实现了答案: 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
    }
  }
}

But I get another error, here are the logs:但我得到另一个错误,这里是日志:

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"
  }
}

Task token is not automatically passed in lambda context, it needs to be passed as input.任务令牌不会在 lambda 上下文中自动传递,它需要作为输入传递。

The context here is not context of lambda function, but the context of the task and to grab details from context, we can use $$.这里的上下文不是 lambda function 的上下文,而是任务的上下文以及从上下文中获取细节,我们可以使用$$. within step function definition, Ex:在步骤 function 定义内,例如:

  • To get Task Token $$.Task.Token获取任务令牌$$.Task.Token
  • To get start time $$.Execution.StartTime获取开始时间$$.Execution.StartTime

Example Step function:示例步骤 function:

  • First Task executes a Lambda with step function input.第一个任务使用步骤 function 输入执行 Lambda。
  • Appends the output of first lambda with step function input.将第一个 lambda 的 output 与步骤 function 输入相附加。
  • Second Task executes another lambda with resource waitForTaskToken , right here, we grab the task token and pass it along with output of previous step as input.第二个任务使用资源waitForTaskToken执行另一个 lambda ,在这里,我们获取任务令牌并将其与上一步的 output 作为输入一起传递。
  • Step functions waits until it gets a SendTaskSuccess or SendTaskFailure Step 函数一直等到它获得SendTaskSuccessSendTaskFailure

在此处输入图像描述

{
  "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.$": "$"
        }
      }
    }
  }
}

Input to Step function :输入到步骤 function

{
  "inputToStep": "myValue"
}

Output of First Lambda : assuming it is a string value "10".第一个 Lambda 的 Output :假设它是一个字符串值“10”。 It will be appended to input Json because of "ResultPath": "$.firstLambdaOutput"它将被附加到输入 Json 因为"ResultPath": "$.firstLambdaOutput"

{
  "inputToStep": "myValue",
  "firstLambdaOutput": "10"
}

Input to Second Lambda : Will receive below json as input with task token appended, because of "token.$": "$$.Task.Token" and "otherInput.$": "$"第二个 Lambda 的输入:将在 json 下方接收作为附加任务令牌的输入,因为"token.$": "$$.Task.Token""otherInput.$": "$"

{ otherInput: { inputToStep: 'myValue', firstLambdaOutput: '10' },
  token: 'This is where Task Token generated by step function will be sent' } 

Regarding the input, there seems to be an easy solution in the docs [1]:关于输入,文档 [1] 中似乎有一个简单的解决方案:

Instead of hard-coding the event payload in the state machine definition, you can use the input from the state machine execution.您可以使用来自 state 机器执行的输入,而不是在 state 机器定义中硬编码事件负载。 The following example uses the input specified when you run the state machine as the event payload:以下示例使用运行 state 机器时指定的输入作为事件负载:

 "Payload.$": "$"

There is another example in the docs [2]:文档 [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
      }
   }
}

You can possibly change "model.$":"$.new_model" to something like "input.$":"$" and get the desired Lambda payload.您可以将"model.$":"$.new_model"更改为类似"input.$":"$"并获得所需的 Lambda 有效负载。

Which translates to the following in YAML:在 YAML 中转换为以下内容:

Parameters:
  Payload:
    input.$: "$"
    token.$: "$$.Task.Token"

[1] https://docs.aws.amazon.com/lambda/latest/dg/services-stepfunctions.html#services-stepfunctions-setup [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 [2] https://docs.amazonaws.cn/en_us/step-functions/latest/dg/connect-lambda.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM