{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Using the Neptune Gremlin Client in an AWS Lambda function" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![Architecture: Using the Neptune Gremlin Client in an AWS Lambda function](https://ianrob-examples.s3-eu-west-1.amazonaws.com/images/gremlin-client-lambda.png \"Architecture: Using the Neptune Gremlin Client in an AWS Lambda function\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import boto3\n", "import os\n", "import json\n", "\n", "client = boto3.client('lambda')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## neptune-endpoint-info Lambda function\n", "\n", "This Lambda function acts as a proxy for a `ClusterEndpointsRefreshAgent`. The Lambda polls the Neptune management API on a periodic basis to fetch all the available instance endpoints. Lambda functions that use a `GremlinClient` with a `ClusterEndpointsRefreshAgent` can then use this Lambda to return specific endpoints (`All`, `Primary` or `ReadReplicas`).\n", "\n", "Use of this Lambda ensures that the management API is not throttled, irrespective of the number of concurrent application Lambdas.\n", "\n", "The source code for this function can be found [here](https://github.com/awslabs/amazon-neptune-tools/blob/master/neptune-gremlin-client/neptune-endpoints-info-lambda/src/main/java/software/amazon/lambda/NeptuneEndpointsInfoLambda.java). There's a CloudFormation template that you can use to install the Lamdba [here](https://github.com/awslabs/amazon-neptune-tools/blob/master/neptune-gremlin-client/cloudformation-templates/neptune-endpoints-info-lambda.json)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "endpoint_info = client.invoke(\n", " FunctionName='neptune-endpoint-info_{}'.format(os.environ['NEPTUNE_CLUSTER_ID']),\n", " InvocationType='RequestResponse',\n", " Payload=b'\"All\"' # or 'Primary' or 'ReadReplicas'\n", ")\n", "\n", "print(endpoint_info['Payload'].read().decode(\"utf-8\"))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Return full cluster metadata from the Labda proxy\n", "\n", "The latest version of the __neptune-endpoint-info__ Lambda function can now allso return a full description of the cluster topology. Supply an empty payload (`\"\"`) to request the full cluster metadata. The Neptune Gremlin Client can now use custom endpoint selection criteria to choose endpoints sourced from a Lambda proxy.\n", "\n", "For more details on using the Neptune Gremlin Client with a Lamnda proxy, [see the documentation](https://github.com/awslabs/amazon-neptune-tools/tree/master/neptune-gremlin-client#connect-the-clusterendpointsrefreshagent-to-a-lambda-proxy-when-you-have-many-clients)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "endpoint_info = client.invoke(\n", " FunctionName='neptune-endpoint-info_{}'.format(os.environ['NEPTUNE_CLUSTER_ID']),\n", " InvocationType='RequestResponse',\n", " Payload=b'\"\"' # empty payload\n", ")\n", "\n", "print(json.dumps(json.loads(endpoint_info['Payload'].read().decode(\"utf-8\")), indent=1))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## neptune-gremlin-client-example Lambda function\n", "\n", "This Lambda function uses a `GremlinClient` to query Neptune. With each invocation it creates a new vertex. The function uses a `ClusterEndpointsRefreshAgent` that is configured to retrieve the Primary endpoint from the _neptune-endpoint-info_ described above.\n", "\n", "The source code for this demo function can be found [here](https://github.com/awslabs/amazon-neptune-tools/blob/master/neptune-gremlin-client/gremlin-client-demo/src/main/java/software/amazon/lambda/NeptuneGremlinClientExampleLambda.java)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "gremlin_client_lambda_response = client.invoke(\n", " FunctionName='neptune-gremlin-client-example_{}'.format(os.environ['NEPTUNE_CLUSTER_ID']),\n", " InvocationType='RequestResponse'\n", ")\n", "\n", "print('New vertex: {}'.format(gremlin_client_lambda_response['Payload'].read().decode(\"utf-8\")))" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.12" } }, "nbformat": 4, "nbformat_minor": 4 }