diff --git a/src/main/java/org/wikitolearn/controllers/InitializerController.java b/src/main/java/org/wikitolearn/controllers/InitializerController.java index 6871c3b..85c5037 100644 --- a/src/main/java/org/wikitolearn/controllers/InitializerController.java +++ b/src/main/java/org/wikitolearn/controllers/InitializerController.java @@ -1,87 +1,100 @@ /** * */ package org.wikitolearn.controllers; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.wikitolearn.dao.MetadataDAO; import org.wikitolearn.dao.PageDAO; import org.wikitolearn.dao.RevisionDAO; import org.wikitolearn.dao.UserDAO; +import org.wikitolearn.models.Process; +import org.wikitolearn.utils.enums.ProcessResult; +import org.wikitolearn.utils.enums.ProcessType; import org.wikitolearn.services.PageService; import org.wikitolearn.services.RevisionService; import org.wikitolearn.services.UserService; /** * * @author aletundo, valsdav * */ @RestController public class InitializerController { private static final Logger LOG = LoggerFactory.getLogger(InitializerController.class); @Autowired private PageService pageService; @Autowired private UserService userService; @Autowired private RevisionService revisionService; @Autowired private MetadataDAO metadataDAO; @Autowired private PageDAO pageDao; @Autowired private UserDAO userDao; @Autowired private RevisionDAO revisionDAO; private boolean initializedDB = false; @RequestMapping(value = "/init", method = RequestMethod.GET, produces = "application/json") public boolean initialize(@RequestParam("lang") String lang){ String apiUrl = "https://" + lang + ".wikitolearn.org/api.php"; + //starting a new Process + Process initializeProcess = new Process(ProcessType.INIT); // Initializing the DB schema, only the first time if (! initializedDB){ initializeDbClasses(); initializedDB = true; } CompletableFuture parallelInsertions = CompletableFuture.allOf(pageService.addAllPages(lang, apiUrl), userService.addAllUsers(apiUrl)) .thenCompose(s -> revisionService.addAllRevisions(lang, apiUrl)); try { - return parallelInsertions.get(); + boolean result = parallelInsertions.get(); + //saving the result of the process + if (result){ + initializeProcess.setProcessResult(ProcessResult.DONE); + }else{ + initializeProcess.setProcessResult(ProcessResult.ERROR); + } + metadataDAO.addProcess(initializeProcess); + return result; } catch (InterruptedException | ExecutionException e) { LOG.error("Something went wrong during database initialization. {}", e.getMessage()); return false; } } /** * This methods initializes all the DAO Classes, creating the right types on the DB. * @return void */ private void initializeDbClasses(){ LOG.info("Creating Database classes..."); metadataDAO.createDatabaseClass(); pageDao.createDatabaseClass(); userDao.createDatabaseClass(); revisionDAO.createDatabaseClass(); LOG.info("Completed creation of database classes."); } } diff --git a/src/main/java/org/wikitolearn/dao/MetadataDAO.java b/src/main/java/org/wikitolearn/dao/MetadataDAO.java index a499165..2ee5f46 100644 --- a/src/main/java/org/wikitolearn/dao/MetadataDAO.java +++ b/src/main/java/org/wikitolearn/dao/MetadataDAO.java @@ -1,95 +1,101 @@ package org.wikitolearn.dao; +import com.orientechnologies.orient.core.id.ORecordId; import com.orientechnologies.orient.core.metadata.schema.OClass; import com.orientechnologies.orient.core.metadata.schema.OType; import com.orientechnologies.orient.core.sql.OCommandSQL; import com.sun.org.apache.xpath.internal.operations.Bool; import com.tinkerpop.blueprints.Direction; import com.tinkerpop.blueprints.Edge; import com.tinkerpop.blueprints.Vertex; import com.tinkerpop.blueprints.impls.orient.OrientGraph; import com.tinkerpop.blueprints.impls.orient.OrientGraphNoTx; import com.tinkerpop.blueprints.impls.orient.OrientVertex; import com.tinkerpop.blueprints.impls.orient.OrientVertexType; import org.springframework.stereotype.Repository; import org.wikitolearn.models.Process; import java.util.Date; import java.util.HashMap; +import java.util.Iterator; import java.util.Map; /** * This class represents Metadata nodes in the DB. There is a unique Metadata node, * as a entrypoint, and a chain of Process nodes, saving some useful information at every * process in the rating engine. For example we can save the number of fetched pages or * saved user votes. * Created by valsdav on 21/03/17. */ @Repository public class MetadataDAO extends GenericDAO { - private String metadataNodeID; - /** * This method creates the classes Metadata and Process in the DB. * The Metadata node is the entrypoint for the chain of Processes, via the * edges LastProcess and PreviousProcess */ @Override public void createDatabaseClass() { LOG.info("Creating DB classes for MetadataDAO..."); OrientGraphNoTx graph = connection.getGraphNT(); try{ graph.createVertexType("Metadata",1); OrientVertexType processVertex = graph.createVertexType("Process",1); processVertex.createProperty("timestamp", OType.DATETIME).setMandatory(true); graph.createEdgeType("LastProcess"); graph.createEdgeType("PreviousProcess"); graph.createEdgeType("SubProcess"); //We want also to create the singleton node for Metadata. OrientVertex metadata_main = graph.addVertex("class:Metadata"); - metadataNodeID = (String) metadata_main.getId(); metadata_main.setProperty("creation_date", new Date()); } catch( Exception e ) { LOG.error("Something went wrong during class creation. {}.", e.getMessage()); } finally { graph.shutdown(); } } /** * This method insert a new Process on the top of the chain in the db. * It creates the new link between the Metadata node and the Process. * @param process Process to be inserted * @return */ public void addProcess(Process process){ LOG.info("Inserting process..."); OrientGraph graph = connection.getGraph(); try { //getting last Process - Vertex metadataNode = graph.getVertex(metadataNodeID); - Edge lastProcessEdge = metadataNode.getEdges(Direction.OUT, "LastProcess").iterator().next(); - Vertex lastProcess = lastProcessEdge.getVertex(Direction.OUT); - graph.removeEdge(lastProcessEdge); + Vertex metadataNode = graph.getVerticesOfClass("Metadata").iterator().next(); + Iterator it = metadataNode.getEdges(Direction.OUT, "LastProcess").iterator(); + Edge lastProcessEdge = null; + Vertex lastProcess = null; + if (it.hasNext()) { + lastProcessEdge = it.next(); + lastProcess = lastProcessEdge.getVertex(Direction.OUT); + graph.removeEdge(lastProcessEdge); + } //adding new Process Map props = new HashMap<>(); props.put("timestamp", process.getTimestamp()); props.put("processType", process.getProcessType()); props.put("processResult", process.getProcessResult()); Vertex newProcess = graph.addVertex("class:Process", props); //linking the node - metadataNode.addEdge("class:LastProcess", newProcess); - newProcess.addEdge("class:PreviousProcess", lastProcess); + graph.addEdge("class:LastProcess", metadataNode, newProcess, "LastProcess"); + if (lastProcess != null){ + graph.addEdge("class:PreviousProcess", newProcess, lastProcess, "PreviousProcess"); + } graph.commit(); } catch (Exception e){ LOG.error("Something went wrong during the insertion of the process. {}.", e.getMessage()); graph.rollback(); } finally { graph.shutdown(); } } } diff --git a/src/main/java/org/wikitolearn/models/Process.java b/src/main/java/org/wikitolearn/models/Process.java index 631fbdc..4f9975c 100644 --- a/src/main/java/org/wikitolearn/models/Process.java +++ b/src/main/java/org/wikitolearn/models/Process.java @@ -1,62 +1,57 @@ package org.wikitolearn.models; +import org.wikitolearn.utils.enums.ProcessResult; +import org.wikitolearn.utils.enums.ProcessType; + import java.util.Date; /** * This class represents a Process happened in the engine. * It has a definite type and can have different results. It is saved in the DB * as a Process vertex. * Created by valsdav on 21/03/17. */ public class Process { private Date timestamp; private ProcessType processType; private ProcessResult processResult; public Process() {} public Process(Date timestamp, ProcessType processType, ProcessResult processResult) { this.timestamp = timestamp; this.processType = processType; this.processResult = processResult; } public Process(ProcessType processType){ this.timestamp = new Date(); this.processType = processType; this.processResult = ProcessResult.ONGOING; } public Date getTimestamp() { return timestamp; } public void setTimestamp(Date timestamp) { this.timestamp = timestamp; } public ProcessType getProcessType() { return processType; } public void setProcessType(ProcessType processType) { this.processType = processType; } public ProcessResult getProcessResult() { return processResult; } public void setProcessResult(ProcessResult processResult) { this.processResult = processResult; } } - -enum ProcessType{ - INIT, FETCH, UPDATE_RANKING_PAGES, UPDATE_RANKING_USERS -} - -enum ProcessResult{ - DONE, ERROR, EXCEPTION, ONGOING -} \ No newline at end of file diff --git a/src/main/java/org/wikitolearn/utils/enums/ProcessResult.java b/src/main/java/org/wikitolearn/utils/enums/ProcessResult.java new file mode 100644 index 0000000..a02aa08 --- /dev/null +++ b/src/main/java/org/wikitolearn/utils/enums/ProcessResult.java @@ -0,0 +1,8 @@ +package org.wikitolearn.utils.enums; + +/** + * Created by valsdav on 21/03/17. + */ +public enum ProcessResult { + DONE, ERROR, EXCEPTION, ONGOING; +} diff --git a/src/main/java/org/wikitolearn/utils/enums/ProcessType.java b/src/main/java/org/wikitolearn/utils/enums/ProcessType.java new file mode 100644 index 0000000..94d683f --- /dev/null +++ b/src/main/java/org/wikitolearn/utils/enums/ProcessType.java @@ -0,0 +1,8 @@ +package org.wikitolearn.utils.enums; + +/** + * Created by valsdav on 21/03/17. + */ +public enum ProcessType { + INIT, FETCH, UPDATE_RANKING_PAGES, UPDATE_RANKING_USERS +}