Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Neo4J Quarkus can't be configured for SSL #19412

Closed
sdaschner opened this issue Aug 16, 2021 · 15 comments · Fixed by #20564
Closed

Neo4J Quarkus can't be configured for SSL #19412

sdaschner opened this issue Aug 16, 2021 · 15 comments · Fixed by #20564
Labels
area/neo4j kind/bug Something isn't working
Milestone

Comments

@sdaschner
Copy link
Contributor

Describe the bug

Using a database URI with encryption makes the application startup fail:

Failed to start application (with profile dev): org.neo4j.driver.exceptions.ClientException: Scheme neo4j+s is not configurable with manual encryption and trust settings
	at org.neo4j.driver.internal.SecuritySettings.assertSecuritySettingsNotUserConfigured(SecuritySettings.java:87)
	at org.neo4j.driver.internal.SecuritySettings.createSecurityPlan(SecuritySettings.java:69)
	at org.neo4j.driver.GraphDatabase.driver(GraphDatabase.java:138)
	at org.neo4j.driver.GraphDatabase.driver(GraphDatabase.java:121)
	at io.quarkus.neo4j.runtime.Neo4jDriverRecorder.initializeDriver(Neo4jDriverRecorder.java:43)
	at io.quarkus.deployment.steps.Neo4jDriverProcessor$configureDriverProducer928533785.deploy_0(Neo4jDriverProcessor$configureDriverProducer928533785.zig:87)
	at io.quarkus.deployment.steps.Neo4jDriverProcessor$configureDriverProducer928533785.deploy(Neo4jDriverProcessor$configureDriverProducer928533785.zig:40)
	at io.quarkus.runner.ApplicationImpl.doStart(ApplicationImpl.zig:579)
	at io.quarkus.runtime.Application.start(Application.java:101)
	at io.quarkus.runtime.ApplicationLifecycleManager.run(ApplicationLifecycleManager.java:101)
	at io.quarkus.runtime.Quarkus.run(Quarkus.java:66)
	at io.quarkus.runtime.Quarkus.run(Quarkus.java:42)
	at io.quarkus.runtime.Quarkus.run(Quarkus.java:119)
	at io.quarkus.runner.GeneratedMain.main(GeneratedMain.zig:29)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:567)
	at io.quarkus.runner.bootstrap.StartupActionImpl$1.run(StartupActionImpl.java:98)
	at java.base/java.lang.Thread.run(Thread.java:853)

The issue is caused by a default "change" in the configuration in the quarkus-neo4j code in Neo4jDriverRecorder#configureSsl, which causes the code in org.neo4j.driver.internal.SecuritySettings to override the defaults, regardless of what we put into our Quarkus properties file.

Expected behavior

No response

Actual behavior

No response

How to Reproduce?

Start up Quarkus with any Neo4J instance that uses an encrypted connection, e.g. using Neo4J Aura Free and connect using the URI: neo4j+s://xxxxxx123.databases.neo4j.io

Output of uname -a or ver

No response

Output of java -version

16

GraalVM version (if different from Java)

No response

Quarkus version or git rev

2.1.2.Final

Build tool (ie. output of mvnw --version or gradlew --version)

No response

Additional information

This issue might be resolved by just removing lines 119-125 in Neo4jDriverRecorder. The default config should work correctly then.

@sdaschner sdaschner added the kind/bug Something isn't working label Aug 16, 2021
@quarkus-bot
Copy link

quarkus-bot bot commented Aug 16, 2021

/cc @michael-simons

@michael-simons
Copy link
Contributor

michael-simons commented Aug 16, 2021

Yep I did notice that too.

I run it like this

quarkus.neo4j.encrypted=true
quarkus.neo4j.uri=neo4j://xxxxxx123.databases.neo4j.io

and don't use the +s, +ssc protocol additions, that are connivence methods anyway for everything that you can configure explicitly.

