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

Update Neo4j-Java-Driver to 4.0.1 and support advanced schemes. #775

Merged
merged 2 commits into from
Mar 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion api/src/main/java/org/neo4j/ogm/config/Configuration.java
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@ public Builder connectionPoolSize(Integer connectionPoolSize) {

/**
* Required encryption level for the connection to the database.
* See org.neo4j.driver.v1.Config.EncryptionLevel for possible values.
* Possible values are {@literal REQUIRED}, {@literal OPTIONAL}, {@literal DISABLED}.
*
* @param encryptionLevel required encryption level
* @return the changed builder
Expand Down
4 changes: 2 additions & 2 deletions api/src/main/java/org/neo4j/ogm/config/Drivers.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

enum Drivers {

BOLT("org.neo4j.ogm.drivers.bolt.driver.BoltDriver", "bolt", "bolt+routing", "neo4j"),
BOLT("org.neo4j.ogm.drivers.bolt.driver.BoltDriver", "bolt", "bolt+routing", "bolt+s", "bolt+ssc", "neo4j", "neo4j+s", "neo4j+ssc"),
EMBEDDED("org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver", "file"),
HTTP("org.neo4j.ogm.drivers.http.driver.HttpDriver", "http", "https");

Expand All @@ -49,7 +49,7 @@ static Drivers getDriverFor(String scheme) {
}
}
}
throw new RuntimeException(UNSUPPORTED_SCHEME_MESSAGE);
throw new IllegalArgumentException(UNSUPPORTED_SCHEME_MESSAGE);
}

String driverClassName() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,10 @@
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

import org.neo4j.driver.AccessMode;
import org.neo4j.driver.AuthToken;
import org.neo4j.driver.AuthTokens;
import org.neo4j.driver.Bookmark;
import org.neo4j.driver.Config;
import org.neo4j.driver.Driver;
import org.neo4j.driver.GraphDatabase;
import org.neo4j.driver.Logging;
import org.neo4j.driver.Session;
import org.neo4j.driver.SessionConfig;
import org.neo4j.driver.*;
import org.neo4j.driver.exceptions.ClientException;
import org.neo4j.driver.exceptions.ServiceUnavailableException;
import org.neo4j.driver.internal.Scheme;
import org.neo4j.ogm.config.Configuration;
import org.neo4j.ogm.config.Credentials;
import org.neo4j.ogm.config.UsernamePasswordCredentials;
Expand Down Expand Up @@ -149,14 +141,27 @@ private void checkDriverInitialized() {
}
}

static boolean isSimpleScheme(String scheme) {

String lowerCaseScheme = scheme.toLowerCase(Locale.ENGLISH);
try {
Scheme.validateScheme(lowerCaseScheme);
} catch (IllegalArgumentException ex) {
throw new IllegalArgumentException(String.format("'%s' is not a supported scheme.", scheme));
}

return lowerCaseScheme.equals("bolt") || lowerCaseScheme.equals("neo4j");
}

private void initializeDriver() {

final String serviceUnavailableMessage = "Could not create driver instance";
try {
Driver driver;
if (credentials != null) {
UsernamePasswordCredentials usernameAndPassword = (UsernamePasswordCredentials) this.credentials;
AuthToken authToken = AuthTokens.basic(usernameAndPassword.getUsername(), usernameAndPassword.getPassword());
AuthToken authToken = AuthTokens
.basic(usernameAndPassword.getUsername(), usernameAndPassword.getPassword());
driver = createDriver(authToken);
} else {
LOGGER.debug("Bolt Driver credentials not supplied");
Expand Down Expand Up @@ -304,57 +309,32 @@ private Optional<Logging> getBoltLogging() {
}

private Config buildDriverConfig() {

// Done outside the try/catch and explicity catch the illegalargument exception of singleURI
// so that exception semantics are not changed since we introduced that feature.
//
// GraphDatabase.routingDriver asserts `neo4j` scheme for each URI, so our trust settings
// have to be applied in this case.
final boolean shouldApplyEncryptionAndTrustSettings;
if (isRoutingConfig()) {
shouldApplyEncryptionAndTrustSettings = true;
} else { // Otherwise we check if it comes with the scheme or not.
URI singleUri = null;
try {
singleUri = getSingleURI();
} catch (IllegalArgumentException e) {
}
shouldApplyEncryptionAndTrustSettings = singleUri == null || isSimpleScheme(singleUri.getScheme());
}

try {
Config.ConfigBuilder configBuilder = Config.builder();
configBuilder.withMaxConnectionPoolSize(configuration.getConnectionPoolSize());

if (configuration.getEncryptionLevel() != null && "REQUIRED"
.equals(configuration.getEncryptionLevel().toUpperCase(Locale.ENGLISH).trim())) {
configBuilder.withEncryption();
} else {
configBuilder.withoutEncryption();
if (shouldApplyEncryptionAndTrustSettings) {
applyEncryptionAndTrustSettings(configBuilder);
}

Config.TrustStrategy.Strategy trustStrategy;
if (configuration.getTrustStrategy() != null) {

String configuredTrustStrategy = configuration.getTrustStrategy().toUpperCase(Locale.ENGLISH).trim();
if (Arrays.asList("TRUST_ON_FIRST_USE", "TRUST_SIGNED_CERTIFICATES")
.contains(configuredTrustStrategy)) {
String validNames = Arrays.stream(Config.TrustStrategy.Strategy.values()).map(
Config.TrustStrategy.Strategy::name).collect(joining(", "));
throw new IllegalArgumentException(
"Truststrategy " + configuredTrustStrategy + " is no longer supported, please choose one of "
+ validNames);
}

try {
trustStrategy = Config.TrustStrategy.Strategy.valueOf(configuredTrustStrategy);
} catch (IllegalArgumentException iae) {
LOGGER.debug("Invalid configuration for the Bolt Driver Trust Strategy: {}",
configuration.getTrustStrategy());
throw iae;
}

switch (trustStrategy) {
case TRUST_ALL_CERTIFICATES:
configBuilder.withTrustStrategy(Config.TrustStrategy.trustAllCertificates());
break;
case TRUST_SYSTEM_CA_SIGNED_CERTIFICATES:
configBuilder.withTrustStrategy(Config.TrustStrategy.trustSystemCertificates());
break;
case TRUST_CUSTOM_CA_SIGNED_CERTIFICATES:
if (configuration.getTrustCertFile() == null) {
throw new IllegalArgumentException(
"Configured trust strategy requires a certificate file.");
}
configBuilder.withTrustStrategy(Config.TrustStrategy
.trustCustomCertificateSignedBy(new File(new URI(configuration.getTrustCertFile()))));
break;
default:
throw new IllegalArgumentException("Unknown strategy." + trustStrategy);
}
}
if (configuration.getConnectionLivenessCheckTimeout() != null) {
configBuilder.withConnectionLivenessCheckTimeout(configuration.getConnectionLivenessCheckTimeout(),
TimeUnit.MILLISECONDS);
Expand All @@ -368,6 +348,56 @@ private Config buildDriverConfig() {
}
}

private void applyEncryptionAndTrustSettings(Config.ConfigBuilder configBuilder) {
if (configuration.getEncryptionLevel() != null && "REQUIRED"
.equals(configuration.getEncryptionLevel().toUpperCase(Locale.ENGLISH).trim())) {
configBuilder.withEncryption();
} else {
configBuilder.withoutEncryption();
}

Config.TrustStrategy.Strategy trustStrategy;
if (configuration.getTrustStrategy() != null) {

String configuredTrustStrategy = configuration.getTrustStrategy().toUpperCase(Locale.ENGLISH).trim();
if (Arrays.asList("TRUST_ON_FIRST_USE", "TRUST_SIGNED_CERTIFICATES")
.contains(configuredTrustStrategy)) {
String validNames = Arrays.stream(Config.TrustStrategy.Strategy.values()).map(
Config.TrustStrategy.Strategy::name).collect(joining(", "));
throw new IllegalArgumentException(
"Truststrategy " + configuredTrustStrategy + " is no longer supported, please choose one of "
+ validNames);
}

try {
trustStrategy = Config.TrustStrategy.Strategy.valueOf(configuredTrustStrategy);
} catch (IllegalArgumentException iae) {
LOGGER.debug("Invalid configuration for the Bolt Driver Trust Strategy: {}",
configuration.getTrustStrategy());
throw iae;
}

switch (trustStrategy) {
case TRUST_ALL_CERTIFICATES:
configBuilder.withTrustStrategy(Config.TrustStrategy.trustAllCertificates());
break;
case TRUST_SYSTEM_CA_SIGNED_CERTIFICATES:
configBuilder.withTrustStrategy(Config.TrustStrategy.trustSystemCertificates());
break;
case TRUST_CUSTOM_CA_SIGNED_CERTIFICATES:
if (configuration.getTrustCertFile() == null) {
throw new IllegalArgumentException(
"Configured trust strategy requires a certificate file.");
}
configBuilder.withTrustStrategy(Config.TrustStrategy
.trustCustomCertificateSignedBy(new File(URI.create(configuration.getTrustCertFile()))));
break;
default:
throw new IllegalArgumentException("Unknown strategy." + trustStrategy);
}
}
}

@SuppressWarnings("deprecation")
static List<Bookmark> bookmarksFromStrings(Iterable<String> bookmarks) {
return StreamSupport.stream(bookmarks.spliterator(), false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import static org.assertj.core.api.Assertions.*;

import java.util.Arrays;
import java.util.Properties;

import org.junit.Test;
Expand Down Expand Up @@ -159,6 +160,49 @@ public void shouldParseEmbeddedUriSchemeCaseInsensitive() {
assertThat(configuration.getURI()).isEqualTo("FILE:///somewhere");
}

@Test
public void shouldDetectSimpleBoltSchemes() {

for (String aSimpleScheme : Arrays.asList("bolt", "Bolt", "neo4j", "Neo4J")) {
String uri = String.format("%s://localhost:7687", aSimpleScheme);
Configuration configuration = new Configuration.Builder()
.uri(uri)
.build();

assertThat(configuration.getDriverClassName()).isEqualTo("org.neo4j.ogm.drivers.bolt.driver.BoltDriver");
assertThat(configuration.getURI()).isEqualTo(uri);
}
}

@Test
public void shouldDetectAdvancedBoltSchemes() {

for (String anAdvancedScheme : Arrays.asList("bolt+s", "Bolt+ssc", "neo4j+s", "Neo4J+ssc")) {
String uri = String.format("%s://localhost:7687", anAdvancedScheme);
Configuration configuration = new Configuration.Builder()
.uri(uri)
.build();

assertThat(configuration.getDriverClassName()).isEqualTo("org.neo4j.ogm.drivers.bolt.driver.BoltDriver");
assertThat(configuration.getURI()).isEqualTo(uri);
}
}

@Test
public void shouldFailEarlyOnInvalidSchemes() {

for (String invalidScheme : Arrays.asList("bolt+x", "neo4j+wth")) {
String uri = String.format("%s://localhost:7687", invalidScheme);

assertThatIllegalArgumentException()
.isThrownBy(() -> new Configuration.Builder()
.uri(uri)
.build())
.withMessage(
"A URI Scheme must be one of: bolt, bolt+routing, bolt+s, bolt+ssc, neo4j, neo4j+s, neo4j+ssc, file, http, https.");
}
}

@Test
public void shouldParseBaseBackagesWithEmtpyValue() {
Properties properties = new Properties();
Expand Down

This file was deleted.

Loading