使用@aws-sdk/client-lambda 调用 Lambda.invoke 返回空响应

问题描述 投票:0回答:0

以下(Angular)组件使用@aws-sdk/lambda-client (v. 3.222.0) 调用 Lambda 函数。 使用与输入相同的负载在 AWS 控制台中测试 Lambda 成功。 此外,当从 Angular 应用程序调用时 - cloudWatch 日志显示成功运行及其返回负载:

73ec2dbb-a647-43ea-82c6-a30407001d65    INFO    event received:  {
  body: "MATCH (n %7Bname:'Israel'%7D) RETURN n",
  headers: { SignatureHeader: '******' }
}

73ec2dbb-a647-43ea-82c6-a30407001d65    INFO    requestPayload:  MATCH (n %7Bname:'Israel'%7D) RETURN n

73ec2dbb-a647-43ea-82c6-a30407001d65    INFO    Successfully received result:  
{
    "results": [
        {
            "n": {
                "~id": "1d68ae59-deef-4dd7-b97d-d2771f7dd793",
                "~entityType": "node",
                "~labels": [
                    "Country"
                ],
                "~properties": {
                    "keyID": 972,
                    "language": "Hebrew",
                    "codeText": "IL",
                    "image": "flags/il.png",
                    "enabled": true,
                    "name": "Israel"
                }
            }
        }
    ]
}

但是,浏览器控制台显示 Angular 应用程序收到了 EMPTY 结果集:

Lambda payload:  {body: "MATCH (n %7Bname:'Israel'%7D) RETURN n", headers: {…}}
Creating LambdaClient:  {body: "MATCH (n %7Bname:'Israel'%7D) RETURN n", headers: {…}}
SENDING LambdaClient. command:  {FunctionName: 'simplify-mvp-neptune-query:dev', InvocationType: 'Event', Payload: Uint8Array(102)}
Returned from LAmbda call. resp:  
Uint8Array [buffer: ArrayBuffer(0), byteLength: 0, byteOffset: 0, length: 0, Symbol(Symbol.toStringTag): 'Uint8Array']

正如您在最后一行控制台中看到的,尽管 cloudWatch 正在发送填充对象,但接收到的缓冲区是空的。

这是客户端(Angular)调用:

import { Lambda } from "@aws-sdk/client-lambda";

...

async queryLambda(data: any) {
    console.log('Creating LambdaClient: ', data);
    const lambdaClient = new Lambda({ 
      region: environment.awsRegion,
      credentials: {        
        accessKeyId: environment.awsAccessKeyLambda,
        secretAccessKey: environment.awsSecretLambda,
      }
    });

    console.log('Creating InvokeCommand');
    const command = {
      FunctionName: environment.awsLambdaDBFunction,
      InvocationType: 'Event',
      //Payload: Buffer.from(JSON.stringify(data)),
      Payload: new TextEncoder().encode(JSON.stringify(data))
    };
  
    
    try {
      console.log('SENDING LambdaClient. command: ', command);      
      const resp  = await lambdaClient.invoke(command);
      console.log('Returned from LAmbda call. resp: ', resp.Payload);
      //const result = Buffer.from(resp.Payload).toString();
      const result = (new TextDecoder('utf-8').decode(resp.Payload));
      console.log('Converted result from buffer: ', result);            
      return result;
    } catch (err) {
      console.log('There was an error invoking Lambda DB function: ', err);
        return false;
    }
   }

我也尝试使用这种方法(这里只显示骨架):

import { LambdaClient, InvokeCommand } from "@aws-sdk/client-lambda"; 
...
const client = new LambdaClient(config);
const command = new InvokeCommand(input);
const response = await client.send(command);

相同的行为,虽然。

这是 Lambda (NodeJS 18.x) 代码:

import axios from 'axios';
import { SignatureV4 } from '@aws-sdk/signature-v4';
import { Sha256 } from '@aws-crypto/sha256-js';

const {
  AWS_ACCESS_KEY_ID,
  AWS_SECRET_ACCESS_KEY,
  AWS_SESSION_TOKEN,
  CALL_SIGNATURE
} = process.env;

const sigv4 = new SignatureV4({
  service: 'neptune-db',
  region: 'us-east-1',
  credentials: {
    accessKeyId: AWS_ACCESS_KEY_ID,
    secretAccessKey: AWS_SECRET_ACCESS_KEY,
    sessionToken: AWS_SESSION_TOKEN,
  },
  sha256: Sha256,
});


const validateSignature = async (requestSignature) => {
  //Lambda call permission validator
  if (requestSignature!=CALL_SIGNATURE) {
    throw new Error('Function call signature does not match');
  }
};


const decodeQuery = async (queryText) => {
    //Decodes some chars in the raw query text for Lambda to process properly
    let result = queryText.replace(/%7B/g, "{");
    result = result.replace(/%7D/g, "}");
    return result;
  };


export const handler = async (event) => {
  
  // retrieve signature and payload
  const requestSignature = event.headers.SignatureHeader;
  //const requestSignature = event.body.SignatureHeader;
  console.log('event received: ', event);
  
  try {
        await validateSignature(requestSignature); // throws if invalid signature
    } catch (error) {
        console.error(error);
        return {
            statusCode: 400,
            body: `Function permission error: ${error}`,
        };
    }
  
  const requestPayload = event.body; //Passed openCypher query string
  console.log('requestPayload: ', requestPayload);
  const signatureQuery = await decodeQuery(requestPayload);
  
  const ocQuery = requestPayload;
  const API_URL = "https://****.****.us-east-1.neptune.amazonaws.com:8182/openCypher?query=" + ocQuery;
  const apiUrl = new URL(API_URL);

  const signed = await sigv4.sign({
    method: 'GET',
    hostname: apiUrl.host,
    path: apiUrl.pathname,
    protocol: apiUrl.protocol,
    query: {
      query: signatureQuery
      },
    headers: {
      'Content-Type': 'application/json',
      host: apiUrl.hostname, 
    }
  });

  try {
    const result = await axios({
      ...signed,
      url: API_URL,
    });

    console.log('Successfully received result: ', JSON.stringify(result.data));
    return {
      statusCode: 200,
      body: result.data
    };
  } catch (error) {
    console.log('An error occurred', error);

    throw error;
  }
};

拜托,我错过了什么? 谢谢!

aws-lambda aws-sdk
© www.soinside.com 2019 - 2024. All rights reserved.