Running the below Lambda for most openCypher queries fails.
This is a NodeJS 18.x Lambda, attempting to send an HTTP request to a Neptune Writer endpoint.
The Lambda works fine when the openCypher query does not contain any strings. This simple query is working fine:
const ocQuery = "MATCH (n) RETURN n LIMIT 1";
But this is failing (Server error 500):
const ocQuery = "MATCH (n {name: 'Israel'}) RETURN n";
And this is failing (Error 403 Access Denied):
const ocQuery = "MATCH (n) WHERE n.name = 'Israel' RETURN n";
I tried escaping the quote char and others, tried encoding these special chars - nothing solved it.
Lambda code:
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
} = process.env;
const ocQuery = "MATCH (n) WHERE n.name = 'Israel' RETURN n";
const API_URL = "https://db-simplify-mvp-dev-instance-1.cwezylrm9ic8.us-east-1.neptune.amazonaws.com:8182/openCypher?query=" + ocQuery;
const apiUrl = new URL(API_URL);
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,
});
export const handler = async () => {
const signed = await sigv4.sign({
method: 'GET',
hostname: apiUrl.host,
path: apiUrl.pathname,
protocol: apiUrl.protocol,
query: {
query: ocQuery
},
headers: {
'Content-Type': 'application/json',
host: apiUrl.hostname,
}
});
try {
const result = await axios({
...signed,
url: API_URL,
});
console.log('Successfully received result: ', result.data);
return {
statusCode: 200,
body: result.data
}
} catch (error) {
console.log('An error occurred', error);
throw error;
}
};
The Lambda IAM execution role has these policies:
AmazonEC2FullAccess
NeptuneFullAccess
AWSLambdaBasicExecutionRole
AmazonSSMReadOnlyAccess
AWSLambdaVPCAccessExecutionRole
VPC Configuration:
The Neptune Security Group has inbound rules to allow the Lambda Security Group on port 8182:
Tried using POST method, same error. What am I missing, please?
EDIT: Updated Lambda code with the solution offered by Taylor that worked great until I attempted to add query parameters. Originally I received this error, which is mostly not showing anymore:
The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method.
You were really close. I think the one big thing that you were missing was to include the query parameters as part of the SigV4 signing process. You also do not need to URL-encode the openCypher query. You can leave the spaces and such as shown below. You'll have to do that, or else the Signature will not get created properly.
I also had to change the way that the results were being returned from the Axios request. See updated code here: