How to configure Neo4j embedded to run apoc proced

2019-02-23 08:05发布

I have setup Neo4j using the latest spring 1.5 release, spring-data-neo4j 4.2, with ogm drivers. The configuration is using embedded driver without URI (so impermanent database store)

Here is the spring @Configuration bean content:

@Bean
public org.neo4j.ogm.config.Configuration neo4jConfiguration() {
    org.neo4j.ogm.config.Configuration configuration = new org.neo4j.ogm.config.Configuration();
    configuration.driverConfiguration().setDriverClassName("org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver");
    // don't set the URI for embedded so we get an impermanent database
    return configuration;
}

@Bean
public SessionFactory getSessionFactory() {
    return new SessionFactory(
            neo4jConfiguration(),
            "xxx.yyy.springboot.neo4j.domain");
}

@Bean
public Neo4jTransactionManager transactionManager() {
    return new Neo4jTransactionManager(getSessionFactory());
}

Trying to run built in procedure works fine:

/**
 * Test we can call out to standard built-in procedures using cypher
 */
@Test
public void testNeo4jProcedureCalls() {

    Session session = sessionFactory.openSession();
    Result result = session.query("CALL dbms.procedures()", ImmutableMap.of());

    assertThat(result).isNotNull();
    List<Map<String, Object>> dataList = StreamSupport.stream(result.spliterator(), false)
            .collect(Collectors.toList());
    assertThat(dataList).isNotNull();
    assertThat(dataList.size()).isGreaterThan(0);
}

Now I'd like to install and run apoc procedures, which I've added to the classpath:

/**
 * Test we can call out to https://neo4j-contrib.github.io/neo4j-apoc-procedures
 */
@Test
public void testNeo4jApocProcedureCalls() {

    Session session = sessionFactory.openSession();
    Result result = session.query("CALL apoc.help(\"apoc\")", ImmutableMap.of());

    assertThat(result).isNotNull();
    List<Map<String, Object>> dataList = StreamSupport.stream(result.spliterator(), false)
            .collect(Collectors.toList());
    assertThat(dataList).isNotNull();
    assertThat(dataList.size()).isGreaterThan(0);
}

However, the above fails with error Description: There is no procedure with the name 'apoc.help' registered for this database instance

I couldn't find any documentation for registering apoc procedures to run in embedded mode. Couldn't find any reference to registering procedures in the OGM documentation. Any tips or snippets would be appreciated.

2条回答
太酷不给撩
2楼-- · 2019-02-23 08:44

Thanks for the pointer Michael. Your example is good for direct access, and this answer gave me the details needed to access through the neo4j-ogm layer:

Deploy a Procedure to Neo4J when using the embedded driver

so here's what I ended up with to register procedures through spring-data-neo4j

Note: isEmbedded() checks the neo4j driver property value contains 'embedded', and the Components.driver() call is static method provided by the ogm layer.

public void registerProcedures(List<Class<?>> toRegister) {
    if(isEmbedded()) {
        EmbeddedDriver embeddedDriver = (EmbeddedDriver) Components.driver();
        GraphDatabaseService databaseService = embeddedDriver.getGraphDatabaseService();
        Procedures procedures = ((GraphDatabaseAPI) databaseService).getDependencyResolver().resolveDependency(Procedures.class);
        toRegister.forEach((proc) -> {
            try {
                procedures.registerProcedure(proc);
            } catch (KernelException e) {
                throw new RuntimeException("Error registering " + proc, e);
            }
        });
    }
}

and add the call to register the procedures in the test when running with embedded:

@Test
public void testNeo4jApocProcedureCalls() {

    registerProcedures(asList(
            Help.class,
            Json.class,
            LoadJson.class,
            Xml.class,
            PathExplorer.class,
            Meta.class)
    );
    Session session = sessionFactory.openSession();
    Result result = session.query("CALL apoc.help('apoc')", ImmutableMap.of());
查看更多
神经病院院长
3楼-- · 2019-02-23 08:45

You have to register them manually with your GraphDatabaseService.

See here for an example: https://github.com/neo4j-contrib/rabbithole/blob/3.0/src/main/java/org/neo4j/community/console/Neo4jService.java#L55

查看更多
登录 后发表回答