cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

4.x server-side routing on Aura

jgaskins
Ninja
Ninja

I'm working on updating my Crystal Neo4j connector to the latest protocols and I'm struggling a bit. I've got a 3-node cluster running on Neo4j Aura, and when I send my ROUTE command, I get back this structure:

 

{"servers" =>
  [{"addresses" =>
     ["neo4j-core-3c0aa8ce-2.production-orch-0178.neo4j.io:7687"],
    "role" => "WRITE"},
   {"addresses" =>
     ["neo4j-core-3c0aa8ce-3.production-orch-0178.neo4j.io:7687",
      "neo4j-core-3c0aa8ce-1.production-orch-0178.neo4j.io:7687"],
    "role" => "READ"},
   {"addresses" =>
     ["neo4j-core-3c0aa8ce-1.production-orch-0178.neo4j.io:7687",
      "neo4j-core-3c0aa8ce-2.production-orch-0178.neo4j.io:7687",
      "neo4j-core-3c0aa8ce-3.production-orch-0178.neo4j.io:7687"],
    "role" => "ROUTE"}],
 "ttl" => 10,
 "db" => "neo4j"}

 

It seems that we need to use server-side routing with Aura because all 3 of those domains resolve to the same IP address (presumably an L4 load balancer) so it isn't possible to do client-side routing at all for this cluster. That seems fine, the documentation says that adding routing: {} to my HELLO command will instruct the server to handle routing:

 

hello Map{
  "scheme"      => "basic",
  "principal"   => username,
  "credentials" => password,
  "user_agent"  => "Neo4j.cr/#{VERSION}",
  "routing"     => Map.new,
}

 

Except it's not working. I keep getting this error:

 

[Neo.ClientError.Cluster.NotALeader] No write operations are allowed directly on this database. Writes must pass through the leader. The role of this server is: FOLLOWER

 

Is there more I need to do to tell the server to handle routing?

1 ACCEPTED SOLUTION

While you're correct that those different DNS names resolve to the same IP and there is another layer involved in the implementation architecture, it isn't generally safe to just resolve the IP address in the way you're doing.  The routing table on Aura provides those different DNS names because the different DNS names are still relevant.

I believe Aura is using TLS SNI, so that the intermediate layer knows where to send the traffic.  Routing the traffic to the right cluster member matters of course so that writes get routed to the causal cluster leader.

Because the other Neo4j drivers are open source, a good way to approach this might be to study the closest supported driver in its protocol behavior back and forth, as routed queries do work with these same routing tables on the java, JS, python, and .NET drivers.

View solution in original post

2 REPLIES 2

While you're correct that those different DNS names resolve to the same IP and there is another layer involved in the implementation architecture, it isn't generally safe to just resolve the IP address in the way you're doing.  The routing table on Aura provides those different DNS names because the different DNS names are still relevant.

I believe Aura is using TLS SNI, so that the intermediate layer knows where to send the traffic.  Routing the traffic to the right cluster member matters of course so that writes get routed to the causal cluster leader.

Because the other Neo4j drivers are open source, a good way to approach this might be to study the closest supported driver in its protocol behavior back and forth, as routed queries do work with these same routing tables on the java, JS, python, and .NET drivers.

SNI was indeed the issue. The funny thing is that I'd been setting the SNI hostname (if it's not explicitly set, Aura terminates the connection), but I had an error that I guess I assumed was also SNI, so I changed it to the entrypoint hostname. This all makes sense in hindsight. Looks like I was making too many changes at once. Thanks!