1 package de.dlr.shepard.common.neo4j;
2
3 import ac.simons.neo4j.migrations.core.Migrations;
4 import ac.simons.neo4j.migrations.core.MigrationsConfig;
5 import ac.simons.neo4j.migrations.core.MigrationsConfig.VersionSortOrder;
6 import ac.simons.neo4j.migrations.core.MigrationsException;
7 import io.quarkus.logging.Log;
8 import jakarta.annotation.Nullable;
9 import java.nio.file.Paths;
10 import org.eclipse.microprofile.config.ConfigProvider;
11 import org.neo4j.driver.AuthTokens;
12 import org.neo4j.driver.Driver;
13 import org.neo4j.driver.GraphDatabase;
14 import org.neo4j.driver.exceptions.ServiceUnavailableException;
15
16 public class MigrationsRunner {
17
18 private final Migrations migrations;
19 private final Driver driver;
20
21 public MigrationsRunner() {
22 this(null);
23 }
24
25 public MigrationsRunner(@Nullable String targetVersion) {
26 String username = ConfigProvider.getConfig().getValue("neo4j.username", String.class);
27 String password = ConfigProvider.getConfig().getValue("neo4j.password", String.class);
28 String host = "neo4j://" + ConfigProvider.getConfig().getValue("neo4j.host", String.class);
29 driver = GraphDatabase.driver(host, AuthTokens.basic(username, password));
30
31
32
33 var localPath = this.getClass().getClassLoader().getResource("neo4j/migrations").toString();
34 var dockerPath = Paths.get("/deployments/neo4j/migrations").toAbsolutePath().toString();
35 var isDocker = localPath.startsWith("jar");
36 var locationsToScan = isDocker ? dockerPath : localPath;
37
38 var config = MigrationsConfig.builder()
39 .withTransactionMode(MigrationsConfig.TransactionMode.PER_STATEMENT)
40 .withPackagesToScan("de.dlr.shepard.common.neo4j.migrations")
41 .withLocationsToScan("file://" + locationsToScan)
42 .withVersionSortOrder(VersionSortOrder.SEMANTIC)
43 .withTarget(targetVersion)
44 .build();
45
46 migrations = new Migrations(config, driver);
47 }
48
49 public void waitForConnection() {
50 while (true) {
51 try {
52 driver.verifyConnectivity();
53 break;
54 } catch (Exception e) {
55 Log.warn("Cannot connect to neo4j database. Retrying...");
56 }
57 try {
58 Thread.sleep(1000);
59 } catch (InterruptedException e) {
60 Log.error("Cannot sleep while waiting for neo4j Connection");
61 Thread.currentThread().interrupt();
62 }
63 }
64 }
65
66 public void apply() {
67 try {
68 migrations.apply();
69 } catch (ServiceUnavailableException e) {
70 Log.error("Migrations cannot be executed because the neo4j database is not available");
71 } catch (MigrationsException e) {
72 Log.error("An error occurred during the execution of the migrations: ", e);
73 }
74 }
75 }