(This is not a theoretical advice, this is from https://neo4j-aura-quarkus-graphql.herokuapp.com, a Quarkus app running on Heroku against aura free).

@sdaschner
Copy link
Contributor Author

Thanks for the quick response! 👍

However, that doesn't work for me:

org.neo4j.driver.exceptions.ServiceUnavailableException: Failed to perform multi-databases feature detection with the following servers: [c30ccb07.databases.neo4j.io(34.78.76.49):7687]
	at org.neo4j.driver.internal.cluster.loadbalancing.LoadBalancer.supportsMultiDb(LoadBalancer.java:153)
	at org.neo4j.driver.internal.cluster.loadbalancing.LoadBalancer.verifyConnectivity(LoadBalancer.java:117)
	at org.neo4j.driver.internal.SessionFactoryImpl.verifyConnectivity(SessionFactoryImpl.java:73)
	at org.neo4j.driver.internal.InternalDriver.verifyConnectivityAsync(InternalDriver.java:141)
	at org.neo4j.driver.internal.InternalDriver.verifyConnectivity(InternalDriver.java:159)
	at org.neo4j.ogm.drivers.bolt.driver.BoltDriver.initializeDriver(BoltDriver.java:170)
[...]
Resulted in: org.neo4j.driver.exceptions.ServiceUnavailableException: Unable to connect to database management service, ensure the database is running and that there is a working network connection to it.
	at org.neo4j.driver.internal.util.Futures.blockingGet(Futures.java:143)
	at org.neo4j.driver.internal.util.Futures.blockingGet(Futures.java:113)
	... 69 more
Resulted in: org.neo4j.ogm.exception.ConnectionException: Could not create driver instance
	at org.neo4j.ogm.drivers.bolt.driver.BoltDriver.initializeDriver(BoltDriver.java:174)
	... 67 more
Resulted in: org.jboss.resteasy.spi.UnhandledException: org.neo4j.ogm.exception.ConnectionException: Could not create driver instance
	at org.jboss.resteasy.core.ExceptionHandler.handleApplicationException(ExceptionHandler.java:106)
	at org.jboss.resteasy.core.ExceptionHandler.handleException(ExceptionHandler.java:372)
	at org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:218)
	at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:519)
	... 17 more

I've used:

quarkus.neo4j.uri=neo4j://c30ccb07.databases.neo4j.io
quarkus.neo4j.encrypted=true
quarkus.neo4j.authentication.username=neo4j
quarkus.neo4j.authentication.password=[...]

Now, is this an Aura Free issue or another Quarkus configuration?

@michael-simons
Copy link
Contributor

Very welcome :)

You are most likely not passing the driver instance created by Quarkus via the properties to Neo4j-OGM.

Make sure you have an application scoped producer of a session factory like this:
https://github.com/michael-simons/neo4j-from-the-jvm-ecosystem/blob/master/quarkus-ogm/src/main/java/org/neo4j/examples/jvm/quarkus/ogm/support/Neo4jOGMConfig.java#L37

OGM will only use initializeDriver when there's no driver (a literal null instance) https://github.com/neo4j/neo4j-ogm/blob/3.2.x/bolt-driver/src/main/java/org/neo4j/ogm/drivers/bolt/driver/BoltDriver.java#L156

@michael-simons
Copy link
Contributor

Oh wait, it's a bit worrying though…

@injectives what could be the cause of:

org.neo4j.driver.exceptions.ServiceUnavailableException: Failed to perform multi-databases feature detection with the following servers: [XXX.databases.neo4j.io(XXX):7687]

Driver incompatibility? And if so, we doesn't it affect my setup?

@sdaschner
Copy link
Contributor Author

sdaschner commented Aug 16, 2021

Interesting 🤔

Well, kind of, I have a CDI producer that emits a SessionFactory, but I used the Configuration manually (with injected config values) instead of the available driver:

    @Produces
    SessionFactory produceSessionFactory() {
        Configuration neoConfig = new Configuration.Builder()
                .uri(databaseUri)
                .credentials(username, password)
                .useNativeTypes()
                .build();

        return new SessionFactory(neoConfig, PACKAGES);
    }

Switching to injecting the Driver worked!

But yes, would be interesting to know. If I use above code in a manual test (without Quarkus) it also fails with the same exception...

@michael-simons
Copy link
Contributor

The quarkus provided driver does not call verifyConnectivity() and I guess if it would, it would fail too.

So do I understand correctly: You use quarkus properties injected into OGM properties? Not that it doesn't change anything here, I am just curious

@sdaschner
Copy link
Contributor Author

So do I understand correctly: You use quarkus properties injected into OGM properties? Not that it doesn't change anything here, I am just curious

I've injected the @ConfigProperty values to access the Quarkus properties in my producer. The class was:

@ApplicationScoped
public class SessionFactoryProducer {

    public static final String[] PACKAGES = {"com.sebastian_daschner.coffee.beans.entity"};

    @ConfigProperty(name = "quarkus.neo4j.uri")
    String databaseUri;

