package nl.knaw.huygens.alexandria.service; import java.io.File; import javax.inject.Inject; import javax.inject.Singleton; import org.apache.tinkerpop.gremlin.neo4j.structure.Neo4jGraph; import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; import nl.knaw.huygens.alexandria.config.AlexandriaConfiguration; import nl.knaw.huygens.alexandria.endpoint.LocationBuilder; import nl.knaw.huygens.alexandria.storage.Storage; import nl.knaw.huygens.alexandria.storage.VertexLabels; /* * #%L * alexandria-service-tinkerpop-neo4j * ======= * Copyright (C) 2015 - 2017 Huygens ING (KNAW) * ======= * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ @Singleton public class Neo4JService extends TinkerPopService { private static Neo4jGraph graph; @Inject public Neo4JService(AlexandriaConfiguration config, LocationBuilder locationBuilder) { super(getStorage(config), locationBuilder); } private static Storage getStorage(AlexandriaConfiguration config) { String dataDir = config.getStorageDirectory() + "/neo4jdb"; createWhenAbsent(dataDir); try { graph = Neo4jGraph.open(dataDir); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("There was an error starting up the Neo4J graph; If this was caused by an interrupted indexing job, restarting the server might help."); } setIndexes(); return new Storage(graph); } private static void setIndexes() { System.out.print("updating 7 indexes: ."); setUniqueIndex("Resource", Storage.IDENTIFIER_PROPERTY); System.out.print("."); setUniqueIndex("Annotation", Storage.IDENTIFIER_PROPERTY); System.out.print("."); setUniqueIndex("AnnotationBody", Storage.IDENTIFIER_PROPERTY); System.out.print("."); setUniqueIndex(VertexLabels.TEXTRANGEANNOTATION, Storage.IDENTIFIER_PROPERTY); System.out.print("."); runCypher("create index on :Resource(cargo)"); System.out.print("."); runCypher("create index on :Annotation(who)"); System.out.print("."); runCypher("create index on :AnnotationBody(type)"); graph.tx().commit(); System.out.println(" indexing started!"); System.out.println("It might take a while to finish, but you can use the server right away."); } private static void setUniqueIndex(String label, String property) { runCypher("create constraint on (r:" + label + ") assert r." + property + " is unique"); runCypher("create index on :" + label + "(state)"); } private static void runCypher(String cypher) { GraphTraversal<Object, Object> traversal = graph.cypher(cypher); if (traversal.hasNext()) { Object next = traversal.next(); // Log.info("next={}", next); } } private static void createWhenAbsent(String dataDir) { File file = new File(dataDir); if (!file.isDirectory()) { file.mkdirs(); } } }