View Javadoc
1   package de.dlr.shepard.common.neo4j;
2   
3   import de.dlr.shepard.auth.apikey.entities.ApiKey;
4   import de.dlr.shepard.auth.permission.model.Permissions;
5   import de.dlr.shepard.auth.users.entities.User;
6   import de.dlr.shepard.common.subscription.entities.Subscription;
7   import de.dlr.shepard.common.util.IConnector;
8   import de.dlr.shepard.context.collection.entities.Collection;
9   import de.dlr.shepard.context.labjournal.entities.LabJournalEntry;
10  import de.dlr.shepard.context.references.dataobject.entities.CollectionReference;
11  import de.dlr.shepard.context.references.file.entities.FileReference;
12  import de.dlr.shepard.context.references.spatialdata.entities.SpatialDataReference;
13  import de.dlr.shepard.context.references.structureddata.entities.StructuredDataReference;
14  import de.dlr.shepard.context.references.timeseriesreference.model.TimeseriesReference;
15  import de.dlr.shepard.context.references.uri.entities.URIReference;
16  import de.dlr.shepard.context.semantic.entities.SemanticAnnotation;
17  import de.dlr.shepard.context.version.entities.Version;
18  import de.dlr.shepard.data.file.entities.FileContainer;
19  import de.dlr.shepard.data.spatialdata.model.SpatialDataContainer;
20  import de.dlr.shepard.data.structureddata.entities.StructuredData;
21  import de.dlr.shepard.data.timeseries.model.Timeseries;
22  import de.dlr.shepard.data.timeseries.model.TimeseriesTuple;
23  import io.quarkus.logging.Log;
24  import java.util.Collections;
25  import lombok.Getter;
26  import org.eclipse.microprofile.config.ConfigProvider;
27  import org.neo4j.ogm.config.Configuration;
28  import org.neo4j.ogm.exception.ConnectionException;
29  import org.neo4j.ogm.model.Result;
30  import org.neo4j.ogm.session.Session;
31  import org.neo4j.ogm.session.SessionFactory;
32  
33  /**
34   * Connector for read and write access to the Neo4J database. The class
35   * represents the lowest level of data access to the Neo4J database.
36   *
37   */
38  // The static getter is generated by lombok, therefore we can suppress the PMD warning.
39  @SuppressWarnings("PMD.MissingStaticMethodInNonInstantiatableClass")
40  public final class NeoConnector implements IConnector {
41  
42    private SessionFactory sessionFactory = null;
43  
44    @Getter
45    private static final NeoConnector instance = new NeoConnector();
46  
47    /**
48     * Private constructor
49     */
50    private NeoConnector() {}
51  
52    /**
53     * Establishes a connection to the Neo4J server by using the URL saved in the
54     * config.properties file returned by the DatabaseHelper. This will block until
55     * a connection could be established.
56     */
57    @Override
58    public boolean connect() {
59      String username = ConfigProvider.getConfig().getValue("neo4j.username", String.class);
60      String password = ConfigProvider.getConfig().getValue("neo4j.password", String.class);
61      String host = ConfigProvider.getConfig().getValue("neo4j.host", String.class);
62      Configuration configuration = new Configuration.Builder()
63        .uri("neo4j://" + host)
64        .credentials(username, password)
65        .verifyConnection(true)
66        .useNativeTypes()
67        .build();
68      while (true) {
69        try {
70          sessionFactory = new SessionFactory(
71            configuration,
72            ApiKey.class.getPackageName(),
73            Collection.class.getPackageName(),
74            CollectionReference.class.getPackageName(),
75            FileContainer.class.getPackageName(),
76            FileReference.class.getPackageName(),
77            LabJournalEntry.class.getPackageName(),
78            Permissions.class.getPackageName(),
79            SemanticAnnotation.class.getPackageName(),
80            SpatialDataContainer.class.getPackageName(),
81            SpatialDataReference.class.getPackageName(),
82            StructuredData.class.getPackageName(),
83            StructuredDataReference.class.getPackageName(),
84            Subscription.class.getPackageName(),
85            TimeseriesTuple.class.getPackageName(),
86            TimeseriesReference.class.getPackageName(),
87            Timeseries.class.getPackageName(),
88            URIReference.class.getPackageName(),
89            User.class.getPackageName(),
90            Version.class.getPackageName()
91          );
92          return true;
93        } catch (ConnectionException ex) {
94          Log.warn("Cannot connect to neo4j database. Retrying...");
95        }
96        try {
97          Thread.sleep(1000);
98        } catch (InterruptedException e) {
99          Log.error("Cannot sleep while waiting for neo4j Connection");
100         Thread.currentThread().interrupt();
101       }
102     }
103   }
104 
105   @Override
106   public boolean disconnect() {
107     if (sessionFactory != null) sessionFactory.close();
108     return true;
109   }
110 
111   @Override
112   public boolean alive() {
113     Result result;
114     try {
115       result = sessionFactory.openSession().query("MATCH (n) RETURN count(*) as count", Collections.emptyMap());
116     } catch (ConnectionException ex) {
117       return false;
118     }
119     return result.iterator().hasNext() && result.iterator().next().containsKey("count");
120   }
121 
122   /**
123    * Returns the internal neo4j session
124    *
125    * @return the internal neo4j session
126    */
127   public Session getNeo4jSession() {
128     if (sessionFactory == null) {
129       return null;
130     }
131     return sessionFactory.openSession();
132   }
133 }