neo4j-php / neo4j-php-client

Php client and driver for neo4j database
https://neo4j.com/developer/php/
MIT License
166 stars 41 forks source link

Cannot connect to Neo4j Aura cloud instance #24

Closed evan-duncan closed 3 years ago

evan-duncan commented 3 years ago

I'm trying to connect to an Aura cloud instance and I'm getting the following stack trace:

GET / - Uncaught Bolt\error\ConnectException: Read error in src/github.com/evan-duncan/prototype/vendor/stefanak-michal/bolt/src/connection/StreamSocket.php:97
Stack trace:
#0 /src/github.com/evan-duncan/prototype/vendor/stefanak-michal/bolt/src/Bolt.php(161): Bolt\connection\StreamSocket->read(4)
#1 src/github.com/evan-duncan/prototype/vendor/stefanak-michal/bolt/src/Bolt.php(140): Bolt\Bolt->unpackProtocolVersion()
#2 src/github.com/evan-duncan/prototype/vendor/stefanak-michal/bolt/src/Bolt.php(214): Bolt\Bolt->handshake()
#3 src/github.com/evan-duncan/prototype/vendor/laudis/neo4j-php-client/src/Network/Bolt/BoltDriver.php(66): Bolt\Bolt->init('LaudisNeo4j/1.0...', 'username', 'password...')
#4 src/github.com/evan-duncan/prototype/vendor/laudis/neo4j-php-client/src/Client.php(52): Laudis\Neo4j\Network\Bolt\BoltDriver->aquireSession()
#5 src/github.com/evan-duncan/prototype/vendor/laudis/neo4j-php-client/src/Client.php(46): Laudis\Neo4j\Client->runStatements(Array, NULL)
#6 src/github.com/evan-duncan/prototype/vendor/laudis/neo4j-php-client/src/Client.php(41): Laudis\Neo4j\Client->runStatement(Object(Laudis\Neo4j\Databags\Statement), NULL)
... removed rest of library code that is irrelevant

I see a related issue here https://github.com/stefanak-michal/Bolt/issues/38

transistive commented 3 years ago

Hi Evan,

Thank you for reporting this issue. When I quickly glance over this, I will have to extend the configuration options for bolt connections before this is going to work. I will try and fix this as soon as possible. This will probably be fixed by Sunday.

In the meantime, can you check if you receive the same error when using an HTTP exception?

Kind regards,

Ghlen

evan-duncan commented 3 years ago

Ghlen,

When attempting to connect via http I get a timeout exception. Aura doesn't seem to have any docs on http fallbacks -- the only URIs they publish are either for bolt protocol or for cluster protocol, and TLS is required. To test HTTP I took the URI I was using for the bolt protocol and changed the protocol to HTTPS, but I get a connection timeout.


GET / - Uncaught GuzzleHttp\Exception\ConnectException: cURL error 28: Failed to connect to $host port 7678: Operation timed out (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) for https://$host:7678 in src/github.com/evan-duncan/prototype/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php:210
Stack trace:
#0 src/github.com/evan-duncan/prototype/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php(158): GuzzleHttp\Handler\CurlFactory::createRejection(Object(GuzzleHttp\Handler\EasyHandle), Array)
#1 src/github.com/evan-duncan/prototype/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php(110): GuzzleHttp\Handler\CurlFactory::finishError(Object(GuzzleHttp\Handler\CurlHandler), Object(GuzzleHttp\Handler\EasyHandle), Object(GuzzleHttp\Handler\CurlFactory))
#2 src/github.com/evan-duncan/prototype/vendor/guzzlehttp/guzzle/src/Handler/CurlHandler.php(47): GuzzleHttp\Handler\CurlFactory::finish(Object(GuzzleHttp\Handler\CurlHandler), Object(GuzzleHttp\Handler\EasyHandle), Object(GuzzleHttp\Handler\CurlFactory))
#3 src/github.com/evan-duncan/prototype/vendor/guzzlehttp/guzzle/src/Handler/Proxy.php(28): GuzzleHttp\Handler\CurlHandler->__invoke(Object(GuzzleHttp\Psr7\Request), Array)
#4 src/github.com/evan-duncan/prototype/vendor/guzzlehttp/guzzle/src/Handler/Proxy.php(48): GuzzleHttp\Handler\Proxy::GuzzleHttp\Handler\{closure}(Object(GuzzleHttp\Psr7\Request), Array)
#5 src/github.com/evan-duncan/prototype/vendor/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php(35): GuzzleHttp\Handler\Proxy::GuzzleHttp\Handler\{closure}(Object(GuzzleHttp\Psr7\Request), Array)
#6 src/github.com/evan-duncan/prototype/vendor/guzzlehttp/guzzle/src/Middleware.php(31): GuzzleHttp\PrepareBodyMiddleware->__invoke(Object(GuzzleHttp\Psr7\Request), Array)
#7 src/github.com/evan-duncan/prototype/vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php(55): GuzzleHttp\Middleware::GuzzleHttp\{closure}(Object(GuzzleHttp\Psr7\Request), Array)
#8 src/github.com/evan-duncan/prototype/vendor/guzzlehttp/guzzle/src/Middleware.php(61): GuzzleHttp\RedirectMiddleware->__invoke(Object(GuzzleHttp\Psr7\Request), Array)
#9 src/github.com/evan-duncan/prototype/vendor/guzzlehttp/guzzle/src/HandlerStack.php(75): GuzzleHttp\Middleware::GuzzleHttp\{closure}(Object(GuzzleHttp\Psr7\Request), Array)
#10 src/github.com/evan-duncan/prototype/vendor/guzzlehttp/guzzle/src/Client.php(331): GuzzleHttp\HandlerStack->__invoke(Object(GuzzleHttp\Psr7\Request), Array)
#11 src/github.com/evan-duncan/prototype/vendor/guzzlehttp/guzzle/src/Client.php(107): GuzzleHttp\Client->transfer(Object(GuzzleHttp\Psr7\Request), Array)
#12 src/github.com/evan-duncan/prototype/vendor/guzzlehttp/guzzle/src/Client.php(137): GuzzleHttp\Client->sendAsync(Object(Laminas\Diactoros\Request), Array)
#13 src/github.com/evan-duncan/prototype/vendor/laudis/neo4j-php-client/src/Network/VersionDiscovery.php(84): GuzzleHttp\Client->sendRequest(Object(Laminas\Diactoros\Request))
#14 src/github.com/evan-duncan/prototype/vendor/laudis/neo4j-php-client/src/Network/VersionDiscovery.php(65): Laudis\Neo4j\Network\VersionDiscovery->discovery(Object(Laudis\Neo4j\Databags\RequestData))
#15 src/github.com/evan-duncan/prototype/vendor/laudis/neo4j-php-client/src/Network/Http/HttpDriver.php(69): Laudis\Neo4j\Network\VersionDiscovery->discoverTransactionUrl(Object(Laudis\Neo4j\Databags\RequestData), 'neo4j')
#16 src/github.com/evan-duncan/prototype/vendor/laudis/neo4j-php-client/src/Client.php(52): Laudis\Neo4j\Network\Http\HttpDriver->aquireSession()
#17 src/github.com/evan-duncan/prototype/vendor/laudis/neo4j-php-client/src/Client.php(46): Laudis\Neo4j\Client->runStatements(Array, NULL)
#18 src/github.com/evan-duncan/prototype/vendor/laudis/neo4j-php-client/src/Client.php(41): Laudis\Neo4j\Client->runStatement(Object(Laudis\Neo4j\Databags\Statement), NULL)
... removed rest of library code that is irrelevant
transistive commented 3 years ago

