diff --git a/benchkit-backend/LICENSES.txt b/benchkit-backend/LICENSES.txt index 995821f879..84ada8eb05 100644 --- a/benchkit-backend/LICENSES.txt +++ b/benchkit-backend/LICENSES.txt @@ -7,12 +7,13 @@ Apache Software License, Version 2.0 Jackson-annotations Jackson-core jackson-databind - Neo4j Bolt Connection (Netty reference impl) - Neo4j Bolt Connection (Pooled provider impl) + Neo4j Bolt Connection (Bolt Provider reference impl) + Neo4j Bolt Connection (Pooled Source impl) Neo4j Bolt Connection (Provider SPI) - Neo4j Bolt Connection (Routed provider impl) + Neo4j Bolt Connection (Routed Source impl) Netty/Buffer - Netty/Codec + Netty/Codec/Base + Netty/Codec/Compression Netty/Codec/HTTP Netty/Common Netty/Handler diff --git a/benchkit-backend/NOTICE.txt b/benchkit-backend/NOTICE.txt index 18004f5006..d6d78a0026 100644 --- a/benchkit-backend/NOTICE.txt +++ b/benchkit-backend/NOTICE.txt @@ -22,12 +22,13 @@ Apache Software License, Version 2.0 Jackson-annotations Jackson-core jackson-databind - Neo4j Bolt Connection (Netty reference impl) - Neo4j Bolt Connection (Pooled provider impl) + Neo4j Bolt Connection (Bolt Provider reference impl) + Neo4j Bolt Connection (Pooled Source impl) Neo4j Bolt Connection (Provider SPI) - Neo4j Bolt Connection (Routed provider impl) + Neo4j Bolt Connection (Routed Source impl) Netty/Buffer - Netty/Codec + Netty/Codec/Base + Netty/Codec/Compression Netty/Codec/HTTP Netty/Common Netty/Handler diff --git a/benchkit-backend/src/main/java/neo4j/org/testkit/backend/Runner.java b/benchkit-backend/src/main/java/neo4j/org/testkit/backend/Runner.java index ee1948f60f..6e31431572 100644 --- a/benchkit-backend/src/main/java/neo4j/org/testkit/backend/Runner.java +++ b/benchkit-backend/src/main/java/neo4j/org/testkit/backend/Runner.java @@ -19,7 +19,8 @@ import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelInitializer; import io.netty.channel.EventLoopGroup; -import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.MultiThreadIoEventLoopGroup; +import io.netty.channel.nio.NioIoHandler; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.codec.http.HttpObjectAggregator; @@ -33,12 +34,9 @@ public class Runner { public static void main(String[] args) throws InterruptedException { var config = Config.load(); - var driver = GraphDatabase.driver( - config.uri(), - config.authToken(), - org.neo4j.driver.Config.builder().withLogging(config.logging()).build()); + var driver = GraphDatabase.driver(config.uri(), config.authToken()); - EventLoopGroup group = new NioEventLoopGroup(); + EventLoopGroup group = new MultiThreadIoEventLoopGroup(NioIoHandler.newFactory()); var logging = config.logging(); var executor = Executors.newCachedThreadPool(); var workloadHandler = new WorkloadHandler(driver, executor, logging); diff --git a/bundle/LICENSES.txt b/bundle/LICENSES.txt index 64fa274009..5b15672369 100644 --- a/bundle/LICENSES.txt +++ b/bundle/LICENSES.txt @@ -4,12 +4,12 @@ libraries. For an overview of the licenses see the NOTICE.txt file. ------------------------------------------------------------------------------ Apache Software License, Version 2.0 - Neo4j Bolt Connection (Netty reference impl) - Neo4j Bolt Connection (Pooled provider impl) + Neo4j Bolt Connection (Bolt Provider reference impl) + Neo4j Bolt Connection (Pooled Source impl) Neo4j Bolt Connection (Provider SPI) - Neo4j Bolt Connection (Routed provider impl) + Neo4j Bolt Connection (Routed Source impl) Netty/Buffer - Netty/Codec + Netty/Codec/Base Netty/Common Netty/Handler Netty/Resolver diff --git a/bundle/NOTICE.txt b/bundle/NOTICE.txt index 988e9585e5..1e10d1ddd8 100644 --- a/bundle/NOTICE.txt +++ b/bundle/NOTICE.txt @@ -19,12 +19,12 @@ Third-party licenses -------------------- Apache Software License, Version 2.0 - Neo4j Bolt Connection (Netty reference impl) - Neo4j Bolt Connection (Pooled provider impl) + Neo4j Bolt Connection (Bolt Provider reference impl) + Neo4j Bolt Connection (Pooled Source impl) Neo4j Bolt Connection (Provider SPI) - Neo4j Bolt Connection (Routed provider impl) + Neo4j Bolt Connection (Routed Source impl) Netty/Buffer - Netty/Codec + Netty/Codec/Base Netty/Common Netty/Handler Netty/Resolver diff --git a/driver/LICENSES.txt b/driver/LICENSES.txt index 64fa274009..5b15672369 100644 --- a/driver/LICENSES.txt +++ b/driver/LICENSES.txt @@ -4,12 +4,12 @@ libraries. For an overview of the licenses see the NOTICE.txt file. ------------------------------------------------------------------------------ Apache Software License, Version 2.0 - Neo4j Bolt Connection (Netty reference impl) - Neo4j Bolt Connection (Pooled provider impl) + Neo4j Bolt Connection (Bolt Provider reference impl) + Neo4j Bolt Connection (Pooled Source impl) Neo4j Bolt Connection (Provider SPI) - Neo4j Bolt Connection (Routed provider impl) + Neo4j Bolt Connection (Routed Source impl) Netty/Buffer - Netty/Codec + Netty/Codec/Base Netty/Common Netty/Handler Netty/Resolver diff --git a/driver/NOTICE.txt b/driver/NOTICE.txt index 988e9585e5..1e10d1ddd8 100644 --- a/driver/NOTICE.txt +++ b/driver/NOTICE.txt @@ -19,12 +19,12 @@ Third-party licenses -------------------- Apache Software License, Version 2.0 - Neo4j Bolt Connection (Netty reference impl) - Neo4j Bolt Connection (Pooled provider impl) + Neo4j Bolt Connection (Bolt Provider reference impl) + Neo4j Bolt Connection (Pooled Source impl) Neo4j Bolt Connection (Provider SPI) - Neo4j Bolt Connection (Routed provider impl) + Neo4j Bolt Connection (Routed Source impl) Netty/Buffer - Netty/Codec + Netty/Codec/Base Netty/Common Netty/Handler Netty/Resolver diff --git a/driver/pom.xml b/driver/pom.xml index 8339c078b3..606403a665 100644 --- a/driver/pom.xml +++ b/driver/pom.xml @@ -20,7 +20,9 @@ ${project.basedir}/.. ${basedir}/target/classes-without-jpms ,-try - --add-opens org.neo4j.driver/org.neo4j.driver.internal.util=ALL-UNNAMED --add-opens org.neo4j.driver/org.neo4j.driver.internal.async=ALL-UNNAMED + --add-reads org.neo4j.driver=io.netty.common --add-reads org.neo4j.driver=org.bouncycastle.provider --add-reads org.neo4j.driver=org.bouncycastle.pkix + --add-opens org.neo4j.driver/org.neo4j.driver.internal.util=ALL-UNNAMED --add-opens org.neo4j.driver/org.neo4j.driver.internal.async=ALL-UNNAMED --add-reads org.neo4j.driver=io.netty.common --add-reads org.neo4j.driver=org.bouncycastle.provider --add-reads org.neo4j.driver=org.bouncycastle.pkix + --add-reads org.neo4j.driver=org.bouncycastle.provider --add-reads org.neo4j.driver=org.bouncycastle.pkix blockHoundTest false @@ -264,6 +266,28 @@ org.apache.maven.surefire surefire-junit-platform ${surefire.and.failsafe.version} + + + org.junit.platform + junit-platform-engine + + + org.junit.platform + junit-platform-launcher + + + org.junit.jupiter + junit-jupiter-engine + + + org.junit.jupiter + junit-jupiter-api + + + org.junit.jupiter + junit-jupiter-params + + org.apache.maven.surefire diff --git a/driver/src/main/java/module-info.java b/driver/src/main/java/module-info.java index d014737e33..5f471e1e22 100644 --- a/driver/src/main/java/module-info.java +++ b/driver/src/main/java/module-info.java @@ -36,7 +36,6 @@ requires org.neo4j.bolt.connection.pooled; requires org.neo4j.bolt.connection.routed; requires reactor.core; - requires io.netty.common; requires transitive java.logging; requires transitive org.reactivestreams; requires static micrometer.core; diff --git a/driver/src/main/java/org/neo4j/driver/Config.java b/driver/src/main/java/org/neo4j/driver/Config.java index 77e28f242f..939ce26acb 100644 --- a/driver/src/main/java/org/neo4j/driver/Config.java +++ b/driver/src/main/java/org/neo4j/driver/Config.java @@ -20,7 +20,6 @@ import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; import static org.neo4j.driver.internal.util.DriverInfoUtil.driverVersion; -import io.netty.channel.EventLoop; import java.io.File; import java.io.Serial; import java.io.Serializable; @@ -349,7 +348,7 @@ public Set disabledNotificationClassifications() { } /** - * Returns the number of {@link EventLoop} threads. + * Returns the number of EventLoop threads. * * @return the number of threads */ diff --git a/driver/src/main/java/org/neo4j/driver/internal/DriverFactory.java b/driver/src/main/java/org/neo4j/driver/internal/DriverFactory.java index 10e65a3d5a..92bec10c68 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/DriverFactory.java +++ b/driver/src/main/java/org/neo4j/driver/internal/DriverFactory.java @@ -19,42 +19,46 @@ import static java.util.Objects.requireNonNull; import static org.neo4j.driver.internal.IdentityResolver.IDENTITY_RESOLVER; -import io.netty.bootstrap.Bootstrap; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.local.LocalAddress; -import io.netty.util.concurrent.EventExecutorGroup; +import java.net.SocketAddress; import java.net.URI; import java.time.Clock; +import java.util.HashMap; import java.util.LinkedHashSet; +import java.util.List; import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Collectors; import org.neo4j.bolt.connection.BoltAgent; import org.neo4j.bolt.connection.BoltConnectionProvider; +import org.neo4j.bolt.connection.BoltConnectionSource; import org.neo4j.bolt.connection.BoltServerAddress; import org.neo4j.bolt.connection.DefaultDomainNameResolver; import org.neo4j.bolt.connection.DomainNameResolver; import org.neo4j.bolt.connection.LoggingProvider; import org.neo4j.bolt.connection.MetricsListener; -import org.neo4j.bolt.connection.RoutingContext; -import org.neo4j.bolt.connection.netty.BootstrapFactory; -import org.neo4j.bolt.connection.netty.NettyBoltConnectionProvider; -import org.neo4j.bolt.connection.pooled.PooledBoltConnectionProvider; +import org.neo4j.bolt.connection.NotificationConfig; +import org.neo4j.bolt.connection.RoutedBoltConnectionParameters; +import org.neo4j.bolt.connection.netty.NettyBoltConnectionProviderFactory; +import org.neo4j.bolt.connection.pooled.PooledBoltConnectionSource; +import org.neo4j.bolt.connection.pooled.SecurityPlanSupplier; +import org.neo4j.bolt.connection.routed.BoltConnectionSourceFactory; import org.neo4j.bolt.connection.routed.Rediscovery; -import org.neo4j.bolt.connection.routed.RoutedBoltConnectionProvider; +import org.neo4j.bolt.connection.routed.RoutedBoltConnectionSource; import org.neo4j.driver.AuthTokenManager; import org.neo4j.driver.ClientCertificateManager; import org.neo4j.driver.Config; import org.neo4j.driver.Driver; import org.neo4j.driver.Logging; import org.neo4j.driver.MetricsAdapter; -import org.neo4j.driver.internal.adaptedbolt.AdaptingDriverBoltConnectionProvider; -import org.neo4j.driver.internal.adaptedbolt.DriverBoltConnectionProvider; +import org.neo4j.driver.exceptions.AuthTokenManagerExecutionException; +import org.neo4j.driver.internal.adaptedbolt.AdaptingDriverBoltConnectionSource; +import org.neo4j.driver.internal.adaptedbolt.BoltAuthTokenManager; +import org.neo4j.driver.internal.adaptedbolt.DriverBoltConnectionSource; import org.neo4j.driver.internal.adaptedbolt.ErrorMapper; +import org.neo4j.driver.internal.adaptedbolt.SingleRoutedBoltConnectionSource; import org.neo4j.driver.internal.boltlistener.BoltConnectionListener; import org.neo4j.driver.internal.homedb.HomeDatabaseCache; import org.neo4j.driver.internal.metrics.DevNullMetricsProvider; @@ -88,7 +92,7 @@ public final Driver newInstance( ClientCertificateManager clientCertificateManager, Config config, SecurityPlan securityPlan, - EventLoopGroup eventLoopGroup, + ScheduledExecutorService eventLoopGroup, Supplier rediscoverySupplier) { if (securityPlan == null) { var settings = new SecuritySettings(config.encrypted(), config.trustStrategy()); @@ -99,45 +103,28 @@ public final Driver newInstance( return newInstance(uri, authTokenManager, config, securityPlanManager, eventLoopGroup, rediscoverySupplier); } - @SuppressWarnings("deprecation") public final Driver newInstance( URI uri, AuthTokenManager authTokenManager, Config config, BoltSecurityPlanManager securityPlanManager, - EventLoopGroup eventLoopGroup, + ScheduledExecutorService eventLoopGroup, Supplier rediscoverySupplier) { requireNonNull(authTokenManager, "authTokenProvider must not be null"); - Bootstrap bootstrap; - boolean ownsEventLoopGroup; - if (eventLoopGroup == null) { - bootstrap = createBootstrap(config.eventLoopThreads()); - ownsEventLoopGroup = true; - } else { - bootstrap = createBootstrap(eventLoopGroup); - ownsEventLoopGroup = false; - } - - var address = new InternalServerAddress(uri); - var routingSettings = new RoutingSettings(config.routingTablePurgeDelayMillis(), new RoutingContext(uri)); - - EventExecutorGroup eventExecutorGroup = bootstrap.config().group(); - var retryLogic = createRetryLogic(config.maxTransactionRetryTimeMillis(), eventExecutorGroup, config.logging()); + var retryExecutor = eventLoopGroup != null ? eventLoopGroup : Executors.newSingleThreadScheduledExecutor(); + var retryLogic = createRetryLogic(config.maxTransactionRetryTimeMillis(), retryExecutor, config.logging()); var metricsProvider = getOrCreateMetricsProvider(config, createClock()); return createDriver( uri, securityPlanManager, - address, - bootstrap.group(), - routingSettings, + eventLoopGroup, retryLogic, metricsProvider, config, authTokenManager, - ownsEventLoopGroup, rediscoverySupplier); } @@ -157,32 +144,29 @@ protected static MetricsProvider getOrCreateMetricsProvider(Config config, Clock private InternalDriver createDriver( URI uri, BoltSecurityPlanManager securityPlanManager, - ServerAddress address, - EventLoopGroup eventLoopGroup, - RoutingSettings routingSettings, + ScheduledExecutorService eventLoopGroup, RetryLogic retryLogic, MetricsProvider metricsProvider, Config config, AuthTokenManager authTokenManager, - boolean ownsEventLoopGroup, Supplier rediscoverySupplier) { - DriverBoltConnectionProvider boltConnectionProvider = null; + DriverBoltConnectionSource boltConnectionProvider = null; try { - var homeDatabaseCache = - HomeDatabaseCache.newInstance(uri.getScheme().startsWith("neo4j")); + var homeDatabaseCache = HomeDatabaseCache.newInstance(Scheme.isRoutingScheme(uri.getScheme())); + var valueFactory = BoltValueFactory.getInstance(); boltConnectionProvider = createDriverBoltConnectionProvider( uri, config, eventLoopGroup, - routingSettings, rediscoverySupplier, homeDatabaseCache, - new BoltServerAddress(address.host(), address.port()), - new RoutingContext(uri), DriverInfoUtil.boltAgent(), config.userAgent(), config.connectionTimeoutMillis(), - metricsProvider.metricsListener()); + metricsProvider.metricsListener(), + authTokenManager, + securityPlanManager::plan, + NotificationConfigMapper.map(config.notificationConfig())); var sessionFactory = createSessionFactory( securityPlanManager, boltConnectionProvider, @@ -190,22 +174,9 @@ private InternalDriver createDriver( config, authTokenManager, homeDatabaseCache); - Supplier> shutdownSupplier = ownsEventLoopGroup - ? () -> { - var closeFuture = new CompletableFuture(); - eventLoopGroup - .shutdownGracefully(200, 15_000, TimeUnit.MILLISECONDS) - .addListener(future -> closeFuture.complete(null)); - return closeFuture; - } - : () -> CompletableFuture.completedStage(null); - var driver = createDriver(securityPlanManager, sessionFactory, metricsProvider, shutdownSupplier, config); + var driver = createDriver(securityPlanManager, sessionFactory, metricsProvider, config); var log = config.logging().getLog(getClass()); - if (uri.getScheme().startsWith("bolt")) { - log.info("Direct driver instance %s created for server address %s", driver.hashCode(), address); - } else { - log.info("Routing driver instance %s created for server address %s", driver.hashCode(), address); - } + log.info("Driver instance %s created for server uri '%s'", driver.hashCode(), uri); return driver; } catch (Throwable driverError) { if (boltConnectionProvider != null) { @@ -223,172 +194,187 @@ private Function> createBoltServerAddr .collect(Collectors.toCollection(LinkedHashSet::new)); } - private DriverBoltConnectionProvider createDriverBoltConnectionProvider( + private DriverBoltConnectionSource createDriverBoltConnectionProvider( URI uri, Config config, - EventLoopGroup eventLoopGroup, - RoutingSettings routingSettings, + ScheduledExecutorService eventLoopGroup, Supplier rediscoverySupplier, BoltConnectionListener boltConnectionListener, - BoltServerAddress address, - RoutingContext routingContext, BoltAgent boltAgent, String userAgent, int connectTimeoutMillis, - MetricsListener metricsListener) { + MetricsListener metricsListener, + AuthTokenManager authTokenManager, + SecurityPlanSupplier securityPlanSupplier, + NotificationConfig notificationConfig) { var clock = createClock(); - var boltConnectionProvider = createBoltConnectionProvider( + var boltValueFactory = BoltValueFactory.getInstance(); + var errorMapper = ErrorMapper.getInstance(); + var boltAuthTokenManager = new BoltAuthTokenManager(authTokenManager, boltValueFactory, errorMapper); + var boltConnectionProvider = createBoltConnectionSource( uri, config, eventLoopGroup, - routingSettings, rediscoverySupplier, boltConnectionListener, - address, - routingContext, boltAgent, userAgent, connectTimeoutMillis, metricsListener, - clock); - return new AdaptingDriverBoltConnectionProvider( - boltConnectionProvider, - ErrorMapper.getInstance(), - BoltValueFactory.getInstance(), - uri.getScheme().startsWith("neo4j"), - address, - routingContext, - boltAgent, - userAgent, - connectTimeoutMillis); + clock, + boltAuthTokenManager, + securityPlanSupplier, + notificationConfig); + return new AdaptingDriverBoltConnectionSource( + boltConnectionProvider, errorMapper, boltValueFactory, Scheme.isRoutingScheme(uri.getScheme())); } - protected BoltConnectionProvider createBoltConnectionProvider( + protected BoltConnectionSource createBoltConnectionSource( URI uri, Config config, - EventLoopGroup eventLoopGroup, - RoutingSettings routingSettings, + ScheduledExecutorService eventLoopGroup, Supplier rediscoverySupplier, BoltConnectionListener boltConnectionListener, - BoltServerAddress address, - RoutingContext routingContext, BoltAgent boltAgent, String userAgent, int connectTimeoutMillis, MetricsListener metricsListener, - Clock clock) { - BoltConnectionProvider boltConnectionProvider; + Clock clock, + org.neo4j.bolt.connection.pooled.AuthTokenManager authTokenManager, + SecurityPlanSupplier securityPlanSupplier, + NotificationConfig notificationConfig) { + BoltConnectionSource boltConnectionSource; var loggingProvider = new BoltLoggingProvider(config.logging()); - Function pooledBoltConnectionProviderSupplier = - selectedAddress -> createPooledBoltConnectionProvider( - config, - eventLoopGroup, - clock, - loggingProvider, - boltConnectionListener, - selectedAddress, - routingContext, - boltAgent, - userAgent, - connectTimeoutMillis, - metricsListener); - if (uri.getScheme().startsWith("neo4j")) { - boltConnectionProvider = createRoutedBoltConnectionProvider( + + switch (uri.getScheme()) { + case Scheme.BOLT_URI_SCHEME, Scheme.BOLT_LOW_TRUST_URI_SCHEME, Scheme.BOLT_HIGH_TRUST_URI_SCHEME -> { + if (uri.getQuery() != null && !uri.getQuery().isEmpty()) { + throw new IllegalArgumentException(NO_ROUTING_CONTEXT_ERROR_MESSAGE + "'" + uri + "'"); + } + } + } + var routingContextAddress = "%s:%d".formatted(uri.getHost(), uri.getPort() != -1 ? uri.getPort() : 7687); + + var pooledSourceSupplierFactory = createPooledBoltConnectionSource( + config, + eventLoopGroup, + clock, + loggingProvider, + boltConnectionListener, + routingContextAddress, + boltAgent, + userAgent, + connectTimeoutMillis, + metricsListener, + authTokenManager, + securityPlanSupplier, + notificationConfig); + if (Scheme.isRoutingScheme(uri.getScheme())) { + boltConnectionSource = createRoutedBoltConnectionProvider( config, - pooledBoltConnectionProviderSupplier, - routingSettings, + pooledSourceSupplierFactory, + config.routingTablePurgeDelayMillis(), rediscoverySupplier, clock, loggingProvider, - address, - routingContext, + uri, boltAgent, userAgent, connectTimeoutMillis, metricsListener); } else { - assertNoRoutingContext(uri, routingSettings); - boltConnectionProvider = pooledBoltConnectionProviderSupplier.apply(address); + boltConnectionSource = new SingleRoutedBoltConnectionSource(pooledSourceSupplierFactory.create(uri, null)); } - return boltConnectionProvider; + return boltConnectionSource; } - private BoltConnectionProvider createRoutedBoltConnectionProvider( + private RoutedBoltConnectionSource createRoutedBoltConnectionProvider( Config config, - Function pooledBoltConnectionProviderFunction, - RoutingSettings routingSettings, + BoltConnectionSourceFactory boltConnectionSourceFactory, + long routingTablePurgeDelayMs, Supplier rediscoverySupplier, Clock clock, LoggingProvider loggingProvider, - BoltServerAddress address, - RoutingContext routingContext, + URI uri, BoltAgent boltAgent, String userAgent, int connectTimeoutMillis, MetricsListener metricsListener) { var boltServerAddressResolver = createBoltServerAddressResolver(config); var rediscovery = rediscoverySupplier != null ? rediscoverySupplier.get() : null; - return new RoutedBoltConnectionProvider( - pooledBoltConnectionProviderFunction, + return new RoutedBoltConnectionSource( + boltConnectionSourceFactory, boltServerAddressResolver, getDomainNameResolver(), - routingSettings.routingTablePurgeDelayMs(), + routingTablePurgeDelayMs, rediscovery, clock, loggingProvider, - address, - routingContext, - boltAgent, - userAgent, - connectTimeoutMillis, - metricsListener); + uri, + List.of(AuthTokenManagerExecutionException.class)); } - private BoltConnectionProvider createPooledBoltConnectionProvider( + private BoltConnectionSourceFactory createPooledBoltConnectionSource( Config config, - EventLoopGroup eventLoopGroup, + ScheduledExecutorService eventLoopGroup, Clock clock, LoggingProvider loggingProvider, BoltConnectionListener boltConnectionListener, - BoltServerAddress address, - RoutingContext routingContext, + String routingContextAddress, BoltAgent boltAgent, String userAgent, int connectTimeoutMillis, - MetricsListener metricsListener) { - var nettyBoltConnectionProvider = createNettyBoltConnectionProvider(eventLoopGroup, clock, loggingProvider); - nettyBoltConnectionProvider = BoltConnectionListener.listeningBoltConnectionProvider( - nettyBoltConnectionProvider, boltConnectionListener); - return new PooledBoltConnectionProvider( - nettyBoltConnectionProvider, - config.maxConnectionPoolSize(), - config.connectionAcquisitionTimeoutMillis(), - config.maxConnectionLifetimeMillis(), - config.idleTimeBeforeConnectionTest(), - clock, - loggingProvider, - metricsListener, - address, - routingContext, - boltAgent, - userAgent, - connectTimeoutMillis); + MetricsListener metricsListener, + org.neo4j.bolt.connection.pooled.AuthTokenManager authTokenManager, + SecurityPlanSupplier securityPlanSupplier, + NotificationConfig notificationConfig) { + return (uri, expectedVerificationHostname) -> { + var boltConnectionProvider = + createBoltConnectionProvider(eventLoopGroup, clock, loggingProvider, config.eventLoopThreads()); + var listeningBoltConnectionProvider = BoltConnectionListener.listeningBoltConnectionProvider( + boltConnectionProvider, boltConnectionListener); + return new PooledBoltConnectionSource( + loggingProvider, + clock, + uri, + listeningBoltConnectionProvider, + authTokenManager, + createSecurityPlanSupplierWithHostname(securityPlanSupplier, expectedVerificationHostname), + config.maxConnectionPoolSize(), + config.connectionAcquisitionTimeoutMillis(), + config.maxConnectionLifetimeMillis(), + config.idleTimeBeforeConnectionTest(), + metricsListener, + routingContextAddress, + boltAgent, + userAgent, + connectTimeoutMillis, + notificationConfig); + }; } - private BoltConnectionProvider createNettyBoltConnectionProvider( - EventLoopGroup eventLoopGroup, Clock clock, LoggingProvider loggingProvider) { - return new NettyBoltConnectionProvider( - eventLoopGroup, - clock, - getDomainNameResolver(), - localAddress(), - loggingProvider, - BoltValueFactory.getInstance(), - null); + protected BoltConnectionProvider createBoltConnectionProvider( + ScheduledExecutorService eventLoopGroup, + Clock clock, + LoggingProvider loggingProvider, + int eventLoopThreads) { + var additionalConfig = new HashMap(); + additionalConfig.put("clock", clock); + if (eventLoopGroup != null) { + additionalConfig.put("eventLoopGroup", eventLoopGroup); + } else if (eventLoopThreads > 0) { + additionalConfig.put("eventLoopThreads", eventLoopThreads); + } + var localAddress = localAddress(); + if (localAddress != null) { + additionalConfig.put("localAddress", localAddress); + } + return new NettyBoltConnectionProviderFactory() + .create(loggingProvider, BoltValueFactory.getInstance(), null, additionalConfig); } @SuppressWarnings("SameReturnValue") - protected LocalAddress localAddress() { + protected SocketAddress localAddress() { return null; } @@ -401,16 +387,9 @@ protected InternalDriver createDriver( BoltSecurityPlanManager securityPlanManager, SessionFactory sessionFactory, MetricsProvider metricsProvider, - Supplier> shutdownSupplier, Config config) { return new InternalDriver( - securityPlanManager, - sessionFactory, - metricsProvider, - config.isTelemetryDisabled(), - config.notificationConfig(), - shutdownSupplier, - config.logging()); + securityPlanManager, sessionFactory, metricsProvider, config.isTelemetryDisabled(), config.logging()); } /** @@ -427,7 +406,7 @@ protected Clock createClock() { */ protected SessionFactory createSessionFactory( BoltSecurityPlanManager securityPlanManager, - DriverBoltConnectionProvider connectionProvider, + DriverBoltConnectionSource connectionProvider, RetryLogic retryLogic, Config config, AuthTokenManager authTokenManager, @@ -442,26 +421,8 @@ protected SessionFactory createSessionFactory( * This method is protected only for testing */ protected RetryLogic createRetryLogic( - long maxTransactionRetryTime, EventExecutorGroup eventExecutorGroup, Logging logging) { - return new ExponentialBackoffRetryLogic(maxTransactionRetryTime, eventExecutorGroup, createClock(), logging); - } - - /** - * Creates new {@link Bootstrap}. - *

- * This method is protected only for testing - */ - protected Bootstrap createBootstrap(int size) { - return BootstrapFactory.newBootstrap(size); - } - - /** - * Creates new {@link Bootstrap}. - *

- * This method is protected only for testing - */ - protected Bootstrap createBootstrap(EventLoopGroup eventLoopGroup) { - return BootstrapFactory.newBootstrap(eventLoopGroup); + long maxTransactionRetryTime, ScheduledExecutorService executor, Logging logging) { + return new ExponentialBackoffRetryLogic(maxTransactionRetryTime, executor, createClock(), logging); } /** @@ -475,10 +436,17 @@ protected DomainNameResolver getDomainNameResolver() { return DefaultDomainNameResolver.getInstance(); } - private static void assertNoRoutingContext(URI uri, RoutingSettings routingSettings) { - var routingContext = routingSettings.routingContext(); - if (routingContext.isDefined()) { - throw new IllegalArgumentException(NO_ROUTING_CONTEXT_ERROR_MESSAGE + "'" + uri + "'"); - } + private static SecurityPlanSupplier createSecurityPlanSupplierWithHostname( + SecurityPlanSupplier securityPlanSupplier, String expectedVerificationHostname) { + return expectedVerificationHostname != null + ? () -> securityPlanSupplier.getPlan().thenApply(securityPlan -> { + if (securityPlan != null && securityPlan.expectedHostname() == null) { + return org.neo4j.bolt.connection.SecurityPlans.encrypted( + securityPlan.sslContext(), securityPlan.verifyHostname(), expectedVerificationHostname); + } else { + return securityPlan; + } + }) + : securityPlanSupplier; } } diff --git a/driver/src/main/java/org/neo4j/driver/internal/InternalDriver.java b/driver/src/main/java/org/neo4j/driver/internal/InternalDriver.java index 2c083f698f..ce38dc0c87 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/InternalDriver.java +++ b/driver/src/main/java/org/neo4j/driver/internal/InternalDriver.java @@ -22,7 +22,6 @@ import java.util.Set; import java.util.concurrent.CompletionStage; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Supplier; import org.neo4j.driver.AccessMode; import org.neo4j.driver.AuthToken; import org.neo4j.driver.BaseSession; @@ -34,7 +33,6 @@ import org.neo4j.driver.Logger; import org.neo4j.driver.Logging; import org.neo4j.driver.Metrics; -import org.neo4j.driver.NotificationConfig; import org.neo4j.driver.Query; import org.neo4j.driver.QueryConfig; import org.neo4j.driver.Session; @@ -69,24 +67,18 @@ public class InternalDriver implements Driver { private final AtomicBoolean closed = new AtomicBoolean(false); private final MetricsProvider metricsProvider; - private final NotificationConfig notificationConfig; - private final Supplier> shutdownSupplier; InternalDriver( BoltSecurityPlanManager securityPlanManager, SessionFactory sessionFactory, MetricsProvider metricsProvider, boolean telemetryDisabled, - NotificationConfig notificationConfig, - Supplier> shutdownSupplier, Logging logging) { this.securityPlanManager = securityPlanManager; this.sessionFactory = sessionFactory; this.metricsProvider = metricsProvider; this.log = logging.getLog(getClass()); this.telemetryDisabled = telemetryDisabled; - this.notificationConfig = notificationConfig; - this.shutdownSupplier = shutdownSupplier; } @Override @@ -107,17 +99,17 @@ public T session( requireNonNull(sessionClass, "sessionConfig must not be null"); T session; if (Session.class.isAssignableFrom(sessionClass)) { - session = (T) new InternalSession(newSession(sessionConfig, notificationConfig, sessionAuthToken)); + session = (T) new InternalSession(newSession(sessionConfig, sessionAuthToken)); } else if (AsyncSession.class.isAssignableFrom(sessionClass)) { - session = (T) new InternalAsyncSession(newSession(sessionConfig, notificationConfig, sessionAuthToken)); + session = (T) new InternalAsyncSession(newSession(sessionConfig, sessionAuthToken)); } else if (org.neo4j.driver.reactive.ReactiveSession.class.isAssignableFrom(sessionClass)) { session = (T) new org.neo4j.driver.internal.reactive.InternalReactiveSession( - newSession(sessionConfig, notificationConfig, sessionAuthToken)); + newSession(sessionConfig, sessionAuthToken)); } else if (org.neo4j.driver.reactivestreams.ReactiveSession.class.isAssignableFrom(sessionClass)) { session = (T) new org.neo4j.driver.internal.reactivestreams.InternalReactiveSession( - newSession(sessionConfig, notificationConfig, sessionAuthToken)); + newSession(sessionConfig, sessionAuthToken)); } else if (RxSession.class.isAssignableFrom(sessionClass)) { - session = (T) new InternalRxSession(newSession(sessionConfig, notificationConfig, sessionAuthToken)); + session = (T) new InternalRxSession(newSession(sessionConfig, sessionAuthToken)); } else { throw new IllegalArgumentException( String.format("Unsupported session type '%s'", sessionClass.getCanonicalName())); @@ -150,7 +142,7 @@ public void close() { public CompletionStage closeAsync() { if (closed.compareAndSet(false, true)) { log.info("Closing driver instance %s", hashCode()); - return sessionFactory.close().thenCompose(ignored -> shutdownSupplier.get()); + return sessionFactory.close(); } return completedWithNull(); } @@ -223,10 +215,9 @@ private static RuntimeException driverCloseException() { return new IllegalStateException("This driver instance has already been closed"); } - public NetworkSession newSession( - SessionConfig config, NotificationConfig notificationConfig, AuthToken overrideAuthToken) { + public NetworkSession newSession(SessionConfig config, AuthToken overrideAuthToken) { assertOpen(); - var session = sessionFactory.newInstance(config, notificationConfig, overrideAuthToken, telemetryDisabled); + var session = sessionFactory.newInstance(config, overrideAuthToken, telemetryDisabled); if (closed.get()) { // session does not immediately acquire connection, it is fine to just throw throw driverCloseException(); diff --git a/driver/src/main/java/org/neo4j/driver/internal/RoutingSettings.java b/driver/src/main/java/org/neo4j/driver/internal/RoutingSettings.java index 76619bf25d..6a3cf4332e 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/RoutingSettings.java +++ b/driver/src/main/java/org/neo4j/driver/internal/RoutingSettings.java @@ -18,8 +18,6 @@ import static java.util.concurrent.TimeUnit.SECONDS; -import org.neo4j.bolt.connection.RoutingContext; - -public record RoutingSettings(long routingTablePurgeDelayMs, RoutingContext routingContext) { +public record RoutingSettings(long routingTablePurgeDelayMs) { public static final long STALE_ROUTING_TABLE_PURGE_DELAY_MS = SECONDS.toMillis(30); } diff --git a/driver/src/main/java/org/neo4j/driver/internal/SessionFactory.java b/driver/src/main/java/org/neo4j/driver/internal/SessionFactory.java index 552c2a3ab7..01e303787d 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/SessionFactory.java +++ b/driver/src/main/java/org/neo4j/driver/internal/SessionFactory.java @@ -18,16 +18,11 @@ import java.util.concurrent.CompletionStage; import org.neo4j.driver.AuthToken; -import org.neo4j.driver.NotificationConfig; import org.neo4j.driver.SessionConfig; import org.neo4j.driver.internal.async.NetworkSession; public interface SessionFactory { - NetworkSession newInstance( - SessionConfig sessionConfig, - NotificationConfig notificationConfig, - AuthToken overrideAuthToken, - boolean telemetryDisabled); + NetworkSession newInstance(SessionConfig sessionConfig, AuthToken overrideAuthToken, boolean telemetryDisabled); CompletionStage verifyConnectivity(); diff --git a/driver/src/main/java/org/neo4j/driver/internal/SessionFactoryImpl.java b/driver/src/main/java/org/neo4j/driver/internal/SessionFactoryImpl.java index b8e8a31065..eff6b6d7f9 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/SessionFactoryImpl.java +++ b/driver/src/main/java/org/neo4j/driver/internal/SessionFactoryImpl.java @@ -24,7 +24,6 @@ import java.util.Set; import java.util.concurrent.CompletionStage; import org.neo4j.bolt.connection.DatabaseName; -import org.neo4j.bolt.connection.DatabaseNameUtil; import org.neo4j.bolt.connection.SecurityPlan; import org.neo4j.driver.AccessMode; import org.neo4j.driver.AuthToken; @@ -36,17 +35,16 @@ import org.neo4j.driver.NotificationConfig; import org.neo4j.driver.SessionConfig; import org.neo4j.driver.Value; -import org.neo4j.driver.internal.adaptedbolt.DriverBoltConnectionProvider; +import org.neo4j.driver.internal.adaptedbolt.DriverBoltConnectionSource; import org.neo4j.driver.internal.async.LeakLoggingNetworkSession; import org.neo4j.driver.internal.async.NetworkSession; import org.neo4j.driver.internal.homedb.HomeDatabaseCache; import org.neo4j.driver.internal.retry.RetryLogic; import org.neo4j.driver.internal.security.BoltSecurityPlanManager; -import org.neo4j.driver.internal.security.InternalAuthToken; public class SessionFactoryImpl implements SessionFactory { private final BoltSecurityPlanManager securityPlanManager; - private final DriverBoltConnectionProvider connectionProvider; + private final DriverBoltConnectionSource connectionSource; private final RetryLogic retryLogic; private final Logging logging; private final boolean leakedSessionsLoggingEnabled; @@ -56,13 +54,13 @@ public class SessionFactoryImpl implements SessionFactory { SessionFactoryImpl( BoltSecurityPlanManager securityPlanManager, - DriverBoltConnectionProvider connectionProvider, + DriverBoltConnectionSource connectionSource, RetryLogic retryLogic, Config config, AuthTokenManager authTokenManager, HomeDatabaseCache homeDatabaseCache) { this.securityPlanManager = Objects.requireNonNull(securityPlanManager); - this.connectionProvider = connectionProvider; + this.connectionSource = connectionSource; this.leakedSessionsLoggingEnabled = config.logLeakedSessions(); this.retryLogic = retryLogic; this.logging = config.logging(); @@ -73,13 +71,10 @@ public class SessionFactoryImpl implements SessionFactory { @Override public NetworkSession newInstance( - SessionConfig sessionConfig, - NotificationConfig notificationConfig, - AuthToken overrideAuthToken, - boolean telemetryDisabled) { + SessionConfig sessionConfig, AuthToken overrideAuthToken, boolean telemetryDisabled) { return createSession( securityPlanManager, - connectionProvider, + connectionSource, retryLogic, parseDatabaseName(sessionConfig), sessionConfig.defaultAccessMode(), @@ -88,7 +83,6 @@ public NetworkSession newInstance( sessionConfig.impersonatedUser().orElse(null), logging, sessionConfig.bookmarkManager().orElse(NoOpBookmarkManager.INSTANCE), - notificationConfig, sessionConfig.notificationConfig(), overrideAuthToken, telemetryDisabled, @@ -124,51 +118,33 @@ private long parseFetchSize(SessionConfig sessionConfig) { private DatabaseName parseDatabaseName(SessionConfig sessionConfig) { return sessionConfig .database() - .flatMap(name -> Optional.of(DatabaseNameUtil.database(name))) - .orElse(DatabaseNameUtil.defaultDatabase()); + .flatMap(name -> Optional.of(DatabaseName.database(name))) + .orElse(DatabaseName.defaultDatabase()); } @Override public CompletionStage verifyConnectivity() { - return securityPlanManager - .plan() - .thenCompose(securityPlan -> authTokenManager - .getToken() - .thenApply(authToken -> - new SecurityPlanAndAuthToken(securityPlan, ((InternalAuthToken) authToken).toMap()))) - .thenCompose(tuple -> connectionProvider.verifyConnectivity(tuple.securityPlan(), tuple.authToken())); + return connectionSource.verifyConnectivity(); } @Override public CompletionStage close() { - return connectionProvider.close(); + return connectionSource.close(); } @Override public CompletionStage supportsMultiDb() { - return securityPlanManager - .plan() - .thenCompose(securityPlan -> authTokenManager - .getToken() - .thenApply(authToken -> - new SecurityPlanAndAuthToken(securityPlan, ((InternalAuthToken) authToken).toMap()))) - .thenCompose(tuple -> connectionProvider.supportsMultiDb(tuple.securityPlan(), tuple.authToken())); + return connectionSource.supportsMultiDb(); } @Override public CompletionStage supportsSessionAuth() { - return securityPlanManager - .plan() - .thenCompose(securityPlan -> authTokenManager - .getToken() - .thenApply(authToken -> - new SecurityPlanAndAuthToken(securityPlan, ((InternalAuthToken) authToken).toMap()))) - .thenCompose(tuple -> connectionProvider.supportsSessionAuth(tuple.securityPlan(), tuple.authToken())); + return connectionSource.supportsSessionAuth(); } private NetworkSession createSession( BoltSecurityPlanManager securityPlanManager, - DriverBoltConnectionProvider connectionProvider, + DriverBoltConnectionSource connectionProvider, RetryLogic retryLogic, DatabaseName databaseName, AccessMode mode, @@ -177,7 +153,6 @@ private NetworkSession createSession( String impersonatedUser, Logging logging, BookmarkManager bookmarkManager, - NotificationConfig driverNotificationConfig, NotificationConfig notificationConfig, AuthToken authToken, boolean telemetryDisabled, @@ -187,7 +162,6 @@ private NetworkSession createSession( Objects.requireNonNull(bookmarkManager, "bookmarkManager may not be null"); return leakedSessionsLoggingEnabled ? new LeakLoggingNetworkSession( - securityPlanManager, connectionProvider, retryLogic, databaseName, @@ -197,14 +171,12 @@ private NetworkSession createSession( fetchSize, logging, bookmarkManager, - driverNotificationConfig, notificationConfig, authToken, telemetryDisabled, authTokenManager, homeDatabaseCache) : new NetworkSession( - securityPlanManager, connectionProvider, retryLogic, databaseName, @@ -214,7 +186,6 @@ private NetworkSession createSession( fetchSize, logging, bookmarkManager, - driverNotificationConfig, notificationConfig, authToken, telemetryDisabled, @@ -222,8 +193,8 @@ private NetworkSession createSession( homeDatabaseCache); } - public DriverBoltConnectionProvider getConnectionProvider() { - return connectionProvider; + public DriverBoltConnectionSource getConnectionSource() { + return connectionSource; } private record SecurityPlanAndAuthToken(SecurityPlan securityPlan, Map authToken) {} diff --git a/driver/src/main/java/org/neo4j/driver/internal/adaptedbolt/AdaptingDriverBoltConnectionProvider.java b/driver/src/main/java/org/neo4j/driver/internal/adaptedbolt/AdaptingDriverBoltConnectionProvider.java deleted file mode 100644 index 06ae502d21..0000000000 --- a/driver/src/main/java/org/neo4j/driver/internal/adaptedbolt/AdaptingDriverBoltConnectionProvider.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) "Neo4j" - * Neo4j Sweden AB [https://neo4j.com] - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.neo4j.driver.internal.adaptedbolt; - -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.CompletionStage; -import java.util.function.Consumer; -import java.util.function.Supplier; -import org.neo4j.bolt.connection.AccessMode; -import org.neo4j.bolt.connection.AuthTokens; -import org.neo4j.bolt.connection.BoltAgent; -import org.neo4j.bolt.connection.BoltConnectionProvider; -import org.neo4j.bolt.connection.BoltProtocolVersion; -import org.neo4j.bolt.connection.BoltServerAddress; -import org.neo4j.bolt.connection.DatabaseName; -import org.neo4j.bolt.connection.NotificationConfig; -import org.neo4j.bolt.connection.RoutingContext; -import org.neo4j.bolt.connection.SecurityPlan; -import org.neo4j.driver.Value; -import org.neo4j.driver.internal.value.BoltValueFactory; - -public class AdaptingDriverBoltConnectionProvider implements DriverBoltConnectionProvider { - private final BoltConnectionProvider delegate; - private final ErrorMapper errorMapper; - private final BoltValueFactory boltValueFactory; - private final boolean routed; - private final BoltServerAddress address; - private final RoutingContext routingContext; - private final BoltAgent boltAgent; - private final String userAgent; - private final int connectTimeoutMillis; - - public AdaptingDriverBoltConnectionProvider( - BoltConnectionProvider delegate, - ErrorMapper errorMapper, - BoltValueFactory boltValueFactory, - boolean routed, - BoltServerAddress address, - RoutingContext routingContext, - BoltAgent boltAgent, - String userAgent, - int connectTimeoutMillis) { - this.delegate = Objects.requireNonNull(delegate); - this.errorMapper = Objects.requireNonNull(errorMapper); - this.boltValueFactory = Objects.requireNonNull(boltValueFactory); - this.routed = routed; - this.address = Objects.requireNonNull(address); - this.routingContext = Objects.requireNonNull(routingContext); - this.boltAgent = Objects.requireNonNull(boltAgent); - this.userAgent = Objects.requireNonNull(userAgent); - this.connectTimeoutMillis = connectTimeoutMillis; - } - - @Override - public CompletionStage connect( - SecurityPlan securityPlan, - DatabaseName databaseName, - Supplier>> authMapStageSupplier, - AccessMode mode, - Set bookmarks, - String impersonatedUser, - BoltProtocolVersion minVersion, - NotificationConfig notificationConfig, - Consumer databaseNameConsumer, - Map additionalParameters) { - return delegate.connect( - address, - routingContext, - boltAgent, - userAgent, - connectTimeoutMillis, - securityPlan, - databaseName, - () -> authMapStageSupplier - .get() - .thenApply(map -> AuthTokens.custom(boltValueFactory.toBoltMap(map))), - mode, - bookmarks, - impersonatedUser, - minVersion, - notificationConfig, - databaseNameConsumer, - additionalParameters) - .exceptionally(errorMapper::mapAndThrow) - .thenApply(boltConnection -> new AdaptingDriverBoltConnection( - boltConnection, - routed ? new RoutedErrorMapper(boltConnection.serverAddress(), mode) : errorMapper, - boltValueFactory)); - } - - @Override - public CompletionStage verifyConnectivity(SecurityPlan securityPlan, Map authMap) { - return delegate.verifyConnectivity( - address, - routingContext, - boltAgent, - userAgent, - connectTimeoutMillis, - securityPlan, - AuthTokens.custom(boltValueFactory.toBoltMap(authMap))) - .exceptionally(errorMapper::mapAndThrow); - } - - @Override - public CompletionStage supportsMultiDb(SecurityPlan securityPlan, Map authMap) { - return delegate.supportsMultiDb( - address, - routingContext, - boltAgent, - userAgent, - connectTimeoutMillis, - securityPlan, - AuthTokens.custom(boltValueFactory.toBoltMap(authMap))) - .exceptionally(errorMapper::mapAndThrow); - } - - @Override - public CompletionStage supportsSessionAuth(SecurityPlan securityPlan, Map authMap) { - return delegate.supportsSessionAuth( - address, - routingContext, - boltAgent, - userAgent, - connectTimeoutMillis, - securityPlan, - AuthTokens.custom(boltValueFactory.toBoltMap(authMap))) - .exceptionally(errorMapper::mapAndThrow); - } - - @Override - public CompletionStage close() { - return delegate.close().exceptionally(errorMapper::mapAndThrow); - } -} diff --git a/driver/src/main/java/org/neo4j/driver/internal/adaptedbolt/AdaptingDriverBoltConnectionSource.java b/driver/src/main/java/org/neo4j/driver/internal/adaptedbolt/AdaptingDriverBoltConnectionSource.java new file mode 100644 index 0000000000..9a3a66524c --- /dev/null +++ b/driver/src/main/java/org/neo4j/driver/internal/adaptedbolt/AdaptingDriverBoltConnectionSource.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) "Neo4j" + * Neo4j Sweden AB [https://neo4j.com] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.neo4j.driver.internal.adaptedbolt; + +import java.util.Objects; +import java.util.concurrent.CompletionStage; +import org.neo4j.bolt.connection.BoltConnectionSource; +import org.neo4j.bolt.connection.RoutedBoltConnectionParameters; +import org.neo4j.driver.internal.value.BoltValueFactory; + +public class AdaptingDriverBoltConnectionSource implements DriverBoltConnectionSource { + private final BoltConnectionSource delegate; + private final ErrorMapper errorMapper; + private final BoltValueFactory boltValueFactory; + private final boolean routed; + + public AdaptingDriverBoltConnectionSource( + BoltConnectionSource delegate, + ErrorMapper errorMapper, + BoltValueFactory boltValueFactory, + boolean routed) { + this.delegate = Objects.requireNonNull(delegate); + this.errorMapper = Objects.requireNonNull(errorMapper); + this.boltValueFactory = Objects.requireNonNull(boltValueFactory); + this.routed = routed; + } + + @Override + public CompletionStage getConnection(RoutedBoltConnectionParameters parameters) { + return delegate.getConnection(parameters) + .exceptionally(errorMapper::mapAndThrow) + .thenApply(boltConnection -> new AdaptingDriverBoltConnection( + boltConnection, + routed || boltConnection.serverSideRoutingEnabled() + ? new RoutedErrorMapper(boltConnection.serverAddress(), parameters.accessMode()) + : errorMapper, + boltValueFactory)); + } + + @Override + public CompletionStage verifyConnectivity() { + return delegate.verifyConnectivity().exceptionally(errorMapper::mapAndThrow); + } + + @Override + public CompletionStage supportsMultiDb() { + return delegate.supportsMultiDb().exceptionally(errorMapper::mapAndThrow); + } + + @Override + public CompletionStage supportsSessionAuth() { + return delegate.supportsSessionAuth().exceptionally(errorMapper::mapAndThrow); + } + + @Override + public CompletionStage close() { + return delegate.close().exceptionally(errorMapper::mapAndThrow); + } +} diff --git a/driver/src/main/java/org/neo4j/driver/internal/adaptedbolt/BoltAuthTokenManager.java b/driver/src/main/java/org/neo4j/driver/internal/adaptedbolt/BoltAuthTokenManager.java new file mode 100644 index 0000000000..e804476269 --- /dev/null +++ b/driver/src/main/java/org/neo4j/driver/internal/adaptedbolt/BoltAuthTokenManager.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) "Neo4j" + * Neo4j Sweden AB [https://neo4j.com] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.neo4j.driver.internal.adaptedbolt; + +import java.util.Objects; +import java.util.concurrent.CompletionStage; +import org.neo4j.bolt.connection.AuthToken; +import org.neo4j.bolt.connection.AuthTokens; +import org.neo4j.bolt.connection.exception.BoltFailureException; +import org.neo4j.bolt.connection.pooled.AuthTokenManager; +import org.neo4j.driver.exceptions.SecurityException; +import org.neo4j.driver.exceptions.SecurityRetryableException; +import org.neo4j.driver.internal.security.InternalAuthToken; +import org.neo4j.driver.internal.value.BoltValueFactory; + +public final class BoltAuthTokenManager implements AuthTokenManager { + private final org.neo4j.driver.AuthTokenManager authTokenManager; + private final BoltValueFactory valueFactory; + private final ErrorMapper errorMapper; + + public BoltAuthTokenManager( + org.neo4j.driver.AuthTokenManager authTokenManager, + BoltValueFactory valueFactory, + ErrorMapper errorMapper) { + this.authTokenManager = Objects.requireNonNull(authTokenManager); + this.valueFactory = Objects.requireNonNull(valueFactory); + this.errorMapper = Objects.requireNonNull(errorMapper); + } + + @Override + public CompletionStage getToken() { + return authTokenManager + .getToken() + .thenApply(authToken -> + AuthTokens.custom(valueFactory.toBoltMap(((InternalAuthToken) authToken).toMap()))); + } + + @Override + public BoltFailureException handleBoltFailureException(AuthToken authToken, BoltFailureException exception) { + var neo4jException = errorMapper.mapBoltFailureException(exception); + if (neo4jException instanceof SecurityException securityException) { + var mappedAuthToken = + new InternalAuthToken(BoltValueFactory.getInstance().toDriverMap(authToken.asMap())); + if (authTokenManager.handleSecurityException(mappedAuthToken, securityException)) { + neo4jException = new SecurityRetryableException(securityException); + } + } + return new BoltFailureExceptionWithNeo4jException(exception, neo4jException); + } +} diff --git a/driver/src/main/java/org/neo4j/driver/internal/adaptedbolt/BoltFailureExceptionWithNeo4jException.java b/driver/src/main/java/org/neo4j/driver/internal/adaptedbolt/BoltFailureExceptionWithNeo4jException.java new file mode 100644 index 0000000000..bc92a57405 --- /dev/null +++ b/driver/src/main/java/org/neo4j/driver/internal/adaptedbolt/BoltFailureExceptionWithNeo4jException.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) "Neo4j" + * Neo4j Sweden AB [https://neo4j.com] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.neo4j.driver.internal.adaptedbolt; + +import java.io.Serial; +import java.util.Objects; +import org.neo4j.bolt.connection.exception.BoltFailureException; +import org.neo4j.driver.exceptions.Neo4jException; + +final class BoltFailureExceptionWithNeo4jException extends BoltFailureException { + @Serial + private static final long serialVersionUID = 401078883000731869L; + + private final Neo4jException neo4jException; + + BoltFailureExceptionWithNeo4jException(BoltFailureException exception, Neo4jException neo4jException) { + super( + exception.code(), + exception.getMessage(), + exception.gqlStatus(), + exception.statusDescription(), + exception.diagnosticRecord(), + exception.getCause()); + this.neo4jException = Objects.requireNonNull(neo4jException); + } + + Neo4jException neo4jException() { + return neo4jException; + } +} diff --git a/driver/src/main/java/org/neo4j/driver/internal/adaptedbolt/DriverBoltConnectionProvider.java b/driver/src/main/java/org/neo4j/driver/internal/adaptedbolt/DriverBoltConnectionProvider.java deleted file mode 100644 index ad6667a747..0000000000 --- a/driver/src/main/java/org/neo4j/driver/internal/adaptedbolt/DriverBoltConnectionProvider.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) "Neo4j" - * Neo4j Sweden AB [https://neo4j.com] - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.neo4j.driver.internal.adaptedbolt; - -import java.util.Map; -import java.util.Set; -import java.util.concurrent.CompletionStage; -import java.util.function.Consumer; -import java.util.function.Supplier; -import org.neo4j.bolt.connection.AccessMode; -import org.neo4j.bolt.connection.BoltProtocolVersion; -import org.neo4j.bolt.connection.DatabaseName; -import org.neo4j.bolt.connection.NotificationConfig; -import org.neo4j.bolt.connection.SecurityPlan; -import org.neo4j.driver.Value; - -public interface DriverBoltConnectionProvider { - - CompletionStage connect( - SecurityPlan securityPlan, - DatabaseName databaseName, - Supplier>> authMapStageSupplier, - AccessMode mode, - Set bookmarks, - String impersonatedUser, - BoltProtocolVersion minVersion, - NotificationConfig notificationConfig, - Consumer databaseNameConsumer, - Map additionalParameters); - - CompletionStage verifyConnectivity(SecurityPlan securityPlan, Map authMap); - - CompletionStage supportsMultiDb(SecurityPlan securityPlan, Map authMap); - - CompletionStage supportsSessionAuth(SecurityPlan securityPlan, Map authMap); - - CompletionStage close(); -} diff --git a/driver/src/main/java/org/neo4j/driver/internal/adaptedbolt/DriverBoltConnectionSource.java b/driver/src/main/java/org/neo4j/driver/internal/adaptedbolt/DriverBoltConnectionSource.java new file mode 100644 index 0000000000..b0d9e4a0fe --- /dev/null +++ b/driver/src/main/java/org/neo4j/driver/internal/adaptedbolt/DriverBoltConnectionSource.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) "Neo4j" + * Neo4j Sweden AB [https://neo4j.com] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.neo4j.driver.internal.adaptedbolt; + +import java.util.concurrent.CompletionStage; +import org.neo4j.bolt.connection.RoutedBoltConnectionParameters; + +public interface DriverBoltConnectionSource { + CompletionStage getConnection(RoutedBoltConnectionParameters parameters); + + CompletionStage verifyConnectivity(); + + CompletionStage supportsMultiDb(); + + CompletionStage supportsSessionAuth(); + + CompletionStage close(); +} diff --git a/driver/src/main/java/org/neo4j/driver/internal/adaptedbolt/ErrorMapper.java b/driver/src/main/java/org/neo4j/driver/internal/adaptedbolt/ErrorMapper.java index 717ca7bffd..e3ea977113 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/adaptedbolt/ErrorMapper.java +++ b/driver/src/main/java/org/neo4j/driver/internal/adaptedbolt/ErrorMapper.java @@ -75,7 +75,9 @@ Throwable map(Throwable throwable) { throwable = Futures.completionExceptionCause(throwable); var result = throwable; try { - if (throwable instanceof BoltFailureException boltFailureException) { + if (throwable instanceof BoltFailureExceptionWithNeo4jException boltFailureExceptionWithNeo4jException) { + return boltFailureExceptionWithNeo4jException.neo4jException(); + } else if (throwable instanceof BoltFailureException boltFailureException) { result = mapBoltFailureException(boltFailureException); } else if (throwable instanceof BoltGqlErrorException boltGqlErrorException) { result = mapGqlCause(boltGqlErrorException); @@ -115,7 +117,7 @@ Throwable map(Throwable throwable) { return result; } - protected Throwable mapBoltFailureException(BoltFailureException boltFailureException) { + protected Neo4jException mapBoltFailureException(BoltFailureException boltFailureException) { var code = boltFailureException.code(); var nested = boltFailureException.gqlCause().map(this::mapGqlCause).orElse(null); return switch (extractErrorClass(code)) { diff --git a/driver/src/main/java/org/neo4j/driver/internal/adaptedbolt/RoutedErrorMapper.java b/driver/src/main/java/org/neo4j/driver/internal/adaptedbolt/RoutedErrorMapper.java index 00eb99e7b2..f69f9a95e7 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/adaptedbolt/RoutedErrorMapper.java +++ b/driver/src/main/java/org/neo4j/driver/internal/adaptedbolt/RoutedErrorMapper.java @@ -24,6 +24,7 @@ import org.neo4j.bolt.connection.exception.BoltFailureException; import org.neo4j.bolt.connection.exception.BoltServiceUnavailableException; import org.neo4j.driver.exceptions.ClientException; +import org.neo4j.driver.exceptions.Neo4jException; import org.neo4j.driver.exceptions.SessionExpiredException; import org.neo4j.driver.internal.GqlStatusError; @@ -37,8 +38,8 @@ class RoutedErrorMapper extends ErrorMapper { } @Override - protected Throwable mapBoltFailureException(BoltFailureException boltFailureException) { - Throwable result; + protected Neo4jException mapBoltFailureException(BoltFailureException boltFailureException) { + Neo4jException result; if ("Neo.ClientError.Cluster.NotALeader".equals(boltFailureException.code()) || "Neo.ClientError.General.ForbiddenOnReadOnlyDatabase".equals(boltFailureException.code())) { result = switch (accessMode) { diff --git a/driver/src/main/java/org/neo4j/driver/internal/adaptedbolt/SingleRoutedBoltConnectionSource.java b/driver/src/main/java/org/neo4j/driver/internal/adaptedbolt/SingleRoutedBoltConnectionSource.java new file mode 100644 index 0000000000..dfc582f61e --- /dev/null +++ b/driver/src/main/java/org/neo4j/driver/internal/adaptedbolt/SingleRoutedBoltConnectionSource.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) "Neo4j" + * Neo4j Sweden AB [https://neo4j.com] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.neo4j.driver.internal.adaptedbolt; + +import java.util.Objects; +import java.util.concurrent.CompletionStage; +import org.neo4j.bolt.connection.BoltConnection; +import org.neo4j.bolt.connection.BoltConnectionParameters; +import org.neo4j.bolt.connection.BoltConnectionSource; +import org.neo4j.bolt.connection.RoutedBoltConnectionParameters; + +public final class SingleRoutedBoltConnectionSource implements BoltConnectionSource { + private final BoltConnectionSource delegate; + + public SingleRoutedBoltConnectionSource(BoltConnectionSource delegate) { + this.delegate = Objects.requireNonNull(delegate); + } + + @Override + public CompletionStage getConnection() { + return delegate.getConnection(); + } + + @Override + public CompletionStage getConnection(RoutedBoltConnectionParameters parameters) { + return delegate.getConnection(parameters).whenComplete((connection, throwable) -> { + if (throwable == null) { + parameters.databaseNameListener().accept(parameters.databaseName()); + } + }); + } + + @Override + public CompletionStage verifyConnectivity() { + return delegate.verifyConnectivity(); + } + + @Override + public CompletionStage supportsMultiDb() { + return delegate.supportsMultiDb(); + } + + @Override + public CompletionStage supportsSessionAuth() { + return delegate.supportsSessionAuth(); + } + + @Override + public CompletionStage close() { + return delegate.close(); + } +} diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/LeakLoggingNetworkSession.java b/driver/src/main/java/org/neo4j/driver/internal/async/LeakLoggingNetworkSession.java index 66ed27a663..5a0aea79c2 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/LeakLoggingNetworkSession.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/LeakLoggingNetworkSession.java @@ -29,18 +29,16 @@ import org.neo4j.driver.BookmarkManager; import org.neo4j.driver.Logging; import org.neo4j.driver.NotificationConfig; -import org.neo4j.driver.internal.adaptedbolt.DriverBoltConnectionProvider; +import org.neo4j.driver.internal.adaptedbolt.DriverBoltConnectionSource; import org.neo4j.driver.internal.homedb.HomeDatabaseCache; import org.neo4j.driver.internal.retry.RetryLogic; -import org.neo4j.driver.internal.security.BoltSecurityPlanManager; import org.neo4j.driver.internal.util.Futures; public class LeakLoggingNetworkSession extends NetworkSession { private final String stackTrace; public LeakLoggingNetworkSession( - BoltSecurityPlanManager securityPlanManager, - DriverBoltConnectionProvider connectionProvider, + DriverBoltConnectionSource connectionProvider, RetryLogic retryLogic, DatabaseName databaseName, AccessMode mode, @@ -49,14 +47,12 @@ public LeakLoggingNetworkSession( long fetchSize, Logging logging, BookmarkManager bookmarkManager, - NotificationConfig driverNotificationConfig, NotificationConfig notificationConfig, AuthToken overrideAuthToken, boolean telemetryDisabled, AuthTokenManager authTokenManager, HomeDatabaseCache homeDatabaseCache) { super( - securityPlanManager, connectionProvider, retryLogic, databaseName, @@ -66,7 +62,6 @@ public LeakLoggingNetworkSession( fetchSize, logging, bookmarkManager, - driverNotificationConfig, notificationConfig, overrideAuthToken, telemetryDisabled, diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/NetworkSession.java b/driver/src/main/java/org/neo4j/driver/internal/async/NetworkSession.java index 6025668fda..3b1aeaee04 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/NetworkSession.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/NetworkSession.java @@ -22,7 +22,6 @@ import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Objects; @@ -39,11 +38,11 @@ import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Collectors; +import org.neo4j.bolt.connection.AuthTokens; import org.neo4j.bolt.connection.BoltProtocolVersion; import org.neo4j.bolt.connection.DatabaseName; -import org.neo4j.bolt.connection.DatabaseNameUtil; import org.neo4j.bolt.connection.NotificationConfig; -import org.neo4j.bolt.connection.SecurityPlan; +import org.neo4j.bolt.connection.RoutedBoltConnectionParameters; import org.neo4j.bolt.connection.TelemetryApi; import org.neo4j.bolt.connection.exception.MinVersionAcquisitionException; import org.neo4j.bolt.connection.message.Message; @@ -72,7 +71,7 @@ import org.neo4j.driver.internal.GqlStatusError; import org.neo4j.driver.internal.NotificationConfigMapper; import org.neo4j.driver.internal.adaptedbolt.DriverBoltConnection; -import org.neo4j.driver.internal.adaptedbolt.DriverBoltConnectionProvider; +import org.neo4j.driver.internal.adaptedbolt.DriverBoltConnectionSource; import org.neo4j.driver.internal.adaptedbolt.DriverResponseHandler; import org.neo4j.driver.internal.cursor.DisposableResultCursorImpl; import org.neo4j.driver.internal.cursor.ResultCursorImpl; @@ -82,15 +81,13 @@ import org.neo4j.driver.internal.homedb.HomeDatabaseCacheKey; import org.neo4j.driver.internal.logging.PrefixedLogger; import org.neo4j.driver.internal.retry.RetryLogic; -import org.neo4j.driver.internal.security.BoltSecurityPlanManager; import org.neo4j.driver.internal.security.InternalAuthToken; import org.neo4j.driver.internal.telemetry.ApiTelemetryWork; import org.neo4j.driver.internal.util.Futures; +import org.neo4j.driver.internal.value.BoltValueFactory; public class NetworkSession { - private static final String HOME_DATABASE_KEY = "homeDatabase"; - private final BoltSecurityPlanManager securityPlanManager; - private final DriverBoltConnectionProvider boltConnectionProvider; + private final DriverBoltConnectionSource boltConnectionProvider; private final NetworkSessionConnectionContext connectionContext; private final AccessMode mode; private final RetryLogic retryLogic; @@ -106,7 +103,6 @@ public class NetworkSession { private final BookmarkManager bookmarkManager; private volatile Set lastUsedBookmarks = Collections.emptySet(); private volatile Set lastReceivedBookmarks; - private final NotificationConfig driverNotificationConfig; private final NotificationConfig notificationConfig; private final boolean telemetryDisabled; private final AuthTokenManager authTokenManager; @@ -114,8 +110,7 @@ public class NetworkSession { private final HomeDatabaseCacheKey homeDatabaseKey; public NetworkSession( - BoltSecurityPlanManager securityPlanManager, - DriverBoltConnectionProvider boltConnectionProvider, + DriverBoltConnectionSource boltConnectionProvider, RetryLogic retryLogic, DatabaseName databaseName, AccessMode mode, @@ -124,7 +119,6 @@ public NetworkSession( long fetchSize, Logging logging, BookmarkManager bookmarkManager, - org.neo4j.driver.NotificationConfig driverNotificationConfig, org.neo4j.driver.NotificationConfig notificationConfig, AuthToken overrideAuthToken, boolean telemetryDisabled, @@ -132,7 +126,6 @@ public NetworkSession( HomeDatabaseCache homeDatabaseCache) { Objects.requireNonNull(bookmarks, "bookmarks may not be null"); Objects.requireNonNull(bookmarkManager, "bookmarkManager may not be null"); - this.securityPlanManager = Objects.requireNonNull(securityPlanManager); this.boltConnectionProvider = Objects.requireNonNull(boltConnectionProvider); this.mode = mode; this.retryLogic = retryLogic; @@ -147,7 +140,6 @@ public NetworkSession( this.connectionContext = new NetworkSessionConnectionContext( databaseNameFuture, determineBookmarks(false), impersonatedUser, overrideAuthToken); this.fetchSize = fetchSize; - this.driverNotificationConfig = NotificationConfigMapper.map(driverNotificationConfig); this.notificationConfig = NotificationConfigMapper.map(notificationConfig); this.telemetryDisabled = telemetryDisabled; this.authTokenManager = authTokenManager; @@ -289,7 +281,7 @@ public CompletionStage beginTransactionAsync( .thenCompose(connection -> { var tx = new UnmanagedTransaction( connection, - connectionContext.databaseNameFuture.getNow(DatabaseNameUtil.defaultDatabase()), + connectionContext.databaseNameFuture.getNow(DatabaseName.defaultDatabase()), asBoltAccessMode(mode), connectionContext.impersonatedUser, this::handleNewBookmark, @@ -412,7 +404,7 @@ protected CompletionStage currentConnectionIsOpen() { } private void handleDatabaseName(String name) { - connectionContext.databaseNameFuture.complete(DatabaseNameUtil.database(name)); + connectionContext.databaseNameFuture.complete(DatabaseName.database(name)); homeDatabaseCache.put(homeDatabaseKey, name); } @@ -420,12 +412,11 @@ private CompletionStage acquireConnection(Acces var overrideAuthToken = connectionContext.overrideAuthToken(); var authTokenManager = overrideAuthToken != null ? NoopAuthTokenManager.INSTANCE : this.authTokenManager; var newConnectionStage = pulledResultCursorStage(connectionStage) - .thenCompose(ignored -> securityPlanManager.plan()) - .thenCompose(securityPlan -> acquireConnection(securityPlan, mode) - .thenApply(connection -> (DriverBoltConnection) - new BoltConnectionWithAuthTokenManager(connection, authTokenManager)) - .thenApply(BoltConnectionWithCloseTracking::new) - .exceptionally(this::mapAcquisitionError)); + .thenCompose(ignored -> acquireAdaptedConnection(mode)) + .thenApply(connection -> + (DriverBoltConnection) new BoltConnectionWithAuthTokenManager(connection, authTokenManager)) + .thenApply(BoltConnectionWithCloseTracking::new) + .exceptionally(this::mapAcquisitionError); connectionStage = newConnectionStage.exceptionally(error -> null); return newConnectionStage; } @@ -463,67 +454,40 @@ private BoltConnectionWithCloseTracking mapAcquisitionError(Throwable throwable) } } - private CompletionStage acquireConnection(SecurityPlan securityPlan, AccessMode mode) { + private CompletionStage acquireAdaptedConnection(AccessMode mode) { var databaseName = connectionContext.databaseNameFuture().getNow(null); var impersonatedUser = connectionContext.impersonatedUser(); var minVersion = minBoltVersion(connectionContext); - var overrideAuthToken = connectionContext.overrideAuthToken(); - var tokenStageSupplier = tokenStageSupplier(overrideAuthToken, authTokenManager); + var overrideAuthToken = connectionContext.overrideAuthToken() != null + ? AuthTokens.custom(BoltValueFactory.getInstance() + .toBoltMap(((InternalAuthToken) connectionContext.overrideAuthToken()).toMap())) + : null; var accessMode = asBoltAccessMode(mode); var bookmarks = connectionContext.rediscoveryBookmarks().stream() .map(Bookmark::value) .collect(Collectors.toSet()); - var additionalParameters = new HashMap(); - if (databaseName == null) { - homeDatabaseCache.get(homeDatabaseKey).ifPresent(name -> additionalParameters.put(HOME_DATABASE_KEY, name)); - } - - Consumer databaseNameConsumer = (name) -> { + Consumer databaseNameListener = (name) -> { if (name != null) { if (databaseName == null) { name.databaseName().ifPresent(n -> homeDatabaseCache.put(homeDatabaseKey, n)); } } else { - name = DatabaseNameUtil.defaultDatabase(); + name = DatabaseName.defaultDatabase(); } connectionContext.databaseNameFuture().complete(name); }; - - return boltConnectionProvider - .connect( - securityPlan, - databaseName, - tokenStageSupplier, - accessMode, - bookmarks, - impersonatedUser, - minVersion, - driverNotificationConfig, - databaseNameConsumer, - additionalParameters) - .thenCompose(boltConnection -> { - if (additionalParameters.containsKey(HOME_DATABASE_KEY) - && !boltConnection.serverSideRoutingEnabled() - && !connectionContext.databaseNameFuture.isDone()) { - // home database was requested with hint, but the returned connection does not have SSR enabled - additionalParameters.remove(HOME_DATABASE_KEY); - return boltConnection - .close() - .thenCompose(ignored -> boltConnectionProvider.connect( - securityPlan, - null, - tokenStageSupplier, - accessMode, - bookmarks, - impersonatedUser, - minVersion, - driverNotificationConfig, - databaseNameConsumer, - additionalParameters)); - } else { - return CompletableFuture.completedStage(boltConnection); - } - }); + var homeDatabaseHint = homeDatabaseCache.get(homeDatabaseKey).orElse(null); + var parameters = RoutedBoltConnectionParameters.builder() + .withAuthToken(overrideAuthToken) + .withMinVersion(minVersion) + .withAccessMode(accessMode) + .withDatabaseName(databaseName) + .withDatabaseNameListener(databaseNameListener) + .withHomeDatabaseHint(homeDatabaseHint) + .withBookmarks(bookmarks) + .withImpersonatedUser(impersonatedUser) + .build(); + return boltConnectionProvider.getConnection(parameters); } private CompletionStage pulledResultCursorStage( @@ -637,7 +601,7 @@ private RunMessage newRunMessage( return Messages.run( connectionContext .databaseNameFuture - .getNow(DatabaseNameUtil.defaultDatabase()) + .getNow(DatabaseName.defaultDatabase()) .databaseName() .orElse(null), asBoltAccessMode(mode), diff --git a/driver/src/main/java/org/neo4j/driver/internal/async/UnmanagedTransaction.java b/driver/src/main/java/org/neo4j/driver/internal/async/UnmanagedTransaction.java index 77fe4bed8e..a5081873c5 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/async/UnmanagedTransaction.java +++ b/driver/src/main/java/org/neo4j/driver/internal/async/UnmanagedTransaction.java @@ -214,7 +214,16 @@ public CompletionStage beginAsync( }); return beginFuture.thenApply(ignored -> this); } else { - return connection.write(messages).thenApply(ignored -> this); + return connection + .write(messages) + .thenApply(ignored -> this) + .whenComplete((ignored, throwable) -> { + if (throwable != null) { + beginFuture.completeExceptionally(throwable); + } else { + beginFuture.complete(this); + } + }); } }); } diff --git a/driver/src/main/java/org/neo4j/driver/internal/boltlistener/ListeningBoltConnectionProvider.java b/driver/src/main/java/org/neo4j/driver/internal/boltlistener/ListeningBoltConnectionProvider.java index f103a4c5a1..bdbf08db0e 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/boltlistener/ListeningBoltConnectionProvider.java +++ b/driver/src/main/java/org/neo4j/driver/internal/boltlistener/ListeningBoltConnectionProvider.java @@ -16,22 +16,15 @@ */ package org.neo4j.driver.internal.boltlistener; -import java.util.Map; +import java.net.URI; import java.util.Objects; -import java.util.Set; import java.util.concurrent.CompletionStage; -import java.util.function.Consumer; -import java.util.function.Supplier; -import org.neo4j.bolt.connection.AccessMode; import org.neo4j.bolt.connection.AuthToken; import org.neo4j.bolt.connection.BoltAgent; import org.neo4j.bolt.connection.BoltConnection; import org.neo4j.bolt.connection.BoltConnectionProvider; import org.neo4j.bolt.connection.BoltProtocolVersion; -import org.neo4j.bolt.connection.BoltServerAddress; -import org.neo4j.bolt.connection.DatabaseName; import org.neo4j.bolt.connection.NotificationConfig; -import org.neo4j.bolt.connection.RoutingContext; import org.neo4j.bolt.connection.SecurityPlan; final class ListeningBoltConnectionProvider implements BoltConnectionProvider { @@ -46,37 +39,25 @@ public ListeningBoltConnectionProvider( @Override public CompletionStage connect( - BoltServerAddress address, - RoutingContext routingContext, + URI uri, + String routingContextAddress, BoltAgent boltAgent, String userAgent, int connectTimeoutMillis, SecurityPlan securityPlan, - DatabaseName databaseName, - Supplier> authTokenStageSupplier, - AccessMode mode, - Set bookmarks, - String impersonatedUser, + AuthToken authToken, BoltProtocolVersion minVersion, - NotificationConfig notificationConfig, - Consumer databaseNameConsumer, - Map additionalParameters) { + NotificationConfig notificationConfig) { return delegate.connect( - address, - routingContext, + uri, + routingContextAddress, boltAgent, userAgent, connectTimeoutMillis, securityPlan, - databaseName, - authTokenStageSupplier, - mode, - bookmarks, - impersonatedUser, + authToken, minVersion, - notificationConfig, - databaseNameConsumer, - additionalParameters) + notificationConfig) .thenApply(boltConnection -> { boltConnection = new ListeningBoltConnection(boltConnection, boltConnectionListener); boltConnectionListener.onOpen(boltConnection); @@ -84,45 +65,6 @@ public CompletionStage connect( }); } - @Override - public CompletionStage verifyConnectivity( - BoltServerAddress address, - RoutingContext routingContext, - BoltAgent boltAgent, - String userAgent, - int connectTimeoutMillis, - SecurityPlan securityPlan, - AuthToken authToken) { - return delegate.verifyConnectivity( - address, routingContext, boltAgent, userAgent, connectTimeoutMillis, securityPlan, authToken); - } - - @Override - public CompletionStage supportsMultiDb( - BoltServerAddress address, - RoutingContext routingContext, - BoltAgent boltAgent, - String userAgent, - int connectTimeoutMillis, - SecurityPlan securityPlan, - AuthToken authToken) { - return delegate.supportsMultiDb( - address, routingContext, boltAgent, userAgent, connectTimeoutMillis, securityPlan, authToken); - } - - @Override - public CompletionStage supportsSessionAuth( - BoltServerAddress address, - RoutingContext routingContext, - BoltAgent boltAgent, - String userAgent, - int connectTimeoutMillis, - SecurityPlan securityPlan, - AuthToken authToken) { - return delegate.supportsSessionAuth( - address, routingContext, boltAgent, userAgent, connectTimeoutMillis, securityPlan, authToken); - } - @Override public CompletionStage close() { return delegate.close(); diff --git a/driver/src/main/java/org/neo4j/driver/internal/retry/ExponentialBackoffRetryLogic.java b/driver/src/main/java/org/neo4j/driver/internal/retry/ExponentialBackoffRetryLogic.java index befbd7185d..0e28f7de8e 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/retry/ExponentialBackoffRetryLogic.java +++ b/driver/src/main/java/org/neo4j/driver/internal/retry/ExponentialBackoffRetryLogic.java @@ -18,13 +18,14 @@ import static java.util.concurrent.TimeUnit.SECONDS; -import io.netty.util.concurrent.EventExecutorGroup; import java.time.Clock; import java.time.Duration; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; +import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; @@ -53,19 +54,20 @@ public class ExponentialBackoffRetryLogic implements RetryLogic { final long initialRetryDelayMs; final double multiplier; final double jitterFactor; - private final EventExecutorGroup eventExecutorGroup; private final Clock clock; private final SleepTask sleepTask; private final Logger log; + private final ScheduledExecutorService executor; + public ExponentialBackoffRetryLogic( - long maxTransactionRetryTime, EventExecutorGroup eventExecutorGroup, Clock clock, Logging logging) { + long maxTransactionRetryTime, ScheduledExecutorService eventExecutorGroup, Clock clock, Logging logging) { this(maxTransactionRetryTime, eventExecutorGroup, clock, logging, Thread::sleep); } protected ExponentialBackoffRetryLogic( long maxTransactionRetryTime, - EventExecutorGroup eventExecutorGroup, + ScheduledExecutorService executor, Clock clock, Logging logging, SleepTask sleepTask) { @@ -74,7 +76,7 @@ protected ExponentialBackoffRetryLogic( INITIAL_RETRY_DELAY_MS, RETRY_DELAY_MULTIPLIER, RETRY_DELAY_JITTER_FACTOR, - eventExecutorGroup, + executor, clock, logging, sleepTask); @@ -85,7 +87,7 @@ protected ExponentialBackoffRetryLogic( long initialRetryDelayMs, double multiplier, double jitterFactor, - EventExecutorGroup eventExecutorGroup, + ScheduledExecutorService executor, Clock clock, Logging logging, SleepTask sleepTask) { @@ -93,7 +95,7 @@ protected ExponentialBackoffRetryLogic( this.initialRetryDelayMs = initialRetryDelayMs; this.multiplier = multiplier; this.jitterFactor = jitterFactor; - this.eventExecutorGroup = eventExecutorGroup; + this.executor = Objects.requireNonNull(executor); this.clock = clock; this.sleepTask = sleepTask; this.log = logging.getLog(getClass()); @@ -198,16 +200,13 @@ private Retry exponentialBackoffRetryRx() { nextDelayMs = (long) (nextDelayMs * multiplier); errors = recordError(error, errors); - // retry on netty event loop thread - var eventExecutor = eventExecutorGroup.next(); var context = Context.of( "errors", errors, "startTime", startTime, "nextDelayMs", nextDelayMs); return Mono.just(context) .delayElement( - Duration.ofMillis(delayWithJitterMs), - Schedulers.fromExecutorService(eventExecutor)); + Duration.ofMillis(delayWithJitterMs), Schedulers.fromExecutorService(executor)); } } addSuppressed(throwable, errors); @@ -218,10 +217,7 @@ private Retry exponentialBackoffRetryRx() { } private void executeWorkInEventLoop(CompletableFuture resultFuture, Supplier> work) { - // this is the very first time we execute given work - var eventExecutor = eventExecutorGroup.next(); - - eventExecutor.execute(() -> executeWork(resultFuture, work, -1, initialRetryDelayMs, null)); + executor.execute(() -> executeWork(resultFuture, work, -1, initialRetryDelayMs, null)); } private void retryWorkInEventLoop( @@ -231,13 +227,11 @@ private void retryWorkInEventLoop( long startTime, long delayMs, List errors) { - // work has failed before, we need to schedule retry with the given delay - var eventExecutor = eventExecutorGroup.next(); var delayWithJitterMs = computeDelayWithJitter(delayMs); log.warn("Async transaction failed and is scheduled to retry in " + delayWithJitterMs + "ms", error); - eventExecutor.schedule( + executor.schedule( () -> { var newRetryDelayMs = (long) (delayMs * multiplier); executeWork(resultFuture, work, startTime, newRetryDelayMs, errors); diff --git a/driver/src/main/java/org/neo4j/driver/internal/security/InternalBoltSecurityPlanManager.java b/driver/src/main/java/org/neo4j/driver/internal/security/InternalBoltSecurityPlanManager.java index 91f3951a49..ea255fc20c 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/security/InternalBoltSecurityPlanManager.java +++ b/driver/src/main/java/org/neo4j/driver/internal/security/InternalBoltSecurityPlanManager.java @@ -18,7 +18,6 @@ import java.util.concurrent.CompletionStage; import org.neo4j.bolt.connection.SecurityPlan; -import org.neo4j.bolt.connection.SecurityPlans; public class InternalBoltSecurityPlanManager implements BoltSecurityPlanManager { private final org.neo4j.driver.internal.security.SecurityPlan securityPlan; @@ -33,10 +32,8 @@ public CompletionStage plan() { .sslContext() .thenApply(sslContext -> securityPlan.requiresEncryption() ? org.neo4j.bolt.connection.SecurityPlans.encrypted( - securityPlan.requiresClientAuth(), - sslContext, - securityPlan.requiresHostnameVerification()) - : SecurityPlans.unencrypted()); + sslContext, securityPlan.requiresHostnameVerification()) + : null); } @Override diff --git a/driver/src/main/java/org/neo4j/driver/internal/util/Futures.java b/driver/src/main/java/org/neo4j/driver/internal/util/Futures.java index 60f0fbc1cd..bd0f3273d6 100644 --- a/driver/src/main/java/org/neo4j/driver/internal/util/Futures.java +++ b/driver/src/main/java/org/neo4j/driver/internal/util/Futures.java @@ -26,7 +26,6 @@ import java.util.concurrent.Future; import java.util.function.BiConsumer; import java.util.function.BiFunction; -import org.neo4j.bolt.connection.netty.EventLoopThread; public final class Futures { private static final CompletableFuture COMPLETED_WITH_NULL = completedFuture(null); @@ -160,7 +159,7 @@ public static void assertNotInEventLoopThread() throws IllegalStateException { * @return {@code true} when given thread belongs to the event loop, {@code false} otherwise. */ public static boolean isEventLoopThread(Thread thread) { - return thread instanceof EventLoopThread; + return thread.getClass().getName().equals("org.neo4j.bolt.connection.netty.EventLoopThread"); } private static void safeRun(Runnable runnable) { diff --git a/driver/src/test/java/org/neo4j/driver/ParametersTest.java b/driver/src/test/java/org/neo4j/driver/ParametersTest.java index e9182a2449..e0109ee852 100644 --- a/driver/src/test/java/org/neo4j/driver/ParametersTest.java +++ b/driver/src/test/java/org/neo4j/driver/ParametersTest.java @@ -24,7 +24,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assumptions.assumeTrue; import static org.mockito.Mockito.mock; -import static org.neo4j.bolt.connection.DatabaseNameUtil.defaultDatabase; +import static org.neo4j.bolt.connection.DatabaseName.defaultDatabase; import static org.neo4j.driver.Values.parameters; import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; import static org.neo4j.driver.internal.util.ValueFactory.emptyNodeValue; @@ -39,10 +39,9 @@ import org.neo4j.driver.exceptions.ClientException; import org.neo4j.driver.internal.InternalRecord; import org.neo4j.driver.internal.InternalSession; -import org.neo4j.driver.internal.adaptedbolt.DriverBoltConnectionProvider; +import org.neo4j.driver.internal.adaptedbolt.DriverBoltConnectionSource; import org.neo4j.driver.internal.async.NetworkSession; import org.neo4j.driver.internal.retry.RetryLogic; -import org.neo4j.driver.internal.security.BoltSecurityPlanManager; class ParametersTest { static Stream addressesToParse() { @@ -100,10 +99,9 @@ void shouldNotBePossibleToUseInvalidParametersViaRecord(Object obj, String expec } private Session mockedSession() { - var provider = mock(DriverBoltConnectionProvider.class); + var provider = mock(DriverBoltConnectionSource.class); var retryLogic = mock(RetryLogic.class); var session = new NetworkSession( - BoltSecurityPlanManager.insecure(), provider, retryLogic, defaultDatabase(), @@ -114,7 +112,6 @@ private Session mockedSession() { DEV_NULL_LOGGING, mock(BookmarkManager.class), Config.defaultConfig().notificationConfig(), - Config.defaultConfig().notificationConfig(), null, false, mock(AuthTokenManager.class), diff --git a/driver/src/test/java/org/neo4j/driver/integration/DriverCloseIT.java b/driver/src/test/java/org/neo4j/driver/integration/DriverCloseIT.java index 864e84c874..d70d277fae 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/DriverCloseIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/DriverCloseIT.java @@ -100,7 +100,7 @@ void shouldInterruptStreamConsumptionAndEndRetriesOnDriverClosure() { CompletableFuture.runAsync(driver::close); return result.list(); })); - assertEquals("Connection provider is closed.", exception.getMessage()); + assertEquals("Connection source is closed.", exception.getMessage()); } private static Driver createDriver() { diff --git a/driver/src/test/java/org/neo4j/driver/integration/ServerKilledIT.java b/driver/src/test/java/org/neo4j/driver/integration/ServerKilledIT.java index c72286ff59..146e94970f 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/ServerKilledIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/ServerKilledIT.java @@ -32,7 +32,6 @@ import org.neo4j.driver.GraphDatabase; import org.neo4j.driver.exceptions.ServiceUnavailableException; import org.neo4j.driver.internal.DriverFactory; -import org.neo4j.driver.internal.security.BoltSecurityPlanManager; import org.neo4j.driver.internal.util.DriverFactoryWithClock; import org.neo4j.driver.internal.util.FakeClock; import org.neo4j.driver.testutil.DatabaseExtension; @@ -122,7 +121,6 @@ private static void acquireAndReleaseConnections(int count, Driver driver) { private Driver createDriver(Clock clock, Config config) { DriverFactory factory = new DriverFactoryWithClock(clock); - return factory.newInstance( - neo4j.uri(), neo4j.authTokenManager(), config, BoltSecurityPlanManager.insecure(), null, null); + return factory.newInstance(neo4j.uri(), neo4j.authTokenManager(), null, config); } } diff --git a/driver/src/test/java/org/neo4j/driver/integration/SessionIT.java b/driver/src/test/java/org/neo4j/driver/integration/SessionIT.java index dc19aba50a..9b71f1236e 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/SessionIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/SessionIT.java @@ -84,7 +84,6 @@ import org.neo4j.driver.exceptions.ServiceUnavailableException; import org.neo4j.driver.exceptions.TransientException; import org.neo4j.driver.internal.DriverFactory; -import org.neo4j.driver.internal.security.BoltSecurityPlanManager; import org.neo4j.driver.internal.util.DisabledOnNeo4jWith; import org.neo4j.driver.internal.util.DriverFactoryWithFixedRetryLogic; import org.neo4j.driver.internal.util.EnabledOnNeo4jWith; @@ -1316,13 +1315,7 @@ private Driver newDriverWithoutRetries() { private Driver newDriverWithFixedRetries(int maxRetriesCount) { DriverFactory driverFactory = new DriverFactoryWithFixedRetryLogic(maxRetriesCount); - return driverFactory.newInstance( - neo4j.uri(), - neo4j.authTokenManager(), - noLoggingConfig(), - BoltSecurityPlanManager.insecure(), - null, - null); + return driverFactory.newInstance(neo4j.uri(), neo4j.authTokenManager(), null, noLoggingConfig()); } private Driver newDriverWithLimitedRetries(int maxTxRetryTime) { diff --git a/driver/src/test/java/org/neo4j/driver/integration/UnmanagedTransactionIT.java b/driver/src/test/java/org/neo4j/driver/integration/UnmanagedTransactionIT.java index 2cc6496163..74517bf9ef 100644 --- a/driver/src/test/java/org/neo4j/driver/integration/UnmanagedTransactionIT.java +++ b/driver/src/test/java/org/neo4j/driver/integration/UnmanagedTransactionIT.java @@ -32,7 +32,6 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.neo4j.bolt.connection.TelemetryApi; -import org.neo4j.driver.NotificationConfig; import org.neo4j.driver.Query; import org.neo4j.driver.SessionConfig; import org.neo4j.driver.TransactionConfig; @@ -57,8 +56,7 @@ class UnmanagedTransactionIT { @BeforeEach @SuppressWarnings("resource") void setUp() { - session = ((InternalDriver) neo4j.driver()) - .newSession(SessionConfig.defaultConfig(), NotificationConfig.defaultConfig(), null); + session = ((InternalDriver) neo4j.driver()).newSession(SessionConfig.defaultConfig(), null); } @AfterEach diff --git a/driver/src/test/java/org/neo4j/driver/internal/CustomSecurityPlanTest.java b/driver/src/test/java/org/neo4j/driver/internal/CustomSecurityPlanTest.java index 56e02c2aa1..45546650ef 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/CustomSecurityPlanTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/CustomSecurityPlanTest.java @@ -24,8 +24,6 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionStage; -import java.util.function.Supplier; import javax.net.ssl.SSLContext; import org.junit.jupiter.api.Test; import org.mockito.Mockito; @@ -60,10 +58,7 @@ void testCustomSecurityPlanUsed() { assertFalse(driverFactory.capturedSecurityPlans.isEmpty()); assertTrue(driverFactory.capturedSecurityPlans.stream() - .allMatch(capturePlan -> capturePlan.requiresEncryption() - && capturePlan.requiresClientAuth() - && capturePlan.sslContext() == sslContext - && capturePlan.requiresHostnameVerification())); + .allMatch(capturePlan -> capturePlan.sslContext() == sslContext && capturePlan.verifyHostname())); } private static class SecurityPlanCapturingDriverFactory extends DriverFactory { @@ -74,11 +69,10 @@ protected InternalDriver createDriver( BoltSecurityPlanManager securityPlanManager, SessionFactory sessionFactory, MetricsProvider metricsProvider, - Supplier> shutdownSupplier, Config config) { capturedSecurityPlans.add( securityPlanManager.plan().toCompletableFuture().join()); - return super.createDriver(securityPlanManager, sessionFactory, metricsProvider, shutdownSupplier, config); + return super.createDriver(securityPlanManager, sessionFactory, metricsProvider, config); } } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/DriverFactoryTest.java b/driver/src/test/java/org/neo4j/driver/internal/DriverFactoryTest.java index 7e226dd120..114ff5350b 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/DriverFactoryTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/DriverFactoryTest.java @@ -28,14 +28,12 @@ import static org.neo4j.driver.Config.defaultConfig; import static org.neo4j.driver.internal.util.Futures.completedWithNull; -import io.netty.bootstrap.Bootstrap; import java.net.URI; import java.time.Clock; import java.util.stream.Stream; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; -import org.neo4j.bolt.connection.netty.BootstrapFactory; import org.neo4j.driver.AuthTokenManager; import org.neo4j.driver.AuthTokens; import org.neo4j.driver.Config; @@ -43,7 +41,7 @@ import org.neo4j.driver.Logging; import org.neo4j.driver.MetricsAdapter; import org.neo4j.driver.SessionConfig; -import org.neo4j.driver.internal.adaptedbolt.DriverBoltConnectionProvider; +import org.neo4j.driver.internal.adaptedbolt.DriverBoltConnectionSource; import org.neo4j.driver.internal.async.LeakLoggingNetworkSession; import org.neo4j.driver.internal.async.NetworkSession; import org.neo4j.driver.internal.homedb.HomeDatabaseCache; @@ -70,8 +68,7 @@ void usesStandardSessionFactoryWhenNothingConfigured(String uri) { var capturedFactory = factory.capturedSessionFactory; assertThat( - capturedFactory.newInstance( - SessionConfig.defaultConfig(), Config.defaultConfig().notificationConfig(), null, true), + capturedFactory.newInstance(SessionConfig.defaultConfig(), null, true), instanceOf(NetworkSession.class)); } @@ -86,8 +83,7 @@ void usesLeakLoggingSessionFactoryWhenConfigured(String uri) { var capturedFactory = factory.capturedSessionFactory; assertThat( - capturedFactory.newInstance( - SessionConfig.defaultConfig(), Config.defaultConfig().notificationConfig(), null, true), + capturedFactory.newInstance(SessionConfig.defaultConfig(), null, true), instanceOf(LeakLoggingNetworkSession.class)); } @@ -155,7 +151,7 @@ private static class SessionFactoryCapturingDriverFactory extends DriverFactory @Override protected SessionFactory createSessionFactory( BoltSecurityPlanManager securityPlanManager, - DriverBoltConnectionProvider connectionProvider, + DriverBoltConnectionSource connectionProvider, RetryLogic retryLogic, Config config, AuthTokenManager authTokenManager, @@ -174,15 +170,10 @@ private static class DriverFactoryWithSessions extends DriverFactory { this.sessionFactory = sessionFactory; } - @Override - protected Bootstrap createBootstrap(int ignored) { - return BootstrapFactory.newBootstrap(1); - } - @Override protected SessionFactory createSessionFactory( BoltSecurityPlanManager securityPlanManager, - DriverBoltConnectionProvider connectionProvider, + DriverBoltConnectionSource connectionProvider, RetryLogic retryLogic, Config config, AuthTokenManager authTokenManager, diff --git a/driver/src/test/java/org/neo4j/driver/internal/InternalDriverTest.java b/driver/src/test/java/org/neo4j/driver/internal/InternalDriverTest.java index b3e18f1659..2d5b1e555b 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/InternalDriverTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/InternalDriverTest.java @@ -135,8 +135,6 @@ private static InternalDriver newDriver(SessionFactory sessionFactory) { sessionFactory, DevNullMetricsProvider.INSTANCE, true, - Config.defaultConfig().notificationConfig(), - () -> CompletableFuture.completedStage(null), DEV_NULL_LOGGING); } @@ -155,12 +153,6 @@ private static InternalDriver newDriver(boolean isMetricsEnabled) { var metricsProvider = DriverFactory.getOrCreateMetricsProvider(config, Clock.systemUTC()); return new InternalDriver( - BoltSecurityPlanManager.insecure(), - sessionFactory, - metricsProvider, - true, - Config.defaultConfig().notificationConfig(), - () -> CompletableFuture.completedStage(null), - DEV_NULL_LOGGING); + BoltSecurityPlanManager.insecure(), sessionFactory, metricsProvider, true, DEV_NULL_LOGGING); } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/InternalTransactionTest.java b/driver/src/test/java/org/neo4j/driver/internal/InternalTransactionTest.java index 9a6e8c434b..589d4c3cdb 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/InternalTransactionTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/InternalTransactionTest.java @@ -57,7 +57,7 @@ import org.neo4j.driver.Transaction; import org.neo4j.driver.Value; import org.neo4j.driver.internal.adaptedbolt.DriverBoltConnection; -import org.neo4j.driver.internal.adaptedbolt.DriverBoltConnectionProvider; +import org.neo4j.driver.internal.adaptedbolt.DriverBoltConnectionSource; import org.neo4j.driver.internal.adaptedbolt.DriverResponseHandler; import org.neo4j.driver.internal.value.IntegerValue; import org.neo4j.driver.testutil.TestUtil; @@ -70,9 +70,8 @@ class InternalTransactionTest { @SuppressWarnings("resource") void setUp() { connection = connectionMock(new BoltProtocolVersion(4, 0)); - var connectionProvider = mock(DriverBoltConnectionProvider.class); - given(connectionProvider.connect(any(), any(), any(), any(), any(), any(), any(), any(), any(), any())) - .willReturn(CompletableFuture.completedFuture(connection)); + var connectionProvider = mock(DriverBoltConnectionSource.class); + given(connectionProvider.getConnection(any())).willReturn(CompletableFuture.completedFuture(connection)); setupConnectionAnswers(connection, List.of(new TestUtil.MessageHandler() { @Override public List> messageTypes() { diff --git a/driver/src/test/java/org/neo4j/driver/internal/SessionFactoryImplTest.java b/driver/src/test/java/org/neo4j/driver/internal/SessionFactoryImplTest.java index 41002b0454..3f22700dd1 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/SessionFactoryImplTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/SessionFactoryImplTest.java @@ -26,7 +26,7 @@ import org.neo4j.driver.AccessMode; import org.neo4j.driver.AuthTokenManager; import org.neo4j.driver.Config; -import org.neo4j.driver.internal.adaptedbolt.DriverBoltConnectionProvider; +import org.neo4j.driver.internal.adaptedbolt.DriverBoltConnectionSource; import org.neo4j.driver.internal.async.LeakLoggingNetworkSession; import org.neo4j.driver.internal.async.NetworkSession; import org.neo4j.driver.internal.security.BoltSecurityPlanManager; @@ -39,17 +39,11 @@ void createsNetworkSessions() { var factory = newSessionFactory(config); var readSession = factory.newInstance( - builder().withDefaultAccessMode(AccessMode.READ).build(), - Config.defaultConfig().notificationConfig(), - null, - true); + builder().withDefaultAccessMode(AccessMode.READ).build(), null, true); assertThat(readSession, instanceOf(NetworkSession.class)); var writeSession = factory.newInstance( - builder().withDefaultAccessMode(AccessMode.WRITE).build(), - Config.defaultConfig().notificationConfig(), - null, - true); + builder().withDefaultAccessMode(AccessMode.WRITE).build(), null, true); assertThat(writeSession, instanceOf(NetworkSession.class)); } @@ -62,24 +56,18 @@ void createsLeakLoggingNetworkSessions() { var factory = newSessionFactory(config); var readSession = factory.newInstance( - builder().withDefaultAccessMode(AccessMode.READ).build(), - Config.defaultConfig().notificationConfig(), - null, - true); + builder().withDefaultAccessMode(AccessMode.READ).build(), null, true); assertThat(readSession, instanceOf(LeakLoggingNetworkSession.class)); var writeSession = factory.newInstance( - builder().withDefaultAccessMode(AccessMode.WRITE).build(), - Config.defaultConfig().notificationConfig(), - null, - true); + builder().withDefaultAccessMode(AccessMode.WRITE).build(), null, true); assertThat(writeSession, instanceOf(LeakLoggingNetworkSession.class)); } private static SessionFactory newSessionFactory(Config config) { return new SessionFactoryImpl( BoltSecurityPlanManager.insecure(), - mock(DriverBoltConnectionProvider.class), + mock(DriverBoltConnectionSource.class), new FixedRetryLogic(0), config, mock(AuthTokenManager.class), diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/InternalAsyncSessionTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/InternalAsyncSessionTest.java index 0c29f6b529..51241c2d5d 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/InternalAsyncSessionTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/InternalAsyncSessionTest.java @@ -55,7 +55,6 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; import java.util.concurrent.ExecutionException; -import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Stream; @@ -66,7 +65,7 @@ import org.mockito.ArgumentMatchers; import org.mockito.stubbing.Answer; import org.neo4j.bolt.connection.BoltProtocolVersion; -import org.neo4j.bolt.connection.DatabaseName; +import org.neo4j.bolt.connection.RoutedBoltConnectionParameters; import org.neo4j.bolt.connection.message.BeginMessage; import org.neo4j.bolt.connection.message.CommitMessage; import org.neo4j.bolt.connection.message.Message; @@ -87,7 +86,7 @@ import org.neo4j.driver.internal.InternalBookmark; import org.neo4j.driver.internal.InternalRecord; import org.neo4j.driver.internal.adaptedbolt.DriverBoltConnection; -import org.neo4j.driver.internal.adaptedbolt.DriverBoltConnectionProvider; +import org.neo4j.driver.internal.adaptedbolt.DriverBoltConnectionSource; import org.neo4j.driver.internal.adaptedbolt.DriverResponseHandler; import org.neo4j.driver.internal.retry.RetryLogic; import org.neo4j.driver.internal.util.FixedRetryLogic; @@ -96,7 +95,7 @@ class InternalAsyncSessionTest { private DriverBoltConnection connection; - private DriverBoltConnectionProvider connectionProvider; + private DriverBoltConnectionSource connectionProvider; private AsyncSession asyncSession; private NetworkSession session; @@ -104,13 +103,11 @@ class InternalAsyncSessionTest { void setUp() { connection = connectionMock(new BoltProtocolVersion(4, 0)); given(connection.close()).willReturn(completedFuture(null)); - connectionProvider = mock(DriverBoltConnectionProvider.class); - given(connectionProvider.connect(any(), any(), any(), any(), any(), any(), any(), any(), any(), any())) + connectionProvider = mock(DriverBoltConnectionSource.class); + given(connectionProvider.getConnection(any())) .willAnswer((Answer>) invocation -> { - var database = (DatabaseName) invocation.getArguments()[1]; - @SuppressWarnings("unchecked") - var databaseConsumer = (Consumer) invocation.getArguments()[8]; - databaseConsumer.accept(database); + var parameters = (RoutedBoltConnectionParameters) invocation.getArguments()[0]; + parameters.databaseNameListener().accept(parameters.databaseName()); return completedFuture(connection); }); session = newSession(connectionProvider); @@ -347,7 +344,7 @@ public void handle(DriverResponseHandler handler) { var e = assertThrows(Exception.class, () -> executeTransaction(asyncSession, transactionMode, work)); assertEquals(error, e); - verify(connectionProvider).connect(any(), any(), any(), any(), any(), any(), any(), any(), any(), any()); + verify(connectionProvider).getConnection(any()); verifyBegin(connection); verifyRollbackTx(connection); } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/InternalAsyncTransactionTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/InternalAsyncTransactionTest.java index 8182c1179b..804dd43b2f 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/InternalAsyncTransactionTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/InternalAsyncTransactionTest.java @@ -40,7 +40,6 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; import java.util.concurrent.ExecutionException; -import java.util.function.Consumer; import java.util.function.Function; import java.util.stream.Stream; import org.junit.jupiter.api.BeforeEach; @@ -49,7 +48,7 @@ import org.junit.jupiter.params.provider.MethodSource; import org.mockito.stubbing.Answer; import org.neo4j.bolt.connection.BoltProtocolVersion; -import org.neo4j.bolt.connection.DatabaseName; +import org.neo4j.bolt.connection.RoutedBoltConnectionParameters; import org.neo4j.bolt.connection.message.BeginMessage; import org.neo4j.bolt.connection.message.CommitMessage; import org.neo4j.bolt.connection.message.Message; @@ -67,7 +66,7 @@ import org.neo4j.driver.exceptions.ServiceUnavailableException; import org.neo4j.driver.internal.InternalRecord; import org.neo4j.driver.internal.adaptedbolt.DriverBoltConnection; -import org.neo4j.driver.internal.adaptedbolt.DriverBoltConnectionProvider; +import org.neo4j.driver.internal.adaptedbolt.DriverBoltConnectionSource; import org.neo4j.driver.internal.adaptedbolt.DriverResponseHandler; import org.neo4j.driver.internal.adaptedbolt.summary.PullSummary; import org.neo4j.driver.internal.value.IntegerValue; @@ -80,13 +79,11 @@ class InternalAsyncTransactionTest { @BeforeEach void setUp() { connection = connectionMock(new BoltProtocolVersion(4, 0)); - var connectionProvider = mock(DriverBoltConnectionProvider.class); - given(connectionProvider.connect(any(), any(), any(), any(), any(), any(), any(), any(), any(), any())) + var connectionProvider = mock(DriverBoltConnectionSource.class); + given(connectionProvider.getConnection(any())) .willAnswer((Answer>) invocation -> { - var database = (DatabaseName) invocation.getArguments()[1]; - @SuppressWarnings("unchecked") - var databaseConsumer = (Consumer) invocation.getArguments()[8]; - databaseConsumer.accept(database); + var parameters = (RoutedBoltConnectionParameters) invocation.getArguments()[0]; + parameters.databaseNameListener().accept(parameters.databaseName()); return completedFuture(connection); }); var networkSession = newSession(connectionProvider); diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/LeakLoggingNetworkSessionTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/LeakLoggingNetworkSessionTest.java index 86eb561c7c..711b6c3850 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/LeakLoggingNetworkSessionTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/LeakLoggingNetworkSessionTest.java @@ -27,7 +27,7 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import static org.neo4j.bolt.connection.DatabaseNameUtil.defaultDatabase; +import static org.neo4j.bolt.connection.DatabaseName.defaultDatabase; import static org.neo4j.driver.AccessMode.READ; import static org.neo4j.driver.testutil.TestUtil.setupConnectionAnswers; @@ -53,10 +53,9 @@ import org.neo4j.driver.Query; import org.neo4j.driver.TransactionConfig; import org.neo4j.driver.internal.adaptedbolt.DriverBoltConnection; -import org.neo4j.driver.internal.adaptedbolt.DriverBoltConnectionProvider; +import org.neo4j.driver.internal.adaptedbolt.DriverBoltConnectionSource; import org.neo4j.driver.internal.adaptedbolt.DriverResponseHandler; import org.neo4j.driver.internal.adaptedbolt.summary.PullSummary; -import org.neo4j.driver.internal.security.BoltSecurityPlanManager; import org.neo4j.driver.internal.telemetry.ApiTelemetryWork; import org.neo4j.driver.internal.util.FixedRetryLogic; import org.neo4j.driver.testutil.TestUtil; @@ -145,7 +144,6 @@ private static void finalize(NetworkSession session) throws Exception { private static LeakLoggingNetworkSession newSession(Logging logging, DriverBoltConnection connection) { return new LeakLoggingNetworkSession( - BoltSecurityPlanManager.insecure(), connectionProviderMock(connection), new FixedRetryLogic(0), defaultDatabase(), @@ -156,17 +154,15 @@ private static LeakLoggingNetworkSession newSession(Logging logging, DriverBoltC logging, mock(BookmarkManager.class), NotificationConfig.defaultConfig(), - NotificationConfig.defaultConfig(), null, true, AuthTokenManagers.basic(AuthTokens::none), mock()); } - private static DriverBoltConnectionProvider connectionProviderMock(DriverBoltConnection connection) { - var provider = mock(DriverBoltConnectionProvider.class); - when(provider.connect(any(), any(), any(), any(), any(), any(), any(), any(), any(), any())) - .thenReturn(CompletableFuture.completedFuture(connection)); + private static DriverBoltConnectionSource connectionProviderMock(DriverBoltConnection connection) { + var provider = mock(DriverBoltConnectionSource.class); + when(provider.getConnection(any())).thenReturn(CompletableFuture.completedFuture(connection)); return provider; } } diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/NetworkSessionTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/NetworkSessionTest.java index 9c9b395049..0a2457a52c 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/NetworkSessionTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/NetworkSessionTest.java @@ -56,7 +56,6 @@ import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; -import java.util.function.Consumer; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -66,7 +65,7 @@ import org.mockito.Mockito; import org.mockito.stubbing.Answer; import org.neo4j.bolt.connection.BoltProtocolVersion; -import org.neo4j.bolt.connection.DatabaseName; +import org.neo4j.bolt.connection.RoutedBoltConnectionParameters; import org.neo4j.bolt.connection.TelemetryApi; import org.neo4j.bolt.connection.message.BeginMessage; import org.neo4j.bolt.connection.message.CommitMessage; @@ -88,7 +87,7 @@ import org.neo4j.driver.exceptions.ClientException; import org.neo4j.driver.internal.InternalBookmark; import org.neo4j.driver.internal.adaptedbolt.DriverBoltConnection; -import org.neo4j.driver.internal.adaptedbolt.DriverBoltConnectionProvider; +import org.neo4j.driver.internal.adaptedbolt.DriverBoltConnectionSource; import org.neo4j.driver.internal.adaptedbolt.DriverResponseHandler; import org.neo4j.driver.internal.adaptedbolt.summary.PullSummary; import org.neo4j.driver.internal.telemetry.ApiTelemetryWork; @@ -98,7 +97,7 @@ class NetworkSessionTest { private DriverBoltConnection connection; - private DriverBoltConnectionProvider connectionProvider; + private DriverBoltConnectionSource connectionProvider; private NetworkSession session; @BeforeEach @@ -106,13 +105,11 @@ void setUp() { connection = connectionMock(new BoltProtocolVersion(5, 4)); given(connection.close()).willReturn(completedFuture(null)); given(connection.valueFactory()).willReturn(mock(BoltValueFactory.class)); - connectionProvider = mock(DriverBoltConnectionProvider.class); - given(connectionProvider.connect(any(), any(), any(), any(), any(), any(), any(), any(), any(), any())) + connectionProvider = mock(DriverBoltConnectionSource.class); + given(connectionProvider.getConnection(any())) .willAnswer((Answer>) invocation -> { - var database = (DatabaseName) invocation.getArguments()[1]; - @SuppressWarnings("unchecked") - var databaseConsumer = (Consumer) invocation.getArguments()[8]; - databaseConsumer.accept(database); + var parameters = (RoutedBoltConnectionParameters) invocation.getArguments()[0]; + parameters.databaseNameListener().accept(parameters.databaseName()); return completedFuture(connection); }); session = newSession(connectionProvider); @@ -293,7 +290,7 @@ void acquiresNewConnectionForRun() { run(session, query); - verify(connectionProvider).connect(any(), any(), any(), any(), any(), any(), any(), any(), any(), any()); + verify(connectionProvider).getConnection(any()); } @Test @@ -311,8 +308,7 @@ void releasesOpenConnectionUsedForRunWhenSessionIsClosed() { void resetDoesNothingWhenNoTransactionAndNoConnection() { await(session.resetAsync()); - verify(connectionProvider, never()) - .connect(any(), any(), any(), any(), any(), any(), any(), any(), any(), any()); + verify(connectionProvider, never()).getConnection(any()); } @Test @@ -321,8 +317,7 @@ void closeWithoutConnection() { close(session); - verify(connectionProvider, never()) - .connect(any(), any(), any(), any(), any(), any(), any(), any(), any(), any()); + verify(connectionProvider, never()).getConnection(any()); } @Test @@ -331,7 +326,7 @@ void acquiresNewConnectionForBeginTx() { var tx = beginTransaction(session); assertNotNull(tx); - verify(connectionProvider).connect(any(), any(), any(), any(), any(), any(), any(), any(), any(), any()); + verify(connectionProvider).getConnection(any()); } @Test @@ -417,7 +412,7 @@ public void handle(DriverResponseHandler handler) { } })); var tx = beginTransaction(session); - verify(connectionProvider).connect(any(), any(), any(), any(), any(), any(), any(), any(), any(), any()); + verify(connectionProvider).getConnection(any()); verifyBegin(connection); var query = "RETURN 42"; await(tx.runAsync(new Query(query))); @@ -508,15 +503,14 @@ void accessModeUsedToAcquireWriteConnections() { private void accessModeUsedToAcquireConnections(AccessMode mode) { var session2 = newSession(connectionProvider, mode); beginTransaction(session2); - var argument = ArgumentCaptor.forClass(org.neo4j.bolt.connection.AccessMode.class); - verify(connectionProvider) - .connect(any(), any(), any(), argument.capture(), any(), any(), any(), any(), any(), any()); + var argument = ArgumentCaptor.forClass(RoutedBoltConnectionParameters.class); + verify(connectionProvider).getConnection(argument.capture()); assertEquals( switch (mode) { case READ -> org.neo4j.bolt.connection.AccessMode.READ; case WRITE -> org.neo4j.bolt.connection.AccessMode.WRITE; }, - argument.getValue()); + argument.getValue().accessMode()); } @Test @@ -537,8 +531,7 @@ void shouldHaveEmptyLastBookmarksInitially() { void shouldDoNothingWhenClosingWithoutAcquiredConnection() { var error = new RuntimeException("Hi"); Mockito.reset(connectionProvider); - given(connectionProvider.connect(any(), any(), any(), any(), any(), any(), any(), any(), any(), any())) - .willReturn(failedFuture(error)); + given(connectionProvider.getConnection(any())).willReturn(failedFuture(error)); var e = assertThrows(Exception.class, () -> run(session, "RETURN 1")); assertEquals(error, e); @@ -550,14 +543,11 @@ void shouldDoNothingWhenClosingWithoutAcquiredConnection() { void shouldRunAfterRunFailure() { var error = new RuntimeException("Hi"); Mockito.reset(connectionProvider); - given(connectionProvider.connect(any(), any(), any(), any(), any(), any(), any(), any(), any(), any())) + given(connectionProvider.getConnection(any())) .willReturn(failedFuture(error)) .willAnswer((Answer>) invocation -> { - var databaseName = (DatabaseName) invocation.getArguments()[1]; - @SuppressWarnings("unchecked") - var databaseNameConsumer = - (Consumer) invocation.getArguments()[8]; - databaseNameConsumer.accept(databaseName); + var parameters = (RoutedBoltConnectionParameters) invocation.getArguments()[0]; + parameters.databaseNameListener().accept(parameters.databaseName()); return completedFuture(connection); }); @@ -570,8 +560,7 @@ void shouldRunAfterRunFailure() { run(session, query); - verify(connectionProvider, times(2)) - .connect(any(), any(), any(), any(), any(), any(), any(), any(), any(), any()); + verify(connectionProvider, times(2)).getConnection(any()); verifyAutocommitRunAndPull(connection, query); } @@ -589,21 +578,15 @@ void shouldRunAfterBeginTxFailureOnBookmark() { given(connection2.close()).willReturn(CompletableFuture.completedStage(null)); Mockito.reset(connectionProvider); - given(connectionProvider.connect(any(), any(), any(), any(), any(), any(), any(), any(), any(), any())) + given(connectionProvider.getConnection(any())) .willAnswer((Answer>) invocation -> { - var databaseName = (DatabaseName) invocation.getArguments()[1]; - @SuppressWarnings("unchecked") - var databaseNameConsumer = - (Consumer) invocation.getArguments()[8]; - databaseNameConsumer.accept(databaseName); + var parameters = (RoutedBoltConnectionParameters) invocation.getArguments()[0]; + parameters.databaseNameListener().accept(parameters.databaseName()); return completedFuture(connection1); }) .willAnswer((Answer>) invocation -> { - var databaseName = (DatabaseName) invocation.getArguments()[1]; - @SuppressWarnings("unchecked") - var databaseNameConsumer = - (Consumer) invocation.getArguments()[8]; - databaseNameConsumer.accept(databaseName); + var parameters = (RoutedBoltConnectionParameters) invocation.getArguments()[0]; + parameters.databaseNameListener().accept(parameters.databaseName()); return completedFuture(connection2); }); @@ -617,8 +600,7 @@ void shouldRunAfterBeginTxFailureOnBookmark() { run(session, query); - verify(connectionProvider, times(2)) - .connect(any(), any(), any(), any(), any(), any(), any(), any(), any(), any()); + verify(connectionProvider, times(2)).getConnection(any()); verifyBegin(connection1); verifyAutocommitRunAndPull(connection2, "RETURN 2"); } @@ -648,21 +630,15 @@ public void handle(DriverResponseHandler handler) { })); Mockito.reset(connectionProvider); - given(connectionProvider.connect(any(), any(), any(), any(), any(), any(), any(), any(), any(), any())) + given(connectionProvider.getConnection(any())) .willAnswer((Answer>) invocation -> { - var databaseName = (DatabaseName) invocation.getArguments()[1]; - @SuppressWarnings("unchecked") - var databaseNameConsumer = - (Consumer) invocation.getArguments()[8]; - databaseNameConsumer.accept(databaseName); + var parameters = (RoutedBoltConnectionParameters) invocation.getArguments()[0]; + parameters.databaseNameListener().accept(parameters.databaseName()); return completedFuture(connection1); }) .willAnswer((Answer>) invocation -> { - var databaseName = (DatabaseName) invocation.getArguments()[1]; - @SuppressWarnings("unchecked") - var databaseNameConsumer = - (Consumer) invocation.getArguments()[8]; - databaseNameConsumer.accept(databaseName); + var parameters = (RoutedBoltConnectionParameters) invocation.getArguments()[0]; + parameters.databaseNameListener().accept(parameters.databaseName()); return completedFuture(connection2); }); @@ -674,8 +650,7 @@ public void handle(DriverResponseHandler handler) { beginTransaction(session); - verify(connectionProvider, times(2)) - .connect(any(), any(), any(), any(), any(), any(), any(), any(), any(), any()); + verify(connectionProvider, times(2)).getConnection(any()); verifyBegin(connection1); verifyBegin(connection2); } @@ -684,14 +659,11 @@ public void handle(DriverResponseHandler handler) { void shouldBeginTxAfterRunFailureToAcquireConnection() { var error = new RuntimeException("Hi"); Mockito.reset(connectionProvider); - given(connectionProvider.connect(any(), any(), any(), any(), any(), any(), any(), any(), any(), any())) + given(connectionProvider.getConnection(any())) .willReturn(failedFuture(error)) .willAnswer((Answer>) invocation -> { - var databaseName = (DatabaseName) invocation.getArguments()[1]; - @SuppressWarnings("unchecked") - var databaseNameConsumer = - (Consumer) invocation.getArguments()[8]; - databaseNameConsumer.accept(databaseName); + var parameters = (RoutedBoltConnectionParameters) invocation.getArguments()[0]; + parameters.databaseNameListener().accept(parameters.databaseName()); return completedFuture(connection); }); setupSuccessfulBegin(connection); @@ -701,8 +673,7 @@ void shouldBeginTxAfterRunFailureToAcquireConnection() { beginTransaction(session); - verify(connectionProvider, times(2)) - .connect(any(), any(), any(), any(), any(), any(), any(), any(), any(), any()); + verify(connectionProvider, times(2)).getConnection(any()); then(connection) .should() .writeAndFlush( diff --git a/driver/src/test/java/org/neo4j/driver/internal/async/UnmanagedTransactionTest.java b/driver/src/test/java/org/neo4j/driver/internal/async/UnmanagedTransactionTest.java index 2f7f041873..68ac9255ba 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/async/UnmanagedTransactionTest.java +++ b/driver/src/test/java/org/neo4j/driver/internal/async/UnmanagedTransactionTest.java @@ -59,7 +59,7 @@ import org.junit.jupiter.params.provider.MethodSource; import org.neo4j.bolt.connection.AccessMode; import org.neo4j.bolt.connection.BoltProtocolVersion; -import org.neo4j.bolt.connection.DatabaseNameUtil; +import org.neo4j.bolt.connection.DatabaseName; import org.neo4j.bolt.connection.TelemetryApi; import org.neo4j.bolt.connection.message.BeginMessage; import org.neo4j.bolt.connection.message.CommitMessage; @@ -324,7 +324,7 @@ public void handle(DriverResponseHandler handler) { var apiTelemetryWork = new ApiTelemetryWork(TelemetryApi.UNMANAGED_TRANSACTION); var tx = new UnmanagedTransaction( connection, - DatabaseNameUtil.defaultDatabase(), + DatabaseName.defaultDatabase(), AccessMode.WRITE, null, (ignored) -> {}, @@ -362,7 +362,7 @@ public void handle(DriverResponseHandler handler) { var apiTelemetryWork = new ApiTelemetryWork(TelemetryApi.UNMANAGED_TRANSACTION); var tx = new UnmanagedTransaction( connection, - DatabaseNameUtil.defaultDatabase(), + DatabaseName.defaultDatabase(), AccessMode.WRITE, null, (ignored) -> {}, @@ -387,7 +387,7 @@ void shouldReleaseConnectionWhenTerminatedAndCommitted() { var apiTelemetryWork = new ApiTelemetryWork(TelemetryApi.UNMANAGED_TRANSACTION); var tx = new UnmanagedTransaction( connection, - DatabaseNameUtil.defaultDatabase(), + DatabaseName.defaultDatabase(), AccessMode.WRITE, null, (ignored) -> {}, @@ -415,7 +415,7 @@ void shouldNotCreateCircularExceptionWhenTerminationCauseEqualsToCursorFailure() var resultCursorsHolder = mockResultCursorWith(terminationCause); var tx = new UnmanagedTransaction( connection, - DatabaseNameUtil.defaultDatabase(), + DatabaseName.defaultDatabase(), AccessMode.WRITE, null, (ignored) -> {}, @@ -442,7 +442,7 @@ void shouldNotCreateCircularExceptionWhenTerminationCauseDifferentFromCursorFail var apiTelemetryWork = new ApiTelemetryWork(TelemetryApi.UNMANAGED_TRANSACTION); var tx = new UnmanagedTransaction( connection, - DatabaseNameUtil.defaultDatabase(), + DatabaseName.defaultDatabase(), AccessMode.WRITE, null, (ignored) -> {}, @@ -471,7 +471,7 @@ void shouldNotCreateCircularExceptionWhenTerminatedWithoutFailure() { var apiTelemetryWork = new ApiTelemetryWork(TelemetryApi.UNMANAGED_TRANSACTION); var tx = new UnmanagedTransaction( connection, - DatabaseNameUtil.defaultDatabase(), + DatabaseName.defaultDatabase(), AccessMode.WRITE, null, (ignored) -> {}, @@ -496,7 +496,7 @@ void shouldReleaseConnectionWhenTerminatedAndRolledBack() { var apiTelemetryWork = new ApiTelemetryWork(TelemetryApi.UNMANAGED_TRANSACTION); var tx = new UnmanagedTransaction( connection, - DatabaseNameUtil.defaultDatabase(), + DatabaseName.defaultDatabase(), AccessMode.WRITE, null, (ignored) -> {}, @@ -531,7 +531,7 @@ public void handle(DriverResponseHandler handler) { var apiTelemetryWork = new ApiTelemetryWork(TelemetryApi.UNMANAGED_TRANSACTION); var tx = new UnmanagedTransaction( connection, - DatabaseNameUtil.defaultDatabase(), + DatabaseName.defaultDatabase(), AccessMode.WRITE, null, (ignored) -> {}, @@ -566,7 +566,7 @@ public void handle(DriverResponseHandler handler) { var apiTelemetryWork = new ApiTelemetryWork(TelemetryApi.UNMANAGED_TRANSACTION); var tx = new UnmanagedTransaction( connection, - DatabaseNameUtil.defaultDatabase(), + DatabaseName.defaultDatabase(), AccessMode.WRITE, null, (ignored) -> {}, @@ -604,7 +604,7 @@ public void handle(DriverResponseHandler handler) { var apiTelemetryWork = new ApiTelemetryWork(TelemetryApi.UNMANAGED_TRANSACTION); var tx = new UnmanagedTransaction( connection, - DatabaseNameUtil.defaultDatabase(), + DatabaseName.defaultDatabase(), AccessMode.WRITE, null, (ignored) -> {}, @@ -662,7 +662,7 @@ public void handle(DriverResponseHandler handler) {} var apiTelemetryWork = new ApiTelemetryWork(TelemetryApi.UNMANAGED_TRANSACTION); var tx = new UnmanagedTransaction( connection, - DatabaseNameUtil.defaultDatabase(), + DatabaseName.defaultDatabase(), AccessMode.WRITE, null, (ignored) -> {}, @@ -740,7 +740,7 @@ public void handle(DriverResponseHandler handler) { var apiTelemetryWork = new ApiTelemetryWork(TelemetryApi.UNMANAGED_TRANSACTION); var tx = new UnmanagedTransaction( connection, - DatabaseNameUtil.defaultDatabase(), + DatabaseName.defaultDatabase(), AccessMode.WRITE, null, (ignored) -> {}, @@ -815,7 +815,7 @@ public void handle(DriverResponseHandler handler) { var apiTelemetryWork = new ApiTelemetryWork(TelemetryApi.UNMANAGED_TRANSACTION); var tx = new UnmanagedTransaction( connection, - DatabaseNameUtil.defaultDatabase(), + DatabaseName.defaultDatabase(), AccessMode.WRITE, null, (ignored) -> {}, @@ -1079,7 +1079,7 @@ private static UnmanagedTransaction beginTx(DriverBoltConnection connection, Set var apiTelemetryWork = new ApiTelemetryWork(TelemetryApi.UNMANAGED_TRANSACTION); var tx = new UnmanagedTransaction( connection, - DatabaseNameUtil.defaultDatabase(), + DatabaseName.defaultDatabase(), AccessMode.WRITE, null, (ignored) -> {}, diff --git a/driver/src/test/java/org/neo4j/driver/internal/util/DriverFactoryWithFixedRetryLogic.java b/driver/src/test/java/org/neo4j/driver/internal/util/DriverFactoryWithFixedRetryLogic.java index 9021bd2603..f6165f4753 100644 --- a/driver/src/test/java/org/neo4j/driver/internal/util/DriverFactoryWithFixedRetryLogic.java +++ b/driver/src/test/java/org/neo4j/driver/internal/util/DriverFactoryWithFixedRetryLogic.java @@ -16,7 +16,7 @@ */ package org.neo4j.driver.internal.util; -import io.netty.util.concurrent.EventExecutorGroup; +import java.util.concurrent.ScheduledExecutorService; import org.neo4j.driver.Logging; import org.neo4j.driver.internal.DriverFactory; import org.neo4j.driver.internal.retry.RetryLogic; @@ -30,7 +30,7 @@ public DriverFactoryWithFixedRetryLogic(int retryCount) { @Override protected RetryLogic createRetryLogic( - long maxTransactionRetryTime, EventExecutorGroup eventExecutorGroup, Logging logging) { + long maxTransactionRetryTime, ScheduledExecutorService executor, Logging logging) { return new FixedRetryLogic(retryCount); } } diff --git a/driver/src/test/java/org/neo4j/driver/testutil/DatabaseExtension.java b/driver/src/test/java/org/neo4j/driver/testutil/DatabaseExtension.java index ad44f68d81..948ea772bb 100644 --- a/driver/src/test/java/org/neo4j/driver/testutil/DatabaseExtension.java +++ b/driver/src/test/java/org/neo4j/driver/testutil/DatabaseExtension.java @@ -249,11 +249,14 @@ public boolean isNeo4j43OrEarlier() { private boolean isNeo4jVersionOrEarlier(int minor) { try (var session = driver.session()) { - var neo4jVersion = session.executeRead( - tx -> tx.run("CALL dbms.components() YIELD versions " + "RETURN versions[0] AS version") - .single() - .get("version") - .asString()); + var neo4jVersion = session.executeRead(tx -> tx.run( + """ + CALL dbms.components() YIELD name, versions + WHERE name = 'Neo4j Kernel' + RETURN versions[0] AS version""") + .single() + .get("version") + .asString()); var versions = neo4jVersion.split("\\."); return parseInt(versions[0]) <= 4 && parseInt(versions[1]) <= minor; } diff --git a/driver/src/test/java/org/neo4j/driver/testutil/TestUtil.java b/driver/src/test/java/org/neo4j/driver/testutil/TestUtil.java index 197299a162..9b6c4f58cb 100644 --- a/driver/src/test/java/org/neo4j/driver/testutil/TestUtil.java +++ b/driver/src/test/java/org/neo4j/driver/testutil/TestUtil.java @@ -29,7 +29,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import static org.neo4j.bolt.connection.DatabaseNameUtil.defaultDatabase; +import static org.neo4j.bolt.connection.DatabaseName.defaultDatabase; import static org.neo4j.driver.AccessMode.WRITE; import static org.neo4j.driver.SessionConfig.forDatabase; import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING; @@ -81,12 +81,11 @@ import org.neo4j.driver.exceptions.ServiceUnavailableException; import org.neo4j.driver.internal.NoOpBookmarkManager; import org.neo4j.driver.internal.adaptedbolt.DriverBoltConnection; -import org.neo4j.driver.internal.adaptedbolt.DriverBoltConnectionProvider; +import org.neo4j.driver.internal.adaptedbolt.DriverBoltConnectionSource; import org.neo4j.driver.internal.adaptedbolt.DriverResponseHandler; import org.neo4j.driver.internal.adaptedbolt.summary.PullSummary; import org.neo4j.driver.internal.async.NetworkSession; import org.neo4j.driver.internal.retry.RetryLogic; -import org.neo4j.driver.internal.security.BoltSecurityPlanManager; import org.neo4j.driver.internal.util.FixedRetryLogic; import org.neo4j.driver.internal.value.BoltValueFactory; import org.reactivestreams.Publisher; @@ -183,29 +182,29 @@ public static boolean databaseExists(Driver driver, String database) { } } - public static NetworkSession newSession(DriverBoltConnectionProvider connectionProvider, Set bookmarks) { + public static NetworkSession newSession(DriverBoltConnectionSource connectionProvider, Set bookmarks) { return newSession(connectionProvider, WRITE, bookmarks); } private static NetworkSession newSession( - DriverBoltConnectionProvider connectionProvider, AccessMode mode, Set bookmarks) { + DriverBoltConnectionSource connectionProvider, AccessMode mode, Set bookmarks) { return newSession(connectionProvider, mode, new FixedRetryLogic(0), bookmarks); } - public static NetworkSession newSession(DriverBoltConnectionProvider connectionProvider, AccessMode mode) { + public static NetworkSession newSession(DriverBoltConnectionSource connectionProvider, AccessMode mode) { return newSession(connectionProvider, mode, Collections.emptySet()); } - public static NetworkSession newSession(DriverBoltConnectionProvider connectionProvider, RetryLogic logic) { + public static NetworkSession newSession(DriverBoltConnectionSource connectionProvider, RetryLogic logic) { return newSession(connectionProvider, WRITE, logic, Collections.emptySet()); } - public static NetworkSession newSession(DriverBoltConnectionProvider connectionProvider) { + public static NetworkSession newSession(DriverBoltConnectionSource connectionProvider) { return newSession(connectionProvider, WRITE, Collections.emptySet()); } public static NetworkSession newSession( - DriverBoltConnectionProvider connectionProvider, + DriverBoltConnectionSource connectionProvider, AccessMode mode, RetryLogic retryLogic, Set bookmarks) { @@ -213,13 +212,12 @@ public static NetworkSession newSession( } public static NetworkSession newSession( - DriverBoltConnectionProvider connectionProvider, + DriverBoltConnectionSource connectionProvider, AccessMode mode, RetryLogic retryLogic, Set bookmarks, boolean telemetryDisabled) { return new NetworkSession( - BoltSecurityPlanManager.insecure(), connectionProvider, retryLogic, defaultDatabase(), @@ -230,7 +228,6 @@ public static NetworkSession newSession( DEV_NULL_LOGGING, NoOpBookmarkManager.INSTANCE, Config.defaultConfig().notificationConfig(), - Config.defaultConfig().notificationConfig(), null, telemetryDisabled, mock(AuthTokenManager.class), diff --git a/examples/LICENSES.txt b/examples/LICENSES.txt index 3d838254bd..0a33b0b1a2 100644 --- a/examples/LICENSES.txt +++ b/examples/LICENSES.txt @@ -4,12 +4,12 @@ libraries. For an overview of the licenses see the NOTICE.txt file. ------------------------------------------------------------------------------ Apache Software License, Version 2.0 - Neo4j Bolt Connection (Netty reference impl) - Neo4j Bolt Connection (Pooled provider impl) + Neo4j Bolt Connection (Bolt Provider reference impl) + Neo4j Bolt Connection (Pooled Source impl) Neo4j Bolt Connection (Provider SPI) - Neo4j Bolt Connection (Routed provider impl) + Neo4j Bolt Connection (Routed Source impl) Netty/Buffer - Netty/Codec + Netty/Codec/Base Netty/Common Netty/Handler Netty/Resolver diff --git a/examples/NOTICE.txt b/examples/NOTICE.txt index be72589619..fb63e48755 100644 --- a/examples/NOTICE.txt +++ b/examples/NOTICE.txt @@ -19,12 +19,12 @@ Third-party licenses -------------------- Apache Software License, Version 2.0 - Neo4j Bolt Connection (Netty reference impl) - Neo4j Bolt Connection (Pooled provider impl) + Neo4j Bolt Connection (Bolt Provider reference impl) + Neo4j Bolt Connection (Pooled Source impl) Neo4j Bolt Connection (Provider SPI) - Neo4j Bolt Connection (Routed provider impl) + Neo4j Bolt Connection (Routed Source impl) Netty/Buffer - Netty/Codec + Netty/Codec/Base Netty/Common Netty/Handler Netty/Resolver diff --git a/pom.xml b/pom.xml index 6a4523bb27..8404c5e053 100644 --- a/pom.xml +++ b/pom.xml @@ -26,25 +26,27 @@ parallelizableIT 3.5.3 + + true - 3.0.0 + 4.1.0 1.0.4 - 4.1.121.Final + 4.2.2.Final - 2023.0.17 + 2023.0.19 1.7.36 3.0 - 5.17.0 - 5.12.2 + 5.18.0 + 5.13.1 7.11.0 1.2.0 @@ -52,14 +54,14 @@ 1.27.1 1.18.0 - 1.80 + 1.81 1.2.13 2.19.0 1.18.38 24.2.1 - 1.14.6 - 1.0.11.RELEASE - 1.21.0 + 1.15.1 + 1.0.13.RELEASE + 1.21.1 2024-12.1 @@ -311,6 +313,7 @@ maven-surefire-plugin ${surefire.and.failsafe.version} + ${surefire.jpms.args} false org.graalvm.nativeimage:svm @@ -351,7 +354,7 @@ verify - -Dfile.encoding=${project.build.sourceEncoding} + -Dfile.encoding=${project.build.sourceEncoding} ${failsafe.sequential.jpms.args} false 1 true diff --git a/testkit-backend/LICENSES.txt b/testkit-backend/LICENSES.txt index aa001d723c..9949059506 100644 --- a/testkit-backend/LICENSES.txt +++ b/testkit-backend/LICENSES.txt @@ -7,12 +7,12 @@ Apache Software License, Version 2.0 Jackson-annotations Jackson-core jackson-databind - Neo4j Bolt Connection (Netty reference impl) - Neo4j Bolt Connection (Pooled provider impl) + Neo4j Bolt Connection (Bolt Provider reference impl) + Neo4j Bolt Connection (Pooled Source impl) Neo4j Bolt Connection (Provider SPI) - Neo4j Bolt Connection (Routed provider impl) + Neo4j Bolt Connection (Routed Source impl) Netty/Buffer - Netty/Codec + Netty/Codec/Base Netty/Common Netty/Handler Netty/Resolver diff --git a/testkit-backend/NOTICE.txt b/testkit-backend/NOTICE.txt index 71a12aa82e..0b4ad33765 100644 --- a/testkit-backend/NOTICE.txt +++ b/testkit-backend/NOTICE.txt @@ -22,12 +22,12 @@ Apache Software License, Version 2.0 Jackson-annotations Jackson-core jackson-databind - Neo4j Bolt Connection (Netty reference impl) - Neo4j Bolt Connection (Pooled provider impl) + Neo4j Bolt Connection (Bolt Provider reference impl) + Neo4j Bolt Connection (Pooled Source impl) Neo4j Bolt Connection (Provider SPI) - Neo4j Bolt Connection (Routed provider impl) + Neo4j Bolt Connection (Routed Source impl) Netty/Buffer - Netty/Codec + Netty/Codec/Base Netty/Common Netty/Handler Netty/Resolver diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/Runner.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/Runner.java index eedc41874f..db5e147113 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/Runner.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/Runner.java @@ -19,7 +19,8 @@ import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelInitializer; import io.netty.channel.EventLoopGroup; -import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.MultiThreadIoEventLoopGroup; +import io.netty.channel.nio.NioIoHandler; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import java.util.logging.Level; @@ -37,7 +38,7 @@ public static void main(String[] args) throws InterruptedException { ? Logging.none() : Logging.console(Level.parse(levelString)); - EventLoopGroup group = new NioEventLoopGroup(); + EventLoopGroup group = new MultiThreadIoEventLoopGroup(NioIoHandler.newFactory()); try { var bootstrap = new ServerBootstrap(); bootstrap diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/GetRoutingTable.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/GetRoutingTable.java index cb59015b60..81b305483e 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/GetRoutingTable.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/GetRoutingTable.java @@ -27,7 +27,7 @@ import neo4j.org.testkit.backend.messages.responses.RoutingTable; import neo4j.org.testkit.backend.messages.responses.TestkitResponse; import org.neo4j.bolt.connection.BoltServerAddress; -import org.neo4j.bolt.connection.DatabaseNameUtil; +import org.neo4j.bolt.connection.DatabaseName; import reactor.core.publisher.Mono; @Setter @@ -49,7 +49,7 @@ public TestkitResponse process(TestkitState testkitState) { data.getDriverId())); } - var databaseName = DatabaseNameUtil.database(data.getDatabase()); + var databaseName = DatabaseName.database(data.getDatabase()); var routingTableHandler = routingTableRegistry .getRoutingTableHandler(databaseName) .orElseThrow(() -> new IllegalStateException(String.format( diff --git a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/NewDriver.java b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/NewDriver.java index 8ccfb1169d..ec08076bf1 100644 --- a/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/NewDriver.java +++ b/testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/NewDriver.java @@ -56,7 +56,6 @@ import org.neo4j.driver.internal.InternalNotificationSeverity; import org.neo4j.driver.internal.InternalServerAddress; import org.neo4j.driver.internal.SecuritySettings; -import org.neo4j.driver.internal.security.BoltSecurityPlanManager; import org.neo4j.driver.internal.security.SecurityPlans; import org.neo4j.driver.internal.security.StaticAuthTokenManager; import org.neo4j.driver.net.ServerAddressResolver; @@ -234,7 +233,7 @@ private org.neo4j.driver.Driver driver( var securityPlan = SecurityPlans.createSecurityPlan( securitySettings, uri.getScheme(), clientCertificateManager, config.logging()); return new DriverFactoryWithDomainNameResolver(domainNameResolver, testkitState, driverId) - .newInstance(uri, authTokenManager, config, BoltSecurityPlanManager.from(securityPlan), null, null); + .newInstance(uri, authTokenManager, clientCertificateManager, config, securityPlan, null, null); } private Optional handleExceptionAsErrorResponse(TestkitState testkitState, RuntimeException e) {