neo4j / apoc

Apache License 2.0
85 stars 27 forks source link

Add documentation that shows how to use an apoc dependency for a neo4j embedded API test #79

Open neo-technology-build-agent opened 2 years ago

neo-technology-build-agent commented 2 years ago

Issue by jexp Monday Sep 07, 2020 at 07:42 GMT Originally opened as https://github.com/neo4j-contrib/neo4j-apoc-procedures/issues/1656


So if someone writes an extension / procedure / integration-test that needs apoc, we need to document how they need to setup their java dependencies (maven/gradle) and the code they need to use with neo4j-harness / TestGraphDBService etc. to properly load the apoc procs.

@michael-simons had figure out a while ago how to do that, we can use his example code for that.

neo-technology-build-agent commented 2 years ago

Comment by jexp Monday Sep 07, 2020 at 07:44 GMT


With Embedded:

https://github.com/michael-simons/neo4j-sdn-ogm-tips/blob/master/examples/testing-ogm-against-embedded-with-apoc/src/test/java/org/neo4j/tips/testing/testing_ogm_against_embedded_with_apoc/ApplicationTests.java#L53-L67

examples/testing-ogm-against-embedded-with-apoc/src/test/java/org/neo4j/tips/testing/testing_ogm_against_embedded_with_apoc/ApplicationTests.java:53-67
        // We need the directory containing the APOC jar, otherwise all APOC procedures must be loaded manually.
        // While the intuitive idea might be not having APOC on the class path at all in that case and just dump
        // it into the plugin directory, it doesn't work as APOC needs some extension factories to work with
        // and those are not loaded from the plugin unless it's part of the original class loader that loaded neo.
        // If you know which methods you're a gonna use, you can configure them manually instead.

With testcontainers

https://github.com/michael-simons/neo4j-sdn-ogm-tips/blob/master/examples/testing-ogm-against-testcontainers-with-apoc/src/test/java/org/neo4j/tips/testing/testing_ogm_against_testcontainers_with_apoc/ApplicationTests.java#L57-L87

neo-technology-build-agent commented 2 years ago

Comment by pelletier197 Friday Sep 25, 2020 at 16:58 GMT


The method you specified there does not work with neo4j 4.1.1+. Apoc does not provide the core functions in their jar anymore.

neo-technology-build-agent commented 2 years ago

Comment by Lukasmp3 Monday Feb 01, 2021 at 09:41 GMT


Still not any progress about this that would work on neo4j 4.1.1+ or neo4j 4.2.1.+?

neo-technology-build-agent commented 2 years ago

Comment by datanostra Wednesday Mar 10, 2021 at 10:13 GMT


Doesn't work with current apoc maven repository (4.2.0.1): https://mvnrepository.com/artifact/org.neo4j.procedure/apoc/4.2.0.1

I successfully run the above example injecting manually the apoc-all dependency, though. But apoc-all is not available from maven repository.

neo-technology-build-agent commented 2 years ago

Comment by fbiville Friday May 07, 2021 at 16:27 GMT


I believe the easiest way is to download APOC "fat JAR" (apoc-XXX-all.jar), which is currently not available from Maven Central, but only from GitHub releases (see https://github.com/neo4j-contrib/neo4j-apoc-procedures/issues/1404 that describes this very issue) as @datanostra pointed out.

@JMHReif and I hacked together to get this fat JAR and add it to Maven's local cache: https://github.com/fbiville/apoc-testing-experiment.

That still requires a manual script invocation so it is far from ideal and solving #1404 would be a better way to address this whole situation.

neo-technology-build-agent commented 2 years ago

Comment by fbiville Wednesday May 12, 2021 at 08:59 GMT


It appears APOC fat JAR is already in Maven Central, it's just a matter of adding it with the right classifier:

        <dependency>
            <groupId>org.neo4j.procedure</groupId>
            <artifactId>apoc</artifactId>
            <version>${apoc.version}</version>
            <scope>test</scope>
            <classifier>all</classifier>
        </dependency>

https://github.com/fbiville/apoc-testing-experiment has been updated. The TestContainers approach works well with Neo4j 4.2 and APOC 4.2. We'll add a test-harness example soon.

neo-technology-build-agent commented 2 years ago

Comment by marksouletheprogrammer Wednesday Aug 10, 2022 at 23:26 GMT


@fbiville Any chance we can get the test-harness example soon?

w22116972 commented 1 year ago

Not sure this solution could help I installed with org.neo4j.procedure in maven and register it with embedded database.

Env: Neo4j 5.3

<apoc.version>5.3.0</apoc.version>
...
        <dependency>
            <groupId>org.neo4j.procedure</groupId>
            <artifactId>apoc-core</artifactId>
            <version>${apoc.version}</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.neo4j.procedure/apoc-extended -->
        <dependency>
            <groupId>org.neo4j.procedure</groupId>
            <artifactId>apoc-extended</artifactId>
            <version>${apoc.version}</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.neo4j.procedure/apoc-processor -->
        <dependency>
            <groupId>org.neo4j.procedure</groupId>
            <artifactId>apoc-processor</artifactId>
            <version>${apoc.version}</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.neo4j.procedure/apoc-common -->
        <dependency>
            <groupId>org.neo4j.procedure</groupId>
            <artifactId>apoc-common</artifactId>
            <version>${apoc.version}</version>
        </dependency>

I register it with default database

final DatabaseManagementService dbms = new DatabaseManagementServiceBuilder(DATABASE_DIRECTORY_PATH)
        .setConfig(BoltConnector.listen_address, LOCAL_ADDRESS)
        .setConfig(GraphDatabaseSettings.default_listen_address, LOCAL_ADDRESS)
        .setConfig(BoltConnector.enabled, true)
        .setConfig(GraphDatabaseSettings.auth_enabled, false)
        .setConfig(HttpConnector.enabled, true).setConfig(GraphDatabaseSettings.procedure_unrestricted, List.of("apoc.*"))
        .build();
GlobalProcedures procedures = ((GraphDatabaseAPI) dbms.database(GraphDatabaseSettings.DEFAULT_DATABASE_NAME))
                .getDependencyResolver()
                .resolveDependency(GlobalProcedures.class);
List<Class<?>> apocProcedures = List.of(Coll.class, apoc.map.Maps.class, Json.class, Create.class,
                apoc.date.Date.class, apoc.lock.Lock.class, LoadJson.class, Xml.class, PathExplorer.class, Meta.class,
                GraphRefactoring.class, apoc.help.Help.class);
apocProcedures.forEach((proc) -> {
            try {
                procedures.registerProcedure(proc);
            } catch (KernelException e) {
                throw new RuntimeException("Error registering "+proc,e);
            }
        });

Then get session from above DatabaseManagementService dbms

    @Test
    @DisplayName("Plugin path should be available")
    public void testPluginIsAvailable() {
        try (Session session = XXX.session()) {
            session.run("CALL apoc.help('keyword')");
        }
    }

List all procedures

procedures.getAllProcedures().forEach(x -> System.out.println(x.name().name()));

Just for more detailed information

import org.neo4j.kernel.api.procedure.GlobalProcedures;
import org.neo4j.kernel.internal.GraphDatabaseAPI;
import apoc.coll.Coll;
import apoc.convert.Json;
import apoc.create.Create;
import apoc.load.LoadJson;
import apoc.load.Xml;
import apoc.meta.Meta;
import apoc.path.PathExplorer;