Skip to content

Commit 88385cb

Browse files
authored
Integrate usage of neptune graph SDK for schema queries and lambda logic (#5)
Introduce usage of the neptune graph (analytics) SDK in a couple scenarios: 1. during pipeline creation, if an axios request fails when querying the Neptune Analytics graph and falls back to SDK and 2. if the user has opted to use SDK for the generated lambda (as opposed to http). Summary of changes: -added new dependency on client-neptune-graph version 3.662.0 -created new lambda template which is used if the user specifies --output-resolver-query-sdk option -set additional lambda environment variable for neptune db name which is required to execute queries using the neptune graph SDK -added logic to fall back to neptune graph SDK if Axios request fails during pipeline creation (previous logic threw Error as the analytics SDK was not yet available) -fixed function which retrieves graph summary to use neptune graph SDK if the neptune-type is neptune-graph (the summary endpoint path for neptune-db is not the same for neptune-graph) -fixed CDK pipeline to only fetch cluster info if the type is neptune-db as it is not required for Neptune-graph (analytics) -set isNeptuneIAMAuth to true if the neptune type is detected as neptune-graph -introduced util.js for parsing functions that are used across multiple modules -refactored function which had many params to use an object param instead for better readability -fixed some typos which specified 'neptume' instead of 'neptune' -changed queryNeptune function to have default value of empty object for params -change jest config from json to js to allow for globals to be set from environment variables -changed test cases to reference <AIR_ROUTES_DB_HOST> and <AIR_ROUTES_DB_PORT values which are swapped at test runtime for the environment variable values for easier test configurability and to prevent future accidental commit of real URLs -removed duplicated airports.source.schema.graphql file in test cases and changed to reference single file in parent directory -fixed Case05/case02.json which I believe was accidentally changed from remove to create pipeline -introduced new test case 7 which sets --output-resolver-query-sdk option
1 parent 8f63bb9 commit 88385cb

37 files changed

+5196
-293
lines changed

.gitignore

+3-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package-lock.json
44
node_modules/**
55
templates/Lambda4AppSyncHTTP/node_modules/**
66
templates/Lambda4AppSyncSDK/node_modules/**
7+
templates/Lambda4AppSyncGraphSDK/node_modules/**
78
coverage/**
89
test/node_modules/**
910
test/TestCases/Case01/output/**
@@ -13,4 +14,5 @@ test/TestCases/Case03/output/**
1314
test/TestCases/Case04/output/**
1415
test/TestCases/Case05/output/**
1516
test/TestCases/Case06/output/**
16-
*.iml
17+
test/TestCases/Case07/output/**
18+
*.iml

.jest.js

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export default {
2+
'transform': {},
3+
'verbose': true,
4+
'testSequencer': './test/jestTestSequencer.js',
5+
'globals': {
6+
// neptune db that has pre-loaded air routes sample data host and port
7+
// ex. db-neptune-foo-bar.cluster-abc.us-west-2.neptune.amazonaws.com
8+
'AIR_ROUTES_DB_HOST': process.env.AIR_ROUTES_DB_HOST,
9+
// ex. 8182
10+
'AIR_ROUTES_DB_PORT': process.env.AIR_ROUTES_DB_PORT
11+
}
12+
};

.jest.json

-5
This file was deleted.

doc/cdk.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Example starting from an Amazon Neptune database endpoint. In this case the util
1111

1212
Example starting from a GraphQL schema.
1313

14-
`neptune-for-graphql --input-schema-file `<*your-graphql-schema-file*>` --output-aws-pipeline-cdk --output-aws-pipeline-cdk-name` <*your-new-GraphQL-API-name*>` --output-aws-pipeline-cdk-neptume-endpoint` <*your-neptune-database-endpoint:port*>` --output-resolver-query-https`
14+
`neptune-for-graphql --input-schema-file `<*your-graphql-schema-file*>` --output-aws-pipeline-cdk --output-aws-pipeline-cdk-name` <*your-new-GraphQL-API-name*>` --output-aws-pipeline-cdk-neptune-endpoint` <*your-neptune-database-endpoint:port*>` --output-resolver-query-https`
1515

1616

1717

doc/cliReference.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ It removes the pipeline created with `--create-update-aws-pipeline`. The resourc
135135
<br>
136136
This trigger the creation of a CDK file to be use to create the AWS resources for the GraphQL API, including the AppSync GraphQL API and the Lambda that run the resolver.
137137

138-
`--output-aws-pipeline-cdk-neptume-endpoint <value>, -ce <value>`
138+
`--output-aws-pipeline-cdk-neptune-endpoint <value>, -ce <value>`
139139
<br>
140140
This set the Neptune database endpoint used by the Lambda function to query the Neptune database. If not set it used the endpoint set with `--input-graphdb-schema-neptune-endpoint`.
141141

package.json

+4-2
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@
2121
"scripts": {
2222
"postinstall": "cd templates/Lambda4AppSyncHTTP && npm install && cd ../Lambda4AppSyncSDK && npm install",
2323
"lint": "eslint neptune-for-graphql.mjs ./src",
24-
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage --runInBand --detectOpenHandles --config .jest.json",
25-
"test:resolver": "node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage --runInBand --detectOpenHandles --config .jest.json --testPathPattern=test/TestCases/Case01"
24+
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage --runInBand --detectOpenHandles --config .jest.js",
25+
"test:sdk": "node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage --runInBand --detectOpenHandles --config .jest.js --testPathPattern=test/TestCases/Case07",
26+
"test:resolver": "node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage --runInBand --detectOpenHandles --config .jest.js --testPathPattern=test/TestCases/Case01"
2627
},
2728
"jest": {
2829
"collectCoverage": true,
@@ -53,6 +54,7 @@
5354
"@aws-sdk/client-lambda": "3.387.0",
5455
"@aws-sdk/client-neptune": "3.387.0",
5556
"@aws-sdk/client-neptunedata": "3.403.0",
57+
"@aws-sdk/client-neptune-graph": "3.662.0",
5658
"@aws-sdk/credential-providers": "3.414.0",
5759
"archiver": "5.3.1",
5860
"aws4-axios": "3.3.0",

src/CDKPipelineApp.js

+62-44
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ express or implied. See the License for the specific language governing
1010
permissions and limitations under the License.
1111
*/
1212

13-
import { getNeptuneClusterinfoBy } from './pipelineResources.js'
13+
import { getNeptuneClusterDbInfoBy } from './pipelineResources.js'
1414
import { readFile, writeFile } from 'fs/promises';
1515
//import semver from 'semver';
1616
import fs from 'fs';
@@ -74,7 +74,22 @@ async function createDeploymentFile(folderPath, zipFilePath) {
7474
}
7575

7676

77-
async function createAWSpipelineCDK (pipelineName, neptuneDBName, neptuneDBregion, appSyncSchema, schemaModel, lambdaFilesPath, outputFile, __dirname, quiet, isNeptuneIAMAuth, neptuneHost, neptunePort, outputFolderPath ) {
77+
async function createAWSpipelineCDK({
78+
pipelineName,
79+
neptuneDBName,
80+
neptuneDBregion,
81+
appSyncSchema,
82+
schemaModel,
83+
lambdaFilesPath,
84+
outputFile,
85+
__dirname,
86+
quiet,
87+
isNeptuneIAMAuth,
88+
neptuneHost,
89+
neptunePort,
90+
outputFolderPath,
91+
neptuneType
92+
}) {
7893

7994
NAME = pipelineName;
8095
REGION = neptuneDBregion;
@@ -89,52 +104,54 @@ async function createAWSpipelineCDK (pipelineName, neptuneDBName, neptuneDBregio
89104
let spinner = null;
90105
let neptuneClusterInfo = null;
91106

92-
try {
93-
loggerInfo('Get Neptune Cluster Info');
94-
if (!quiet) spinner = ora('Getting ...').start();
95-
neptuneClusterInfo = await getNeptuneClusterinfoBy(NEPTUNE_DB_NAME, REGION);
96-
if (!quiet) spinner.succeed('Got Neptune Cluster Info');
97-
if (isNeptuneIAMAuth) {
98-
if (!neptuneClusterInfo.isIAMauth) {
99-
loggerError("The Neptune database authentication is set to VPC.");
100-
loggerError("Remove the --output-aws-pipeline-cdk-neptune-IAM option.");
101-
process.exit(1);
102-
}
103-
} else {
104-
if (neptuneClusterInfo.isIAMauth) {
105-
loggerError("The Neptune database authentication is set to IAM.");
106-
loggerError("Add the --output-aws-pipeline-cdk-neptune-IAM option.");
107-
process.exit(1);
107+
if (neptuneType === 'neptune-db') {
108+
try {
109+
loggerInfo('Get Neptune Cluster Info');
110+
if (!quiet) spinner = ora('Getting ...').start();
111+
neptuneClusterInfo = await getNeptuneClusterDbInfoBy(NEPTUNE_DB_NAME, REGION);
112+
if (!quiet) spinner.succeed('Got Neptune Cluster Info');
113+
if (isNeptuneIAMAuth) {
114+
if (!neptuneClusterInfo.isIAMauth) {
115+
loggerError("The Neptune database authentication is set to VPC.");
116+
loggerError("Remove the --output-aws-pipeline-cdk-neptune-IAM option.");
117+
process.exit(1);
118+
}
108119
} else {
109-
loggerInfo(`Subnet Group: ` + neptuneClusterInfo.dbSubnetGroup);
120+
if (neptuneClusterInfo.isIAMauth) {
121+
loggerError("The Neptune database authentication is set to IAM.");
122+
loggerError("Add the --output-aws-pipeline-cdk-neptune-IAM option.");
123+
process.exit(1);
124+
} else {
125+
loggerInfo(`Subnet Group: ` + neptuneClusterInfo.dbSubnetGroup);
126+
}
110127
}
111-
}
112128

113-
if (neptuneClusterInfo.version != '') {
114-
const v = neptuneClusterInfo.version;
115-
if (lambdaFilesPath.includes('SDK') == true && //semver.satisfies(v, '>=1.2.1.0') ) {
116-
(v == '1.2.1.0' || v == '1.2.0.2' || v == '1.2.0.1' || v == '1.2.0.0' || v == '1.1.1.0' || v == '1.1.0.0')) {
117-
loggerError("Neptune SDK query is supported starting with Neptune versions 1.2.1.0.R5");
118-
loggerError("Switch to Neptune HTTPS query with option --output-resolver-query-https");
119-
process.exit(1);
129+
if (neptuneClusterInfo.version != '') {
130+
const v = neptuneClusterInfo.version;
131+
if (lambdaFilesPath.includes('SDK') == true && //semver.satisfies(v, '>=1.2.1.0') ) {
132+
(v == '1.2.1.0' || v == '1.2.0.2' || v == '1.2.0.1' || v == '1.2.0.0' || v == '1.1.1.0' || v == '1.1.0.0')) {
133+
loggerError("Neptune SDK query is supported starting with Neptune versions 1.2.1.0.R5");
134+
loggerError("Switch to Neptune HTTPS query with option --output-resolver-query-https");
135+
process.exit(1);
136+
}
120137
}
121-
}
122138

123-
NEPTUNE_HOST = neptuneClusterInfo.host;
124-
NEPTUNE_PORT = neptuneClusterInfo.port;
125-
NEPTUNE_DBSubnetGroup = neptuneClusterInfo.dbSubnetGroup.replace('default-', '');
126-
NEPTUNE_IAM_POLICY_RESOURCE = neptuneClusterInfo.iamPolicyResource;
127-
128-
} catch (error) {
129-
msg = 'Error getting Neptune Cluster Info: ' + JSON.stringify(error);
130-
loggerError(msg);
131-
if (!quiet) spinner.fail("Error getting Neptune Cluster Info.");
132-
if (!isNeptuneIAMAuth) {
133-
spinner.clear();
134-
loggerError("VPC data is not available to proceed.");
135-
process.exit(1);
136-
} else {
137-
loggerInfo("Proceeding without getting Neptune Cluster info.");
139+
NEPTUNE_HOST = neptuneClusterInfo.host;
140+
NEPTUNE_PORT = neptuneClusterInfo.port;
141+
NEPTUNE_DBSubnetGroup = neptuneClusterInfo.dbSubnetGroup.replace('default-', '');
142+
NEPTUNE_IAM_POLICY_RESOURCE = neptuneClusterInfo.iamPolicyResource;
143+
144+
} catch (error) {
145+
msg = 'Error getting Neptune Cluster Info: ' + JSON.stringify(error);
146+
loggerError(msg);
147+
if (!quiet) spinner.fail("Error getting Neptune Cluster Info.");
148+
if (!isNeptuneIAMAuth) {
149+
spinner.clear();
150+
loggerError("VPC data is not available to proceed.");
151+
process.exit(1);
152+
} else {
153+
loggerInfo("Proceeding without getting Neptune Cluster info.");
154+
}
138155
}
139156
}
140157

@@ -150,7 +167,8 @@ async function createAWSpipelineCDK (pipelineName, neptuneDBName, neptuneDBregio
150167
CDKFile = CDKFile.replace( "const NAME = '';", `const NAME = '${NAME}';` );
151168
CDKFile = CDKFile.replace( "const REGION = '';", `const REGION = '${REGION}';` );
152169
CDKFile = CDKFile.replace( "const NEPTUNE_HOST = '';", `const NEPTUNE_HOST = '${NEPTUNE_HOST}';` );
153-
CDKFile = CDKFile.replace( "const NEPTUNE_PORT = '';", `const NEPTUNE_PORT = '${NEPTUNE_PORT}';` );
170+
CDKFile = CDKFile.replace( "const NEPTUNE_PORT = '';", `const NEPTUNE_PORT = '${NEPTUNE_PORT}';` );
171+
CDKFile = CDKFile.replace( "const NEPTUNE_DB_NAME = '';", `const NEPTUNE_DB_NAME = '${NEPTUNE_DB_NAME}';` );
154172
CDKFile = CDKFile.replace( "const NEPTUNE_DBSubnetGroup = null;", `const NEPTUNE_DBSubnetGroup = '${NEPTUNE_DBSubnetGroup}';` );
155173
CDKFile = CDKFile.replace( "const NEPTUNE_IAM_AUTH = false;", `const NEPTUNE_IAM_AUTH = ${isNeptuneIAMAuth};` );
156174
CDKFile = CDKFile.replace( "const NEPTUNE_IAM_POLICY_RESOURCE = '*';", `const NEPTUNE_IAM_POLICY_RESOURCE = '${NEPTUNE_IAM_POLICY_RESOURCE}';` );

0 commit comments

Comments
 (0)