    @ConfigProperty(name = "quarkus.neo4j.authentication.username")
    String username;

    @ConfigProperty(name = "quarkus.neo4j.authentication.password")
    String password;

    @Produces
    SessionFactory produceSessionFactory() {
        Configuration neoConfig = new Configuration.Builder()
                .uri(databaseUri)
                .credentials(username, password)
                .useNativeTypes()
                .build();

        return new SessionFactory(neoConfig, PACKAGES);
    }

    void disposeSessionFactory(@Disposes SessionFactory sessionFactory) {
        sessionFactory.close();
    }
}

Btw, IDK if the native types might produce another issue if we just use the Quarkus-provided driver? :)

@michael-simons
Copy link
Contributor

Config makes sense.
No, the types should not make a difference. "Native" here means date and time types native to Neo4j, and not string based properties.

@sdaschner
Copy link
Contributor Author

Btw are there some plans to fix this (the original issue with neo4j+s)? I could come up with a PR, but I probably don't have all the scenarios & permutations to test this.

@injectives
Copy link

Oh wait, it's a bit worrying though…

@injectives what could be the cause of:

org.neo4j.driver.exceptions.ServiceUnavailableException: Failed to perform multi-databases feature detection with the following servers: [XXX.databases.neo4j.io(XXX):7687]

Driver incompatibility? And if so, we doesn't it affect my setup?

Failure to acquire a working connection towards a routing server. More details here: neo4j/neo4j-java-driver#986 (comment)

@gsmet
Copy link
Member

gsmet commented Aug 20, 2021

Not sure if the Quarkus team can do anything here? @michael-simons maybe some adjustments in the doc are needed?

I'll let you judge of that but if we can't do anything on our side, I would be in favor of closing the issue.

@sandronm
Copy link

sandronm commented Oct 5, 2021

Yep I did notice that too.

I run it like this

quarkus.neo4j.encrypted=true
quarkus.neo4j.uri=neo4j://xxxxxx123.databases.neo4j.io

and don't use the +s, +ssc protocol additions, that are connivence methods anyway for everything that you can configure explicitly.

(This is not a theoretical advice, this is from https://neo4j-aura-quarkus-graphql.herokuapp.com, a Quarkus app running on Heroku against aura free).

Hello, is it still the official recommandation of Neo4J when we are using the Driver to create the SessionFactory?

As reminder:

    @Produces
    @ApplicationScoped
    SessionFactory produceSessionFactory(Driver driver) {
        var sessionFactory = new SessionFactory(new BoltDriver(driver), "my.package");
        return sessionFactory;
    }

We are just facing the original issue "Failed to start application (with profile dev): org.neo4j.driver.exceptions.ClientException: Scheme neo4j+s is not configurable with manual encryption and trust settings" at the moment and I'm wondering if this recommandation is still the only one available.

@michael-simons
Copy link
Contributor

Hi @sandronm this is now mixing in OGM for good measures, right?
Anyhow: If you pass in configured instance of org.neo4j.driver.Driver to OGM's org.neo4j.ogm.drivers.bolt.driver.BoltDriver it will be used as is, we are not doing anything with it.

The message you receive does happen as

  • you used neo4j+s as protocol
  • Quarkus overrides this

-> Things fail.

Please use neo4j as protocol and configure encryption explicit.

This is how the config of the above mentioned app looks like:

image

michael-simons added a commit to michael-simons/quarkus that referenced this issue Oct 6, 2021
This adds dedicated support of Neo4j `neo4j+s` and `neo4j+ssc` URL schemes by skipping all other configuration of encryption settings as the underlying driver prevents configuration of encryption settings via url schema and explicit settings at the same time.

Also adds a bit of documentation.

This fixes quarkusio#19412.
@michael-simons
Copy link
Contributor

I added a fix for this, @sandronm . Thanks for pushing it, tbh I find it annoying myself.

michael-simons added a commit to michael-simons/quarkus that referenced this issue Oct 8, 2021
This adds dedicated support of Neo4j `neo4j+s` and `neo4j+ssc` URL schemes by skipping all other configuration of encryption settings as the underlying driver prevents configuration of encryption settings via url schema and explicit settings at the same time.

Also adds a bit of documentation.

This fixes quarkusio#19412.

Co-authored-by: Guillaume Smet <[email protected]>
@quarkus-bot quarkus-bot bot added this to the 2.4 - main milestone Oct 11, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/neo4j kind/bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants