Skip to content
This repository was archived by the owner on Sep 1, 2023. It is now read-only.

Commit 0e46a80

Browse files
GH-23 - Support +s and +ssc schemes.
This adds support for `bolt+s`, `bolt+ssc`, `neo4j+s` and `neo4j+ssc` by ignoring any properties for encryption and trust settings.
1 parent ac110a9 commit 0e46a80

File tree

3 files changed

+95
-20
lines changed

3 files changed

+95
-20
lines changed

neo4j-java-driver-spring-boot-autoconfigure/src/main/java/org/neo4j/driver/springframework/boot/autoconfigure/Neo4jDriverProperties.java

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,14 @@
2121
import java.io.File;
2222
import java.net.URI;
2323
import java.time.Duration;
24+
import java.util.Locale;
2425
import java.util.concurrent.TimeUnit;
2526

2627
import org.neo4j.driver.AuthToken;
2728
import org.neo4j.driver.AuthTokens;
2829
import org.neo4j.driver.Config;
30+
import org.neo4j.driver.internal.Scheme;
2931
import org.neo4j.driver.net.ServerAddressResolver;
30-
3132
import org.springframework.beans.BeanUtils;
3233
import org.springframework.boot.context.properties.ConfigurationProperties;
3334
import org.springframework.boot.context.properties.source.InvalidConfigurationPropertyValueException;
@@ -102,27 +103,44 @@ public Config asDriverConfig() {
102103

103104
Config.ConfigBuilder builder = Config.builder();
104105
this.pool.applyTo(builder);
105-
this.config.applyTo(builder);
106+
String scheme = uri == null ? "bolt" : uri.getScheme();
107+
this.config.applyTo(builder, isSimpleScheme(scheme));
106108

107109
return builder.withLogging(new Neo4jSpringJclLogging()).build();
108110
}
109111

