I am doing some dev-ops work in the AWS environment (unmanaged) with Neo4j Enterprise causal cluster using version 3.5.8. I would like to be able to add a new user from an Ubuntu bash command line. The best resource I have found so far is here:
If there is a plugin or something I can add to the environment to enable this, that's fine. And if there is something in Neo4j's roadmap, that is interesting too. I didn't see anything in the change log for the future Neo4j 4.0
If you have neo4j installed on a machine, you'll get the cypher-shell command.
You can use cypher-shell as part of bash scripts or any other automation approach to execute queries against a Neo4j cluster. Make sure to use bolt+routing://my-neo4j-endpoint:7687 to ensure that you're always talking to the cluster, and not just one individual node.
Thanks for showing how to put this together! I have been playing with the technique, and have found a way to create a user and set that user's native role in a single line. (Expressing it all in a single line seems to be really important to our dev ops guy.)
But the limitation I have found is with specifying the endpoint. I have 3 members in a causal cluster. I feel that the "bolt+routing" part should find the right server regardless of which of those three servesr I name.
At the moment 7688 is my 'write' server. If I specify that one it works; it creates a new user. But if I specify 7689 or 7690, I get an error message: "Could not perform discovery. No routing servers available." The problem is that this script can't drop down into cypher-shell. It just has to pass in parameter.
Shouldn't it automatically find the write server?
I am testing this in a Docker container on Ubuntu, also in a Docker container on OSX. Both environments work the same.
It should automatically find the write server irrespective of what port you connect to. But this in turn requires that each of your cluster nodes running in Docker have the correct default_advertised_address setting, which is what gets published to your client, and that you've verified causal clustering is working correctly.
When you connect to any node in the cluster, you can run CALL dbms.cluster.overview() to see roughly what the client sees. If that is missing any entry or is advertising the wrong addresses, it means you have a configuration issue with your cluster.
Thank you Dana.
Can you confirm two more points around routing for me?
The routing protocol ( bolt+routing) works only in a cluster setup. It will fail on a single instance setup. If I am on a single instance I have to drop the +routing part of the protocol.
Routing in a cluster only works from the leader to followers, not from followers to leader. Followers know who the other members are, including leader, but if you write to a follower it will not pass that request to the leader.
The above is what I am experiencing. If I am wrong on either then I will continue investigating.
yes. today bolt+routing:// will fail on a single instance non-clustered Neo4j setup.
a WRITE sent to a follower will foward it to the LEADER if
a. you connect with bolt+routing://
and
b. you have defined the transaction as a WRITE transaction, for example via session.WriteTransactionNeo4j documentation - Neo4j Documentation
When writing queries from Neo4j Desktop does Neo4j Desktop work out what the cypher is doing and then wrap the request in the correct Transaction type (read or write)?
I managed to use the session.WriteTransaction in a Python script. Is it possible to specify 'session.WriteTransaction' in a cypher-shell command, or from a bash prompt, or is it necessary for that to come from one of the language API's java/go/c++/python/javascript..?
Neo4j Browser is a Neo4j Bolt Javascript enabled client and cypher-shell is a Neo4j Bolt Java enabled client. As each does not allow you to specify whether the cypher is a READ or WRITE, it must send each as a WRITE so as not to result in error. Thus all cypher statements will go to the leader.
Okay, that's useful to know, so now I understand why the browser and cypher-shell just work. I don't have to worry about sending a session.WriteTransaction along with my cypher-shell request because that decision has already been made for me, it's already wrapped in one.
It's also good to know that when I send a session.WriteTransaction it doesn't specifically mean that the cypher has to execute a CRUD operation; it just means route this to a (the) server that can write. If it doesn't update something, no biggie.
And finally, by deduction, the only way I can send a session.ReadTransaction is via one of the bolt language drivers (Drivers & Language Guides - Developer Guides) or something that uses one of those.
Thanks @david.allen & @dana.canzano for helping me navigate causal cluster routing and user management. This thread has cleared up a lot of vague questions I've had around routing, I expect it will be useful to others too, particularly those not using LDAP.