Skip to content

Commit

Permalink
Fixes #558: Check for neo4j version being compatible with neo version (
Browse files Browse the repository at this point in the history
…#2700)

* Fixes #558: Check for neo4j version being compatible with neo version

* doc addition - changed neo4j version getting

* added test - changed version handling

* edit comment
  • Loading branch information
vga91 authored May 6, 2022
1 parent 46d99b6 commit 4292b67
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 0 deletions.
24 changes: 24 additions & 0 deletions core/src/main/java/apoc/cypher/CypherInitializer.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import apoc.ApocConfig;
import apoc.util.Util;
import apoc.version.Version;
import org.apache.commons.configuration2.Configuration;
import org.neo4j.common.DependencyResolver;
import org.neo4j.configuration.Config;
import org.neo4j.configuration.GraphDatabaseSettings;
import org.neo4j.internal.helpers.collection.Iterators;
import org.neo4j.kernel.api.procedure.GlobalProcedures;
Expand All @@ -15,7 +17,9 @@
import java.util.Collections;

import java.util.ConcurrentModificationException;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.TreeMap;

public class CypherInitializer implements AvailabilityListener {
Expand All @@ -24,6 +28,7 @@ public class CypherInitializer implements AvailabilityListener {
private final Log userLog;
private final GlobalProcedures procs;
private final DependencyResolver dependencyResolver;
private final String defaultDb;

/**
* indicates the status of the initializer, to be used for tests to ensure initializer operations are already done
Expand All @@ -35,6 +40,7 @@ public CypherInitializer(GraphDatabaseAPI db, Log userLog) {
this.userLog = userLog;
this.dependencyResolver = db.getDependencyResolver();
this.procs = dependencyResolver.resolveDependency(GlobalProcedures.class);
this.defaultDb = dependencyResolver.resolveDependency(Config.class).get(GraphDatabaseSettings.default_database);
}

public boolean isFinished() {
Expand All @@ -57,6 +63,17 @@ public void available() {
if (!isSystemDatabase) {
awaitApocProceduresRegistered();
}

if (defaultDb.equals(db.databaseName())) {
final List<String> versions = db.executeTransactionally("CALL dbms.components", Collections.emptyMap(),
r -> (List<String>) r.next().get("versions"));
final String apocFullVersion = Version.class.getPackage().getImplementationVersion();
if (isVersionDifferent(versions, apocFullVersion)) {
userLog.warn("The apoc version (%s) and the Neo4j DBMS versions %s are incompatible. \n" +
"See the compatibility matrix in https://neo4j.com/labs/apoc/4.4/installation/ to see the correct version",
apocFullVersion, versions.toString());
}
}
Configuration config = dependencyResolver.resolveDependency(ApocConfig.class).getConfig();

for (String query : collectInitializers(isSystemDatabase, config)) {
Expand All @@ -75,6 +92,13 @@ public void available() {
}).start();
}

// the visibility is public only for testing purpose, it could be private otherwise
public static boolean isVersionDifferent(List<String> versions, String apocFullVersion) {
return Optional.ofNullable(apocFullVersion)
.map(v -> versions.stream().noneMatch(v::startsWith))
.orElse(true);
}

private Collection<String> collectInitializers(boolean isSystemDatabase, Configuration config) {
Map<String, String> initializers = new TreeMap<>();

Expand Down
20 changes: 20 additions & 0 deletions core/src/test/java/apoc/cypher/CypherIsVersionDifferentTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package apoc.cypher;

import org.junit.Test;

import java.util.List;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

public class CypherIsVersionDifferentTest {

@Test
public void shouldReturnFalseOnlyWithCompatibleVersion() {
assertTrue(CypherInitializer.isVersionDifferent(List.of("3.5"), "4.4.0.2"));
assertTrue(CypherInitializer.isVersionDifferent(List.of("5_0"), "4.4.0.2"));

// we expect that APOC versioning is always consistent to Neo4j versioning
assertFalse(CypherInitializer.isVersionDifferent(List.of("5_0"), "5_0_0_1"));
}
}
6 changes: 6 additions & 0 deletions docs/asciidoc/modules/ROOT/pages/installation/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ The version compatibility matrix explains the mapping between Neo4j and APOC ver

// end::version-matrix[]

If by mistake a jar not compatible with the neo4j version is inserted, a `log.warn` like this will appear in `neo4j.log`:
```
The apoc version (<APOC_VERSION>) and the Neo4j DBMS versions [NEO4J_VERSION] are incompatible.
See the compatibility matrix in https://neo4j.com/labs/apoc/4.4/installation/ to see the correct version
```

[[docker]]
== Docker

Expand Down

0 comments on commit 4292b67

Please sign in to comment.