View Javadoc
1   package de.dlr.shepard.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.MigrationsException;
6   import io.quarkus.logging.Log;
7   import java.nio.file.Paths;
8   import org.eclipse.microprofile.config.ConfigProvider;
9   import org.neo4j.driver.AuthTokens;
10  import org.neo4j.driver.Driver;
11  import org.neo4j.driver.GraphDatabase;
12  import org.neo4j.driver.exceptions.ServiceUnavailableException;
13  
14  public class MigrationsRunner {
15  
16    private Migrations migrations;
17    private Driver driver;
18  
19    public MigrationsRunner() {
20      String username = ConfigProvider.getConfig().getValue("neo4j.username", String.class);
21      String password = ConfigProvider.getConfig().getValue("neo4j.password", String.class);
22      String host = "neo4j://" + ConfigProvider.getConfig().getValue("neo4j.host", String.class);
23      driver = GraphDatabase.driver(host, AuthTokens.basic(username, password));
24  
25      // This is a workaround to make all migrations available in a dockerized quarkus jar.
26      // See https://gitlab.com/dlr-shepard/shepard/-/issues/146 for more information
27      var localPath = this.getClass().getClassLoader().getResource("neo4j/migrations").toString();
28      var dockerPath = Paths.get("/deployments/neo4j/migrations").toAbsolutePath().toString();
29      var isDocker = localPath.startsWith("jar");
30      var locationsToScan = isDocker ? dockerPath : localPath;
31  
32      var config = MigrationsConfig.builder()
33        .withTransactionMode(MigrationsConfig.TransactionMode.PER_STATEMENT)
34        .withPackagesToScan("de.dlr.shepard.neo4j.migrations")
35        .withLocationsToScan("file://" + locationsToScan)
36        .build();
37  
38      migrations = new Migrations(config, driver);
39    }
40  
41    public void waitForConnection() {
42      while (true) {
43        try {
44          driver.verifyConnectivity();
45          break;
46        } catch (Exception e) {
47          Log.warn("Cannot connect to neo4j database. Retrying...");
48        }
49        try {
50          Thread.sleep(1000);
51        } catch (InterruptedException e) {
52          Log.error("Cannot sleep while waiting for neo4j Connection");
53          Thread.currentThread().interrupt();
54        }
55      }
56    }
57  
58    public void apply() {
59      try {
60        migrations.apply();
61      } catch (ServiceUnavailableException e) {
62        Log.error("Migrations cannot be executed because the neo4j database is not available");
63      } catch (MigrationsException e) {
64        Log.error("An error occurred during the execution of the migrations: ", e);
65      }
66    }
67  }