繁体   English   中英

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

[英]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:

  • 第一个任务使用步骤 function 输入执行 Lambda。
  • 将第一个 lambda 的 output 与步骤 function 输入相附加。
  • 第二个任务使用资源waitForTaskToken执行另一个 lambda ,在这里,我们获取任务令牌并将其与上一步的 output 作为输入一起传递。
  • 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.$": "$"
        }
      }
    }
  }
}

输入到步骤 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.

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