以下(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;
}
};
拜托,我错过了什么? 谢谢!