Skip to content
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
6 changes: 6 additions & 0 deletions driver/clirr-ignored-differences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -365,4 +365,10 @@
<to>org.neo4j.driver.Value</to>
</difference>

<difference>
<className>org/neo4j/driver/GraphDatabase</className>
<differenceType>7002</differenceType>
<method>org.neo4j.driver.Driver routingDriver(java.lang.Iterable, org.neo4j.driver.AuthToken, org.neo4j.driver.Config)</method>
</difference>

</differences>
65 changes: 0 additions & 65 deletions driver/src/main/java/org/neo4j/driver/GraphDatabase.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,7 @@
*/
package org.neo4j.driver;

import static org.neo4j.driver.internal.Scheme.NEO4J_URI_SCHEME;

import java.net.URI;
import org.neo4j.driver.exceptions.ServiceUnavailableException;
import org.neo4j.driver.internal.DriverFactory;
import org.neo4j.driver.internal.SecuritySettings;
import org.neo4j.driver.internal.cluster.RoutingSettings;
Expand Down Expand Up @@ -133,68 +130,6 @@ static Driver driver(URI uri, AuthToken authToken, Config config, DriverFactory
return driverFactory.newInstance(uri, authToken, routingSettings, retrySettings, config, securityPlan);
}

/**
* Try to create a neo4j driver from the <b>first</b> available address.
* This is wrapper for the {@link #driver} method that finds the <b>first</b>
* server to respond positively.
*
* @param routingUris an {@link Iterable} of server {@link URI}s for Neo4j instances. All given URIs should
* have 'neo4j' scheme.
* @param authToken authentication to use, see {@link AuthTokens}
* @param config user defined configuration
* @return a new driver instance
* @deprecated driver should be configured with initial address resolution as documented in the driver manual
*/
@Deprecated
public static Driver routingDriver(Iterable<URI> routingUris, AuthToken authToken, Config config) {
return routingDriver(routingUris, authToken, config, new DriverFactory());
}

static Driver routingDriver(
Iterable<URI> routingUris, AuthToken authToken, Config config, DriverFactory driverFactory) {
assertRoutingUris(routingUris);
Logger log = createLogger(config);

for (URI uri : routingUris) {
final Driver driver = driver(uri, authToken, config, driverFactory);
try {
driver.verifyConnectivity();
return driver;
} catch (ServiceUnavailableException e) {
log.warn("Unable to create routing driver for URI: " + uri, e);
closeDriver(driver, uri, log);
} catch (Throwable e) {
// for any other errors, we first close the driver and then rethrow the original error out.
closeDriver(driver, uri, log);
throw e;
}
}

throw new ServiceUnavailableException("Failed to discover an available server");
}

private static void closeDriver(Driver driver, URI uri, Logger log) {
try {
driver.close();
} catch (Throwable closeError) {
log.warn("Unable to close driver towards URI: " + uri, closeError);
}
}

private static void assertRoutingUris(Iterable<URI> uris) {
for (URI uri : uris) {
if (!NEO4J_URI_SCHEME.equals(uri.getScheme())) {
throw new IllegalArgumentException(
"Illegal URI scheme, expected '" + NEO4J_URI_SCHEME + "' in '" + uri + "'");
}
}
}

private static Logger createLogger(Config config) {
Logging logging = getOrDefault(config).logging();
return logging.getLog(GraphDatabase.class);
}

private static Config getOrDefault(Config config) {
return config != null ? config : Config.defaultConfig();
}
Expand Down
51 changes: 0 additions & 51 deletions driver/src/test/java/org/neo4j/driver/GraphDatabaseTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,18 @@
*/
package org.neo4j.driver;

import static java.util.Arrays.asList;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.junit.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.neo4j.driver.Logging.none;
import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING;

import io.netty.util.concurrent.EventExecutorGroup;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.URI;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.junit.jupiter.api.Test;
Expand All @@ -62,49 +54,6 @@ void throwsWhenBoltSchemeUsedWithRoutingParams() {
IllegalArgumentException.class, () -> GraphDatabase.driver("bolt://localhost:7687/?policy=my_policy"));
}

@Test
void shouldLogWhenUnableToCreateRoutingDriver() {
Logging logging = mock(Logging.class);
Logger logger = mock(Logger.class);
when(logging.getLog(any(Class.class))).thenReturn(logger);
InternalDriver driver = mock(InternalDriver.class);
doThrow(ServiceUnavailableException.class).when(driver).verifyConnectivity();
DriverFactory driverFactory = new MockSupplyingDriverFactory(Arrays.asList(driver, driver));
Config config = Config.builder().withLogging(logging).build();

List<URI> routingUris = asList(URI.create("neo4j://localhost:9001"), URI.create("neo4j://localhost:9002"));

assertThrows(
ServiceUnavailableException.class,
() -> GraphDatabase.routingDriver(routingUris, AuthTokens.none(), config, driverFactory));

verify(logger)
.warn(eq("Unable to create routing driver for URI: neo4j://localhost:9001"), any(Throwable.class));

verify(logger)
.warn(eq("Unable to create routing driver for URI: neo4j://localhost:9002"), any(Throwable.class));
}

@Test
void shouldNotFailRoutingDriverWhenThereIsWorkingUri() {
Logging logging = mock(Logging.class);
Logger logger = mock(Logger.class);
when(logging.getLog(any(Class.class))).thenReturn(logger);
InternalDriver failingDriver = mock(InternalDriver.class);
doThrow(ServiceUnavailableException.class).when(failingDriver).verifyConnectivity();
InternalDriver workingDriver = mock(InternalDriver.class);
DriverFactory driverFactory = new MockSupplyingDriverFactory(Arrays.asList(failingDriver, workingDriver));
Config config = Config.builder().withLogging(logging).build();

List<URI> routingUris = asList(URI.create("neo4j://localhost:9001"), URI.create("neo4j://localhost:9002"));

Driver driver = GraphDatabase.routingDriver(routingUris, AuthTokens.none(), config, driverFactory);

verify(logger)
.warn(eq("Unable to create routing driver for URI: neo4j://localhost:9001"), any(Throwable.class));
assertEquals(driver, workingDriver);
}

@Test
void shouldRespondToInterruptsWhenConnectingToUnresponsiveServer() throws Exception {
try (ServerSocket serverSocket = new ServerSocket(0)) {
Expand Down