Testcontainers-java: Cannot deploy Neo4j unmanaged extension

Created on 20 May 2020  路  4Comments  路  Source: testcontainers/testcontainers-java

First, thanks for the amazing work everyone. TestContainers and the Neo4j module are great :)

Context

I recently migrated Liquigraph 4 (for Neo4j 4) tests to TestContainers and I used a Cypher user-defined procedure to remove all data, indices and constraints from the running Neo4j instance (via Neo4jContainer) between each test.

I'm trying the same migration for Liquigraph 3 (for Neo4j 3) and unfortunately, a Cypher extension is not possible as the API has changed in incompatible ways across Neo4j 3.x versions.
The "universal" way to go in that case is to use the older mechanism called unmanaged extension.
However, it does not seem to work with Neo4jContainer for reasons that elude me.

How to reproduce

cd $(mktemp -d) && \
   git clone https://github.com/fbiville/test-containers-neo4j-unmanaged-extensions.git && \
   mvn -f test-containers-neo4j-unmanaged-extensions/pom.xml test

What happens

The test will fail.

When inspecting the container, the unmanaged extension setting is properly exported to the environment (as NEO4J_dbms_unmanaged__extension__classes) but neo4j.conf is not modified (no dbms.unmanaged_extension_classes set). Therefore, the extension is not enabled.

As described in the reproduction repository README, you can suspend the execution of the test and inspect the running container by starting an interactive shell session.

The same extension works fine when deployed to a Neo4j instance managed by Neo4j Desktop.

What should happen

neo4j.conf should be appropriately updated, thus enabling the extension (and the test should succeed).

Most helpful comment

Thanks for the great reproducer, @fbiville. That was really helpful to figure things out.

There are two issues here, both related to Neo4j respectively the Neo4j Docker image itself, not to test containers. So please @bsideup you can close this issue.

Container doesn't startup at all in 3.5, 3.4 and probably older

The container fails to start with the following exception:
com.sun.jersey.api.container.ContainerException: The ResourceConfig instance does not contain any root resource classes

Neo4j cannot correctly load / deduce the path of the JAX-RS resource.

Solution: Annotate the resource with @Path and the methods as needed, i.e:

@Path("/clearDb")
public class ClearDatabaseExtension {

    private final GraphDatabaseService graphDb;

    public ClearDatabaseExtension(@Context GraphDatabaseService graphDb) {
        this.graphDb = graphDb;
    }

    @POST
    public void clear() {
    }
}

Container config is not applied

First of all: The Neo4jContainer#withNeo4jConfig does not modify neo4j.conf itself. So settings made through this convenience method will not appear in the config file. It only formats the settings according to our docs (see docker-environment-variables).

Second: The settings is correct and works in all later Neo4j images. However, 3.0.0 upto (excluding) 3.0.12 seems buggy in regard of dbms.unmanaged_extension_classes.

To fix this, one can add the setting a second time as env-Variable, shown below:

private static final Neo4jContainer<?> CONTAINER = new Neo4jContainer<>(String.format("neo4j:%s", neo4jVersion()))
        .withAdminPassword(ADMIN_PASSWORD)
        .withPlugins(MountableFile.forHostPath(extensionPath()))
        .withNeo4jConfig("dbms.unmanaged_extension_classes", String
                .format("%s=/ext", ClearDatabaseExtension.class.getPackage().getName()))
        .withEnv("NEO4J_dbms_unmanagedExtensionClasses", String
                .format("%s=/ext", ClearDatabaseExtension.class.getPackage().getName()));

All 4 comments

/cc @michael-simons

I鈥檒l have a look next week. Afk for the long weekend.

Thanks for the great reproducer, @fbiville. That was really helpful to figure things out.

There are two issues here, both related to Neo4j respectively the Neo4j Docker image itself, not to test containers. So please @bsideup you can close this issue.

Container doesn't startup at all in 3.5, 3.4 and probably older

The container fails to start with the following exception:
com.sun.jersey.api.container.ContainerException: The ResourceConfig instance does not contain any root resource classes

Neo4j cannot correctly load / deduce the path of the JAX-RS resource.

Solution: Annotate the resource with @Path and the methods as needed, i.e:

@Path("/clearDb")
public class ClearDatabaseExtension {

    private final GraphDatabaseService graphDb;

    public ClearDatabaseExtension(@Context GraphDatabaseService graphDb) {
        this.graphDb = graphDb;
    }

    @POST
    public void clear() {
    }
}

Container config is not applied

First of all: The Neo4jContainer#withNeo4jConfig does not modify neo4j.conf itself. So settings made through this convenience method will not appear in the config file. It only formats the settings according to our docs (see docker-environment-variables).

Second: The settings is correct and works in all later Neo4j images. However, 3.0.0 upto (excluding) 3.0.12 seems buggy in regard of dbms.unmanaged_extension_classes.

To fix this, one can add the setting a second time as env-Variable, shown below:

private static final Neo4jContainer<?> CONTAINER = new Neo4jContainer<>(String.format("neo4j:%s", neo4jVersion()))
        .withAdminPassword(ADMIN_PASSWORD)
        .withPlugins(MountableFile.forHostPath(extensionPath()))
        .withNeo4jConfig("dbms.unmanaged_extension_classes", String
                .format("%s=/ext", ClearDatabaseExtension.class.getPackage().getName()))
        .withEnv("NEO4J_dbms_unmanagedExtensionClasses", String
                .format("%s=/ext", ClearDatabaseExtension.class.getPackage().getName()));

Thanks a lot, I updated https://github.com/fbiville/test-containers-neo4j-unmanaged-extensions to include the fixes (and their description)

Was this page helpful?
0 / 5 - 0 ratings