112+
static boolean isSimpleScheme(String scheme) {
113+
114+
String lowerCaseScheme = scheme.toLowerCase(Locale.ENGLISH);
115+
try {
116+
Scheme.validateScheme(lowerCaseScheme);
117+
} catch (IllegalArgumentException ex) {
118+
throw new IllegalArgumentException(String.format("'%s' is not a supported scheme.", scheme));
119+
}
120+
121+
return lowerCaseScheme.equals("bolt") || lowerCaseScheme.equals("neo4j");
122+
}
123+
110124
public static class Authentication {
111125

112126
/**
113127
* The login of the user connecting to the database.
114128
*/
115129
private String username;
116130

117-
/** The password of the user connecting to the database. */
131+
/**
132+
* The password of the user connecting to the database.
133+
*/
118134
private String password;
119135

120136
/**
121137
* The realm to connect to.
122138
*/
123139
private String realm;
124140

125-
/** A kerberos ticket for connecting to the database. Mutual exclusive with a given username. */
141+
/**
142+
* A kerberos ticket for connecting to the database. Mutual exclusive with a given username.
143+
*/
126144
private String kerberosTicket;
127145

128146
public String getUsername() {
@@ -353,21 +371,28 @@ public void setServerAddressResolverClass(
353371
this.serverAddressResolverClass = serverAddressResolverClass;
354372
}
355373

356-
private void applyTo(Config.ConfigBuilder builder) {
374+
private void applyTo(Config.ConfigBuilder builder, boolean withEncryptionAndTrustSettings) {
357375

358-
if (this.encrypted) {
359-
builder.withEncryption();
360-
} else {
361-
builder.withoutEncryption();
376+
if (withEncryptionAndTrustSettings) {
377+
applyEncryptionAndTrustSettings(builder);
362378
}
363-
builder.withTrustStrategy(this.trustSettings.toInternalRepresentation());
379+
364380
builder.withConnectionTimeout(this.connectionTimeout.toMillis(), TimeUnit.MILLISECONDS);
365381
builder.withMaxTransactionRetryTime(this.maxTransactionRetryTime.toMillis(), TimeUnit.MILLISECONDS);
366382

367383
if (this.serverAddressResolverClass != null) {
368384
builder.withResolver(BeanUtils.instantiateClass(this.serverAddressResolverClass));
369385
}
370386
}
387+
388+
private void applyEncryptionAndTrustSettings(Config.ConfigBuilder builder) {
389+
if (this.encrypted) {
390+
builder.withEncryption();
391+
} else {
392+
builder.withoutEncryption();
393+
}
394+
builder.withTrustStrategy(this.trustSettings.toInternalRepresentation());
395+
}
371396
}
372397

373398
public static class TrustSettings {

neo4j-java-driver-spring-boot-autoconfigure/src/test/java/org/neo4j/driver/springframework/boot/autoconfigure/Neo4jDriverAutoConfigurationTest.java

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,13 @@
1818
*/
1919
package org.neo4j.driver.springframework.boot.autoconfigure;
2020

21+
import static org.assertj.core.api.Assertions.*;
22+
import static org.neo4j.driver.springframework.boot.test.Neo4jDriverMocks.*;
23+
2124
import org.junit.jupiter.api.Test;
25+
import org.junit.jupiter.params.ParameterizedTest;
26+
import org.junit.jupiter.params.provider.ValueSource;
2227
import org.neo4j.driver.Driver;
23-
2428
import org.neo4j.driver.springframework.boot.autoconfigure.domain.EmptyPackage;
2529
import org.neo4j.ogm.drivers.bolt.driver.BoltDriver;
2630
import org.neo4j.ogm.session.SessionFactory;
@@ -33,9 +37,6 @@
3337
import org.springframework.context.annotation.Configuration;
3438
import org.springframework.data.neo4j.transaction.Neo4jTransactionManager;
3539

36-
import static org.assertj.core.api.Assertions.assertThat;
37-
import static org.neo4j.driver.springframework.boot.test.Neo4jDriverMocks.*;
38-
3940
/**
4041
* @author Michael J. Simons
4142
*/
@@ -83,10 +84,32 @@ void shouldAlsoCreateOGMBeans() {
8384
.hasSingleBean(Driver.class)
8485
.hasSingleBean(BoltDriver.class)
8586
.hasSingleBean(SessionFactory.class)
86-
.hasSingleBean(Neo4jTransactionManager.class) // See https://github.com/spring-projects/spring-boot/pull/17662
87+
.hasSingleBean(Neo4jTransactionManager.class)
8788
);
8889
}
8990

91+
/**
92+
* These tests assert correct configuration behaviour for cases in which one of the "advanced" schemes is used to
93+
* configure the driver. If any of the schemes is used, than a contradicting explicit configuration will throw an
94+
* error.
95+
*
96+
* @param scheme The schme to test.
97+
*/
98+
@ParameterizedTest
99+
@ValueSource(strings = { "bolt+s", "bolt+ssc", "neo4j+s", "neo4j+ssc" })
100+
void schemesShouldBeApplied(String scheme) {
101+
102+
this.contextRunner
103+
.withPropertyValues("org.neo4j.driver.uri=" + scheme + "://localhost:4711")
104+
.withClassLoader(new FilteredClassLoader(SessionFactory.class))
105+
.run((ctx) -> {
106+
assertThat(ctx).hasSingleBean(Driver.class);
107+
108+
Driver driver = ctx.getBean(Driver.class);
109+
assertThat(driver.isEncrypted()).isTrue();
110+
});
111+
}
112+
90113
// Needed to not make OGM go mad on package root
91114
@Configuration(proxyBeanMethods = false)
92115
@EntityScan(basePackageClasses = EmptyPackage.class)

neo4j-java-driver-spring-boot-autoconfigure/src/test/java/org/neo4j/driver/springframework/boot/autoconfigure/Neo4jDriverPropertiesTest.java

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
*/
1919
package org.neo4j.driver.springframework.boot.autoconfigure;
2020

21+
import static org.assertj.core.api.Assertions.*;
22+
2123
import java.io.File;
2224
import java.io.IOException;
2325
import java.time.Duration;
@@ -27,10 +29,11 @@
2729
import org.junit.jupiter.api.DisplayName;
2830
import org.junit.jupiter.api.Nested;
2931
import org.junit.jupiter.api.Test;
30-
import org.neo4j.driver.internal.retry.RetrySettings;
32+
import org.junit.jupiter.params.ParameterizedTest;
33+
import org.junit.jupiter.params.provider.ValueSource;
3134
import org.neo4j.driver.AuthTokens;
3235
import org.neo4j.driver.Config;
33-
36+
import org.neo4j.driver.internal.retry.RetrySettings;
3437
import org.neo4j.driver.springframework.boot.autoconfigure.Neo4jDriverProperties.Authentication;
3538
import org.neo4j.driver.springframework.boot.autoconfigure.Neo4jDriverProperties.DriverSettings;
3639
import org.neo4j.driver.springframework.boot.autoconfigure.Neo4jDriverProperties.PoolSettings;
@@ -42,9 +45,6 @@
4245
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
4346
import org.springframework.context.annotation.Configuration;
4447

45-
import static org.assertj.core.api.Assertions.assertThat;
46-
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
47-
4848
/**
4949
* @author Michael J. Simons
5050
*/
@@ -376,6 +376,33 @@ void shouldNotAssumeDefaultValuesForUrl() {
376376
assertThat(driverProperties.getUri()).isNull();
377377
}
378378

379+
@Nested
380+
class SchemeDetection {
381+
382+
@ParameterizedTest
383+
@ValueSource(strings = { "bolt", "Bolt", "neo4j", "Neo4J" })
384+
void shouldDetectSimpleSchemes(String aSimpleScheme) {
385+
386+
assertThat(Neo4jDriverProperties.isSimpleScheme(aSimpleScheme)).isTrue();
387+
}
388+
389+
@ParameterizedTest
390+
@ValueSource(strings = { "bolt+s", "Bolt+ssc", "neo4j+s", "Neo4J+ssc" })
391+
void shouldDetectAdvancedSchemes(String anAdvancedScheme) {
392+
393+
assertThat(Neo4jDriverProperties.isSimpleScheme(anAdvancedScheme)).isFalse();
394+
}
395+
396+
@ParameterizedTest
397+
@ValueSource(strings = { "bolt+routing", "bolt+x", "neo4j+wth" })
398+
void shouldFailEarlyOnInvalidSchemes(String invalidScheme) {
399+
400+
assertThatIllegalArgumentException()
401+
.isThrownBy(() -> Neo4jDriverProperties.isSimpleScheme(invalidScheme))
402+
.withMessage("'%s' is not a supported scheme.", invalidScheme);
403+
}
404+
}
405+
379406
@Configuration(proxyBeanMethods = false)
380407
@EnableConfigurationProperties(Neo4jDriverProperties.class)
381408
static class TestConfiguration {

0 commit comments

Comments
 (0)