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=========================================================
21 package org.openecomp.sdc.be.dao.titan;
23 import com.thinkaurelius.titan.core.*;
24 import com.thinkaurelius.titan.graphdb.query.TitanPredicate;
25 import fj.data.Either;
26 import org.apache.commons.lang3.tuple.ImmutablePair;
27 import org.apache.commons.lang3.tuple.ImmutableTriple;
28 import org.apache.tinkerpop.gremlin.structure.*;
29 import org.apache.tinkerpop.gremlin.structure.util.ElementHelper;
30 import org.openecomp.sdc.be.config.ConfigurationManager;
31 import org.openecomp.sdc.be.dao.graph.GraphElementFactory;
32 import org.openecomp.sdc.be.dao.graph.datatype.*;
33 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
34 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
35 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
36 import org.openecomp.sdc.be.resources.data.GraphNodeLock;
37 import org.openecomp.sdc.common.log.wrappers.Logger;
38 import org.springframework.stereotype.Component;
41 import java.util.Map.Entry;
42 import java.util.stream.Collectors;
43 import java.util.stream.StreamSupport;
44 @Component("titan-generic-dao")
45 public class TitanGenericDao {
47 private TitanGraphClient titanClient;
48 private static Logger log = Logger.getLogger(TitanGenericDao.class.getName());
49 private static final String LOCK_NODE_PREFIX = "lock_";
51 public TitanGenericDao(TitanGraphClient titanClient) {
52 this.titanClient = titanClient;
53 log.info("** TitanGenericDao created");
56 public TitanOperationStatus commit() {
57 log.debug("doing commit.");
58 return titanClient.commit();
61 public TitanOperationStatus rollback() {
62 log.error("Going to execute rollback on graph.");
63 return titanClient.rollback();
66 public <T, TStatus> void handleTransactionCommitRollback(boolean inTransaction, Either<T, TStatus> result) {
68 if (result == null || result.isRight()) {
76 public Either<TitanGraph, TitanOperationStatus> getGraph() {
77 return titanClient.getGraph();
81 public boolean isGraphOpen() {
82 return titanClient.getHealth();
91 public <T extends GraphNode> Either<T, TitanOperationStatus> createNode(T node, Class<T> clazz) {
92 log.debug("try to create node for ID [{}]", node.getKeyValueId());
93 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
97 TitanGraph tGraph = graph.left().value();
99 Vertex vertex = tGraph.addVertex();
101 vertex.property(GraphPropertiesDictionary.LABEL.getProperty(), node.getLabel());
103 Map<String, Object> properties = node.toGraphMap();
104 if (properties != null) {
105 setProperties(vertex, properties);
107 Map<String, Object> newProps = getProperties(vertex);
108 newNode = GraphElementFactory.createElement(node.getLabel(), GraphElementTypeEnum.Node, newProps, clazz);
109 log.debug("created node for props : {}", newProps);
110 log.debug("Node was created for ID [{}]", node.getKeyValueId());
111 return Either.left(newNode);
113 } catch (Exception e) {
114 log.debug("Failed to create Node for ID [{}]", node.getKeyValueId(), e);
115 return Either.right(TitanGraphClient.handleTitanException(e));
119 log.debug("Failed to create Node for ID [{}] {}", node.getKeyValueId(), graph.right().value());
120 return Either.right(graph.right().value());
124 public Either<TitanVertex, TitanOperationStatus> createNode(GraphNode node) {
125 log.debug("try to create node for ID [{}]", node.getKeyValueId());
126 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
127 if (graph.isLeft()) {
129 TitanGraph tGraph = graph.left().value();
131 TitanVertex vertex = tGraph.addVertex();
133 vertex.property(GraphPropertiesDictionary.LABEL.getProperty(), node.getLabel());
135 Map<String, Object> properties = node.toGraphMap();
136 if (properties != null) {
137 setProperties(vertex, properties);
139 log.debug("Node was created for ID [{}]", node.getKeyValueId());
140 return Either.left(vertex);
142 } catch (Exception e) {
143 log.debug("Failed to create Node for ID [{}]", node.getKeyValueId(), e);
144 return Either.right(TitanGraphClient.handleTitanException(e));
148 log.debug("Failed to create Node for ID [{}] {}", node.getKeyValueId(), graph.right().value());
149 return Either.right(graph.right().value());
158 public Either<GraphRelation, TitanOperationStatus> createRelation(GraphRelation relation) {
159 log.debug("try to create relation from [{}] to [{}] ", relation.getFrom(), relation.getTo());
161 RelationEndPoint from = relation.getFrom();
162 RelationEndPoint to = relation.getTo();
163 ImmutablePair<String, Object> fromKeyId = new ImmutablePair<>(from.getIdName(), from.getIdValue());
164 ImmutablePair<String, Object> toKeyId = new ImmutablePair<>(to.getIdName(), to.getIdValue());
166 return createEdge(relation.getType(), fromKeyId, toKeyId, from.getLabel().getName(), to.getLabel().getName(), relation.toGraphMap());
170 private Either<GraphRelation, TitanOperationStatus> createEdge(String type, ImmutablePair<String, Object> from, ImmutablePair<String, Object> to, String fromLabel, String toLabel, Map<String, Object> properties) {
171 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
173 if (graph.isLeft()) {
175 Either<Vertex, TitanOperationStatus> fromV = getVertexByPropertyAndLabel(from.getKey(), from.getValue(), fromLabel);
176 if (fromV.isRight()) {
177 TitanOperationStatus error = fromV.right().value();
178 if (TitanOperationStatus.NOT_FOUND.equals(error)) {
179 return Either.right(TitanOperationStatus.INVALID_ID);
181 return Either.right(error);
184 Either<Vertex, TitanOperationStatus> toV = getVertexByPropertyAndLabel(to.getKey(), to.getValue(), toLabel);
186 TitanOperationStatus error = toV.right().value();
187 if (TitanOperationStatus.NOT_FOUND.equals(error)) {
188 return Either.right(TitanOperationStatus.INVALID_ID);
190 return Either.right(error);
194 Vertex fromVertex = fromV.left().value();
195 Vertex toVertex = toV.left().value();
196 Edge edge = fromVertex.addEdge(type, toVertex);
198 if (properties != null) {
200 setProperties(edge, properties);
203 Vertex vertexOut = edge.outVertex();
204 Vertex vertexIn = edge.inVertex();
206 GraphNode nodeOut = GraphElementFactory.createElement(fromLabel, GraphElementTypeEnum.Node, getProperties(vertexOut), GraphNode.class);
207 GraphNode nodeIn = GraphElementFactory.createElement(toLabel, GraphElementTypeEnum.Node, getProperties(vertexIn), GraphNode.class);
209 GraphRelation newRelation = GraphElementFactory.createRelation(edge.label(), getProperties(edge), nodeOut, nodeIn);
211 return Either.left(newRelation);
212 } catch (Exception e) {
213 log.debug("Failed to create edge from [{}] to [{}]", from, to, e);
214 return Either.right(TitanGraphClient.handleTitanException(e));
217 log.debug("Failed to create edge from [{}] to [{}] {}", from, to, graph.right().value());
218 return Either.right(graph.right().value());
222 public TitanOperationStatus createEdge(Vertex vertexOut, Vertex vertexIn, GraphEdgeLabels type, Map<String, Object> properties) {
224 Edge edge = addEdge(vertexOut, vertexIn, type, properties);
225 } catch (Exception e) {
226 log.debug("Failed to create edge from [{}] to [{}]", vertexOut, vertexIn, e);
227 return TitanGraphClient.handleTitanException(e);
229 return TitanOperationStatus.OK;
233 private Edge addEdge(Vertex vertexOut, Vertex vertexIn, GraphEdgeLabels type, Map<String, Object> properties) {
234 Edge edge = vertexOut.addEdge(type.getProperty(), vertexIn);
236 if (properties != null) {
238 setProperties(edge, properties);
244 * creates an identical edge in the graph
246 * @return the copy operation status
248 public Either<Edge, TitanOperationStatus> copyEdge(Vertex out, Vertex in, Edge edge) {
249 GraphEdgeLabels byName = GraphEdgeLabels.getByName(edge.label());
250 return this.saveEdge(out, in, byName, edgePropertiesToMap(edge));
253 private <V> Map<String, Object> edgePropertiesToMap(Edge edge) {
254 Iterable<Property<Object>> propertiesIterable = edge::properties;
255 return StreamSupport.stream(propertiesIterable.spliterator(), false).collect(Collectors.toMap(Property::key, Property::value));
258 public Either<Edge, TitanOperationStatus> saveEdge(Vertex vertexOut, Vertex vertexIn, GraphEdgeLabels type, Map<String, Object> properties) {
260 Edge edge = addEdge(vertexOut, vertexIn, type, properties);
261 return Either.left(edge);
262 } catch (Exception e) {
263 log.debug("Failed to create edge from [{}] to [{}]", vertexOut, vertexIn, e);
264 return Either.right(TitanGraphClient.handleTitanException(e));
269 public TitanOperationStatus createEdge(TitanVertex vertexOut, GraphNode to, GraphEdgeLabels type, Map<String, Object> properties) {
271 TitanVertex vertexIn;
272 Either<Vertex, TitanOperationStatus> toV = getVertexByPropertyAndLabel(to.getUniqueIdKey(), to.getUniqueId(), to.getLabel());
274 TitanOperationStatus error = toV.right().value();
275 if (TitanOperationStatus.NOT_FOUND.equals(error)) {
276 return TitanOperationStatus.INVALID_ID;
281 vertexIn = (TitanVertex) toV.left().value();
282 return createEdge(vertexOut, vertexIn, type, properties);
293 public Either<GraphRelation, TitanOperationStatus> createRelation(GraphNode from, GraphNode to, GraphEdgeLabels label, Map<String, Object> properties) {
294 log.debug("try to create relation from [{}] to [{}]", from.getKeyValueId(), to.getKeyValueId());
295 return createEdge(label.getProperty(), from.getKeyValueId(), to.getKeyValueId(), from.getLabel(), to.getLabel(), properties);
298 public Either<GraphRelation, TitanOperationStatus> replaceRelationLabel(GraphNode from, GraphNode to, GraphEdgeLabels label, GraphEdgeLabels newLabel) {
300 log.debug("try to replace relation {} to {} from [{}] to [{}]", label.name(), newLabel.name(), from.getKeyValueId(), to.getKeyValueId());
301 Either<GraphRelation, TitanOperationStatus> getRelationResult = getRelation(from, to, label);
302 if (getRelationResult.isRight()) {
303 return getRelationResult;
306 GraphRelation origRelation = getRelationResult.left().value();
307 Either<GraphRelation, TitanOperationStatus> createRelationResult = createRelation(from, to, newLabel, origRelation.toGraphMap());
308 if (createRelationResult.isRight()) {
309 return createRelationResult;
312 Either<GraphRelation, TitanOperationStatus> deleteRelationResult = deleteRelation(origRelation);
313 if (deleteRelationResult.isRight()) {
314 return deleteRelationResult;
316 return Either.left(createRelationResult.left().value());
326 public <T extends GraphNode> Either<T, TitanOperationStatus> getNode(String keyName, Object keyValue, Class<T> clazz) {
328 log.debug("Try to get node for key [{}] with value [{}] ", keyName, keyValue);
330 Either<TitanVertex, TitanOperationStatus> vertexByProperty = getVertexByProperty(keyName, keyValue);
332 if (vertexByProperty.isLeft()) {
334 Vertex vertex = vertexByProperty.left().value();
335 Map<String, Object> properties = getProperties(vertex);
336 T node = GraphElementFactory.createElement((String) properties.get(GraphPropertiesDictionary.LABEL.getProperty()), GraphElementTypeEnum.Node, properties, clazz);
337 return Either.left(node);
338 } catch (Exception e) {
339 log.debug("Failed to get node for key [{}] with value [{}] ", keyName, keyValue, e);
340 return Either.right(TitanGraphClient.handleTitanException(e));
343 log.debug("Failed to get node for key [{}] with value [{}] ", keyName, keyValue, vertexByProperty.right().value());
344 return Either.right(vertexByProperty.right().value());
355 public Either<GraphRelation, TitanOperationStatus> getRelation(GraphNode from, GraphNode to, GraphEdgeLabels label) {
356 log.debug("try to get relation from [{}] to [{}]", from.getKeyValueId(), to.getKeyValueId());
358 Either<Edge, TitanOperationStatus> edge = getEdgeByNodes(from, to, label);
362 Map<String, Object> properties = getProperties(edge.left().value());
363 GraphRelation relation = GraphElementFactory.createRelation(label.getProperty(), properties, from, to);
364 return Either.left(relation);
365 } catch (Exception e) {
366 log.debug("Failed to get get relation from [{}] to [{}]", from.getKeyValueId(), to.getKeyValueId(), e);
367 return Either.right(TitanGraphClient.handleTitanException(e));
370 log.debug("Failed to get get relation from [{}] to [{}] {}", from.getKeyValueId(), to.getKeyValueId(), edge.right().value());
371 return Either.right(edge.right().value());
375 public Either<Edge, TitanOperationStatus> getEdgeByNodes(GraphNode from, GraphNode to, GraphEdgeLabels label) {
376 ImmutablePair<String, Object> keyValueIdFrom = from.getKeyValueId();
377 ImmutablePair<String, Object> keyValueIdTo = to.getKeyValueId();
379 return getEdgeByVerticies(keyValueIdFrom.getKey(), keyValueIdFrom.getValue(), keyValueIdTo.getKey(), keyValueIdTo.getValue(), label.getProperty());
382 public Either<GraphRelation, TitanOperationStatus> deleteIncomingRelationByCriteria(GraphNode to, GraphEdgeLabels label, Map<String, Object> props) {
384 Either<Edge, TitanOperationStatus> edgeByCriteria = getIncomingEdgeByCriteria(to, label, props);
385 if (edgeByCriteria.isLeft()) {
386 Either<TitanGraph, TitanOperationStatus> graph = getGraph();
387 if (graph.isLeft()) {
388 Edge edge = edgeByCriteria.left().value();
389 log.debug("delete edge {} to {} ", label.getProperty(), to.getUniqueId());
391 Map<String, Object> properties = getProperties(edge);
392 Vertex fromVertex = edge.outVertex();
393 String fromLabel = fromVertex.value(GraphPropertiesDictionary.LABEL.getProperty());
394 GraphNode nodeFrom = GraphElementFactory.createElement(fromLabel, GraphElementTypeEnum.Node, getProperties(fromVertex), GraphNode.class);
395 GraphRelation relation = GraphElementFactory.createRelation(label.getProperty(), properties, nodeFrom, to);
396 return Either.left(relation);
398 log.debug("failed to get graph");
399 return Either.right(graph.right().value());
403 log.debug("failed to find edge {} to {}", label.getProperty(), to.getUniqueId());
404 return Either.right(edgeByCriteria.right().value());
409 public Either<GraphRelation, TitanOperationStatus> getIncomingRelationByCriteria(GraphNode to, GraphEdgeLabels label, Map<String, Object> props) {
411 Either<Edge, TitanOperationStatus> edgeByCriteria = getIncomingEdgeByCriteria(to, label, props);
412 if (edgeByCriteria.isLeft()) {
413 Either<TitanGraph, TitanOperationStatus> graph = getGraph();
414 if (graph.isLeft()) {
415 Edge edge = edgeByCriteria.left().value();
416 Map<String, Object> properties = getProperties(edge);
417 Vertex fromVertex = edge.outVertex();
418 String fromLabel = fromVertex.value(GraphPropertiesDictionary.LABEL.getProperty());
419 GraphNode nodeFrom = GraphElementFactory.createElement(fromLabel, GraphElementTypeEnum.Node, getProperties(fromVertex), GraphNode.class);
420 GraphRelation relation = GraphElementFactory.createRelation(label.getProperty(), properties, nodeFrom, to);
421 return Either.left(relation);
423 log.debug("failed to get graph");
424 return Either.right(graph.right().value());
428 log.debug("failed to find edge {} to {}", label.getProperty(), to.getUniqueId());
429 return Either.right(edgeByCriteria.right().value());
434 public Either<Edge, TitanOperationStatus> getIncomingEdgeByCriteria(GraphNode to, GraphEdgeLabels label, Map<String, Object> props) {
436 ImmutablePair<String, Object> keyValueIdTo = to.getKeyValueId();
438 Either<TitanVertex, TitanOperationStatus> vertexFrom = getVertexByProperty(keyValueIdTo.getKey(), keyValueIdTo.getValue());
439 if (vertexFrom.isRight()) {
440 return Either.right(vertexFrom.right().value());
442 Vertex vertex = vertexFrom.left().value();
443 TitanVertex titanVertex = (TitanVertex) vertex;
444 TitanVertexQuery<?> query = titanVertex.query();
445 query = query.labels(label.getProperty());
447 if (props != null && !props.isEmpty()) {
448 for (Map.Entry<String, Object> entry : props.entrySet()) {
449 query = query.has(entry.getKey(), entry.getValue());
452 Edge matchingEdge = null;
453 Iterable<TitanEdge> edges = query.edges();
455 log.debug("No edges in graph for criteria");
456 return Either.right(TitanOperationStatus.NOT_FOUND);
458 Iterator<TitanEdge> eIter = edges.iterator();
459 if (eIter.hasNext()) {
460 matchingEdge = eIter.next();
463 if (matchingEdge == null) {
464 log.debug("No edges in graph for criteria");
465 return Either.right(TitanOperationStatus.NOT_FOUND);
467 return Either.left(matchingEdge);
470 public Either<Edge, TitanOperationStatus> getEdgeByVerticies(String keyNameFrom, Object keyValueFrom, String keyNameTo, Object keyValueTo, String label) {
471 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
473 if (graph.isLeft()) {
475 Either<TitanVertex, TitanOperationStatus> vertexFrom = getVertexByProperty(keyNameFrom, keyValueFrom);
476 if (vertexFrom.isRight()) {
477 return Either.right(vertexFrom.right().value());
479 Iterable<TitanEdge> edges = ((TitanVertex) vertexFrom.left().value()).query().labels(label).edges();
480 Iterator<TitanEdge> eIter = edges.iterator();
481 while (eIter.hasNext()) {
482 Edge edge = eIter.next();
483 Vertex vertexIn = edge.inVertex();
484 if (vertexIn.value(keyNameTo) != null && vertexIn.value(keyNameTo).equals(keyValueTo) && label.equals(edge.label())) {
485 return Either.left(edge);
488 log.debug("No relation in graph from [{}={}] to [{}={}]", keyNameFrom, keyValueFrom, keyNameTo, keyValueTo);
489 return Either.right(TitanOperationStatus.NOT_FOUND);
490 } catch (Exception e) {
491 log.debug("Failed to get get relation from [{}={}] to [{}={}]", keyNameFrom, keyValueFrom, keyNameTo, keyValueTo, e);
492 return Either.right(TitanGraphClient.handleTitanException(e));
495 return Either.right(graph.right().value());
499 public Either<List<Edge>, TitanOperationStatus> getEdgesForNode(GraphNode node, Direction requestedDirection) {
501 Either<List<Edge>, TitanOperationStatus> result;
503 ImmutablePair<String, Object> keyValueId = node.getKeyValueId();
504 Either<TitanVertex, TitanOperationStatus> eitherVertex = getVertexByProperty(keyValueId.getKey(), keyValueId.getValue());
506 if (eitherVertex.isLeft()) {
507 List<Edge> edges = prepareEdgesList(eitherVertex.left().value(), requestedDirection);
509 result = Either.left(edges);
511 result = Either.right(eitherVertex.right().value());
516 private List<Edge> prepareEdgesList(Vertex vertex, Direction requestedDirection) {
517 List<Edge> edges = new ArrayList<>();
518 Iterator<TitanEdge> edgesItr = ((TitanVertex) vertex).query().edges().iterator();
519 while (edgesItr.hasNext()) {
520 Edge edge = edgesItr.next();
521 Direction currEdgeDirection = getEdgeDirection(vertex, edge);
522 if (currEdgeDirection == requestedDirection || requestedDirection == Direction.BOTH) {
530 private Direction getEdgeDirection(Vertex vertex, Edge edge) {
532 Vertex vertexOut = edge.outVertex();
533 if (vertexOut.equals(vertex)) {
534 result = Direction.OUT;
536 result = Direction.IN;
550 public Either<GraphRelation, TitanOperationStatus> updateRelation(GraphNode from, GraphNode to, GraphEdgeLabels label, Map<String, Object> properties) {
551 log.debug("try to update relation from [{}] to [{}]", from.getKeyValueId(), to.getKeyValueId());
552 return updateEdge(label.getProperty(), from.getKeyValueId(), to.getKeyValueId(), from.getLabel(), to.getLabel(), properties);
555 private Either<GraphRelation, TitanOperationStatus> updateEdge(String type, ImmutablePair<String, Object> from, ImmutablePair<String, Object> to, String fromLabel, String toLabel, Map<String, Object> properties) {
557 Either<Edge, TitanOperationStatus> edgeS = getEdgeByVerticies(from.getKey(), from.getValue(), to.getKey(), to.getValue(), type);
558 if (edgeS.isLeft()) {
561 Edge edge = edgeS.left().value();
562 if (properties != null) {
563 setProperties(edge, properties);
566 Vertex vertexOut = edge.outVertex();
567 Vertex vertexIn = edge.inVertex();
569 GraphNode nodeOut = GraphElementFactory.createElement(fromLabel, GraphElementTypeEnum.Node, getProperties(vertexOut), GraphNode.class);
570 GraphNode nodeIn = GraphElementFactory.createElement(toLabel, GraphElementTypeEnum.Node, getProperties(vertexIn), GraphNode.class);
572 GraphRelation newRelation = GraphElementFactory.createRelation(edge.label(), getProperties(edge), nodeOut, nodeIn);
573 if (log.isDebugEnabled()) {
574 log.debug("Relation was updated from [{}] to [{}] ", from, to);
576 return Either.left(newRelation);
577 } catch (Exception e) {
578 if (log.isDebugEnabled()) {
579 log.debug("Failed to update relation from [{}] to [{}] ", from, to, e);
581 return Either.right(TitanGraphClient.handleTitanException(e));
584 if (log.isDebugEnabled()) {
585 log.debug("Failed to update relation from [{}] to [{}] {}", from, to, edgeS.right().value());
587 return Either.right(edgeS.right().value());
596 public Either<GraphRelation, TitanOperationStatus> updateRelation(GraphRelation relation) {
597 log.debug("try to update relation from [{}] to [{}]", relation.getFrom(), relation.getTo());
598 RelationEndPoint from = relation.getFrom();
599 RelationEndPoint to = relation.getTo();
600 ImmutablePair<String, Object> fromKeyId = new ImmutablePair<>(from.getIdName(), from.getIdValue());
601 ImmutablePair<String, Object> toKeyId = new ImmutablePair<>(to.getIdName(), to.getIdValue());
603 return updateEdge(relation.getType(), fromKeyId, toKeyId, from.getLabel().getName(), to.getLabel().getName(), relation.toGraphMap());
607 private Either<Vertex, TitanOperationStatus> getVertexByPropertyAndLabel(String name, Object value, String label) {
609 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
610 if (graph.isLeft()) {
612 TitanGraph tGraph = graph.left().value();
614 @SuppressWarnings("unchecked")
615 Iterable<TitanVertex> vertecies = tGraph.query().has(name, value).has(GraphPropertiesDictionary.LABEL.getProperty(), label).vertices();
617 java.util.Iterator<TitanVertex> iterator = vertecies.iterator();
618 if (iterator.hasNext()) {
619 Vertex vertex = iterator.next();
620 return Either.left(vertex);
622 if (log.isDebugEnabled()) {
623 log.debug("No vertex in graph for key =" + name + " and value = " + value + " label = " + label);
625 return Either.right(TitanOperationStatus.NOT_FOUND);
626 } catch (Exception e) {
627 if (log.isDebugEnabled()) {
628 log.debug("Failed to get vertex in graph for key ={} and value = {} label = {}",name,value,label);
630 return Either.right(TitanGraphClient.handleTitanException(e));
634 if (log.isDebugEnabled()) {
635 log.debug("No vertex in graph for key ={} and value = {} label = {} error : {}",name,value,label,graph.right().value());
637 return Either.right(graph.right().value());
641 public Either<TitanVertex, TitanOperationStatus> getVertexByProperty(String name, Object value) {
643 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
645 if (log.isDebugEnabled()) {
646 log.debug("No vertex in graph for key = {} and value = {}", name, value);
648 return Either.right(TitanOperationStatus.NOT_FOUND);
650 if (graph.isLeft()) {
652 TitanGraph tGraph = graph.left().value();
654 @SuppressWarnings("unchecked")
655 Iterable<TitanVertex> vertecies = tGraph.query().has(name, value).vertices();
657 java.util.Iterator<TitanVertex> iterator = vertecies.iterator();
658 if (iterator.hasNext()) {
659 TitanVertex vertex = iterator.next();
660 return Either.left(vertex);
662 if (log.isDebugEnabled()) {
663 log.debug("No vertex in graph for key ={} and value = {}", name, value);
665 return Either.right(TitanOperationStatus.NOT_FOUND);
667 } catch (Exception e) {
668 if (log.isDebugEnabled()) {
669 log.debug("Failed to get vertex in graph for key = {} and value = ", name, value);
671 return Either.right(TitanGraphClient.handleTitanException(e));
674 if (log.isDebugEnabled()) {
675 log.debug("No vertex in graph for key = {} and value = {} error : {}", name, value, graph.right().value());
677 return Either.right(graph.right().value());
681 public <T extends GraphNode> Either<List<T>, TitanOperationStatus> getByCriteria(NodeTypeEnum type, Map<String, Object> hasProps, Map<String, Object> hasNotProps, Class<T> clazz) {
682 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
683 if (graph.isLeft()) {
685 TitanGraph tGraph = graph.left().value();
687 TitanGraphQuery<? extends TitanGraphQuery> query = tGraph.query();
688 query = query.has(GraphPropertiesDictionary.LABEL.getProperty(), type.getName());
690 if (hasProps != null && !hasProps.isEmpty()) {
691 for (Map.Entry<String, Object> entry : hasProps.entrySet()) {
692 query = query.has(entry.getKey(), entry.getValue());
695 if (hasNotProps != null && !hasNotProps.isEmpty()) {
696 for (Map.Entry<String, Object> entry : hasNotProps.entrySet()) {
697 query = query.hasNot(entry.getKey(), entry.getValue());
700 Iterable<TitanVertex> vertices = query.vertices();
701 if (vertices == null) {
702 return Either.right(TitanOperationStatus.NOT_FOUND);
705 Iterator<TitanVertex> iterator = vertices.iterator();
706 List<T> result = new ArrayList<>();
708 while (iterator.hasNext()) {
709 Vertex vertex = iterator.next();
711 Map<String, Object> newProp = getProperties(vertex);
713 T element = GraphElementFactory.createElement(type.getName(), GraphElementTypeEnum.Node, newProp, clazz);
716 if (log.isDebugEnabled()) {
717 log.debug("Number of fetced nodes in graph for criteria : from type = {} and properties has = {}, properties hasNot = {} is {}", type, hasProps, hasNotProps, result.size());
719 if (result.size() == 0) {
720 return Either.right(TitanOperationStatus.NOT_FOUND);
723 return Either.left(result);
724 } catch (Exception e) {
725 if (log.isDebugEnabled()) {
726 log.debug("Failed get by criteria for type = {}", type, e);
728 return Either.right(TitanGraphClient.handleTitanException(e));
732 if (log.isDebugEnabled()) {
733 log.debug("Failed get by criteria for type ={} error : {}", type, graph.right().value());
735 return Either.right(graph.right().value());
739 public <T extends GraphNode> Either<List<T>, TitanOperationStatus> getByCriteria(NodeTypeEnum type, Class<T> clazz, List<ImmutableTriple<QueryType, String, Object>> props) {
740 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
741 if (graph.isLeft()) {
743 TitanGraph tGraph = graph.left().value();
745 TitanGraphQuery<? extends TitanGraphQuery> query = tGraph.query();
746 query = query.has(GraphPropertiesDictionary.LABEL.getProperty(), type.getName());
747 for (ImmutableTriple<QueryType, String, Object> prop : props) {
748 if (QueryType.HAS.equals(prop.getLeft())) {
749 query = query.has(prop.getMiddle(), prop.getRight());
751 query = query.hasNot(prop.getMiddle(), prop.getRight());
754 Iterable<TitanVertex> vertices = query.vertices();
755 if (vertices == null) {
756 return Either.right(TitanOperationStatus.NOT_FOUND);
759 Iterator<TitanVertex> iterator = vertices.iterator();
760 List<T> result = new ArrayList<>();
762 while (iterator.hasNext()) {
763 Vertex vertex = iterator.next();
765 Map<String, Object> newProp = getProperties(vertex);
767 T element = GraphElementFactory.createElement(type.getName(), GraphElementTypeEnum.Node, newProp, clazz);
770 if (result.size() == 0) {
771 return Either.right(TitanOperationStatus.NOT_FOUND);
774 return Either.left(result);
775 } catch (Exception e) {
776 if (log.isDebugEnabled()) {
777 log.debug("Failed get by criteria for type = {}", type, e);
779 return Either.right(TitanGraphClient.handleTitanException(e));
783 if (log.isDebugEnabled()) {
784 log.debug("Failed get by criteria for type ={} error : {}", type, graph.right().value());
786 return Either.right(graph.right().value());
790 public <T extends GraphNode> Either<List<T>, TitanOperationStatus> getByCriteria(NodeTypeEnum type, Map<String, Object> props, Class<T> clazz) {
791 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
792 if (graph.isLeft()) {
794 TitanGraph tGraph = graph.left().value();
796 TitanGraphQuery<? extends TitanGraphQuery> query = tGraph.query();
797 query = query.has(GraphPropertiesDictionary.LABEL.getProperty(), type.getName());
799 if (props != null && !props.isEmpty()) {
800 for (Map.Entry<String, Object> entry : props.entrySet()) {
801 query = query.has(entry.getKey(), entry.getValue());
804 Iterable<TitanVertex> vertices = query.vertices();
805 if (vertices == null) {
806 return Either.right(TitanOperationStatus.NOT_FOUND);
809 Iterator<TitanVertex> iterator = vertices.iterator();
810 List<T> result = new ArrayList<>();
812 while (iterator.hasNext()) {
813 Vertex vertex = iterator.next();
815 Map<String, Object> newProp = getProperties(vertex);
817 T element = GraphElementFactory.createElement(type.getName(), GraphElementTypeEnum.Node, newProp, clazz);
820 if (log.isDebugEnabled()) {
821 log.debug("Number of fetced nodes in graph for criteria : from type = {} and properties = {} is {}", type, props, result.size());
823 if (result.size() == 0) {
824 return Either.right(TitanOperationStatus.NOT_FOUND);
827 return Either.left(result);
828 } catch (Exception e) {
829 if (log.isDebugEnabled()) {
830 log.debug("Failed get by criteria for type = {} and properties = {}", type, props, e);
832 return Either.right(TitanGraphClient.handleTitanException(e));
836 if (log.isDebugEnabled()) {
837 log.debug("Failed get by criteria for type ={} and properties = {} error : {}", type, props, graph.right().value());
839 return Either.right(graph.right().value());
843 public <T extends GraphNode> Either<List<T>, TitanOperationStatus> getByCriteriaWithPredicate(NodeTypeEnum type, Map<String, Entry<TitanPredicate, Object>> props, Class<T> clazz) {
844 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
845 if (graph.isLeft()) {
847 TitanGraph tGraph = graph.left().value();
849 TitanGraphQuery<? extends TitanGraphQuery> query = tGraph.query();
850 query = query.has(GraphPropertiesDictionary.LABEL.getProperty(), type.getName());
852 if (props != null && !props.isEmpty()) {
853 TitanPredicate predicate = null;
854 Object object = null;
855 for (Map.Entry<String, Entry<TitanPredicate, Object>> entry : props.entrySet()) {
856 predicate = entry.getValue().getKey();
857 object = entry.getValue().getValue();
858 query = query.has(entry.getKey(), predicate, object);
861 Iterable<TitanVertex> vertices = query.vertices();
862 if (vertices == null) {
863 return Either.right(TitanOperationStatus.NOT_FOUND);
866 Iterator<TitanVertex> iterator = vertices.iterator();
867 List<T> result = new ArrayList<>();
869 while (iterator.hasNext()) {
870 Vertex vertex = iterator.next();
872 Map<String, Object> newProp = getProperties(vertex);
873 T element = GraphElementFactory.createElement(type.getName(), GraphElementTypeEnum.Node, newProp, clazz);
876 if (result.size() == 0) {
877 return Either.right(TitanOperationStatus.NOT_FOUND);
879 if (log.isDebugEnabled()) {
880 log.debug("No nodes in graph for criteria : from type = {} and properties = {}", type, props);
882 return Either.left(result);
883 } catch (Exception e) {
884 if (log.isDebugEnabled()) {
885 log.debug("Failed get by criteria for type = {} and properties = {}", type, props, e);
887 return Either.right(TitanGraphClient.handleTitanException(e));
891 if (log.isDebugEnabled()) {
892 log.debug("Failed get by criteria for type = {} and properties = {} error : {}", type, props, graph.right().value());
894 return Either.right(graph.right().value());
898 public <T extends GraphNode> Either<List<T>, TitanOperationStatus> getAll(NodeTypeEnum type, Class<T> clazz) {
899 return getByCriteria(type, null, clazz);
908 public <T extends GraphNode> Either<T, TitanOperationStatus> updateNode(GraphNode node, Class<T> clazz) {
909 log.debug("Try to update node for {}", node.getKeyValueId());
911 ImmutablePair<String, Object> keyValueId = node.getKeyValueId();
912 Either<Vertex, TitanOperationStatus> vertexByProperty = getVertexByPropertyAndLabel(keyValueId.getKey(), keyValueId.getValue(), node.getLabel());
914 if (vertexByProperty.isLeft()) {
916 Vertex vertex = vertexByProperty.left().value();
918 Map<String, Object> mapProps = node.toGraphMap();
920 for (Map.Entry<String, Object> entry : mapProps.entrySet()) {
921 if (!entry.getKey().equals(node.getUniqueIdKey())) {
922 vertex.property(entry.getKey(), entry.getValue());
926 Either<Vertex, TitanOperationStatus> vertexByPropertyAndLabel = getVertexByPropertyAndLabel(keyValueId.getKey(), keyValueId.getValue(), node.getLabel());
927 if (vertexByPropertyAndLabel.isRight()) {
928 return Either.right(vertexByPropertyAndLabel.right().value());
930 Map<String, Object> newProp = getProperties(vertexByPropertyAndLabel.left().value());
931 T updateNode = GraphElementFactory.createElement(node.getLabel(), GraphElementTypeEnum.Node, newProp, clazz);
932 return Either.left(updateNode);
934 } catch (Exception e) {
935 if (log.isDebugEnabled()) {
936 log.debug("Failed to update node for {}", node.getKeyValueId(), e);
938 return Either.right(TitanGraphClient.handleTitanException(e));
941 if (log.isDebugEnabled()) {
942 log.debug("Failed to update node for {} error :{}", node.getKeyValueId(), vertexByProperty.right().value());
944 return Either.right(vertexByProperty.right().value());
949 public TitanOperationStatus updateVertex(GraphNode node, Vertex vertex) {
950 log.debug("Try to update node for {}", node.getKeyValueId());
953 Map<String, Object> mapProps = node.toGraphMap();
955 for (Map.Entry<String, Object> entry : mapProps.entrySet()) {
956 if (!entry.getKey().equals(node.getUniqueIdKey())) {
957 vertex.property(entry.getKey(), entry.getValue());
961 } catch (Exception e) {
962 if (log.isDebugEnabled()) {
963 log.debug("Failed to update node for {}", node.getKeyValueId(), e);
965 return TitanGraphClient.handleTitanException(e);
967 return TitanOperationStatus.OK;
977 public <T extends GraphNode> Either<T, TitanOperationStatus> deleteNode(GraphNode node, Class<T> clazz) {
978 log.debug("Try to delete node for {}", node.getKeyValueId());
979 ImmutablePair<String, Object> keyValueId = node.getKeyValueId();
980 return deleteNode(keyValueId.getKey(), keyValueId.getValue(), clazz);
990 public <T extends GraphNode> Either<T, TitanOperationStatus> deleteNode(String keyName, Object keyValue, Class<T> clazz) {
991 Either<TitanVertex, TitanOperationStatus> vertexByProperty = getVertexByProperty(keyName, keyValue);
993 if (vertexByProperty.isLeft()) {
995 Vertex vertex = vertexByProperty.left().value();
997 Map<String, Object> properties = getProperties(vertex);
998 if (properties != null) {
999 String label = (String) properties.get(GraphPropertiesDictionary.LABEL.getProperty());
1001 T node = GraphElementFactory.createElement(label, GraphElementTypeEnum.Node, properties, clazz);
1003 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
1004 if (graph.isLeft()) {
1005 TitanGraph tGraph = graph.left().value();
1008 return Either.right(graph.right().value());
1010 return Either.left(node);
1012 if (log.isDebugEnabled()) {
1013 log.debug("Failed to delete node for {} = {} Missing label property on node", keyName, keyValue);
1015 return Either.right(TitanOperationStatus.MISSING_NODE_LABEL);
1018 if (log.isDebugEnabled()) {
1019 log.debug("Failed to delete node for {} = {} Missing label property on node", keyName, keyValue);
1021 return Either.right(TitanOperationStatus.MISSING_NODE_LABEL);
1023 } catch (Exception e) {
1024 if (log.isDebugEnabled()) {
1025 log.debug("Failed to delete node for {} = {}", keyName, keyValue, e);
1027 return Either.right(TitanGraphClient.handleTitanException(e));
1031 return Either.right(vertexByProperty.right().value());
1035 public Either<GraphRelation, TitanOperationStatus> deleteRelation(GraphRelation relation) {
1036 log.debug("try to delete relation from [{}] to [{}]", relation.getFrom(), relation.getTo());
1037 RelationEndPoint from = relation.getFrom();
1038 RelationEndPoint to = relation.getTo();
1039 ImmutablePair<String, Object> fromKeyId = new ImmutablePair<>(from.getIdName(), from.getIdValue());
1040 ImmutablePair<String, Object> toKeyId = new ImmutablePair<>(to.getIdName(), to.getIdValue());
1042 return deleteEdge(relation.getType(), fromKeyId, toKeyId, from.getLabel().getName(), to.getLabel().getName());
1046 public Either<Boolean, TitanOperationStatus> isRelationExist(GraphNode from, GraphNode to, GraphEdgeLabels edgeLabel) {
1047 return getEdgeByNodes(from, to, edgeLabel)
1051 .bind(err -> err == TitanOperationStatus.NOT_FOUND ? Either.left(false): Either.right(err));
1054 public Either<GraphRelation, TitanOperationStatus> deleteRelation(GraphNode from, GraphNode to, GraphEdgeLabels label) {
1055 log.debug("try to delete relation from [{}] to [{}]", from.getKeyValueId(), to.getKeyValueId());
1056 return deleteEdge(label.getProperty(), from.getKeyValueId(), to.getKeyValueId(), from.getLabel(), to.getLabel());
1059 private Either<GraphRelation, TitanOperationStatus> deleteEdge(String type, ImmutablePair<String, Object> fromKeyId, ImmutablePair<String, Object> toKeyId, String fromLabel, String toLabel) {
1060 Either<Edge, TitanOperationStatus> edgeS = getEdgeByVerticies(fromKeyId.getKey(), fromKeyId.getValue(), toKeyId.getKey(), toKeyId.getValue(), type);
1061 if (edgeS.isLeft()) {
1063 Edge edge = edgeS.left().value();
1065 Vertex vertexOut = edge.outVertex();
1066 Vertex vertexIn = edge.inVertex();
1068 GraphNode nodeOut = GraphElementFactory.createElement(fromLabel, GraphElementTypeEnum.Node, getProperties(vertexOut), GraphNode.class);
1069 GraphNode nodeIn = GraphElementFactory.createElement(toLabel, GraphElementTypeEnum.Node, getProperties(vertexIn), GraphNode.class);
1071 GraphRelation newRelation = GraphElementFactory.createRelation(edge.label(), getProperties(edge), nodeOut, nodeIn);
1073 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
1075 if (graph.isLeft()) {
1079 if (log.isDebugEnabled()) {
1080 log.debug("Failed to delete relation {} from {} to {} error : {}",type,fromKeyId,toKeyId,graph.right().value());
1082 return Either.right(graph.right().value());
1084 return Either.left(newRelation);
1085 } catch (Exception e) {
1086 if (log.isDebugEnabled()) {
1087 log.debug("Failed to delete relation {} from {} to {}", type, fromKeyId, toKeyId, e);
1089 return Either.right(TitanGraphClient.handleTitanException(e));
1092 if (log.isDebugEnabled()) {
1093 log.debug("Failed to delete relation {} from {} to {} error : {}", type, fromKeyId, toKeyId, edgeS.right().value());
1095 return Either.right(edgeS.right().value());
1099 public void setTitanGraphClient(TitanGraphClient titanGraphClient) {
1100 this.titanClient = titanGraphClient;
1103 public Either<GraphRelation, TitanOperationStatus> deleteIncomingRelation(GraphRelation relation) {
1105 RelationEndPoint to = relation.getTo();
1106 ImmutablePair<String, Object> toKeyId = new ImmutablePair<>(to.getIdName(), to.getIdValue());
1108 return deleteIncomingEdge(relation.getType(), toKeyId);
1112 private Either<GraphRelation, TitanOperationStatus> deleteIncomingEdge(String type, ImmutablePair<String, Object> toKeyId) {
1114 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
1116 if (graph.isLeft()) {
1117 Either<TitanVertex, TitanOperationStatus> rootVertexResult = getVertexByProperty(toKeyId.getKey(), toKeyId.getValue());
1118 if (rootVertexResult.isLeft()) {
1119 Vertex rootVertex = rootVertexResult.left().value();
1120 Iterator<Edge> edgesIterator = rootVertex.edges(Direction.IN, type);
1121 if (edgesIterator != null) {
1125 if (edgesIterator.hasNext()) {
1126 edge = edgesIterator.next();
1127 if (edgesIterator.hasNext()) {
1128 return Either.right(TitanOperationStatus.MULTIPLE_EDGES_WITH_SAME_LABEL);
1131 return Either.right(TitanOperationStatus.NOT_FOUND);
1134 log.debug("Find the tail vertex of the edge of type {} to vertex {}", type, toKeyId);
1135 Vertex vertexOut = edge.outVertex();
1136 String fromLabel = vertexOut.value(GraphPropertiesDictionary.LABEL.getProperty());
1137 String toLabel = rootVertex.value(GraphPropertiesDictionary.LABEL.getProperty());
1138 log.debug("The label of the outgoing vertex is {}", fromLabel);
1139 GraphNode nodeOut = GraphElementFactory.createElement(fromLabel, GraphElementTypeEnum.Node, getProperties(vertexOut), GraphNode.class);
1141 GraphNode nodeIn = GraphElementFactory.createElement(toLabel, GraphElementTypeEnum.Node, getProperties(rootVertex), GraphNode.class);
1143 GraphRelation newRelation = GraphElementFactory.createRelation(edge.label(), getProperties(edge), nodeOut, nodeIn);
1147 return Either.left(newRelation);
1150 return Either.right(TitanOperationStatus.NOT_FOUND);
1154 return Either.right(graph.right().value());
1158 return Either.right(graph.right().value());
1163 public Either<GraphRelation, TitanOperationStatus> deleteOutgoingRelation(GraphRelation relation) {
1165 RelationEndPoint from = relation.getFrom();
1166 ImmutablePair<String, Object> fromKeyId = new ImmutablePair<>(from.getIdName(), from.getIdValue());
1168 return deleteOutgoingEdge(relation.getType(), fromKeyId);
1172 private Either<GraphRelation, TitanOperationStatus> deleteOutgoingEdge(String type, ImmutablePair<String, Object> toKeyId) {
1174 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
1176 if (graph.isLeft()) {
1177 Either<TitanVertex, TitanOperationStatus> rootVertexResult = getVertexByProperty(toKeyId.getKey(), toKeyId.getValue());
1178 if (rootVertexResult.isLeft()) {
1179 Vertex rootVertex = rootVertexResult.left().value();
1180 Iterator<Edge> edgesIterator = rootVertex.edges(Direction.OUT, type);
1181 if (edgesIterator != null) {
1185 if (edgesIterator.hasNext()) {
1186 edge = edgesIterator.next();
1187 if (edgesIterator.hasNext()) {
1188 return Either.right(TitanOperationStatus.MULTIPLE_EDGES_WITH_SAME_LABEL);
1191 return Either.right(TitanOperationStatus.NOT_FOUND);
1194 log.debug("Find the tail vertex of the edge of type {} to vertex ", type, toKeyId);
1195 Vertex vertexIn = edge.inVertex();
1196 String toLabel = vertexIn.value(GraphPropertiesDictionary.LABEL.getProperty());
1197 String fromLabel = rootVertex.value(GraphPropertiesDictionary.LABEL.getProperty());
1198 log.debug("The label of the tail vertex is {}", toLabel);
1199 GraphNode nodeFrom = GraphElementFactory.createElement(fromLabel, GraphElementTypeEnum.Node, getProperties(rootVertex), GraphNode.class);
1201 GraphNode nodeTo = GraphElementFactory.createElement(toLabel, GraphElementTypeEnum.Node, getProperties(vertexIn), GraphNode.class);
1203 GraphRelation newRelation = GraphElementFactory.createRelation(edge.label(), getProperties(edge), nodeFrom, nodeTo);
1207 return Either.left(newRelation);
1210 return Either.right(TitanOperationStatus.NOT_FOUND);
1214 return Either.right(graph.right().value());
1218 return Either.right(graph.right().value());
1228 public TitanOperationStatus lockElement(String id, NodeTypeEnum type) {
1230 StringBuffer lockId = new StringBuffer(LOCK_NODE_PREFIX);
1231 lockId.append(type.getName()).append("_").append(id);
1232 return lockNode(lockId.toString());
1235 public TitanOperationStatus lockElement(GraphNode node) {
1237 StringBuffer lockId = createLockElementId(node);
1239 return lockNode(lockId.toString());
1242 private TitanOperationStatus lockNode(String lockId) {
1243 TitanOperationStatus status = TitanOperationStatus.OK;
1245 GraphNodeLock lockNode = new GraphNodeLock(lockId);
1247 Either<GraphNodeLock, TitanOperationStatus> lockNodeNew = createNode(lockNode, GraphNodeLock.class);
1248 if (lockNodeNew.isLeft()) {
1249 log.debug("before commit, Lock node created for {}", lockId);
1250 return titanClient.commit();
1252 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
1253 if (graph.isLeft()) {
1254 TitanGraph tGraph = graph.left().value();
1255 Either<TitanVertex, TitanOperationStatus> vertex = getVertexByProperty(lockNode.getUniqueIdKey(), lockNode.getUniqueId());
1256 if (vertex.isLeft()) {
1257 status = relockNode(lockNode, lockNodeNew, tGraph, vertex);
1259 status = vertex.right().value();
1262 status = graph.right().value();
1268 private TitanOperationStatus relockNode(GraphNodeLock lockNode, Either<GraphNodeLock, TitanOperationStatus> lockNodeNew, TitanGraph tGraph, Either<TitanVertex, TitanOperationStatus> vertex) {
1269 TitanOperationStatus status = TitanOperationStatus.OK;
1270 Long time = vertex.left().value().value(GraphPropertiesDictionary.CREATION_DATE.getProperty());
1271 Long lockTimeout = ConfigurationManager.getConfigurationManager().getConfiguration().getTitanLockTimeout();
1272 if (time + lockTimeout * 1000 < System.currentTimeMillis()) {
1273 log.debug("Found not released lock node with id {}", lockNode.getUniqueId());
1274 vertex.left().value().remove();
1275 lockNodeNew = createNode(lockNode, GraphNodeLock.class);
1276 if (lockNodeNew.isLeft()) {
1277 log.debug("Lock node created for {}", lockNode.getUniqueIdKey());
1278 return titanClient.commit();
1280 log.debug("Failed Lock node for {} . Commit transacton for deleted previous vertex .", lockNode.getUniqueIdKey());
1281 titanClient.commit();
1282 status = checkLockError(lockNode.getUniqueIdKey(), lockNodeNew);
1285 log.debug("Failed Lock node for {} rollback transacton", lockNode.getUniqueIdKey());
1286 titanClient.rollback();
1287 status = checkLockError(lockNode.getUniqueIdKey(), lockNodeNew);
1292 public <T extends GraphNode> Either<List<ImmutablePair<T, GraphEdge>>, TitanOperationStatus> getChildrenNodes(String key, String uniqueId, GraphEdgeLabels edgeType, NodeTypeEnum nodeTypeEnum, Class<T> clazz, boolean withEdges) {
1294 List<ImmutablePair<T, GraphEdge>> immutablePairs = new ArrayList<>();
1296 Either<TitanGraph, TitanOperationStatus> graphRes = titanClient.getGraph();
1297 if (graphRes.isRight()) {
1298 log.error("Failed to retrieve graph. status is {}", graphRes);
1299 return Either.right(graphRes.right().value());
1302 TitanGraph titanGraph = graphRes.left().value();
1303 @SuppressWarnings("unchecked")
1304 Iterable<TitanVertex> vertices = titanGraph.query().has(key, uniqueId).vertices();
1305 if (vertices == null || !vertices.iterator().hasNext()) {
1306 return Either.right(TitanOperationStatus.INVALID_ID);
1309 Vertex rootVertex = vertices.iterator().next();
1311 Iterator<Edge> edgesCreatorIterator = rootVertex.edges(Direction.OUT, edgeType.getProperty());
1312 if (edgesCreatorIterator != null) {
1313 while (edgesCreatorIterator.hasNext()) {
1314 Edge edge = edgesCreatorIterator.next();
1315 GraphEdge graphEdge = null;
1318 Map<String, Object> edgeProps = getProperties(edge);
1319 GraphEdgeLabels edgeTypeFromGraph = GraphEdgeLabels.getByName(edge.label());
1320 graphEdge = new GraphEdge(edgeTypeFromGraph, edgeProps);
1323 Vertex outgoingVertex = edge.inVertex();
1324 Map<String, Object> properties = getProperties(outgoingVertex);
1325 T data = GraphElementFactory.createElement(nodeTypeEnum.getName(), GraphElementTypeEnum.Node, properties, clazz);
1327 ImmutablePair<T, GraphEdge> immutablePair = new ImmutablePair<>(clazz.cast(data), graphEdge);
1328 immutablePairs.add(immutablePair);
1332 if (immutablePairs.isEmpty()) {
1333 return Either.right(TitanOperationStatus.NOT_FOUND);
1336 return Either.left(immutablePairs);
1340 public Either<List<ImmutablePair<TitanVertex, Edge>>, TitanOperationStatus> getChildrenVertecies(String key, String uniqueId, GraphEdgeLabels edgeType) {
1342 List<ImmutablePair<TitanVertex, Edge>> immutablePairs = new ArrayList<>();
1344 Either<TitanGraph, TitanOperationStatus> graphRes = titanClient.getGraph();
1345 if (graphRes.isRight()) {
1346 log.error("Failed to retrieve graph. status is {}", graphRes);
1347 return Either.right(graphRes.right().value());
1350 TitanGraph titanGraph = graphRes.left().value();
1351 @SuppressWarnings("unchecked")
1352 Iterable<TitanVertex> vertices = titanGraph.query().has(key, uniqueId).vertices();
1353 if (vertices == null || !vertices.iterator().hasNext()) {
1354 return Either.right(TitanOperationStatus.INVALID_ID);
1357 Vertex rootVertex = vertices.iterator().next();
1359 Iterator<Edge> edgesCreatorIterator = rootVertex.edges(Direction.OUT, edgeType.getProperty());
1360 if (edgesCreatorIterator != null) {
1361 while (edgesCreatorIterator.hasNext()) {
1362 Edge edge = edgesCreatorIterator.next();
1363 TitanVertex vertex = (TitanVertex) edge.inVertex();
1365 ImmutablePair<TitanVertex, Edge> immutablePair = new ImmutablePair<>(vertex, edge);
1366 immutablePairs.add(immutablePair);
1369 if (immutablePairs.isEmpty()) {
1370 return Either.right(TitanOperationStatus.NOT_FOUND);
1373 return Either.left(immutablePairs);
1377 public <T extends GraphNode> Either<List<ImmutablePair<T, GraphEdge>>, TitanOperationStatus> getChildrenNodes(String key, String uniqueId, GraphEdgeLabels edgeType, NodeTypeEnum nodeTypeEnum, Class<T> clazz) {
1378 return this.getChildrenNodes(key, uniqueId, edgeType, nodeTypeEnum, clazz, true);
1381 private TitanOperationStatus checkLockError(String lockId, Either<GraphNodeLock, TitanOperationStatus> lockNodeNew) {
1382 TitanOperationStatus status;
1383 TitanOperationStatus error = lockNodeNew.right().value();
1384 log.debug("Failed to Lock node for {} error = {}", lockId, error);
1385 if (error.equals(TitanOperationStatus.TITAN_SCHEMA_VIOLATION) || error.equals(TitanOperationStatus.ILLEGAL_ARGUMENT)) {
1386 status = TitanOperationStatus.ALREADY_LOCKED;
1398 public TitanOperationStatus releaseElement(GraphNode node) {
1399 StringBuffer lockId = createLockElementId(node);
1401 return unlockNode(lockId);
1404 private TitanOperationStatus unlockNode(StringBuffer lockId) {
1405 GraphNodeLock lockNode = new GraphNodeLock(lockId.toString());
1407 Either<GraphNodeLock, TitanOperationStatus> lockNodeNew = deleteNode(lockNode, GraphNodeLock.class);
1408 if (lockNodeNew.isLeft()) {
1409 log.debug("Lock node released for lock id = {}", lockId);
1410 return titanClient.commit();
1412 titanClient.rollback();
1413 TitanOperationStatus error = lockNodeNew.right().value();
1414 log.debug("Failed to Release node for lock id {} error = {}", lockId, error);
1419 public TitanOperationStatus releaseElement(String id, NodeTypeEnum type) {
1420 StringBuffer lockId = new StringBuffer(LOCK_NODE_PREFIX);
1421 lockId.append(type.getName()).append("_").append(id);
1422 return unlockNode(lockId);
1425 private StringBuffer createLockElementId(GraphNode node) {
1426 StringBuffer lockId = new StringBuffer(LOCK_NODE_PREFIX);
1427 lockId.append(node.getLabel()).append("_").append(node.getUniqueId());
1431 public <T extends GraphNode> Either<ImmutablePair<T, GraphEdge>, TitanOperationStatus> getChild(String key, String uniqueId, GraphEdgeLabels edgeType, NodeTypeEnum nodeTypeEnum, Class<T> clazz) {
1433 Either<List<ImmutablePair<T, GraphEdge>>, TitanOperationStatus> childrenNodes = getChildrenNodes(key, uniqueId, edgeType, nodeTypeEnum, clazz);
1435 if (childrenNodes.isRight()) {
1436 return Either.right(childrenNodes.right().value());
1439 List<ImmutablePair<T, GraphEdge>> value = childrenNodes.left().value();
1441 if (value.size() > 1) {
1442 return Either.right(TitanOperationStatus.MULTIPLE_CHILDS_WITH_SAME_EDGE);
1445 return Either.left(value.get(0));
1449 public ImmutablePair<TitanVertex, Edge> getChildVertex(TitanVertex vertex, GraphEdgeLabels edgeType) {
1451 ImmutablePair<TitanVertex, Edge> pair = null;
1452 Iterator<Edge> edges = vertex.edges(Direction.OUT, edgeType.getProperty());
1453 if (edges.hasNext()) {
1454 // get only first edge
1455 Edge edge = edges.next();
1456 pair = new ImmutablePair<>((TitanVertex) edge.inVertex(), edge);
1461 public <T extends GraphNode> Either<List<ImmutablePair<T, GraphEdge>>, TitanOperationStatus> getParentNodes(String key, String uniqueId, GraphEdgeLabels edgeType, NodeTypeEnum nodeTypeEnum, Class<T> clazz) {
1463 List<ImmutablePair<T, GraphEdge>> immutablePairs = new ArrayList<>();
1466 GraphEdge graphEdge = null;
1468 Either<TitanGraph, TitanOperationStatus> graphRes = titanClient.getGraph();
1469 if (graphRes.isRight()) {
1470 log.error("Failed to retrieve graph. status is {}", graphRes);
1471 return Either.right(graphRes.right().value());
1474 TitanGraph titanGraph = graphRes.left().value();
1475 @SuppressWarnings("unchecked")
1476 Iterable<TitanVertex> vertices = titanGraph.query().has(key, uniqueId).vertices();
1477 if (vertices == null || !vertices.iterator().hasNext()) {
1478 return Either.right(TitanOperationStatus.INVALID_ID);
1481 Vertex rootVertex = vertices.iterator().next();
1483 Iterator<Edge> edgesCreatorIterator = rootVertex.edges(Direction.IN, edgeType.name());
1484 if (edgesCreatorIterator != null) {
1485 while (edgesCreatorIterator.hasNext()) {
1486 Edge edge = edgesCreatorIterator.next();
1487 Map<String, Object> edgeProps = getProperties(edge);
1488 GraphEdgeLabels edgeTypeFromGraph = GraphEdgeLabels.getByName(edge.label());
1489 graphEdge = new GraphEdge(edgeTypeFromGraph, edgeProps);
1491 Vertex outgoingVertex = edge.outVertex();
1492 Map<String, Object> properties = getProperties(outgoingVertex);
1493 data = GraphElementFactory.createElement(nodeTypeEnum.getName(), GraphElementTypeEnum.Node, properties, clazz);
1495 ImmutablePair<T, GraphEdge> immutablePair = new ImmutablePair<>(clazz.cast(data), graphEdge);
1496 immutablePairs.add(immutablePair);
1500 if (immutablePairs.isEmpty()) {
1501 return Either.right(TitanOperationStatus.NOT_FOUND);
1504 return Either.left(immutablePairs);
1508 public <T extends GraphNode> Either<ImmutablePair<T, GraphEdge>, TitanOperationStatus> getParentNode(String key, String uniqueId, GraphEdgeLabels edgeType, NodeTypeEnum nodeTypeEnum, Class<T> clazz) {
1510 Either<List<ImmutablePair<T, GraphEdge>>, TitanOperationStatus> parentNodesRes = this.getParentNodes(key, uniqueId, edgeType, nodeTypeEnum, clazz);
1512 if (parentNodesRes.isRight()) {
1513 log.debug("failed to get edge key:{} uniqueId:{} edgeType {} nodeTypeEnum: {}, reason:{}", key, uniqueId, edgeType, nodeTypeEnum, parentNodesRes.right().value());
1514 return Either.right(parentNodesRes.right().value());
1517 List<ImmutablePair<T, GraphEdge>> value = parentNodesRes.left().value();
1519 if (value.size() > 1) {
1520 return Either.right(TitanOperationStatus.MULTIPLE_CHILDS_WITH_SAME_EDGE);
1523 return Either.left(value.get(0));
1526 public <T extends GraphNode> Either<ImmutablePair<T, GraphEdge>, TitanOperationStatus> getChildByEdgeCriteria(String key, String uniqueId, GraphEdgeLabels edgeType, NodeTypeEnum nodeTypeEnum, Class<T> clazz, Map<String, Object> edgeProperties) {
1528 Either<Edge, TitanOperationStatus> outgoingEdgeByCriteria = getOutgoingEdgeByCriteria(key, uniqueId, edgeType, edgeProperties);
1529 if (outgoingEdgeByCriteria.isRight()) {
1530 TitanOperationStatus status = outgoingEdgeByCriteria.right().value();
1531 log.debug("Cannot find outgoing edge from vertex {} with label {} and properties {}" + uniqueId, edgeType, edgeProperties);
1532 return Either.right(status);
1535 Edge edge = outgoingEdgeByCriteria.left().value();
1536 Map<String, Object> edgeProps = getProperties(edge);
1537 GraphEdgeLabels edgeTypeFromGraph = GraphEdgeLabels.getByName(edge.label());
1538 GraphEdge graphEdge = new GraphEdge(edgeTypeFromGraph, edgeProps);
1540 Vertex outgoingVertex = edge.inVertex();
1541 Map<String, Object> properties = getProperties(outgoingVertex);
1542 T data = GraphElementFactory.createElement(nodeTypeEnum.getName(), GraphElementTypeEnum.Node, properties, clazz);
1544 ImmutablePair<T, GraphEdge> immutablePair = new ImmutablePair<>(clazz.cast(data), graphEdge);
1546 return Either.left(immutablePair);
1549 public Either<ImmutablePair<TitanVertex, Edge>, TitanOperationStatus> getChildByEdgeCriteria(TitanVertex vertex, GraphEdgeLabels edgeType, Map<String, Object> edgeProperties) {
1551 Either<Edge, TitanOperationStatus> outgoingEdgeByCriteria = getOutgoingEdgeByCriteria(vertex, edgeType, edgeProperties);
1552 if (outgoingEdgeByCriteria.isRight()) {
1553 TitanOperationStatus status = outgoingEdgeByCriteria.right().value();
1554 log.debug("Cannot find outgoing edge from vertex {} with label {} and properties {}", vertex, edgeType, edgeProperties);
1555 return Either.right(status);
1557 Edge edge = outgoingEdgeByCriteria.left().value();
1559 TitanVertex outgoingVertex = (TitanVertex) edge.inVertex();
1561 ImmutablePair<TitanVertex, Edge> immutablePair = new ImmutablePair<>(outgoingVertex, edge);
1563 return Either.left(immutablePair);
1566 public Either<Edge, TitanOperationStatus> getOutgoingEdgeByCriteria(String key, String value, GraphEdgeLabels label, Map<String, Object> props) {
1568 Either<TitanVertex, TitanOperationStatus> vertexFrom = getVertexByProperty(key, value);
1569 if (vertexFrom.isRight()) {
1570 TitanOperationStatus status = vertexFrom.right().value();
1571 if (status == TitanOperationStatus.NOT_FOUND) {
1572 return Either.right(TitanOperationStatus.INVALID_ID);
1574 return Either.right(status);
1577 return getOutgoingEdgeByCriteria(vertexFrom.left().value(), label, props);
1580 public Either<Edge, TitanOperationStatus> getOutgoingEdgeByCriteria(TitanVertex vertex, GraphEdgeLabels label, Map<String, Object> props) {
1582 TitanVertexQuery<?> query = vertex.query();
1583 query = query.direction(Direction.OUT).labels(label.getProperty());
1585 if (props != null && !props.isEmpty()) {
1586 for (Map.Entry<String, Object> entry : props.entrySet()) {
1587 query = query.has(entry.getKey(), entry.getValue());
1590 Edge matchingEdge = null;
1591 Iterable<TitanEdge> edges = query.edges();
1592 if (edges == null) {
1593 log.debug("No edges in graph for criteria");
1594 return Either.right(TitanOperationStatus.NOT_FOUND);
1596 Iterator<TitanEdge> eIter = edges.iterator();
1597 if (eIter.hasNext()) {
1598 matchingEdge = eIter.next();
1601 if (matchingEdge == null) {
1602 log.debug("No edges in graph for criteria");
1603 return Either.right(TitanOperationStatus.NOT_FOUND);
1605 return Either.left(matchingEdge);
1608 public <T extends GraphNode> Either<List<ImmutablePair<T, GraphEdge>>, TitanOperationStatus> deleteChildrenNodes(String key, String uniqueId, GraphEdgeLabels edgeType, NodeTypeEnum nodeTypeEnum, Class<T> clazz) {
1610 List<ImmutablePair<T, GraphEdge>> result = new ArrayList<>();
1612 Either<List<ImmutablePair<T, GraphEdge>>, TitanOperationStatus> childrenNodesRes = getChildrenNodes(key, uniqueId, edgeType, nodeTypeEnum, clazz);
1614 if (childrenNodesRes.isRight()) {
1615 TitanOperationStatus status = childrenNodesRes.right().value();
1616 return Either.right(status);
1619 List<ImmutablePair<T, GraphEdge>> list = childrenNodesRes.left().value();
1620 for (ImmutablePair<T, GraphEdge> pair : list) {
1621 T node = pair.getKey();
1622 Either<T, TitanOperationStatus> deleteNodeRes = this.deleteNode(node, clazz);
1623 if (deleteNodeRes.isRight()) {
1624 TitanOperationStatus status = deleteNodeRes.right().value();
1625 log.error("Failed to delete node {} . status is {}", node, status);
1626 return Either.right(status);
1628 ImmutablePair<T, GraphEdge> deletedPair = new ImmutablePair<>(node, pair.getValue());
1629 result.add(deletedPair);
1632 return Either.left(result);
1636 public void setProperties(Element element, Map<String, Object> properties) {
1638 if (properties != null && !properties.isEmpty()) {
1640 Object[] propertyKeyValues = new Object[properties.size() * 2];
1642 for (Entry<String, Object> entry : properties.entrySet()) {
1643 propertyKeyValues[i++] = entry.getKey();
1644 propertyKeyValues[i++] = entry.getValue();
1647 ElementHelper.attachProperties(element, propertyKeyValues);
1653 public Map<String, Object> getProperties(Element element) {
1655 Map<String, Object> result = new HashMap<>();
1657 if (element != null && element.keys() != null && element.keys().size() > 0) {
1658 Map<String, Property> propertyMap = ElementHelper.propertyMap(element, element.keys().toArray(new String[element.keys().size()]));
1660 for (Entry<String, Property> entry : propertyMap.entrySet()) {
1661 String key = entry.getKey();
1662 Object value = entry.getValue().value();
1664 result.put(key, value);
1670 public Object getProperty(TitanVertex vertex, String key) {
1671 PropertyKey propertyKey = titanClient.getGraph().left().value().getPropertyKey(key);
1672 return vertex.valueOrNull(propertyKey);
1675 public Object getProperty(Edge edge, String key) {
1676 Object value = null;
1677 Property<Object> property = edge.property(key);
1678 if (property != null) {
1679 return property.orElse(null);
1684 public <T extends GraphNode> Either<List<ImmutablePair<T, GraphEdge>>, TitanOperationStatus> getChildrenByEdgeCriteria(Vertex vertex, String vertexUniqueId, GraphEdgeLabels edgeType, NodeTypeEnum nodeTypeEnum, Class<T> clazz,
1685 Map<String, Object> edgeProperties) {
1687 List<ImmutablePair<T, GraphEdge>> result = new ArrayList<>();
1689 Either<List<Edge>, TitanOperationStatus> outgoingEdgeByCriteria = getOutgoingEdgesByCriteria(vertex, edgeType, edgeProperties);
1690 if (outgoingEdgeByCriteria.isRight()) {
1691 TitanOperationStatus status = outgoingEdgeByCriteria.right().value();
1692 log.debug("Cannot find outgoing edge from vertex {} with label {} and properties {}", vertexUniqueId, edgeType, edgeProperties);
1693 return Either.right(status);
1696 List<Edge> edges = outgoingEdgeByCriteria.left().value();
1697 if (edges != null) {
1698 for (Edge edge : edges) {
1699 Map<String, Object> edgeProps = getProperties(edge);
1700 GraphEdgeLabels edgeTypeFromGraph = GraphEdgeLabels.getByName(edge.label());
1701 GraphEdge graphEdge = new GraphEdge(edgeTypeFromGraph, edgeProps);
1703 Vertex outgoingVertex = edge.inVertex();
1704 Map<String, Object> properties = getProperties(outgoingVertex);
1705 T data = GraphElementFactory.createElement(nodeTypeEnum.getName(), GraphElementTypeEnum.Node, properties, clazz);
1707 ImmutablePair<T, GraphEdge> immutablePair = new ImmutablePair<>(clazz.cast(data), graphEdge);
1708 result.add(immutablePair);
1712 return Either.left(result);
1715 public Either<List<Edge>, TitanOperationStatus> getOutgoingEdgesByCriteria(Vertex vertexFrom, GraphEdgeLabels label, Map<String, Object> props) {
1717 List<Edge> edgesResult = new ArrayList<>();
1719 TitanVertex titanVertex = (TitanVertex) vertexFrom;
1720 TitanVertexQuery<?> query = titanVertex.query();
1722 query = query.direction(Direction.OUT).labels(label.getProperty());
1724 if (props != null && !props.isEmpty()) {
1725 for (Map.Entry<String, Object> entry : props.entrySet()) {
1726 query = query.has(entry.getKey(), entry.getValue());
1730 Iterable<TitanEdge> edges = query.edges();
1731 Iterator<TitanEdge> eIter = edges.iterator();
1732 if (edges == null || !eIter.hasNext()) {
1733 log.debug("No edges found in graph for criteria (label = {} properties={})", label.getProperty(), props);
1734 return Either.right(TitanOperationStatus.NOT_FOUND);
1737 while (eIter.hasNext()) {
1738 Edge edge = eIter.next();
1739 edgesResult.add(edge);
1742 if (edgesResult.isEmpty()) {
1743 log.debug("No edges found in graph for criteria (label = {} properties={})", label.getProperty(), props);
1744 return Either.right(TitanOperationStatus.NOT_FOUND);
1746 return Either.left(edgesResult);