Skip to content

build: Keep eventloop around. #2838

New issue

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

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

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
*/
package org.springframework.data.neo4j.test;

import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.util.concurrent.DefaultThreadFactory;
import org.apache.commons.logging.Log;
import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.BeforeEachCallback;
Expand All @@ -23,21 +26,26 @@
import org.junit.platform.commons.support.ReflectionSupport;
import org.neo4j.driver.AccessMode;
import org.neo4j.driver.AuthToken;
import org.neo4j.driver.AuthTokenManagers;
import org.neo4j.driver.AuthTokens;
import org.neo4j.driver.Config;
import org.neo4j.driver.Driver;
import org.neo4j.driver.GraphDatabase;
import org.neo4j.driver.Logging;
import org.neo4j.driver.Record;
import org.neo4j.driver.Session;
import org.neo4j.driver.SessionConfig;
import org.neo4j.driver.internal.DriverFactory;
import org.neo4j.driver.internal.SecuritySettings;
import org.neo4j.driver.internal.security.SecurityPlan;
import org.neo4j.driver.internal.security.SecurityPlans;
import org.springframework.core.log.LogMessage;
import org.springframework.lang.Nullable;
import org.testcontainers.containers.Neo4jContainer;
import org.testcontainers.utility.TestcontainersConfiguration;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.net.URI;
import java.util.List;
import java.util.Locale;
import java.util.Map;
Expand Down Expand Up @@ -82,12 +90,14 @@ public class Neo4jExtension implements BeforeAllCallback, BeforeEachCallback {
private static final String SYS_PROPERTY_FORCE_CONTAINER_REUSE = "SDN_FORCE_REUSE_OF_CONTAINERS";
private static final Log log = org.apache.commons.logging.LogFactory.getLog(Neo4jExtension.class);

private static Set<String> COMMUNITY_EDITION_INDICATOR = Set.of("community");
private static final Set<String> COMMUNITY_EDITION_INDICATOR = Set.of("community");
private static final Set<String> COMMERCIAL_EDITION_INDICATOR = Set.of("commercial", "enterprise");

private static Set<String> COMMERCIAL_EDITION_INDICATOR = Set.of("commercial", "enterprise");
private static final EventLoopGroup EVENT_LOOP_GROUP = new NioEventLoopGroup(new DefaultThreadFactory(Neo4jExtension.class, true));

@Override
public void beforeAll(ExtensionContext context) throws Exception {

List<Field> injectableFields = ReflectionSupport.findFields(context.getRequiredTestClass(),
field -> Modifier.isStatic(field.getModifiers()) && field.getType() == Neo4jConnectionSupport.class,
HierarchyTraversalMode.BOTTOM_UP);
Expand Down Expand Up @@ -163,12 +173,16 @@ private void checkRequiredFeatures(Neo4jConnectionSupport neo4jConnectionSupport
*/
public static final class Neo4jConnectionSupport implements ExtensionContext.Store.CloseableResource {

public final String url;
private final DriverFactory driverFactory;

public final URI uri;

public final AuthToken authToken;

public final Config config;

private final SecurityPlan securityPlan;

private volatile ServerVersion cachedServerVersion;

/**
Expand All @@ -177,11 +191,14 @@ public static final class Neo4jConnectionSupport implements ExtensionContext.Sto
private volatile Driver driverInstance;

public Neo4jConnectionSupport(String url, AuthToken authToken) {
this.url = url;
this.uri = URI.create(url);
this.authToken = authToken;
this.config = Config.builder().withLogging(Logging.slf4j())
.withMaxConnectionPoolSize(Runtime.getRuntime().availableProcessors())
.build();
var settings = new SecuritySettings(config.encrypted(), config.trustStrategy());
this.securityPlan = SecurityPlans.createSecurityPlan(settings, uri.getScheme());
this.driverFactory = new DriverFactory();
}

/**
Expand All @@ -198,14 +215,18 @@ public Driver getDriver() {
synchronized (this) {
driver = this.driverInstance;
if (!isUsable(driver)) {
this.driverInstance = GraphDatabase.driver(url, authToken, config);
this.driverInstance = createDriverInstance();
driver = this.driverInstance;
}
}
}
return driver;
}

private Driver createDriverInstance() {
return this.driverFactory.newInstance(uri, AuthTokenManagers.basic(() -> authToken), config, securityPlan, EVENT_LOOP_GROUP, null);
}

/**
* A driver is usable if it's not null and can verify its connectivity. This method force closes
* the bean if the connectivity cannot be verified to avoid having a netty pool dangling around.
Expand Down