Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.
Menggunakan protokol Bolt untuk membuat openCypher kueri ke Neptunus
Bolt
Untuk terhubung ke Neptunus menggunakan driver Bolt Neo4j, cukup ganti nomor dan Port dengan URL titik akhir cluster Anda menggunakan skema. bolt
URI Jika Anda memiliki satu instance Neptunus yang berjalan, gunakan endpoint read_write. Jika beberapa instance berjalan, maka dua driver direkomendasikan, satu untuk penulis dan satu lagi untuk semua replika baca. Jika Anda hanya memiliki dua titik akhir default, driver read_write dan read_only sudah cukup, tetapi jika Anda memiliki titik akhir khusus juga, pertimbangkan untuk membuat instance driver untuk masing-masing titik akhir.
catatan
Meskipun spesifikasi Bolt menyatakan bahwa Bolt dapat terhubung menggunakan salah satu TCP atau, WebSockets Neptunus hanya mendukung koneksi untuk Bolt. TCP
Neptunus memungkinkan hingga 1000 koneksi Bolt bersamaan.
Untuk contoh openCypher kueri dalam berbagai bahasa yang menggunakan driver Bolt, lihat dokumentasi Neo4j Drivers & Language
penting
Driver Neo4j Bolt untuk Python,. NET, JavaScript, dan Golang awalnya tidak mendukung pembaruan otomatis token otentikasi AWS Signature v4. Ini berarti bahwa setelah tanda tangan kedaluwarsa (seringkali dalam 5 menit), pengemudi gagal mengautentikasi, dan permintaan berikutnya gagal. Python,. NET, JavaScript, dan contoh Go di bawah ini semuanya terpengaruh oleh masalah ini.
Lihat masalah driver Python Neo4j
Pada driver versi 5.8.0, otentikasi ulang pratinjau baru API dirilis untuk driver Go (lihat v5.8.0
Menggunakan Bolt dengan Java untuk terhubung ke Neptunus
Anda dapat mengunduh driver untuk versi apa pun yang ingin Anda gunakan dari MVNrepositori
<dependency> <groupId>org.neo4j.driver</groupId> <artifactId>neo4j-java-driver</artifactId> <version>4.3.3</version> </dependency>
Kemudian, untuk terhubung ke Neptunus di Jawa menggunakan salah satu driver Bolt ini, buat instance driver untuk instance primer/writer di cluster Anda menggunakan kode seperti berikut:
import org.neo4j.driver.Driver; import org.neo4j.driver.GraphDatabase; final Driver driver = GraphDatabase.driver("bolt://
(your cluster endpoint URL)
:(your cluster port)
", AuthTokens.none(), Config.builder().withEncryption() .withTrustStrategy(TrustStrategy.trustSystemCertificates()) .build());
Jika Anda memiliki satu atau lebih replika pembaca, Anda juga dapat membuat instance driver untuk mereka menggunakan kode seperti ini:
final Driver read_only_driver = // (without connection timeout) GraphDatabase.driver("bolt://
(your cluster endpoint URL)
:(your cluster port)
", Config.builder().withEncryption() .withTrustStrategy(TrustStrategy.trustSystemCertificates()) .build());
Atau, dengan batas waktu:
final Driver read_only_timeout_driver = // (with connection timeout) GraphDatabase.driver("bolt://
(your cluster endpoint URL)
:(your cluster port)
", Config.builder().withConnectionTimeout(30, TimeUnit.SECONDS) .withEncryption() .withTrustStrategy(TrustStrategy.trustSystemCertificates()) .build());
Jika Anda memiliki titik akhir khusus, mungkin juga bermanfaat untuk membuat instance driver untuk masing-masing titik.
Contoh openCypher kueri Python menggunakan Bolt
Berikut ini cara membuat openCypher kueri dengan Python menggunakan Bolt:
python -m pip install neo4j
from neo4j import GraphDatabase uri = "bolt://
(your cluster endpoint URL)
:(your cluster port)
" driver = GraphDatabase.driver(uri, auth=("username", "password"), encrypted=True)
Perhatikan bahwa auth
parameter diabaikan.
SEBUAH. NET openCypher contoh kueri menggunakan Bolt
Untuk membuat openCypher kueri di. NETmenggunakan Bolt, langkah pertama adalah menginstal driver Neo4j menggunakan. NuHet Untuk melakukan panggilan sinkron, gunakan .Simple
versi, seperti ini:
Install-Package Neo4j.Driver.Simple-4.3.0
using Neo4j.Driver; namespace hello { // This example creates a node and reads a node in a Neptune // Cluster where IAM Authentication is not enabled. public class HelloWorldExample : IDisposable { private bool _disposed = false; private readonly IDriver _driver; private static string url = "bolt://(your cluster endpoint URL):
(your cluster port)
"; private static string createNodeQuery = "CREATE (a:Greeting) SET a.message = 'HelloWorldExample'"; private static string readNodeQuery = "MATCH(n:Greeting) RETURN n.message"; ~HelloWorldExample() => Dispose(false); public HelloWorldExample(string uri) { _driver = GraphDatabase.Driver(uri, AuthTokens.None, o => o.WithEncryptionLevel(EncryptionLevel.Encrypted)); } public void createNode() { // Open a session using (var session = _driver.Session()) { // Run the query in a write transaction var greeting = session.WriteTransaction(tx => { var result = tx.Run(createNodeQuery); // Consume the result return result.Consume(); }); // The output will look like this: // ResultSummary{Query=`CREATE (a:Greeting) SET a.message = 'HelloWorldExample"..... Console.WriteLine(greeting); } } public void retrieveNode() { // Open a session using (var session = _driver.Session()) { // Run the query in a read transaction var greeting = session.ReadTransaction(tx => { var result = tx.Run(readNodeQuery); // Consume the result. Read the single node // created in a previous step. return result.Single()[0].As<string>(); }); // The output will look like this: // HelloWorldExample Console.WriteLine(greeting); } } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (_disposed) return; if (disposing) { _driver?.Dispose(); } _disposed = true; } public static void Main() { using (var apiCaller = new HelloWorldExample(url)) { apiCaller.createNode(); apiCaller.retrieveNode(); } } } }
Contoh openCypher query Java menggunakan Bolt dengan IAM otentikasi
Kode Java di bawah ini menunjukkan cara membuat openCypher kueri di Java menggunakan Bolt dengan IAM otentikasi. JavaDoc Komentar tersebut menjelaskan penggunaannya. Setelah instance driver tersedia, Anda dapat menggunakannya untuk membuat beberapa permintaan yang diautentikasi.
package software.amazon.neptune.bolt; import com.amazonaws.DefaultRequest; import com.amazonaws.Request; import com.amazonaws.auth.AWS4Signer; import com.amazonaws.auth.AWSCredentialsProvider; import com.amazonaws.http.HttpMethodName; import com.google.gson.Gson; import lombok.Builder; import lombok.Getter; import lombok.NonNull; import org.neo4j.driver.Value; import org.neo4j.driver.Values; import org.neo4j.driver.internal.security.InternalAuthToken; import org.neo4j.driver.internal.value.StringValue; import java.net.URI; import java.util.Collections; import java.util.HashMap; import java.util.Map; import static com.amazonaws.auth.internal.SignerConstants.AUTHORIZATION; import static com.amazonaws.auth.internal.SignerConstants.HOST; import static com.amazonaws.auth.internal.SignerConstants.X_AMZ_DATE; import static com.amazonaws.auth.internal.SignerConstants.X_AMZ_SECURITY_TOKEN; /** * Use this class instead of `AuthTokens.basic` when working with an IAM * auth-enabled server. It works the same as `AuthTokens.basic` when using * static credentials, and avoids making requests with an expired signature * when using temporary credentials. Internally, it generates a new signature * on every invocation (this may change in a future implementation). * * Note that authentication happens only the first time for a pooled connection. * * Typical usage: * * NeptuneAuthToken authToken = NeptuneAuthToken.builder() * .credentialsProvider(credentialsProvider) * .region("aws region") * .url("cluster endpoint url") * .build(); * * Driver driver = GraphDatabase.driver( * authToken.getUrl(), * authToken, * config * ); */ public class NeptuneAuthToken extends InternalAuthToken { private static final String SCHEME = "basic"; private static final String REALM = "realm"; private static final String SERVICE_NAME = "neptune-db"; private static final String HTTP_METHOD_HDR = "HttpMethod"; private static final String DUMMY_USERNAME = "username"; @NonNull private final String region; @NonNull @Getter private final String url; @NonNull private final AWSCredentialsProvider credentialsProvider; private final Gson gson = new Gson(); @Builder private NeptuneAuthToken( @NonNull final String region, @NonNull final String url, @NonNull final AWSCredentialsProvider credentialsProvider ) { // The superclass caches the result of toMap(), which we don't want super(Collections.emptyMap()); this.region = region; this.url = url; this.credentialsProvider = credentialsProvider; } @Override public Map<String, Value> toMap() { final Map<String, Value> map = new HashMap<>(); map.put(SCHEME_KEY, Values.value(SCHEME)); map.put(PRINCIPAL_KEY, Values.value(DUMMY_USERNAME)); map.put(CREDENTIALS_KEY, new StringValue(getSignedHeader())); map.put(REALM_KEY, Values.value(REALM)); return map; } private String getSignedHeader() { final Request<Void> request = new DefaultRequest<>(SERVICE_NAME); request.setHttpMethod(HttpMethodName.GET); request.setEndpoint(URI.create(url)); // Comment out the following line if you're using an engine version older than 1.2.0.0 request.setResourcePath("/opencypher"); final AWS4Signer signer = new AWS4Signer(); signer.setRegionName(region); signer.setServiceName(request.getServiceName()); signer.sign(request, credentialsProvider.getCredentials()); return getAuthInfoJson(request); } private String getAuthInfoJson(final Request<Void> request) { final Map<String, Object> obj = new HashMap<>(); obj.put(AUTHORIZATION, request.getHeaders().get(AUTHORIZATION)); obj.put(HTTP_METHOD_HDR, request.getHttpMethod()); obj.put(X_AMZ_DATE, request.getHeaders().get(X_AMZ_DATE)); obj.put(HOST, request.getHeaders().get(HOST)); obj.put(X_AMZ_SECURITY_TOKEN, request.getHeaders().get(X_AMZ_SECURITY_TOKEN)); return gson.toJson(obj); } }
Contoh openCypher kueri Python menggunakan Bolt dengan otentikasi IAM
Kelas Python di bawah ini memungkinkan Anda membuat openCypher kueri dengan Python menggunakan Bolt dengan otentikasi: IAM
import json from neo4j import Auth from botocore.awsrequest import AWSRequest from botocore.credentials import Credentials from botocore.auth import ( SigV4Auth, _host_from_url, ) SCHEME = "basic" REALM = "realm" SERVICE_NAME = "neptune-db" DUMMY_USERNAME = "username" HTTP_METHOD_HDR = "HttpMethod" HTTP_METHOD = "GET" AUTHORIZATION = "Authorization" X_AMZ_DATE = "X-Amz-Date" X_AMZ_SECURITY_TOKEN = "X-Amz-Security-Token" HOST = "Host" class NeptuneAuthToken(Auth): def __init__( self, credentials: Credentials, region: str, url: str, **parameters ): # Do NOT add "/opencypher" in the line below if you're using an engine version older than 1.2.0.0 request = AWSRequest(method=HTTP_METHOD, url=url + "/opencypher") request.headers.add_header("Host", _host_from_url(request.url)) sigv4 = SigV4Auth(credentials, SERVICE_NAME, region) sigv4.add_auth(request) auth_obj = { hdr: request.headers[hdr] for hdr in [AUTHORIZATION, X_AMZ_DATE, X_AMZ_SECURITY_TOKEN, HOST] } auth_obj[HTTP_METHOD_HDR] = request.method creds: str = json.dumps(auth_obj) super().__init__(SCHEME, DUMMY_USERNAME, creds, REALM, **parameters)
Anda menggunakan kelas ini untuk membuat driver sebagai berikut:
authToken = NeptuneAuthToken(creds, REGION, URL) driver = GraphDatabase.driver(URL, auth=authToken, encrypted=True)
Contoh Node.js menggunakan IAM otentikasi dan Bolt
Kode Node.js di bawah ini menggunakan AWS SDK untuk JavaScript versi 3 dan ES6 sintaks untuk membuat driver yang mengautentikasi permintaan:
import neo4j from "neo4j-driver"; import { HttpRequest } from "@aws-sdk/protocol-http"; import { defaultProvider } from "@aws-sdk/credential-provider-node"; import { SignatureV4 } from "@aws-sdk/signature-v4"; import crypto from "@aws-crypto/sha256-js"; const { Sha256 } = crypto; import assert from "node:assert"; const region = "us-west-2"; const serviceName = "neptune-db"; const host = "(your cluster endpoint URL)"; const port = 8182; const protocol = "bolt"; const hostPort = host + ":" + port; const url = protocol + "://" + hostPort; const createQuery = "CREATE (n:Greeting {message: 'Hello'}) RETURN ID(n)"; const readQuery = "MATCH(n:Greeting) WHERE ID(n) = $id RETURN n.message"; async function signedHeader() { const req = new HttpRequest({ method: "GET", protocol: protocol, hostname: host, port: port, // Comment out the following line if you're using an engine version older than 1.2.0.0 path: "/opencypher", headers: { host: hostPort } }); const signer = new SignatureV4({ credentials: defaultProvider(), region: region, service: serviceName, sha256: Sha256 }); return signer.sign(req, { unsignableHeaders: new Set(["x-amz-content-sha256"]) }) .then((signedRequest) => { const authInfo = { "Authorization": signedRequest.headers["authorization"], "HttpMethod": signedRequest.method, "X-Amz-Date": signedRequest.headers["x-amz-date"], "Host": signedRequest.headers["host"], "X-Amz-Security-Token": signedRequest.headers["x-amz-security-token"] }; return JSON.stringify(authInfo); }); } async function createDriver() { let authToken = { scheme: "basic", realm: "realm", principal: "username", credentials: await signedHeader() }; return neo4j.driver(url, authToken, { encrypted: "ENCRYPTION_ON", trust: "TRUST_SYSTEM_CA_SIGNED_CERTIFICATES", maxConnectionPoolSize: 1, // logging: neo4j.logging.console("debug") } ); } function unmanagedTxn(driver) { const session = driver.session(); const tx = session.beginTransaction(); tx.run(createQuery) .then((res) => { const id = res.records[0].get(0); return tx.run(readQuery, { id: id }); }) .then((res) => { // All good, the transaction will be committed const msg = res.records[0].get("n.message"); assert.equal(msg, "Hello"); }) .catch(err => { // The transaction will be rolled back, now handle the error. console.log(err); }) .then(() => session.close()); } createDriver() .then((driver) => { unmanagedTxn(driver); driver.close(); }) .catch((err) => { console.log(err); });
SEBUAH. NET openCypher contoh kueri menggunakan Bolt dengan IAM otentikasi
Untuk mengaktifkan IAM otentikasi di. NET, Anda perlu menandatangani permintaan saat membuat koneksi. Contoh di bawah ini menunjukkan cara membuat NeptuneAuthToken
helper untuk menghasilkan token otentikasi:
using Amazon.Runtime; using Amazon.Util; using Neo4j.Driver; using System.Security.Cryptography; using System.Text; using System.Text.Json; using System.Web; namespace Hello { /* * Use this class instead of `AuthTokens.None` when working with an IAM-auth-enabled server. * * Note that authentication happens only the first time for a pooled connection. * * Typical usage: * * var authToken = new NeptuneAuthToken(AccessKey, SecretKey, Region).GetAuthToken(Host); * _driver = GraphDatabase.Driver(Url, authToken, o => o.WithEncryptionLevel(EncryptionLevel.Encrypted)); */ public class NeptuneAuthToken { private const string ServiceName = "neptune-db"; private const string Scheme = "basic"; private const string Realm = "realm"; private const string DummyUserName = "username"; private const string Algorithm = "AWS4-HMAC-SHA256"; private const string AWSRequest = "aws4_request"; private readonly string _accessKey; private readonly string _secretKey; private readonly string _region; private readonly string _emptyPayloadHash; private readonly SHA256 _sha256; public NeptuneAuthToken(string awsKey = null, string secretKey = null, string region = null) { var awsCredentials = awsKey == null || secretKey == null ? FallbackCredentialsFactory.GetCredentials().GetCredentials() : null; _accessKey = awsKey ?? awsCredentials.AccessKey; _secretKey = secretKey ?? awsCredentials.SecretKey; _region = region ?? FallbackRegionFactory.GetRegionEndpoint().SystemName; //ex: us-east-1 _sha256 = SHA256.Create(); _emptyPayloadHash = Hash(Array.Empty<byte>()); } public IAuthToken GetAuthToken(string url) { return AuthTokens.Custom(DummyUserName, GetCredentials(url), Realm, Scheme); } /******************** AWS SIGNING FUNCTIONS *********************/ private string Hash(byte[] bytesToHash) { return ToHexString(_sha256.ComputeHash(bytesToHash)); } private static byte[] HmacSHA256(byte[] key, string data) { return new HMACSHA256(key).ComputeHash(Encoding.UTF8.GetBytes(data)); } private byte[] GetSignatureKey(string dateStamp) { var kSecret = Encoding.UTF8.GetBytes($"AWS4{_secretKey}"); var kDate = HmacSHA256(kSecret, dateStamp); var kRegion = HmacSHA256(kDate, _region); var kService = HmacSHA256(kRegion, ServiceName); return HmacSHA256(kService, AWSRequest); } private static string ToHexString(byte[] array) { return Convert.ToHexString(array).ToLowerInvariant(); } private string GetCredentials(string url) { var request = new HttpRequestMessage { Method = HttpMethod.Get, RequestUri = new Uri($"https://{url}/opencypher") }; var signedrequest = Sign(request); var headers = new Dictionary<string, object> { [HeaderKeys.AuthorizationHeader] = signedrequest.Headers.GetValues(HeaderKeys.AuthorizationHeader).FirstOrDefault(), ["HttpMethod"] = HttpMethod.Get.ToString(), [HeaderKeys.XAmzDateHeader] = signedrequest.Headers.GetValues(HeaderKeys.XAmzDateHeader).FirstOrDefault(), // Host should be capitalized, not like in Amazon.Util.HeaderKeys.HostHeader ["Host"] = signedrequest.Headers.GetValues(HeaderKeys.HostHeader).FirstOrDefault(), }; return JsonSerializer.Serialize(headers); } private HttpRequestMessage Sign(HttpRequestMessage request) { var now = DateTimeOffset.UtcNow; var amzdate = now.ToString("yyyyMMddTHHmmssZ"); var datestamp = now.ToString("yyyyMMdd"); if (request.Headers.Host == null) { request.Headers.Host = $"{request.RequestUri.Host}:{request.RequestUri.Port}"; } request.Headers.Add(HeaderKeys.XAmzDateHeader, amzdate); var canonicalQueryParams = GetCanonicalQueryParams(request); var canonicalRequest = new StringBuilder(); canonicalRequest.Append(request.Method + "\n"); canonicalRequest.Append(request.RequestUri.AbsolutePath + "\n"); canonicalRequest.Append(canonicalQueryParams + "\n"); var signedHeadersList = new List<string>(); foreach (var header in request.Headers.OrderBy(a => a.Key.ToLowerInvariant())) { canonicalRequest.Append(header.Key.ToLowerInvariant()); canonicalRequest.Append(':'); canonicalRequest.Append(string.Join(",", header.Value.Select(s => s.Trim()))); canonicalRequest.Append('\n'); signedHeadersList.Add(header.Key.ToLowerInvariant()); } canonicalRequest.Append('\n'); var signedHeaders = string.Join(";", signedHeadersList); canonicalRequest.Append(signedHeaders + "\n"); canonicalRequest.Append(_emptyPayloadHash); var credentialScope = $"{datestamp}/{_region}/{ServiceName}/{AWSRequest}"; var stringToSign = $"{Algorithm}\n{amzdate}\n{credentialScope}\n" + Hash(Encoding.UTF8.GetBytes(canonicalRequest.ToString())); var signing_key = GetSignatureKey(datestamp); var signature = ToHexString(HmacSHA256(signing_key, stringToSign)); request.Headers.TryAddWithoutValidation(HeaderKeys.AuthorizationHeader, $"{Algorithm} Credential={_accessKey}/{credentialScope}, SignedHeaders={signedHeaders}, Signature={signature}"); return request; } private static string GetCanonicalQueryParams(HttpRequestMessage request) { var querystring = HttpUtility.ParseQueryString(request.RequestUri.Query); // Query params must be escaped in upper case (i.e. "%2C", not "%2c"). var queryParams = querystring.AllKeys.OrderBy(a => a) .Select(key => $"{key}={Uri.EscapeDataString(querystring[key])}"); return string.Join("&", queryParams); } } }
Berikut adalah cara membuat openCypher kueri di. NETmenggunakan Bolt dengan IAM otentikasi. Contoh di bawah ini menggunakan NeptuneAuthToken
helper:
using Neo4j.Driver; namespace Hello { public class HelloWorldExample { private const string Host = "
(your hostname)
:8182"; private const string Url = $"bolt://{Host}"; private const string CreateNodeQuery = "CREATE (a:Greeting) SET a.message = 'HelloWorldExample'"; private const string ReadNodeQuery = "MATCH(n:Greeting) RETURN n.message"; private const string AccessKey = "(your access key)
"; private const string SecretKey = "(your secret key)
"; private const string Region = "(your AWS region)
"; // e.g. "us-west-2" private readonly IDriver _driver; public HelloWorldExample() { var authToken = new NeptuneAuthToken(AccessKey, SecretKey, Region).GetAuthToken(Host); // Note that when the connection is reinitialized after max connection lifetime // has been reached, the signature token could have already been expired (usually 5 min) // You can face exceptions like: // `Unexpected server exception 'Signature expired: XXXX is now earlier than YYYY (ZZZZ - 5 min.)` _driver = GraphDatabase.Driver(Url, authToken, o => o.WithMaxConnectionLifetime(TimeSpan.FromMinutes(60)).WithEncryptionLevel(EncryptionLevel.Encrypted)); } public async Task CreateNode() { // Open a session using (var session = _driver.AsyncSession()) { // Run the query in a write transaction var greeting = await session.WriteTransactionAsync(async tx => { var result = await tx.RunAsync(CreateNodeQuery); // Consume the result return await result.ConsumeAsync(); }); // The output will look like this: // ResultSummary{Query=`CREATE (a:Greeting) SET a.message = 'HelloWorldExample"..... Console.WriteLine(greeting.Query); } } public async Task RetrieveNode() { // Open a session using (var session = _driver.AsyncSession()) { // Run the query in a read transaction var greeting = await session.ReadTransactionAsync(async tx => { var result = await tx.RunAsync(ReadNodeQuery); var records = await result.ToListAsync(); // Consume the result. Read the single node // created in a previous step. return records[0].Values.First().Value; }); // The output will look like this: // HelloWorldExample Console.WriteLine(greeting); } } } }
Contoh ini dapat diluncurkan dengan menjalankan kode di bawah ini pada .NET 6
atau .NET 7
dengan paket-paket berikut:
Neo4j
.Driver=4.3.0
AWSSDK
.Core=3.7.102.1
namespace Hello { class Program { static async Task Main() { var apiCaller = new HelloWorldExample(); await apiCaller.CreateNode(); await apiCaller.RetrieveNode(); } } }
Contoh openCypher kueri Golang menggunakan Bolt dengan IAM otentikasi
Paket Golang di bawah ini menunjukkan cara membuat openCypher kueri dalam bahasa Go menggunakan Bolt dengan IAM otentikasi:
package main import ( "context" "encoding/json" "fmt" "github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/aws/signer/v4" "github.com/neo4j/neo4j-go-driver/v5/neo4j" "log" "net/http" "os" "time" ) const ( ServiceName = "neptune-db" DummyUsername = "username" ) // Find node by id using Go driver func findNode(ctx context.Context, region string, hostAndPort string, nodeId string) (string, error) { req, err := http.NewRequest(http.MethodGet, "https://"+hostAndPort+"/opencypher", nil) if err != nil { return "", fmt.Errorf("error creating request, %v", err) } // credentials must have been exported as environment variables signer := v4.NewSigner(credentials.NewEnvCredentials()) _, err = signer.Sign(req, nil, ServiceName, region, time.Now()) if err != nil { return "", fmt.Errorf("error signing request: %v", err) } hdrs := []string{"Authorization", "X-Amz-Date", "X-Amz-Security-Token"} hdrMap := make(map[string]string) for _, h := range hdrs { hdrMap[h] = req.Header.Get(h) } hdrMap["Host"] = req.Host hdrMap["HttpMethod"] = req.Method password, err := json.Marshal(hdrMap) if err != nil { return "", fmt.Errorf("error creating JSON, %v", err) } authToken := neo4j.BasicAuth(DummyUsername, string(password), "") // +s enables encryption with a full certificate check // Use +ssc to disable client side TLS verification driver, err := neo4j.NewDriverWithContext("bolt+s://"+hostAndPort+"/opencypher", authToken) if err != nil { return "", fmt.Errorf("error creating driver, %v", err) } defer driver.Close(ctx) if err := driver.VerifyConnectivity(ctx); err != nil { log.Fatalf("failed to verify connection, %v", err) } config := neo4j.SessionConfig{} session := driver.NewSession(ctx, config) defer session.Close(ctx) result, err := session.Run( ctx, fmt.Sprintf("MATCH (n) WHERE ID(n) = '%s' RETURN n", nodeId), map[string]any{}, ) if err != nil { return "", fmt.Errorf("error running query, %v", err) } if !result.Next(ctx) { return "", fmt.Errorf("node not found") } n, found := result.Record().Get("n") if !found { return "", fmt.Errorf("node not found") } return fmt.Sprintf("+%v\n", n), nil } func main() { if len(os.Args) < 3 { log.Fatal("Usage: go main.go
(region) (host and port)
") } region := os.Args[1] hostAndPort := os.Args[2] ctx := context.Background() res, err := findNode(ctx, region, hostAndPort, "72c2e8c1-7d5f-5f30-10ca-9d2bb8c4afbc") if err != nil { log.Fatal(err) } fmt.Println(res) }
Perilaku koneksi baut di Neptunus
Berikut adalah beberapa hal yang perlu diingat tentang koneksi Neptunus Bolt:
Karena koneksi Bolt dibuat di TCP layer, Anda tidak dapat menggunakan Application Load Balancer di depannya, seperti yang Anda bisa dengan endpoint. HTTP
Port yang digunakan Neptunus untuk koneksi Bolt adalah port cluster DB Anda.
Berdasarkan pembukaan Bolt yang diteruskan ke sana, server Neptunus memilih versi Bolt tertinggi yang sesuai (1, 2, 3, atau 4.0).
Jumlah maksimum koneksi ke server Neptunus yang dapat dibuka klien kapan saja adalah 1.000.
Jika klien tidak menutup koneksi setelah kueri, koneksi itu dapat digunakan untuk menjalankan kueri berikutnya.
Namun, jika koneksi menganggur selama 20 menit, server menutupnya secara otomatis.
-
Jika IAM otentikasi tidak diaktifkan, Anda dapat menggunakan
AuthTokens.none()
daripada memberikan nama pengguna dan kata sandi dummy. Misalnya, di Jawa:GraphDatabase.driver("bolt://
(your cluster endpoint URL)
:(your cluster port)
", AuthTokens.none(), Config.builder().withEncryption().withTrustStrategy(TrustStrategy.trustSystemCertificates()).build()); Ketika IAM otentikasi diaktifkan, koneksi Bolt selalu terputus beberapa menit lebih dari 10 hari setelah dibuat jika belum ditutup karena alasan lain.
Jika klien mengirim kueri untuk dieksekusi melalui koneksi tanpa menghabiskan hasil kueri sebelumnya, kueri baru akan dibuang. Untuk membuang hasil sebelumnya, klien harus mengirim pesan reset melalui koneksi.
Hanya satu transaksi pada satu waktu yang dapat dibuat pada koneksi tertentu.
Jika pengecualian terjadi selama transaksi, server Neptunus memutar kembali transaksi dan menutup koneksi. Dalam hal ini, driver membuat koneksi baru untuk kueri berikutnya.
Ketahuilah bahwa sesi tidak aman untuk utas. Beberapa operasi paralel harus menggunakan beberapa sesi terpisah.