5

我无法使用 EventBridge 服务将 AWS 状态机返回的值之一作为输入传递给 Lambda。

我在 AWS Step Functions 中创建了一个状态机来为我们领域中的特定问题建模。一旦状态机完成,我想从我的一个 Lambda 中执行另一个操作。为了实现这一点,我使用 EventBridge 创建了一个新规则:每当状态机完成时,它都会使用特定的 Json 输入触发我的 lambda。

我的问题是如何从状态机输出中提取属性并将它们作为 lambda 输入的属性传递。

假设我的状态机返回这个:

{
    "usefulObject":{
        "usefulProperty":"value"
    },
    "anotherProperty":"anotherValue"
}

我想在我的 lambda 中接收以下有效负载:

{
    "property":"value"
}

最初,我认为我可以使用 EventBridge 规则上的“输入转换”选项来执行此操作,例如:

  • 输入变压器路径:
{"propertyValue":"$.usefulObject.usefulProperty"}
  • 输入转换器模板:
{"property":<propertyValue>}

但是,在测试期间,我意识到事件有效负载包含的数据比我的状态机输出要多得多。实际上,状态机输出被包装在这个“事件容器”对象中,如下所示:

{
    "version": "0",
    "id": "...",
    "detail-type": "Step Functions Execution Status Change",
    "source": "aws.states",
    "account": "...",
    "time": "2020-11-10T13:59:57Z",
    "region": "us-east-1",
    "resources": [
        "...myStateMachineArn..."
    ],
    "detail": {
        "executionArn": "...myStateMachineExecutionArn...",
        "stateMachineArn": "...myStateMachineArn...",
        "name": "ff72036a-2917-c657-80e7-2589b7b76d59",
        "status": "SUCCEEDED",
        "startDate": 1605016794597,
        "stopDate": 1605016797936,
        "input": "{\n  \"usefulObject\":{\n    \"usefulProperty\": \"value\"\n  },\n  \"anotherProperty\": \"anotherValue\"\n}",
        "inputDetails": {
            "included": true
        },
        "output": "{\n  \"usefulObject\":{\n    \"usefulProperty\": \"value\"\n  },\n  \"anotherProperty\": \"anotherValue\"\n}",
        "outputDetails": {
            "included": true
        }
    }
}

如您所见,在实际的事件负载中,我的状态机数据存储为output节点内的字符串化 Json 值。如果然后我将输入转换路径更改为:

{"propertyValue":"$.detail.output.usefulObject.usefulProperty"}

property我在转换后的输入中得到一个空结果。事实证明,JsonPath 无法将字符串化值作为 Json 有效负载的一部分进行遍历,并且将在搜索中失败。

如何usefulProperty从事件有效负载中的 Json 字符串中提取值,以便将其传递给我的 lambda 函数?有没有办法使用我缺少的纯 JsonPath 来做到这一点?也许有一种方法可以将 AWS 配置为不将有效负载转换为字符串,而将其作为整个事件有效负载的一部分?还有其他选择吗?

4

1 回答 1

2

您可以尝试以下几件事来防止您的输入和输出被解释器字符串化:

  1. 而不是输入:
{"propertyValue":"$.usefulObject.usefulProperty"}

尝试

{"propertyValue.$":"$.usefulObject.usefulProperty"}

或者

{"propertyValue": $.usefulObject.usefulProperty}
  1. 确保您的 lambda 不返回结果的字符串化版本,即:return JSON.stringify(usefulObject)

  2. 如果这些都没有帮助,您可以尝试使用以下方法转换步骤函数模板中的输出字符串:

{
    "propertyValue.$": "States.StringToJson($.detail.output.usefulObject.usefulProperty)"
}
  1. longshot:确保您没有故意将其转换为字符串,在您的步骤函数模板中的States.JsonToString某处...... :)

根据https://states-language.net/上的文档

  1. 尝试从 Lambda 中的事件对象中提取值,然后使用它:
exports.lambdaHandler = async (event) => {
  // parse your input or output string and use it as an object;
  let receivedParams = JSON.parse(event.detail.input);
  let propertyValueObject = {
    propertyValue: receivedParams.usefulObject.usefulProperty,
  };

  // do something in your lambda with propertValueObject 
  // which is equal to: { propertyValue: 'value' }
  console.log(propertyValueObject);
};

let event = {
    "version": "0",
    "id": "...",
    "detail-type": "Step Functions Execution Status Change",
    "source": "aws.states",
    "account": "...",
    "time": "2020-11-10T13:59:57Z",
    "region": "us-east-1",
    "resources": [
        "...myStateMachineArn..."
    ],
    "detail": {
        "executionArn": "...myStateMachineExecutionArn...",
        "stateMachineArn": "...myStateMachineArn...",
        "name": "ff72036a-2917-c657-80e7-2589b7b76d59",
        "status": "SUCCEEDED",
        "startDate": 1605016794597,
        "stopDate": 1605016797936,
        "input": "{\n  \"usefulObject\":{\n    \"usefulProperty\": \"value\"\n  },\n  \"anotherProperty\": \"anotherValue\"\n}",
        "inputDetails": {
            "included": true
        },
        "output": "{\n  \"usefulObject\":{\n    \"usefulProperty\": \"value\"\n  },\n  \"anotherProperty\": \"anotherValue\"\n}",
        "outputDetails": {
            "included": true
        }
    }
}

const lambdaHandler = (event) => {
  // parse your input or output string and use it as an object;
  let receivedParams = JSON.parse(event.detail.input);
  let propertyValueObject = {
    propertyValue: receivedParams.usefulObject.usefulProperty,
  };

  // do something in your lambda with propertValueObject 
  // which is equal to: { propertyValue: 'value' }
  console.log(propertyValueObject);
};

lambdaHandler(event)

于 2021-09-21T01:40:14.560 回答