diff --git a/content-api/content-actors/pom.xml b/content-api/content-actors/pom.xml
index 45e1e286a..c0f084a7b 100644
--- a/content-api/content-actors/pom.xml
+++ b/content-api/content-actors/pom.xml
@@ -93,6 +93,19 @@
2.5.22
test
+
+
+ org.sunbird
+ graph-dac
+
+
+ org.apache.commons
+ commons-lang3
+
+
+ 1.0-SNAPSHOT
+ jar
+
diff --git a/content-api/content-actors/src/main/scala/org/sunbird/content/actors/ContentActor.scala b/content-api/content-actors/src/main/scala/org/sunbird/content/actors/ContentActor.scala
index 837810741..8151b7897 100644
--- a/content-api/content-actors/src/main/scala/org/sunbird/content/actors/ContentActor.scala
+++ b/content-api/content-actors/src/main/scala/org/sunbird/content/actors/ContentActor.scala
@@ -15,8 +15,9 @@ import org.sunbird.content.review.mgr.ReviewManager
import org.sunbird.content.upload.mgr.UploadManager
import org.sunbird.content.util._
import org.sunbird.graph.OntologyEngineContext
-import org.sunbird.graph.dac.model.Node
+import org.sunbird.graph.dac.model.{Node, Vertex}
import org.sunbird.graph.nodes.DataNode
+import org.sunbird.graph.vertex.DataVertex
import org.sunbird.graph.utils.NodeUtil
import org.sunbird.managers.HierarchyManager
import org.sunbird.managers.HierarchyManager.hierarchyPrefix
@@ -66,7 +67,7 @@ class ContentActor @Inject() (implicit oec: OntologyEngineContext, ss: StorageSe
def create(request: Request): Future[Response] = {
populateDefaultersForCreation(request)
RequestUtil.restrictProperties(request)
- DataNode.create(request, dataModifier).map(node => {
+ DataVertex.create(request, vertexDataModifier).map(node => {
ResponseHandler.OK.put(ContentConstants.IDENTIFIER, node.getIdentifier).put("node_id", node.getIdentifier)
.put("versionKey", node.getMetadata.get("versionKey"))
})
@@ -296,6 +297,20 @@ class ContentActor @Inject() (implicit oec: OntologyEngineContext, ss: StorageSe
node
}
+ def vertexDataModifier(vertex: Vertex): Vertex = {
+ if (vertex.getMetadata.containsKey("trackable") &&
+ vertex.getMetadata.getOrDefault("trackable", new java.util.HashMap[String, AnyRef]).asInstanceOf[java.util.Map[String, AnyRef]].containsKey("enabled") &&
+ "Yes".equalsIgnoreCase(vertex.getMetadata.getOrDefault("trackable", new java.util.HashMap[String, AnyRef]).asInstanceOf[java.util.Map[String, AnyRef]].getOrDefault("enabled", "").asInstanceOf[String])) {
+ vertex.getMetadata.put("contentType", "Course")
+ }
+
+ //TODO: Below fix to be reviewed when the fix for null to Stringify in ExternalStore.scala is implemented
+ if (vertex.getExternalData != null && vertex.getExternalData.containsKey("relational_metadata") && vertex.getExternalData.get("relational_metadata") == null) {
+ vertex.getExternalData.put("relational_metadata", "{}")
+ }
+ vertex
+ }
+
def getImportConfig(): ImportConfig = {
val requiredProps = Platform.getStringList("import.required_props", java.util.Arrays.asList("name", "code", "mimeType", "contentType", "artifactUrl", "framework")).asScala.toList
val validStages = Platform.getStringList("import.valid_stages", java.util.Arrays.asList("create", "upload", "review", "publish")).asScala.toList
diff --git a/content-api/content-actors/src/main/scala/org/sunbird/content/actors/EventActor.scala b/content-api/content-actors/src/main/scala/org/sunbird/content/actors/EventActor.scala
index a1d672b9b..718ed8b0f 100644
--- a/content-api/content-actors/src/main/scala/org/sunbird/content/actors/EventActor.scala
+++ b/content-api/content-actors/src/main/scala/org/sunbird/content/actors/EventActor.scala
@@ -6,7 +6,7 @@ import org.sunbird.common.dto.{Request, Response, ResponseHandler}
import org.sunbird.common.exception.{ClientException, ResponseCode}
import org.sunbird.content.util.ContentConstants
import org.sunbird.graph.OntologyEngineContext
-import org.sunbird.graph.dac.model.{Node, Relation}
+import org.sunbird.graph.dac.model.{Node, Relation, Vertex}
import org.sunbird.graph.nodes.DataNode
import java.util
@@ -79,4 +79,13 @@ class EventActor @Inject()(implicit oec: OntologyEngineContext, ss: StorageServi
node
}
+ override def vertexDataModifier(vertex: Vertex): Vertex = {
+ if (vertex.getMetadata.containsKey("trackable") &&
+ vertex.getMetadata.getOrDefault("trackable", new java.util.HashMap[String, AnyRef]).asInstanceOf[java.util.Map[String, AnyRef]].containsKey("enabled") &&
+ "Yes".equalsIgnoreCase(vertex.getMetadata.getOrDefault("trackable", new java.util.HashMap[String, AnyRef]).asInstanceOf[java.util.Map[String, AnyRef]].getOrDefault("enabled", "").asInstanceOf[String])) {
+ vertex.getMetadata.put("contentType", "Event")
+ }
+ vertex
+ }
+
}
\ No newline at end of file
diff --git a/ontology-engine/graph-common/src/main/java/org/sunbird/graph/common/enums/GraphDACParams.java b/ontology-engine/graph-common/src/main/java/org/sunbird/graph/common/enums/GraphDACParams.java
index 230c04005..4b853c3cb 100644
--- a/ontology-engine/graph-common/src/main/java/org/sunbird/graph/common/enums/GraphDACParams.java
+++ b/ontology-engine/graph-common/src/main/java/org/sunbird/graph/common/enums/GraphDACParams.java
@@ -8,5 +8,5 @@ public enum GraphDACParams {
MERGE, nodes, RETURN, keys, rootNode, nodeId, WHERE, startNodeId, endNodeId, relationType,
startNodeIds, endNodeIds, collectionId, collection, indexProperty, taskId, input, getTags,
searchCriteria, paramMap, cypherQuery, paramValueMap, queryStatementMap, SYS_INTERNAL_LAST_UPDATED_ON,
- CONSUMER_ID, consumerId, CHANNEL_ID, channel, APP_ID, appId, Nodes_Count, Relations_Count;
+ CONSUMER_ID, consumerId, CHANNEL_ID, channel, APP_ID, appId, Nodes_Count, Relations_Count, vertex;
}
diff --git a/ontology-engine/graph-core_2.12/pom.xml b/ontology-engine/graph-core_2.12/pom.xml
index 729c430e4..2f20c92b4 100644
--- a/ontology-engine/graph-core_2.12/pom.xml
+++ b/ontology-engine/graph-core_2.12/pom.xml
@@ -28,6 +28,18 @@
1.0-SNAPSHOT
jar
+
+ org.sunbird
+ graph-dac
+
+
+ org.apache.commons
+ commons-lang3
+
+
+ 1.0-SNAPSHOT
+ jar
+
org.sunbird
schema-validator
diff --git a/ontology-engine/graph-core_2.12/src/main/scala/org/sunbird/graph/GraphService.scala b/ontology-engine/graph-core_2.12/src/main/scala/org/sunbird/graph/GraphService.scala
index e090a8591..412465d23 100644
--- a/ontology-engine/graph-core_2.12/src/main/scala/org/sunbird/graph/GraphService.scala
+++ b/ontology-engine/graph-core_2.12/src/main/scala/org/sunbird/graph/GraphService.scala
@@ -12,6 +12,7 @@ import java.lang
import scala.concurrent.{ExecutionContext, Future}
class GraphService {
+
implicit val ec: ExecutionContext = ExecutionContext.global
val isrRelativePathEnabled: lang.Boolean = Platform.getBoolean("cloudstorage.metadata.replace_absolute_path", false)
diff --git a/ontology-engine/graph-core_2.12/src/main/scala/org/sunbird/graph/JanusGraphService.scala b/ontology-engine/graph-core_2.12/src/main/scala/org/sunbird/graph/JanusGraphService.scala
new file mode 100644
index 000000000..9f09b1f9f
--- /dev/null
+++ b/ontology-engine/graph-core_2.12/src/main/scala/org/sunbird/graph/JanusGraphService.scala
@@ -0,0 +1,75 @@
+package org.sunbird.graph
+
+import org.sunbird.common.Platform
+import org.sunbird.common.dto.{Property, Request, Response}
+import org.sunbird.graph.dac.model.{Vertex, VertexSubGraph}
+import org.sunbird.graph.util.CSPMetaUtil
+import org.sunbird.janus.service.operation.{EdgeOperations, SearchOperations, VertexOperations}
+
+import java.lang
+import scala.concurrent.{ExecutionContext, Future}
+class JanusGraphService {
+
+ private val VertexOperations = new VertexOperations()
+ private val EdgeOperations = new EdgeOperations()
+ private val SearchOperations = new SearchOperations()
+
+ implicit val ec: ExecutionContext = ExecutionContext.global
+ val isrRelativePathEnabled: lang.Boolean = Platform.getBoolean("cloudstorage.metadata.replace_absolute_path", false)
+
+
+ def addVertex(graphId: String, vertex: Vertex): Future[Vertex] = {
+ if (isrRelativePathEnabled) {
+ val metadata = CSPMetaUtil.updateRelativePath(vertex.getMetadata)
+ vertex.setMetadata(metadata)
+ }
+ VertexOperations.addVertex(graphId, vertex).map(resVertex => if (isrRelativePathEnabled) CSPMetaUtil.updateAbsolutePath(resVertex) else resVertex)
+
+ }
+
+ def createEdges(graphId: String, edgeMap: java.util.List[java.util.Map[String, AnyRef]]): Future[Response] = {
+ EdgeOperations.createEdges(graphId, edgeMap)
+ }
+
+ def removeEdges(graphId: String, edgeMap: java.util.List[java.util.Map[String, AnyRef]]): Future[Response] = {
+ EdgeOperations.removeEdges(graphId, edgeMap)
+ }
+
+ def getNodeByUniqueId(graphId: String, vertexId: String, getTags: Boolean, request: Request): Future[Vertex] = {
+ SearchOperations.getNodeByUniqueId(graphId, vertexId, getTags, request).map(vertex => if (isrRelativePathEnabled) CSPMetaUtil.updateAbsolutePath(vertex) else vertex)
+ }
+
+ def deleteNode(graphId: String, vertexId: String, request: Request): Future[java.lang.Boolean] = {
+ VertexOperations.deleteVertex(graphId, vertexId, request)
+ }
+
+ def upsertVertex(graphId: String, vertex: Vertex, request: Request): Future[Vertex] = {
+ if (isrRelativePathEnabled) {
+ val metadata = CSPMetaUtil.updateRelativePath(vertex.getMetadata)
+ vertex.setMetadata(metadata)
+ }
+ VertexOperations.upsertVertex(graphId, vertex, request)
+ .map(resVertex => if (isrRelativePathEnabled) CSPMetaUtil.updateAbsolutePath(resVertex) else resVertex)
+ }
+
+ def upsertRootNode(graphId: String, request: Request): Future[Vertex] = {
+ VertexOperations.upsertRootVertex(graphId, request)
+ }
+
+ def updateVertexes(graphId: String, identifiers: java.util.List[String], metadata: java.util.Map[String, AnyRef]): Future[java.util.Map[String, Vertex]] = {
+ val updatedMetadata = if (isrRelativePathEnabled) CSPMetaUtil.updateRelativePath(metadata) else metadata
+ VertexOperations.updateVertexes(graphId, identifiers, updatedMetadata)
+ }
+
+ def getNodeProperty(graphId: String, identifier: String, property: String): Future[Property] = {
+ SearchOperations.getNodeProperty(graphId, identifier, property).map(property => if (isrRelativePathEnabled) CSPMetaUtil.updateAbsolutePath(property) else property)
+ }
+
+ def checkCyclicLoop(graphId: String, endNodeId: String, startNodeId: String, relationType: String) = {
+ SearchOperations.checkCyclicLoop(graphId, endNodeId, relationType, startNodeId)
+ }
+
+ def getSubGraph(graphId: String, nodeId: String, depth: Int): Future[VertexSubGraph] = {
+ EdgeOperations.getSubGraph(graphId, nodeId, depth)
+ }
+}
\ No newline at end of file
diff --git a/ontology-engine/graph-core_2.12/src/main/scala/org/sunbird/graph/OntologyEngineContext.scala b/ontology-engine/graph-core_2.12/src/main/scala/org/sunbird/graph/OntologyEngineContext.scala
index 167eff5ad..106410c66 100644
--- a/ontology-engine/graph-core_2.12/src/main/scala/org/sunbird/graph/OntologyEngineContext.scala
+++ b/ontology-engine/graph-core_2.12/src/main/scala/org/sunbird/graph/OntologyEngineContext.scala
@@ -10,11 +10,15 @@ class OntologyEngineContext {
private val dialGraphDB = new DialGraphService
private val hUtil = new HttpUtil
private lazy val kfClient = new KafkaClient
-
+ private lazy val janusGraphDB = new JanusGraphService
def graphService = {
graphDB
}
+ def janusGraphService = {
+ janusGraphDB
+ }
+
def dialgraphService = {
dialGraphDB
}
diff --git a/ontology-engine/graph-core_2.12/src/main/scala/org/sunbird/graph/util/CSPMetaUtil.scala b/ontology-engine/graph-core_2.12/src/main/scala/org/sunbird/graph/util/CSPMetaUtil.scala
index c8c4b51d3..d8771da22 100644
--- a/ontology-engine/graph-core_2.12/src/main/scala/org/sunbird/graph/util/CSPMetaUtil.scala
+++ b/ontology-engine/graph-core_2.12/src/main/scala/org/sunbird/graph/util/CSPMetaUtil.scala
@@ -1,13 +1,12 @@
package org.sunbird.graph.util
import java.util
-
import org.apache.commons.collections4.MapUtils
import org.apache.commons.lang3.StringUtils
import org.slf4j.LoggerFactory
import org.sunbird.common.dto.Property
import org.sunbird.common.{JsonUtils, Platform}
-import org.sunbird.graph.dac.model.Node
+import org.sunbird.graph.dac.model.{Node, Vertex}
import scala.collection.JavaConverters._
import scala.collection.immutable.Map
@@ -43,6 +42,12 @@ object CSPMetaUtil {
node
}
+ def updateAbsolutePath(vertex: Vertex): Vertex = {
+ val metadata = updateAbsolutePath(vertex.getMetadata)
+ vertex.setMetadata(metadata)
+ vertex
+ }
+
def updateAbsolutePath(nodes: java.util.List[Node]): java.util.List[Node] = {
nodes.asScala.toList.map(node => {
updateAbsolutePath(node)
diff --git a/ontology-engine/graph-dac-api/pom.xml b/ontology-engine/graph-dac-api/pom.xml
index 0c51b8f68..2bb1e628a 100644
--- a/ontology-engine/graph-dac-api/pom.xml
+++ b/ontology-engine/graph-dac-api/pom.xml
@@ -86,6 +86,21 @@
1.17.6
test
+
+ org.apache.tinkerpop
+ gremlin-driver
+ 3.7.2
+
+
+ org.janusgraph
+ janusgraph-core
+ 1.0.0
+
+
+ org.janusgraph
+ janusgraph-inmemory
+ 1.0.0
+
diff --git a/ontology-engine/graph-dac-api/src/main/java/org/sunbird/graph/dac/model/Edges.java b/ontology-engine/graph-dac-api/src/main/java/org/sunbird/graph/dac/model/Edges.java
new file mode 100644
index 000000000..e2aabd6ce
--- /dev/null
+++ b/ontology-engine/graph-dac-api/src/main/java/org/sunbird/graph/dac/model/Edges.java
@@ -0,0 +1,288 @@
+package org.sunbird.graph.dac.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.apache.commons.collections4.MapUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.sunbird.common.exception.ServerException;
+import org.sunbird.graph.common.enums.SystemProperties;
+import org.sunbird.graph.dac.enums.GraphDACErrorCodes;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class Edges implements Serializable {
+
+ private static final long serialVersionUID = -7207054262120122453L;
+ private Object id;
+ private String graphId;
+ private String edgeType;
+ private String startVertexId;
+ private String endVertexId;
+ private String startVertexName;
+ private String endVertexName;
+ private String startVertexType;
+ private String endVertexType;
+ private String startVertexObjectType;
+ private String endVertexObjectType;
+ private Map metadata;
+ private Map startVertexMetadata;
+ private Map endVertexMetadata;
+
+ public Edges() {
+
+ }
+
+ public Edges(String startVertexId, String edgeType, String endVertexId) {
+ this.startVertexId = startVertexId;
+ this.endVertexId = endVertexId;
+ this.edgeType = edgeType;
+ }
+
+ public Edges(String graphId, Edge edge) {
+ if (null == edge)
+ throw new ServerException(GraphDACErrorCodes.ERR_GRAPH_NULL_DB_REL.name(),
+ "Failed to create relation object. Relation from database is null.");
+ this.graphId = graphId;
+
+ Vertex startVertex = edge.inVertex();
+ Vertex endVertex = edge.outVertex();
+ this.startVertexId = (String) startVertex.property(SystemProperties.IL_UNIQUE_ID.name()).value();
+ this.endVertexId = (String) endVertex.property(SystemProperties.IL_UNIQUE_ID.name()).value();
+ this.startVertexName = getName(startVertex);
+ this.endVertexName = getName(endVertex);
+ this.startVertexType = getVertexType(startVertex);
+ this.endVertexType = getVertexType(endVertex);
+ this.startVertexObjectType = getObjectType(startVertex);
+ this.endVertexObjectType = getObjectType(endVertex);
+ this.edgeType = edge.label();
+ this.metadata = new HashMap();
+ this.startVertexMetadata = getNodeMetadata(edge.outVertex());
+ this.endVertexMetadata = getNodeMetadata(edge.inVertex());
+ edge.keys().forEach(key -> this.metadata.put(key, edge.value(key)));
+ }
+
+ public Edges(String graphId, Edge edge, Map