2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
20 package org.openecomp.sdc.be.dao.janusgraph;
22 import fj.data.Either;
23 import java.util.ArrayList;
24 import java.util.HashMap;
25 import java.util.Iterator;
26 import java.util.List;
28 import java.util.Map.Entry;
29 import java.util.function.Predicate;
30 import java.util.stream.Collectors;
31 import java.util.stream.StreamSupport;
32 import javax.validation.constraints.NotNull;
33 import org.apache.commons.collections.CollectionUtils;
34 import org.apache.commons.lang.StringUtils;
35 import org.apache.commons.lang3.tuple.ImmutablePair;
36 import org.apache.commons.lang3.tuple.ImmutableTriple;
37 import org.apache.tinkerpop.gremlin.structure.Direction;
38 import org.apache.tinkerpop.gremlin.structure.Edge;
39 import org.apache.tinkerpop.gremlin.structure.Element;
40 import org.apache.tinkerpop.gremlin.structure.Property;
41 import org.apache.tinkerpop.gremlin.structure.Vertex;
42 import org.apache.tinkerpop.gremlin.structure.util.ElementHelper;
43 import org.janusgraph.core.JanusGraph;
44 import org.janusgraph.core.JanusGraphEdge;
45 import org.janusgraph.core.JanusGraphQuery;
46 import org.janusgraph.core.JanusGraphTransaction;
47 import org.janusgraph.core.JanusGraphVertex;
48 import org.janusgraph.core.JanusGraphVertexQuery;
49 import org.janusgraph.core.PropertyKey;
50 import org.janusgraph.graphdb.query.JanusGraphPredicate;
51 import org.openecomp.sdc.be.config.ConfigurationManager;
52 import org.openecomp.sdc.be.dao.api.exception.JanusGraphException;
53 import org.openecomp.sdc.be.dao.graph.GraphElementFactory;
54 import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
55 import org.openecomp.sdc.be.dao.graph.datatype.GraphElementTypeEnum;
56 import org.openecomp.sdc.be.dao.graph.datatype.GraphNode;
57 import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
58 import org.openecomp.sdc.be.dao.graph.datatype.RelationEndPoint;
59 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
60 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
61 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
62 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
63 import org.openecomp.sdc.be.resources.data.GraphNodeLock;
64 import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
65 import org.openecomp.sdc.common.log.wrappers.Logger;
66 import org.springframework.beans.factory.annotation.Qualifier;
68 public class JanusGraphGenericDao {
70 private static final String LOCK_NODE_PREFIX = "lock_";
71 private static Logger log = Logger.getLogger(JanusGraphGenericDao.class.getName());
72 private JanusGraphClient janusGraphClient;
74 public JanusGraphGenericDao(@Qualifier("janusgraph-client") JanusGraphClient janusGraphClient) {
75 this.janusGraphClient = janusGraphClient;
76 log.info("** JanusGraphGenericDao created");
79 public JanusGraphOperationStatus commit() {
80 log.debug("doing commit.");
81 return janusGraphClient.commit();
84 public JanusGraphOperationStatus rollback() {
85 log.error("Going to execute rollback on graph.");
86 return janusGraphClient.rollback();
89 public <T, TStatus> void handleTransactionCommitRollback(boolean inTransaction, Either<T, TStatus> result) {
91 if (result == null || result.isRight()) {
99 public Either<JanusGraph, JanusGraphOperationStatus> getGraph() {
100 return janusGraphClient.getGraph();
104 public boolean isGraphOpen() {
105 return janusGraphClient.getHealth();
113 public <T extends GraphNode> Either<T, JanusGraphOperationStatus> createNode(final T node, final Class<T> clazz) {
114 log.debug("try to create node for ID [{}]", node.getKeyValueIdForLog());
115 final Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
116 if (graph.isLeft()) {
119 if (node instanceof GraphNodeLock) {
120 final Either<T, JanusGraphOperationStatus> nodeOriginal = getNode(GraphPropertiesDictionary.UNIQUE_ID.getProperty(),
121 node.getUniqueId(), clazz);
122 if (nodeOriginal.isLeft()) {
123 final Long lockTimeout = ConfigurationManager.getConfigurationManager().getConfiguration().getJanusGraphLockTimeout();
124 if (System.currentTimeMillis() - ((GraphNodeLock) nodeOriginal.left().value()).getTime() > lockTimeout * 1000L) {
125 deleteNode(node, clazz);
128 final JanusGraphTransaction tGraph = graph.left().value().tx().createThreadedTx();
129 final Vertex vertex = tGraph.addVertex();
130 vertex.property(GraphPropertiesDictionary.LABEL.getProperty(), node.getLabel());
131 final Map<String, Object> properties = node.toGraphMap();
132 if (properties != null) {
133 setProperties(vertex, properties);
135 final Map<String, Object> newProps = getProperties(vertex);
136 newNode = GraphElementFactory.createElement(node.getLabel(), GraphElementTypeEnum.Node, newProps, clazz);
137 log.debug("created node for props : {}", newProps);
138 log.debug("Node was created for ID [{}]", node.getKeyValueIdForLog());
141 return Either.left(newNode);
143 final JanusGraph tGraph = graph.left().value();
144 final Vertex vertex = tGraph.addVertex();
145 vertex.property(GraphPropertiesDictionary.LABEL.getProperty(), node.getLabel());
146 final Map<String, Object> properties = node.toGraphMap();
147 if (properties != null) {
148 setProperties(vertex, properties);
150 final Map<String, Object> newProps = getProperties(vertex);
151 newNode = GraphElementFactory.createElement(node.getLabel(), GraphElementTypeEnum.Node, newProps, clazz);
152 log.debug("created node for props : {}", newProps);
153 log.debug("Node was created for ID [{}]", node.getKeyValueIdForLog());
155 return Either.left(newNode);
157 } catch (Exception e) {
158 log.debug("Failed to create Node for ID [{}]", node.getKeyValueId(), e);
159 return Either.right(JanusGraphClient.handleJanusGraphException(e));
162 log.debug("Failed to create Node for ID [{}] {}", node.getKeyValueIdForLog(), graph.right().value());
163 return Either.right(graph.right().value());
167 public Either<JanusGraphVertex, JanusGraphOperationStatus> createNode(GraphNode node) {
168 log.debug("try to create node for ID [{}]", node.getKeyValueId());
169 Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
170 if (graph.isLeft()) {
172 JanusGraph tGraph = graph.left().value();
173 JanusGraphVertex vertex = tGraph.addVertex();
174 vertex.property(GraphPropertiesDictionary.LABEL.getProperty(), node.getLabel());
175 Map<String, Object> properties = node.toGraphMap();
176 if (properties != null) {
177 setProperties(vertex, properties);
179 log.debug("Node was created for ID [{}]", node.getKeyValueId());
180 return Either.left(vertex);
181 } catch (Exception e) {
182 log.debug("Failed to create Node for ID [{}]", node.getKeyValueId(), e);
183 return Either.right(JanusGraphClient.handleJanusGraphException(e));
186 log.debug("Failed to create Node for ID [{}] {}", node.getKeyValueId(), graph.right().value());
187 return Either.right(graph.right().value());
195 public Either<GraphRelation, JanusGraphOperationStatus> createRelation(GraphRelation relation) {
196 log.debug("try to create relation from [{}] to [{}] ", relation.getFrom(), relation.getTo());
197 RelationEndPoint from = relation.getFrom();
198 RelationEndPoint to = relation.getTo();
199 ImmutablePair<String, Object> fromKeyId = new ImmutablePair<>(from.getIdName(), from.getIdValue());
200 ImmutablePair<String, Object> toKeyId = new ImmutablePair<>(to.getIdName(), to.getIdValue());
201 return createEdge(relation.getType(), fromKeyId, toKeyId, from.getLabel().getName(), to.getLabel().getName(), relation.toGraphMap());
204 private Either<GraphRelation, JanusGraphOperationStatus> createEdge(String type, ImmutablePair<String, Object> from,
205 ImmutablePair<String, Object> to, String fromLabel, String toLabel,
206 Map<String, Object> properties) {
207 Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
208 if (graph.isLeft()) {
210 Either<Vertex, JanusGraphOperationStatus> fromV = getVertexByPropertyAndLabel(from.getKey(), from.getValue(), fromLabel);
211 if (fromV.isRight()) {
212 JanusGraphOperationStatus error = fromV.right().value();
213 if (JanusGraphOperationStatus.NOT_FOUND.equals(error)) {
214 return Either.right(JanusGraphOperationStatus.INVALID_ID);
216 return Either.right(error);
219 Either<Vertex, JanusGraphOperationStatus> toV = getVertexByPropertyAndLabel(to.getKey(), to.getValue(), toLabel);
221 JanusGraphOperationStatus error = toV.right().value();
222 if (JanusGraphOperationStatus.NOT_FOUND.equals(error)) {
223 return Either.right(JanusGraphOperationStatus.INVALID_ID);
225 return Either.right(error);
228 Vertex fromVertex = fromV.left().value();
229 Vertex toVertex = toV.left().value();
230 Edge edge = fromVertex.addEdge(type, toVertex);
231 if (properties != null) {
232 setProperties(edge, properties);
234 Vertex vertexOut = edge.outVertex();
235 Vertex vertexIn = edge.inVertex();
236 GraphNode nodeOut = GraphElementFactory
237 .createElement(fromLabel, GraphElementTypeEnum.Node, getProperties(vertexOut), GraphNode.class);
238 GraphNode nodeIn = GraphElementFactory.createElement(toLabel, GraphElementTypeEnum.Node, getProperties(vertexIn), GraphNode.class);
239 GraphRelation newRelation = GraphElementFactory.createRelation(edge.label(), getProperties(edge), nodeOut, nodeIn);
240 return Either.left(newRelation);
241 } catch (Exception e) {
242 log.debug("Failed to create edge from [{}] to [{}]", from, to, e);
243 return Either.right(janusGraphClient.handleJanusGraphException(e));
246 log.debug("Failed to create edge from [{}] to [{}] {}", from, to, graph.right().value());
247 return Either.right(graph.right().value());
251 public JanusGraphOperationStatus createEdge(Vertex vertexOut, Vertex vertexIn, GraphEdgeLabels type, Map<String, Object> properties) {
253 Edge edge = addEdge(vertexOut, vertexIn, type, properties);
254 } catch (Exception e) {
255 log.debug("Failed to create edge from [{}] to [{}]", vertexOut, vertexIn, e);
256 return janusGraphClient.handleJanusGraphException(e);
258 return JanusGraphOperationStatus.OK;
261 private Edge addEdge(Vertex vertexOut, Vertex vertexIn, GraphEdgeLabels type, Map<String, Object> properties) {
262 Edge edge = vertexOut.addEdge(type.getProperty(), vertexIn);
263 if (properties != null) {
264 setProperties(edge, properties);
270 * creates an identical edge in the graph
273 * @return the copy operation status
275 public Either<Edge, JanusGraphOperationStatus> copyEdge(Vertex out, Vertex in, Edge edge) {
276 GraphEdgeLabels byName = GraphEdgeLabels.getByName(edge.label());
277 return this.saveEdge(out, in, byName, edgePropertiesToMap(edge));
280 private <V> Map<String, Object> edgePropertiesToMap(Edge edge) {
281 Iterable<Property<Object>> propertiesIterable = edge::properties;
282 return StreamSupport.stream(propertiesIterable.spliterator(), false).collect(Collectors.toMap(Property::key, Property::value));
285 public Either<Edge, JanusGraphOperationStatus> saveEdge(Vertex vertexOut, Vertex vertexIn, GraphEdgeLabels type, Map<String, Object> properties) {
287 Edge edge = addEdge(vertexOut, vertexIn, type, properties);
288 return Either.left(edge);
289 } catch (Exception e) {
290 log.debug("Failed to create edge from [{}] to [{}]", vertexOut, vertexIn, e);
291 return Either.right(janusGraphClient.handleJanusGraphException(e));
295 public JanusGraphOperationStatus createEdge(JanusGraphVertex vertexOut, GraphNode to, GraphEdgeLabels type, Map<String, Object> properties) {
296 JanusGraphVertex vertexIn;
297 Either<Vertex, JanusGraphOperationStatus> toV = getVertexByPropertyAndLabel(to.getUniqueIdKey(), to.getUniqueId(), to.getLabel());
299 JanusGraphOperationStatus error = toV.right().value();
300 if (JanusGraphOperationStatus.NOT_FOUND.equals(error)) {
301 return JanusGraphOperationStatus.INVALID_ID;
306 vertexIn = (JanusGraphVertex) toV.left().value();
307 return createEdge(vertexOut, vertexIn, type, properties);
317 public Either<GraphRelation, JanusGraphOperationStatus> createRelation(GraphNode from, GraphNode to, GraphEdgeLabels label,
318 Map<String, Object> properties) {
319 log.debug("try to create relation from [{}] to [{}]", from.getKeyValueId(), to.getKeyValueId());
320 return createEdge(label.getProperty(), from.getKeyValueId(), to.getKeyValueId(), from.getLabel(), to.getLabel(), properties);
323 public Either<GraphRelation, JanusGraphOperationStatus> replaceRelationLabel(GraphNode from, GraphNode to, GraphEdgeLabels label,
324 GraphEdgeLabels newLabel) {
325 log.debug("try to replace relation {} to {} from [{}] to [{}]", label.name(), newLabel.name(), from.getKeyValueId(), to.getKeyValueId());
326 Either<GraphRelation, JanusGraphOperationStatus> getRelationResult = getRelation(from, to, label);
327 if (getRelationResult.isRight()) {
328 return getRelationResult;
330 GraphRelation origRelation = getRelationResult.left().value();
331 Either<GraphRelation, JanusGraphOperationStatus> createRelationResult = createRelation(from, to, newLabel, origRelation.toGraphMap());
332 if (createRelationResult.isRight()) {
333 return createRelationResult;
335 Either<GraphRelation, JanusGraphOperationStatus> deleteRelationResult = deleteRelation(origRelation);
336 if (deleteRelationResult.isRight()) {
337 return deleteRelationResult;
339 return Either.left(createRelationResult.left().value());
348 public <T extends GraphNode> Either<T, JanusGraphOperationStatus> getNode(String keyName, Object keyValue, Class<T> clazz) {
349 log.debug("Try to get node for key [{}] with value [{}] ", keyName, keyValue);
350 Either<JanusGraphVertex, JanusGraphOperationStatus> vertexByProperty;
351 if (clazz != null && clazz.isAssignableFrom(GraphNodeLock.class)) {
352 final Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
353 if (graph.isRight()) {
354 return Either.right(graph.right().value());
356 vertexByProperty = getVertexByPropertyFromGraph(graph.left().value().tx().createThreadedTx(), keyName, keyValue);
358 vertexByProperty = getVertexByProperty(keyName, keyValue);
360 if (vertexByProperty.isLeft()) {
362 Vertex vertex = vertexByProperty.left().value();
363 Map<String, Object> properties = getProperties(vertex);
364 T node = GraphElementFactory
365 .createElement((String) properties.get(GraphPropertiesDictionary.LABEL.getProperty()), GraphElementTypeEnum.Node, properties,
367 return Either.left(node);
368 } catch (Exception e) {
369 log.debug("Failed to get node for key [{}] with value [{}] ", keyName, keyValue, e);
370 return Either.right(JanusGraphClient.handleJanusGraphException(e));
373 log.debug("Failed to get node for key [{}] with value [{}] ", keyName, keyValue, vertexByProperty.right().value());
374 return Either.right(vertexByProperty.right().value());
378 public <T extends GraphNode> Either<T, JanusGraphOperationStatus> getNode(final String keyName, final Object keyValue, final Class<T> clazz,
379 final String model) {
380 log.debug("Try to get node for key [{}] with value [{}] ", keyName, keyValue);
381 final Either<JanusGraphVertex, JanusGraphOperationStatus> vertexByProperty = getVertexByPropertyForModel(keyName, keyValue, model);
382 if (vertexByProperty.isLeft()) {
384 final Vertex vertex = vertexByProperty.left().value();
385 final Map<String, Object> properties = getProperties(vertex);
386 final T node = GraphElementFactory
387 .createElement((String) properties.get(GraphPropertiesDictionary.LABEL.getProperty()), GraphElementTypeEnum.Node, properties,
389 return Either.left(node);
390 } catch (final Exception e) {
391 log.debug("Failed to get node for key [{}] with value [{}] ", keyName, keyValue, e);
392 return Either.right(JanusGraphClient.handleJanusGraphException(e));
395 log.debug("Failed to get node for key [{}] with value [{}] ", keyName, keyValue, vertexByProperty.right().value());
396 return Either.right(vertexByProperty.right().value());
406 public Either<GraphRelation, JanusGraphOperationStatus> getRelation(GraphNode from, GraphNode to, GraphEdgeLabels label) {
407 log.debug("try to get relation from [{}] to [{}]", from.getKeyValueId(), to.getKeyValueId());
408 Either<Edge, JanusGraphOperationStatus> edge = getEdgeByNodes(from, to, label);
411 Map<String, Object> properties = getProperties(edge.left().value());
412 GraphRelation relation = GraphElementFactory.createRelation(label.getProperty(), properties, from, to);
413 return Either.left(relation);
414 } catch (Exception e) {
415 log.debug("Failed to get get relation from [{}] to [{}]", from.getKeyValueId(), to.getKeyValueId(), e);
416 return Either.right(JanusGraphClient.handleJanusGraphException(e));
419 log.debug("Failed to get get relation from [{}] to [{}] {}", from.getKeyValueId(), to.getKeyValueId(), edge.right().value());
420 return Either.right(edge.right().value());
424 public Either<Edge, JanusGraphOperationStatus> getEdgeByNodes(GraphNode from, GraphNode to, GraphEdgeLabels label) {
425 ImmutablePair<String, Object> keyValueIdFrom = from.getKeyValueId();
426 ImmutablePair<String, Object> keyValueIdTo = to.getKeyValueId();
427 return getEdgeByVerticies(keyValueIdFrom.getKey(), keyValueIdFrom.getValue(), keyValueIdTo.getKey(), keyValueIdTo.getValue(),
428 label.getProperty());
431 public Either<GraphRelation, JanusGraphOperationStatus> deleteIncomingRelationByCriteria(GraphNode to, GraphEdgeLabels label,
432 Map<String, Object> props) {
433 Either<Edge, JanusGraphOperationStatus> edgeByCriteria = getIncomingEdgeByCriteria(to, label, props);
434 if (edgeByCriteria.isLeft()) {
435 Either<JanusGraph, JanusGraphOperationStatus> graph = getGraph();
436 if (graph.isLeft()) {
437 Edge edge = edgeByCriteria.left().value();
438 log.debug("delete edge {} to {} ", label.getProperty(), to.getUniqueId());
440 Map<String, Object> properties = getProperties(edge);
441 Vertex fromVertex = edge.outVertex();
442 String fromLabel = fromVertex.value(GraphPropertiesDictionary.LABEL.getProperty());
443 GraphNode nodeFrom = GraphElementFactory
444 .createElement(fromLabel, GraphElementTypeEnum.Node, getProperties(fromVertex), GraphNode.class);
445 GraphRelation relation = GraphElementFactory.createRelation(label.getProperty(), properties, nodeFrom, to);
446 return Either.left(relation);
448 log.debug("failed to get graph");
449 return Either.right(graph.right().value());
452 log.debug("failed to find edge {} to {}", label.getProperty(), to.getUniqueId());
453 return Either.right(edgeByCriteria.right().value());
457 public Either<GraphRelation, JanusGraphOperationStatus> getIncomingRelationByCriteria(GraphNode to, GraphEdgeLabels label,
458 Map<String, Object> props) {
459 Either<Edge, JanusGraphOperationStatus> edgeByCriteria = getIncomingEdgeByCriteria(to, label, props);
460 if (edgeByCriteria.isLeft()) {
461 Either<JanusGraph, JanusGraphOperationStatus> graph = getGraph();
462 if (graph.isLeft()) {
463 Edge edge = edgeByCriteria.left().value();
464 Map<String, Object> properties = getProperties(edge);
465 Vertex fromVertex = edge.outVertex();
466 String fromLabel = fromVertex.value(GraphPropertiesDictionary.LABEL.getProperty());
467 GraphNode nodeFrom = GraphElementFactory
468 .createElement(fromLabel, GraphElementTypeEnum.Node, getProperties(fromVertex), GraphNode.class);
469 GraphRelation relation = GraphElementFactory.createRelation(label.getProperty(), properties, nodeFrom, to);
470 return Either.left(relation);
472 log.debug("failed to get graph");
473 return Either.right(graph.right().value());
476 log.debug("failed to find edge {} to {}", label.getProperty(), to.getUniqueId());
477 return Either.right(edgeByCriteria.right().value());
481 public Either<Edge, JanusGraphOperationStatus> getIncomingEdgeByCriteria(GraphNode to, GraphEdgeLabels label, Map<String, Object> props) {
482 ImmutablePair<String, Object> keyValueIdTo = to.getKeyValueId();
483 Either<JanusGraphVertex, JanusGraphOperationStatus> vertexFrom = getVertexByProperty(keyValueIdTo.getKey(), keyValueIdTo.getValue());
484 if (vertexFrom.isRight()) {
485 return Either.right(vertexFrom.right().value());
487 Vertex vertex = vertexFrom.left().value();
488 JanusGraphVertex janusGraphVertex = (JanusGraphVertex) vertex;
489 JanusGraphVertexQuery<?> query = janusGraphVertex.query();
490 query = query.labels(label.getProperty());
491 if (props != null && !props.isEmpty()) {
492 for (Map.Entry<String, Object> entry : props.entrySet()) {
493 query = query.has(entry.getKey(), entry.getValue());
496 Edge matchingEdge = null;
497 Iterable<JanusGraphEdge> edges = query.edges();
499 log.debug("No edges in graph for criteria");
500 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
502 Iterator<JanusGraphEdge> eIter = edges.iterator();
503 if (eIter.hasNext()) {
504 matchingEdge = eIter.next();
506 if (matchingEdge == null) {
507 log.debug("No edges in graph for criteria");
508 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
510 return Either.left(matchingEdge);
513 public Either<Edge, JanusGraphOperationStatus> getEdgeByVerticies(String keyNameFrom, Object keyValueFrom, String keyNameTo, Object keyValueTo,
515 Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
516 if (graph.isLeft()) {
518 Either<JanusGraphVertex, JanusGraphOperationStatus> vertexFrom = getVertexByProperty(keyNameFrom, keyValueFrom);
519 if (vertexFrom.isRight()) {
520 return Either.right(vertexFrom.right().value());
522 Iterable<JanusGraphEdge> edges = ((JanusGraphVertex) vertexFrom.left().value()).query().labels(label).edges();
523 Iterator<JanusGraphEdge> eIter = edges.iterator();
524 while (eIter.hasNext()) {
525 Edge edge = eIter.next();
526 Vertex vertexIn = edge.inVertex();
527 if (vertexIn.value(keyNameTo) != null && vertexIn.value(keyNameTo).equals(keyValueTo) && label.equals(edge.label())) {
528 return Either.left(edge);
531 log.debug("No relation in graph from [{}={}] to [{}={}]", keyNameFrom, keyValueFrom, keyNameTo, keyValueTo);
532 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
533 } catch (Exception e) {
534 log.debug("Failed to get get relation from [{}={}] to [{}={}]", keyNameFrom, keyValueFrom, keyNameTo, keyValueTo, e);
535 return Either.right(JanusGraphClient.handleJanusGraphException(e));
538 return Either.right(graph.right().value());
542 public Either<List<Edge>, JanusGraphOperationStatus> getEdgesForNode(GraphNode node, Direction requestedDirection) {
543 Either<List<Edge>, JanusGraphOperationStatus> result;
544 ImmutablePair<String, Object> keyValueId = node.getKeyValueId();
545 Either<JanusGraphVertex, JanusGraphOperationStatus> eitherVertex = getVertexByProperty(keyValueId.getKey(), keyValueId.getValue());
546 if (eitherVertex.isLeft()) {
547 List<Edge> edges = prepareEdgesList(eitherVertex.left().value(), requestedDirection);
548 result = Either.left(edges);
550 result = Either.right(eitherVertex.right().value());
555 private List<Edge> prepareEdgesList(Vertex vertex, Direction requestedDirection) {
556 List<Edge> edges = new ArrayList<>();
557 Iterator<JanusGraphEdge> edgesItr = ((JanusGraphVertex) vertex).query().edges().iterator();
558 while (edgesItr.hasNext()) {
559 Edge edge = edgesItr.next();
560 Direction currEdgeDirection = getEdgeDirection(vertex, edge);
561 if (currEdgeDirection == requestedDirection || requestedDirection == Direction.BOTH) {
568 private Direction getEdgeDirection(Vertex vertex, Edge edge) {
570 Vertex vertexOut = edge.outVertex();
571 if (vertexOut.equals(vertex)) {
572 result = Direction.OUT;
574 result = Direction.IN;
586 public Either<GraphRelation, JanusGraphOperationStatus> updateRelation(GraphNode from, GraphNode to, GraphEdgeLabels label,
587 Map<String, Object> properties) {
588 log.debug("try to update relation from [{}] to [{}]", from.getKeyValueId(), to.getKeyValueId());
589 return updateEdge(label.getProperty(), from.getKeyValueId(), to.getKeyValueId(), from.getLabel(), to.getLabel(), properties);
592 private Either<GraphRelation, JanusGraphOperationStatus> updateEdge(String type, ImmutablePair<String, Object> from,
593 ImmutablePair<String, Object> to, String fromLabel, String toLabel,
594 Map<String, Object> properties) {
595 Either<Edge, JanusGraphOperationStatus> edgeS = getEdgeByVerticies(from.getKey(), from.getValue(), to.getKey(), to.getValue(), type);
596 if (edgeS.isLeft()) {
598 Edge edge = edgeS.left().value();
599 if (properties != null) {
600 setProperties(edge, properties);
602 Vertex vertexOut = edge.outVertex();
603 Vertex vertexIn = edge.inVertex();
604 GraphNode nodeOut = GraphElementFactory
605 .createElement(fromLabel, GraphElementTypeEnum.Node, getProperties(vertexOut), GraphNode.class);
606 GraphNode nodeIn = GraphElementFactory.createElement(toLabel, GraphElementTypeEnum.Node, getProperties(vertexIn), GraphNode.class);
607 GraphRelation newRelation = GraphElementFactory.createRelation(edge.label(), getProperties(edge), nodeOut, nodeIn);
608 log.debug("Relation was updated from [{}] to [{}] ", from, to);
609 return Either.left(newRelation);
610 } catch (Exception e) {
611 log.debug("Failed to update relation from [{}] to [{}] ", from, to, e);
612 return Either.right(JanusGraphClient.handleJanusGraphException(e));
615 log.debug("Failed to update relation from [{}] to [{}] {}", from, to, edgeS.right().value());
616 return Either.right(edgeS.right().value());
624 public Either<GraphRelation, JanusGraphOperationStatus> updateRelation(GraphRelation relation) {
625 log.debug("try to update relation from [{}] to [{}]", relation.getFrom(), relation.getTo());
626 RelationEndPoint from = relation.getFrom();
627 RelationEndPoint to = relation.getTo();
628 ImmutablePair<String, Object> fromKeyId = new ImmutablePair<>(from.getIdName(), from.getIdValue());
629 ImmutablePair<String, Object> toKeyId = new ImmutablePair<>(to.getIdName(), to.getIdValue());
630 return updateEdge(relation.getType(), fromKeyId, toKeyId, from.getLabel().getName(), to.getLabel().getName(), relation.toGraphMap());
633 private Either<Vertex, JanusGraphOperationStatus> getVertexByPropertyAndLabel(String name, Object value, String label) {
634 Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
635 if (graph.isLeft()) {
637 JanusGraph tGraph = graph.left().value();
638 @SuppressWarnings("unchecked") Iterable<JanusGraphVertex> vertecies = tGraph.query().has(name, value)
639 .has(GraphPropertiesDictionary.LABEL.getProperty(), label).vertices();
640 java.util.Iterator<JanusGraphVertex> iterator = vertecies.iterator();
641 if (iterator.hasNext()) {
642 Vertex vertex = iterator.next();
643 return Either.left(vertex);
645 log.debug("No vertex in graph for key =" + name + " and value = " + value + " label = " + label);
646 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
647 } catch (Exception e) {
648 log.debug("Failed to get vertex in graph for key ={} and value = {} label = {}", name, value, label);
649 return Either.right(JanusGraphClient.handleJanusGraphException(e));
652 log.debug("No vertex in graph for key ={} and value = {} label = {} error : {}", name, value, label, graph.right().value());
653 return Either.right(graph.right().value());
657 public Either<JanusGraphVertex, JanusGraphOperationStatus> getVertexByPropertyForModel(final String name, final Object value,
658 final String model) {
659 final Either<Iterable<JanusGraphVertex>, JanusGraphOperationStatus> vertices = getVerticesByProperty(name, value);
661 if (vertices.isLeft()) {
662 final Predicate<? super JanusGraphVertex> filterPredicate =
663 StringUtils.isEmpty(model) ? this::vertexNotConnectedToAnyModel : vertex -> vertexValidForModel(vertex, model);
664 final List<JanusGraphVertex> verticesForModel = StreamSupport.stream(vertices.left().value().spliterator(), false).filter(filterPredicate)
665 .collect(Collectors.toList());
667 if (CollectionUtils.isEmpty(verticesForModel)) {
668 log.debug("No vertex in graph for key ={} and value = {}", name, value);
669 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
671 return Either.left(verticesForModel.get(0));
673 return Either.right(vertices.right().value());
676 public Either<JanusGraphVertex, JanusGraphOperationStatus> getVertexByProperty(final String name, final Object value) {
677 final Either<Iterable<JanusGraphVertex>, JanusGraphOperationStatus> vertices = getVerticesByProperty(name, value);
678 if (vertices.isLeft()) {
679 return Either.left(vertices.left().value().iterator().next());
681 return Either.right(vertices.right().value());
684 private Either<JanusGraphVertex, JanusGraphOperationStatus> getVertexByPropertyFromGraph(final JanusGraphTransaction graph, final String name,
685 final Object value) {
686 final Either<Iterable<JanusGraphVertex>, JanusGraphOperationStatus> vertices = getVerticesByPropertyFromGraph(graph, name, value);
687 if (vertices.isLeft()) {
688 return Either.left(vertices.left().value().iterator().next());
690 return Either.right(vertices.right().value());
693 private Either<Iterable<JanusGraphVertex>, JanusGraphOperationStatus> getVerticesByPropertyFromGraph(final JanusGraphTransaction graph,
694 final String name, final Object value) {
696 log.debug("No vertex in graph for key = {} and value = {}", name, value);
697 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
700 @SuppressWarnings("unchecked") Iterable<JanusGraphVertex> vertices = graph.query().has(name, value).vertices();
701 if (vertices.iterator().hasNext()) {
702 return Either.left(vertices);
704 log.debug("No vertex in graph for key ={} and value = {}", name, value);
705 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
707 } catch (Exception e) {
708 log.debug("Failed to get vertex in graph for key = {} and value = ", name, value);
709 return Either.right(JanusGraphClient.handleJanusGraphException(e));
713 private Either<Iterable<JanusGraphVertex>, JanusGraphOperationStatus> getVerticesByProperty(final String name, final Object value) {
714 final Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
716 log.debug("No vertex in graph for key = {} and value = {}", name, value);
717 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
719 if (graph.isLeft()) {
721 final JanusGraph tGraph = graph.left().value();
722 @SuppressWarnings("unchecked") Iterable<JanusGraphVertex> vertices = tGraph.query().has(name, value).vertices();
723 if (vertices.iterator().hasNext()) {
724 return Either.left(vertices);
726 log.debug("No vertex in graph for key ={} and value = {}", name, value);
727 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
729 } catch (Exception e) {
730 log.debug("Failed to get vertex in graph for key = {} and value = ", name, value);
731 return Either.right(JanusGraphClient.handleJanusGraphException(e));
734 log.debug("No vertex in graph for key = {} and value = {} error : {}", name, value, graph.right().value());
735 return Either.right(graph.right().value());
739 private boolean vertexValidForModel(final JanusGraphVertex vertex, final String model) {
740 final Either<List<ImmutablePair<JanusGraphVertex, Edge>>, JanusGraphOperationStatus> modelVertices = getParentVerticies(vertex,
741 GraphEdgeLabels.MODEL_ELEMENT);
743 if (modelVertices.isLeft()) {
744 for (ImmutablePair<JanusGraphVertex, Edge> vertexPair : modelVertices.left().value()) {
745 if (modelVertexMatchesModel(vertexPair.getLeft(), model)) {
753 private boolean modelVertexMatchesModel(final JanusGraphVertex modelVertex, final String model) {
754 if (model.equals((String) modelVertex.property("name").value())) {
757 final Either<List<ImmutablePair<JanusGraphVertex, Edge>>, JanusGraphOperationStatus> derivedModels =
758 getParentVerticies(modelVertex, GraphEdgeLabels.DERIVED_FROM);
759 if (derivedModels.isLeft()) {
760 for (final ImmutablePair<JanusGraphVertex, Edge> derivedModel : derivedModels.left().value()) {
761 if (modelVertexMatchesModel(derivedModel.left, model)) {
769 private boolean vertexNotConnectedToAnyModel(final JanusGraphVertex vertex) {
770 return !vertex.edges(Direction.IN, EdgeLabelEnum.MODEL_ELEMENT.name()).hasNext();
774 public <T extends GraphNode> Either<List<T>, JanusGraphOperationStatus> getByCriteria(NodeTypeEnum type, Map<String, Object> hasProps,
775 Map<String, Object> hasNotProps, Class<T> clazz) {
776 Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
777 if (graph.isLeft()) {
779 JanusGraph tGraph = graph.left().value();
780 JanusGraphQuery<? extends JanusGraphQuery> query = tGraph.query();
781 query = query.has(GraphPropertiesDictionary.LABEL.getProperty(), type.getName());
782 if (hasProps != null && !hasProps.isEmpty()) {
783 for (Map.Entry<String, Object> entry : hasProps.entrySet()) {
784 query = query.has(entry.getKey(), entry.getValue());
787 if (hasNotProps != null && !hasNotProps.isEmpty()) {
788 for (Map.Entry<String, Object> entry : hasNotProps.entrySet()) {
789 query = query.hasNot(entry.getKey(), entry.getValue());
792 Iterable<JanusGraphVertex> vertices = query.vertices();
793 if (vertices == null) {
794 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
796 Iterator<JanusGraphVertex> iterator = vertices.iterator();
797 List<T> result = new ArrayList<>();
798 while (iterator.hasNext()) {
799 Vertex vertex = iterator.next();
800 Map<String, Object> newProp = getProperties(vertex);
801 T element = GraphElementFactory.createElement(type.getName(), GraphElementTypeEnum.Node, newProp, clazz);
804 log.debug("Number of fetced nodes in graph for criteria : from type = {} and properties has = {}, properties hasNot = {} is {}",
805 type, hasProps, hasNotProps, result.size());
806 if (result.size() == 0) {
807 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
809 return Either.left(result);
810 } catch (Exception e) {
811 log.debug("Failed get by criteria for type = {}", type, e);
812 return Either.right(JanusGraphClient.handleJanusGraphException(e));
815 log.debug("Failed get by criteria for type ={} error : {}", type, graph.right().value());
816 return Either.right(graph.right().value());
820 public <T extends GraphNode> Either<List<T>, JanusGraphOperationStatus> getByCriteria(NodeTypeEnum type, Class<T> clazz,
821 List<ImmutableTriple<QueryType, String, Object>> props) {
822 Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
823 if (graph.isLeft()) {
825 JanusGraph tGraph = graph.left().value();
826 JanusGraphQuery<? extends JanusGraphQuery> query = tGraph.query();
827 query = query.has(GraphPropertiesDictionary.LABEL.getProperty(), type.getName());
828 for (ImmutableTriple<QueryType, String, Object> prop : props) {
829 if (QueryType.HAS.equals(prop.getLeft())) {
830 query = query.has(prop.getMiddle(), prop.getRight());
832 query = query.hasNot(prop.getMiddle(), prop.getRight());
835 Iterable<JanusGraphVertex> vertices = query.vertices();
836 if (vertices == null) {
837 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
839 Iterator<JanusGraphVertex> iterator = vertices.iterator();
840 List<T> result = new ArrayList<>();
841 while (iterator.hasNext()) {
842 Vertex vertex = iterator.next();
843 Map<String, Object> newProp = getProperties(vertex);
844 T element = GraphElementFactory.createElement(type.getName(), GraphElementTypeEnum.Node, newProp, clazz);
847 if (result.size() == 0) {
848 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
850 return Either.left(result);
851 } catch (Exception e) {
852 log.debug("Failed get by criteria for type = {}", type, e);
853 return Either.right(JanusGraphClient.handleJanusGraphException(e));
856 log.debug("Failed get by criteria for type ={} error : {}", type, graph.right().value());
857 return Either.right(graph.right().value());
861 public <T extends GraphNode> Either<List<T>, JanusGraphOperationStatus> getByCriteria(NodeTypeEnum type, Map<String, Object> props,
863 return getByCriteriaForModel(type, props, null, clazz);
866 public <T extends GraphNode> Either<List<T>, JanusGraphOperationStatus> getByCriteriaForModel(final NodeTypeEnum type,
867 final Map<String, Object> props,
868 final String model, final Class<T> clazz) {
870 final Either<Iterable<JanusGraphVertex>, JanusGraphOperationStatus> vertices = getVerticesByCriteria(type, props);
872 if (vertices.isLeft()) {
873 final Predicate<? super JanusGraphVertex> filterPredicate =
874 StringUtils.isEmpty(model) ? this::vertexNotConnectedToAnyModel : vertex -> vertexValidForModel(vertex, model);
875 final List<JanusGraphVertex> verticesForModel = StreamSupport.stream(vertices.left().value().spliterator(), false)
876 .filter(filterPredicate).collect(Collectors.toList());
878 if (CollectionUtils.isEmpty(verticesForModel)) {
879 log.debug("No vertex in graph for props ={} ", props);
880 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
883 final Iterator<JanusGraphVertex> iterator = verticesForModel.iterator();
884 final List<T> result = new ArrayList<>();
885 while (iterator.hasNext()) {
886 Vertex vertex = iterator.next();
887 Map<String, Object> newProp = getProperties(vertex);
888 T element = GraphElementFactory.createElement(type.getName(), GraphElementTypeEnum.Node, newProp, clazz);
891 log.debug("Number of fetced nodes in graph for criteria : from type = {} and properties = {} is {}", type, props, result.size());
892 return Either.left(result);
895 return Either.right(vertices.right().value());
896 } catch (Exception e) {
897 log.debug("Failed get by criteria for type = {} and properties = {}", type, props, e);
898 return Either.right(JanusGraphClient.handleJanusGraphException(e));
902 private Either<Iterable<JanusGraphVertex>, JanusGraphOperationStatus> getVerticesByCriteria(final NodeTypeEnum type,
903 final Map<String, Object> props) {
904 final Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
905 if (graph.isLeft()) {
907 final JanusGraph tGraph = graph.left().value();
908 JanusGraphQuery<? extends JanusGraphQuery> query = tGraph.query();
909 query = query.has(GraphPropertiesDictionary.LABEL.getProperty(), type.getName());
910 if (props != null && !props.isEmpty()) {
911 for (Map.Entry<String, Object> entry : props.entrySet()) {
912 query = query.has(entry.getKey(), entry.getValue());
915 final Iterable<JanusGraphVertex> vertices = query.vertices();
916 if (vertices == null || !vertices.iterator().hasNext()) {
917 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
919 return Either.left(vertices);
920 } catch (Exception e) {
921 log.debug("Failed get by criteria for type = {} and properties = {}", type, props, e);
922 return Either.right(JanusGraphClient.handleJanusGraphException(e));
925 log.debug("Failed get by criteria for type ={} and properties = {} error : {}", type, props, graph.right().value());
926 return Either.right(graph.right().value());
930 public <T extends GraphNode> Either<List<T>, JanusGraphOperationStatus> getByCriteriaWithPredicate(NodeTypeEnum type,
931 Map<String, Entry<JanusGraphPredicate, Object>> props,
932 Class<T> clazz, String modelName) {
933 Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
934 if (graph.isLeft()) {
936 JanusGraph tGraph = graph.left().value();
937 JanusGraphQuery<? extends JanusGraphQuery> query = tGraph.query();
938 query = query.has(GraphPropertiesDictionary.LABEL.getProperty(), type.getName());
939 if (props != null && !props.isEmpty()) {
940 JanusGraphPredicate predicate = null;
941 Object object = null;
942 for (Map.Entry<String, Entry<JanusGraphPredicate, Object>> entry : props.entrySet()) {
943 predicate = entry.getValue().getKey();
944 object = entry.getValue().getValue();
945 query = query.has(entry.getKey(), predicate, object);
948 Iterable<JanusGraphVertex> vertices = query.vertices();
949 if (vertices == null) {
950 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
952 final Predicate<? super JanusGraphVertex> filterPredicate =
953 StringUtils.isEmpty(modelName) ? this::vertexNotConnectedToAnyModel : vertex -> vertexValidForModel(vertex, modelName);
954 final List<JanusGraphVertex> verticesForModel = StreamSupport.stream(vertices.spliterator(), false).filter(filterPredicate)
955 .collect(Collectors.toList());
956 Iterator<JanusGraphVertex> iterator = verticesForModel.iterator();
957 List<T> result = new ArrayList<>();
958 while (iterator.hasNext()) {
959 Vertex vertex = iterator.next();
960 Map<String, Object> newProp = getProperties(vertex);
961 T element = GraphElementFactory.createElement(type.getName(), GraphElementTypeEnum.Node, newProp, clazz);
964 if (result.size() == 0) {
965 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
967 log.debug("No nodes in graph for criteria : from type = {} and properties = {}", type, props);
968 return Either.left(result);
969 } catch (Exception e) {
970 log.debug("Failed get by criteria for type = {} and properties = {}", type, props, e);
971 return Either.right(JanusGraphClient.handleJanusGraphException(e));
974 log.debug("Failed get by criteria for type = {} and properties = {} error : {}", type, props, graph.right().value());
975 return Either.right(graph.right().value());
979 public <T extends GraphNode> Either<List<T>, JanusGraphOperationStatus> getAll(NodeTypeEnum type, Class<T> clazz) {
980 return getByCriteria(type, null, clazz);
988 public <T extends GraphNode> Either<T, JanusGraphOperationStatus> updateNode(GraphNode node, Class<T> clazz) {
989 log.debug("Try to update node for {}", node.getKeyValueIdForLog());
990 ImmutablePair<String, Object> keyValueId = node.getKeyValueId();
991 Either<Vertex, JanusGraphOperationStatus> vertexByProperty = getVertexByPropertyAndLabel(keyValueId.getKey(), keyValueId.getValue(),
993 if (vertexByProperty.isLeft()) {
995 Vertex vertex = vertexByProperty.left().value();
996 Map<String, Object> mapProps = node.toGraphMap();
997 for (Map.Entry<String, Object> entry : mapProps.entrySet()) {
998 if (!entry.getKey().equals(node.getUniqueIdKey())) {
999 vertex.property(entry.getKey(), entry.getValue());
1002 Either<Vertex, JanusGraphOperationStatus> vertexByPropertyAndLabel = getVertexByPropertyAndLabel(keyValueId.getKey(),
1003 keyValueId.getValue(), node.getLabel());
1004 if (vertexByPropertyAndLabel.isRight()) {
1005 return Either.right(vertexByPropertyAndLabel.right().value());
1007 Map<String, Object> newProp = getProperties(vertexByPropertyAndLabel.left().value());
1008 T updateNode = GraphElementFactory.createElement(node.getLabel(), GraphElementTypeEnum.Node, newProp, clazz);
1009 return Either.left(updateNode);
1011 } catch (Exception e) {
1012 log.debug("Failed to update node for {}", node.getKeyValueId(), e);
1013 return Either.right(JanusGraphClient.handleJanusGraphException(e));
1016 log.debug("Failed to update node for {} error :{}", node.getKeyValueIdForLog(), vertexByProperty.right().value());
1017 return Either.right(vertexByProperty.right().value());
1021 public JanusGraphOperationStatus updateVertex(GraphNode node, Vertex vertex) {
1022 log.debug("Try to update node for {}", node.getKeyValueId());
1024 Map<String, Object> mapProps = node.toGraphMap();
1025 for (Map.Entry<String, Object> entry : mapProps.entrySet()) {
1026 if (!entry.getKey().equals(node.getUniqueIdKey())) {
1027 vertex.property(entry.getKey(), entry.getValue());
1030 } catch (Exception e) {
1031 log.debug("Failed to update node for {}", node.getKeyValueId(), e);
1032 return JanusGraphClient.handleJanusGraphException(e);
1034 return JanusGraphOperationStatus.OK;
1042 public <T extends GraphNode> Either<T, JanusGraphOperationStatus> deleteNode(GraphNode node, Class<T> clazz) {
1043 log.debug("Try to delete node for {}", node.getKeyValueId());
1044 ImmutablePair<String, Object> keyValueId = node.getKeyValueId();
1045 return deleteNode(keyValueId.getKey(), keyValueId.getValue(), clazz);
1054 public <T extends GraphNode> Either<T, JanusGraphOperationStatus> deleteNode(String keyName, Object keyValue, Class<T> clazz) {
1055 if (clazz.isAssignableFrom(GraphNodeLock.class)) {
1056 return deleteLockNode(keyName, keyValue, clazz);
1058 return deleteAnyNode(keyName, keyValue, clazz);
1062 private <T extends GraphNode> Either<T, JanusGraphOperationStatus> deleteAnyNode(String keyName, Object keyValue, Class<T> clazz) {
1063 final Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
1064 if (graph.isRight()) {
1065 return Either.right(graph.right().value());
1067 final Either<JanusGraphVertex, JanusGraphOperationStatus> vertexByProperty = getVertexByProperty(keyName, keyValue);
1068 if (vertexByProperty.isRight()) {
1069 return Either.right(vertexByProperty.right().value());
1072 Vertex vertex = vertexByProperty.left().value();
1073 Map<String, Object> properties = getProperties(vertex);
1074 if (properties != null) {
1075 String label = (String) properties.get(GraphPropertiesDictionary.LABEL.getProperty());
1076 T node = GraphElementFactory.createElement(label, GraphElementTypeEnum.Node, properties, clazz);
1079 return Either.left(node);
1081 log.debug("Failed to delete node for {} = {} Missing label property on node", keyName, keyValue);
1082 return Either.right(JanusGraphOperationStatus.MISSING_NODE_LABEL);
1085 log.debug("Failed to delete node for {} = {} Missing label property on node", keyName, keyValue);
1086 return Either.right(JanusGraphOperationStatus.MISSING_NODE_LABEL);
1088 } catch (Exception e) {
1089 log.debug("Failed to delete node for {} = {}", keyName, keyValue, e);
1090 return Either.right(JanusGraphClient.handleJanusGraphException(e));
1094 private <T extends GraphNode> Either<T, JanusGraphOperationStatus> deleteLockNode(String keyName, Object keyValue, Class<T> clazz) {
1095 final Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
1096 if (graph.isRight()) {
1097 return Either.right(graph.right().value());
1099 final JanusGraphTransaction tGraph = graph.left().value().tx().createThreadedTx();
1100 final Either<JanusGraphVertex, JanusGraphOperationStatus> vertexByProperty = getVertexByPropertyFromGraph(tGraph, keyName, keyValue);
1101 if (vertexByProperty.isRight()) {
1103 return Either.right(vertexByProperty.right().value());
1107 final Vertex vertex = vertexByProperty.left().value();
1108 final Map<String, Object> properties = getProperties(vertex);
1109 if (properties != null) {
1110 final String label = (String) properties.get(GraphPropertiesDictionary.LABEL.getProperty());
1111 final T node = GraphElementFactory.createElement(label, GraphElementTypeEnum.Node, properties, clazz);
1115 return Either.left(node);
1117 log.debug("Failed to delete node for {} = {} Missing label property on node", keyName, keyValue);
1118 return Either.right(JanusGraphOperationStatus.MISSING_NODE_LABEL);
1121 log.debug("Failed to delete node for {} = {} Missing label property on node", keyName, keyValue);
1122 return Either.right(JanusGraphOperationStatus.MISSING_NODE_LABEL);
1124 } catch (Exception e) {
1125 log.debug("Failed to delete node for {} = {}", keyName, keyValue, e);
1126 return Either.right(JanusGraphClient.handleJanusGraphException(e));
1130 public Either<GraphRelation, JanusGraphOperationStatus> deleteRelation(GraphRelation relation) {
1131 log.debug("try to delete relation from [{}] to [{}]", relation.getFrom(), relation.getTo());
1132 RelationEndPoint from = relation.getFrom();
1133 RelationEndPoint to = relation.getTo();
1134 ImmutablePair<String, Object> fromKeyId = new ImmutablePair<>(from.getIdName(), from.getIdValue());
1135 ImmutablePair<String, Object> toKeyId = new ImmutablePair<>(to.getIdName(), to.getIdValue());
1136 return deleteEdge(relation.getType(), fromKeyId, toKeyId, from.getLabel().getName(), to.getLabel().getName());
1139 public Either<Boolean, JanusGraphOperationStatus> isRelationExist(GraphNode from, GraphNode to, GraphEdgeLabels edgeLabel) {
1140 return getEdgeByNodes(from, to, edgeLabel).left().map(edge -> true).right()
1141 .bind(err -> err == JanusGraphOperationStatus.NOT_FOUND ? Either.left(false) : Either.right(err));
1144 public Either<GraphRelation, JanusGraphOperationStatus> deleteRelation(GraphNode from, GraphNode to, GraphEdgeLabels label) {
1145 log.debug("try to delete relation from [{}] to [{}]", from.getKeyValueId(), to.getKeyValueId());
1146 return deleteEdge(label.getProperty(), from.getKeyValueId(), to.getKeyValueId(), from.getLabel(), to.getLabel());
1149 private Either<GraphRelation, JanusGraphOperationStatus> deleteEdge(String type, ImmutablePair<String, Object> fromKeyId,
1150 ImmutablePair<String, Object> toKeyId, String fromLabel, String toLabel) {
1151 Either<Edge, JanusGraphOperationStatus> edgeS = getEdgeByVerticies(fromKeyId.getKey(), fromKeyId.getValue(), toKeyId.getKey(),
1152 toKeyId.getValue(), type);
1153 if (edgeS.isLeft()) {
1155 Edge edge = edgeS.left().value();
1156 Vertex vertexOut = edge.outVertex();
1157 Vertex vertexIn = edge.inVertex();
1158 GraphNode nodeOut = GraphElementFactory
1159 .createElement(fromLabel, GraphElementTypeEnum.Node, getProperties(vertexOut), GraphNode.class);
1160 GraphNode nodeIn = GraphElementFactory.createElement(toLabel, GraphElementTypeEnum.Node, getProperties(vertexIn), GraphNode.class);
1161 GraphRelation newRelation = GraphElementFactory.createRelation(edge.label(), getProperties(edge), nodeOut, nodeIn);
1162 Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
1163 if (graph.isLeft()) {
1166 log.debug("Failed to delete relation {} from {} to {} error : {}", type, fromKeyId, toKeyId, graph.right().value());
1167 return Either.right(graph.right().value());
1169 return Either.left(newRelation);
1170 } catch (Exception e) {
1171 log.debug("Failed to delete relation {} from {} to {}", type, fromKeyId, toKeyId, e);
1172 return Either.right(JanusGraphClient.handleJanusGraphException(e));
1175 log.debug("Failed to delete relation {} from {} to {} error : {}", type, fromKeyId, toKeyId, edgeS.right().value());
1176 return Either.right(edgeS.right().value());
1180 public void setJanusGraphClient(JanusGraphClient janusGraphClient) {
1181 this.janusGraphClient = janusGraphClient;
1184 public Either<GraphRelation, JanusGraphOperationStatus> deleteIncomingRelation(GraphRelation relation) {
1185 RelationEndPoint to = relation.getTo();
1186 ImmutablePair<String, Object> toKeyId = new ImmutablePair<>(to.getIdName(), to.getIdValue());
1187 return deleteIncomingEdge(relation.getType(), toKeyId);
1190 private Either<GraphRelation, JanusGraphOperationStatus> deleteIncomingEdge(String type, ImmutablePair<String, Object> toKeyId) {
1191 Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
1192 if (graph.isLeft()) {
1193 Either<JanusGraphVertex, JanusGraphOperationStatus> rootVertexResult = getVertexByProperty(toKeyId.getKey(), toKeyId.getValue());
1194 if (rootVertexResult.isLeft()) {
1195 Vertex rootVertex = rootVertexResult.left().value();
1196 Iterator<Edge> edgesIterator = rootVertex.edges(Direction.IN, type);
1197 if (edgesIterator != null) {
1199 if (edgesIterator.hasNext()) {
1200 edge = edgesIterator.next();
1201 if (edgesIterator.hasNext()) {
1202 return Either.right(JanusGraphOperationStatus.MULTIPLE_EDGES_WITH_SAME_LABEL);
1205 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
1207 log.debug("Find the tail vertex of the edge of type {} to vertex {}", type, toKeyId);
1208 Vertex vertexOut = edge.outVertex();
1209 String fromLabel = vertexOut.value(GraphPropertiesDictionary.LABEL.getProperty());
1210 String toLabel = rootVertex.value(GraphPropertiesDictionary.LABEL.getProperty());
1211 log.debug("The label of the outgoing vertex is {}", fromLabel);
1212 GraphNode nodeOut = GraphElementFactory
1213 .createElement(fromLabel, GraphElementTypeEnum.Node, getProperties(vertexOut), GraphNode.class);
1214 GraphNode nodeIn = GraphElementFactory
1215 .createElement(toLabel, GraphElementTypeEnum.Node, getProperties(rootVertex), GraphNode.class);
1216 GraphRelation newRelation = GraphElementFactory.createRelation(edge.label(), getProperties(edge), nodeOut, nodeIn);
1218 return Either.left(newRelation);
1220 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
1223 return Either.right(graph.right().value());
1226 return Either.right(graph.right().value());
1230 public Either<GraphRelation, JanusGraphOperationStatus> deleteOutgoingRelation(GraphRelation relation) {
1231 RelationEndPoint from = relation.getFrom();
1232 ImmutablePair<String, Object> fromKeyId = new ImmutablePair<>(from.getIdName(), from.getIdValue());
1233 return deleteOutgoingEdge(relation.getType(), fromKeyId);
1236 private Either<GraphRelation, JanusGraphOperationStatus> deleteOutgoingEdge(String type, ImmutablePair<String, Object> toKeyId) {
1237 Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
1238 if (graph.isLeft()) {
1239 Either<JanusGraphVertex, JanusGraphOperationStatus> rootVertexResult = getVertexByProperty(toKeyId.getKey(), toKeyId.getValue());
1240 if (rootVertexResult.isLeft()) {
1241 Vertex rootVertex = rootVertexResult.left().value();
1242 Iterator<Edge> edgesIterator = rootVertex.edges(Direction.OUT, type);
1243 if (edgesIterator != null) {
1245 if (edgesIterator.hasNext()) {
1246 edge = edgesIterator.next();
1247 if (edgesIterator.hasNext()) {
1248 return Either.right(JanusGraphOperationStatus.MULTIPLE_EDGES_WITH_SAME_LABEL);
1251 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
1253 log.debug("Find the tail vertex of the edge of type {} to vertex ", type, toKeyId);
1254 Vertex vertexIn = edge.inVertex();
1255 String toLabel = vertexIn.value(GraphPropertiesDictionary.LABEL.getProperty());
1256 String fromLabel = rootVertex.value(GraphPropertiesDictionary.LABEL.getProperty());
1257 log.debug("The label of the tail vertex is {}", toLabel);
1258 GraphNode nodeFrom = GraphElementFactory
1259 .createElement(fromLabel, GraphElementTypeEnum.Node, getProperties(rootVertex), GraphNode.class);
1260 GraphNode nodeTo = GraphElementFactory
1261 .createElement(toLabel, GraphElementTypeEnum.Node, getProperties(vertexIn), GraphNode.class);
1262 GraphRelation newRelation = GraphElementFactory.createRelation(edge.label(), getProperties(edge), nodeFrom, nodeTo);
1264 return Either.left(newRelation);
1266 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
1269 return Either.right(graph.right().value());
1272 return Either.right(graph.right().value());
1280 public JanusGraphOperationStatus lockElement(String id, NodeTypeEnum type) {
1281 StringBuilder lockId = new StringBuilder(LOCK_NODE_PREFIX);
1282 lockId.append(type.getName()).append("_").append(id);
1283 return lockNode(lockId.toString());
1286 public JanusGraphOperationStatus lockElement(GraphNode node) {
1287 String lockId = createLockElementId(node);
1288 return lockNode(lockId);
1291 private JanusGraphOperationStatus lockNode(String lockId) {
1292 GraphNodeLock lockNode = new GraphNodeLock(lockId);
1293 Either<GraphNodeLock, JanusGraphOperationStatus> lockNodeNew = createNode(lockNode, GraphNodeLock.class);
1294 if (lockNodeNew.isLeft()) {
1295 log.debug("before commit, Lock node created for {}", lockId);
1296 return janusGraphClient.commit();
1298 Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
1299 if (graph.isLeft()) {
1300 JanusGraph tGraph = graph.left().value();
1301 Either<JanusGraphVertex, JanusGraphOperationStatus> vertex = getVertexByProperty(lockNode.getUniqueIdKey(), lockNode.getUniqueId());
1302 if (vertex.isLeft()) {
1303 return relockNode(lockNode, lockNodeNew, tGraph, vertex);
1305 return vertex.right().value();
1308 return graph.right().value();
1313 private JanusGraphOperationStatus relockNode(GraphNodeLock lockNode, Either<GraphNodeLock, JanusGraphOperationStatus> lockNodeNew,
1314 JanusGraph tGraph, Either<JanusGraphVertex, JanusGraphOperationStatus> vertex) {
1315 Long time = vertex.left().value().value(GraphPropertiesDictionary.CREATION_DATE.getProperty());
1316 Long lockTimeout = ConfigurationManager.getConfigurationManager().getConfiguration().getJanusGraphLockTimeout();
1317 if (time + lockTimeout * 1000 < System.currentTimeMillis()) {
1318 log.debug("Found not released lock node with id {}", lockNode.getUniqueId());
1319 vertex.left().value().remove();
1320 lockNodeNew = createNode(lockNode, GraphNodeLock.class);
1321 if (lockNodeNew.isLeft()) {
1322 log.debug("Lock node created for {}", lockNode.getUniqueIdKey());
1323 return janusGraphClient.commit();
1325 log.debug("Failed Lock node for {} . Commit transacton for deleted previous vertex .", lockNode.getUniqueIdKey());
1326 janusGraphClient.commit();
1327 return checkLockError(lockNode.getUniqueIdKey(), lockNodeNew);
1330 log.debug("Failed Lock node for {} rollback transacton", lockNode.getUniqueIdKey());
1331 janusGraphClient.rollback();
1332 return checkLockError(lockNode.getUniqueIdKey(), lockNodeNew);
1336 public <T extends GraphNode> Either<List<ImmutablePair<T, GraphEdge>>, JanusGraphOperationStatus> getChildrenNodes(String key, String uniqueId,
1337 GraphEdgeLabels edgeType,
1338 NodeTypeEnum nodeTypeEnum,
1340 boolean withEdges) {
1341 List<ImmutablePair<T, GraphEdge>> immutablePairs = new ArrayList<>();
1342 Either<JanusGraph, JanusGraphOperationStatus> graphRes = janusGraphClient.getGraph();
1343 if (graphRes.isRight()) {
1344 log.error("Failed to retrieve graph. status is {}", graphRes);
1345 return Either.right(graphRes.right().value());
1347 JanusGraph janusGraph = graphRes.left().value();
1348 @SuppressWarnings("unchecked") Iterable<JanusGraphVertex> vertices = janusGraph.query().has(key, uniqueId).vertices();
1349 if (vertices == null || !vertices.iterator().hasNext()) {
1350 return Either.right(JanusGraphOperationStatus.INVALID_ID);
1352 Vertex rootVertex = vertices.iterator().next();
1353 Iterator<Edge> edgesCreatorIterator = rootVertex.edges(Direction.OUT, edgeType.getProperty());
1354 if (edgesCreatorIterator != null) {
1355 while (edgesCreatorIterator.hasNext()) {
1356 Edge edge = edgesCreatorIterator.next();
1357 GraphEdge graphEdge = null;
1359 Map<String, Object> edgeProps = getProperties(edge);
1360 GraphEdgeLabels edgeTypeFromGraph = GraphEdgeLabels.getByName(edge.label());
1361 graphEdge = new GraphEdge(edgeTypeFromGraph, edgeProps);
1363 Vertex outgoingVertex = edge.inVertex();
1364 Map<String, Object> properties = getProperties(outgoingVertex);
1365 T data = GraphElementFactory.createElement(nodeTypeEnum.getName(), GraphElementTypeEnum.Node, properties, clazz);
1366 ImmutablePair<T, GraphEdge> immutablePair = new ImmutablePair<>(clazz.cast(data), graphEdge);
1367 immutablePairs.add(immutablePair);
1370 if (immutablePairs.isEmpty()) {
1371 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
1373 return Either.left(immutablePairs);
1376 public <T extends GraphNode> JanusGraphOperationStatus deleteAllChildrenNodes(String key, String uniqueId, GraphEdgeLabels edgeType) {
1377 final JanusGraph janusGraph = getJanusGraph();
1378 final Iterable<JanusGraphVertex> vertices = janusGraph.query().has(key, uniqueId).vertices();
1379 if (vertices == null || !vertices.iterator().hasNext()) {
1380 return JanusGraphOperationStatus.NOT_FOUND;
1382 final Vertex rootVertex = vertices.iterator().next();
1383 final Iterator<Edge> outEdges = rootVertex.edges(Direction.OUT, edgeType.getProperty());
1384 while (outEdges.hasNext()) {
1385 final Edge edge = outEdges.next();
1386 final Vertex vertexIn = edge.inVertex();
1387 final Iterator<Edge> outSubEdges = vertexIn.edges(Direction.OUT);
1388 while (outSubEdges.hasNext()) {
1389 Edge subEdge = outSubEdges.next();
1390 Vertex vertex = subEdge.inVertex();
1391 Map<String, Object> properties = getProperties(vertex);
1392 if (properties != null) {
1393 String label = (String) properties.get(GraphPropertiesDictionary.LABEL.getProperty());
1394 if (label.equals("property")) {
1399 Map<String, Object> properties = getProperties(vertexIn);
1400 if (properties != null) {
1401 String label = (String) properties.get(GraphPropertiesDictionary.LABEL.getProperty());
1402 GraphNode node = GraphElementFactory
1403 .createElement(label, GraphElementTypeEnum.Node, properties, GraphNode.class);
1409 return JanusGraphOperationStatus.OK;
1413 * Gets the JanusGraph instance.
1415 * @return the JanusGraph instance
1416 * @throws JanusGraphException when the graph was not created
1418 public JanusGraph getJanusGraph() {
1419 final Either<JanusGraph, JanusGraphOperationStatus> graphRes = janusGraphClient.getGraph();
1420 if (graphRes.isRight()) {
1421 final var errorMsg = String.format("Failed to retrieve graph. Status was '%s'", graphRes.right().value());
1422 log.error(EcompLoggerErrorCode.SCHEMA_ERROR, JanusGraphGenericDao.class.getName(), errorMsg);
1423 throw new JanusGraphException(graphRes.right().value(), errorMsg);
1425 return graphRes.left().value();
1428 public Either<List<ImmutablePair<JanusGraphVertex, Edge>>, JanusGraphOperationStatus> getChildrenVertecies(String key, String uniqueId,
1429 GraphEdgeLabels edgeType) {
1430 List<ImmutablePair<JanusGraphVertex, Edge>> immutablePairs = new ArrayList<>();
1431 Either<JanusGraph, JanusGraphOperationStatus> graphRes = janusGraphClient.getGraph();
1432 if (graphRes.isRight()) {
1433 log.error("Failed to retrieve graph. status is {}", graphRes);
1434 return Either.right(graphRes.right().value());
1436 JanusGraph janusGraph = graphRes.left().value();
1437 @SuppressWarnings("unchecked") Iterable<JanusGraphVertex> vertices = janusGraph.query().has(key, uniqueId).vertices();
1438 if (vertices == null || !vertices.iterator().hasNext()) {
1439 return Either.right(JanusGraphOperationStatus.INVALID_ID);
1441 return getChildrenVerticies(vertices.iterator().next(), edgeType);
1444 public Either<List<ImmutablePair<JanusGraphVertex, Edge>>, JanusGraphOperationStatus> getChildrenVerticies(
1445 final JanusGraphVertex rootVertex, final GraphEdgeLabels edgeType) {
1446 return getEdgeVerticies(rootVertex, Direction.OUT, edgeType);
1449 public Either<List<ImmutablePair<JanusGraphVertex, Edge>>, JanusGraphOperationStatus> getParentVerticies(
1450 final JanusGraphVertex rootVertex, final GraphEdgeLabels edgeType) {
1451 return getEdgeVerticies(rootVertex, Direction.IN, edgeType);
1454 public Either<List<ImmutablePair<JanusGraphVertex, Edge>>, JanusGraphOperationStatus> getEdgeVerticies(
1455 final JanusGraphVertex rootVertex, final Direction direction, final GraphEdgeLabels edgeType) {
1456 final List<ImmutablePair<JanusGraphVertex, Edge>> immutablePairs = new ArrayList<>();
1457 final Iterator<Edge> edgesCreatorIterator = rootVertex.edges(direction, edgeType.getProperty());
1458 if (edgesCreatorIterator != null) {
1459 while (edgesCreatorIterator.hasNext()) {
1460 Edge edge = edgesCreatorIterator.next();
1461 JanusGraphVertex vertex = Direction.OUT.equals(direction) ? (JanusGraphVertex) edge.inVertex() : (JanusGraphVertex) edge.outVertex();
1462 ImmutablePair<JanusGraphVertex, Edge> immutablePair = new ImmutablePair<>(vertex, edge);
1463 immutablePairs.add(immutablePair);
1466 if (immutablePairs.isEmpty()) {
1467 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
1469 return Either.left(immutablePairs);
1472 public <T extends GraphNode> Either<List<ImmutablePair<T, GraphEdge>>, JanusGraphOperationStatus> getChildrenNodes(String key, String uniqueId,
1473 GraphEdgeLabels edgeType,
1474 NodeTypeEnum nodeTypeEnum,
1476 return this.getChildrenNodes(key, uniqueId, edgeType, nodeTypeEnum, clazz, true);
1479 private JanusGraphOperationStatus checkLockError(String lockId, Either<GraphNodeLock, JanusGraphOperationStatus> lockNodeNew) {
1480 JanusGraphOperationStatus status;
1481 JanusGraphOperationStatus error = lockNodeNew.right().value();
1482 log.debug("Failed to Lock node for {} error = {}", lockId, error);
1483 if (error.equals(JanusGraphOperationStatus.JANUSGRAPH_SCHEMA_VIOLATION) || error.equals(JanusGraphOperationStatus.ILLEGAL_ARGUMENT)) {
1484 status = JanusGraphOperationStatus.ALREADY_LOCKED;
1495 public JanusGraphOperationStatus releaseElement(GraphNode node) {
1496 String lockId = createLockElementId(node);
1497 return unlockNode(lockId);
1500 private JanusGraphOperationStatus unlockNode(String lockId) {
1501 GraphNodeLock lockNode = new GraphNodeLock(lockId.toString());
1502 Either<GraphNodeLock, JanusGraphOperationStatus> lockNodeNew = deleteNode(lockNode, GraphNodeLock.class);
1503 if (lockNodeNew.isLeft()) {
1504 log.debug("Lock node released for lock id = {}", lockId);
1505 return JanusGraphOperationStatus.OK;
1507 janusGraphClient.rollback();
1508 JanusGraphOperationStatus error = lockNodeNew.right().value();
1509 log.debug("Failed to Release node for lock id {} error = {}", lockId, error);
1514 public JanusGraphOperationStatus releaseElement(String id, NodeTypeEnum type) {
1515 StringBuilder lockId = new StringBuilder(LOCK_NODE_PREFIX);
1516 lockId.append(type.getName()).append("_").append(id);
1517 return unlockNode(lockId.toString());
1520 private String createLockElementId(GraphNode node) {
1521 StringBuilder lockId = new StringBuilder(LOCK_NODE_PREFIX);
1522 lockId.append(node.getLabel()).append("_").append(node.getUniqueId());
1523 return lockId.toString();
1526 public <T extends GraphNode> Either<ImmutablePair<T, GraphEdge>, JanusGraphOperationStatus> getChild(String key, String uniqueId,
1527 GraphEdgeLabels edgeType,
1528 NodeTypeEnum nodeTypeEnum, Class<T> clazz) {
1529 Either<List<ImmutablePair<T, GraphEdge>>, JanusGraphOperationStatus> childrenNodes = getChildrenNodes(key, uniqueId, edgeType, nodeTypeEnum,
1531 if (childrenNodes.isRight()) {
1532 return Either.right(childrenNodes.right().value());
1534 List<ImmutablePair<T, GraphEdge>> value = childrenNodes.left().value();
1535 if (value.size() > 1) {
1536 return Either.right(JanusGraphOperationStatus.MULTIPLE_CHILDS_WITH_SAME_EDGE);
1538 return Either.left(value.get(0));
1541 public ImmutablePair<JanusGraphVertex, Edge> getChildVertex(JanusGraphVertex vertex, GraphEdgeLabels edgeType) {
1542 ImmutablePair<JanusGraphVertex, Edge> pair = null;
1543 Iterator<Edge> edges = vertex.edges(Direction.OUT, edgeType.getProperty());
1544 if (edges.hasNext()) {
1545 // get only first edge
1546 Edge edge = edges.next();
1547 pair = new ImmutablePair<>((JanusGraphVertex) edge.inVertex(), edge);
1552 public <T extends GraphNode> Either<List<ImmutablePair<T, GraphEdge>>, JanusGraphOperationStatus> getParentNodes(String key, String uniqueId,
1553 GraphEdgeLabels edgeType,
1554 NodeTypeEnum nodeTypeEnum,
1556 List<ImmutablePair<T, GraphEdge>> immutablePairs = new ArrayList<>();
1558 GraphEdge graphEdge = null;
1559 Either<JanusGraph, JanusGraphOperationStatus> graphRes = janusGraphClient.getGraph();
1560 if (graphRes.isRight()) {
1561 log.error("Failed to retrieve graph. status is {}", graphRes);
1562 return Either.right(graphRes.right().value());
1564 JanusGraph janusGraph = graphRes.left().value();
1565 @SuppressWarnings("unchecked") Iterable<JanusGraphVertex> vertices = janusGraph.query().has(key, uniqueId).vertices();
1566 if (vertices == null || !vertices.iterator().hasNext()) {
1567 return Either.right(JanusGraphOperationStatus.INVALID_ID);
1569 Vertex rootVertex = vertices.iterator().next();
1570 Iterator<Edge> edgesCreatorIterator = rootVertex.edges(Direction.IN, edgeType.name());
1571 if (edgesCreatorIterator != null) {
1572 while (edgesCreatorIterator.hasNext()) {
1573 Edge edge = edgesCreatorIterator.next();
1574 Map<String, Object> edgeProps = getProperties(edge);
1575 GraphEdgeLabels edgeTypeFromGraph = GraphEdgeLabels.getByName(edge.label());
1576 graphEdge = new GraphEdge(edgeTypeFromGraph, edgeProps);
1577 Vertex outgoingVertex = edge.outVertex();
1578 Map<String, Object> properties = getProperties(outgoingVertex);
1579 data = GraphElementFactory.createElement(nodeTypeEnum.getName(), GraphElementTypeEnum.Node, properties, clazz);
1580 ImmutablePair<T, GraphEdge> immutablePair = new ImmutablePair<>(clazz.cast(data), graphEdge);
1581 immutablePairs.add(immutablePair);
1584 if (immutablePairs.isEmpty()) {
1585 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
1587 return Either.left(immutablePairs);
1590 public <T extends GraphNode> Either<ImmutablePair<T, GraphEdge>, JanusGraphOperationStatus> getParentNode(String key, String uniqueId,
1591 GraphEdgeLabels edgeType,
1592 NodeTypeEnum nodeTypeEnum,
1594 Either<List<ImmutablePair<T, GraphEdge>>, JanusGraphOperationStatus> parentNodesRes = this
1595 .getParentNodes(key, uniqueId, edgeType, nodeTypeEnum, clazz);
1596 if (parentNodesRes.isRight()) {
1597 log.debug("failed to get edge key:{} uniqueId:{} edgeType {} nodeTypeEnum: {}, reason:{}", key, uniqueId, edgeType, nodeTypeEnum,
1598 parentNodesRes.right().value());
1599 return Either.right(parentNodesRes.right().value());
1601 List<ImmutablePair<T, GraphEdge>> value = parentNodesRes.left().value();
1602 if (value.size() > 1) {
1603 return Either.right(JanusGraphOperationStatus.MULTIPLE_CHILDS_WITH_SAME_EDGE);
1605 return Either.left(value.get(0));
1608 public <T extends GraphNode> Either<ImmutablePair<T, GraphEdge>, JanusGraphOperationStatus> getChildByEdgeCriteria(String key, String uniqueId,
1609 GraphEdgeLabels edgeType,
1610 NodeTypeEnum nodeTypeEnum,
1612 Map<String, Object> edgeProperties) {
1613 Either<Edge, JanusGraphOperationStatus> outgoingEdgeByCriteria = getOutgoingEdgeByCriteria(key, uniqueId, edgeType, edgeProperties);
1614 if (outgoingEdgeByCriteria.isRight()) {
1615 JanusGraphOperationStatus status = outgoingEdgeByCriteria.right().value();
1616 log.debug("Cannot find outgoing edge from vertex {} with label {} and properties {}" + uniqueId, edgeType, edgeProperties);
1617 return Either.right(status);
1619 Edge edge = outgoingEdgeByCriteria.left().value();
1620 Map<String, Object> edgeProps = getProperties(edge);
1621 GraphEdgeLabels edgeTypeFromGraph = GraphEdgeLabels.getByName(edge.label());
1622 GraphEdge graphEdge = new GraphEdge(edgeTypeFromGraph, edgeProps);
1623 Vertex outgoingVertex = edge.inVertex();
1624 Map<String, Object> properties = getProperties(outgoingVertex);
1625 T data = GraphElementFactory.createElement(nodeTypeEnum.getName(), GraphElementTypeEnum.Node, properties, clazz);
1626 ImmutablePair<T, GraphEdge> immutablePair = new ImmutablePair<>(clazz.cast(data), graphEdge);
1627 return Either.left(immutablePair);
1630 public Either<ImmutablePair<JanusGraphVertex, Edge>, JanusGraphOperationStatus> getChildByEdgeCriteria(JanusGraphVertex vertex,
1631 GraphEdgeLabels edgeType,
1632 Map<String, Object> edgeProperties) {
1633 Either<Edge, JanusGraphOperationStatus> outgoingEdgeByCriteria = getOutgoingEdgeByCriteria(vertex, edgeType, edgeProperties);
1634 if (outgoingEdgeByCriteria.isRight()) {
1635 JanusGraphOperationStatus status = outgoingEdgeByCriteria.right().value();
1636 log.debug("Cannot find outgoing edge from vertex {} with label {} and properties {}", vertex, edgeType, edgeProperties);
1637 return Either.right(status);
1639 Edge edge = outgoingEdgeByCriteria.left().value();
1640 JanusGraphVertex outgoingVertex = (JanusGraphVertex) edge.inVertex();
1641 ImmutablePair<JanusGraphVertex, Edge> immutablePair = new ImmutablePair<>(outgoingVertex, edge);
1642 return Either.left(immutablePair);
1645 public Either<Edge, JanusGraphOperationStatus> getOutgoingEdgeByCriteria(String key, String value, GraphEdgeLabels label,
1646 Map<String, Object> props) {
1647 Either<JanusGraphVertex, JanusGraphOperationStatus> vertexFrom = getVertexByProperty(key, value);
1648 if (vertexFrom.isRight()) {
1649 JanusGraphOperationStatus status = vertexFrom.right().value();
1650 if (status == JanusGraphOperationStatus.NOT_FOUND) {
1651 return Either.right(JanusGraphOperationStatus.INVALID_ID);
1653 return Either.right(status);
1655 return getOutgoingEdgeByCriteria(vertexFrom.left().value(), label, props);
1658 public Either<Edge, JanusGraphOperationStatus> getOutgoingEdgeByCriteria(JanusGraphVertex vertex, GraphEdgeLabels label,
1659 Map<String, Object> props) {
1660 JanusGraphVertexQuery<?> query = vertex.query();
1661 query = query.direction(Direction.OUT).labels(label.getProperty());
1662 if (props != null && !props.isEmpty()) {
1663 for (Map.Entry<String, Object> entry : props.entrySet()) {
1664 query = query.has(entry.getKey(), entry.getValue());
1667 Edge matchingEdge = null;
1668 Iterable<JanusGraphEdge> edges = query.edges();
1669 if (edges == null) {
1670 log.debug("No edges in graph for criteria");
1671 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
1673 Iterator<JanusGraphEdge> eIter = edges.iterator();
1674 if (eIter.hasNext()) {
1675 matchingEdge = eIter.next();
1677 if (matchingEdge == null) {
1678 log.debug("No edges in graph for criteria");
1679 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
1681 return Either.left(matchingEdge);
1684 public <T extends GraphNode> Either<List<ImmutablePair<T, GraphEdge>>, JanusGraphOperationStatus> deleteChildrenNodes(String key, String uniqueId,
1685 GraphEdgeLabels edgeType,
1686 NodeTypeEnum nodeTypeEnum,
1688 List<ImmutablePair<T, GraphEdge>> result = new ArrayList<>();
1689 Either<List<ImmutablePair<T, GraphEdge>>, JanusGraphOperationStatus> childrenNodesRes = getChildrenNodes(key, uniqueId, edgeType,
1690 nodeTypeEnum, clazz);
1691 if (childrenNodesRes.isRight()) {
1692 JanusGraphOperationStatus status = childrenNodesRes.right().value();
1693 return Either.right(status);
1695 List<ImmutablePair<T, GraphEdge>> list = childrenNodesRes.left().value();
1696 for (ImmutablePair<T, GraphEdge> pair : list) {
1697 T node = pair.getKey();
1698 Either<T, JanusGraphOperationStatus> deleteNodeRes = this.deleteNode(node, clazz);
1699 if (deleteNodeRes.isRight()) {
1700 JanusGraphOperationStatus status = deleteNodeRes.right().value();
1701 log.error("Failed to delete node {} . status is {}", node, status);
1702 return Either.right(status);
1704 ImmutablePair<T, GraphEdge> deletedPair = new ImmutablePair<>(node, pair.getValue());
1705 result.add(deletedPair);
1707 return Either.left(result);
1710 public void setProperties(Element element, Map<String, Object> properties) {
1711 if (properties != null && !properties.isEmpty()) {
1712 Object[] propertyKeyValues = new Object[properties.size() * 2];
1714 for (Entry<String, Object> entry : properties.entrySet()) {
1715 propertyKeyValues[i++] = entry.getKey();
1716 propertyKeyValues[i++] = entry.getValue();
1718 ElementHelper.attachProperties(element, propertyKeyValues);
1722 public Map<String, Object> getProperties(Element element) {
1723 Map<String, Object> result = new HashMap<>();
1724 if (element != null && element.keys() != null && element.keys().size() > 0) {
1725 Map<String, Property> propertyMap = ElementHelper.propertyMap(element, element.keys().toArray(new String[element.keys().size()]));
1726 for (Entry<String, Property> entry : propertyMap.entrySet()) {
1727 String key = entry.getKey();
1728 Object value = entry.getValue().value();
1729 result.put(key, value);
1735 public Object getProperty(JanusGraphVertex vertex, String key) {
1736 PropertyKey propertyKey = janusGraphClient.getGraph().left().value().getPropertyKey(key);
1737 return vertex.valueOrNull(propertyKey);
1740 public Object getProperty(Edge edge, String key) {
1741 Object value = null;
1742 Property<Object> property = edge.property(key);
1743 if (property != null) {
1744 return property.orElse(null);
1749 public <T extends GraphNode> Either<List<ImmutablePair<T, GraphEdge>>, JanusGraphOperationStatus> getChildrenByEdgeCriteria(Vertex vertex,
1750 String vertexUniqueId,
1751 GraphEdgeLabels edgeType,
1752 NodeTypeEnum nodeTypeEnum,
1754 Map<String, Object> edgeProperties) {
1755 List<ImmutablePair<T, GraphEdge>> result = new ArrayList<>();
1756 Either<List<Edge>, JanusGraphOperationStatus> outgoingEdgeByCriteria = getOutgoingEdgesByCriteria(vertex, edgeType, edgeProperties);
1757 if (outgoingEdgeByCriteria.isRight()) {
1758 JanusGraphOperationStatus status = outgoingEdgeByCriteria.right().value();
1759 log.debug("Cannot find outgoing edge from vertex {} with label {} and properties {}", vertexUniqueId, edgeType, edgeProperties);
1760 return Either.right(status);
1762 List<Edge> edges = outgoingEdgeByCriteria.left().value();
1763 if (edges != null) {
1764 for (Edge edge : edges) {
1765 Map<String, Object> edgeProps = getProperties(edge);
1766 GraphEdgeLabels edgeTypeFromGraph = GraphEdgeLabels.getByName(edge.label());
1767 GraphEdge graphEdge = new GraphEdge(edgeTypeFromGraph, edgeProps);
1768 Vertex outgoingVertex = edge.inVertex();
1769 Map<String, Object> properties = getProperties(outgoingVertex);
1770 T data = GraphElementFactory.createElement(nodeTypeEnum.getName(), GraphElementTypeEnum.Node, properties, clazz);
1771 ImmutablePair<T, GraphEdge> immutablePair = new ImmutablePair<>(clazz.cast(data), graphEdge);
1772 result.add(immutablePair);
1775 return Either.left(result);
1779 Either<List<Edge>, JanusGraphOperationStatus> getOutgoingEdgesByCriteria(Vertex vertexFrom, GraphEdgeLabels label, Map<String, Object> props) {
1780 List<Edge> edgesResult = new ArrayList<>();
1781 JanusGraphVertex janusGraphVertex = (JanusGraphVertex) vertexFrom;
1782 JanusGraphVertexQuery<?> query = janusGraphVertex.query();
1783 query = query.direction(Direction.OUT).labels(label.getProperty());
1784 if (props != null && !props.isEmpty()) {
1785 for (Map.Entry<String, Object> entry : props.entrySet()) {
1786 query = query.has(entry.getKey(), entry.getValue());
1789 Iterable<JanusGraphEdge> edges = query.edges();
1790 Iterator<JanusGraphEdge> eIter = edges.iterator();
1791 if (!eIter.hasNext()) {
1792 log.debug("No edges found in graph for criteria (label = {} properties={})", label.getProperty(), props);
1793 return Either.left(edgesResult);
1795 while (eIter.hasNext()) {
1796 Edge edge = eIter.next();
1797 edgesResult.add(edge);
1799 if (edgesResult.isEmpty()) {
1800 log.debug("No edges found in graph for criteria (label = {} properties={})", label.getProperty(), props);
1801 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
1803 return Either.left(edgesResult);