Thank you for the heads up! I'll try and fix this ASAP.

transistive commented 3 years ago

Hello Evan, I updated to code to make it possible to tweak the SSL context options. You can find it in version 1.1.3. Here is an example:

$client = ClientBuilder::create()
    ->addBoltConnection('main', 'my-bolt-connection@somewhereinthecloud', BoltInjections::create()->withSslContextOptions([ 
          'verify_peer' => true,
          'allow_self_signed' => true
    ])
    ->build();

As I have no way of knowing this works without having access to the service, can you test it for me? Once I get confirmation it works, I will close the issue.

evan-duncan commented 3 years ago

I'm still having issues. Now I'm getting connection refused errors no matter how I configure it. I wrote a test against the stream socket directly and this will connect from my dev machine. I can't get my dev machine to connect through the client builder.

<?php

require 'vendor/autoload.php';

$url = 'foo.databases.neo4j.io';
$conn = new \Bolt\connection\StreamSocket($url, 7687);
$conn->setSslContextOptions([
    'verify_peer' => true,
    'allow_self_signed' => true,
]);

$bolt = new \Bolt\Bolt($conn);
$bolt->init('Test', 'username', 'password');

var_dump($bolt->run('MATCH (c:Category) RETURN c'));
$ php test.php
array(2) {
  ["t_first"]=>
  int(60)
  ["fields"]=>
  array(1) {
    [0]=>
    string(1) "c"
  }

edit: for clarity I tried connecting using "neo4j+s://user:pass@host:port" and it wasn’t until I reduced the uri to just the host that I could properly connect. I think the connection url needs to be reduced and strip out user:pass to connect

evan-duncan commented 3 years ago

I looked through the code and does look like you are passing the URL. Let me change my test to go through this lib

evan-duncan commented 3 years ago

Alright I got this to connect not converting the host to an IP. Removing this block https://github.com/laudis-technologies/neo4j-php-client/blob/main/src/Network/Bolt/BoltDriver.php#L60-L64. Is there a way for me to not allow my hostname to be converted to an IP? I'm also not sure why the IP would refuse the connection, but here we are.

transistive commented 3 years ago

Interesting! I haven't introduced a way to do this, but I will. I'll try and patch it up later on tonight!

transistive commented 3 years ago

It seems the step of translating the hostname to IP is completely superfluous. I have removed the suggested lines of yours. Can you confirm it works in version 1.1.4?

Thanks in advance!

evan-duncan commented 3 years ago

It's not published to packagist yet but I will test it once it is.

evan-duncan commented 3 years ago

Ah nevermind I just pulled it from github and it's working. 🎉 . Thanks Ghlen!

transistive commented 3 years ago

Thanks for the feedback! The version tags are supposed to update automatically with packagist, but it is sometimes botched :shrug: It should now be available through composer within 10 minutes.

Have a good day/evening!